agent-inbox 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CLAUDE.md +113 -0
  2. package/README.md +195 -1
  3. package/dist/federation/address.d.ts +24 -0
  4. package/dist/federation/address.d.ts.map +1 -0
  5. package/dist/federation/address.js +54 -0
  6. package/dist/federation/address.js.map +1 -0
  7. package/dist/federation/connection-manager.d.ts +118 -0
  8. package/dist/federation/connection-manager.d.ts.map +1 -0
  9. package/dist/federation/connection-manager.js +369 -0
  10. package/dist/federation/connection-manager.js.map +1 -0
  11. package/dist/federation/delivery-queue.d.ts +66 -0
  12. package/dist/federation/delivery-queue.d.ts.map +1 -0
  13. package/dist/federation/delivery-queue.js +199 -0
  14. package/dist/federation/delivery-queue.js.map +1 -0
  15. package/dist/federation/index.d.ts +7 -0
  16. package/dist/federation/index.d.ts.map +1 -0
  17. package/dist/federation/index.js +6 -0
  18. package/dist/federation/index.js.map +1 -0
  19. package/dist/federation/routing-engine.d.ts +74 -0
  20. package/dist/federation/routing-engine.d.ts.map +1 -0
  21. package/dist/federation/routing-engine.js +158 -0
  22. package/dist/federation/routing-engine.js.map +1 -0
  23. package/dist/federation/trust.d.ts +39 -0
  24. package/dist/federation/trust.d.ts.map +1 -0
  25. package/dist/federation/trust.js +64 -0
  26. package/dist/federation/trust.js.map +1 -0
  27. package/dist/index.d.ts +60 -2
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +217 -18
  30. package/dist/index.js.map +1 -1
  31. package/dist/ipc/ipc-server.d.ts +20 -0
  32. package/dist/ipc/ipc-server.d.ts.map +1 -0
  33. package/dist/ipc/ipc-server.js +152 -0
  34. package/dist/ipc/ipc-server.js.map +1 -0
  35. package/dist/jsonrpc/mail-server.d.ts +45 -0
  36. package/dist/jsonrpc/mail-server.d.ts.map +1 -0
  37. package/dist/jsonrpc/mail-server.js +284 -0
  38. package/dist/jsonrpc/mail-server.js.map +1 -0
  39. package/dist/map/map-client.d.ts +91 -0
  40. package/dist/map/map-client.d.ts.map +1 -0
  41. package/dist/map/map-client.js +202 -0
  42. package/dist/map/map-client.js.map +1 -0
  43. package/dist/mcp/mcp-server.d.ts +23 -0
  44. package/dist/mcp/mcp-server.d.ts.map +1 -0
  45. package/dist/mcp/mcp-server.js +226 -0
  46. package/dist/mcp/mcp-server.js.map +1 -0
  47. package/dist/push/notifier.d.ts +49 -0
  48. package/dist/push/notifier.d.ts.map +1 -0
  49. package/dist/push/notifier.js +150 -0
  50. package/dist/push/notifier.js.map +1 -0
  51. package/dist/registry/warm-registry.d.ts +63 -0
  52. package/dist/registry/warm-registry.d.ts.map +1 -0
  53. package/dist/registry/warm-registry.js +173 -0
  54. package/dist/registry/warm-registry.js.map +1 -0
  55. package/dist/router/message-router.d.ts +44 -0
  56. package/dist/router/message-router.d.ts.map +1 -0
  57. package/dist/router/message-router.js +137 -0
  58. package/dist/router/message-router.js.map +1 -0
  59. package/dist/storage/interface.d.ts +31 -0
  60. package/dist/storage/interface.d.ts.map +1 -0
  61. package/dist/storage/interface.js +2 -0
  62. package/dist/storage/interface.js.map +1 -0
  63. package/dist/storage/memory.d.ts +28 -0
  64. package/dist/storage/memory.d.ts.map +1 -0
  65. package/dist/storage/memory.js +118 -0
  66. package/dist/storage/memory.js.map +1 -0
  67. package/dist/storage/sqlite.d.ts +35 -0
  68. package/dist/storage/sqlite.d.ts.map +1 -0
  69. package/dist/storage/sqlite.js +445 -0
  70. package/dist/storage/sqlite.js.map +1 -0
  71. package/dist/traceability/traceability.d.ts +29 -0
  72. package/dist/traceability/traceability.d.ts.map +1 -0
  73. package/dist/traceability/traceability.js +150 -0
  74. package/dist/traceability/traceability.js.map +1 -0
  75. package/dist/types.d.ts +253 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +3 -0
  78. package/dist/types.js.map +1 -0
  79. package/docs/DESIGN.md +1156 -0
  80. package/docs/PLAN.md +545 -0
  81. package/hooks/inbox-hook.mjs +119 -0
  82. package/hooks/register-hook.mjs +69 -0
  83. package/package.json +33 -25
  84. package/rules/agent-inbox.md +78 -0
  85. package/src/federation/address.ts +61 -0
  86. package/src/federation/connection-manager.ts +458 -0
  87. package/src/federation/delivery-queue.ts +222 -0
  88. package/src/federation/index.ts +6 -0
  89. package/src/federation/routing-engine.ts +188 -0
  90. package/src/federation/trust.ts +71 -0
  91. package/src/index.ts +299 -0
  92. package/src/ipc/ipc-server.ts +180 -0
  93. package/src/jsonrpc/mail-server.ts +356 -0
  94. package/src/map/map-client.ts +260 -0
  95. package/src/mcp/mcp-server.ts +272 -0
  96. package/src/push/notifier.ts +192 -0
  97. package/src/registry/warm-registry.ts +210 -0
  98. package/src/router/message-router.ts +175 -0
  99. package/src/storage/interface.ts +48 -0
  100. package/src/storage/memory.ts +145 -0
  101. package/src/storage/sqlite.ts +645 -0
  102. package/src/traceability/traceability.ts +183 -0
  103. package/src/types.ts +287 -0
  104. package/test/federation/address.test.ts +101 -0
  105. package/test/federation/connection-manager.test.ts +546 -0
  106. package/test/federation/delivery-queue.test.ts +159 -0
  107. package/test/federation/integration.test.ts +823 -0
  108. package/test/federation/routing-engine.test.ts +117 -0
  109. package/test/federation/sdk-integration.test.ts +748 -0
  110. package/test/federation/trust.test.ts +89 -0
  111. package/test/ipc-jsonrpc.test.ts +113 -0
  112. package/test/ipc-server.test.ts +138 -0
  113. package/test/mail-server.test.ts +208 -0
  114. package/test/map-client.test.ts +408 -0
  115. package/test/message-router.test.ts +184 -0
  116. package/test/push-notifier.test.ts +139 -0
  117. package/test/registry/warm-registry.test.ts +171 -0
  118. package/test/sqlite-storage.test.ts +243 -0
  119. package/test/storage.test.ts +196 -0
  120. package/test/traceability.test.ts +123 -0
  121. package/tsconfig.json +20 -0
  122. package/tsup.config.ts +10 -0
  123. package/vitest.config.ts +8 -0
  124. package/dist/index.d.mts +0 -2
  125. package/dist/index.mjs +0 -1
  126. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,445 @@
1
+ import Database from "better-sqlite3";
2
+ export class SqliteStorage {
3
+ db;
4
+ constructor(opts) {
5
+ this.db = new Database(opts.path);
6
+ this.db.pragma("journal_mode = WAL");
7
+ this.db.pragma("foreign_keys = ON");
8
+ this.migrate();
9
+ }
10
+ migrate() {
11
+ this.db.exec(`
12
+ CREATE TABLE IF NOT EXISTS agents (
13
+ agent_id TEXT PRIMARY KEY,
14
+ display_name TEXT,
15
+ program TEXT,
16
+ model TEXT,
17
+ scope TEXT NOT NULL DEFAULT 'default',
18
+ status TEXT NOT NULL DEFAULT 'active',
19
+ metadata TEXT NOT NULL DEFAULT '{}',
20
+ registered_at TEXT NOT NULL,
21
+ last_active_at TEXT NOT NULL
22
+ );
23
+
24
+ CREATE TABLE IF NOT EXISTS messages (
25
+ id TEXT PRIMARY KEY,
26
+ scope TEXT NOT NULL DEFAULT 'default',
27
+ sender_id TEXT NOT NULL,
28
+ subject TEXT,
29
+ content TEXT NOT NULL,
30
+ thread_tag TEXT,
31
+ in_reply_to TEXT,
32
+ conversation_id TEXT,
33
+ importance TEXT NOT NULL DEFAULT 'normal',
34
+ metadata TEXT NOT NULL DEFAULT '{}',
35
+ created_at TEXT NOT NULL
36
+ );
37
+
38
+ CREATE TABLE IF NOT EXISTS recipients (
39
+ message_id TEXT NOT NULL,
40
+ agent_id TEXT NOT NULL,
41
+ kind TEXT NOT NULL DEFAULT 'to',
42
+ delivered_at TEXT,
43
+ read_at TEXT,
44
+ ack_at TEXT,
45
+ PRIMARY KEY (message_id, agent_id),
46
+ FOREIGN KEY (message_id) REFERENCES messages(id)
47
+ );
48
+
49
+ CREATE TABLE IF NOT EXISTS conversations (
50
+ id TEXT PRIMARY KEY,
51
+ scope TEXT NOT NULL DEFAULT 'default',
52
+ subject TEXT,
53
+ status TEXT NOT NULL DEFAULT 'active',
54
+ metadata TEXT NOT NULL DEFAULT '{}',
55
+ created_at TEXT NOT NULL,
56
+ updated_at TEXT NOT NULL
57
+ );
58
+
59
+ CREATE TABLE IF NOT EXISTS participants (
60
+ conversation_id TEXT NOT NULL,
61
+ agent_id TEXT NOT NULL,
62
+ role TEXT,
63
+ joined_at TEXT NOT NULL,
64
+ PRIMARY KEY (conversation_id, agent_id),
65
+ FOREIGN KEY (conversation_id) REFERENCES conversations(id)
66
+ );
67
+
68
+ CREATE TABLE IF NOT EXISTS turns (
69
+ id TEXT PRIMARY KEY,
70
+ conversation_id TEXT NOT NULL,
71
+ participant_id TEXT NOT NULL,
72
+ source_message_id TEXT,
73
+ content_type TEXT NOT NULL,
74
+ content TEXT NOT NULL,
75
+ thread_id TEXT,
76
+ in_reply_to TEXT,
77
+ created_at TEXT NOT NULL,
78
+ FOREIGN KEY (conversation_id) REFERENCES conversations(id)
79
+ );
80
+
81
+ CREATE TABLE IF NOT EXISTS threads (
82
+ id TEXT PRIMARY KEY,
83
+ conversation_id TEXT NOT NULL,
84
+ root_turn_id TEXT NOT NULL,
85
+ parent_thread_id TEXT,
86
+ subject TEXT,
87
+ created_at TEXT NOT NULL,
88
+ FOREIGN KEY (conversation_id) REFERENCES conversations(id)
89
+ );
90
+
91
+ -- Indexes for common queries
92
+ CREATE INDEX IF NOT EXISTS idx_messages_scope ON messages(scope);
93
+ CREATE INDEX IF NOT EXISTS idx_messages_sender ON messages(sender_id);
94
+ CREATE INDEX IF NOT EXISTS idx_messages_thread_tag ON messages(thread_tag, scope);
95
+ CREATE INDEX IF NOT EXISTS idx_messages_conversation ON messages(conversation_id);
96
+ CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at);
97
+ CREATE INDEX IF NOT EXISTS idx_recipients_agent ON recipients(agent_id);
98
+ CREATE INDEX IF NOT EXISTS idx_turns_conversation ON turns(conversation_id);
99
+ CREATE INDEX IF NOT EXISTS idx_agents_scope ON agents(scope);
100
+
101
+ -- FTS5 virtual table for full-text search
102
+ CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
103
+ id UNINDEXED,
104
+ subject,
105
+ text_content,
106
+ content='messages',
107
+ content_rowid='rowid'
108
+ );
109
+
110
+ -- Triggers to keep FTS in sync
111
+ CREATE TRIGGER IF NOT EXISTS messages_ai AFTER INSERT ON messages BEGIN
112
+ INSERT INTO messages_fts(rowid, id, subject, text_content)
113
+ VALUES (NEW.rowid, NEW.id, NEW.subject,
114
+ CASE WHEN json_extract(NEW.content, '$.type') = 'text'
115
+ THEN json_extract(NEW.content, '$.text')
116
+ ELSE '' END);
117
+ END;
118
+
119
+ CREATE TRIGGER IF NOT EXISTS messages_ad AFTER DELETE ON messages BEGIN
120
+ INSERT INTO messages_fts(messages_fts, rowid, id, subject, text_content)
121
+ VALUES ('delete', OLD.rowid, OLD.id, OLD.subject,
122
+ CASE WHEN json_extract(OLD.content, '$.type') = 'text'
123
+ THEN json_extract(OLD.content, '$.text')
124
+ ELSE '' END);
125
+ END;
126
+
127
+ CREATE TRIGGER IF NOT EXISTS messages_au AFTER UPDATE ON messages BEGIN
128
+ INSERT INTO messages_fts(messages_fts, rowid, id, subject, text_content)
129
+ VALUES ('delete', OLD.rowid, OLD.id, OLD.subject,
130
+ CASE WHEN json_extract(OLD.content, '$.type') = 'text'
131
+ THEN json_extract(OLD.content, '$.text')
132
+ ELSE '' END);
133
+ INSERT INTO messages_fts(rowid, id, subject, text_content)
134
+ VALUES (NEW.rowid, NEW.id, NEW.subject,
135
+ CASE WHEN json_extract(NEW.content, '$.type') = 'text'
136
+ THEN json_extract(NEW.content, '$.text')
137
+ ELSE '' END);
138
+ END;
139
+ `);
140
+ }
141
+ // --- Agents ---
142
+ getAgent(agentId) {
143
+ const row = this.db
144
+ .prepare("SELECT * FROM agents WHERE agent_id = ?")
145
+ .get(agentId);
146
+ return row ? rowToAgent(row) : undefined;
147
+ }
148
+ putAgent(agent) {
149
+ this.db
150
+ .prepare(`INSERT OR REPLACE INTO agents
151
+ (agent_id, display_name, program, model, scope, status, metadata, registered_at, last_active_at)
152
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
153
+ .run(agent.agent_id, agent.display_name ?? null, agent.program ?? null, agent.model ?? null, agent.scope, agent.status, JSON.stringify(agent.metadata), agent.registered_at, agent.last_active_at);
154
+ }
155
+ listAgents(scope) {
156
+ if (scope) {
157
+ return this.db.prepare("SELECT * FROM agents WHERE scope = ?").all(scope).map(rowToAgent);
158
+ }
159
+ return this.db.prepare("SELECT * FROM agents").all().map(rowToAgent);
160
+ }
161
+ removeAgent(agentId) {
162
+ const result = this.db
163
+ .prepare("DELETE FROM agents WHERE agent_id = ?")
164
+ .run(agentId);
165
+ return result.changes > 0;
166
+ }
167
+ // --- Messages ---
168
+ getMessage(id) {
169
+ const row = this.db
170
+ .prepare("SELECT * FROM messages WHERE id = ?")
171
+ .get(id);
172
+ if (!row)
173
+ return undefined;
174
+ return this.rowToMessage(row);
175
+ }
176
+ putMessage(message) {
177
+ const upsertMsg = this.db.prepare(`INSERT OR REPLACE INTO messages
178
+ (id, scope, sender_id, subject, content, thread_tag, in_reply_to, conversation_id, importance, metadata, created_at)
179
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
180
+ const upsertRecipient = this.db.prepare(`INSERT OR REPLACE INTO recipients
181
+ (message_id, agent_id, kind, delivered_at, read_at, ack_at)
182
+ VALUES (?, ?, ?, ?, ?, ?)`);
183
+ this.db.transaction(() => {
184
+ upsertMsg.run(message.id, message.scope, message.sender_id, message.subject ?? null, JSON.stringify(message.content), message.thread_tag ?? null, message.in_reply_to ?? null, message.conversation_id ?? null, message.importance, JSON.stringify(message.metadata), message.created_at);
185
+ // Delete old recipients and re-insert
186
+ this.db
187
+ .prepare("DELETE FROM recipients WHERE message_id = ?")
188
+ .run(message.id);
189
+ for (const r of message.recipients) {
190
+ upsertRecipient.run(message.id, r.agent_id, r.kind, r.delivered_at ?? null, r.read_at ?? null, r.ack_at ?? null);
191
+ }
192
+ })();
193
+ return message;
194
+ }
195
+ getInbox(agentId, opts) {
196
+ let sql = `
197
+ SELECT m.* FROM messages m
198
+ JOIN recipients r ON r.message_id = m.id
199
+ WHERE r.agent_id = ?
200
+ `;
201
+ const params = [agentId];
202
+ if (opts?.unreadOnly) {
203
+ sql += " AND r.read_at IS NULL";
204
+ }
205
+ if (opts?.since) {
206
+ sql += " AND m.created_at >= ?";
207
+ params.push(opts.since);
208
+ }
209
+ sql += " ORDER BY m.created_at ASC";
210
+ if (opts?.limit) {
211
+ sql += " LIMIT ?";
212
+ params.push(opts.limit);
213
+ }
214
+ const rows = this.db.prepare(sql).all(...params);
215
+ return rows.map((row) => this.rowToMessage(row));
216
+ }
217
+ getThread(query) {
218
+ const rows = this.db
219
+ .prepare("SELECT * FROM messages WHERE thread_tag = ? AND scope = ? ORDER BY created_at ASC")
220
+ .all(query.threadTag, query.scope);
221
+ return rows.map((row) => this.rowToMessage(row));
222
+ }
223
+ getSentMessages(agentId, limit) {
224
+ let sql = "SELECT * FROM messages WHERE sender_id = ? ORDER BY created_at ASC";
225
+ const params = [agentId];
226
+ if (limit) {
227
+ sql += " LIMIT ?";
228
+ params.push(limit);
229
+ }
230
+ const rows = this.db.prepare(sql).all(...params);
231
+ return rows.map((row) => this.rowToMessage(row));
232
+ }
233
+ searchMessages(query, scope) {
234
+ let sql;
235
+ let params;
236
+ if (scope) {
237
+ sql = `
238
+ SELECT m.* FROM messages m
239
+ JOIN messages_fts fts ON fts.id = m.id
240
+ WHERE messages_fts MATCH ? AND m.scope = ?
241
+ ORDER BY m.created_at ASC
242
+ `;
243
+ params = [query, scope];
244
+ }
245
+ else {
246
+ sql = `
247
+ SELECT m.* FROM messages m
248
+ JOIN messages_fts fts ON fts.id = m.id
249
+ WHERE messages_fts MATCH ?
250
+ ORDER BY m.created_at ASC
251
+ `;
252
+ params = [query];
253
+ }
254
+ try {
255
+ const rows = this.db.prepare(sql).all(...params);
256
+ return rows.map((row) => this.rowToMessage(row));
257
+ }
258
+ catch {
259
+ // FTS query syntax error — fall back to LIKE
260
+ return this.searchMessagesLike(query, scope);
261
+ }
262
+ }
263
+ searchMessagesLike(query, scope) {
264
+ const pattern = `%${query}%`;
265
+ let sql = `
266
+ SELECT * FROM messages
267
+ WHERE (subject LIKE ? OR content LIKE ?)
268
+ `;
269
+ const params = [pattern, pattern];
270
+ if (scope) {
271
+ sql += " AND scope = ?";
272
+ params.push(scope);
273
+ }
274
+ sql += " ORDER BY created_at ASC";
275
+ const rows = this.db.prepare(sql).all(...params);
276
+ return rows.map((row) => this.rowToMessage(row));
277
+ }
278
+ // --- Conversations ---
279
+ getConversation(id) {
280
+ const row = this.db
281
+ .prepare("SELECT * FROM conversations WHERE id = ?")
282
+ .get(id);
283
+ if (!row)
284
+ return undefined;
285
+ return this.rowToConversation(row);
286
+ }
287
+ putConversation(conversation) {
288
+ this.db.transaction(() => {
289
+ this.db
290
+ .prepare(`INSERT OR REPLACE INTO conversations
291
+ (id, scope, subject, status, metadata, created_at, updated_at)
292
+ VALUES (?, ?, ?, ?, ?, ?, ?)`)
293
+ .run(conversation.id, conversation.scope, conversation.subject ?? null, conversation.status, JSON.stringify(conversation.metadata), conversation.created_at, conversation.updated_at);
294
+ // Re-sync participants
295
+ this.db
296
+ .prepare("DELETE FROM participants WHERE conversation_id = ?")
297
+ .run(conversation.id);
298
+ const insertP = this.db.prepare(`INSERT INTO participants (conversation_id, agent_id, role, joined_at) VALUES (?, ?, ?, ?)`);
299
+ for (const p of conversation.participants) {
300
+ insertP.run(conversation.id, p.agent_id, p.role ?? null, p.joined_at);
301
+ }
302
+ })();
303
+ return conversation;
304
+ }
305
+ listConversations(scope) {
306
+ let rows;
307
+ if (scope) {
308
+ rows = this.db
309
+ .prepare("SELECT * FROM conversations WHERE scope = ? ORDER BY updated_at DESC")
310
+ .all(scope);
311
+ }
312
+ else {
313
+ rows = this.db
314
+ .prepare("SELECT * FROM conversations ORDER BY updated_at DESC")
315
+ .all();
316
+ }
317
+ return rows.map((row) => this.rowToConversation(row));
318
+ }
319
+ // --- Turns ---
320
+ addTurn(turn) {
321
+ this.db
322
+ .prepare(`INSERT INTO turns
323
+ (id, conversation_id, participant_id, source_message_id, content_type, content, thread_id, in_reply_to, created_at)
324
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`)
325
+ .run(turn.id, turn.conversation_id, turn.participant_id, turn.source_message_id ?? null, turn.content_type, JSON.stringify(turn.content), turn.thread_id ?? null, turn.in_reply_to ?? null, turn.created_at);
326
+ }
327
+ getTurns(conversationId) {
328
+ const rows = this.db
329
+ .prepare("SELECT * FROM turns WHERE conversation_id = ? ORDER BY created_at ASC")
330
+ .all(conversationId);
331
+ return rows.map(rowToTurn);
332
+ }
333
+ // --- Threads ---
334
+ getThread2(id) {
335
+ const row = this.db
336
+ .prepare("SELECT * FROM threads WHERE id = ?")
337
+ .get(id);
338
+ return row ? rowToThread(row) : undefined;
339
+ }
340
+ putThread(thread) {
341
+ this.db
342
+ .prepare(`INSERT OR REPLACE INTO threads
343
+ (id, conversation_id, root_turn_id, parent_thread_id, subject, created_at)
344
+ VALUES (?, ?, ?, ?, ?, ?)`)
345
+ .run(thread.id, thread.conversation_id, thread.root_turn_id, thread.parent_thread_id ?? null, thread.subject ?? null, thread.created_at);
346
+ return thread;
347
+ }
348
+ getThreadsByConversation(conversationId) {
349
+ const rows = this.db
350
+ .prepare("SELECT * FROM threads WHERE conversation_id = ?")
351
+ .all(conversationId);
352
+ return rows.map(rowToThread);
353
+ }
354
+ // --- Helpers ---
355
+ getRecipients(messageId) {
356
+ const rows = this.db
357
+ .prepare("SELECT * FROM recipients WHERE message_id = ?")
358
+ .all(messageId);
359
+ return rows.map((r) => ({
360
+ agent_id: r.agent_id,
361
+ kind: r.kind,
362
+ delivered_at: r.delivered_at ?? undefined,
363
+ read_at: r.read_at ?? undefined,
364
+ ack_at: r.ack_at ?? undefined,
365
+ }));
366
+ }
367
+ getParticipants(conversationId) {
368
+ const rows = this.db
369
+ .prepare("SELECT * FROM participants WHERE conversation_id = ?")
370
+ .all(conversationId);
371
+ return rows.map((r) => ({
372
+ agent_id: r.agent_id,
373
+ role: r.role ?? undefined,
374
+ joined_at: r.joined_at,
375
+ }));
376
+ }
377
+ rowToMessage(row) {
378
+ return {
379
+ id: row.id,
380
+ scope: row.scope,
381
+ sender_id: row.sender_id,
382
+ recipients: this.getRecipients(row.id),
383
+ subject: row.subject ?? undefined,
384
+ content: JSON.parse(row.content),
385
+ thread_tag: row.thread_tag ?? undefined,
386
+ in_reply_to: row.in_reply_to ?? undefined,
387
+ conversation_id: row.conversation_id ?? undefined,
388
+ importance: row.importance,
389
+ metadata: JSON.parse(row.metadata),
390
+ created_at: row.created_at,
391
+ };
392
+ }
393
+ rowToConversation(row) {
394
+ return {
395
+ id: row.id,
396
+ scope: row.scope,
397
+ subject: row.subject ?? undefined,
398
+ status: row.status,
399
+ participants: this.getParticipants(row.id),
400
+ metadata: JSON.parse(row.metadata),
401
+ created_at: row.created_at,
402
+ updated_at: row.updated_at,
403
+ };
404
+ }
405
+ close() {
406
+ this.db.close();
407
+ }
408
+ }
409
+ function rowToAgent(row) {
410
+ return {
411
+ agent_id: row.agent_id,
412
+ display_name: row.display_name ?? undefined,
413
+ program: row.program ?? undefined,
414
+ model: row.model ?? undefined,
415
+ scope: row.scope,
416
+ status: row.status,
417
+ metadata: JSON.parse(row.metadata),
418
+ registered_at: row.registered_at,
419
+ last_active_at: row.last_active_at,
420
+ };
421
+ }
422
+ function rowToTurn(row) {
423
+ return {
424
+ id: row.id,
425
+ conversation_id: row.conversation_id,
426
+ participant_id: row.participant_id,
427
+ source_message_id: row.source_message_id ?? undefined,
428
+ content_type: row.content_type,
429
+ content: JSON.parse(row.content),
430
+ thread_id: row.thread_id ?? undefined,
431
+ in_reply_to: row.in_reply_to ?? undefined,
432
+ created_at: row.created_at,
433
+ };
434
+ }
435
+ function rowToThread(row) {
436
+ return {
437
+ id: row.id,
438
+ conversation_id: row.conversation_id,
439
+ root_turn_id: row.root_turn_id,
440
+ parent_thread_id: row.parent_thread_id ?? undefined,
441
+ subject: row.subject ?? undefined,
442
+ created_at: row.created_at,
443
+ };
444
+ }
445
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/storage/sqlite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { EventEmitter } from "node:events";
2
+ import type { Storage } from "../storage/interface.js";
3
+ /**
4
+ * Auto-creates Conversations, Turns, and Threads from messaging events.
5
+ *
6
+ * Rules:
7
+ * 1. Message with conversationId → add Turn to that Conversation
8
+ * 2. Message with thread_tag, no conversationId → find/create Conversation for thread_tag+scope
9
+ * 3. Message with neither → add Turn to catch-all Conversation for scope
10
+ * 4. Reply (in_reply_to) → create Thread if not exists, link Turn
11
+ */
12
+ export declare class TraceabilityLayer {
13
+ private storage;
14
+ /** Maps "thread_tag:scope" → conversation ID */
15
+ private tagToConversation;
16
+ /** Maps scope → catch-all conversation ID */
17
+ private scopeCatchAll;
18
+ /** Maps original message ID → thread ID (for reply chains) */
19
+ private replyChainToThread;
20
+ constructor(storage: Storage, events: EventEmitter);
21
+ private onMessage;
22
+ private resolveConversation;
23
+ private createConversation;
24
+ private ensureParticipant;
25
+ private resolveThread;
26
+ private findRootMessage;
27
+ private findTurnForMessage;
28
+ }
29
+ //# sourceMappingURL=traceability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceability.d.ts","sourceRoot":"","sources":["../../src/traceability/traceability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEvD;;;;;;;;GAQG;AACH,qBAAa,iBAAiB;IAS1B,OAAO,CAAC,OAAO;IARjB,gDAAgD;IAChD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,6CAA6C;IAC7C,OAAO,CAAC,aAAa,CAA6B;IAClD,8DAA8D;IAC9D,OAAO,CAAC,kBAAkB,CAA6B;gBAG7C,OAAO,EAAE,OAAO,EACxB,MAAM,EAAE,YAAY;IAKtB,OAAO,CAAC,SAAS;IA6CjB,OAAO,CAAC,mBAAmB;IAoC3B,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,kBAAkB;CAS3B"}
@@ -0,0 +1,150 @@
1
+ import { ulid } from "ulid";
2
+ /**
3
+ * Auto-creates Conversations, Turns, and Threads from messaging events.
4
+ *
5
+ * Rules:
6
+ * 1. Message with conversationId → add Turn to that Conversation
7
+ * 2. Message with thread_tag, no conversationId → find/create Conversation for thread_tag+scope
8
+ * 3. Message with neither → add Turn to catch-all Conversation for scope
9
+ * 4. Reply (in_reply_to) → create Thread if not exists, link Turn
10
+ */
11
+ export class TraceabilityLayer {
12
+ storage;
13
+ /** Maps "thread_tag:scope" → conversation ID */
14
+ tagToConversation = new Map();
15
+ /** Maps scope → catch-all conversation ID */
16
+ scopeCatchAll = new Map();
17
+ /** Maps original message ID → thread ID (for reply chains) */
18
+ replyChainToThread = new Map();
19
+ constructor(storage, events) {
20
+ this.storage = storage;
21
+ events.on("message.created", (msg) => this.onMessage(msg));
22
+ }
23
+ onMessage(message) {
24
+ const conversationId = this.resolveConversation(message);
25
+ // Update message's conversation_id if not already set
26
+ if (!message.conversation_id) {
27
+ message.conversation_id = conversationId;
28
+ this.storage.putMessage(message);
29
+ }
30
+ // Ensure sender is a participant
31
+ this.ensureParticipant(conversationId, message.sender_id);
32
+ // Ensure recipients are participants
33
+ for (const r of message.recipients) {
34
+ this.ensureParticipant(conversationId, r.agent_id);
35
+ }
36
+ // Create Turn
37
+ const turn = {
38
+ id: `turn-${ulid()}`,
39
+ conversation_id: conversationId,
40
+ participant_id: message.sender_id,
41
+ source_message_id: message.id,
42
+ content_type: message.content.type,
43
+ content: message.content,
44
+ created_at: message.created_at,
45
+ };
46
+ // Handle reply threading
47
+ if (message.in_reply_to) {
48
+ const threadId = this.resolveThread(message, conversationId, turn.id);
49
+ turn.thread_id = threadId;
50
+ turn.in_reply_to = this.findTurnForMessage(message.in_reply_to);
51
+ }
52
+ this.storage.addTurn(turn);
53
+ // Update conversation updated_at
54
+ const conv = this.storage.getConversation(conversationId);
55
+ if (conv) {
56
+ conv.updated_at = message.created_at;
57
+ this.storage.putConversation(conv);
58
+ }
59
+ }
60
+ resolveConversation(message) {
61
+ // 1. Explicit conversation ID
62
+ if (message.conversation_id) {
63
+ const existing = this.storage.getConversation(message.conversation_id);
64
+ if (existing)
65
+ return existing.id;
66
+ // Create it if it doesn't exist
67
+ return this.createConversation(message.scope, message.subject, message.conversation_id);
68
+ }
69
+ // 2. thread_tag → conversation
70
+ if (message.thread_tag) {
71
+ const key = `${message.thread_tag}:${message.scope}`;
72
+ const existing = this.tagToConversation.get(key);
73
+ if (existing)
74
+ return existing;
75
+ const convId = this.createConversation(message.scope, message.thread_tag);
76
+ this.tagToConversation.set(key, convId);
77
+ return convId;
78
+ }
79
+ // 3. Catch-all for scope
80
+ const existing = this.scopeCatchAll.get(message.scope);
81
+ if (existing)
82
+ return existing;
83
+ const convId = this.createConversation(message.scope, "General");
84
+ this.scopeCatchAll.set(message.scope, convId);
85
+ return convId;
86
+ }
87
+ createConversation(scope, subject, explicitId) {
88
+ const now = new Date().toISOString();
89
+ const conv = {
90
+ id: explicitId ?? `conv-${ulid()}`,
91
+ scope,
92
+ subject,
93
+ status: "active",
94
+ participants: [],
95
+ metadata: {},
96
+ created_at: now,
97
+ updated_at: now,
98
+ };
99
+ this.storage.putConversation(conv);
100
+ return conv.id;
101
+ }
102
+ ensureParticipant(conversationId, agentId) {
103
+ const conv = this.storage.getConversation(conversationId);
104
+ if (!conv)
105
+ return;
106
+ if (conv.participants.some((p) => p.agent_id === agentId))
107
+ return;
108
+ conv.participants.push({
109
+ agent_id: agentId,
110
+ joined_at: new Date().toISOString(),
111
+ });
112
+ this.storage.putConversation(conv);
113
+ }
114
+ resolveThread(message, conversationId, turnId) {
115
+ // Find the root of the reply chain
116
+ const rootMessageId = this.findRootMessage(message.in_reply_to);
117
+ const existingThreadId = this.replyChainToThread.get(rootMessageId);
118
+ if (existingThreadId)
119
+ return existingThreadId;
120
+ // Create new thread
121
+ const rootTurnId = this.findTurnForMessage(rootMessageId) ?? turnId;
122
+ const thread = {
123
+ id: `thread-${ulid()}`,
124
+ conversation_id: conversationId,
125
+ root_turn_id: rootTurnId,
126
+ subject: message.subject,
127
+ created_at: new Date().toISOString(),
128
+ };
129
+ this.storage.putThread(thread);
130
+ this.replyChainToThread.set(rootMessageId, thread.id);
131
+ return thread.id;
132
+ }
133
+ findRootMessage(messageId) {
134
+ const msg = this.storage.getMessage(messageId);
135
+ if (!msg || !msg.in_reply_to)
136
+ return messageId;
137
+ return this.findRootMessage(msg.in_reply_to);
138
+ }
139
+ findTurnForMessage(messageId) {
140
+ // Look through all conversations for a turn with this source_message_id
141
+ for (const conv of this.storage.listConversations()) {
142
+ const turns = this.storage.getTurns(conv.id);
143
+ const turn = turns.find((t) => t.source_message_id === messageId);
144
+ if (turn)
145
+ return turn.id;
146
+ }
147
+ return undefined;
148
+ }
149
+ }
150
+ //# sourceMappingURL=traceability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceability.js","sourceRoot":"","sources":["../../src/traceability/traceability.ts"],"names":[],"mappings":"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"}