showcase · tier 2 · ops & support
Support triage
The overnight queue gets classified with schema enums, first replies drafted, urgent tickets escalated.
- 6tasksthe plan falls out of the bindings
- 4wavesparallel by construction
- 2verbs exercisedinvoke · infer
- T2the tierops & support
The whole file
6 tasks · 4 wavesThe plan falls out of the bindings, nothing is scheduled by hand.
support-triage.nika.yamlsource
nika: v1workflow: id: support-triage description: "Ticket queue → typed triage → urgent escalation → triage board"# A NON-thinking local model, deliberately: a thinking model can spend the# whole `max_tokens` budget in its think block and return before the JSON# (engine#428). Schema showcases pick a model that answers directly.model: ollama/llama3.2:3b # local · zero key · swap for groq/llama-3.3-70b (triage wants speed)const: queue_path: "examples/fixtures/support-queue.json"secrets: oncall_webhook: source: env key: ONCALL_WEBHOOK_URL egress: # sanction the one send · the secret IS the URL - to: "nika:notify" host_from_self: truepermits: tools: ["nika:jq", "nika:notify", "nika:read", "nika:uuid", "nika:write"] fs: read: ["examples/fixtures/support-queue.json"] # One board per batch id. `*` matches a single segment and never crosses # `/`, so the uuid can never steer the write out of out/ — `out/**` would # let it. write: ["out/triage-*.json"] net: # `host_from_self:` above sanctions the FLOW (the secret may be the URL) — # it does not grant the capability. The host stays unknown at check, so it # is judged at RUN against this bound: name the escalation host here or the # send is refused mid-run, after the tokens are already spent. http: ["hooks.slack.com"]tasks: batch: invoke: tool: "nika:uuid" args: { version: v7 } queue: invoke: tool: "nika:read" args: { path: "${{ const.queue_path }}" } triage: with: queue: ${{ tasks.queue.output }} infer: max_tokens: 1500 # the whole queue in one call · a ceiling, not UNBOUNDED prompt: | Triage every ticket in this queue · ${{ with.queue }} For each · classify category and urgency, draft a 2-sentence first reply. schema: type: object additionalProperties: false # a deterministic shape across providers required: [tickets] properties: tickets: type: array items: type: object additionalProperties: false required: [id, category, urgency, first_reply] properties: id: { type: string } category: { type: string, enum: [billing, bug, how-to, account, other] } urgency: { type: string, enum: [low, normal, high, critical] } first_reply: { type: string } urgent: with: tickets: ${{ tasks.triage.output.tickets }} invoke: tool: "nika:jq" args: input: "${{ with.tickets }}" expression: 'map(select(.urgency == "high" or .urgency == "critical"))' escalate: with: urgent: ${{ tasks.urgent.output }} batch: ${{ tasks.batch.output }} when: ${{ size(with.urgent) > 0 }} invoke: tool: "nika:notify" args: channel: webhook target: "${{ secrets.oncall_webhook }}" message: "Urgent tickets in triage batch ${{ with.batch }} · ${{ with.urgent }}" severity: warning board: with: tickets: ${{ tasks.triage.output.tickets }} batch: ${{ tasks.batch.output }} invoke: tool: "nika:write" args: # A `.json` artifact takes ONE interpolated value as `content:` and # lets the engine serialize it. Typing `{ "tickets": ${{ … }} }` by # hand emits unquoted fields and the board stops being JSON. path: "out/triage-${{ with.batch }}.json" content: "${{ with.tickets }}" create_dirs: trueoutputs: tickets: value: ${{ tasks.triage.output.tickets }} description: "The classified queue with drafted first replies"nika inspect · engine 0.106.1 · vendored graph, never re-derived
6 declared edges · 4 waves · the plan falls out of the bindings