release/1.3.1
md 70 lines 2.71 KB
Rendered Raw
1 # ed-agent
2
3 **Embed Ed.** Your app gets a brain. Your users keep their data.
4
5 Ed is a chat agent you drop into an application. It sits one layer above the
6 [`onde`](https://crates.io/crates/onde) inference SDK: `onde` gives you an
7 engine to load a model into and send messages to, and Ed adds the part every
8 application built on it was writing for itself.
9
10 - **Lifecycle orchestration.** Loading a model is a sequence of state changes,
11 not one call. Ed drives `Loading -> Ready` (or `-> Error`) and reports each
12 transition.
13 - **Notification.** `onde` exposes status by polling. A UI needs to be told. Ed
14 pushes transitions, tool activity, and replies to an `EventSink` you implement.
15 - **Tool calling.** The host registers an explicit JSON-schema capability list.
16 Read-only tools run automatically; mutating tools require host approval.
17 - **A flattened reply.** Inference returns `Result<InferenceResult, _>`; a
18 frontend wants one shape covering both outcomes. That's `ChatReply`.
19
20 Ed deliberately does not own sessions, persistence, model catalogues, or
21 downloads. Those differ per application and belong to you.
22
23 ## Usage
24
25 ```rust
26 use ed_agent::{Ed, GgufModelConfig};
27
28 let ed = Ed::new();
29 ed.load(GgufModelConfig::qwen25_1_5b(), None, None).await?;
30
31 let reply = ed.send("Summarise this thread.").await;
32 println!("{}", reply.reply.unwrap_or_default());
33 ```
34
35 Use `Ed::with_agent` to provide a `ToolExecutor`, `ApprovalHandler`, and
36 `EventSink`. For Tauri applications,
37 [`ed-agent-tauri`](https://crates.io/crates/ed-agent-tauri) provides that
38 implementation plus the commands a webview invokes.
39
40 ## Any load path, same transitions
41
42 `Ed::load` covers GGUF. For anything else — an assigned model from a server, a
43 UQFF build, a load API that doesn't exist yet — hand the call to `load_with` and
44 Ed reports the transitions around it:
45
46 ```rust
47 ed.load_with("Onde model", |engine| {
48 engine.load_assigned_model(env, app_id, secret, prompt, sampling)
49 })
50 .await?;
51 ```
52
53 Ed takes a closure rather than wrapping each path by name on purpose. Those APIs
54 take types that would drag their crates into Ed's public signature and pin every
55 host to Ed's version of them — and at least one of those types has already moved
56 between `onde` releases. A closure keeps Ed's dependency surface to `onde` alone.
57
58 ## Platforms
59
60 Ed has no `cfg(target_os)` gates. `onde` already splits real and fallback
61 implementations internally, so this crate compiles everywhere and surfaces
62 `onde`'s error on a platform it can't run inference on.
63
64 Be careful adding platform gates in a host: a gate narrower than `onde`'s own
65 support list silently disables chat on a platform that would have worked.
66
67 ## Copyright
68
69 © 2026 [Onde Inference](https://ondeinference.com).
70 Licensed under MIT or Apache-2.0.