Runtime
The everruns-runtime crate runs an Everruns harness entirely inside your own Rust process. There is no PostgreSQL, no control-plane server, and no worker boundary — just the harness, your capabilities, and your code.
It is the Rust-native counterpart to the SDKs: where the SDKs talk to a running Everruns server over HTTP, the runtime is the engine, linked straight into your binary.
Use the runtime when you want to:
- Run a harness in-process with no external services
- Register your own capabilities, drivers, and tools
- Provide your own backend stores (files, messages, sessions, …)
- Inspect the assembled turn context before execution
It ships in-memory by default, so the smallest useful host is a single build().await? away.
Install
Requires Rust 1.94+ (edition 2024).
cargo add everruns-runtimeThe crate also depends on everruns-core for shared types (capabilities, drivers, models):
cargo add everruns-coreQuickstart
Build an in-process runtime with an in-memory backend and a simulated LLM, then run a turn:
use everruns_core::{ CapabilityRegistry, DriverId, DriverRegistry, PlatformDefinition, ResolvedModel,};use everruns_core::llmsim_driver::LlmSimConfig;use everruns_runtime::InProcessRuntimeBuilder;
let platform = PlatformDefinition::new(CapabilityRegistry::new(), DriverRegistry::new());
let runtime = InProcessRuntimeBuilder::new() .platform_definition(platform) .llm_sim(LlmSimConfig::fixed("hello from everruns-runtime")) .default_model(ResolvedModel { model: "llmsim-model".into(), provider_type: DriverId::LlmSim, api_key: Some("fake-key".into()), base_url: None, provider_metadata: None, }) // .capability(...) // .backends(...) // .harness(...) // .session(...) .build() .await?;The quickstart uses the built-in llmsim driver for deterministic, offline runs. To talk to a live provider, register that provider’s driver and point default_model at it — see Talk to OpenAI below.
Talk to OpenAI
A real provider needs two things, not one: the provider’s driver must be registered in the DriverRegistry, and default_model must select it. Setting default_model alone is not enough — the runtime resolves provider_type against the registry, so an unregistered driver fails at turn time.
Add the provider crate:
cargo add everruns-openaiThen register its driver and select it as the default model:
use everruns_core::driver_registry::DriverRegistry;use everruns_core::{CapabilityRegistry, DriverId, PlatformDefinition, ResolvedModel};use everruns_runtime::InProcessRuntimeBuilder;
// 1. Register the OpenAI driver so `DriverId::OpenAI` can be resolved.let mut drivers = DriverRegistry::new();everruns_openai::register_driver(&mut drivers);
// 2. Build the platform from that registry.let platform = PlatformDefinition::new(CapabilityRegistry::new(), drivers);
// 3. Point the runtime's default model at OpenAI.let runtime = InProcessRuntimeBuilder::new() .platform_definition(platform) .default_model(ResolvedModel { model: "gpt-5.5".into(), provider_type: DriverId::OpenAI, api_key: Some(std::env::var("OPENAI_API_KEY")?), base_url: None, provider_metadata: None, }) .single_session(|s| { s.harness("assistant", "You are a concise, helpful assistant.") .agent("assistant-agent", "Answer in one short sentence.") .session_title("OpenAI Session") }) .build() .await?;
let session_id = runtime.default_session_id().expect("single_session id");let result = runtime .run_text_turn(session_id, "Say hello from everruns-runtime in one sentence.") .await?;println!("{}", result.response);The same pattern works for any provider crate — swap everruns-openai for everruns-anthropic (DriverId::Anthropic), everruns-openrouter (DriverId::OpenRouter), and so on, matching the crate to its DriverId. To reach an OpenAI-compatible endpoint (a local gateway, Ollama, …), set base_url and pick the DriverId that matches the API the server speaks: DriverId::OpenAI for the Responses API, or DriverId::OpenAICompletions for the Chat Completions API.
A complete, runnable version lives at crates/runtime/examples/openai_runtime.rs:
export OPENAI_API_KEY=sk-...cargo run -p everruns-runtime --example openai_runtimeInspect the turn context
load_context(session_id) returns the exact merged context the reason phase will use — before the first turn or after messages already exist:
let context = runtime.load_context(session_id).await?;println!("messages = {}", context.messages.len());println!("model = {}", context.runtime_agent.model);println!("tools = {}", context.runtime_agent.tools.len());The context bundles the harness chain, optional agent, session, filtered message history, resolved model, and the assembled RuntimeAgent. With no messages yet, context.messages is empty and model/locale resolution falls back to merged harness, agent, session, and platform defaults.
The harness’s base system prompt is optional. Pass an empty string (or, when constructing a Harness directly, leave system_prompt as None) for a harness that only contributes capabilities or MCP servers. The prompt-composition layer trims empty fragments, so runtime_agent.system_prompt is assembled purely from whatever layers — parent harness, agent, session, capabilities — actually contribute text, and may be empty if none do.
Execute-time hosts use everruns_core::assemble_turn_context(...) while inspection uses everruns_core::inspect_turn_context(...); both share the same assembly logic, so in-process and worker-backed behavior stay aligned.
Custom backends
The runtime ships in-memory defaults, but public extension traits let you supply your own stores:
| Trait | Backs |
|---|---|
RuntimeHarnessStore | Harness definitions |
RuntimeAgentStore | Agent configurations |
RuntimeSessionStore | Sessions |
RuntimeMessageStore | Message history |
RuntimeFileStore | Session files |
RuntimeProviderStore | LLM providers |
EventBus | Emitted events (extends EventEmitter) |
Pass them through RuntimeBackends on the builder; any store you don’t override stays in-memory:
use everruns_runtime::{InProcessRuntimeBuilder, RuntimeBackends};
let runtime = InProcessRuntimeBuilder::new() .backends( RuntimeBackends::in_memory() .with_file_store(my_file_store) .with_message_store(my_message_store) .with_event_bus(my_event_bus), ) .build() .await?;The default in-memory EventBus retains emitted events for InProcessRuntime::events(); production buses inherit the default collected_events and return an empty Vec.
Local backends
In-memory stores vanish when the process exits. For an embedded, single-process host that should survive restarts — a terminal coding agent, a personal agent, a long-lived CLI — the companion everruns-local crate provides SQLite-backed, file-persisted implementations of the optional host-backend slots:
| Type | Backs |
|---|---|
LocalSessionTaskRegistry | Session tasks and their message channel |
LocalScheduleStore | Session schedules (with a local metadata JSON bag) |
LocalPlatformStore | Subagent-critical platform store core |
LocalProfile | Local data dir, workspace, and identity defaults |
LocalBackends | Composes the above into RuntimeBackends |
Task and message state persists to a SQLite file, so a freshly-spawned process can read, continue, and inspect work an earlier process started.
cargo add everruns-localuse everruns_local::{LocalBackends, LocalProfile};use everruns_runtime::{InProcessRuntimeBuilder, RuntimeBackends};
// LocalProfile stores plain filesystem paths and does not expand a leading// `~`; pass an absolute path your application owns. Its SQLite file is derived// from the data dir.let profile = LocalProfile::new("/var/lib/everruns") .with_workspace_root("/var/lib/everruns/workspace");
// Layer the local stores over a set of runtime backends. Any store (or event// bus) you set on `RuntimeBackends` is preserved.let local = LocalBackends::new(profile, RuntimeBackends::in_memory())?;
let runtime = InProcessRuntimeBuilder::new() .platform_definition(platform) .backends(local.runtime_backends.clone()) .build() .await?;LocalBackends only adds the local stores — it preserves a caller-supplied event bus (via RuntimeBackends) and session file-system factory (via the platform’s PlatformDefinition), so it composes with the custom backends above rather than replacing them. See docs.rs/everruns-local for the full API.
Local MCP servers
MCP server tools are first-class runtime tools. Local-process (stdio) MCP servers are gated behind the mcp-stdio feature, off by default so the hosted server/worker never compile stdio in:
cargo add everruns-runtime --features mcp-stdioBuilt with the runtime
-
yolop — a minimal terminal coding agent built on
everruns-runtime(codex/claude-code in spirit). It started as thecoding-cliexample below, promoted into a standalone, releasable project, and is where active development happens: interactive TUI, real-filesystem tools, abashtool, multi-provider LLMs (OpenAI, Anthropic, Gemini, OpenRouter, Ollama), MCP servers (stdio + HTTP), resumable sessions, and Zed editor integration over ACP.Terminal window brew install everruns/tap/yolop# orcargo install yolop --locked -
examples/coding-cli— the in-tree reference embedder for the public crate: a single-binary coding agent with a ratatui TUI, real-filesystem tools onRealDiskFileStore, a custombashtool, skills, and infinity-context trimming. It lives at the workspace edge and depends on the public crate exactly the way an external embedder would. -
examples/weekend-concierge-host— a root-level host app that defines its own capability, private tool data, seeded files, and an in-process turn loop.
Run the in-tree examples:
cargo run -p everruns-runtime --example in_process_runtimecargo run -p everruns-runtime --example inspect_contextcargo run -p everruns-runtime --example openai_runtime # needs OPENAI_API_KEYcargo run --manifest-path examples/coding-cli/Cargo.tomlcargo run --manifest-path examples/weekend-concierge-host/Cargo.tomlSee also
- Embedding Everruns — compose your own
PlatformDefinition, server, and worker; the runtime is the in-process slice of that story. - SDKs — client libraries for talking to a running Everruns server over HTTP.
- Harnesses — the agent execution templates the runtime runs.
- Capabilities — the tools and behaviors you register on a harness.
- docs.rs/everruns-runtime — full API reference.