Guide: a new domain
bash
npm run new-domain -- bookings # scaffolds domains/bookings from templates/
npm run new-domain -- bookings --lang python # the same, with the tool server in Python (python-tools.md)Then, in the build order (docs/PLAYBOOK.md):
- Tools —
domains/bookings/mcp/server.ts(ormcp/server.py). Implement reads (search_*,get_*,reference_data) and the triad:validate_booking_slots(write-free; returnsproblems,from_record,defaults),preview_booking,create_booking(refuses withoutconfirmed:trueandAGENT_ALLOW_WRITES === "true"; returns{created:true, entity_id, label?, entity_url?}). Keepinternal_*for gateway-only work (uploads, attach). Wrap every handler with thereg()pattern from the example (auth context + trace context from_meta). - Probe —
domains/bookings/probe/probe.tsagainst the dev backend with--yes: one known-good create, then one field stripped at a time; tag, clean up, report. Fold the findings into the registry. - Schema registry —
schema/booking-schema.json: slots with sources, mandatory sets, ask sets, probe findings. Keep the validate tool reading it. - Skill —
skills/bookings/SKILL.md: routing, entry, the cascade, ask sets (one question per turn), validation after every change, what the runtime owns, never-rules. Deltas for variants ("all orchestrator rules apply; only X differs"). - Steps —
steps/index.tsfromstepHelpers(docs/guides/new-step.md); list their order indomain.json(step_order, or per type undertypes.<t>.steps). - Manifest —
domain.json: name, title, description (the router card), route hints, mcp, skills, shared skills, steps, slot labels, hidden slots, attested lists, entity names. - Mock policy (optional but recommended) —
mock/policy.tswithregisterMockModel: the model's part of the journey as a state machine, so CI runs the whole domain with no key. - Evals —
evals/run-evals.tsfrom the template; the coverage checklist in the playbook.
Run npm run gateway (the domain is discovered at boot), walk the journey in the playground, then npm run gateway:evals & npm run evals.
With entity types
Declare types in the manifest (title, skill, tools, keywords, steps, flags) plus core_skills for the orchestrator and type_tool if you rename set_type. Only the in-play type's skill and tools reach the model.
Media
Implement internal_upload_media, internal_attach_media, internal_detach_media (optionally internal_arrange_media) and set AGENT_MEDIA_DOMAIN; the gateway does the rest.
Source: docs/guides/new-domain.md — edit it there; the site mirrors the repository.