Recipe catalog / message-facets
Label the facets of a message
Which of these does message do: ask a question, report a problem, request an action, state a deadline, reference prior contact?
You need several independent yes/no labels on an incoming message in one call, for triage rules or form pre-fill.
Explore this recipe interactively ยท Source and implementation guide
Use message-facets in TypeScript
Install with npm install jev-recipes. Requires Node.js 22.9 or newer and ES modules. Set TYPESAFE_API_KEY in your server environment for live calls, which send input to TypeSafe and use API quota. See the installation guide.
import { messageFacets } from 'jev-recipes/message-facets';
const result = await messageFacets({
"message": "Following up on ticket 4821: the export still fails with a timeout. Can you escalate this? We need it working before our board meeting on Friday.",
"minConfidence": 0.8
});
console.log(result);
Input contract
| Field | Type | Needed |
|---|---|---|
| message | string | Required |
| context | string | Optional |
| minConfidence | number | Optional |
Full input and result schemas
{
"input": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"message": {
"type": "string"
},
"context": {
"type": "string"
},
"minConfidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"message"
]
},
"result": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"model": {
"type": "string"
},
"usage": {
"type": "object",
"properties": {
"input_tokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"output_tokens": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"input_tokens",
"output_tokens"
],
"additionalProperties": false
},
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"detected": {
"type": "array",
"items": {
"type": "string",
"enum": [
"asksQuestion",
"reportsProblem",
"requestsAction",
"statesDeadline",
"referencesPriorContact"
]
}
},
"labels": {
"type": "object",
"properties": {
"asksQuestion": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
},
"reportsProblem": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
},
"requestsAction": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
},
"statesDeadline": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
},
"referencesPriorContact": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"ready",
"review"
]
},
"verdict": {
"type": "string",
"enum": [
"present",
"absent"
]
},
"probability": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": [
"status",
"verdict",
"probability",
"confidence"
],
"additionalProperties": false
}
},
"required": [
"asksQuestion",
"reportsProblem",
"requestsAction",
"statesDeadline",
"referencesPriorContact"
],
"additionalProperties": false
}
},
"required": [
"model",
"usage",
"status",
"detected",
"labels"
],
"additionalProperties": false
}
}Saved example result
This hand-authored response demonstrates the contract. It is not a model accuracy measurement. Run it without an API key: npx jev-recipes demo message-facets.
{
"model": "demo-fixture",
"usage": {
"input_tokens": 0,
"output_tokens": 0
},
"status": "ready",
"detected": [
"asksQuestion",
"reportsProblem",
"requestsAction",
"statesDeadline",
"referencesPriorContact"
],
"labels": {
"asksQuestion": {
"status": "ready",
"verdict": "present",
"probability": 0.86,
"confidence": 0.86
},
"reportsProblem": {
"status": "ready",
"verdict": "present",
"probability": 0.97,
"confidence": 0.97
},
"requestsAction": {
"status": "ready",
"verdict": "present",
"probability": 0.95,
"confidence": 0.95
},
"statesDeadline": {
"status": "ready",
"verdict": "present",
"probability": 0.93,
"confidence": 0.93
},
"referencesPriorContact": {
"status": "ready",
"verdict": "present",
"probability": 0.96,
"confidence": 0.96
}
}
}
Evaluation evidence
No verified live accuracy measurement is available. Evaluate representative cases before using this decision in your workflow.
Use the evaluation guide to measure this decision on your own labeled cases.
Limitations
- Labels are independent, so a message can carry several or none.
- Deadline detection reports that a deadline is stated. Parse the actual date in code.
Related recipes
- turn-intent: Use turn-intent when you need the single primary purpose of a message.
- urgency-signal: Use urgency-signal to detect an explicit request for urgent attention.