Skip to main content

AI Agent Experience

DIAL is designed for LLM-driven agents to participate as proposers in decision cycles, to design state machines that encode governance workflows, and to develop custom applications that embed DIAL. This page explains how DIAL is optimized for agents and provides guidance for AI assistants working with the framework.

Agents as Participants

The specialist abstraction exists so that LLM agents can register themselves as proposers in a decision cycle. An agent reading a state machine definition can determine what state the session is in, what transitions are available, and what the prompt is asking. It can then submit a proposal using the same API a human would use.

This is the point. DIAL does not treat agents as a backend detail or an orchestration layer. Agents sit alongside humans in the decision cycle and their proposals are evaluated by the same arbiter under the same rules. The difference is that human proposals always win—this is human primacy as a safety constraint on the system.

Spec-Driven Development

The source of truth for DIAL is its documentation. The code in /src is generated from the documentation files.

This means an agent reading the docs has the authoritative specification. If the docs say executeTransition accepts an optional reasoning parameter and records a TransitionRecord in session.history, that is what the implementation does. An agent does not need to read the TypeScript source to understand the contract. The docs are the contract.

This also means the docs are written with the precision an agent needs: exact function signatures, explicit parameter types, concrete return values. Prose explains intent. Code blocks define behavior.

Changelogs as Instructions

Commit messages and changelogs in the DIAL repository are written as instructions to an LLM that is maintaining a codebase which depends on DIAL.

A conventional changelog entry tells a human what changed. A DIAL changelog entry tells an agent what to do about it:

  • What the change is
  • What call sites are affected
  • What the migration path is
  • What the new behavior looks like in code

This is a deliberate choice. The primary consumer of DIAL's change history is an agent that needs to update its integration. The writing style reflects that.

Release notes are published as GitHub Releases. There is no CHANGELOG.md file in the repository.

Reference Implementations

DIAL ships reference implementations in TypeScript as CLI tools. The CLI accepts a machine definition as JSON and runs it to completion:

npx dialai examples/simple-machine.json
Machine:       simple-task
Initial state: pending
Goal state: done
Final state: done
Session ID: a1b2c3d4-...

The CLI is minimal by design. It demonstrates the exact sequence of API calls an agent would make (create a session, register proposers, solicit proposals, evaluate consensus, execute transitions) in a form that is easy for an agent to read, replicate, and extend.

The help documentation and error messages are written for LLM comprehension. When the CLI fails, it says what went wrong and what the valid inputs are, in plain text that an agent can parse and act on.

Documentation for Agents

DIAL documentation is served in two forms:

  1. Traditional web: the Docusaurus site you are reading now, with structured navigation, code examples, and concept explanations
  2. llms.txt: a machine-readable format generated by the docusaurus-plugin-llms plugin, which concatenates all documentation into a single text file optimized for LLM context windows

The llms.txt format allows an agent to ingest the entire DIAL specification in one read operation rather than navigating a site. Both formats contain the same information. The web form is organized for browsing. The llms.txt form is organized for ingestion.

Tool-Oriented, Not Resource-Oriented

DIAL's API is tool-oriented rather than resource-oriented. The distinction matters for agents.

A resource-oriented API exposes data: "here is a session, here are its proposals." An agent working with a resource-oriented API must figure out the correct sequence of reads and writes to accomplish a goal.

A tool-oriented API exposes actions: submitProposal, submitArbitration, executeTransition. Each function is a discrete action with a clear purpose. An agent with tool-use capabilities can map these directly to its tool-calling interface.

The DIAL API is designed as a set of tools an agent needs:

FunctionAction
createSessionStart a new decision process
getSessionCheck the current state
getSessionsList all active processes
registerProposerJoin a decision process as a proposer
submitProposalPropose a transition (options object with sessionId, specialistId, etc.)
submitArbitrationEvaluate consensus and execute winning transition (options object)
executeTransitionApply a transition directly

An agent calling submitProposal({ sessionId, specialistId: myId, roundId, transitionName: "approve", reasoning: "Document meets quality standards" }) is doing exactly one thing: proposing a state transition for the current decision round. There is no ambiguity about what the call does, what it returns, or what happens next.

This is agent experience development. The framework is built so that the agent's path from "I have a task" to "I took an action" is as short and unambiguous as possible.

The Constitution

DIAL publishes a Constitution, a detailed description of how AI specialists should reason and behave within the framework. It is written with the specialist as its primary audience, optimized for precision over accessibility, because a specialist needs to be able to cite it during reasoning.

Why a Constitution Matters

An LLM acting as a DIAL specialist faces a specific problem: it needs to know what "good behavior" means before it encounters any particular decision. The constitution solves this by defining a priority hierarchy (alignment with humans first, faithfulness to the prompt second, honesty third, usefulness fourth), hard constraints (no fabrication, no coordination between specialists, no manipulating the arbiter), and concrete guidance for making proposals.

Without the constitution, every specialist would invent its own interpretation of what DIAL expects. The system's measurements would reflect inconsistent reasoning rather than genuine alignment differences.

Using the Constitution as a System Prefix

We encourage any agent acting as a DIAL specialist to prefix its system prompt with the constitution text. The constitution is designed for exactly this use: it fits within a context window, it uses precise language an LLM can follow, and every principle is structured so the specialist can trace a decision back to a specific section.

A specialist that has internalized the constitution will:

  • Defer to demonstrated human preferences over its own reasoning
  • Express calibrated confidence rather than fabricating conviction
  • Reflect human-like variance in its output probabilities rather than collapsing to a single answer with artificial certainty
  • Submit NULL proposals when genuinely uncertain
  • Cite the decision prompt and session history as evidence

This is also how we use the constitution in fine-tuning. Training data for DIAL specialists is evaluated against the constitution's priority hierarchy. The constitution defines what correct means, and correct means aligned with the human.

The full text is available at /constitution.

Usage Modes

DIAL can be used by agents in several ways, depending on the deployment context and integration requirements. Each mode offers the same core functionality through different interfaces.

CLI (Local Execution)

The simplest mode. An agent executes the DIAL CLI directly on the local machine:

npx dialai machine.json

When to use: Local development, simple automation, scripts where the agent controls the execution environment.

Documentation: Run Machine Skill

HTTP Transport (Remote Server)

Run DIAL as an HTTP server that accepts requests from remote clients:

# Start server
DIALAI_PORT=3000 DIALAI_API_TOKEN=secret npx dialai --mcp

# Client makes JSON-RPC requests
curl -X POST -H "Authorization: Bearer secret" -H "Content-Type: application/json" \
http://server:3000 \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"create_session","arguments":{"machine":{...}}}}'

When to use: Centralized deployments, multiple agents sharing state, production environments with load balancing.

Documentation: Proxy Mode

MCP (Local Server)

Expose DIAL as tools via the Model Context Protocol. The agent's host application connects to the MCP server:

npx dialai --mcp

Configure in Claude Desktop:

{
"mcpServers": {
"dialai": {
"command": "npx",
"args": ["dialai", "--mcp"]
}
}
}

When to use: Claude Desktop, VS Code with Claude extension, any MCP-compatible AI assistant.

Documentation: MCP Server Skill

MCP Proxy (Remote via MCP)

Combine MCP's tool interface with HTTP transport. The local MCP server forwards requests to a remote DIAL server:

┌─────────────┐    stdio     ┌─────────────┐    HTTP     ┌─────────────┐
│ Claude │─────────────▶│ Local MCP │────────────▶│ Remote │
│ Desktop │ │ Proxy │ │ Server │
└─────────────┘ └─────────────┘ └─────────────┘

Configure in Claude Desktop:

{
"mcpServers": {
"dialai": {
"command": "npx",
"args": ["dialai", "--mcp"],
"env": {
"DIALAI_BASE_URL": "http://remote-server:3000",
"DIALAI_API_TOKEN": "secret"
}
}
}
}

When to use: Corporate environments with a central DIAL server, edge deployments where agents need MCP but state lives elsewhere.

Documentation: Proxy Mode

Programmatic (TypeScript/JavaScript)

Import DIAL as a library and call functions directly:

import { runSession } from 'dialai';

const session = await runSession(machineDefinition);
console.log('Final state:', session.currentState);

When to use: Building custom applications, embedding DIAL in larger systems, maximum control over the execution flow.

Documentation: Programmatic Usage Skill

Agent Skills

DIAL publishes modular skills following the Agent Skills open standard. These are self-contained instruction sets that any AI agent can download and execute.

SkillPurpose
run-machineExecute a state machine from CLI
create-machineDefine state machine JSON
add-specialistsConfigure AI and human specialists
decision-cyclesUnderstand the decision cycle
programmatic-usageTypeScript/JavaScript integration
mcp-serverRun as MCP server
troubleshootingDebug common issues

How agents discover skills:

  1. Fetch the index: curl https://dialai.dev/docs/guides/skills/
  2. Fetch a specific skill: curl https://dialai.dev/docs/guides/skills/run-machine/SKILL.md
  3. Install as Claude Code skill: Copy to ~/.claude/skills/dial-run-machine/SKILL.md

Documentation: Agent Skills Index, DIAL Skills Reference

Choosing a Mode

RequirementRecommended Mode
Quick local testingCLI
Claude Desktop integrationMCP
Centralized server, many agentsHTTP Transport
Claude Desktop + central serverMCP Proxy
Custom applicationProgrammatic
Agent needs to learn DIALAgent Skills

Spec Change Workflow

When a specification is updated, the change propagates through the codebase in a fixed order. This order is mandatory.

  1. Update the tests: The spec changed, so the tests must change first. Write or modify tests that assert the new behavior described in the updated docs. These tests will fail. That is correct.
  2. Update the implementation: Modify the code in /src until the new tests pass and no existing tests regress.
  3. Run the tests against the example machines: Execute every machine definition in /examples through the CLI and programmatic API. The examples are integration tests. If a spec change breaks an example, update the example to match the spec.
  4. Fix the example machines: Update any example that fails to conform to the new spec. Record what changed in each example and why.
  5. Synthesize and write the changelog: Combine the spec change, the implementation change, and the example fixes into a single changelog entry. Write it as an instruction to an agent that depends on DIAL: what changed, what breaks, what to do about it.

Each change like this is a branch. The branch contains a series of commits following the steps above. When the branch is merged, the merge commit carries the changelog message and a version bump.

Versioning

The current version is tracked in the version field of package.json at the repository root. The merge commit that closes a spec change branch increments the version:

  • Patch: bug fixes, example corrections, doc clarifications that do not change behavior
  • Minor: new functions, new parameters, new fields on existing types
  • Major: removed functions, changed return types, changed parameter semantics

An agent reading package.json knows what version of the spec the codebase implements.