Getting Started
Build a typed AI agent in 60 seconds. Dawn is file-system routing for agents — no registry, no hand-written tool schemas, no glue.
By the end of this guide you'll have a working deep-research assistant at /research that plans sub-questions, searches a local corpus, and writes cited reports — running offline out of the box, live against a real model when you opt in.
Prefer to build with a coding agent? Copy the prompt above and paste it into Claude Code, Cursor, or your agent of choice.
1. Install
npm create dawn-ai-app@latest my-agent
cd my-agent
npm installRequires Node.js 22.12 or later.
For a minimal greeter scaffold instead, pass --template basic:
npm create dawn-ai-app@latest my-app -- --template basic2. What you got
The scaffold is a complete deep-research assistant. The folder structure is the agent — no registration step.
src/app/research/
index.ts # research coordinator agent
state.ts # route state shape
plan.md # seeds the thread's planning todos
tools/
searchCorpus.ts # keyword search over the bundled corpus
readDoc.ts # reads a corpus document in full
subagents/
researcher/index.ts # specialist dispatched per sub-question
skills/
cite-sources/SKILL.md # loaded on demand: citation rules
synthesize-findings/SKILL.md # loaded on demand: report structure
evals/
research-quality.eval.ts # quality eval with scorers and a gate
test/
research.test.ts # harness tests (offline, no API key)
workspace/
AGENTS.md # house style injected every turn
corpus/ # bundled documents the agent searches
scripts/
fetch-source.mjs # network fetch script called via runBash
dawn.config.ts # app config: permissions, tool-output offloadingThe route entry (index.ts) is a research coordinator. It plans sub-questions, dispatches the researcher subagent for each one, and synthesizes a cited report. Tools under tools/ are bound to both agents at build time — dawn check infers their types from function signatures.
import { agent } from "@dawn-ai/sdk"
export default agent({
model: "gpt-5-mini",
description:
"A deep-research assistant: plans sub-questions, dispatches researchers, and writes a cited report.",
systemPrompt: `You are a deep-research coordinator. Given a question:
1. Plan the sub-questions to investigate and record them in your todos.
2. For each sub-question, dispatch a specialist with \`task({ subagent: "researcher", input: "<sub-question>" })\`.
3. You may also \`searchCorpus({ query })\` and \`readDoc({ path })\` directly for quick lookups.
4. When the corpus lacks coverage, you may run \`runBash({ command: "node scripts/fetch-source.mjs <topic>" })\` — the human must approve it.
5. Synthesize the findings into a cited report and save it with \`writeFile({ path: "reports/<slug>.md", content: "<report>" })\`.
Cite every claim with its source path in square brackets, e.g. [corpus/agent-architectures.md]. Keep the final answer concise.`,
})The plan.md file opts the route into Dawn's planning capability — its checklist items seed each thread's todos. workspace/AGENTS.md is injected into the agent's system prompt every turn as durable memory. Skills under skills/ are loaded on demand by name.
3. Verify and test
npm run checkGenerates route and tool types. Output:
Dawn app is valid: 2 routes discovered.
- /research (agent)
- /research/subagents/researcher (agent)npm testRuns the harness tests in test/research.test.ts. The test script drives the agent using recorded fixture responses, covering corpus search, subagent dispatch, tool-output offloading, and the human-in-the-loop permission gate. No API key is needed.
npm run evalRuns the quality eval in src/app/research/evals/research-quality.eval.ts. The agent run replays fixtures, then two dataset cases are scored across four scorers (toolCalled, contains, cites-source, llmJudge). The generated fixtures also cover the judge requests from llmJudge, so the scaffolded eval runs without an API key.
Before running the app live, run dawn verify as your preflight — it checks app integrity plus environment readiness (Node version, the provider API key your routes need, and the Docker daemon when a sandbox is configured) so dawn dev and dawn start boot cleanly. See dawn verify.
4. Run it live
Set your API key and start the dev server:
export OPENAI_API_KEY=sk-...
npx dawn dev --port 2024The dev server exposes the Agent Protocol. In another terminal, create a thread, capture its id, then run the research agent on that thread:
THREAD_ID=$(curl -s -X POST http://127.0.0.1:2024/threads \
-H "Content-Type: application/json" \
-d '{}' | jq -r .thread_id)
curl -s -X POST http://127.0.0.1:2024/threads/$THREAD_ID/runs/wait \
-H "Content-Type: application/json" \
-d '{
"route": "/research#agent",
"input": {
"messages": [{ "role": "user", "content": "What are common agent architectures?" }]
}
}' | jq .The #agent suffix is required — it selects the agent entry on the route. The report lands in workspace/reports/ inside the project. Thread state checkpoints to .dawn/checkpoints.sqlite; threads persist across dev-server restarts.
5. Ship it
dawn buildDiscovers routes from the app directory (appDir, defaulting to src/app), runs typegen, and writes deployment artifacts for both default build.targets: a node target (.dawn/build/server.mjs plus a hardened Dockerfile) and a langsmith target (.dawn/build/langgraph.json plus per-route entry files). The generated assistant_ids match the local ids, such as /research#agent.
Serve it in production
The node target is a runnable server, not just a platform artifact. Serve it locally with dawn start:
npx dawn startYou should now see the agent listening on 0.0.0.0:8000, serving Agent Protocol and AG-UI and engaging the execution sandbox if configured. To ship it as a container instead:
docker build -t my-agent .
docker run -p 8000:8000 --env-file .env my-agentSee Deploying to production for the full Node/Docker path and the LangSmith alternative.