Skip to content

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.

Terminal window
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 once
aw coll.query collection=expenses where:='{"note":"taxi"}' search=hotel sort=-amount limit=50
aw coll.update collection=expenses id=<ID> set:='{"amount":13}' if_version=2
aw 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.update changes only the given fields; null clears a field.
  • Versions: every row has one; if_version gives a conflict instead of overwriting.
  • Changing columns: coll.alter replaces the column list. Values of removed columns stay stored and come back if the column returns.
  • Dropping a collection: coll.drop deletes the table and all rows. It defaults to ask for agents.
  • Reacting to changes: use events.wait module=coll subject_prefix=expenses/.

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.

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:number
qty:number
total:number:Total = row.price * row.qty
big:bool = row.total >= 100
net: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) and today(), plus all of JavaScript’s Math.
  • Read-only: computed columns can’t be written; coll.add and coll.update reject them.
  • Queries: filters, search and sort work on computed values like any other column.
  • Errors: a failing formula shows #ERR in that cell (hover for the reason). The API returns the reason in the row’s errors; 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:

Terminal window
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.