Agent Runtime
Agent Runtime
The harness between orchestration and the agent engine — runtime interface, invoker, adapter vs runtime config, env layers, and run-scoped authentication.
Runtime interface, invoker, env layers, and run-scoped auth. Use the Full screen button above, or open the agent runtime diagram in a new tab ↗.
The harness between orchestration and the actual agent engine.
Harness And Agent Runtime
The harness is the runtime boundary between LifeOSAI orchestration and the actual agent engine.
Runtime Interface
packages/agent/src/runtimes/types.ts defines the runtime contract:
AgentRuntime sessionId stream(prompt) sendMessage(content) interrupt() respondToPermission(toolUseId, response) close()Runtime options include:
cwdsystemPromptmodelsessionIdpermissionModeallowedToolsenvmcpServersuserManagementUrlprojectPathchannelsMessageHandleradditionalSkillPaths
The rest of the application should not need to know if the underlying runtime is Claude Code or Pi Agent. It should consume normalized stream events.
Supported Runtimes
| Runtime | Location | Responsibility |
|---|---|---|
| Claude Code | packages/agent/src/runtimes/claude-code-runtime.ts | Wrap Claude Code SDK sessions and stream SDK messages |
| Pi Agent | packages/agent/src/runtimes/pi-agent-runtime.ts | Run Pi coding agent sessions and normalize events |
| Runtime factory | packages/agent/src/runtimes/factory.ts | Choose the runtime by configured adapter/runtime key |
| Event normalizer | packages/agent/src/runtimes/event-normalizer.ts | Normalize events for frontend and orchestration consumers |
Agent Invoker
apps/api/src/orchestration/engine/agent-invoker.ts is the bridge from a
heartbeat run to a runtime process.
It is responsible for:
- resolving adapter type and model
- resolving instructions files and skill paths
- resolving the company, agent, and project cwd
- loading agent env and project env
- resolving company secret refs
- merging runtime env
- minting the run-scoped bearer token
- injecting
LIFEOSAI_*wake context - attaching the channels MCP server
- starting Claude Code or Pi Agent
- redacting secrets from logs
- publishing run log events
- returning session id, usage, result, and error state
Adapter Config Versus Runtime Config
Do not collapse these into one blob. They have different readers and different validation paths.
| Field type | Goes in | Reason |
|---|---|---|
| env, cwd, command, args, model | adapter_config | Process-spawn and adapter inputs |
| instructionsBundleMode, instructionsRootPath, instructionsEntryFile | adapter_config | Adapter discovery logic |
| adapter-specific knobs | adapter_config | Used by adapter execution |
| heartbeat enabled, intervalSec, wakeOnDemand, maxConcurrentRuns | runtime_config | Scheduler policy |
| session compaction policy | runtime_config | Session rotation policy |
Defaults should be applied at agent creation time. PATCH should merge only what the caller sends, so partial updates do not resurrect old defaults.
Runtime Env
LifeOSAI supports two env layers:
- Agent-scoped env: stored on the agent.
- Project-scoped env: stored on the project.
Project env overrides agent env on key collisions. This lets an operator define common runtime keys once at the agent level, then override them for one project.
Env values use the shared binding schema in
packages/shared/src/orchestration/env-config.ts:
KEY=valueKEY={ type: "plain", value: "value" }KEY={ type: "secret_ref", ref: "company-secret-name" }Validation rules:
- key must match
^[A-Za-z_][A-Za-z0-9_]*$ - plaintext sensitive keys can be rejected in strict mode
***REDACTED***cannot be written back as a value- secret refs must belong to the same company
- secret-backed keys are marked for log redaction
Run-Scoped API Authentication
Agent-exposed APIs are protected by a run-scoped bearer token:
Authorization: Bearer $LIFEOSAI_RUN_TOKENThe token binds the request to:
- company id
- agent id
- run id
This is stronger than trusting user-provided headers such as
X-LIFEOSAI-AGENT-ID. Headers can still be useful for diagnostics or backward
compatibility, but they should not be the security boundary.
Runtime Environment Variables
The invoker injects wake and execution context as environment variables. Common values include:
LIFEOSAI_API_URLLIFEOSAI_RUN_TOKENLIFEOSAI_RUN_IDLIFEOSAI_AGENT_IDLIFEOSAI_COMPANY_IDLIFEOSAI_WAKE_REASONLIFEOSAI_WAKE_SOURCELIFEOSAI_TASK_IDor issue id when applicableLIFEOSAI_TIMEZONE- channel-specific values when the wake source is a channel
Timer wakes do not always include an issue id. In that case the agent should follow its heartbeat or inbox instructions and inspect available work.