Skip to content

C:\> Documentation

Charts and saved reports

A question like 'failures per day this week' deserves a picture. Next week you will want the same picture again, so save it as a report.

Contents

Charts in a thread

Ask for a trend, a breakdown or a single headline number and the agent answers with a chart. It queries your database with the grouping already in the query, sends the rows to the sandbox in your browser under a name, and then calls render_chart with that name and a small specification: the chart type, the category field, the measures, and an optional field to split the rows into series.

The chart is drawn in your browser from rows the model never saw. What the model gets back is an acknowledgement: the title, the type, how many categories and which series. That is all it needs to write the sentence under the picture, and it is all that goes into the stored conversation alongside the drawn data.

Three chart types, chosen by what the question is asking for:

  • barCompare a measure across categories. Several measures draw side by side; a stacked bar shows a total divided into its parts.
  • lineChange over an ordered axis, usually time.
  • statOne number, large. For "how many right now" questions where an axis would only get in the way.
A chart drawn from a query
Ask for it by day and the agent groups in the query, then draws the result in your browser. The rows never enter the conversation; the chart does.
A chart drawn from a query
Screenshot of A chart drawn from a query. Ask for it by day and the agent groups in the query, then draws the result in your browser. The rows never enter the conversation; the chart does.
Ask for it by day and the agent groups in the query, then draws the result in your browser. The rows never enter the conversation; the chart does.

A missing value is drawn as a gap rather than as zero. Negative values hang below the baseline. There is no dual-axis chart on purpose: two measures with different scales are two charts.

Per day, per week, per month

Most trend questions are "per something". The structured query the agent writes can bucket a date or time column by hour, day, week, month or year as part of the grouping, and order by the bucket or by an aggregate, so the whole aggregation happens in your database and only the totals come back.

what the agent asked for
{
  "table": "payment_attempts",
  "where": [{ "column": "status", "op": "=", "value": "failed" }],
  "groupBy": {
    "buckets": [{ "column": "created_at", "unit": "day", "alias": "day" }],
    "aggregates": [{ "function": "count", "column": "*", "alias": "failures" }]
  },
  "orderBy": [{ "column": "day", "dir": "asc" }]
}

On SQL Server the bucket compiles to the DATEADD(DATEDIFF()) idiom, which every supported version understands, and on PostgreSQL to date_trunc. Everything else about the query is unchanged: names are checked against the discovered schema, values travel as parameters, and the statement is read-only and capped.

If a query with a bucket goes through an on-prem connector running an older build, that build does not know the bucket and answers that a grouping needs at least one column. Pull the current image and restart the connector; nothing else needs reconfiguring.

Saved reports

A chart drawn from a query carries Save as report. Give it a name and the query, the environment it ran against and the chart specification are kept together under Reports. Opening a report runs the query again, through the same read-only path the agent uses, and draws the same chart over today's rows, with the rows themselves in a table underneath.

A saved report, run again
The query and the chart, kept together under a name. Opening the report runs the query again and draws today's rows.
A saved report, run again
Screenshot of A saved report, run again. The query and the chart, kept together under a name. Opening the report runs the query again and draws today's rows.
The query and the chart, kept together under a name. Opening the report runs the query again and draws today's rows.

That is the whole feature. It exists for the support engineer who knows exactly which number they need every Monday and whose change-control process means a new report on the reporting server is a fortnight away. Rename it, run it again, delete it when it has done its job.

Not everything can be saved

A chart drawn over rows the agent reshaped with run_js has no single query behind it, so it cannot be saved. Ask the agent to express the grouping in the query instead; it will usually manage, and the chart then becomes a report.

Limits and what we record

A chart holds at most 1000 categories and 12 series. Past that the agent is told to aggregate rather than handed something unreadable. A report's query runs under the same row, size and time caps as any other database query, and the browser tool only appears on a live streamed turn, the same as run_js.

Every chart the agent draws is written to the audit log with its outcome, the dataset it drew from, its type and title, and how many categories and series it holds. Every report a person runs is written with who ran it, which environment, and the exact query. Creating, renaming and deleting a report are audited too.

Need help getting set up?

We do the first setup on a call with you: the CI step, the connection string, and a first investigation against your real code.