Tables and Agent Tools#
A table holds the structured state of a workspace: books you are reading, calendar blocks, leads, metric samples. What a row is comes from the columns the table declares, and that declaration is what lets you edit a row as a form, and an agent add one by name while reaching nothing else.
What a table is#
A table is a named set of typed columns and the rows they hold. A column's declared kind decides
what a cell means: what it can hold, which control edits it, and what a write has to satisfy to be
stored. Every row also carries an id, which is not a column.
A column's name is its column name. There is no second name and no separate label: the label
you see is Title Case of the name, so release_date shows as "Release Date". A rename keeps the
kind and every value, and workflows, Data Views, and saved queries that reference the old name do
not follow it.
A kind is what the column means; how it is stored follows from it. There are fourteen, in the order the picker offers them:
| Kind | Holds |
|---|---|
| Text | One line of free text |
| Long text | Multi-line prose |
| Block document | Rich document content, the same format a task description uses |
| JSON | Freeform JSON: objects, lists, strings, numbers, booleans, and nested nulls |
| Tool group | One configured tool group, chosen with the shared tool picker |
| Select | Exactly one option from a closed list you define, each one optionally toned |
| Resource | A link to one workspace resource — a document, a workflow, a table, or a memory |
| Integer | A whole number |
| Decimal | A fractional number |
| Boolean | Yes or no |
| Date | A calendar day, no time |
| Date and time | An instant, stored in UTC and shown in your timezone |
| List | An ordered list of one declared entry kind |
| Object | A named shape with its own declared columns, closed to anything else |
A Select accepts only its options, an Integer rejects 3.5, a Resource accepts only the id of a
resource of the kind it names, and an Object rejects a key it does not declare. JSON is the one
kind that checks nothing, which makes it right for data whose shape is genuinely open — a provider
response, a webhook body — and wrong for a shape you have merely not written down yet.
Five kinds carry an interior, declared beside the kind:
- Select declares its Options, each with an optional tone. With no options it can hold nothing.
- List declares what Each entry is.
- Object declares its own columns, which may nest further.
- Resource declares what it Points at — a document, a workflow, a table, or a memory.
- Tool group declares the Surface its tools run on, which is what the picker offers.
Declaring a reading list#
1. Create the table. Open Tables, choose Create Table, and set Name to
Reading List; the handle reading-list is minted from the name, and Handle (optional) takes
a different one where the minted one is wrong.
2. Declare the columns. Each row of the Columns editor takes a name, a kind, a Required switch, and a description:
title Text
author Text
status Select — unread, reading, finished
rating Integer
added_at Date and time
status as a Select rather than Text is the difference between an agent that writes finished and
one that writes Finished, done, or read.
3. Add a row. Open the table, choose Add Row, and fill the form. The write is checked
against the declaration, so a rating of 4.5 or a status of abandoned is refused rather than
stored.
Note: the grid opens locked. Existing cells are read-only, and Add column and Edit column are disabled, until you open the lock beside Rows.
The assistant does all three, and reaches for the narrowest kind that fits:
Create a reading-list table with a title, an author, a status of unread/reading/finished, an integer rating, and an added timestamp.
Changing a declaration#
Columns are added, renamed, retyped, and dropped from Add column and Edit column in the grid's column headers, or by asking the assistant.
A change within one storage class is instant. Text to Select, Select to Long text, Decimal to Integer: the column does not move and no stored value is rewritten.
A change the stored values do not satisfy is refused, naming the row that disagrees. Narrowing a Select while a row still holds the option you are removing fails, and so does tightening Decimal to Integer over a fractional value. Repair or clear those rows, then make the change.
Dropping a column that still holds values is refused. Clear it deliberately first.
Note: a new Required column on a table that already has rows is refused, because the rows already there cannot satisfy it. Add it optional, backfill it, then make it required.
Editing rows#
In the grid, each cell is edited by the control its kind names.
- A Select is a dropdown. The chosen option reads Title Cased behind a dot in its tone, and
reads
Not setwhile an optional column is empty. - A Date and a Date and time open a picker — a calendar day for one, a day and a time for the other, shown in your timezone.
- A Resource is a chip naming its target, with a picker to retarget it. The row stores the id alone and the name is resolved from the target, so a rename keeps up.
- A Block document is the document editor, inline in the cell.
- Long text is a textarea, Boolean a switch, and Integer and Decimal number inputs stepping by 1 and 0.1.
JSON, List, and Object have no cell-sized control: the cell previews the value and opens a full editor from the pencil. The Add Row form has the room, so there an Object unfolds into its own declared columns and a List into its entries.
When a row breaks the declaration#
Every write is checked against the declaration, so nothing you write through a table creates a bad row. The database underneath checks the storage rather than the meaning — no column of it can test select membership or an object's shape — so a row that predates the declaration it is now read against can still violate it.
That produces one broken row, not a broken table. A read tags every row with its state:
- Valid — satisfies the declaration.
- Broken — does not, and says which column and why. It keeps its place in the grid as Broken row, with Show values for the raw values, Repair to edit them, and Delete row.
- Unreadable — carried no readable id, so it is shown but cannot be repaired or deleted from the grid.
A read never fails as a whole and never drops a row, and a broken row is counted in the total, so an agent asked how many books are on the list cannot undercount because one row is malformed. A repair is checked like any other write: a fix that still breaks the declaration is refused rather than stored.
Scoped tools over one table#
An agent working from the workspace table tools — list_tables, query_table, insert_table_row
and the rest — has to work out which table you meant and read its columns first, and those tools
reach every table in the workspace. They are the right tools for authoring and ad-hoc work, and the
wrong ones for an agent whose job is your reading list.
The Table Tools node replaces both problems with one dropdown.
4. Add a Table Tools node. Set Table to Reading List and leave the operation checkboxes
as they are.
It composes one tool per enabled operation, prefixed with the table's name in snake_case:
reading_list_query filter, sort, and page rows
reading_list_get read one row by id
reading_list_add add one row
reading_list_update change columns of one row
reading_list_remove delete one row — off by default
Each parameter schema is generated from the table's columns, so reading_list_add shows the agent
title, author, status as an enum of its three options, rating as an integer, and added_at
as a timestamp. A List arrives as a typed array and an Object as a closed shape. These tools cannot
reach another table, and cannot write a column the table does not declare.
5. Wire it into the agent. Connect the node's tools socket to the AI node's tools socket, or
into the Flatten node feeding it if other tool providers are already there.
Note: one node targets one table. A second table is a second node — the tool names differ, so both feed the same AI node.
Set Tool Name when the derived prefix collides with another node's, or when the table's name makes a poor tool name. Every generated name has to be ASCII letters, numbers, underscores, or hyphens, and at most 64 characters; the node reports a name it cannot generate when you save the workflow, rather than failing mid-conversation.
A table's AI access settings gate all of this. With AI tools can read or AI tools can write off, these tools refuse that operation; a scoped tool grants nothing the table withholds.
Next steps#
Data Views put a table's rows on a Pegboard as a table, a card list, or a checklist.