Collections
A collection is a table with typed columns. Each row is a JSON object, a document, checked against the columns. People edit it as a sheet; agents use tools.
Column types: text, number, bool, date (YYYY-MM-DD or RFC 3339) and json.
aw coll.create name=expenses columns:='[{"name":"date","type":"date"},{"name":"amount","type":"number"},{"name":"note","type":"text"}]'aw coll.add collection=expenses row:='{"date":"2026-10-03","amount":12.5,"note":"taxi"}'aw coll.add collection=expenses rows:='[{…},{…}]' # up to 500 at onceaw coll.query collection=expenses where:='{"note":"taxi"}' search=hotel sort=-amount limit=50aw coll.update collection=expenses id=<ID> set:='{"amount":13}' if_version=2aw coll.delete collection=expenses id=<ID>- Validation: unknown columns and wrong types are rejected with the list of valid columns, which catches typos.
- Partial updates:
coll.updatechanges only the given fields;nullclears a field. - Versions: every row has one;
if_versiongives a conflict instead of overwriting. - Changing columns:
coll.alterreplaces the column list. Values of removed columns stay stored and come back if the column returns. - Dropping a collection:
coll.dropdeletes the table and all rows. It defaults toaskfor agents. - Reacting to changes: use
events.wait module=coll subject_prefix=expenses/.
The sheet
Section titled “The sheet”Click a cell to edit. Enter saves and Esc cancels; clicking elsewhere saves if you changed something. Bool cells toggle with one click. The input row at the bottom adds a row. You can sort by any column, search, and page through 200 rows at a time. Changes by agents appear within seconds; refreshing pauses while you edit.
Computed columns
Section titled “Computed columns”A column with a formula is computed: a JavaScript expression over the row, evaluated every time rows are read, so it’s never stale. In the column editor, write name:type = formula:
price:numberqty:numbertotal:number:Total = row.price * row.qtybig:bool = row.total >= 100net:number = round(row.total / 1.19, 2)wait:number = row.due ? days(today(), row.due) : null- References: a formula sees the row’s fields as
row.name, including computed columns to its left, so formulas can build on each other. - Helpers:
round(x, digits),days(from, to)andtoday(), plus all of JavaScript’sMath. - Read-only: computed columns can’t be written;
coll.addandcoll.updatereject them. - Queries: filters, search and sort work on computed values like any other column.
- Errors: a failing formula shows
#ERRin that cell (hover for the reason). The API returns the reason in the row’serrors; the query itself still succeeds. - Safety: formulas run in an isolated JavaScript interpreter with no access to anything but the row, under a time limit of 2 seconds per read. A formula that hits the limit is paused for a minute. Fixing it takes effect immediately.
Via the API, a computed column is a column with formula:
aw coll.alter name=orders columns:='[…, {"name":"total","type":"number","formula":"row.price * row.qty"}]'To act on changes (send a message, update another table) or to run something on a schedule, use functions.