Embed the runtime
Run sessions inside a Rust service you already own.
Run the server when you want a process to talk to. Embed the crate when another Rust service already owns startup, configuration and deployment, and you want sessions inside it.
Each Session is one conversation, and your service can run many sessions on one shared runtime.
This Rust excerpt assumes you've already configured the session directory, telemetry and the loop,
model and tool executors described below:
use std::sync::Arc;
let limits = brain::Limits::default();
let writer = brain::Writer::spawn_with(&limits);
let feed = Arc::new(brain::Feed::with_limits(telemetry.clone(), &limits));
let runtime = Arc::new(brain::SessionRuntime {
environment_control: None,
tool_executions: Arc::default(),
limits: limits.clone(),
harness,
model_executor,
tool_executor,
live: feed.clone(),
telemetry,
});
let store = brain::LocalSessionStore::create(
&sessions_dir.join(session_id.as_str()),
session_id,
&serde_json::to_value(&config)?,
writer.clone(),
feed.clone(),
)?;
let creating = brain::Session::begin(store.clone(), runtime.clone(), &config, &opening_transcript)?;
let session = creating.complete(config)?;
session
.message(brain_protocol::MessageRequest {
input: "Explain the current changes.".into(),
})
.await?;Open only the session you need. When it needs explicit activation, call
interrupt_unfinished_turn, then Session::open. LocalSessionStore::open on its own allows
transcript and Event reads without an actor. To speed up the next open, call checkpoint() at a
quiescent boundary before dropping execution; the projection it writes is disposable. Keep one live
store and sequencer per session and serialize mutations to it. The stock server handles that
coordination for you.
Hold a filesystem lock on the local data directory for the life of the process before opening
mutable stores. When embedding the stock server's composition, brain_server::data_layout::lock
provides that lock. Brain supports one local writer; cross-server ownership belongs to your host
platform.
You supply the ports
Provide harness, model_executor and tool_executor implementations for your deployment.
Set environment_control if your host supports resource operations; None leaves them unavailable.
- Harness: an
Arc<dyn brain::AgentHarness>selected at startup. It receives the session identity, activation input, andTurnServices. The stock server usesbrain_sessions::StdioHarness; an embedding can implement the same Rust trait in-process. The implementation owns native state, compaction, and recovery policy. - Model executor: receives the session id and resolves the credential it sealed for it.
- Tool executor: receives the Tool and its Environment entry.
A custom SessionStore can build asynchronous append completions with
CommitHandle::from_completion. Returning success must mean the canonical records have committed.
What the runtime guarantees
Journal commits still land synchronously before effects, and recovery still rebuilds every
projection from the same canonical journal. Embedding doesn't loosen admission:
Session::begin and complete hold configuration to the same contract as the server.
What stays yours
Which sessions exist, which are running, what happens to them after a restart and when to forget them. Where environments live and how they're found. Credentials, and how HTTP retries are answered. All product policy. The runtime has opinions about correctness, not about your architecture.
Telemetry delivery
The telemetry channel is bounded and never holds up a turn. A worker drains queued records into
ordered batches and retries a rejected batch for up to 30 seconds, so a sink may see the same batch
more than once and must handle duplicates safely. When deliveries are exhausted, they're counted and
reported through telemetry_delivery_dropped records if the queue still has room.
Telemetry is best effort. For resumable event forwarding, consume the session event endpoint, save its sequence cursor once the destination acknowledges a batch, and reconnect from that cursor. The session's canonical journal, not the telemetry queue, is the durable record.