Ask in your own words. Get the official source. A free civic assistant for London on a single Cloudflare Worker: you type what you need, the app's router picks the workflow and the model paints a live A2UI interface (not just text) — swap a JSON, swap the app. No sign-up, no cookies; the AG-UI/A2UI dev console lives behind a dev mode (
?dev=1orCtrl+K).
▶ sortmy.london · one input, many London workflows — Sort My Care (NHS
wayfinder), Sort My Wander (free heritage + green space), Sort My Food Hygiene, Sort My Scam Check
(clone-firm flag), plus a founder-funding copilot and step-free routing via ?usecase= ·
Londonmaxxing 003.
The product is a single-input civic wayfinder (a signpost to official services, never advice — always confirm at the official source): you ask in your own words and the Worker's router builds the workflow, live at sortmy.london. The engine underneath (Groundwork) is the reusable asset: add a workflow by dropping in a
usecases/*.json.
Groundwork is the engine — for builders who want agent apps as config, not code, and the
Londoners each workflow serves. Two pillars: a swappable workflow engine (swap a JSON, swap the app
— each workflow's stage choreography is a usecases/*.json read at runtime; render modes stay in code)
and generative UI (the agent streams the interface, not just text). One free-text input picks the
workflow via the Worker's auto-router (ADR 0004); ?usecase= is an explicit bypass for deep links;
add your own workflow by dropping in a usecases/*.json.
User types one ask ─▶ UI ─▶ POST /api/run (prompt) ─▶ router: heuristic → model → no-match
▲ resolved ─▶ runUsecase (plan → tool → render)
└────── Generative UI (A2UI + HUD) streams back ──────────────────────────┘
- The engine: one
POST /run?usecase=<id>+ a smallrunUsecaseinterpreter (plan → tool → render) — each workflow's plan→tool→render choreography is a declarativeusecases/*.json, selected by theusecasequery param; render + deterministic query dispatch by name via theworker/src/workflows.tsregistry (founders/route/corpus), so adding a corpus workflow is register-only — acorpus/registry.tsentry + a JSON + a UI entry, no engine edit (open/closed). - Generative UI: the agent streams AG-UI events that render as built-in A2UI cards — it paints the interface, not just text (AG Grid deferred).
- Example workflow — Founder's Copilot (model-backed;
?usecase=founders-copilot, never auto-routed): describe your idea → the model assesses your stage and ranks matching grants (two live model tools that stream their reasoning, #18), qualify-first, plus a verified incorporate how-to pack. The live Companies House filing (#12) is planned. - Example workflow — Sort My Route (interchange proof): a step-free London route — same engine, one
?usecase=away (a canned stub today, so never auto-routed; live tools are planned). - Civic pilot — Sort My Care: a deterministic postcode → nearest-NHS-services signpost — model-free
and fetch-free, with honest "data as of …" freshness and a "confirm with the official source" disclaimer.
Proof that a new corpus workflow is register + a JSON, not an engine edit.
?usecase=sort-my-care. - Civic — Sort My Wander: the same deterministic corpus signpost over free heritage sites + green
spaces near a postcode — register-only, curated Historic England link.
?usecase=sort-my-wander. - Civic — Sort My Scam Check: a firm name/FCA-reference flag, never a verdict — register status +
a deterministic clone look-alike note, signposting to the FCA register.
?usecase=sort-my-scam-check. - Keyless demo path; secrets stay Worker-only (stack rationale below).
URL parameters (all optional): ?usecase=<id> selects the workflow (founders-copilot · sort-my-route ·
sort-my-care · sort-my-wander · sort-my-scam-check · sort-my-food-hygiene); ?theme=light|dark forces
the theme (else system); ?variant=thames|indigo|green picks the London accent (else Thames Teal; persisted
in localStorage, cycled by the swatch button beside the theme toggle); ?dev=1 reveals the AG-UI/A2UI dev
console + ⚙ Key panel (also Ctrl+K / Ctrl+I; persisted in localStorage); ?demo=1 forces the Worker's
deterministic path. No secret is ever read from the URL or inlined into the SPA bundle.
Screenshot — Founder's Copilot
Grants matched to the idea, qualify-first gate, live AG-UI event stream.
Screenshot — Sort My Route
A step-free London route — same engine, one usecase away.
make help # all targets
make dev # worker (:8787) + ui (:5173) locally, keyless
make test # ui + worker + ingest tests
make deploy # build the SPA + deploy the Worker to Cloudflare
make bump # stamp a version across ui/worker + the README badge
make demo # boot both, then open localhost:5173 (prod: sortmy.london)Toggle the two example workflows in the UI; cd worker && npm run tail shows one Arize span per stage.
Demo: https://sortmy.london — SPA on Cloudflare Pages, Worker API same-origin at /api/*
(deploy). Full map: docs/plans/001-build-plan.md.
Data pipeline (keyless, arc 016): a weekly GitHub Action (ingest.yml,
GITHUB_TOKEN only) runs the pure, pytest-covered parsers (ingest/) over five
keyless OGL sources and publishes normalised artifacts to the rolling
corpus-data release; the Worker's
daily cron (04:47 UTC) ingests them into D1 behind a swap gate (min-rows + licence-attribution) —
and every corpus degrades to its bundled sample whenever D1 is unbound, failing, or not yet swapped.
Switches: ?usecase=founders-copilot|sort-my-route|sort-my-care|sort-my-wander|sort-my-scam-check|sort-my-food-hygiene
picks the workflow (every sort-my-* corpus flow is deterministic — model-free + fetch-free)
· a Demo⇄Live toggle in the header
(or ?demo=1) forces the keyless deterministic stub even with a model key set — the events header then
shows an honest chip (LIVE · <model> · ~N tok / DEMO · deterministic / STUB · fell back) · ?theme=light|dark
overrides the theme · ?variant=thames|indigo|green picks the London accent (ADR 0005)
· BYOK sends Authorization: Bearer <key> to the Worker instead of its server-side key.
One engine, many workflows — each a usecases/*.json selected via the usecase query param. Two examples prove it: funding
discovery (no single API) and civic routing (TfL ↔ council data siloed by mandate, not tech). A modular
agent built in a day joins what incumbents can't, and swaps between both from one core. See
docs/usecase-workflows.md.
- Cloudflare (Workers · Pages · Workers AI · D1) — one serverless edge deploy, zero-ops; the Worker is
the trust boundary (secrets server-side, sole egress). Workers AI serves the keyless free render
chain; the D1 corpus store (fed by the daily ingest cron, bundled-sample fallback) +
data/demo/*.jsonare the data sources (no KV; AI Gateway dormant, #29). - OpenRouter — one key, many models. A BYOK key swaps the model with no code change; keyless runs use a
free chain (Workers AI → OpenRouter
:free→ stub; the GitHub Models tier was dropped ahead of its 2026-07-30 retirement, #132), so the Worker rarely/never spends. - Arize — LLM tracing: one span per stage (
plan → tool → render), exported to Arize over OTLP whenARIZE_API_KEY+ARIZE_SPACE_IDare set (console otherwise); browser spans forward viaPOST /trace. - UI (React 19 · Tailwind v4 · A2UI) — a static Pages bundle that issues no external request: the CSP
is
script/style/font-src 'self', so Inter + JetBrains Mono ship self-hosted via@fontsourceand even axe-core is vendored. The theme is project-owned (ADR 0005): fo Linear neutrals plus three London accent variants (?variant=), light + dark, every pair contrast-measured and gated by the e2e sweep's variant × scheme axe matrix.
- Architecture · User stories · Use-case workflows · Glossary · Data sources · Usecase catalog · Design · archived (historical): submission, demo script
- Reuse base:
qte77/agenthud-agui-a2ui· fetcher:qte77/polyfetch-scrape
Apache-2.0 — see LICENSE · third-party attribution in NOTICE.