Architecture

Extension directory

This directory covers all 58 roder-ext-* crates in the Roder workspace. Every extension implements the same contract: it declares a manifest (id, version, provides,required_capabilities) and installs typed services into the runtime registry. The runtime core never knows vendor specifics — it talks to the service interfaces.

Directory vs runtime. This page lists what exists in the source tree. The live runtime reports its installed set through the app-server extensions/listmethod — configuration, API keys, and distribution profiles decide which of these are actually active. Distribution profiles (full, minimal,openai-only, anthropic-only, research-headless) bundle different subsets.

Categories

Inference providers

Inference extensions install an InferenceEngine into the registry. The turn engine streams provider events (text, reasoning, tool calls) through the same interface regardless of vendor, so providers are swappable without touching the core loop.

roder-ext-openai-responsesWhen configured
InferenceEngine({provider_id})

Generic OpenAI Responses API engine: streams /v1/responses and maps output items and deltas to inference events, including reasoning summaries, hosted web search, and opaque provider compaction items. Reused as the engine for xAI API-key, OpenRouter, Codex OAuth, and custom OpenAI-compatible providers. Codex exposes GPT-5.6 Sol/Terra/Luna, defaults to Sol, and maps Roder's Ultra effort to the provider's max reasoning value.

roder-ext-openai-chat-completionsOpt-in
InferenceEngine(openai-chat-completions)

Streams the classic OpenAI Chat Completions API (/v1/chat/completions) through a shared stream_chat_completions helper. Not wired into the default host; mainly consumed as a library by other providers such as Xiaomi MiMo.

roder-ext-anthropicWhen configured
InferenceEngine(anthropic)

Maps harness turns to Anthropic Messages API request bodies and streams SSE from api.anthropic.com, translating tool_use content blocks into harness tool-call events. Local context summaries are sent as post-compaction input while older pre-summary history is dropped from the active request. Resolves the API key at call time from config or environment.

roder-ext-geminiWhen configured
InferenceEngine(gemini)

Adapts harness turns to the Google Gemini generateContent streaming API with text and tool-call support.

roder-ext-vertexWhen configured
InferenceEngine(vertex)

Runs Gemini models on Vertex AI using service-account OAuth (credentials path or inline JSON) with project and location configuration.

roder-ext-xaiDefault · SuperGrok
InferenceEngine(supergrok)InferenceEngine(xai)

Always registers the SuperGrok OAuth engine; when an xAI API key is declared it additionally installs a direct xAI surface built on the OpenAI Responses engine pointed at api.x.ai/v1. Both catalogs default to grok-4.5 with 500k context and high reasoning.

roder-ext-claude-codeDefault
InferenceEngine(claude-code)

Spawns and manages the Claude Code CLI through the claude-agent-sdk, streaming SDK events into harness inference events. Reuses the CLI session by default so conversation history stays on the Claude Code side. When a paired Claude-in-Chrome extension is detected, it can authorize the CLI's native browser tools and render their activity as hosted tool calls in Roder.

roder-ext-cursorDefault
InferenceEngine(cursor)

Talks directly to Cursor's AgentService backend APIs for Composer-style agent turns, including fast model variants, Claude Fable 5, reasoning parameters, and stable per-thread conversation ids. Live turns require a Cursor User API key.

roder-ext-kimi-codeDefault · OAuth or key
InferenceEngine(kimi-code)

Kimi Code provider for Kimi subscription OAuth or API-key auth. The CLI can save keys with roder auth login kimi-code --api-key, and app-server auth status reports configured API-key state.

roder-ext-fireworksDefault · needs key
InferenceEngine(fireworks)

First-party Fireworks AI provider using account-scoped model ids, offline catalog metadata, model discovery, and the OpenAI-compatible Responses transport.

roder-ext-openrouterDefault · needs key
InferenceEngine(openrouter)

OpenRouter API-key provider built on the OpenAI Responses engine, with optional HTTP-Referer and X-Title attribution headers.

roder-ext-opencodeDefault
InferenceEngine(opencode)InferenceEngine(opencode-go)

Two OpenCode subscription providers (Zen and Go) speaking a chat-completions-style HTTP API at opencode.ai, with cached model lists and retry policy.

roder-ext-poolsideDefault
InferenceEngine(poolside)

Poolside Laguna API-key provider using chat completions at inference.poolside.ai/v1 with cached /models discovery.

roder-ext-roder-cloudDefault · needs key
InferenceEngine(roder-cloud)

Hosted roder.cloud inference: prunes requests down to a documented Responses-API subset, exchanges a roder_ API key for short-lived JWTs, and parses edge Responses payloads. Hosted tools are intentionally omitted.

roder-ext-xiaomi-mimoDefault
InferenceEngine(xiaomi-mimo)InferenceEngine(xiaomi-mimo-token-plan)SpeechSynthesizer(xiaomi-mimo)SpeechSynthesizer(xiaomi-mimo-token-plan)

Xiaomi MiMo in both pay-as-you-go and Token Plan billing modes via OpenAI-compatible chat completions, plus matching text-to-speech synthesizer surfaces.

roder-ext-inference-routerDefault · off until configured
InferenceRouter(local)

Local policy router for adaptive model selection: when [inference_router] is enabled it scores turn signals and picks a tiered provider, model, and reasoning level from config before each turn.

Speech and transcription

Speech extensions install SpeechTranscriber (audio in) or SpeechSynthesizer (audio out) services used by voice-capable clients.

roder-ext-openai-speechDefault · needs key
SpeechTranscriber(openai-speech)

Posts captured audio to OpenAI transcription endpoints (Whisper-class models) and returns normalized transcripts with metadata.

roder-ext-google-speechDefault · needs credentials
SpeechTranscriber(google-speech)

Google Cloud Speech-to-Text client supporting OAuth access tokens, API keys, or Application Default Credentials, with project and location awareness.

Embeddings

Embedding extensions install an EmbeddingProvider used by the memory system for vector recall. The active provider is selected by memory configuration.

roder-ext-openai-embeddingsDefault · needs key
EmbeddingProvider(openai)

Calls the OpenAI embeddings API (text-embedding-3 family). The default embedding provider for the SQLite memory store when an OpenAI key is present.

roder-ext-google-embeddingsDefault · needs key
EmbeddingProvider(google)

Gemini Embedding 2 via the Generative Language API, with separate query and document input modes for retrieval.

roder-ext-zeroentropy-embeddingsDefault · needs key
EmbeddingProvider(zeroentropy)

ZeroEntropy zembed-1 embeddings with configurable encoding format and latency tier, and query/document retrieval intent.

Memory and knowledge

Memory extensions bundle three services: a MemoryStore for persistence, a ContextProvider that injects recalled records into turns, and a ToolProvider with memory CRUD and search tools. Only one memory backend is active at a time, chosen by RODER_MEMORY_BACKEND.

roder-ext-memoryDefault backend
MemoryStore(sqlite-memory)ContextProvider(memory-context)ToolProvider(memory-tools)

SQLite-backed project and global memory under {roder_home}/memory, with an optional embedding provider for vector recall. The default memory backend.

roder-ext-honchoConfig-selected
MemoryStore(honcho-memory)ContextProvider(memory-context)ToolProvider(memory-tools)

Remote Honcho workspace backend: a REST client maps memory scopes to Honcho sessions and peers, and semantic search is delegated to Honcho's hosted retrieval instead of local vectors.

roder-ext-knowledge-mdWhen enabled
KnowledgeStore(markdown-knowledge)ToolProvider(knowledge-tools)ContextProvider(knowledge-context)

Project knowledge base stored as Markdown files with YAML front matter under {roder_home}/knowledge. Exposes knowledge_* tools and, when recall is enabled, injects matching documents into context (default limit four).

Session and thread persistence

Thread stores persist sessions, turn items, and events so resumes, forks, replays, and evals all read the same durable record.

roder-ext-jsonl-thread-storeDefault
ThreadStore(jsonl-thread-store)

Append-only JSONL event logs per thread under {roder_home}/threads/{thread_id}/, with a thread-index.json for listing, plus archive and restore support. The runtime keeps compaction boundaries and redacted lifecycle extension records so resumes can continue from compact state and flag interrupted turns that need recovery. The default store.

roder-ext-postgres-sessionWhen configured
ThreadStore(postgres-session)

Tenant-scoped PostgreSQL persistence for threads, context artifacts, and lifecycle extension state over async SQL, configured with a database_url. Built for multi-tenant hosted deployments.

Web search uses a canonical router plus optional provider-specific tools. The router exposes one unified web_search tool; namespaced mode installs the per-provider tools directly.

roder-ext-web-searchWhen enabled
ToolProvider(web-search)

The canonical web_search router: delegates each query to the configured backend (Firecrawl, Perplexity, Tavily, or Parallel) and normalizes results into one response shape.

roder-ext-firecrawl-searchRouter backend
ToolProvider(firecrawl-search)

Firecrawl search API client exposing namespaced search and retrieval tools; also serves as a router backend.

roder-ext-perplexity-searchRouter backend
ToolProvider(perplexity-search)

Perplexity raw Search API tools with request-id metadata extraction.

roder-ext-tavily-searchRouter backend
ToolProvider(tavily-search)

Tavily search API adapter exposing Tavily-backed search tools.

roder-ext-parallel-searchRouter backend
ToolProvider(parallel-search)

Parallel.ai objective-oriented search with extended tool-argument options for goal-directed queries.

Tools, browser, VCS, and language

ToolProvider extensions add callable tools to the registry; the policy layer governs every invocation. This group also covers version control and workspace fork providers.

roder-ext-chromeDefault
ToolProvider(chrome)

Registers chrome_* tools bound to the Roder browser-extension bridge, letting the agent inspect, control, debug, and record the user's live Chrome session.

roder-ext-webwrightDefault
TaskExecutor(webwright.browser_task)ToolProvider(webwright)

Playwright-based browser automation: a background webwright.browser_task executor plus helper tools. Runs a shell preflight for Playwright dependencies and writes artifacts under Roder home.

roder-ext-mcpOpt-in
ToolProvider(mcp-tools)

Connects to configured MCP servers over streamable HTTP, registers their tools, and forwards optional per-thread bearer identity. Offline servers warn in discover mode or fail startup in discover_required mode.

roder-ext-gitDefault
VersionControlProvider(git)ForkProvider(git-worktree)

Shells out to git for status, diffs, snapshots, and line metadata, and creates linked git worktrees for workspace forks.

roder-ext-fork-riftDefault · needs binary
ForkProvider(rift)

Copy-on-write workspace snapshots by shelling out to a configured rift binary (APFS clonefile, btrfs snapshots, reflinks) behind a narrow CLI adapter with typed errors, since the rift CLI is pre-1.0.

roder-ext-zerolangDefault · needs binary
ToolProvider(zerolang)

Invokes the configured zero compiler binary for diagnostics, graph inspection, validation, fix plans, and checked ProgramGraph edits (zerolang_edit, zerolang_check, and friends).

roder-ext-task-ledgerDefault
ToolProvider(task-ledger)

An in-process task_ledger.update tool that maintains a validated task snapshot — pending, in_progress, completed, blocked — with optional evidence per item.

roder-ext-verificationDefault
ToolProvider(verification)

A verification_review gate tool for eval and non-interactive coding turns: the model submits structured completion evidence, and status, gap, and skip-reason rules are validated server-side.

Policy

PolicyContributor extensions participate in tool-call review alongside the core permission system.

roder-ext-plan-modeDefault
PolicyContributor(plan-mode)ToolProvider(plan-mode-tools)

Installs the plan-mode policy contributor plus the exit_plan_mode tool the model calls to leave planning and begin execution.

Task executors and subagents

TaskExecutor extensions run background work outside the main turn; the SubagentDispatcher runs nested agents with their own budgets and tool registries.

roder-ext-task-processDefault
TaskExecutor(process)

Spawns background shell processes in the workspace (via the unix-local runner when remote), streaming stdout and stderr and tracking a process descriptor for stop and resume.

roder-ext-task-subagentOpt-in
TaskExecutor(subagent)

Background subagent tasks: deserializes task input and delegates to the first registered SubagentDispatcher, so it requires the subagents extension to be installed first.

roder-ext-subagentsWhen enabled
SubagentDispatcher(in-process-subagents)ToolProvider(roder-subagents-task)ToolProvider(agent_swarm)

An in-process dispatcher for child turns against the parent tool registry. Exposes task, bounded agent_swarm fanout, and Codex V2-style agent-control lifecycles with canonical paths, context forks, follow-up turns, mailbox-aware waiting, non-destructive interruption, and role/lane validation before child work starts.

Notifications

NotificationSink extensions deliver turn and task lifecycle events (NeedsInput, TurnIdle, TaskCompleted, TaskFailed) to the user.

roder-ext-notify-terminalDefault
NotificationSink(terminal-bell)

Writes an ASCII bell to stderr for selected notification kinds, throttled to once every two seconds.

roder-ext-notify-desktopWhen enabled
NotificationSink(desktop)

Best-effort native OS notifications via notify-rust when the desktop feature is enabled.

Remote runners

RemoteRunnerProvider extensions execute workspace commands and file I/O behind one common protocol covering files, commands, ports, snapshots, mounts, artifacts, and provider state. Most hosted runners share a single HTTP client from roder-ext-runner-hosted-common.

roder-ext-runner-unix-localDefault
RemoteRunnerProvider(unix-local)

Runs commands and file I/O directly against a canonical local workspace root with path-escape guards. No snapshot support.

roder-ext-runner-dockerDefault · needs Docker
RemoteRunnerProvider(docker)

Starts a long-lived container with the workspace bind-mounted; commands and file ops run through docker exec, and snapshots use docker export.

roder-ext-runner-spritesDefault · needs token
RemoteRunnerProvider(sprites)

Fly Sprites sandboxes over HTTP and WebSocket: creates and restores sprites, applies policies, materializes runner manifests, and can deploy a managed remote app-server.

roder-ext-runner-blaxelDefault · needs API key and workspace
RemoteRunnerProvider(blaxel)

First-party Blaxel Sandboxes provider over the control-plane plus per-sandbox process, filesystem, and preview APIs. It lazily initializes runner-bound threads on first approved workspace tool, routes coding tools into the selected sandbox, supports pause/resume plus durable detach/rejoin, and force-kills remote process groups on cancellation.

roder-ext-runner-cloudflareDefault · needs token
RemoteRunnerProvider(cloudflare)

Hosted Cloudflare runner via the shared hosted-runner REST client.

roder-ext-runner-daytonaDefault · needs key
RemoteRunnerProvider(daytona)

Hosted Daytona runner via the shared hosted-runner REST client.

roder-ext-runner-e2bDefault · needs key
RemoteRunnerProvider(e2b)

Hosted E2B runner via the shared hosted-runner REST client.

roder-ext-runner-modalDefault · needs token
RemoteRunnerProvider(modal)

Hosted Modal runner via the shared hosted-runner REST client.

roder-ext-runner-runloopDefault · needs key
RemoteRunnerProvider(runloop)

Hosted Runloop runner via the shared hosted-runner REST client.

roder-ext-runner-vercelDefault · needs token
RemoteRunnerProvider(vercel)

Hosted Vercel runner via the shared hosted-runner REST client.

Infrastructure and support crates

These crates round out the extension system: one bridges out-of-process extensions, the others are libraries without runtime manifests of their own.

roder-ext-process-hostPer config entry
Dynamic: bridges any child-declared service

Spawns child processes declared in [[process_extensions]] config and speaks newline-delimited JSON-RPC over stdio, bridging the child's declared services (inference engines, event sinks, dispatchers, task executors) into the registry. This is how extensions written in any language plug in.

roder-ext-runner-hosted-commonLibrary
Support library (no manifest)

The shared HTTP client implementing the hosted-runner session protocol (sessions, commands, files) used by the Cloudflare, Daytona, E2B, Modal, Runloop, and Vercel runner crates. Hosted runner commands can carry cancellation leases; Blaxel uses its provider-specific sandbox APIs.

roder-ext-disk-contextNot installable yet
Helper only (extension not yet implemented)

Exports a saved_context_block helper for building disk-sourced context blocks. Distribution metadata references a DiskContextExtension that is not implemented yet, so there is currently no runtime install path.

How an extension plugs in

Regardless of category, every extension follows the same lifecycle:

  • Manifest. The crate implements RoderExtension and returns anExtensionManifest describing itself and the sensitive capabilities it needs (network hosts, secrets, filesystem scopes, process spawning).
  • Install. The extension host calls install, and the extension registers its services — an inference engine, tool provider, store, runner, sink, or any combination — into the typed registry.
  • Gating. build_default_registry installs the stock set, but config and credentials gate conditional extensions: missing API keys suppress provider surfaces, RODER_MEMORY_BACKEND selects one memory store, web search and subagents appear only when enabled.
  • Use. The turn engine, tool policy, and task system resolve services from the registry at runtime — never from the crates directly — so any service can be replaced by an alternative implementation, including one running out-of-process viaroder-ext-process-host.

For the service-type taxonomy and how to write your own extension, see theextension model documentation.