Sources
Any CSV, TSV, JSON or Parquet file on a volume can be queried too, as
file:<volume>/<path> under SQL.
You see your own workspace’s datasets. The RL Arena’s three tables are listed for the Arena’s workspace only, when
the dashboard names one (see who can use the Arena).
A dataset’s table follows the dataset’s policy. Under
Mask every text column, text included, holds the masked text, and a row whose text changed since the last
scan shows held back until the personal data scan has run. A file queried as file:datasets/... is the file
as it is on the volume: the policy doesn’t reach it.
Where a row has been reviewed, pii_count, pii_types and
anonymized_text are what the reviewer settled, under every policy.
Explore
- Show as: Number, Bar, Line or Table.
- Measure: count, count distinct, sum, average, median, min, max of a column.
- By: the column to group by; time columns bucket by hour, day, week or month, numeric columns by a bin width. Split by adds a second category: stacked bars, or one line per value.
- Everything is a filter. Click a bar, a point or a category cell and a filter chip appears; every chart and the row table narrow to it. Quick filters list the values of every category column. Click a chip to remove it.
- Rows behind this selection shows the filtered rows; speech rows play their clip inline.
- SQL opens the current chart as DuckDB SQL over the table
src, editable and re-runnable. One SELECT per query (FROM-first andWITHare fine; a second statement,COPY,ATTACH,PRAGMAorSETisn’t), and the query can’t read any file or URL: the connection only ever sees the table. - Ask turns a question in words into SQL with a model, shows the SQL, and runs it. The model is the Arena’s
judge for the Arena’s workspace, else the dashboard’s Anthropic or OpenAI key. It’s sent the column names and
three sample rows, with names and phone numbers masked first. A model outside the platform (Anthropic, OpenAI,
or an endpoint that isn’t a deployment on the platform’s gateway) is only asked once you’ve said that’s fine:
the page asks you once before your question goes out. Say yes and it won’t ask again in that workspace on that
browser; say no and nothing is sent. Over the API, send
allow_external: truewith the question; without it the answer is a 409 with{"detail": {"code": "external_consent_required", "message": "..."}}. The judge on the platform needs no yes.
Board
Pin to board keeps a chart or a number. Tiles on the board share the filter chips, so clicking a bar in one tile narrows every tile. The board is saved in the browser for now.Dashboards
Insights → Dashboards holds named boards, saved for the workspace rather than for one browser. A board is a twelve-column grid of panels, and a panel is one question: a source, a query, a visualisation and its options.- Add panel opens the editor: source, Build or SQL, the query, then the visualisation and its options, with a live preview of the panel exactly as it will appear.
- Visualisations: stat (with sparkline and thresholds), gauge, bar (grouped, stacked or horizontal), line, area, pie or donut, heatmap (two categories against a measure), table (thresholds colour the numbers), and text for a note explaining the board.
- Options per panel: unit, decimals, legend, stacking, orientation, value labels, min and max, and colour thresholds, plus the panel’s width (of twelve) and height.
- Cross-filtering: clicking a bar, slice or category cell adds a board filter, and every panel that has that column narrows to it. Filters show as chips at the top and clear with a click.
- Drag a panel by its handle to reorder the board. Refresh re-runs everything, or set an interval from ten seconds to five minutes.
- Export downloads the board as JSON, and Import on the Dashboards tab creates a board from one, so a board moves between workspaces or lives in a repository next to the code it watches.
GET|POST /api/insights/dashboards, GET|PUT|DELETE /api/insights/dashboards/{id}. The document a
board exports is exactly what the API stores.
Engine
The dashboard API loads each source into DuckDB on demand (cached for thirty seconds per token) and runs the query there, so sources with hundreds of thousands of rows answer in well under a second. Routes:GET /api/insights/sources, GET /api/insights/sources/{source}/columns, POST /api/insights/query (a
builder spec), POST /api/insights/sql, POST /api/insights/ask.
