Skip to main content
A custom runtime server is for agents where your runtime code owns the agent loop. Dari still hosts the session, provisions the sandbox, passes in each user message, records assistant events, and persists state. Your code decides how to call models, which SDKs to use, what memory to keep, and what response to return. Use a custom runtime server when you are integrating another agent runtime, such as Claude Agent SDK, or when the agent behavior cannot be described as a standard Dari-managed model/tool loop.
dari.yml
name: claude-sdk-runtime
harness:
  kind: customRuntimeServer
  protocol: dari-runtime-v1
  customRuntimeServer:
    command: sh -c 'uvicorn custom_runtime_server:app --host 0.0.0.0 --port "${PORT:-8787}"'
    port: 8787
    health_path: /health
    advance_path: /runtime/advance
instructions:
  system: prompts/system.md
sandbox:
  provider: e2b
  internet_access: true
  secrets:
    - ANTHROPIC_API_KEY
  setup:
    script: setup.sh
The custom runtime server mode is kind: customRuntimeServer. It runs an HTTP server inside the session sandbox. Dari starts the server, checks its health endpoint, and calls its advance endpoint when a message needs a response. Your server process should listen on the PORT environment variable that Dari provides; customRuntimeServer.port tells Dari which sandbox port to expose for hosted sandboxes.

What Your Code Owns

Your runtime receives the latest input and the state returned from the previous turn. For the common case, return assistant text and JSON state:
{
  "text": "I inspected the repository and found a Vite frontend.",
  "state": {"thread_id": "abc123"}
}
Dari records text as an assistant message, saves state, and waits for the next user message. If a response omits state, Dari keeps the previous state unchanged. Return "state": null only when you want to clear saved state. If you need more control, the response can return explicit events and action fields, but most custom runtimes should start with text and state. llm is optional for a custom runtime server. Omit it when your runtime calls its own model provider or SDK. Use sandbox.secrets to expose provider credentials to your runtime process.

When To Use It

Use a custom runtime server when you need to bring your own model SDK, preserve provider-specific conversation state, run a custom planner, integrate an existing agent framework, or emit events that the managed Pi runtime does not produce. Do not use a custom runtime server just to change the system prompt, choose a model, or enable built-in file and shell tools. Those are managed Pi runtime use cases. Keep customRuntimeServer.command fast. Install dependencies with sandbox.setup or a Dockerfile, then use command only to start the server.

Complete Example

See Claude Agent SDK Example for a custom runtime server that resumes Claude SDK memory across Dari turns.