release/1.3.1
rs 75 lines 2.87 KB
Raw
1 //! Ed: an embeddable, local-LLM-first chat agent.
2 //!
3 //! Ed sits one layer above the [`onde`] inference SDK. `onde` gives you a
4 //! [`ChatEngine`](onde::inference::ChatEngine) you can load a model into and
5 //! send messages to; Ed adds the part every application built on it was
6 //! writing for itself:
7 //!
8 //! - **Lifecycle orchestration.** Loading a model is a sequence of state
9 //! changes, not one call. Ed drives `Loading -> Ready` (or `-> Error`) and
10 //! reports each transition.
11 //! - **Notification.** `onde` exposes status by polling
12 //! [`info()`](onde::inference::ChatEngine::info). A UI needs to be told.
13 //! Ed pushes transitions and replies to a [`StatusSink`] the host implements.
14 //! - **A flattened reply.** Inference returns `Result<InferenceResult, _>`;
15 //! a frontend wants one shape covering both outcomes. That's [`ChatReply`].
16 //!
17 //! Ed deliberately does *not* own sessions, persistence, model catalogues, or
18 //! downloads. Those differ per application and belong to the host. For
19 //! persistence it defines the [`SessionStore`] seam the host implements.
20 //!
21 //! # Platforms
22 //!
23 //! Ed has no `cfg(target_os)` gates. `onde` already splits real and fallback
24 //! implementations internally, so this crate compiles on every platform `onde`
25 //! supports (macOS, iOS, tvOS, visionOS, watchOS, Windows, Linux, Android) and
26 //! simply surfaces `onde`'s error where it can't run inference. Outside that
27 //! list `onde` falls back to a stub whose signatures differ, so Ed does not
28 //! build there either.
29 //!
30 //! Do not add platform gates here, and be careful about adding them in a host:
31 //! a gate narrower than `onde`'s own support list silently disables chat on a
32 //! platform that would have worked.
33 //!
34 //! # Example
35 //!
36 //! ```no_run
37 //! use ed_agent::{Ed, GgufModelConfig};
38 //!
39 //! # async fn example() {
40 //! let ed = Ed::new();
41 //! let config = GgufModelConfig::qwen25_1_5b();
42 //! ed.load(config, None, None).await.expect("load");
43 //!
44 //! let reply = ed.send("Summarise this thread.").await;
45 //! println!("{}", reply.reply.unwrap_or_default());
46 //! # }
47 //! ```
48
49 #![forbid(unsafe_code)]
50
51 mod ed;
52 mod reply;
53 mod session;
54 mod sink;
55 mod stream;
56 mod tool;
57
58 pub use ed::Ed;
59 pub use reply::ChatReply;
60 pub use session::{SessionError, SessionMeta, SessionStore};
61 pub use sink::{EventSink, NoopSink, StatusSink};
62 pub use stream::TextStream;
63 pub use tool::{
64 AgentConfig, AgentError, AgentReply, AgentToolDefinition, ApprovalDecision, ApprovalHandler,
65 ApprovalRequest, DenyApprovals, RejectingExecutor, ToolCall, ToolExecutionResult, ToolExecutor,
66 ToolRisk,
67 };
68
69 // Re-exported so a host depends on `ed-agent` alone and never has to match a
70 // second `onde` version against this crate's.
71 pub use onde::inference::types::{ChatMessage, ChatRole};
72 pub use onde::inference::{
73 ChatEngine, EngineInfo, EngineStatus, GgufModelConfig, InferenceError, SamplingConfig,
74 ToolCallingSupport, UqffModelConfig,
75 };