Contents
Getting started
Using Codepanion
Connecting your tools
Exact calculations
"How many of these 900 orders settled late, and what's the median delay?" is exactly the kind of question a model answers confidently and wrongly. The run_js tool exists so it doesn't have to: the agent writes a short JavaScript snippet, the snippet runs, and the agent reads back the value it returned. Parsing, filtering, aggregation, date maths and regular expressions are all computed.
State carries across calls within one investigation, so the agent can build a calculation up in steps (define a helper in one call, use it in the next) rather than restating everything each time.
Piping query results in
A database query can send its rows to the sandbox instead of to the model. The agent names a dataset; the full result set is delivered to your browser and appears there as an array of row objects under that name, ready for a follow-up run_js call.
late = orders.filter(o => o.settled_at > o.due_at);
({ late: late.length, total: orders.length })What the model gets back from the query is only a compact summary: the row count, the column names, and up to five sample rows. The rows themselves never enter the model's context and are never written into the stored conversation. They exist in the browser tab you have open, and go away with it. It means an investigation can compute across hundreds of production rows without those rows becoming part of a transcript.
Your side of it loses nothing: the query step still reports how many rows it fetched, and the calculation step carries the exact snippet and the value it returned.
The same dataset can be drawn instead of computed over: the agent's render_chart tool reads it from the sandbox and draws it in your browser. See charts and saved reports.
A dataset is capped at 5 MB once serialised. Over that, nothing is delivered and the agent is told to narrow the query (fewer columns, a tighter filter, a lower limit) rather than being handed a truncated result it might read as complete. On a turn that isn't streaming there is no browser to deliver to, so the agent works from the summary or asks for the rows directly.
Where it runs, and its limits
The sandbox runs in your own browser and has access only to standard JavaScript language built-ins (JSON, Math, Date, Array, String, RegExp). It has no network, page, file or host access. A snippet cannot touch the Codepanion app around it or read anything you didn't already query.
Each call gets five seconds of wall clock. A snippet still running at the limit is killed outright rather than asked to stop, which also clears the sandbox's accumulated state. The agent is told both things, so it retries with a bounded calculation instead of quietly losing its working.
Good to know
The agent writes the code that runs here, and it sees only data you already asked for. Your connection-string resolver runs separately on the server or on your connector. See catalog databases.
What you see and what we record
A calculation is an ordinary tool step in the thread: summarised in plain language, with the exact snippet and the value it returned behind Show Details. Every call is also written to the audit log against its investigation (the outcome, the length of the snippet, and the opening of it) because it computed over production data, even though it did so on your own machine.