| 1 | # Ed |
| 2 | |
| 3 | **Embed Ed.** Your app gets a brain. Your users keep their data. |
| 4 | |
| 5 | Ed is an agent you drop into an application. It loads an open-weights model, |
| 6 | keeps the conversation, calls only the host tools you register, and hands back |
| 7 | replies. The model runs on the user's device — there is no metered inference |
| 8 | API and private context does not need to leave the device. |
| 9 | |
| 10 | ## Why it exists |
| 11 | |
| 12 | Seven applications needed the same thing: load a model, know whether it's ready, |
| 13 | keep a conversation, hand back a reply. Seven times somebody wrote it again. Two |
| 14 | of them ended up byte-identical in three files. |
| 15 | |
| 16 | None of that code was interesting. It was the wiring between an inference engine |
| 17 | that reports status by polling and a user interface that needs to be told — |
| 18 | plus the flattening of `Result<InferenceResult, _>` into one payload a view can |
| 19 | render either way. Ed is that layer, written once. |
| 20 | |
| 21 | It deliberately doesn't own sessions, persistence, model catalogues, or |
| 22 | downloads. Those differ per application and stay yours. |
| 23 | |
| 24 | ## Onde runs the model. Ed makes it a feature. |
| 25 | |
| 26 | [Onde](https://ondeinference.com) is the inference engine: weights, quantisation, |
| 27 | Metal and CPU backends, tokens out. Ed is the part above it your users touch. |
| 28 | |
| 29 | ## See it live |
| 30 | |
| 31 | - **[smbCloud MailX](https://smbcloudmail.com/en-us)** — siMail drafts replies, |
| 32 | summarises long threads, and helps triage the inbox. The mail never leaves the |
| 33 | machine to get read. |
| 34 | - **[Siti AI](https://github.com/getsigit/siti)** — a private assistant for |
| 35 | macOS, iOS, and Android, and the open reference app: its source is public, so |
| 36 | it's the codebase to read for a full integration. |
| 37 | - **[Pepak Basa Jawa Komplit](https://apps.apple.com/se/app/pepak-basa-jawa-komplit/id6752241812)** |
| 38 | — Joko, a Javanese tutor who answers offline, which matters where the app is |
| 39 | used. |
| 40 | - **[Rumi Learn Persian](https://apps.apple.com/se/app/rumi-l%C3%A4r-dig-persiska/id6753832408)** |
| 41 | — Rumi, a Persian tutor, same model, same device. |
| 42 | |
| 43 | ## Quick start |
| 44 | |
| 45 | ```toml |
| 46 | [dependencies] |
| 47 | ed-agent = "1.2" |
| 48 | ``` |
| 49 | |
| 50 | ```rust |
| 51 | use ed_agent::{Ed, GgufModelConfig}; |
| 52 | |
| 53 | let ed = Ed::new(); |
| 54 | ed.load(GgufModelConfig::qwen25_1_5b(), None, None).await?; |
| 55 | |
| 56 | let reply = ed.send("Summarise this thread.").await; |
| 57 | println!("{}", reply.reply.unwrap_or_default()); |
| 58 | ``` |
| 59 | |
| 60 | Stream a reply with `Ed::stream` (plain chat) or let `Ed::run` forward deltas to |
| 61 | `EventSink::text_delta`. `Ed::restore_history` loads a saved conversation, |
| 62 | `Ed::generate` is a one-shot call that leaves the history alone, and |
| 63 | `Ed::set_system_prompt` / `set_sampling` change the model's settings. These |
| 64 | three need a loaded model. Persistence stays yours; implement `SessionStore` |
| 65 | over whatever you already have. |
| 66 | |
| 67 | Construct with `Ed::with_agent` to provide the executor for registered tools |
| 68 | and the approval handler for mutating tools. Read-only tools run directly; |
| 69 | mutating tools must receive `AllowOnce` or `AllowForSession` first. |
| 70 | |
| 71 | ## Crates |
| 72 | |
| 73 | | Crate | What it's for | |
| 74 | | --- | --- | |
| 75 | | [`ed-agent`](crates/ed-agent) | The agent. No framework dependency. | |
| 76 | | [`ed-agent-ffi`](crates/ed-agent-ffi) | UniFFI bridge used by the Swift XCFramework. | |
| 77 | | [`ed-agent-tauri`](crates/ed-agent-tauri) | Tauri bindings: a sink that emits to the webview, the commands it invokes, and `EdSessions` for apps with a chat history and webview-answered approvals. | |
| 78 | |
| 79 | The Onde Agent Platform crates, for agents that editors drive over the Agent Client Protocol |
| 80 | (ACP). SplitFire Agent is built on them. |
| 81 | |
| 82 | | Crate | What it's for | |
| 83 | | --- | --- | |
| 84 | | [`ed-acp`](crates/ed-acp) | An ACP v1 server: sessions, auth, the turn loop on Onde Cloud, tool approval, workspace tools and MCP. A product supplies a `Profile`. | |
| 85 | | [`ed-acp-tui`](crates/ed-acp-tui) | A terminal UI for any ACP agent. | |
| 86 | | [`ed-mcp`](crates/ed-mcp) | MCP client glue over `rmcp`, the official Rust SDK: stdio and streamable HTTP servers, bearer tokens, tool namespacing, timeouts, progress and cancellation. With the `agent` feature, `McpExecutor` serves a toolset to Ed as tools. | |
| 87 | | [`ed-onde-account`](crates/ed-onde-account) | Onde Inference account client: sign in, activate an app and get its Onde Cloud API key through ondeinference.com, with no Onde secrets in the host app. | |
| 88 | | [`ed-acp-testkit`](crates/ed-acp-testkit) | Mock Onde Cloud endpoint, raw ACP client, the ACP registry probe and the ACP v1 conformance suite. | |
| 89 | |
| 90 | Free the intelligence. |
| 91 | |
| 92 | ## Copyright |
| 93 | |
| 94 | © 2026 [Onde Inference](https://ondeinference.com). |
| 95 | Licensed under MIT or Apache-2.0. |