Skip to content

Agent Runtime

Architecture & Code

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:

  • cwd
  • systemPrompt
  • model
  • sessionId
  • permissionMode
  • allowedTools
  • env
  • mcpServers
  • userManagementUrl
  • projectPath
  • channelsMessageHandler
  • additionalSkillPaths

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

RuntimeLocationResponsibility
Claude Codepackages/agent/src/runtimes/claude-code-runtime.tsWrap Claude Code SDK sessions and stream SDK messages
Pi Agentpackages/agent/src/runtimes/pi-agent-runtime.tsRun Pi coding agent sessions and normalize events
Runtime factorypackages/agent/src/runtimes/factory.tsChoose the runtime by configured adapter/runtime key
Event normalizerpackages/agent/src/runtimes/event-normalizer.tsNormalize 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 typeGoes inReason
env, cwd, command, args, modeladapter_configProcess-spawn and adapter inputs
instructionsBundleMode, instructionsRootPath, instructionsEntryFileadapter_configAdapter discovery logic
adapter-specific knobsadapter_configUsed by adapter execution
heartbeat enabled, intervalSec, wakeOnDemand, maxConcurrentRunsruntime_configScheduler policy
session compaction policyruntime_configSession 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:

  1. Agent-scoped env: stored on the agent.
  2. 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=value
KEY={ 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_TOKEN

The 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_URL
  • LIFEOSAI_RUN_TOKEN
  • LIFEOSAI_RUN_ID
  • LIFEOSAI_AGENT_ID
  • LIFEOSAI_COMPANY_ID
  • LIFEOSAI_WAKE_REASON
  • LIFEOSAI_WAKE_SOURCE
  • LIFEOSAI_TASK_ID or issue id when applicable
  • LIFEOSAI_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.