How the turntype.Detect Component Classifies Request Types in WorkWeave Router

The turntype.Detect component classifies incoming requests by executing a strict ordered cascade of heuristics in DetectFromEnvelope, analyzing the request envelope and routing features to distinguish specialized turn types—such as probes, compaction tasks, and sub-agent dispatches—from standard conversation loops.

The turntype package in the workweave/router repository provides intelligent request classification for AI conversation routing. By evaluating the inbound request envelope alongside extracted routing features, the component determines whether a turn represents a quota check, title generation, context compaction, or ordinary user interaction. This classification enables the router to apply precise resource policies and routing logic based on operational intent.

The Core Entry Point: DetectFromEnvelope

The classification logic centers on the DetectFromEnvelope function, located in internal/router/turntype/detect.go (lines 53-86). This function serves as the primary entry point for the classification system, accepting three parameters: the request envelope, routing features, and an optional sub-agent header string. It implements a strict ordered cascade where the most specific signals are evaluated first, ensuring high-impact operational classifications take precedence over general conversation turns.

Turn Type Constants

The component defines seven distinct turn type constants in internal/router/turntype/detect.go (lines 14-29):

  • Probe – Tiny quota-checking requests with max_tokens ≤ 4
  • TitleGen – Claude Code sidebar-title generation (no tools + JSON-schema title response)
  • Compaction – Claude Code context-compaction instruction (specific marker phrase in Anthropic format)
  • SubAgentDispatch – Requests originating from sub-agents (header or metadata hints)
  • Classifier – Short-form classifier calls (no tools, limited token and message counts)
  • ToolResult – Turns where the last message kind is "tool_result"
  • MainLoop – Default classification for ordinary user-assistant turns

The Heuristic Decision Cascade

The DetectFromEnvelope function processes these heuristics in a specific sequence, returning immediately upon the first match to prevent misclassification.

1. Null Envelope Handling

If the request envelope is nil, the function immediately returns MainLoop. This safety check ensures the system gracefully handles malformed or missing envelope data without crashing.

2. Probe Detection

The isProbe helper (lines 88-90) checks if features.MaxTokens is less than or equal to a hard-coded threshold of 4 tokens. This identifies tiny quota-checking requests that require minimal resource allocation.

3. Title Generation Detection

The isTitleGen function (lines 109-116) identifies Claude Code sidebar-title generation by verifying two conditions: the envelope's RequestsTitleSchema() method returns true, and the request contains no tools. This distinguishes UI metadata requests from functional conversation turns.

4. Context Compaction Detection

For Anthropic-format requests, the isCompaction heuristic (lines 70-75) scans the system prompt and the tail of the last user message for the compaction marker phrase: "your task is to create a detailed summary". It also verifies the presence of the "do not call any tools" clause to confirm this is a context-summarization operation rather than a functional request.

5. Sub-Agent Dispatch Detection

The isSubAgentDispatch function (lines 76-86) detects requests originating from sub-agents through three signals:

  • The x-weave-subagent-type header is present
  • metadata.user_id begins with the literal prefix "subagent:"
  • The first user message starts with "<transcript>" within the first 64 bytes

6. Classifier Detection

The isClassifier helper (lines 92-106) identifies short-form classification calls by verifying:

  • The request contains no tools
  • features.MaxTokens is ≤ 256 tokens
  • features.MessageCount is ≤ 3 messages

7. Tool Result Detection

If the most recent message kind (features.LastKind) equals "tool_result", the turn is classified as ToolResult. This identifies conversation turns that are processing function call results rather than initiating new user queries.

8. MainLoop Fallback

Any request not matching the preceding heuristics defaults to MainLoop. This conservative fallback ensures that standard user-assistant conversations receive full resource allocation and routing treatment.

Safety and Precision Design

The helper functions—isProbe, isTitleGen, isCompaction, hasCompactionMarker, isSubAgentDispatch, and isClassifier—are deliberately tight in their validation logic. A false positive would incorrectly hard-pin a request to a specialized routing path, potentially breaking functionality, while a false negative safely falls back to MainLoop. This design prioritizes operational safety over aggressive optimization.

Practical Implementation Example

The following Go example demonstrates how to integrate the classification component within a proxy handler:

// Example: Classify an incoming request inside a proxy handler.
import (
    "workweave/router/internal/translate"
    "workweave/router/internal/router/turntype"
)

// env is the parsed request envelope (already built by translate).
// feats are populated from the request header and body (maxTokens, etc.).
func classify(env *translate.RequestEnvelope, feats translate.RoutingFeatures, subAgentHeader string) turntype.TurnType {
    // DetectFromEnvelope implements the full heuristic cascade.
    return turntype.DetectFromEnvelope(env, feats, subAgentHeader)
}

// Usage:
tt := classify(envelope, routingFeatures, r.Header.Get("x-weave-subagent-type"))
switch tt {
case turntype.Probe:
    // cheap quota-check handling …
case turntype.TitleGen:
    // generate sidebar title …
case turntype.Compaction:
    // apply Claude Code compaction logic …
case turntype.SubAgentDispatch:
    // route to the appropriate sub-agent …
case turntype.Classifier:
    // run short-form classification …
case turntype.ToolResult:
    // process tool result turn …
default:
    // normal main-loop conversation
}

Key Source Files

The classification system spans these critical files within the workweave/router codebase:

Summary

  • The turntype.Detect component uses an ordered cascade of heuristics in DetectFromEnvelope to classify requests
  • Seven distinct turn types handle specialized operations from quota probes to context compaction
  • Strict evaluation order ensures high-impact classifications (like probes and sub-agent dispatches) take precedence
  • Conservative fallback to MainLoop prevents misclassification of standard conversations
  • Tight validation logic in helper functions minimizes false positives while accepting safe false negatives

Frequently Asked Questions

What is the order of precedence for turn type classification?

The DetectFromEnvelope function evaluates heuristics in this strict sequence: Null check → Probe → TitleGen → Compaction → SubAgentDispatch → Classifier → ToolResult → MainLoop. This ordering ensures that lightweight system operations (probes) and specialized routing needs (sub-agents) are identified before standard conversational turns.

How does the component distinguish a probe request from a regular turn?

The isProbe helper function in internal/router/turntype/detect.go (lines 88-90) classifies a request as a Probe when features.MaxTokens is less than or equal to 4 tokens. This hard-coded threshold identifies quota-checking requests that require minimal processing resources compared to full conversation turns.

What triggers a SubAgentDispatch classification?

The isSubAgentDispatch function detects sub-agent origins through three signals: the presence of an x-weave-subagent-type header, a metadata.user_id starting with "subagent:", or the first user message beginning with "<transcript>" within the initial 64 bytes. Any of these conditions indicates the request requires sub-agent routing logic.

Why does the classifier heuristic check both token and message limits?

The isClassifier function (lines 92-106) verifies that requests contain no tools, have max_tokens ≤ 256, and contain ≤ 3 messages. These combined constraints distinguish short-form classification calls—which are typically lightweight, structured queries—from complex, multi-turn conversations that require MainLoop processing and full resource allocation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →