Dev Server

dawn dev starts a local runtime with LangSmith-style /runs/wait and /runs/stream endpoints. It watches route and tool files, regenerates types when signatures change, and restarts the child route runtime for structural changes.

Starting the server

text
dawn dev

By default the server binds an ephemeral localhost port (announced on stdout as Dawn dev ready at http://127.0.0.1:<port>). Pass --port <n> for a stable port:

text
dawn dev --port 3001

The bind address is always 127.0.0.1.

Invoking a route

With the server running in one terminal, you can hit it from another:

text
echo '{"tenant":"acme"}' | dawn run '/hello/[tenant]' --url http://127.0.0.1:3001

dawn run resolves the route id to an assistant_id of the form <routeId>#<kind> (e.g. /hello/[tenant]#agent), POSTs to /runs/wait, and prints the result.

Protocol endpoints

The dev server handles three endpoints. Anything else returns 404.

Readiness check.

text
GET /healthz
-> 200 { "status": "ready" }

Returns 200 once the child runtime is up; non-200 means not-ready. dawn dev itself uses this endpoint internally to detect readiness.

The assistant_id format <routeId>#<kind> is the same format dawn build writes into the graphs map of .dawn/build/langgraph.json, so the same client request shape works against dawn dev and against a deployed runtime.

Middleware

src/middleware.ts (default-exporting a function returned by defineMiddleware) runs before every local /runs/wait and /runs/stream request handled by dawn dev. It can short-circuit a request with reject(status, body?), or continue with allow(context?) — the optional context flows to every tool as ctx.middleware (a Readonly<Record<string, unknown>>).

MiddlewareRequest shape: { assistantId, headers, method, params, routeId, url }. See Middleware for the full reference.

Hot reload

When you save a file under src/app/, the dev server:

  1. 1

    Reclassifies the change

    Typegen-only changes (tool signatures, state schemas) trigger a debounced typegen run (~100ms) — the child does not restart. Structural changes restart the child.

  2. 2

    Restarts the child runtime when needed

    Dawn uses a parent-child process architecture. The parent owns the HTTP server and file watcher; the child owns the route graph. On a structural change the child is stop()ed (with a forced kill timeout — in-flight requests are given a brief grace window, then force-killed) and a fresh child is started.

  3. 3

    Preserves assistant ids

    Assistants keep their stable ids (<routeId>#<kind>) across restarts, so any agent or harness holding an assistant_id continues to work without reconnection.

Logging

The parent process keeps the HTTP server alive while child route runtimes restart. Set DAWN_DEV_SHUTDOWN_TIMEOUT_MS to override the child-restart grace window.

Related