| 1 | -- A workspace's own agents (docs/WORKSPACE.md, "Agents"): their |
| 2 | -- definitions, every version of them, each reply they gave and what it |
| 3 | -- cost, and spend rolled up by month and day for their budgets. |
| 4 | |
| 5 | -- One row per agent. Routing, budget and autonomy are small JSON objects |
| 6 | -- (@g1t/contracts workspace-agents.ts), read and written whole. |
| 7 | CREATE TABLE agents ( |
| 8 | id TEXT PRIMARY KEY, |
| 9 | -- By id, not slug: a renamed workspace keeps its agents. |
| 10 | workspace_id TEXT NOT NULL, |
| 11 | handle TEXT NOT NULL, |
| 12 | display_name TEXT NOT NULL, |
| 13 | avatar TEXT, |
| 14 | role TEXT NOT NULL, |
| 15 | instructions TEXT NOT NULL, |
| 16 | personality_preset TEXT NOT NULL DEFAULT 'crisp', |
| 17 | personality TEXT NOT NULL DEFAULT '', |
| 18 | routing TEXT NOT NULL, |
| 19 | budget TEXT NOT NULL, |
| 20 | autonomy TEXT NOT NULL, |
| 21 | capacity INTEGER NOT NULL DEFAULT 3, |
| 22 | template TEXT, |
| 23 | version INTEGER NOT NULL DEFAULT 1, |
| 24 | -- The desk's presence: a reply is in flight until this time. A time, not |
| 25 | -- a flag, so a desk that died mid-reply never leaves it "working". |
| 26 | busy_until TEXT, |
| 27 | created_by TEXT NOT NULL, |
| 28 | created_at TEXT NOT NULL, |
| 29 | updated_at TEXT NOT NULL, |
| 30 | archived_at TEXT |
| 31 | ); |
| 32 | |
| 33 | -- A handle is unique among a workspace's agents that are not archived: |
| 34 | -- archiving one frees its handle, and its old messages still resolve by id. |
| 35 | CREATE UNIQUE INDEX agents_handle ON agents (workspace_id, handle) WHERE archived_at IS NULL; |
| 36 | CREATE INDEX agents_workspace ON agents (workspace_id, archived_at); |
| 37 | |
| 38 | -- Every version of every definition, as it was saved, for the profile's |
| 39 | -- history and for runs to say which version they ran. |
| 40 | CREATE TABLE agent_versions ( |
| 41 | agent_id TEXT NOT NULL, |
| 42 | version INTEGER NOT NULL, |
| 43 | definition TEXT NOT NULL, |
| 44 | changed_by TEXT NOT NULL, |
| 45 | created_at TEXT NOT NULL, |
| 46 | PRIMARY KEY (agent_id, version) |
| 47 | ); |
| 48 | |
| 49 | -- Each message an agent was handed, and what came of it: spend and audit. |
| 50 | -- status: working, replied, failed, blocked (budget or access; a short |
| 51 | -- notice was posted, or kept back as a repeat), skipped (hop limit). |
| 52 | CREATE TABLE agent_replies ( |
| 53 | id TEXT PRIMARY KEY, |
| 54 | agent_id TEXT NOT NULL, |
| 55 | workspace_id TEXT NOT NULL, |
| 56 | channel_id TEXT NOT NULL, |
| 57 | -- The message that woke it; one reply per message, however often it is handed over. |
| 58 | message_id TEXT NOT NULL, |
| 59 | -- The message the agent posted, when it posted one. |
| 60 | reply_id TEXT, |
| 61 | asked_by TEXT, |
| 62 | agent_version INTEGER, |
| 63 | model TEXT, |
| 64 | tier TEXT, |
| 65 | input_tokens INTEGER NOT NULL DEFAULT 0, |
| 66 | output_tokens INTEGER NOT NULL DEFAULT 0, |
| 67 | -- What the model cost at the provider's price, in millionths of a dollar. |
| 68 | cost_micros INTEGER NOT NULL DEFAULT 0, |
| 69 | -- What it counts against the agent's budget: the model at price plus |
| 70 | -- the agent rate. Billing's ledger, with comped terms and discounts, is |
| 71 | -- what the workspace is actually charged. |
| 72 | charged_micros INTEGER NOT NULL DEFAULT 0, |
| 73 | status TEXT NOT NULL, |
| 74 | error TEXT, |
| 75 | created_at TEXT NOT NULL, |
| 76 | finished_at TEXT |
| 77 | ); |
| 78 | |
| 79 | CREATE UNIQUE INDEX agent_replies_message ON agent_replies (agent_id, message_id); |
| 80 | CREATE INDEX agent_replies_recent ON agent_replies (agent_id, created_at); |
| 81 | CREATE INDEX agent_replies_channel ON agent_replies (agent_id, channel_id, status, created_at); |
| 82 | |
| 83 | -- Spend by agent and period: `YYYY-MM` for the month, `YYYY-MM-DD` for the |
| 84 | -- day, both UTC. Budgets and `spent_month_micros` read these, never a sum |
| 85 | -- over every reply. |
| 86 | CREATE TABLE agent_spend ( |
| 87 | agent_id TEXT NOT NULL, |
| 88 | period TEXT NOT NULL, |
| 89 | micros INTEGER NOT NULL DEFAULT 0, |
| 90 | replies INTEGER NOT NULL DEFAULT 0, |
| 91 | PRIMARY KEY (agent_id, period) |
| 92 | ); |