Skip to content
Get API key

Tool routing

In an agent loop, invoking a full reasoning LLM just to decide whether a turn needs repository search, a file edit, a test run, or a clarifying question wastes 1–3 seconds and thousands of output tokens. With mouse-1, you pass the user's request and current workspace summary in state, attach a choice question over candidate tools alongside companion noul questions, and route in ~40–100 ms.

Pattern: speculative fan-out for agent routing

Section titled “Pattern: speculative fan-out for agent routing”

Because every question in POST /v1/systemone runs in parallel against the same state, ask your primary routing choice question and any follow-up noul checks in a single call:

  1. next_tool (choice): Which tool or handler should run next?
  2. needs_sandbox (noul): Does this turn require booting a code execution sandbox?
  3. needs_clarification (noul): Would one missing fact from the user materially change the implementation?
{
"model": "mouse-1",
"state": {
"user_prompt": "Rename exported function `parseToken` to `verifyToken` in src/auth.ts and update all callers.",
"recent_files": ["src/auth.ts", "src/http/middleware.ts"],
"sandbox_status": "hibernated"
},
"questions": {
"next_tool": {
"type": "choice",
"instructions": "Which tool should handle `user_prompt` first?",
"criteria": {
"grep_search": "Find all callers or references across the repository before editing",
"edit_file": "Modify a single known file when all locations are already in context",
"run_tests": "Run the test suite to verify changes",
"ask_user": "Ask the user to clarify an ambiguous requirement",
"direct_reply": "Answer directly without touching the repository"
}
},
"needs_sandbox": {
"type": "noul",
"instructions": "Does fulfilling `user_prompt` require reading or modifying files in the repository?"
},
"needs_clarification": {
"type": "noul",
"instructions": "Is `user_prompt` missing a required decision that only the user can make?"
}
}
}
{
"id": "dec_21b90e4a7c12f803",
"object": "systemone.response",
"model": "mouse-preview-2026-10-13",
"answers": {
"next_tool": {
"type": "choice",
"choice": "grep_search",
"confidence": 0.85,
"probabilities": {
"grep_search": 0.88,
"edit_file": 0.10,
"run_tests": 0.01,
"ask_user": 0.01,
"direct_reply": 0.0
},
"mouse": {
"calibrated": false,
"p_top": 0.88,
"abstain": null
}
},
"needs_sandbox": {
"type": "noul",
"noul": 0.99,
"mouse": {
"calibrated": false,
"p_top": 0.99,
"abstain": null
}
},
"needs_clarification": {
"type": "noul",
"noul": 0.02,
"mouse": {
"calibrated": false,
"p_top": 0.98,
"abstain": null
}
}
},
"usage": {
"input_tokens": 132,
"state_tokens": 31,
"question_tokens": 68,
"framing_tokens": 33,
"image_tokens": 0,
"cached_tokens": 0,
"output_tokens": 0,
"cost_usd": 0.0000132
},
"latency_ms": 42.1
}

Use confidence (or mouse.abstain when using a calibration profile) as a second axis: dispatch directly when confidence is high, and fall back to your full reasoning model when confidence is low.

const { answers } = await decide(state, questions);
// 1. Pre-warm sandbox in parallel if repository access is needed
if (answers.needs_sandbox.noul >= 0.6) {
void ensureSandboxWarmed(threadId);
}
// 2. If the prompt is genuinely ambiguous, ask the user before burning tokens
if (answers.needs_clarification.noul >= 0.85) {
return promptUserForClarification(state.user_prompt);
}
// 3. Confidence-gated tool dispatch
const route = answers.next_tool;
if (route.mouse.abstain === true || route.confidence < 0.65) {
// Uncertain route -> let the full reasoning model plan the turn
return runFullReasoningTurn(state);
}
return dispatchTool(route.choice, state);

Routing across large skill or MCP catalogs (100–1,000 options)

Section titled “Routing across large skill or MCP catalogs (100–1,000 options)”

Because choice supports up to 1,024 options per question, you can pass an entire catalog of MCP tools or agent skills in a single choice question:

  1. Request 1 (Rank & Gate): Pass all skill names and 1-line descriptions in a choice question alongside an any_skill_applies (noul) question.
  2. Shortlist in code: If any_skill_applies.noul < 0.4, load zero skills. Otherwise, take the top 3 skills by probabilities[skill] and inject only their full instructions into the agent's context.