-
Notifications
You must be signed in to change notification settings - Fork 0
adapting for your domain
The travel repo is a worked example. To build the same shape for logistics, retail, healthcare, manufacturing — any industrial domain — fork this repository and walk this checklist.
Every change you make replaces "travel-specific" pieces. The SPA shell, the gateway integration, the auth flow, and the deployment do not change. Only three things are domain-specific:
-
The orchestrator playbook — the per-message workflow
(this repo's
itinerary-planner.yaml). - The widget set — the JSON schemas + React components that the SPA can render.
- The MCP playbooks — the providers your orchestrator calls (in this repo, Duffel / Amadeus / Google Places / Firestore).
If a piece is not in that list, you almost certainly do not need to touch it.
| Step | Source | Action |
|---|---|---|
| 1.1 | package.json |
Rename, version reset, update repo URL. |
| 1.2 | README.md |
Rewrite for your domain. Keep "Source of Truth" section pointing at your widget contract. |
| 1.3 | .env.example |
Update Auth0 application + gateway base URL placeholders. |
| 1.4 | wrangler.toml |
Update Cloudflare Pages project name. |
| 1.5 |
index.html, public/
|
Update title, favicon, branding. |
The SPA shell at src/components/shell/ does not need
domain-specific changes for this phase. You will rebrand visual
copy later (often inside widget components).
| Step | Source | Action |
|---|---|---|
| 2.1 | playbooks/widget-contract/*.schema.json |
Inventory: keep the generic widgets (bot_text, user_text, clarify_question, error_card, loading_card, notification, action_chooser). Remove travel-specific schemas (flight_*, hotel_*, place_*, itinerary_summary, order_confirmation). |
| 2.2 | New <your_widget>.schema.json files |
Author the schemas for your domain's primitives (e.g. shipment_card, route_map, inventory_status for logistics). |
| 2.3 | src/components/widgets/ |
Remove the travel-specific .tsx components. Add new ones following the existing pattern. |
| 2.4 | src/components/widgets/widgetUtils.tsx |
Update the dispatch table. |
| 2.5 | playbooks/widget-contract/widget_envelope_examples.md |
Add one example envelope per new widget. |
| 2.6 | Validate |
npm run contracts && npm run smoke:widgets && npm run type-check && npm test. |
See Widget contract for the workflow on authoring one widget end-to-end.
| Step | Source | Action |
|---|---|---|
| 3.1 | playbooks/itinerary-planner.yaml |
Copy as playbooks/<your_orchestrator>.yaml. |
| 3.2 | playbooks/agent/system_prompt_extraction.md |
Rewrite the LLM's slot-extraction prompt for your domain (what are your "slots"? destinations vs. shipment IDs vs. patient identifiers vs. SKUs). |
| 3.3 | The extract_turn step's Python code |
Update slot semantics, tool-decision logic, and rendering decisions for your domain. |
| 3.4 | Provider call steps (call_google_places, call_duffel_offers, etc.) |
Replace with your providers (call_carrier_api, call_inventory_service, etc.). Each provider is one tool: agent step pointing at its MCP playbook. |
| 3.5 |
render_widget_chat step |
Update the envelope-building logic to emit your new widget types. |
| 3.6 | persist_calendar_event_* |
Replace with whatever per-domain projections you need (e.g. persist_shipment_milestone, persist_appointment). |
| 3.7 | The Firestore database name (or backend) | Update firestore_database workload var, or replace the firestore MCP with a different store entirely. |
| Step | Source | Action |
|---|---|---|
| 4.1 |
noetl/ops repo, automation/agents/mcp/
|
Author a new playbook per provider (HTTP API or otherwise). Each is its own *.yaml file. |
| 4.2 | NoETL keychain | Provision credentials for the provider (API tokens, OAuth client secrets) under named aliases. The orchestrator references them as {{ provider_credential }}. |
| 4.3 | Catalog registration | Run noetl catalog register (or your equivalent) so the new MCP playbooks are dispatchable. |
You never write a long-running provider service. Each provider is a playbook the worker pool dispatches on demand.
Auth0 is the default. If your domain needs a different identity provider, see the Auth and session page's "Swapping the identity provider" section.
If Auth0 stays but your tenant changes:
| Step | Source | Action |
|---|---|---|
| 5.1 | Auth0 dashboard | Create the new application. Set callback / logout / origin URLs to your domain. |
| 5.2 |
.env.example and the build pipeline |
Update VITE_AUTH0_DOMAIN, VITE_AUTH0_CLIENT_ID. |
| 5.3 | Gateway config | Update the gateway's Auth0 JWKS pointer and client secret in the relevant k8s Secret. |
| Step | Source | Action |
|---|---|---|
| 6.1 | DNS | Point your domain at Cloudflare Pages (SPA) and Cloudflare Tunnel (gateway). |
| 6.2 | Cloudflare Pages | Connect the forked repo. Set VITE_* env vars in the project settings. |
| 6.3 | GKE | Re-use the existing |
| GKE Helm install. |
See Deployment for the full sequence.
When forking, you will be tempted to take shortcuts. Push back on:
- "Just call the database from the SPA for read-only stuff." The widget the user sees is a render of slot state derived from event log. Subscribe through the gateway; do not bypass it. See the Ephemeral Blueprints doc.
- "Put the API token in the SPA for client-side calls." Tokens live in the NoETL keychain and resolve at step execution. The SPA never holds a third-party token.
- "Add a Python sidecar to the SPA so it can do X." If X is "talk to an external system", that is a playbook step on a worker. The SPA layer stays browser-side only.
- "Stand up a long-running agent process for tenant Y." Agents are sequences of playbook steps. No persistent agent infra per tenant.
-
"Bypass the polling loop with a custom polling thread for
faster updates." Use the gateway's SSE
playbook/stateframe family. Polling exists only as the cold-start fallback.
If you find yourself rewriting:
- The chat thread UI shell → stop. It is domain-neutral.
- The gateway integration modules in
src/api/→ stop. The wire protocol is fixed. - The widget envelope shape (
_envelope.schema.json) → stop. This is the contract every widget participates in. - The Auth0-to-session exchange → stop. Swap the identity provider only, not the gateway-session model.
- The deployment story → stop. Cloudflare Pages + GKE Helm install works for any forked SPA.
The point of this repo is that you do not rebuild any of the above per domain. Each domain replaces only the three pieces listed at the top of this page.
- Widget contract — author your domain's visual vocabulary.
- Playbook: itinerary-planner — the template orchestrator to copy.
- Gateway integration — the wire protocol your SPA already speaks.
- Foundational principle: Ephemeral Blueprints.
Travel SPA
Architecture
- Architecture
- Widget contract
- Business data via playbooks
- Playbook: itinerary-planner
- Playbook: calendar/list
Integration
Operations
See also
- noetl wiki (app)
- ops wiki (deploy)
- Ephemeral Blueprints