TAP workflows — Detailed
TAP Tagging Suggestions
The active TAP tagging surface is suggestions-only.
| Item | Value |
|---|---|
| Registered sync route | POST /tap/workflows/tagging-suggestions |
| Registered create run route | POST /tap/workflows/tagging-suggestions/create-run |
| Registered start run route | POST /tap/workflows/tagging-suggestions/start?runId=<uuid> |
| Registered poll route | GET /tap/workflows/tagging-suggestions/runs/<uuid> |
| Agent | tap-caption-tagging-agent |
| Writes to TAP | No |
| TAP API credentials | Not required |
Request Shape
{
"options": {
"maxTagsPerPost": 6,
"generateCaption": true,
"includeReasoning": true
},
"posts": [
{
"postId": 12345,
"tenantId": "tap",
"university": {
"id": "uol",
"name": "University of Liverpool"
},
"text": "Graduation day on campus",
"caption": null,
"media": [
{
"url": "https://example.test/signed-image.jpg",
"type": "image",
"altText": null
}
],
"existingTags": [],
"userContext": {
"country": "Thailand"
}
}
]
}
Response Shape
{
"jobId": "7f4b9a2e-2f0a-4e0a-8d8c-9b6f6f8f2a31",
"processed": 1,
"results": [
{
"postId": 12345,
"status": "success",
"caption": "Students celebrate graduation on campus.",
"tags": ["Graduation", "Campus", "Students"],
"confidence": "high",
"reasoning": "The image and post text indicate a graduation scene."
}
],
"errors": [],
"summary": {
"postCount": 1,
"imageCount": 1,
"processedCount": 1,
"skippedCount": 0,
"failedCount": 0
}
}
Valid tagging requests return HTTP 200 even when individual media items cannot be processed. Failed or skipped post results include additive diagnostics:
{
"jobId": "7f4b9a2e-2f0a-4e0a-8d8c-9b6f6f8f2a31",
"processed": 0,
"results": [
{
"postId": 12345,
"status": "failed",
"caption": null,
"tags": [],
"reason": "rate_limited",
"retryable": true,
"mediaDiagnostics": {
"status": "failed",
"reason": "rate_limited",
"retryable": true,
"type": "image"
},
"errors": ["429 rate limit"]
}
],
"errors": ["Post 12345: 429 rate limit"],
"summary": {
"postCount": 1,
"imageCount": 1,
"processedCount": 0,
"skippedCount": 0,
"failedCount": 1
}
}
Tracked Run Progress
{
"runId": "44c34b7f-b5f8-4a0f-a44b-03d1fd260f17",
"status": "running",
"message": "3/10 posts processed",
"progress": {
"total": 10,
"processed": 3,
"succeeded": 3,
"failed": 0,
"skipped": 0
}
}
Terminal poll responses include a result field using the synchronous response shape.
TAP Query Compatibility Route
TAP query remains a custom bounded synchronous route backed by
tap-query-workflow:
POST /tap/workflows/query
The start-async, create-run, start, and runs/:runId query compatibility
routes return 410 with migration guidance. The tap-chat-workflow source
module is not exported by the current TAP workflow registry, and there is no
active /tap/chat route in the TAP runtime.
TAP Topic Detection
Topic detection is an internal workflow for completed or quiet student conversations. TAP should call the product-facing tool route for on-demand classification; the generic workflow route remains available for internal workflow debugging. Scheduled polling of TAP conversations is not wired yet.
| Item | Value |
|---|---|
| Workflow ID | tap-topic-detection-workflow |
| Agent | tap-topic-detection-agent |
| Product route | POST /tap/tools/topic-detection |
| Internal workflow route | POST /tap/workflows/topic-detection |
| Default analysis mode | fast |
| Persistence | TAP SQL message ledger, result log, and current assignment tables |
| Writes to TAP APIs | No |
Flow
Analysis Modes
fast and full preserve the same response and audit schema. The difference is only the prompt sent to the model:
fastsends a smaller prompt using the locally ranked topic shortlist.fullsends the full taxonomy plus the shortlist for QA comparison, backfill, or escalation.
Both modes persist provider request ID, provider latency, prompt/completion/total/reasoning tokens, workflow step timings, candidate topics, final detected topics, evidence, raw agent response, and validation errors. The product response also includes additive provider diagnostics, retryability, and an input summary when those values are available.
Local Gates And Model Role
The workflow does not route every message directly to the model. The local service first normalizes IDs, persists the message ledger, builds context, applies cheap eligibility gates, and ranks likely topic candidates from the taxonomy. The LLM is then used for the semantic judgment step where it chooses supported topics, evidence message IDs, message findings, or fallback: "other".
This keeps the request auditable and cheaper than sending the whole taxonomy and unfiltered context every time. It also means fast and full differ only in prompt size; they do not change the persistence, timing, token, or result schema.
Input Shape
The workflow accepts caller-provided conversationId and threadId when available. If neither is provided, it generates an internal conversation ID. Conversations are eligible when they have an explicit completion/closed signal or have been quiet for the configured inactivity window.
Use dryRun: true for endpoint smoke tests that should not write topic results or assignments. Use dryRun: false only after the TAP topic detection tables have been deployed.
{
"conversationId": "chat-123",
"threadId": "thread-123",
"conversationStatus": "completed",
"analysisMode": "fast",
"providerLane": "standard",
"dryRun": true,
"messages": [
{
"messageId": "msg-1",
"role": "student",
"sequence": 1,
"text": "Are there scholarship deadlines for September?"
}
]
}
TAP Dev Verification
The TAP dev Mastra deployment was verified on 2026-06-16 with the on-demand workflow route:
POST /tap/workflows/topic-detection
The dry-run request used providerLane: "standard" and analysisMode: "fast" against a scholarship, visa, and accommodation conversation. The route returned HTTP 200 with wrapper status success, workflow status success, classifier status llm, and detected:
scholarships_and_fundingvisa_and_immigrationaccommodation
Observed timing and token evidence from that test:
| Metric | Value |
|---|---|
| End-to-end elapsed time | 28,015 ms |
| Provider latency | 27,376 ms |
| Total tokens | 3,474 |
| Validation errors | 0 |
The same deployment also passed targeted Bruno checks for TAP content safety, Azure content safety, and tagging suggestions.
The product-facing tool route returns the same workflow result under data:
{
"data": {
"workflowId": "tap.topic-detection.v1",
"conversationId": "chat-123",
"status": "success",
"analysisMode": "fast",
"detectedTopics": []
}
}
The internal workflow route returns a wrapper:
{
"runId": "fast-lx123abc-7f3e9a21",
"status": "success",
"result": {
"workflowId": "tap.topic-detection.v1",
"conversationId": "chat-123",
"status": "success",
"analysisMode": "fast",
"detectedTopics": []
}
}