Digitorn App Language Reference
Digitorn apps are declared in a single YAML file. The compiler parses
that YAML into the AppDefinition Pydantic model
and the daemon runs it.
There is one canonical schema (v2) with 8 top-level blocks.
Every field has exactly one home; legacy flat YAMLs (execution:,
modules: at the top level, ...) are still accepted by an alias pass
that reshapes them to canonical before validation.
The optional schema_version: 2 declaration at the top of the file
future-proofs against breaking changes.
The 8 blocks
| Block | Required | What it holds | Doc |
|---|---|---|---|
app: | Yes | Identity - app_id, name, version, icon, color, tags, quick_prompts. | App Configuration |
runtime: | No (defaults) | Lifecycle - mode, entry_agent, max_turns, timeout, triggers, hooks, middleware, pipeline, context, workdir, default_channel. | App Configuration, Triggers, Middleware, Tool Hooks, Context Management |
agents: | At least 1 in practice | List of agents. Each has id, role, brain, system_prompt, modules, pool, delegate_to. | Agents, Multi-Agent |
tools: | No | What the agent can call: modules (dict), capabilities (grant / deny), channels (dict). | Tools, Built-in Tools, MCP Servers, Channels, Security |
security: | No | Runtime boundaries: behavior, sandbox, credentials_schema. | Behavior Engine, OS Sandbox, credentials.md |
ui: | No | Pure display, never read by the daemon: theme, features, widgets, workspace (renderer), slash_commands, quick_prompts, greeting. (ui.preview is deprecated; use tools.modules.web_preview for iframe-preview attachments.) | Client Manifest, Widgets, Workspace & Preview |
dev: | No | Developer affordances: skills, variables, include (fragmentation). | Skills System, Bundle namespaces |
flow: | No | Optional declarative orchestration graph for multi-agent apps. Top-level since v2 because it changes how agents coordinate (explicit scenography vs implicit Agent() calls). | Flows |
The ui.workspace block (renderer) is a different concept from
runtime.workdir (filesystem path). The schema renames the legacy
execution.workspace to runtime.workdir to remove the ambiguity
(see RuntimeBlock.workdir).
Quick example
This example uses a local Ollama model so no external credentials
are required. Replace the brain block to use any other provider
(provider: openai, provider: anthropic, provider: deepseek,
etc.); see Agents for the full list.
app:
app_id: my-assistant
name: My Assistant
runtime:
mode: conversation
agents:
- id: assistant
role: assistant
brain:
provider: ollama
model: qwen25-7b-gpu:latest
backend: openai_compat
config:
base_url: http://localhost:11434/v1
api_key: ollama
system_prompt: |
You are a helpful assistant. Reply concisely.
tools:
modules:
memory:
config:
auto_remember: false
capabilities:
default_policy: auto
grant:
- module: memory
actions: [remember]
ui:
greeting: "Hello! How can I help?"
Deploy and chat with it:
digitorn start # daemon if not running
digitorn app run my-assistant.yaml # deploy + arm triggers
digitorn dev chat my-assistant -m "Hi there!" # talk to it
Migration from the legacy flat shape
If your YAML has execution:, modules:, channels:, behavior:, ...
at the top level, the compiler still accepts it via the alias pass. The bidirectional
mirror means both shapes work at read time.
To rewrite the file in-place to the canonical 8-block form:
digitorn yaml migrate-v2 path/to/app.yaml
Field renames the migrator applies (no compat retention). Each row shows the legacy v1 path on the left and the v2 canonical path on the right:
| Legacy v1 | Canonical v2 |
|---|---|
execution.workspace | runtime.workdir |
execution.workspace_mode | runtime.workdir_mode |
execution.greeting | ui.greeting |
execution.sandbox | security.sandbox |
execution.credentials_schema | security.credentials_schema |
dependencies.variables | dev.variables |
dependencies.channels | tools.channels |
dependencies.credentials | security.credentials_schema |
dependencies.payload | runtime.payload_schema |
Top-level lifts (legacy → canonical home, fields keep their name):
| Legacy top-level (v1) | Canonical (v2) |
|---|---|
modules: | tools.modules |
capabilities: | tools.capabilities |
channels: | tools.channels |
behavior: | security.behavior |
widgets: | ui.widgets |
workspace: (block at root) | ui.workspace (renderer) |
preview: | ui.preview (deprecated, ignored at deploy - use tools.modules.web_preview) |
theme: | ui.theme |
features: | ui.features |
slash_commands: | ui.slash_commands |
skills: | dev.skills |
variables: | dev.variables |
include: | dev.include |
middleware: | runtime.middleware |
pipeline: | runtime.pipeline |
flow: (in v1 was top-level too, but is now strictly canonical) | flow: (top-level, NOT under runtime) |
Everything that was under execution: (mode, triggers, hooks,
max_turns, timeout, session_mode, direct_modules,
tool_injection, default_channel, context, payload_schema,
watchers, scheduler, ...) lifts to runtime: with the same name.
security.sandbox → security.sandbox,
security.credentials_schema → security.credentials_schema,
ui.greeting → ui.greeting.
Documentation by topic
Getting started
- Getting Started - install, first app, run loop
- App Configuration - exhaustive reference for the 8 blocks
- Examples - complete real-world apps
Agents and tools
- Agents - agent definition, brain, providers, fallback
- Multi-Agent - coordinator + specialists,
agent_spawn, isolation - Tools - adaptive tool injection, discovery, semantic search
- Built-in Tools - delegation, memory, todo, messaging
- Execution Primitives - parallel execution, watchers, scheduler
- MCP Servers - connect external MCP servers, sandbox, OAuth2
- Web Module - search + fetch + parse
- LSP Diagnostics - real-time code diagnostics
Memory and context
- Cognitive Memory - working memory, tasks, notes, facts
- Context Management - compaction, summary brain, hooks
- Advanced RAG - hybrid retrieval, citations, semantic cache, Text2SQL
Runtime control
- Triggers - cron, watch, http (background mode)
- Flows - declarative orchestration graph
- Middleware Pipeline - secret masking, content filter, RAG inject
- Tool Hooks - pre/post hooks around tool calls
- Skills System -
/commit,/review, custom commands - Channels (Bidirectional I/O) - webhooks, cron, email, RSS
- Background Sessions - mono / multi session modes
- Macros - reusable YAML fragments
- Composition - referencing other apps
- Rules - modular project instructions
Security
- Capabilities -
default_policy, grant / deny, approve gates - Behavior Engine - declarative runtime rules + classifier
- OS Sandbox - Landlock, seccomp, Seatbelt, Job Objects
- Auth - JWT, per-user installs
UI and client
- Client Manifest -
features,theme,slash_commands - Widgets - declarative UI primitives
- Workspace & Preview - virtual filesystem streamed to the client
- Preview SDK -
@digitorn/preview-sdkReact package: hooks, components, host protocol, hidden namespaces - Bundle namespaces -
{{prompt.X}},{{include:}}, hot reload
Operating and deploying
- Daemon Configuration - server, KV, database, CORS
- Observability & Monitoring - metrics, health, tracing
- Production Deployment - TLS, rate limiting, hardening
- Multi-Tenant Installs - per-user vs system-wide
- Bundle namespaces - fragmentation, i18n, hot reload
- Dev CLI - test against the real daemon
- API Integration - REST + Socket.IO contracts
- Expressions - template language
Modules
The daemon ships 23 agent-facing modules (under
packages/digitorn/modules/):
agent_spawn, behavior, channels, context_builder, cron_native,
database, dev_tools, filesystem, http, index, llm_provider,
lsp, mcp, memory, preview, queue, rag, shell, vector,
web, web_preview, widget, workspace.
packages/digitorn/modules/cron also ships but is a system-only
scheduler with no @action surface; it is not listed in the
module reference.
context_builder and llm_provider are auto-loaded; you never
declare them under tools.modules. Per-module reference docs live
under reference/modules/.
Architecture
The compiler walks the YAML once, validates against the eight Pydantic
blocks, then bootstraps each declared module. Once running, every tool
call goes through the AgentContext, hooks fire around it via
HookRunner, and ContextBuilder decides what tool schemas reach the
LLM (direct vs discovery vs compact).
Tool delivery - direct, compact, or discovery
The ContextBuilder module exposes meta-tools the agent can use to
discover capabilities lazily:
- direct - full tool schemas injected up front. Best for small apps (< ~30 tools).
- compact_direct - tool names + 1-line descriptions, full schema
on demand via
get_tool. - discovery - only
list_categories,browse_category,search_tools,get_tool,execute_toolinjected. Agent walks the tree as needed. Scales to hundreds of tools.
The mode is auto-detected by the compiler based on tool count, or
forced via runtime.tool_injection.
LLM compatibility
Three backends are supported
(AgentBrain.backend: Literal["openai_compat", "anthropic", "github_copilot"]
in, default openai_compat):
openai_compat- any OpenAI-compatible/v1endpoint (OpenAI, DeepSeek, Groq, Mistral, Together, Ollama, vLLM, LM Studio, OpenRouter, Cerebras, Perplexity, Fireworks, xAI, Gemini, ...).anthropic- Anthropic SDK (also accepts theclaude-codeAPI-key alias for Claude Code OAuth tokens, see llm_provider module).github_copilot- uses your GitHub Copilot subscription.
Models that support native tool calling (OpenAI, Anthropic,
DeepSeek, Groq, Mistral, Together) get tools via the API
tools= parameter. Models that don't (Ollama, LM Studio, vLLM, small
local models) get tool schemas injected into the system prompt; tool
calls are parsed from the text output via a multi-format recovery
parser.
CLI
The digitorn command is exposed by the digitorn PyPI package.
All sub-commands are registered with Typer.
# First-run wizard + environment doctor
digitorn init
digitorn doctor
# Apps (validate, deploy, run, schema, list, undeploy, delete)
digitorn app validate <app.yaml>
digitorn app deploy <app.yaml>
digitorn app run <app.yaml> # equivalent to deploy --force, shows triggers
digitorn app schema <module_id>
digitorn app list
digitorn app undeploy <app_id>
digitorn app delete <app_id>
# Per-app encrypted secrets
digitorn secret set <app_id> <key> [value]
digitorn secret get <app_id> <key>
digitorn secret list <app_id>
digitorn secret delete <app_id> <key>
# YAML migration
digitorn yaml migrate-v2 <app.yaml>
digitorn yaml migrate-credentials <app.yaml>
# MCP servers
digitorn mcp install <server>
digitorn mcp list
digitorn mcp uninstall <server_id>
# Middleware
digitorn middleware list
digitorn middleware install <path>
digitorn middleware uninstall <middleware_id>
# Dev loop (test apps against the live daemon)
digitorn dev deploy <app.yaml> [--scope system|user]
digitorn dev chat <app_id> [-m "message"]
digitorn dev status <app_id>
digitorn dev history <app_id> <session_id>
# Daemon control
digitorn start [--host 127.0.0.1] [--port 8000] [--workers N] [--config config.yaml] [--app app.yaml]
digitorn supervise [...] # daemon under restart-on-crash supervisor
digitorn stop [--host 127.0.0.1] [--port 8000]
digitorn status [--host 127.0.0.1] [--port 8000]
digitorn version
# System service (systemd / launchd / Windows Service)
digitorn service install # register the daemon as an OS service
digitorn service start
digitorn service stop
digitorn service status
digitorn service logs
digitorn service uninstall
# Module catalog + credential vault + packages + hub
digitorn modules ...
digitorn credentials ...
digitorn requires ...
digitorn package ...
digitorn hub ...
digitorn install-local # pair this daemon to a central account
digitorn auth login|logout|whoami # CLI auth against the central service
digitorn db ...
digitorn with no arguments prints Typer help. For systemd / launchd
/ Windows service installation, see
Production Deployment.