Routing Studio is Theo’s per-customer routing layer. You describe how your users phrase requests, and Theo’s routing engine biases the classifier toward the right mode — without you ever having to manage a separate “preference” object. Rules live directly on each API key: open the key, add the words that should fire a rule, pick the destination, and save. A routing rule maps a list of keywords (or, for power users, a raw regex) to a Theo engine. Rules run BEFORE Theo’s global intent classifier so your domain wins on ambiguity. The routing engine layers them on top of its global cascade and never lets them escape Theo’s safety locks (stealth, agentic) or leak upstream vendor names into your customers’ surfaces. Alongside rules you can also configure:Documentation Index
Fetch the complete documentation index at: https://docs.hitheo.ai/llms.txt
Use this file to discover all available pages before exploring further.
- Few-shot examples — prompt / expected-mode pairs injected into the classifier’s system prompt (up to 8 per request).
- Confidence-floor overrides — per-mode replacements for Theo’s global
0.85promotion floor. Lower a floor to make intent promotion easier; raise it to be conservative.
Edit rules on a key
Openapi.hitheo.ai/dashboard/keys, find the API key you want to tune, and click the Routing pill. The panel inlines everything you need:
- Inherited context — if no per-key rules are set, the panel tells you whether the key currently inherits the team default, your personal default, or nothing.
- Rules — one row per rule. Each row has a keyword chip input, a destination combobox, and a Gentle / Balanced / Strict toggle. The empty state offers a few one-click starter templates (Pricing questions, Customer complaints, Legal review, Photo & image requests) and a Blank rule chip for power users.
- More options — a small caret on each row reveals a note field, a raw regex textarea, an optional Theo engine pin, and a raw confidence slider for fine-grained control.
- Try a prompt — a compact input appears once you’ve started editing. Type a sample customer prompt and the panel renders a one-line diff (
baseline mode → with-rules mode) so you can see exactly what would change before saving.
Advanced: hand-written regex
The chip editor projects keywords down to the samepattern string the API uses internally. To author a rule with a raw ECMAScript regex (lookaheads, anchors, capturing groups), expand the row’s More options caret and edit the pattern textarea. Pasting a regex switches the row to Advanced mode automatically so we never silently rewrite your pattern; loading a key whose pattern doesn’t round-trip through the chip editor opens that row in Advanced mode by default.
ContractIQ — a complete walkthrough
ContractIQ is a fictional legal-tech tool. Their users paste contract clauses and ask Theo to analyze them. Without any rules, “look at this clause” routes tofast (a short reply); with one rule on the key, it routes to think (deep analysis).
1. Set rules on the API key
active: true field confirms the rules are driving completions on this key right now. To drop the rules and fall back to inherited defaults, send a DELETE to the same endpoint (or call theo.routingRules.clear(keyId) from the SDK).
2. Send a completion
meta event now carries a customer_preference field that confirms a rule fired:
3. Test changes before they ship
Use the test endpoint to replay a fixture prompt with vs. without the preference:routing telemetry shape your production callers receive — the diff is a precise, deterministic preview of what your tuning does.
Testing an unsaved draft
The dashboard test bench replays the draft you’re currently editing — it never makes you save first. If you’re building your own UI on top of the API, hit the no-idPOST /api/v1/routing-preferences/test route with the full draft body. Same response shape as the by-id route; nothing is persisted.
Order of precedence
Routing Studio sits inside Theo’s broader routing engine. The full cascade, first match wins:- Agentic locks (
insurance_*,data_extraction) — never promoted. - Attachments → vision — image attachments on a non-media caller route to
vision. - Skill exclusive override — a skill with
intensity: 100and amodelPreferencewins. - Routing Studio rule — your rules fire here.
- Intent classifier — runs with your few-shot examples injected and uses your per-mode confidence-floor overrides.
- Stealth family preservation — promotions from a
stealth_*caller stay inside the stealth family. - Conversation hint — falls back to the prior-turn artifact type when the caller used
auto. - Requested mode — default.
Confidence-floor overrides
The classifier won’t promote a caller’s mode unless its confidence is ≥0.85 (PROMOTION_CONFIDENCE_FLOOR). For specialist domains where the classifier is often correct at lower confidence, lower the floor:
[0.5, 0.99] — neither end of the range can disable the floor entirely.
Brand-safety contract
Every customer-authored field — name, description, rule pattern, rule description, example prompt — is scanned for upstream vendor names (Claude, OpenAI, Anthropic, Gemini, fal.ai, etc.) and rejected at validation time. Theo’s surfaces always read as Theo. Your customers never see the underlying model providers. The same scan runs on Routing Studio’s outputs — thecustomer_preference block your callers receive is guaranteed to be free of vendor names.
Limits
| Limit | Value |
|---|---|
| Rules per preference | 50 |
| Examples per preference | 30 |
| Examples injected into classifier | 8 (highest-priority first) |
| Pattern length | 512 chars |
| Example prompt length | 1024 chars |
| Confidence range | [0.5, 0.99] (clamped) |
| Test prompt length | 4096 chars |
| Cache TTL | 5 minutes (Redis) |
Team vs. personal scope
Passscope: "team" on create to scope the preference to your active org. Team preferences become candidates for org defaults; team admins (with the team config permission) can manage them. Without a team binding, a key inherits its scope’s default → the user’s personal default → no preference.
is_default: true on a second team preference returns 409 conflict — at most one default per scope.
Common patterns
- Domain vocabulary biasing. Use rules for hard keywords (“policy”, “claim”, “rune”), use examples for phrasings (“draft me a response to this complaint” →
think). - Cost containment. Raise floors on
image/videofor personal keys; let team keys keep the defaults. - Speed bias. Lower the
fastfloor and add examples like{ prompt: "thanks!", expected_mode: "fast" }so short replies don’t escalate tothink.
Per-key vs. shared sets — when to use which
If you’re tuning one or two keys, edit rules directly on the keys page. The dashboard hides everything but the rule editor itself — no “preference” to create, no binding to wire up. Reach for shared sets when:- You want one rule list to span many API keys (e.g. every key on your team uses the same legal vocabulary).
- You want a team default that new keys inherit automatically.
- You’re scripting bulk changes and would rather author rules in source control once than mirror them across keys.
routing_preferences table; the only thing that differs is whether the row is named for a specific key (hidden from the shared list) or carries a customer-chosen name.
Next steps
/api/v1/routing-preferencesreference — full request/response schemas for every endpoint.- Routing Studio SDK reference —
theo.routingPreferences.*,theo.routingRules.*, and the per-key binding helpers. - Engine Routing & Fallbacks — where Routing Studio fits inside Theo’s broader routing engine.
