Example — Support Copilot
A complete multi-file Causet application demonstrating AI decisions, vector memory, and the full write path from ticket creation through triage to queryable agent dashboards.
Source: the Support Copilot example application (maintained internally alongside the platform).
What it demonstrates
| Feature | File |
|---|---|
| AI providers | providers/ai.providers.causet |
| Prompt templates | prompts/triage.prompts.causet |
| Decision definition | decisions/triage.decisions.causet |
| Vector memory | memories/customer.memories.causet |
op: decision | actions/support.actions.causet |
| Apply AI output | listeners/triage.listeners.causet |
| Read models | projections/support.projections.causet |
| Agent queries | queries/support.queries.causet |
Architecture
App layout
# app.causet
dsl_version: 1
app: support_copilot
includes:
states: [./states/**/*.state.causet]
events: [./events/**/*.events.causet]
actions: [./actions/**/*.actions.causet]
providers: [./providers/**/*.providers.causet]
prompts: [./prompts/**/*.prompts.causet]
decisions: [./decisions/**/*.decisions.causet]
memories: [./memories/**/*.memories.causet]
listeners: [./listeners/**/*.listeners.causet]
projections: [./projections/**/*.projections.causet]
queries: [./queries/**/*.queries.causet]Key actions
Seed customer memory
RECORD_CUSTOMER_NOTE and SIMULATE_ORDER emit events listed in customer_history.source_events. With memory ingestion enabled, these are embedded for later retrieval.
actions:
RECORD_CUSTOMER_NOTE:
state: customer
entity_id_expr: intent.customer_id
core:
rules:
- name: record_note
then:
- op: emit
event_type: CUSTOMER_NOTE_RECORDED
payload:
customer_id: intent.customer_id
note: intent.note
author: intent.authorCreate ticket + AI triage
Core persists the ticket and emits TICKET_CREATED. Side effects run op: decision — after core commits.
CREATE_TICKET:
state: ticket
entity_id_expr: intent.ticket_id
core:
rules:
- name: persist_ticket_fields
then:
- op: set
path: /status
value: open
- op: emit
event_type: TICKET_CREATED
payload:
ticket_id: intent.ticket_id
customer_id: intent.customer_id
subject: intent.subject
body: intent.body
side_effects:
rules:
- name: ai_triage
then:
- op: decision
ref: triage_ticket
input:
ticket_id: intent.ticket_id
customer_id: intent.customer_id
subject: intent.subject
body: intent.bodyDecision + memory + prompt
Decision — references reasoning provider, triage prompt, and customer memory:
decisions:
triage_ticket:
provider: reasoning
prompt: triage_v1
emits: TICKET_AI_TRIAGED
memories:
- customer_history
input:
ticket_id: { type: string, required: true }
customer_id: { type: string, required: true }
subject: { type: string, required: true }
body: { type: string, required: true }
output:
priority: { type: string, required: true }
category: { type: string, required: true }
summary: { type: string, required: true }
confidence: { type: number, required: true }Memory — ingests notes and orders, partitioned by customer:
memories:
customer_history:
source_events:
- CUSTOMER_NOTE_RECORDED
- ORDER_PLACED
partition_by: customer_id
embedding:
provider: embeddings
content: |
[{{ event.type }}] customer={{ event.customer_id }}
note={{ event.note }} author={{ event.author }}
order={{ event.order_id }} total={{ event.total }} items={{ event.item_summary }}Listener — applies AI fields when TICKET_AI_TRIAGED fires:
listeners:
- on: TICKET_AI_TRIAGED
mutate:
- op: set
field: priority
value: event.payload.priority
- op: set
field: category
value: event.payload.category
- op: set
field: ai_summary
value: event.payload.summary
- op: set
field: ai_confidence
value: event.payload.confidenceCompile and deploy
causet build compile --runtime path/to/support-copilot --out build/tmp-support-copilot-outOutputs include causet.decisions.json plus runtime and projections IR. Deploy and activate on your fork with projections enabled.
Cloud configuration
- Deploy and activate the spec on your fork (include
causet.decisions.json). - In Causet Cloud → AI Providers, add BYOK keys for
reasoningandembeddings. - Enable memory ingestion for the fork if using vector memory.
For offline testing, set providers to executor: mock in your .causet files, or use the mock mode toggle in the Causet Cloud support-demo app for this walkthrough.
Example intents
1. Seed memory
{ "intent_type": "RECORD_CUSTOMER_NOTE", "customer_id": "cust_1", "note": "Prefers email contact", "author": "agent_7" }
{ "intent_type": "SIMULATE_ORDER", "customer_id": "cust_1", "order_id": "ord_99", "total": 149.99, "item_summary": "Pro plan annual" }2. Create and triage
{
"intent_type": "CREATE_TICKET",
"ticket_id": "tkt_100",
"customer_id": "cust_1",
"subject": "Billing question on ord_99",
"body": "I was charged twice for my Pro plan renewal."
}3. Query results
After triage completes, named queries such as urgent_tickets, tickets_for_customer, and triage_dashboard read from materialized projection tables.
Interactive demo
Causet Cloud includes a live demo in-app: /platform/{platform}/app/{application}/support-demo.
The demo executes intents via the control-plane proxy and refreshes query results after CREATE_TICKET.
The demo uses @causet/sdk via the control-plane proxy. Configure platform, application, fork, and API key in the demo UI — see Install Causet.
Design notes
- Core before AI — ticket state and
TICKET_CREATEDcommit even if the LLM fails. Triage is best-effort in side effects. - Memory is async — allow a beat between seed intents and triage in demos so embeddings are available.
- Listeners for AI fields — keeps core deterministic; AI output arrives as an event like any other domain fact.
- Structured output — the decision schema forces JSON fields the listener and projections can rely on.
See also
- AI in Causet — platform overview
- Defining Decisions —
op: decisionreference - Vector Memory — ingestion and retrieval
- Recommendation Memory — deterministic entity-state personalization (complementary)