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.
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 (offline, no API key)
All three commands run without any API key — fixtures replace live model calls.
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.
npm run evalRuns the quality eval in src/app/research/evals/research-quality.eval.ts. Two dataset cases are scored across four scorers (toolCalled, contains, cites-source, llmJudge). Both must pass for the gate to clear.
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. Create a thread, then run it:
# 1. Create a thread
curl -s -X POST http://127.0.0.1:2024/threads \
-H "Content-Type: application/json" \
-d '{}' | jq .
# 2. Run the agent on that thread (replace <thread_id> with the id from step 1)
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 .dawn/build/langgraph.json plus per-route entry files. The generated assistant_ids match the local ids, such as /research#agent.