Expose HTTP with SSE
Use this when you need to serve agents over HTTP with Server-Sent Events streaming, supporting multiple protocol adapters (AI SDK, AG-UI, A2A, MCP).
Prerequisites
Section titled “Prerequisites”awakencrate with theserverfeature enabledtokiowithrt-multi-threadandsignalfeatures- A built
AgentRuntime
- Add the dependency.
[dependencies]awaken = { git = "https://github.com/AwakenWorks/awaken", features = ["server"] }tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal"] }- Build the runtime.
use std::sync::Arc;use awaken::engine::GenaiExecutor;use awaken::registry_spec::ModelSpec;use awaken::{AgentRuntimeBuilder, AgentSpec};use awaken::contract::commit_coordinator::CommitCoordinator;use awaken::stores::{InMemoryStore, MemoryCommitCoordinator};
let store = Arc::new(InMemoryStore::new());let coordinator = MemoryCommitCoordinator::wrap(store.clone()) as Arc<dyn CommitCoordinator>;
let runtime = AgentRuntimeBuilder::new() .with_agent_spec( AgentSpec::new("assistant") .with_model_id("claude-sonnet") .with_system_prompt("You are a helpful assistant."), ) .with_tool("search", Arc::new(SearchTool)) .with_provider("anthropic", Arc::new(GenaiExecutor::new())) .with_model(ModelSpec::new("claude-sonnet", "anthropic", "claude-sonnet-4-20250514")) .with_commit_coordinator(coordinator) .build()?;
let runtime = Arc::new(runtime);- Create the application state.
use awaken::server::app::{ServerState, ServerConfig};use awaken::server::mailbox::{Mailbox, MailboxConfig};use awaken::stores::InMemoryMailboxStore;
let mailbox_store = Arc::new(InMemoryMailboxStore::new());let mailbox = Arc::new(Mailbox::new( runtime.clone(), mailbox_store, store.clone(), "default-consumer".to_string(), MailboxConfig::default(),));
let state = ServerState::new( runtime.clone(), mailbox, store, runtime.resolver_arc(), ServerConfig::default(),);ServerConfig::default() binds to 0.0.0.0:3000 with an SSE buffer size of 64.
- Build the router.
use awaken::server::routes::build_router;
let app = build_router().with_state(state);build_router registers all route groups:
/health— health check/v1/threads— thread CRUD and messaging/v1/runsand/v1/threads/:id/runs— run APIs/v1/config/*and/v1/capabilities— config and capabilities APIs- Protocol adapters: AI SDK v6, AG-UI, A2A, MCP
- Start the server.
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;axum::serve(listener, app).await?;- Configure SSE buffer size.
let config = ServerConfig { address: "0.0.0.0:8080".into(), sse_buffer_size: 128, ..ServerConfig::default()};Increase sse_buffer_size if clients consume events slowly and you observe dropped messages.
Verify
Section titled “Verify”curl http://localhost:3000/healthShould return 200 OK. Then create a thread and run:
curl -X POST http://localhost:3000/v1/threads \ -H "Content-Type: application/json" \ -d '{}'Common Errors
Section titled “Common Errors”| Error | Cause | Fix |
|---|---|---|
| Address already in use | Port 3000 is occupied | Change the bind address in ServerConfig or TcpListener::bind |
| SSE stream closes immediately | Client does not support text/event-stream | Use curl with --no-buffer or an SSE-compatible client |
| Missing protocol routes | Feature flags not enabled | Ensure server feature is enabled on the awaken crate |
Related Example
Section titled “Related Example”crates/awaken-server/tests/run_api.rs — integration tests demonstrating thread creation, run execution, and SSE streaming.
Key Files
Section titled “Key Files”crates/awaken-server/src/app.rs—ServerState,ServerConfigcrates/awaken-server/src/routes.rs—build_routerand route definitionscrates/awaken-server/src/http_sse.rs— SSE response helperscrates/awaken-server/src/mailbox.rs—Mailboxrun queue