Conversation classification
The agent classifies operator Chat turns and Intake items with two Cloudflare Workers AI System One models:
- Clef makes the decisions: route (
question,status,work_request,bug,decision,chitchat,human,refuse), severity, product area, and theneeds_work,asks_internals, andasks_other_projectsignals. - Clairic reads values from the text: the Steelframe version and the environment. Text answers are exact spans of the message, so Clairic cannot invent a version that was not written.
Both models share one credential. Classification is advisory unless a route is confident: it never replaces the Chat reply and never fails a turn.
What is stored
Section titled “What is stored”conversation_classifications is keyed by subject:
| Subject | ID | Used by |
|---|---|---|
chat_session | chat_sessions.id | Chat sidebar category and product area |
intake | intake_items.id | Intake kind/severity fill and the detail view |
A Chat session’s latest route and product area are also copied to
chat_sessions.category and chat_sessions.product_area so the sidebar can
filter without a join. The full row keeps confidence, the yes/no signals, the
reporting version, the environment, and the serialized classification for
replay.
For an Intake, the classifier only fills kind and severity that the
operator did not set explicitly. A confident bug becomes kind=bug; a
work_request becomes kind=feature; a question becomes kind=question.
- Create a Cloudflare API token with Workers AI access.
- Store
cloudflare_aiwith the account ID in the URL field and the token in the secret field. - Optionally set
clef_model(cleforclef-flash) andclairic_model(clairic).
Local testing can use CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN
instead of the credential. If the account ID is missing, the agent tries the
token’s account list once and caches the first account; a token without
Account:Read must set the ID explicitly.
| Method | Path | Purpose |
|---|---|---|
GET | /api/classifications?subject_kind=intake&limit=100 | Recent classifications. |
GET | /api/classifications/{kind}/{id} | One subject’s latest answer. |
Chat sessions expose category and product_area in
GET /api/operator/chat/sessions. Intake items expose a classification
object in GET /api/intake.
Thresholds and failure
Section titled “Thresholds and failure”- A route below
0.6confidence is recorded but not treated as a decision. needs_workat or above0.6, or a confidentbug/work_request, offers an Intake (the Discord 📥 reaction, or the Board composer).- Missing credentials, a non-2xx response, a timeout, or a malformed body logs a warning and leaves the row unclassified. The Chat turn and Intake create still succeed.
The classifier runs in the background after the Chat turn, so it never adds latency to the reply.