Skip to main content

Runtime

The EstaCoda runtime is the execution environment that owns session execution. It loads one selected profile, builds shared runtime substrate, assembles session-bound components, executes provider and tool work under policy, and persists the resulting state.

This page explains how runtime creation works, what is reused, what is rebuilt per session, and where failures usually happen.


What the runtime is

A runtime combines shared substrate with session-bound execution components.

AreaExamples
Profile stateConfig, credentials, memory files, skills, gateway state
Provider substrateProvider registry, provider executor, primary route, fallback routes, auxiliary routes
Tool substrateBuilt-in tool providers, MCP-discovered tools, process manager, browser backend
Memory substrateMemory store, memory provider, memory index, retrieval service, prompt context builder
Session-bound componentsTool registry, tool executor, tool planner, provider turn loop, runtime router, agent loop
PersistenceSession DB, artifacts, trajectory, cron, workflow state where available
PolicySecurity mode, trust store, approval control, child fail-closed policy

Runtime config loads from exactly one selected profile. Workspace trust gates local action behavior and may affect trusted runtime capabilities such as MCP startup, but it does not change which profile config is loaded.


Profile selection

Runtime config loads from one profile, in this order:

  1. Explicit profileId passed to the command
  2. Active profile if no explicit profile ID is given
  3. default if no active profile is set

There is no user/project config merge. Profile state lives under:

~/.estacoda/profiles/<id>/

Sessions are scoped by profile_id in the session database. createRuntime() rejects an existing session if that session belongs to a different profile than the runtime being created.

See Architecture for the full state boundary map.


Runtime construction

Runtime construction has three practical phases.

Phase A: shared substrate

createRuntime() builds the shared substrate for the selected profile and session.

It creates or resolves:

SubstrateExamples
State pathsGlobal state home, profile state home, workspace root
StoresMemory store, artifact store, cron store, session DB
Memory infrastructureMemory index store, memory index sync, local memory retrieval, memory prompt context
Provider infrastructureProvider registry, provider executor, primary route, fallback routes, auxiliary routes
Skill infrastructureOfficial skills, profile skills, pack-materialized skills, skill evolution stores
MCP infrastructureConfigured MCP servers and discovered MCP tools, gated by trusted runtime capability state
Process and media stateProcess manager, channel media root, audio cache, image cache
Browser infrastructureBrowser backend, supervised local CDP lifecycle, emergency cleanup
Voice infrastructureLocal Whisper worker when configured
Prompt infrastructureProject context loader, context reference expander, session compression service
Delegation substrateFileStateTracker, parent routes, shared provider/tool substrate
TrajectoryTrajectoryRecorder for the active session

Approval control is injected into runtime creation and used by runtime methods that grant, inspect, or revoke approvals.

Phase B: session-bound components

AgentLoopBuilder.buildSession() assembles the session-bound execution components.

It creates:

ComponentRole
ToolRegistrySession-visible tool registry
ToolExecutorExecutes tool actions under security policy
ToolCallPlannerMaps provider tool calls to executable tool plans
RunRecorderRecords turn/tool/session events and trajectory data
MemoryRecallOrchestratorPrepares per-turn recall context
ToolPlanRunnerRuns planned tools, handles concurrency, failure caps, and continuation packets
ProviderTurnLoopRuns provider iterations and finalizes provider output
SkillPlaybookRunnerExecutes skill playbook tool steps
NativeToolExecutorExecutes native runtime intents
IntentRouterRoutes user intent to runtime paths and skills
RuntimeRouterSelects native, skill, or provider-backed execution
AgentLoopCoordinates the turn boundary and persistence

Tool registration happens in phases so tools receive the right runtime and session context:

  1. pre-skill-visibility
  2. post-skill-visibility
  3. post-memory-provider
  4. post-tool-executor

MCP-discovered tools are added to the session-visible tool registry during session construction, alongside built-in tool registration phases.

Phase C: workflow wiring

After AgentLoopBuilder.buildSession() returns, createRuntime() wires workflow support when the session DB is SQLiteSessionDB.

Workflow wiring includes:

ComponentRole
SQLiteWorkflowStorePersists workflow runs, steps, events, locks, and artifacts
WorkflowLockServiceCoordinates workflow locks
WorkflowEngineExecutes workflow plans
WorkflowProcessRegistryTracks workflow-related processes
WorkflowEventSummaryServiceCompacts workflow event history
WorkflowCommandDispatcherHandles workflow commands
WorkflowAgentLoopAdapterRoutes active workflow turns through the agent loop
WorkflowRestartRecoveryMarks interrupted runs and recovers stale locks

Workflow wiring is best effort. If workflow setup fails, runtime creation can continue without workflow support, and workflow-specific commands should report the missing capability.


Provider route resolution

The runtime resolves three kinds of provider routes.

Primary route

The primary route comes from model in profile config. It is used for normal inference.

If the primary route is not runnable because credentials are missing, the model is stale, or the provider fails, EstaCoda reports the failure. It does not silently fall back unless fallback routes are configured.

Fallback routes

Fallback routes come from model.fallbacks. They are tried only when the primary route fails at execution time.

Fallbacks preserve route metadata such as:

MetadataUse
apiKeyEnvCredential environment variable
baseUrlProvider endpoint
apiModeAdapter mode, such as OpenAI-compatible or OpenAI Responses
authMethodCredential/auth mode

If all fallback routes fail, the turn reports the error and stops.

Auxiliary routes

Auxiliary routes are specialized model routes configured under auxiliaryModels. They use the same provider registry and executor path as primary routes.

SlotPurpose
visionImage analysis
compressionSemantic session compression
assessorSmart approval classification
web_extractWeb extraction
session_searchSemantic session search
mcpMCP tool delegation
memory_flushMemory operations
delegationSubagent delegation
skills_librarySkills distribution
title_generationSession title generation
curatorMemory curation
memory_compactionMemory file compaction
profile_contextProfile context generation

Unsupported auxiliary task names fail during config normalization.


Provider execution boundary

ProviderTurnLoop treats provider output as usable only after finalization. Streaming can emit live visible tokens, but these surfaces use finalized visible output only:

SurfaceUses finalized output
Executable tool callsYes
Persisted assistant contentYes
Provider-bound historyYes
Summaries and compressionYes
Memory inputsYes
Skill learningYes
ExportsYes

Stream safety rules:

  • Streamed tool-call fragments are collected while the stream is open.
  • Stream errors discard collected fragments.
  • Incomplete streams remain provider failures.
  • [DONE] is an internal transport marker, not user-visible output.
  • Visible-only transport completion may finalize as finishReason: "unknown".
  • Transport completion with unfinished tool fragments fails as incomplete-stream.
  • OpenAI-compatible chat completions support streaming.
  • OpenAI Responses execution is implemented. Responses streaming is not part of the current supported runtime baseline.

ProviderExecutionResult.toolCalls is canonical. Length-truncated tool calls retry once on the successful route chain. If the retry is still length-truncated, the runtime returns deterministic refusal text and executes no tools.

Reasoning is hidden material. Raw reasoning is turn-local only. Visible output, provider-bound history, semantic compression, summaries, memory, skill learning, and exports strip raw reasoning and inline hidden reasoning blocks.

Visible text with finishReason: "length" can continue on the successful route chain. Synthetic continuation messages are local-only. Intermediate partials are not persisted. Final visible text is persisted once. Continuation uses exact overlap trimming.


Tool boundary

The provider does not know how to execute tools. The tool executor does not know how to call providers. The agent loop bridges the two.

ComponentResponsibility
ProviderReturns visible text and finalized tool calls
ToolCallPlannerResolves provider tool calls to known tool definitions
ToolExecutorExecutes concrete tool actions under policy
ToolPlanRunnerRuns tool plans and builds continuation packets
ProviderTurnLoopFeeds tool results back to the provider when needed
AgentLoopCoordinates the overall turn boundary

Tool risk classes drive gating:

Risk classMeaning
safeLow-risk read or local computation
cautionNeeds care or may expose local state
external-side-effectCan affect external systems
irreversibleCan make hard-to-reverse changes

The security policy gates on normalized targetKey, not display summary.


CLI runtime lifecycle

In CLI interactive mode, the runtime persists across turns in the active session. This avoids rebuilding the full runtime after every message and keeps session-bound state available in memory.

A CLI runtime is disposed when the session exits or the process shuts down. Disposal stops runtime-owned resources such as MCP servers, browser lifecycle resources, local Whisper workers, memory index sync, and session DB connections when the runtime owns them.


Gateway runtime lifecycle

Gateway mode uses RuntimeCache.

A gateway runtime is not created fresh for every incoming turn. The gateway asks the cache for a runtime keyed by sessionId and the current runtime fingerprint.

Cache caseBehavior
No entryCreate runtime
Cache hitReuse runtime
Fingerprint mismatchCreate replacement runtime and retire the old entry
Suspended entryCreate replacement runtime
Explicit invalidationSuspend and replace on next use
Idle TTL exceededDispose idle runtime
LRU cap exceededDispose least-recent idle runtimes

Current implementation defaults:

SettingDefault
Max cached runtimes50
Idle TTL30 minutes
Dispose timeout10 seconds

These are implementation defaults, not public API guarantees. Inspect RuntimeCache for current values.

The gateway invalidates cached runtimes when policy-affecting state changes, such as persistent approval grant/revoke or session model override changes.

Runtime cache entries are keyed by sessionId. Session rows are scoped by profile_id, and createRuntime() rejects profile/session mismatches. Runtime cache documentation should still treat session identity as a sensitive boundary.


Delegation runtime

delegate_task builds child agent loops through DefaultChildAgentLoopFactory, which uses the shared AgentLoopBuilder.

Parent-owned substrate is reused:

Reused from parentExamples
Provider substrateProvider registry, provider executor, routes
StoresSession DB, memory provider, artifact store
Runtime substrateProcess manager, browser backend, trust store
MCP substrateMCP tool registrations
Delegation stateSubagentRegistry, FileStateTracker

Session-bound child components are fresh per child session. Child sessions have their own tool registry, tool executor, provider turn loop, runtime router, and agent loop.

Child sessions are persisted with parent session ID, role/depth, effective tool access, stripped or blocked diagnostics, model override metadata where present, and runtime suppression metadata.

Child tool access is resolved before provider schemas are built. The default child profile keeps parent-visible read-only-local and read-only-network tools only, strips exact/prefix blocked tools, and excludes browser, media, and MCP toolsets. terminal.run remains excluded.

Child approvals are non-interactive and fail closed. Hardline denies run first. Any action that would ask, use parent grants, use pending approval queues, or depend on persisted/session approvals is denied in the child runtime.

File-state tracking snapshots parent reads before delegation and emits advisory stale-file warnings when tracked child writes touch those paths. Outcome memory is opt-in and stores bounded task preview plus deterministic status/reason metadata.


Memory prompt assembly

Per-turn memory context is prepared before provider prompt assembly. MemoryRecallOrchestrator gathers recall context, and MemoryPromptContextBuilder renders the canonical memory prompt context.

The prompt assembly pipeline includes:

  1. Canonical memory prompt context
  2. Project context, including AGENTS.md
  3. Optional compaction notice
  4. Session history
  5. Optional session recall and external recall
  6. Live user message
  7. Channel attachments
  8. Intent, skill instructions, skill setup, and skill resources
  9. Workflow plan
  10. Tool menu
  11. Explicit reference context
  12. Tool results or continuation feedback

Recall, external recall, and compression summaries are reference-only context. They are included for continuity but are not treated as authoritative instructions.

Provider-turn semantic compression is owned by AgentLoop, not ProviderTurnLoop. When enabled and over threshold, AgentLoop preserves the parent transcript by compacting into a child session before provider prompt assembly.


Runtime disposal

Runtime disposal is responsible for cleaning up resources owned by the runtime.

Disposal includes:

ResourceCleanup
Browser lifecycleStop lifecycle, cleanup sessions, close owned backend
Local WhisperDispose worker when present
MCP serversStop loaded MCP servers
Memory index syncDispose sync worker
Session DBClose when runtime owns the connection

Gateway cached runtimes are disposed through RuntimeCache.safeDispose(), which applies a timeout so stuck disposal does not block cache cleanup forever.


Runtime startup failures

FailureWhat happensFirst inspection command
Missing profile configRuntime creation fails earlyestacoda verify
Profile/session mismatchRuntime creation rejects the sessionestacoda sessions list
Non-runnable primary routeTurn reports provider/model failureestacoda model diagnose
Missing auxiliary routeCalling subsystem falls back where supportedestacoda model show
MCP server unreachableMCP tools are not registered; runtime continuesestacoda gateway diagnose
Browser backend unavailableBrowser tools report connection errorsestacoda doctor
SQLite lock or corruptionSession or workflow operations failCheck ~/.estacoda/sessions.sqlite permissions
Workflow wiring unavailableRuntime continues without workflow supportWorkflow-related commands and runtime logs

How to inspect runtime state

# Current primary route and readiness
estacoda model show

# Live diagnostic against configured provider
estacoda model diagnose

# List catalog-known providers
estacoda model list

# Full setup readiness
estacoda verify

# General diagnosis
estacoda doctor

# Gateway readiness
estacoda gateway diagnose

# Full gateway status, including runtime cache state when available
estacoda gateway status

# Recent sessions
estacoda sessions list

# Current session
estacoda sessions current

# Code dependency graph
estacoda knowledge code summary
estacoda knowledge code refresh