Tables provide typed, structured storage for your agent. You define a schema using z from @botpress/runtime, and the ADK syncs it with Botpress on deploy. Tables are accessible from conversations, workflows, actions, tools, and triggers.
import { Table, z } from "@botpress/runtime"export default new Table({ name: "OrderTable", description: "Customer orders", keyColumn: "userId", columns: { userId: z.string(), items: z.array(z.string()), total: z.number(), status: z.string(), },})
The description field is optional but useful when the table gets surfaced to the LLM (via Zai or knowledge). keyColumn is optional too; it sets the default key used when calling .upsertRows() so you don’t have to pass it on every call.
A computed column is derived from other columns. Set computed: true, pass the columns it depends on into dependencies, and return its value from value:
Computed columns recalculate whenever their dependencies change. When you write to the table, you can pass waitComputed: true to block any further modifications to the table until the recalculation finishes:
Aggregation groups rows by one or more columns and computes summary statistics for other columns. This transforms your table data into summary reports.Pass a group object to findRows() where each key is a column name and the value is either a single operation or an array of operations:
const { rows } = await OrderTable.findRows({ group: { status: "key", // Group by status total: ["sum", "avg"], // Sum and average the total column id: "count", // Count rows in each group },})
The returned rows have different fields based on your group configuration. The field names combine the column name (in camelCase) with the operation:
// For the group config above, each row in the result contains:{ statusKey: "pending", // The grouping value totalSum: 1500.00, // Sum of totals in this group totalAvg: 125.00, // Average of totals in this group idCount: 12, // Number of rows in this group}