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.