Expand description
A Rust SDK for the AG-UI protocol — hosting an agent and consuming one.
AG-UI is the protocol between a user-facing application and an agent
backend. A run is a stream of Events: the agent opens messages, streams
text and reasoning, calls tools, publishes state, and finishes — or pauses
for human input.
It implements all 36 event types, both halves of the protocol, and a drift check in CI that fails the build when upstream’s event set moves — held to what an official SDK would have to be, because becoming the official AG-UI Rust SDK is the goal. It is not that yet: this crate is not affiliated with or endorsed by the AG-UI protocol organisation.
§What is in the box
The crate root is the shared vocabulary: the types, their exact JSON representation, and the SSE framing that carries them. No runtime, no I/O, no async — that part compiles for everyone.
Everything past it is a feature, because most programs want one side of the
protocol and should not pay to compile the other. Each entry below is
gated the same way its module is: a link to an item this build does not
have is a rustdoc error, not a dead link, which is what the doc-features
CI job exists to catch.
server— host an agent. Implementserver::Agent, hand it toserver::run(), and you have a stream a transport can serialize.client— consume a remote agent, materializing its events into messages and state.axum— mount a hosted agent on an axum router, one call.
Each runtime keeps its own Error and Result under its own module. A
bare Error is always a protocol error, ag_ui::server::Error is a
hosting error, and collapsing them into the root would hide a distinction
that matters at every ?.
use ag_ui::{Event, EventStreamFormatter, SseFormatter, TextMessageRole};
let formatter = SseFormatter::new();
let run = [
Event::run_started("thread-1", "run-1"),
Event::text_message_start("msg-1", TextMessageRole::Assistant),
Event::text_message_content("msg-1", "Hello"),
Event::text_message_end("msg-1"),
Event::run_finished_success("thread-1", "run-1"),
];
let body: String = run
.iter()
.map(|event| formatter.encode_to_string(event).unwrap())
.collect();
assert!(body.starts_with(r#"data: {"type":"RUN_STARTED","threadId":"thread-1""#));§Identifiers are strings
ThreadId, RunId and friends wrap String, not Uuid. Producers
send arbitrary strings and a stricter type would reject valid traffic — see
the ids module for the history.
§Features
sse(default) —SseFormatterandtext/event-streamframing.protobuf— the binary transport’s media type and a documented stub; theencode::protobufmodule explains why there is no encoder.schemars— derivesschemars::JsonSchemaon the public types.utoipa— derivesutoipa::ToSchemaon the public types.server— the server runtime: the agent trait, typestate emitters, state deltas. Executor-agnostic; no tokio.verify(default) —server’s ordering state machine. Off, the whole verifier is a zero-sized type whose checks compile away. Listed indefaultrather than implied byserversodefault-features = falsecan drop it.client— the client runtime, transport-agnostic.http— adds the reqwest-backed transport toclient. What most consumers want; leave it off for wasm or a custom transport.axum— mounts a hosted agent on an axum router. Impliesserverandsse, and is the one feature that pulls in tokio.
[dependencies]
# host an agent behind axum
ag-ui = { version = "0.3", features = ["axum"] }
# or consume one over HTTP
ag-ui = { version = "0.3", features = ["http"] }Re-exports§
pub use capabilities::AgentCapabilities;pub use capabilities::ExecutionCapabilities;pub use capabilities::HumanInTheLoopCapabilities;pub use capabilities::IdentityCapabilities;pub use capabilities::MultiAgentCapabilities;pub use capabilities::MultimodalCapabilities;pub use capabilities::MultimodalInputCapabilities;pub use capabilities::MultimodalOutputCapabilities;pub use capabilities::OutputCapabilities;pub use capabilities::ReasoningCapabilities;pub use capabilities::StateCapabilities;pub use capabilities::SubAgentInfo;pub use capabilities::ToolsCapabilities;pub use capabilities::TransportCapabilities;pub use context::Context;pub use error::Error;pub use error::Result;pub use event::ActivityDeltaEvent;pub use event::ActivitySnapshotEvent;pub use event::BaseEvent;pub use event::CustomEvent;pub use event::Event;pub use event::EventType;pub use event::MessagesSnapshotEvent;pub use event::RawEvent;pub use event::ReasoningEncryptedValueEvent;pub use event::ReasoningEncryptedValueSubtype;pub use event::ReasoningEndEvent;pub use event::ReasoningMessageChunkEvent;pub use event::ReasoningMessageContentEvent;pub use event::ReasoningMessageEndEvent;pub use event::ReasoningMessageStartEvent;pub use event::ReasoningRole;pub use event::ReasoningStartEvent;pub use event::RunErrorEvent;pub use event::RunFinishedEvent;pub use event::RunStartedEvent;pub use event::StateDeltaEvent;pub use event::StateSnapshotEvent;pub use event::StepFinishedEvent;pub use event::StepStartedEvent;pub use event::SubagentErrorEvent;pub use event::SubagentFinishedEvent;pub use event::SubagentOutcome;pub use event::SubagentStartedEvent;pub use event::TextMessageChunkEvent;pub use event::TextMessageContentEvent;pub use event::TextMessageEndEvent;pub use event::TextMessageRole;pub use event::TextMessageStartEvent;pub use event::ToolCallArgsEvent;pub use event::ToolCallChunkEvent;pub use event::ToolCallEndEvent;pub use event::ToolCallResultEvent;pub use event::ToolCallStartEvent;pub use event::ToolResultRole;pub use event::ThinkingEndEvent;pub use event::ThinkingStartEvent;pub use event::ThinkingTextMessageContentEvent;pub use event::ThinkingTextMessageEndEvent;pub use event::ThinkingTextMessageStartEvent;pub use ids::AgentId;pub use ids::MessageId;pub use ids::RunId;pub use ids::StepName;pub use ids::SubagentRunId;pub use ids::ThreadId;pub use ids::ToolCallId;pub use input::RunAgentInput;pub use message::ActivityMessage;pub use message::AssistantMessage;pub use message::BinaryInputContent;pub use message::DeveloperMessage;pub use message::InputContent;pub use message::InputContentSource;pub use message::MediaInputContent;pub use message::Message;pub use message::ReasoningMessage;pub use message::Role;pub use message::SystemMessage;pub use message::TextInputContent;pub use message::ToolMessage;pub use message::UserContent;pub use message::UserMessage;pub use metadata::AGUI_METADATA_KEY;pub use metadata::merge_metadata;pub use outcome::Interrupt;pub use outcome::ResumeEntry;pub use outcome::ResumeStatus;pub use outcome::RunOutcome;pub use patch::JsonPatch;pub use patch::PatchOperation;pub use token_usage::TokenUsage;pub use token_usage::aggregate_token_usage;pub use tool::FunctionCall;pub use tool::Tool;pub use tool::ToolCall;pub use tool::ToolCallKind;pub use encode::protobuf::ProtobufFormatter;pub use encode::sse::SseFormatter;pub use encode::EventStreamFormatter;pub use encode::PROTOBUF_MEDIA_TYPE;pub use encode::SSE_MEDIA_TYPE;pub use encode::media_type;pub use encode::supported_media_types;
Modules§
- axum
- Serve an AG-UI agent from an axum router.
- capabilities
- What an agent can do — a categorized snapshot for discovery UIs, routing, and debugging.
- client
- Consume a remote AG-UI agent: turn its event stream into messages and state.
- context
- Additional context handed to an agent alongside the messages.
- encode
- Wire encoding for the event stream.
- error
- Error and result types shared by the whole crate.
- event
- The AG-UI event stream.
- ids
- String-backed identifier newtypes.
- input
- The request body an agent receives to start or resume a run.
- message
- The message union and its multimodal content parts.
- metadata
- Metadata: extra information attached to events, messages, tool calls and resume entries.
- outcome
- Run outcomes and the human-in-the-loop interrupt protocol.
- patch
- JSON Patch operations, as defined by RFC 6902.
- server
- Host an AG-UI agent in Rust.
- token_
usage - Per-model token accounting carried by
RUN_FINISHEDandRUN_ERROR. - tool
- Tool definitions and tool calls.
Type Aliases§
- Json
Object - A JSON object — the Rust spelling of TypeScript’s
Record<string, any>.