atteq API
  • Guides
  • Recipes
  • Cookbook
  • API Reference
Mail triageMemoryTriageWeekly summary
powered by Zudoku
Cookbook

Triage

Sort each new thread of one connection under the organization's labels, sending some to people and the rest to an agent.

This page is made from the recipe triage, version 1, and says nothing the recipe does not. How a recipe is composed explains every word it uses.

Its setup

Each new conversation on [The connection Triage answers] is labelled: those with [The labels that go to people] wait for a person, and [The agent that answers what is not for people] takes the rest.

Each phrase in brackets is a parameter the recipe asks for, named as the table of parameters below names it.

While [The labels that go to people] is left blank: Each new conversation on [The connection Triage answers] is labelled, and [The agent that answers what is not for people] takes every one.

Its parts, in the order data travels

  1. thread_flow answers — Makes this triage the flow the connection answers each message with.
    • answers the connection ${param.connection} (the value of the parameter connection) with the flow triage, in place of the flow it answered with
  2. flow triage — Sorts the first message of each conversation and hands each message to a person or to the agent.
    • step arrived runs the tool first
    • step checked runs the tool first
    • step answered runs the tool to_agent, only while agent has a value
    • step for_a_person runs the tool to_people, only while agent is left blank
    • step read runs the tool classify
    • step sorted runs the tool first
    • step labelled runs the tool put_label
    • step acknowledged runs the tool acknowledge, only while acknowledgement has a value
    • step for_people runs the tool to_people, only while people_labels has a value
  3. tool first — Passes on the conversation the message arrived on, for the flow to choose where it goes next.
    • runs the built-in pass_value
  4. tool acknowledge — Sends the acknowledgement you wrote at once, even where the connection prepares its replies.
    • runs the built-in reply_on_thread
  5. tool classify — Asks the reading model once which of the organization's labels fits the message.
    • runs the built-in structured_answers
  6. tool put_label — Puts the label the model answered on the conversation.
    • runs the built-in label_conversation
  7. tool to_people — Leaves the conversation waiting for a person, saying why.
    • runs the built-in hand_to_person
  8. tool to_agent — Hands the message to the agent you chose, which answers or prepares its answer as the connection says.
    • runs the built-in hand_to_agent, only while agent has a value

Its parameters

ParameterKindWhat it asksValue
connectionconnectionThe connection Triage answersrequired; fixed once installed
agentagentThe agent that answers what is not for people — Leave it blank and every message goes to a person.may be left blank; fixed once installed
people_labelslabelsThe labels that go to people — A conversation with one of these labels waits for a person; none, and everything goes to the agent.may be left blank
acknowledgementtextAcknowledgement — Sent at once on the first message of each conversation; empty, nothing is sent.default ""

The labels it proposes

Created at install in the organization's vocabulary, as its own labels and never the recipe's: the client edits, leaves out or keeps its own label instead of each, and those kept that join fill people_labels.

LabelWhat belongs under itJoins
SalesWants to buy, asks for a price or a quote, or asks about a product or a service.no
SupportHas a problem or a question with something they already use or bought.no
BillingAsks about an invoice, a charge, a payment or a refund.yes
ComplaintComplains, is upset, or asks to speak to a person.yes

How its data moves

The flow triage:

StepInputValueComes from
arrivedvalue$ref:trigger.thread.interaction_idthread.interaction_id of what set the run off
checkedvalue$ref:trigger.texttext of what set the run off
answeredtext$ref:trigger.texttext of what set the run off
answeredmessages$ref:trigger.messagesmessages of what set the run off
for_a_personreasonTriage on this connection names no agent, so every message goes to a person.fixed
readtext$ref:trigger.texttext of what set the run off
sortedvalue$ref:trigger.thread.interaction_idthread.interaction_id of what set the run off
labelledadd["$ref:read.label"]a list of label of the step read's answer
acknowledgedtext${param.acknowledgement}replace with the value of the parameter acknowledgement
for_peoplereasonTriage put a label on this conversation that the client sends to people.fixed

A value written $ref:<step>.<path> is what an earlier step answered, and $ref:trigger.<path> is what set the run off. A value with ${...} in it is a placeholder: building it by hand, replace it with your own.

Build it yourself

To install it as it is: POST /api/v1/recipes/{key}/install with the key triage and a value for each parameter. To build the same thing with your own particulars, make each part in this order -- each one may name the ones before it -- with the operations below.

The YAML under each part is the recipe's declaration, not a request body: the API takes other names for the same things (a tool's builtin is source and config.builtin, a step's tool is tool_id, an edge's from is source_step_id). From a recipe to the API on the lead page maps every field, kind by kind.

1. tool first

Passes on the conversation the message arrived on, for the flow to choose where it goes next.

  • POST /api/v1/tools creates the instance: a built-in's, or a flow offered as one tool by its config.flow_id.
Code
kind: tool key: first name: Triage on ${param.connection.name} — where the message arrived says: Passes on the conversation the message arrived on, for the flow to choose where it goes next. description: 'The step every message runs first, so the flow can branch on whether the conversation''s flow has run before. It is one more tool execution per message: every later message costs two, the hand-over and this, where a connection that "this agent answers" costs one.' builtin: pass_value

2. tool acknowledge

Sends the acknowledgement you wrote at once, even where the connection prepares its replies.

  • POST /api/v1/tools creates the instance: a built-in's, or a flow offered as one tool by its config.flow_id.
Code
kind: tool key: acknowledge name: Triage on ${param.connection.name} — acknowledgement says: Sends the acknowledgement you wrote at once, even where the connection prepares its replies. builtin: reply_on_thread

3. tool classify

Asks the reading model once which of the organization's labels fits the message.

  • POST /api/v1/tools creates the instance: a built-in's, or a flow offered as one tool by its config.flow_id.
Code
kind: tool key: classify name: Triage on ${param.connection.name} — which label fits says: Asks the reading model once which of the organization's labels fits the message. builtin: structured_answers config: fields: - key: label type: option options_from: labels description: Which of the organization's labels fits this message.

4. tool put_label

Puts the label the model answered on the conversation.

  • POST /api/v1/tools creates the instance: a built-in's, or a flow offered as one tool by its config.flow_id.
Code
kind: tool key: put_label name: Triage on ${param.connection.name} — put the label on says: Puts the label the model answered on the conversation. builtin: label_conversation

5. tool to_people

Leaves the conversation waiting for a person, saying why.

  • POST /api/v1/tools creates the instance: a built-in's, or a flow offered as one tool by its config.flow_id.
Code
kind: tool key: to_people name: Triage on ${param.connection.name} — to a person says: Leaves the conversation waiting for a person, saying why. builtin: hand_to_person

6. tool to_agent

Hands the message to the agent you chose, which answers or prepares its answer as the connection says.

  • POST /api/v1/tools creates the instance: a built-in's, or a flow offered as one tool by its config.flow_id.
Code
kind: tool key: to_agent name: Triage on ${param.connection.name} — to ${param.agent.name} says: Hands the message to the agent you chose, which answers or prepares its answer as the connection says. description: Hands what arrived on ${param.connection.name} to ${param.agent.name}. builtin: hand_to_agent config: agent_id: ${param.agent} deadline_seconds: 120 when: ${param.agent}

7. flow triage

Sorts the first message of each conversation and hands each message to a person or to the agent.

  • POST /api/v1/flows creates the flow.
  • POST /api/v1/flows/{flow_id}/steps adds each step, naming the tool it runs.
  • POST /api/v1/flows/{flow_id}/edges adds each edge.
  • PATCH /api/v1/flows/{flow_id}/entry-step sets the step a run starts at.
Code
kind: flow key: triage name: Triage on ${param.connection.name} says: Sorts the first message of each conversation and hands each message to a person or to the agent. steps: - key: arrived tool: ${resource.first} params: value: $ref:trigger.thread.interaction_id - key: checked tool: ${resource.first} params: value: $ref:trigger.text - key: read tool: ${resource.classify} params: text: $ref:trigger.text - key: labelled tool: ${resource.put_label} params: add: - $ref:read.label - key: sorted tool: ${resource.first} params: value: $ref:trigger.thread.interaction_id - key: acknowledged tool: ${resource.acknowledge} params: text: ${param.acknowledgement} when: ${param.acknowledgement} - key: for_people tool: ${resource.to_people} params: reason: Triage put a label on this conversation that the client sends to people. when: ${param.people_labels} - key: answered tool: ${resource.to_agent} params: text: $ref:trigger.text messages: $ref:trigger.messages when: ${param.agent} - key: for_a_person tool: ${resource.to_people} params: reason: Triage on this connection names no agent, so every message goes to a person. unless: ${param.agent} edges: - from: arrived to: checked condition: field: trigger.thread.is_first_run op: === value: true - from: arrived to: answered - from: arrived to: for_a_person - from: checked to: read condition: field: trigger.text op: '!==' value: '' - from: checked to: sorted - from: read to: labelled condition: field: read.label op: exists - from: read to: sorted - from: labelled to: sorted - from: sorted to: acknowledged - from: sorted to: for_people condition: field: read.label op: includes value: ${param.people_labels} when: ${param.people_labels} unless: ${param.acknowledgement} - from: sorted to: answered unless: ${param.acknowledgement} - from: sorted to: for_a_person unless: ${param.acknowledgement} - from: acknowledged to: for_people condition: field: read.label op: includes value: ${param.people_labels} when: ${param.people_labels} - from: acknowledged to: answered - from: acknowledged to: for_a_person

8. thread_flow answers

Makes this triage the flow the connection answers each message with.

No public operation places a flow on a connection that already answers. The nearest by hand makes the connection's channel with the flow, which a connection already answered has to be made again for:

  • POST /api/v1/channels makes the connection's channel, answered by the flow it names.
Code
kind: thread_flow key: answers name: Triage answers ${param.connection.name} says: Makes this triage the flow the connection answers each message with. connection: ${param.connection} flow: ${resource.triage}

How to adapt it

Choose the connection, the labels that go to people, the agent that answers the rest -- or none, and every message goes to a person -- and, if you want one, the acknowledgement sent at once. Tune what goes where by editing your labels and their lines, which are all the model reads. To build your own, keep its shape: a first step that runs on every message, a branch on whether the thread's flow has run before, the reading with the labels as its answers, the label put on, the acknowledgement after them, and a hand-over chosen by whether that label is one of a list.

What cannot change once installed

Installed, every part is the recipe's: it is listed where its kind lives, marked as the recipe's, and refuses every edit and deletion by hand, naming the recipe.

  • tool first: its configuration and fixed values.
  • tool acknowledge: its configuration and fixed values.
  • tool classify: its configuration and fixed values.
  • tool put_label: its configuration and fixed values.
  • tool to_people: its configuration and fixed values.
  • tool to_agent: its configuration and fixed values.
  • flow triage: its steps and edges.
  • thread_flow answers: the connection it answers and the flow it runs there.

What stays the organization's:

  • the values of people_labels, acknowledgement, changed on the installed recipe and written through to every part that uses them;
  • not connection: the connection is fixed once installed, because it says which install this is -- answering another connection is installing the recipe there;
  • not agent: the agent it names, or naming none, is fixed once installed -- answering the connection with another is uninstalling the recipe and installing it again;
  • whether the recipe is on, which switches its automations on and off together;
  • presentation -- a column's width, a step's position -- which changes nothing it runs.

What it costs

What its parts consume -- a tool execution, a model's tokens, a message, storage -- is recorded and charged as those parts are, exactly as your own use of them is; nothing is charged for the recipe itself.

Last modified on November 4, 2026
MemoryWeekly summary
On this page
  • Its setup
  • Its parts, in the order data travels
  • Its parameters
  • The labels it proposes
  • How its data moves
  • Build it yourself
    • 1. tool first
    • 2. tool acknowledge
    • 3. tool classify
    • 4. tool put_label
    • 5. tool to_people
    • 6. tool to_agent
    • 7. flow triage
    • 8. thread_flow answers
  • How to adapt it
  • What cannot change once installed
  • What it costs
YAML
YAML
YAML
YAML
YAML
YAML
YAML
YAML