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, ai returns 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

triage.ecko
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.