Use casesBackground processing
Customer support triage
Mock mode is deterministic and schema-valid, so routing logic has real CI tests with no API key and no flakiness.
The problem
Support queues need intent, urgency, and product area before a human sees the ticket. Prototype in Python, wire to OpenAI, ship - then discover routing rules never had tests because the model path needed a key and returned slightly different labels each run.
Why Ecko
- Deterministic mock mode
- Without a key,
aireturns typed values that satisfy your struct every time. Route on them in unit tests the way you would on production output. - Typed labels
- An enum-like struct for intent prevents "Billing" and "billing issue" from splitting into two queues.
- One binary on the worker
- Drop the triage worker on a queue consumer host. No virtualenv activation in systemd units.
In practice
import std.test type Intent = Billing | Bug | Account type Ticket { intent: Intent, urgency: Int, product: String } fn triage(text) = ai[Ticket] "Triage this support ticket: {text}" fn queue(t) = match t.intent { Billing => "finance" Bug => "engineering" Account => "accounts" } # No key in CI: ai[Ticket] returns the same schema-valid Ticket every run. test.case("billing goes to the finance queue", fn() { t = triage("I was charged twice") test.eq(queue(t), "finance") })
Try it on your workload.