Skip to content
207 linesCodeBlameRaw
1-- Sessions, memory, routines and the workspace's agent policy
2-- (docs/WORKSPACE.md, "Sessions", "Memory", "Routines", "Budgets").
3
4-- One row per session: a bounded piece of work an agent took on. Talking
5-- to an agent is a reply (agent_replies); real work is a session, with its
6-- own context, transcript, cap and live card. Sessions form trees: a
7-- session starts others for its subagents or for colleagues it brings in,
8-- and the whole tree is paid by the agent at its root (payer_agent_id).
9CREATE TABLE agent_sessions (
10 id TEXT PRIMARY KEY,
11 workspace_id TEXT NOT NULL,
12 agent_id TEXT NOT NULL,
13 -- The subagent running it, by name, for kind `subagent`.
14 subagent TEXT,
15 -- chat, routine, helper or subagent.
16 kind TEXT NOT NULL,
17 parent_id TEXT,
18 root_id TEXT NOT NULL,
19 payer_agent_id TEXT NOT NULL,
20 title TEXT NOT NULL,
21 goal TEXT NOT NULL,
22 -- queued, working, waiting, needs_approval, done, failed or stopped.
23 status TEXT NOT NULL,
24 status_note TEXT,
25 summary TEXT,
26 -- Where it was asked and where it reports, and who asked with what access
27 -- (the asker's access caps everything it reads and does).
28 workspace TEXT NOT NULL,
29 channel_id TEXT NOT NULL,
30 channel_kind TEXT NOT NULL,
31 channel_name TEXT,
32 -- The conversation's thread the request was in (null: top level).
33 thread_root TEXT,
34 message_id TEXT,
35 card_message_id TEXT,
36 asked_by TEXT,
37 asked_by_username TEXT,
38 asker TEXT,
39 routine_id TEXT,
40 -- The agents that handed this work along, oldest first (hop limit, no ping-pong).
41 chain TEXT NOT NULL DEFAULT '[]',
42 hops INTEGER NOT NULL DEFAULT 0,
43 -- The model's working context: a bounded list of turns, compacted as it
44 -- grows. The full record is agent_session_events.
45 context TEXT NOT NULL DEFAULT '[]',
46 -- What arrived while it worked (steering, helpers' results), read at its next step.
47 inbox TEXT NOT NULL DEFAULT '[]',
48 steps INTEGER NOT NULL DEFAULT 0,
49 tool_calls INTEGER NOT NULL DEFAULT 0,
50 input_tokens INTEGER NOT NULL DEFAULT 0,
51 output_tokens INTEGER NOT NULL DEFAULT 0,
52 cost_micros INTEGER NOT NULL DEFAULT 0,
53 charged_micros INTEGER NOT NULL DEFAULT 0,
54 cap_micros INTEGER,
55 model TEXT,
56 outputs TEXT NOT NULL DEFAULT '[]',
57 -- When its current step started: a step that never finished is picked up again.
58 step_started_at TEXT,
59 created_at TEXT NOT NULL,
60 updated_at TEXT NOT NULL,
61 finished_at TEXT
62);
63
64CREATE INDEX agent_sessions_agent ON agent_sessions (agent_id, created_at);
65CREATE INDEX agent_sessions_workspace ON agent_sessions (workspace_id, status, created_at);
66CREATE INDEX agent_sessions_root ON agent_sessions (root_id);
67CREATE INDEX agent_sessions_parent ON agent_sessions (parent_id);
68CREATE INDEX agent_sessions_card ON agent_sessions (card_message_id);
69CREATE INDEX agent_sessions_payer ON agent_sessions (payer_agent_id, created_at);
70
71-- A session's transcript, as its page shows it: what it was asked, what
72-- it said, every tool it used (arguments cut, never results), steering,
73-- updates it posted, sessions it started, and its report.
74CREATE TABLE agent_session_events (
75 session_id TEXT NOT NULL,
76 seq INTEGER NOT NULL,
77 kind TEXT NOT NULL,
78 by_name TEXT,
79 body TEXT NOT NULL,
80 tool TEXT,
81 outcome TEXT,
82 created_at TEXT NOT NULL,
83 PRIMARY KEY (session_id, seq)
84);
85
86-- What an agent remembers, each fact with its source and a scope that
87-- decides where it may be recalled: workspace, a channel, or one person's
88-- direct messages (scope_ref: the channel or user id).
89CREATE TABLE agent_memories (
90 id TEXT PRIMARY KEY,
91 agent_id TEXT NOT NULL,
92 workspace_id TEXT NOT NULL,
93 scope TEXT NOT NULL,
94 scope_ref TEXT NOT NULL DEFAULT '',
95 scope_label TEXT,
96 body TEXT NOT NULL,
97 source_kind TEXT NOT NULL,
98 source_ref TEXT,
99 source_label TEXT,
100 source_channel_id TEXT,
101 created_by TEXT NOT NULL,
102 created_by_kind TEXT NOT NULL,
103 pinned INTEGER NOT NULL DEFAULT 0,
104 created_at TEXT NOT NULL,
105 updated_at TEXT NOT NULL
106);
107
108CREATE INDEX agent_memories_agent ON agent_memories (agent_id, scope, scope_ref);
109
110-- Work an agent does on a schedule: each run is a session in the routine's
111-- channel, with the access of the person who set it up (sponsor).
112CREATE TABLE agent_routines (
113 id TEXT PRIMARY KEY,
114 agent_id TEXT NOT NULL,
115 workspace_id TEXT NOT NULL,
116 -- The workspace's slug when it was saved, for posting and billing.
117 workspace TEXT NOT NULL,
118 name TEXT NOT NULL,
119 instructions TEXT NOT NULL,
120 -- JSON: every (hour, day, weekday, week), minute, hour, weekday. UTC.
121 -- Null when it runs only on events.
122 schedule TEXT,
123 -- JSON lists: what it runs on (pull_ready, checks_failed...), and which
124 -- repositories those come from (workspace/name; empty: any its sponsor can read).
125 events TEXT NOT NULL DEFAULT '[]',
126 repos TEXT NOT NULL DEFAULT '[]',
127 channel_id TEXT NOT NULL,
128 channel_name TEXT,
129 sponsor TEXT NOT NULL,
130 sponsor_username TEXT,
131 enabled INTEGER NOT NULL DEFAULT 1,
132 paused_note TEXT,
133 next_run_at TEXT,
134 last_run_at TEXT,
135 last_session_id TEXT,
136 runs INTEGER NOT NULL DEFAULT 0,
137 created_at TEXT NOT NULL,
138 updated_at TEXT NOT NULL
139);
140
141CREATE INDEX agent_routines_agent ON agent_routines (agent_id);
142CREATE INDEX agent_routines_due ON agent_routines (enabled, next_run_at);
143CREATE INDEX agent_routines_workspace ON agent_routines (workspace_id, enabled);
144
145-- What each routine ran on, so one thing that happened runs it once.
146CREATE TABLE agent_routine_runs (
147 routine_id TEXT NOT NULL,
148 -- The event's kind and what it was about: pull_ready:rep_1:12.
149 run_key TEXT NOT NULL,
150 session_id TEXT,
151 created_at TEXT NOT NULL,
152 PRIMARY KEY (routine_id, run_key)
153);
154CREATE INDEX agent_routine_runs_recent ON agent_routine_runs (routine_id, created_at);
155
156-- The workspace's say over all its agents together.
157CREATE TABLE agent_policies (
158 workspace_id TEXT PRIMARY KEY,
159 monthly_micros INTEGER,
160 default_agent_monthly_micros INTEGER,
161 default_session_micros INTEGER NOT NULL DEFAULT 2000000,
162 updated_by TEXT,
163 updated_at TEXT NOT NULL
164);
165
166-- Every agent's spend together, by workspace and period (YYYY-MM, YYYY-MM-DD),
167-- for the workspace's agent budget; and which alerts went out this month.
168CREATE TABLE workspace_agent_spend (
169 workspace_id TEXT NOT NULL,
170 period TEXT NOT NULL,
171 micros INTEGER NOT NULL DEFAULT 0,
172 alerted INTEGER NOT NULL DEFAULT 0,
173 PRIMARY KEY (workspace_id, period)
174);
175
176-- Replies say who they were for, where, and how many tools they used, for
177-- the spend breakdown and the Activity tab.
178ALTER TABLE agent_replies ADD COLUMN asked_by_username TEXT;
179ALTER TABLE agent_replies ADD COLUMN channel_name TEXT;
180ALTER TABLE agent_replies ADD COLUMN tool_count INTEGER NOT NULL DEFAULT 0;
181-- Session steps counted with the agent's spend, beside replies.
182ALTER TABLE agent_spend ADD COLUMN sessions INTEGER NOT NULL DEFAULT 0;
183
184-- Issues an agent drafted in a conversation, as cards with File and
185-- Discard: whoever presses File files it as themselves, if they can read
186-- the repository. status: draft, filed, discarded.
187CREATE TABLE agent_drafts (
188 id TEXT PRIMARY KEY,
189 agent_id TEXT NOT NULL,
190 workspace_id TEXT NOT NULL,
191 workspace TEXT NOT NULL,
192 channel_id TEXT NOT NULL,
193 message_id TEXT,
194 session_id TEXT,
195 repo_id TEXT NOT NULL,
196 repo TEXT NOT NULL,
197 title TEXT NOT NULL,
198 body TEXT NOT NULL,
199 labels TEXT NOT NULL DEFAULT '[]',
200 asked_by TEXT,
201 status TEXT NOT NULL DEFAULT 'draft',
202 filed_by TEXT,
203 number INTEGER,
204 created_at TEXT NOT NULL,
205 updated_at TEXT NOT NULL
206);
207CREATE INDEX agent_drafts_message ON agent_drafts (message_id);