API & response format

Querying

Send a query to the orchestrator's /query endpoint. Every response — regardless of which pipeline stage handled it — compiles to the same Pod schema:

{
  "query": "30% of 8 miles",
  "stage_used": 1,
  "assumptions_available": false,
  "pods": [
    { "title": "Input Interpretation", "type": "text",           "content": "8 miles × 30%" },
    { "title": "Result",               "type": "primary_result", "content": "2.4 miles" },
    { "title": "Unit Conversions",     "type": "list",           "content": ["3.862 km", "3862 m", "12672 ft"] },
    { "title": "Comparisons",          "type": "list",           "content": ["≈ 16× length of the Hindenburg"] }
  ]
}

Pod assembly always prepends an Input Interpretation pod and appends a Comparisons pod when a numeric result matches a known magnitude reference.

Pod types

Type Meaning
text Plain text content
primary_result The main answer
list A list of related values
latex LaTeX markup (symbolic math results)
image Base64/URL image (plots)
assumption A labelled assumption used in the computation
error An error explanation
did_you_mean Disambiguation suggestions for ambiguous entities

The stage_used field reports which pipeline stage produced the answer (1 = grammar fast path, 2/3 = LLM-planned), and assumptions_available signals that Fermi-style assumptions are attached.

Rate limiting

Flask-Limiter enforces 30 requests/minute per API key (X-API-Key header) or client IP. Limits are stored in Redis when available.

Caching

  • Cache key: SHA-256 of the query (case-insensitive), prefixed with language and domain hint when non-default.
  • Per-domain TTLs: weather 10 min, temporal 1 h, facts 24 h, math indefinite.
  • Responses containing error pods are never cached.
  • Redis via compose; falls back to a bounded in-memory LRU when Redis is unavailable.

Security & resource controls

Control Mechanism
Query length cap 500 chars at /query; 1000-char expression cap in the data API
Plot expression sanitisation Allowlist regex before the sympy parser
SQL injection guard Connector select fields checked against column whitelists
Process timeouts qalc subprocess: 10 s; tool HTTP calls: 10–30 s

Metrics

In-process counters are exposed at GET /metrics on the orchestrator.