Skip to content

Smart Router (Tool/Web Routing)

Last Verified: February 2026
Scope: Routing tool/web queries to the cheapest viable data source.

This document is about SmartRouter (web/tools). It is not the same as SmartMessageRouter (message routing between MiniApps/workflows/conversation).


Goals

  • Decide when a user request needs current info (web search) vs internal context.
  • Route to the lowest-cost provider that can satisfy the request.
  • Provide structured metadata (source, cost) and a clean fallback to GPT‑5 generation.

Key files

  • Router: app/orchestrator/smart_router.py
  • Analyzer (LLM-assisted intent/complexity): app/orchestrator/query_analyzer.py
  • Providers + adapters: app/orchestrator/providers/
  • Perplexity client (httpx + tracing): app/utils/perplexity_client.py

Cost / source hierarchy (current)

SmartRouter attempts (cheapest → most expensive):

  1. Free APIs (e.g., weather)
  2. OAuth APIs (calendar/email, if connected)
  3. Parallel Search (if configured) — deep/multi-hop, structured research
  4. Perplexity (if configured) — fast web search
  5. GPT‑5 fallback — no web call (router returns response=None)

Provider availability is driven by env vars: - PARALLEL_API_KEY enables Parallel provider - PERPLEXITY_API_KEY enables Perplexity provider


Execution flow (simplified)

  1. QueryAnalyzer.analyze() classifies:
  2. complexity: simple / multi-intent / multi-step / ambiguous / conversational
  3. per-intent data_source recommendations

  4. SmartRouter.route():

  5. handles ambiguous/multi-intent logic
  6. executes the recommended provider (with fallback to Perplexity when appropriate)
  7. returns:
    { "response": "...", "source": "perplexity", "cost": 0.005, "metadata": {} }
    
  8. or returns GPT‑5 fallback signal:
    { "response": null, "source": "gpt5", "cost": 0.03, "metadata": {"reason": "..."} }
    

Where it’s used

The tool/router layer is invoked by the orchestrator when a message requires external info/tooling: - app/orchestrator/tool_executor.py