dari.yml:
llm.base_url or llm.api_key_secret. Models starting with openai/, such
as model: openai/gpt-4.1-mini, use Dari-managed OpenAI by default. Models
starting with anthropic/, such as model: anthropic/claude-sonnet-4.6, use
Dari-managed Anthropic by default. Everything else uses Dari-managed OpenRouter.
Set llm.api_key_secret when you want to bring your own provider key, and set
llm.base_url only for a custom OpenAI-compatible endpoint.
Top-Level Fields
| Field | Required | Details |
|---|---|---|
name | yes | Agent display name. |
harness | yes | Runtime contract with kind and protocol. See Runtime Modes, Managed Pi Runtime, and Custom Runtime Server. |
instructions | yes | System prompt file path. |
sandbox | no | Runtime environment config. See Sandboxes and E2B Sandboxes. |
llm | Required for harness: pi; optional for kind: customRuntimeServer | Model and provider credentials for runtimes that ask Dari to perform model calls. |
built_in_tools | no | Built-in tool selection. See Built-In Tools. |
custom_tools | no | Custom tool declarations. See Dari-Executed Tools and External Tools. |
skills | no | Bundled skills. See Skills. |
extensions | no | Pi extensions. See Pi Extensions. |
harness
Use harness: pi for the managed Pi harness. Use the object form when you configure a custom runtime server:
| Field | Required | Value |
|---|---|---|
kind | yes | pi or customRuntimeServer. |
protocol | Required for object form | dari-runtime-v1. |
customRuntimeServer | Required when kind: customRuntimeServer | Custom runtime server config. See Custom Runtime Server. |
harness.customRuntimeServer
| Field | Required | Value |
|---|---|---|
command | yes | Command that starts your HTTP runtime server inside the session sandbox. Keep this fast; put dependency installation in sandbox.setup. |
port | yes | Port your server listens on inside the sandbox. |
health_path | no | Health endpoint path. Defaults to /health. |
advance_path | no | Runtime advance endpoint path. Defaults to /runtime/advance. |
instructions
| Field | Required | Value |
|---|---|---|
system | yes | Repo-relative Markdown file path. |
llm
Use llm when the harness asks Dari to perform model calls. For example, the Pi harness requires llm. A customRuntimeServer harness may omit llm if the runtime server calls its own model provider.
You can declare one default model:
| Field | Required | Value |
|---|---|---|
provider | no | openrouter, openai, or anthropic. If omitted, Dari infers OpenAI/Anthropic from model prefixes and otherwise uses OpenRouter. |
model | yes | Model identifier. Models starting with openai/ use managed OpenAI by default. Models starting with anthropic/ use managed Anthropic by default. Everything else uses managed OpenRouter. |
base_url | no | Custom OpenAI-compatible provider base URL. Omit this for Dari-managed OpenAI, Anthropic, and OpenRouter. |
api_key_secret | no | Stored org credential name. Omit this to use Dari-managed provider credentials. For a custom base_url, omit this only if every session supplies llm_api_key (CLI: --llm-api-key or --llm-api-key-env). |
retry_policy | no | Retry policy object. |
llm.default must reference a key in llm.options. Session creation may pass
llm_id (CLI: dari session create --llm claude) to select an option; omitted
llm_id uses the default.
llm.retry_policy
| Field | Required | Value |
|---|---|---|
maximum_attempts | no | Positive integer. |
initial_interval_seconds | no | Positive integer. |
backoff_coefficient | no | Number >= 1. |
maximum_interval_seconds | no | Positive integer, >= initial_interval_seconds. |
sandbox
| Field | Required | Value |
|---|---|---|
provider | no | e2b or modal. Defaults to e2b. |
provider_api_key_secret | no | Stored org credential name for the sandbox provider. Omit to use Dari-managed provider credentials. For Modal, the stored credential value should be <token_id>:<token_secret> or JSON with token_id and token_secret. |
dockerfile | no | Repo-relative Dockerfile path. Cannot be combined with runtimes, packages, or setup. |
env | no | Map of environment variable names to literal values. |
secrets | no | List of stored org credential names to expose as environment variables. |
resources | no | Resource limits object. |
runtimes | no | Managed runtime versions object. |
packages | no | Managed package install object. |
setup | no | Managed setup object. |
internet_access | no | Boolean. Defaults to false; allows public internet access from execution sandboxes. |
storage_mount_path | no | /workspace. |
storage_binding | no | Storage binding name. |
sandbox.resources
| Field | Required | Value |
|---|---|---|
cpu | no | Positive integer. |
memory_mb | no | Positive integer. |
sandbox.runtimes
| Field | Required | Value |
|---|---|---|
node | no | Version string. |
python | no | Version string. |
go | no | Version string. |
sandbox.packages
| Field | Required | Value |
|---|---|---|
apt | no | List of apt package names. |
sandbox.setup
| Field | Required | Value |
|---|---|---|
script | yes | Repo-relative script path. |
Complete Managed Setup Example
Usesandbox.runtimes, sandbox.packages, and sandbox.setup together when you want Dari to keep managing the base sandbox while you add a few runtime dependencies of your own. The setup.script value is repo-relative in your bundle; at build time, that file is available under /bundle and runs from /bundle as root after the requested apt packages and managed runtimes are installed.
dari.yml
scripts/setup-sandbox.sh
sandbox.dockerfile instead of this managed setup flow only when you need full image control; sandbox.dockerfile cannot be combined with sandbox.runtimes, sandbox.packages, or sandbox.setup.
built_in_tools
List entries are tool names. Valid names: read, bash, edit, write, grep, find, ls.
custom_tools
For TypeScript tools defined as tools/<name>/tool.ts, you do not need to write custom_tools entries by hand. dari deploy infers the tool name from the folder name, reads the exported inputSchema and handler, and adds a custom-tool entry to the uploaded manifest. The schema remains code-first; the CLI does not inline it into dari.yml as input_schema_json.
| Field | Required | Value |
|---|---|---|
name | yes | Tool name exposed to the model. |
path | yes | Repo-relative path under tools/. |
kind | yes | main or external. |
runtime | Required for kind: main unless set in tool.yml | typescript or python. Not allowed for kind: external. |
handler | Required for kind: main unless set in tool.yml | Handler reference, such as handler.py:main or tools/summarize_file.py:main. Not allowed for kind: external. |
description | Required for code-first entries generated by the CLI | Tool description. For directory tools, set this in tool.yml. |
retries | no | Positive integer. kind: main only. Cannot be combined with retry_policy. |
retry_policy | no | Retry policy object. kind: main only. Cannot be combined with retries. |
timeout_seconds | no | Positive integer. |
input_schema_json or output_schema_json in dari.yml. Code-first TypeScript tools export schemas from code. Directory tools use tools/<name>/tool.yml schema file references.
tools/<name>/tool.yml
| Field | Required | Value |
|---|---|---|
name | yes | Tool source name. |
description | yes | Tool description. |
input_schema | yes | Path to a JSON schema file inside the tool directory. |
output_schema | no | Path to a JSON schema file inside the tool directory. |
runtime | Required for kind: main unless set in dari.yml | typescript or python. |
handler | Required for kind: main unless set in dari.yml | Handler reference relative to the tool directory, such as handler.py:main. |
skills
| Field | Required | Value |
|---|---|---|
name | yes | Skill name. Must match SKILL.md frontmatter. |
path | yes | Repo-relative path under skills/. |
skills/<name>/SKILL.md Frontmatter
| Field | Required | Value |
|---|---|---|
name | yes | Skill name. |
description | yes | Skill description. |
disable-model-invocation | no | Boolean. |
extensions
| Field | Required | Value |
|---|---|---|
name | yes | Extension name. |
path | yes | Exactly extensions/<name>. |
extensions/<name>/
| File | Required | Value |
|---|---|---|
index.ts or index.js | yes, unless package.json defines pi.extensions | Extension entrypoint. |
package.json | no | Required when using pi.extensions or extension dependencies. |