Before you start
- An OpenRouter or TypeSafe API key. You can paste it while turning the classifier on, or store it first under Settings then Providers.
- Traces whose spans carry user and assistant messages, tagged with a call site. See Call sites.
- Traces that carry a thread ID or a session ID, so messages from one session can be read together.
Turn it on
- Open Classifiers.
- Select Enable Frustration on the banner at the top of the page.
- Choose the provider to run it on. Each provider shows Key stored or No key added.
- If the provider has no key, paste it into the API key field.
- Select Save key and enable, or Enable when a key is already stored.
What is sent, and to whom
For each message it scores, Tessary sends:- The user’s message and the four messages before it.
- Text only. Tool calls, tool results, and reasoning are not sent.
- The text as stored, which means after PII redaction.
- Pasted blocks replaced by a marker such as
[PASTE: 40 lines, 1873 chars], and long messages cut to their start and end.
What it costs
Scoring costs about $0.04 per 1,000 messages. Your provider bills each call to your key, so track the spend in your provider’s dashboard. Only messages that can be scored are sent, and each session stops being sent after its first flag, so the number of calls is lower than your message count.Which messages are scored
A user message is scored only when the four messages before it are user, assistant, user, assistant, and each has text. So:- A session’s first two user messages are never scored.
- A message whose previous assistant turn ended on a tool call with no text is not scored.
- A session here is the messages that share a trace’s thread ID, or its session ID when it has no thread.
- Once one message in a session is flagged, the rest of that session is not scored.
- A user who is annoyed about something outside the chat, such as a late delivery.
- A message that is only confused or urgent.
- Emotion inside text the user pasted or asked for.
- A message too ambiguous to call. When unsure, the model reads it as neutral.
When a case opens
One flagged message is not a finding and pages nobody. It is listed on the classifier as a detection. Each call site learns its own normal rate of frustrated sessions from its first sessions, then watches that rate. When the rate rises above what it learned, Tessary files a finding and opens a case in one step, titled for example “Frustrated sessions increased from 2.1% to 6.8% on support-chat”. The finding does not wait for triage: its numbers are the claim, so it is ruled when it is filed.A call site that frustrates users from its first day learns that rate as its normal, and opens a case only if it gets worse.
Read the finding and the case
Both pages show the same evidence:- A chart of the call site’s rate of frustrated sessions over time, against the rate it learned.
- The frustrated sessions, newest first, each with its flagged message and score. Every session the rate counted is listed; scroll to the end or select Load more sessions for the next page.
- The selected session as it happened: the flagged turn and the two turns before it, with tool calls, read from the real traces. The flagged message is highlighted, and the pane scrolls to it.
Run RCA on the case
Select Run RCA on the case. Root-cause analysis reads every frustrated session the finding cites and, with a connected repository, your code. It returns one of two verdicts: Causes identified or No cause found. Each cause shows:- What the agent did, and how many sessions show it.
- A confidence: high, medium, or low.
- Where it comes from: a prompt, code, a tool, the model, or unknown, with the file, commit, and excerpt when one lines up.
- A suggested fix.
- The sessions and turns that show it. On the case, the Show link on a cause, such as Show 12 sessions, narrows the session list to that cause.
Resolve the case
Select Resolve, write one line on what happened, and choose what the case turned out to be:
Resolve as Fixed only once the fix is live. Resolved earlier, the call site learns the frustrated rate as its normal. A frustration case cannot be absorbed.
When it pauses
If the key stops working, the classifier stops sending and its row on Classifiers says why:
Saving a working key lifts the pause. Retry on the classifier lifts it right away, or says why it cannot. Messages that arrive while it is paused are skipped, not scored later.
What Tessary keeps
- The text sent for scoring is deleted on the same schedule as the trace it came from. See Data retention.
- Whether a message was flagged, the model’s scores, the cost, and the response time are kept after the text is deleted, because the call site’s rate is rebuilt from them.
- Flagged sessions are detections, and follow the detection retention period.
Turn it off
Switch the classifier off on its row under Classifiers. It stops sending messages. Cases it already opened stay open until someone resolves them.Read next
Cases
How a case collects findings, and the states it moves through.
Troubleshooting
What to check when the classifier shows no detections.
