How the agent answers
The loop between your question and the answer, planning, clarifying, running, and verifying.
The agent is a tool loop, not a single model call. Each turn it decides what it needs, calls a tool, reads the result, and decides again.
The gates
Two checks bracket the query, and both exist because a confidently wrong number is worse than no number.
Clarify before computing
If the question names a metric the config does not pin down ("revenue" when
there are three revenue columns and no metrics entry), the agent asks rather
than guessing. Defining the metric in the
config removes the question
permanently.
Verify after computing
Once the query returns, a verification pass checks the result against the question. It is looking for silent failures: an aggregate over an empty set, a join that quietly dropped rows, a filter that matched nothing. A result that fails is flagged rather than presented as fact.
Tools the agent can call
| Tool | When |
|---|---|
| SQL | The default path for a connected database |
| DuckDB | For uploaded files, and for cross-source joins |
| Python | Logic SQL cannot express; sandboxed, reads the result set |
| Chart | Renders the result as an interactive Plotly figure |
| Table | Returns tabular output |
| Web search | External context the database does not contain |
Web search carries a per-search fee, so the agent reaches for it only when the question genuinely needs something outside your data.
Streaming
Answers stream. Over the API you receive tokens as they are generated plus structured events for tool calls, charts, and completion. See the chat API.