pipecrab_lm/lib.rs
1//! pipecrab-lm: the provider-neutral structured-generation interface.
2//!
3//! [`LanguageModel`] is the swappable LM capability the conversation loop drives:
4//! a [`Conversation`] in, a [`ModelStream`] of [`ModelDelta`]s out
5//! *incrementally* — text to append, or a complete [`ToolCall`]. Every item is a
6//! preemption point, so a barge-in
7//! [`Interrupt`](pipecrab_core::SystemFrame::Interrupt) stops the reply within a
8//! single delta. Concrete engines stay behind the trait, so the pipeline never
9//! names one.
10//!
11//! # `ModelDelta` vs [`ModelFrame`](pipecrab_core::ModelFrame)
12//!
13//! A [`ModelDelta`] is the *internal* protocol between a [`LanguageModel`] and
14//! [`LmStage`], not a pipeline frame. The stage translates deltas into native
15//! frames: visible text becomes agent [`Transcript`](pipecrab_core::Transcript)s
16//! (cumulative partials, then a final) because a transcript is prose; a tool call
17//! becomes [`ModelFrame::ToolCall`](pipecrab_core::ModelFrame::ToolCall) because
18//! it is structured protocol; the lifecycle becomes
19//! [`GenerationStarted`](pipecrab_core::ModelFrame::GenerationStarted) /
20//! [`GenerationFinished`](pipecrab_core::ModelFrame::GenerationFinished).
21//! Tool-call syntax, JSON, and provider metadata never enter a transcript.
22//!
23//! # Tools
24//!
25//! [`ToolDefinition::parameters`] is a [`serde_json::Value`] so a framework's
26//! schema reaches a hosted adapter without a string round trip. Core stays
27//! JSON-free: a [`ToolCall`] carries validated arguments as JSON *text*, and
28//! [`ModelDelta::tool_call`] normalizes a JSON object into it.
29//! Provider-specific streaming, tool-call fragments, and constrained output are
30//! parsed *inside* the implementation; the stage sees only complete calls.
31//! [`LmStage::with_tools`] / [`add_tools`](LmStage::add_tools) configure tools on
32//! the stage — validated (duplicate names rejected) and passed to every
33//! generation. An adapter that wraps a higher-level agent (e.g. Rig) keeps its own
34//! registered tools internal, so the stage neither reads nor copies them.
35//!
36//! The chat-context types ([`Message`], [`Conversation`]) preserve structured
37//! assistant turns, tool calls, tool results, and external events so a hosted
38//! adapter can reconstruct valid provider history.
39//!
40//! Platform-neutral and `wasm32`-checkable: the concrete engines live elsewhere
41//! (a native `llama.cpp` context, a hosted Rig agent, a browser Worker), each
42//! behind this trait, so the interface itself carries no backend dependency and
43//! compiles for both the host and `wasm32-unknown-unknown`.
44#![forbid(unsafe_code)]
45#![warn(missing_docs)]
46
47mod model;
48mod stage;
49
50pub use model::{
51 Conversation, GenParams, LanguageModel, LmConfigError, LmError, Message, ModelDelta,
52 ModelStream, ToolDefinition,
53};
54pub use pipecrab_core::ToolCall;
55pub use stage::{Generate, LmStage};