proofscan 0.10.62 → 0.11.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.
- package/README.ja.md +1 -0
- package/README.md +2 -0
- package/dist/a2a/agent-card.d.ts +2 -0
- package/dist/a2a/agent-card.d.ts.map +1 -1
- package/dist/a2a/agent-card.js +2 -2
- package/dist/a2a/agent-card.js.map +1 -1
- package/dist/a2a/client.d.ts +74 -12
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +228 -29
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/normalizer.d.ts +4 -0
- package/dist/a2a/normalizer.d.ts.map +1 -1
- package/dist/a2a/normalizer.js +7 -4
- package/dist/a2a/normalizer.js.map +1 -1
- package/dist/a2a/session-manager.d.ts +81 -0
- package/dist/a2a/session-manager.d.ts.map +1 -0
- package/dist/a2a/session-manager.js +176 -0
- package/dist/a2a/session-manager.js.map +1 -0
- package/dist/a2a/types.d.ts +60 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/cli.d.ts +2 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +35 -10
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +12 -10
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/connectors.js +2 -2
- package/dist/commands/connectors.js.map +1 -1
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +1 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/plans.js +1 -1
- package/dist/commands/plans.js.map +1 -1
- package/dist/commands/record.js +5 -4
- package/dist/commands/record.js.map +1 -1
- package/dist/commands/rpc.d.ts.map +1 -1
- package/dist/commands/rpc.js +90 -28
- package/dist/commands/rpc.js.map +1 -1
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +8 -10
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/secrets.d.ts.map +1 -1
- package/dist/commands/secrets.js +11 -10
- package/dist/commands/secrets.js.map +1 -1
- package/dist/commands/sessions.js +2 -2
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/summary.d.ts.map +1 -1
- package/dist/commands/summary.js +4 -2
- package/dist/commands/summary.js.map +1 -1
- package/dist/commands/task.d.ts +14 -0
- package/dist/commands/task.d.ts.map +1 -0
- package/dist/commands/task.js +520 -0
- package/dist/commands/task.js.map +1 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +68 -21
- package/dist/db/connection.js.map +1 -1
- package/dist/db/events-store.d.ts +307 -8
- package/dist/db/events-store.d.ts.map +1 -1
- package/dist/db/events-store.js +620 -26
- package/dist/db/events-store.js.map +1 -1
- package/dist/db/proofs-store.d.ts +8 -1
- package/dist/db/proofs-store.d.ts.map +1 -1
- package/dist/db/proofs-store.js +18 -8
- package/dist/db/proofs-store.js.map +1 -1
- package/dist/db/schema.d.ts +15 -3
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +150 -5
- package/dist/db/schema.js.map +1 -1
- package/dist/db/tool-analysis.d.ts +15 -3
- package/dist/db/tool-analysis.d.ts.map +1 -1
- package/dist/db/tool-analysis.js +35 -17
- package/dist/db/tool-analysis.js.map +1 -1
- package/dist/db/types.d.ts +64 -1
- package/dist/db/types.d.ts.map +1 -1
- package/dist/filter/fields.d.ts.map +1 -1
- package/dist/filter/fields.js +22 -0
- package/dist/filter/fields.js.map +1 -1
- package/dist/filter/parser.js +2 -2
- package/dist/filter/parser.js.map +1 -1
- package/dist/filter/types.d.ts +1 -1
- package/dist/filter/types.d.ts.map +1 -1
- package/dist/html/analytics.test.ts +682 -0
- package/dist/html/analytics.ts +499 -0
- package/dist/html/browser.ts +39 -0
- package/dist/html/index.ts +97 -0
- package/dist/html/rpc-inspector.test.ts +529 -0
- package/dist/html/rpc-inspector.ts +1700 -0
- package/dist/html/templates.js +4 -4
- package/dist/html/templates.js.map +1 -1
- package/dist/html/templates.test.ts +861 -0
- package/dist/html/templates.ts +3163 -0
- package/dist/html/trace-viewer.html +624 -0
- package/dist/html/types.d.ts +3 -3
- package/dist/html/types.d.ts.map +1 -1
- package/dist/html/types.ts +491 -0
- package/dist/html/utils.ts +107 -0
- package/dist/monitor/data/connectors.d.ts.map +1 -1
- package/dist/monitor/data/connectors.js +113 -8
- package/dist/monitor/data/connectors.js.map +1 -1
- package/dist/monitor/data/popl.js +2 -2
- package/dist/monitor/data/popl.js.map +1 -1
- package/dist/monitor/routes/api.js +2 -2
- package/dist/monitor/routes/api.js.map +1 -1
- package/dist/monitor/routes/connectors.js +15 -15
- package/dist/monitor/routes/connectors.js.map +1 -1
- package/dist/monitor/routes/popl.js +5 -5
- package/dist/monitor/routes/popl.js.map +1 -1
- package/dist/monitor/templates/components.js +2 -2
- package/dist/monitor/templates/components.js.map +1 -1
- package/dist/monitor/templates/popl.js +4 -4
- package/dist/monitor/templates/popl.js.map +1 -1
- package/dist/monitor/types.d.ts +2 -2
- package/dist/monitor/types.d.ts.map +1 -1
- package/dist/proxy/bridge-utils.d.ts +41 -0
- package/dist/proxy/bridge-utils.d.ts.map +1 -0
- package/dist/proxy/bridge-utils.js +60 -0
- package/dist/proxy/bridge-utils.js.map +1 -0
- package/dist/proxy/ipc-client.d.ts.map +1 -1
- package/dist/proxy/ipc-client.js +1 -2
- package/dist/proxy/ipc-client.js.map +1 -1
- package/dist/proxy/ipc-server.d.ts.map +1 -1
- package/dist/proxy/ipc-server.js +4 -2
- package/dist/proxy/ipc-server.js.map +1 -1
- package/dist/proxy/mcp-server.d.ts +31 -0
- package/dist/proxy/mcp-server.d.ts.map +1 -1
- package/dist/proxy/mcp-server.js +393 -4
- package/dist/proxy/mcp-server.js.map +1 -1
- package/dist/proxy/types.d.ts +95 -0
- package/dist/proxy/types.d.ts.map +1 -1
- package/dist/secrets/management.d.ts +2 -2
- package/dist/secrets/management.d.ts.map +1 -1
- package/dist/secrets/management.js +7 -7
- package/dist/secrets/management.js.map +1 -1
- package/dist/shell/completer.d.ts.map +1 -1
- package/dist/shell/completer.js +16 -0
- package/dist/shell/completer.js.map +1 -1
- package/dist/shell/context-applicator.d.ts.map +1 -1
- package/dist/shell/context-applicator.js +32 -0
- package/dist/shell/context-applicator.js.map +1 -1
- package/dist/shell/filter-mappers.d.ts +5 -1
- package/dist/shell/filter-mappers.d.ts.map +1 -1
- package/dist/shell/filter-mappers.js +12 -0
- package/dist/shell/filter-mappers.js.map +1 -1
- package/dist/shell/find-command.js +13 -13
- package/dist/shell/find-command.js.map +1 -1
- package/dist/shell/inscribe-commands.js +5 -5
- package/dist/shell/inscribe-commands.js.map +1 -1
- package/dist/shell/pager/less-pager.d.ts +1 -1
- package/dist/shell/pager/less-pager.d.ts.map +1 -1
- package/dist/shell/pager/less-pager.js +5 -2
- package/dist/shell/pager/less-pager.js.map +1 -1
- package/dist/shell/pager/more-pager.d.ts +1 -1
- package/dist/shell/pager/more-pager.d.ts.map +1 -1
- package/dist/shell/pager/more-pager.js +3 -2
- package/dist/shell/pager/more-pager.js.map +1 -1
- package/dist/shell/pager/renderer.d.ts.map +1 -1
- package/dist/shell/pager/renderer.js +66 -15
- package/dist/shell/pager/renderer.js.map +1 -1
- package/dist/shell/pager/types.d.ts +5 -2
- package/dist/shell/pager/types.d.ts.map +1 -1
- package/dist/shell/pager/utils.d.ts +5 -2
- package/dist/shell/pager/utils.d.ts.map +1 -1
- package/dist/shell/pager/utils.js +14 -17
- package/dist/shell/pager/utils.js.map +1 -1
- package/dist/shell/pipeline-types.d.ts +12 -4
- package/dist/shell/pipeline-types.d.ts.map +1 -1
- package/dist/shell/ref-commands.js +7 -7
- package/dist/shell/ref-commands.js.map +1 -1
- package/dist/shell/ref-resolver.d.ts +15 -15
- package/dist/shell/ref-resolver.d.ts.map +1 -1
- package/dist/shell/ref-resolver.js +34 -20
- package/dist/shell/ref-resolver.js.map +1 -1
- package/dist/shell/repl.d.ts +25 -0
- package/dist/shell/repl.d.ts.map +1 -1
- package/dist/shell/repl.js +285 -51
- package/dist/shell/repl.js.map +1 -1
- package/dist/shell/router-commands.d.ts +30 -0
- package/dist/shell/router-commands.d.ts.map +1 -1
- package/dist/shell/router-commands.js +1011 -62
- package/dist/shell/router-commands.js.map +1 -1
- package/dist/shell/selector.d.ts +1 -1
- package/dist/shell/selector.d.ts.map +1 -1
- package/dist/shell/selector.js +1 -1
- package/dist/shell/selector.js.map +1 -1
- package/dist/shell/types.d.ts.map +1 -1
- package/dist/shell/types.js +3 -1
- package/dist/shell/types.js.map +1 -1
- package/dist/shell/where-command.d.ts.map +1 -1
- package/dist/shell/where-command.js +19 -3
- package/dist/shell/where-command.js.map +1 -1
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +7 -1
- package/dist/utils/output.js.map +1 -1
- package/package.json +2 -2
package/dist/db/events-store.js
CHANGED
|
@@ -13,8 +13,9 @@ export class EventsStore {
|
|
|
13
13
|
return getEventsDb(this.configDir);
|
|
14
14
|
}
|
|
15
15
|
// ==================== Sessions ====================
|
|
16
|
-
createSession(
|
|
17
|
-
|
|
16
|
+
createSession(targetId, options) {
|
|
17
|
+
// Support legacy connectorId for backward compatibility
|
|
18
|
+
const connectorId = options?.connectorId || targetId;
|
|
18
19
|
const session = {
|
|
19
20
|
session_id: randomUUID(),
|
|
20
21
|
connector_id: connectorId,
|
|
@@ -46,20 +47,26 @@ export class EventsStore {
|
|
|
46
47
|
const stmt = this.db.prepare(`SELECT * FROM sessions WHERE session_id = ?`);
|
|
47
48
|
return stmt.get(sessionId);
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
+
getSessionsByTarget(targetId, limit) {
|
|
50
51
|
let sql = `
|
|
51
52
|
SELECT s.*,
|
|
52
53
|
(SELECT COUNT(*) FROM events WHERE session_id = s.session_id) as event_count,
|
|
53
54
|
(SELECT COUNT(*) FROM rpc_calls WHERE session_id = s.session_id) as rpc_count
|
|
54
55
|
FROM sessions s
|
|
55
|
-
WHERE s.
|
|
56
|
+
WHERE s.target_id = ?
|
|
56
57
|
ORDER BY s.started_at DESC
|
|
57
58
|
`;
|
|
58
59
|
if (limit) {
|
|
59
60
|
sql += ` LIMIT ${limit}`;
|
|
60
61
|
}
|
|
61
62
|
const stmt = this.db.prepare(sql);
|
|
62
|
-
return stmt.all(
|
|
63
|
+
return stmt.all(targetId);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @deprecated Use getSessionsByTarget instead
|
|
67
|
+
*/
|
|
68
|
+
getSessionsByConnector(connectorId, limit) {
|
|
69
|
+
return this.getSessionsByTarget(connectorId, limit);
|
|
63
70
|
}
|
|
64
71
|
getAllSessions(limit) {
|
|
65
72
|
let sql = `
|
|
@@ -155,17 +162,57 @@ export class EventsStore {
|
|
|
155
162
|
const stmt = this.db.prepare(sql);
|
|
156
163
|
return stmt.all(sessionId);
|
|
157
164
|
}
|
|
158
|
-
|
|
165
|
+
/**
|
|
166
|
+
* Get events with pagination support (Phase 6.2)
|
|
167
|
+
*
|
|
168
|
+
* @param sessionId - Session ID
|
|
169
|
+
* @param options - Pagination options
|
|
170
|
+
* @param options.limit - Maximum number of events to return (default: 50, max: 200)
|
|
171
|
+
* @param options.before - Event ID for pagination cursor (exclusive)
|
|
172
|
+
* @returns Events in descending order (newest first)
|
|
173
|
+
*/
|
|
174
|
+
getEvents(sessionId, options = {}) {
|
|
175
|
+
// Enforce max limit of 200
|
|
176
|
+
let limit = options.limit ?? 50;
|
|
177
|
+
if (limit > 200) {
|
|
178
|
+
limit = 200;
|
|
179
|
+
}
|
|
180
|
+
let sql = `SELECT * FROM events WHERE session_id = ?`;
|
|
181
|
+
const params = [sessionId];
|
|
182
|
+
// Exclusive cursor: get events older than the specified event_id
|
|
183
|
+
// Use composite cursor (ts, event_id) for stable pagination with same-timestamp events
|
|
184
|
+
if (options.before) {
|
|
185
|
+
const cursorStmt = this.db.prepare(`SELECT ts, event_id FROM events WHERE event_id = ?`);
|
|
186
|
+
const cursorEvent = cursorStmt.get(options.before);
|
|
187
|
+
if (cursorEvent) {
|
|
188
|
+
// Events with earlier timestamp, OR same timestamp but earlier event_id
|
|
189
|
+
sql += ` AND (ts < ? OR (ts = ? AND event_id < ?))`;
|
|
190
|
+
params.push(cursorEvent.ts, cursorEvent.ts, cursorEvent.event_id);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// Order by ts DESC, event_id DESC for deterministic ordering with same-timestamp events
|
|
194
|
+
sql += ` ORDER BY ts DESC, event_id DESC LIMIT ?`;
|
|
195
|
+
params.push(limit);
|
|
196
|
+
const stmt = this.db.prepare(sql);
|
|
197
|
+
return stmt.all(...params);
|
|
198
|
+
}
|
|
199
|
+
getRecentEventsByTarget(targetId, limit = 20) {
|
|
159
200
|
const stmt = this.db.prepare(`
|
|
160
201
|
SELECT e.* FROM events e
|
|
161
202
|
JOIN sessions s ON e.session_id = s.session_id
|
|
162
|
-
WHERE s.
|
|
203
|
+
WHERE s.target_id = ?
|
|
163
204
|
ORDER BY e.ts DESC
|
|
164
205
|
LIMIT ?
|
|
165
206
|
`);
|
|
166
|
-
const events = stmt.all(
|
|
207
|
+
const events = stmt.all(targetId, limit);
|
|
167
208
|
return events.reverse(); // Return in chronological order
|
|
168
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* @deprecated Use getRecentEventsByTarget instead
|
|
212
|
+
*/
|
|
213
|
+
getRecentEventsByConnector(connectorId, limit = 20) {
|
|
214
|
+
return this.getRecentEventsByTarget(connectorId, limit);
|
|
215
|
+
}
|
|
169
216
|
// ==================== RPC Calls ====================
|
|
170
217
|
saveRpcCall(sessionId, rpcId, method) {
|
|
171
218
|
const rpcCall = {
|
|
@@ -203,19 +250,21 @@ export class EventsStore {
|
|
|
203
250
|
* Get sessions that can be pruned (not protected)
|
|
204
251
|
*/
|
|
205
252
|
getPruneCandidates(options = {}) {
|
|
206
|
-
const { keepLast, before, connectorId } = options;
|
|
253
|
+
const { keepLast, before, targetId, connectorId } = options;
|
|
207
254
|
const candidates = [];
|
|
255
|
+
// Use targetId if provided, otherwise fall back to connectorId
|
|
256
|
+
const filterId = targetId || connectorId;
|
|
208
257
|
// Get all unprotected sessions
|
|
209
258
|
let sql = `
|
|
210
|
-
SELECT s.session_id, s.connector_id, s.started_at, s.protected,
|
|
259
|
+
SELECT s.session_id, s.target_id as connector_id, s.started_at, s.protected,
|
|
211
260
|
(SELECT COUNT(*) FROM events WHERE session_id = s.session_id) as event_count
|
|
212
261
|
FROM sessions s
|
|
213
262
|
WHERE s.protected = 0
|
|
214
263
|
`;
|
|
215
264
|
const params = [];
|
|
216
|
-
if (
|
|
217
|
-
sql += ` AND s.
|
|
218
|
-
params.push(
|
|
265
|
+
if (filterId) {
|
|
266
|
+
sql += ` AND s.target_id = ?`;
|
|
267
|
+
params.push(filterId);
|
|
219
268
|
}
|
|
220
269
|
if (before) {
|
|
221
270
|
sql += ` AND s.started_at < ?`;
|
|
@@ -429,15 +478,15 @@ export class EventsStore {
|
|
|
429
478
|
});
|
|
430
479
|
}
|
|
431
480
|
/**
|
|
432
|
-
* Get latest session (optionally for a specific
|
|
481
|
+
* Get latest session (optionally for a specific target)
|
|
433
482
|
* Used by RefResolver
|
|
434
483
|
*/
|
|
435
|
-
getLatestSession(
|
|
436
|
-
let sql = `SELECT session_id,
|
|
484
|
+
getLatestSession(targetId) {
|
|
485
|
+
let sql = `SELECT session_id, target_id FROM sessions`;
|
|
437
486
|
const params = [];
|
|
438
|
-
if (
|
|
439
|
-
sql += ` WHERE
|
|
440
|
-
params.push(
|
|
487
|
+
if (targetId) {
|
|
488
|
+
sql += ` WHERE target_id = ?`;
|
|
489
|
+
params.push(targetId);
|
|
441
490
|
}
|
|
442
491
|
sql += ` ORDER BY started_at DESC LIMIT 1`;
|
|
443
492
|
const stmt = this.db.prepare(sql);
|
|
@@ -474,23 +523,23 @@ export class EventsStore {
|
|
|
474
523
|
* Get session by ID or prefix
|
|
475
524
|
* Used by RefResolver
|
|
476
525
|
*/
|
|
477
|
-
getSessionByPrefix(prefix,
|
|
526
|
+
getSessionByPrefix(prefix, targetId) {
|
|
478
527
|
// Try exact match first
|
|
479
|
-
let stmt = this.db.prepare(`SELECT session_id,
|
|
528
|
+
let stmt = this.db.prepare(`SELECT session_id, target_id FROM sessions WHERE session_id = ?`);
|
|
480
529
|
let result = stmt.get(prefix);
|
|
481
530
|
if (result) {
|
|
482
|
-
if (
|
|
531
|
+
if (targetId && result.target_id !== targetId) {
|
|
483
532
|
return null; // Wrong connector
|
|
484
533
|
}
|
|
485
534
|
return result;
|
|
486
535
|
}
|
|
487
536
|
// Try prefix match (escape SQL wildcards in user input)
|
|
488
537
|
const escapedPrefix = prefix.replace(/[%_]/g, '\\$&');
|
|
489
|
-
let sql = `SELECT session_id,
|
|
538
|
+
let sql = `SELECT session_id, target_id FROM sessions WHERE session_id LIKE ? ESCAPE '\\'`;
|
|
490
539
|
const params = [escapedPrefix + '%'];
|
|
491
|
-
if (
|
|
492
|
-
sql += ` AND
|
|
493
|
-
params.push(
|
|
540
|
+
if (targetId) {
|
|
541
|
+
sql += ` AND target_id = ?`;
|
|
542
|
+
params.push(targetId);
|
|
494
543
|
}
|
|
495
544
|
sql += ` ORDER BY started_at DESC LIMIT 1`;
|
|
496
545
|
stmt = this.db.prepare(sql);
|
|
@@ -536,5 +585,550 @@ export class EventsStore {
|
|
|
536
585
|
response: response || undefined,
|
|
537
586
|
};
|
|
538
587
|
}
|
|
588
|
+
// ==================== A2A Sessions (Phase 7.0) ====================
|
|
589
|
+
/**
|
|
590
|
+
* Get A2A sessions for a target
|
|
591
|
+
*
|
|
592
|
+
* A2A sessions are sessions with actor_kind = 'agent'
|
|
593
|
+
*
|
|
594
|
+
* @param targetId - Target ID (agent ID)
|
|
595
|
+
* @param limit - Maximum number of sessions to return
|
|
596
|
+
* @returns Array of sessions with message count and last activity
|
|
597
|
+
*/
|
|
598
|
+
getA2ASessions(targetId, limit = 50) {
|
|
599
|
+
const sql = `
|
|
600
|
+
SELECT
|
|
601
|
+
s.session_id,
|
|
602
|
+
(SELECT COUNT(*) FROM events WHERE session_id = s.session_id AND (normalized_json LIKE '%"actor":"user"%' OR normalized_json LIKE '%"actor":"assistant"%')) as message_count,
|
|
603
|
+
COALESCE(
|
|
604
|
+
(SELECT ts FROM events WHERE session_id = s.session_id ORDER BY ts DESC LIMIT 1),
|
|
605
|
+
s.started_at
|
|
606
|
+
) as last_activity
|
|
607
|
+
FROM sessions s
|
|
608
|
+
WHERE s.target_id = ? AND s.actor_kind = 'agent'
|
|
609
|
+
ORDER BY last_activity DESC
|
|
610
|
+
LIMIT ?
|
|
611
|
+
`;
|
|
612
|
+
const stmt = this.db.prepare(sql);
|
|
613
|
+
return stmt.all(targetId, limit);
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Get A2A messages for a session
|
|
617
|
+
*
|
|
618
|
+
* Returns messages with role, content, and timestamp from normalized_json
|
|
619
|
+
*
|
|
620
|
+
* @param sessionId - Session ID
|
|
621
|
+
* @param limit - Maximum number of messages to return
|
|
622
|
+
* @returns Array of A2A messages
|
|
623
|
+
*/
|
|
624
|
+
getA2AMessages(sessionId, limit = 100) {
|
|
625
|
+
const sql = `
|
|
626
|
+
SELECT
|
|
627
|
+
e.event_id,
|
|
628
|
+
e.normalized_json,
|
|
629
|
+
e.raw_json,
|
|
630
|
+
e.ts
|
|
631
|
+
FROM events e
|
|
632
|
+
WHERE e.session_id = ?
|
|
633
|
+
AND e.normalized_json IS NOT NULL
|
|
634
|
+
AND (e.normalized_json LIKE '%"actor":"user"%' OR e.normalized_json LIKE '%"actor":"assistant"%')
|
|
635
|
+
ORDER BY e.ts ASC
|
|
636
|
+
LIMIT ?
|
|
637
|
+
`;
|
|
638
|
+
const stmt = this.db.prepare(sql);
|
|
639
|
+
const events = stmt.all(sessionId, limit);
|
|
640
|
+
const messages = [];
|
|
641
|
+
for (let i = 0; i < events.length; i++) {
|
|
642
|
+
const event = events[i];
|
|
643
|
+
let role = 'user';
|
|
644
|
+
let content = '';
|
|
645
|
+
if (event.normalized_json) {
|
|
646
|
+
try {
|
|
647
|
+
const normalized = JSON.parse(event.normalized_json);
|
|
648
|
+
if (normalized.actor === 'assistant') {
|
|
649
|
+
role = 'assistant';
|
|
650
|
+
}
|
|
651
|
+
if (normalized.content && normalized.content.type === 'text') {
|
|
652
|
+
content = normalized.content.text || '';
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
catch {
|
|
656
|
+
// If parsing fails, try raw_json
|
|
657
|
+
if (event.raw_json) {
|
|
658
|
+
try {
|
|
659
|
+
const raw = JSON.parse(event.raw_json);
|
|
660
|
+
// Raw format: { jsonrpc: '2.0', id: '...', result: { role: '...', parts: [...] } }
|
|
661
|
+
const result = raw.result || raw;
|
|
662
|
+
if (result.role === 'assistant') {
|
|
663
|
+
role = 'assistant';
|
|
664
|
+
}
|
|
665
|
+
if (result.parts && Array.isArray(result.parts)) {
|
|
666
|
+
content = result.parts
|
|
667
|
+
.filter((p) => p && typeof p === 'object' && 'text' in p)
|
|
668
|
+
.map((p) => p.text)
|
|
669
|
+
.join('');
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
catch {
|
|
673
|
+
// Parsing failed, use summary or empty
|
|
674
|
+
content = '';
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
messages.push({
|
|
680
|
+
id: i + 1,
|
|
681
|
+
role,
|
|
682
|
+
content,
|
|
683
|
+
timestamp: event.ts,
|
|
684
|
+
rawJson: event.raw_json,
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
return messages;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Get A2A message detail by index
|
|
691
|
+
*
|
|
692
|
+
* @param sessionId - Session ID
|
|
693
|
+
* @param index - Message index (1-based)
|
|
694
|
+
* @returns Message detail or null if not found
|
|
695
|
+
*/
|
|
696
|
+
getA2AMessageByIndex(sessionId, index) {
|
|
697
|
+
const messages = this.getA2AMessages(sessionId, index);
|
|
698
|
+
return messages[index - 1] || null;
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Get A2A session by session ID (with metadata)
|
|
702
|
+
*
|
|
703
|
+
* @param sessionId - Session ID (or prefix)
|
|
704
|
+
* @param targetId - Optional target ID for filtering
|
|
705
|
+
* @returns Session or null
|
|
706
|
+
*/
|
|
707
|
+
getA2ASessionById(sessionId, targetId) {
|
|
708
|
+
let sql = `
|
|
709
|
+
SELECT
|
|
710
|
+
s.session_id,
|
|
711
|
+
s.target_id,
|
|
712
|
+
s.started_at,
|
|
713
|
+
(SELECT COUNT(*) FROM events WHERE session_id = s.session_id AND (normalized_json LIKE '%"actor":"user"%' OR normalized_json LIKE '%"actor":"assistant"%')) as message_count,
|
|
714
|
+
COALESCE(
|
|
715
|
+
(SELECT ts FROM events WHERE session_id = s.session_id ORDER BY ts DESC LIMIT 1),
|
|
716
|
+
s.started_at
|
|
717
|
+
) as last_activity
|
|
718
|
+
FROM sessions s
|
|
719
|
+
WHERE s.session_id LIKE ? AND s.actor_kind = 'agent'
|
|
720
|
+
`;
|
|
721
|
+
const params = [sessionId + '%'];
|
|
722
|
+
if (targetId) {
|
|
723
|
+
sql += ` AND s.target_id = ?`;
|
|
724
|
+
params.push(targetId);
|
|
725
|
+
}
|
|
726
|
+
sql += ` ORDER BY s.started_at DESC LIMIT 1`;
|
|
727
|
+
const stmt = this.db.prepare(sql);
|
|
728
|
+
return stmt.get(...params);
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Get A2A messages across all sessions for a target (agent)
|
|
732
|
+
*
|
|
733
|
+
* Phase 2.3.1: Cross-session history search
|
|
734
|
+
*
|
|
735
|
+
* Returns messages in descending timestamp order (newest first)
|
|
736
|
+
*
|
|
737
|
+
* @param targetId - Target ID (agent ID)
|
|
738
|
+
* @param limit - Maximum number of messages to return
|
|
739
|
+
* @returns Array of A2A messages with session ID
|
|
740
|
+
*/
|
|
741
|
+
getA2AMessagesForTarget(targetId, limit) {
|
|
742
|
+
const sql = `
|
|
743
|
+
SELECT
|
|
744
|
+
e.session_id,
|
|
745
|
+
e.ts,
|
|
746
|
+
json_extract(e.normalized_json, '$.actor') as role,
|
|
747
|
+
json_extract(e.normalized_json, '$.content.text') as content
|
|
748
|
+
FROM events e
|
|
749
|
+
JOIN sessions s ON e.session_id = s.session_id
|
|
750
|
+
WHERE s.target_id = ?
|
|
751
|
+
AND e.normalized_json IS NOT NULL
|
|
752
|
+
AND (json_extract(e.normalized_json, '$.actor') = 'user'
|
|
753
|
+
OR json_extract(e.normalized_json, '$.actor') = 'assistant')
|
|
754
|
+
ORDER BY e.ts DESC
|
|
755
|
+
LIMIT ?
|
|
756
|
+
`;
|
|
757
|
+
const stmt = this.db.prepare(sql);
|
|
758
|
+
const rows = stmt.all(targetId, limit);
|
|
759
|
+
const messages = [];
|
|
760
|
+
for (let i = 0; i < rows.length; i++) {
|
|
761
|
+
const row = rows[i];
|
|
762
|
+
messages.push({
|
|
763
|
+
id: i + 1,
|
|
764
|
+
sessionId: row.session_id,
|
|
765
|
+
role: (row.role === 'assistant' ? 'assistant' : 'user'),
|
|
766
|
+
content: row.content || '',
|
|
767
|
+
timestamp: row.ts,
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
// Return in descending order (newest first)
|
|
771
|
+
return messages;
|
|
772
|
+
}
|
|
773
|
+
// ==================== Task Events (Phase 2.4) ====================
|
|
774
|
+
/**
|
|
775
|
+
* Normalize task status string to TaskStatus
|
|
776
|
+
* @private
|
|
777
|
+
*/
|
|
778
|
+
normalizeTaskStatus(status) {
|
|
779
|
+
if (typeof status !== 'string')
|
|
780
|
+
return 'pending';
|
|
781
|
+
const validStatuses = [
|
|
782
|
+
'pending',
|
|
783
|
+
'working',
|
|
784
|
+
'input_required',
|
|
785
|
+
'completed',
|
|
786
|
+
'failed',
|
|
787
|
+
'canceled',
|
|
788
|
+
'rejected',
|
|
789
|
+
];
|
|
790
|
+
if (validStatuses.includes(status)) {
|
|
791
|
+
return status;
|
|
792
|
+
}
|
|
793
|
+
return 'pending';
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Save a task event
|
|
797
|
+
*
|
|
798
|
+
* @param sessionId - Session ID
|
|
799
|
+
* @param taskEventKind - Task event kind
|
|
800
|
+
* @param payload - Task event payload
|
|
801
|
+
* @returns Task event record
|
|
802
|
+
*/
|
|
803
|
+
saveTaskEvent(sessionId, taskEventKind, payload) {
|
|
804
|
+
const event = {
|
|
805
|
+
event_id: randomUUID(),
|
|
806
|
+
session_id: sessionId,
|
|
807
|
+
task_id: payload.taskId,
|
|
808
|
+
event_kind: taskEventKind,
|
|
809
|
+
ts: new Date().toISOString(),
|
|
810
|
+
payload_json: JSON.stringify(payload),
|
|
811
|
+
};
|
|
812
|
+
const stmt = this.db.prepare(`
|
|
813
|
+
INSERT INTO task_events (event_id, session_id, task_id, event_kind, ts, payload_json)
|
|
814
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
815
|
+
`);
|
|
816
|
+
stmt.run(event.event_id, event.session_id, event.task_id, event.event_kind, event.ts, event.payload_json);
|
|
817
|
+
return event;
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* Get task events for a session
|
|
821
|
+
*
|
|
822
|
+
* @param sessionId - Session ID
|
|
823
|
+
* @param limit - Maximum number of events to return
|
|
824
|
+
* @returns Task events in chronological order
|
|
825
|
+
*/
|
|
826
|
+
getTaskEventsBySession(sessionId, limit) {
|
|
827
|
+
let sql = `SELECT * FROM task_events WHERE session_id = ? ORDER BY ts ASC`;
|
|
828
|
+
if (limit) {
|
|
829
|
+
sql += ` LIMIT ${limit}`;
|
|
830
|
+
}
|
|
831
|
+
const stmt = this.db.prepare(sql);
|
|
832
|
+
return stmt.all(sessionId);
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Get task events for a specific task
|
|
836
|
+
*
|
|
837
|
+
* @param taskId - Task ID
|
|
838
|
+
* @returns Task events for the task in chronological order
|
|
839
|
+
*/
|
|
840
|
+
getTaskEventsByTaskId(taskId) {
|
|
841
|
+
const stmt = this.db.prepare(`
|
|
842
|
+
SELECT * FROM task_events WHERE task_id = ? ORDER BY ts ASC
|
|
843
|
+
`);
|
|
844
|
+
return stmt.all(taskId);
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Get recent task events across all sessions
|
|
848
|
+
*
|
|
849
|
+
* @param limit - Maximum number of events to return
|
|
850
|
+
* @returns Task events in descending order (newest first)
|
|
851
|
+
*/
|
|
852
|
+
getRecentTaskEvents(limit = 20) {
|
|
853
|
+
const stmt = this.db.prepare(`
|
|
854
|
+
SELECT * FROM task_events ORDER BY ts DESC LIMIT ?
|
|
855
|
+
`);
|
|
856
|
+
const events = stmt.all(limit);
|
|
857
|
+
return events.reverse(); // Return in chronological order (oldest first)
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Get all task events for a target (agent)
|
|
861
|
+
*
|
|
862
|
+
* @param targetId - Target ID (agent ID)
|
|
863
|
+
* @param limit - Maximum number of events to return
|
|
864
|
+
* @returns Task events in chronological order
|
|
865
|
+
*/
|
|
866
|
+
getTaskEventsByTarget(targetId, limit = 100) {
|
|
867
|
+
const stmt = this.db.prepare(`
|
|
868
|
+
SELECT te.* FROM task_events te
|
|
869
|
+
JOIN sessions s ON te.session_id = s.session_id
|
|
870
|
+
WHERE s.target_id = ?
|
|
871
|
+
ORDER BY te.ts ASC
|
|
872
|
+
LIMIT ?
|
|
873
|
+
`);
|
|
874
|
+
return stmt.all(targetId, limit);
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Get the last recorded status for a task
|
|
878
|
+
*
|
|
879
|
+
* @param taskId - Task ID
|
|
880
|
+
* @returns Last task event or null if not found
|
|
881
|
+
*/
|
|
882
|
+
getLastTaskEvent(taskId) {
|
|
883
|
+
const stmt = this.db.prepare(`
|
|
884
|
+
SELECT * FROM task_events
|
|
885
|
+
WHERE task_id = ?
|
|
886
|
+
ORDER BY ts DESC
|
|
887
|
+
LIMIT 1
|
|
888
|
+
`);
|
|
889
|
+
return stmt.get(taskId);
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Record task creation event
|
|
893
|
+
*
|
|
894
|
+
* @param sessionId - Session ID
|
|
895
|
+
* @param taskId - Task ID
|
|
896
|
+
* @param rawStatus - Raw status string from response
|
|
897
|
+
*/
|
|
898
|
+
recordTaskCreated(sessionId, taskId, rawStatus) {
|
|
899
|
+
const status = this.normalizeTaskStatus(rawStatus);
|
|
900
|
+
this.saveTaskEvent(sessionId, 'a2a:task:created', {
|
|
901
|
+
taskId,
|
|
902
|
+
rawStatus,
|
|
903
|
+
status,
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Record task status update event
|
|
908
|
+
*
|
|
909
|
+
* Only records if status actually changed (no duplicate status events)
|
|
910
|
+
*
|
|
911
|
+
* @param sessionId - Session ID
|
|
912
|
+
* @param taskId - Task ID
|
|
913
|
+
* @param rawStatus - New raw status string
|
|
914
|
+
* @returns True if event was recorded, false if status unchanged
|
|
915
|
+
*/
|
|
916
|
+
recordTaskUpdated(sessionId, taskId, rawStatus) {
|
|
917
|
+
const status = this.normalizeTaskStatus(rawStatus);
|
|
918
|
+
// Check last recorded status to avoid duplicate events
|
|
919
|
+
const lastEvent = this.getLastTaskEvent(taskId);
|
|
920
|
+
if (lastEvent) {
|
|
921
|
+
const lastPayload = JSON.parse(lastEvent.payload_json);
|
|
922
|
+
if (lastPayload.status === status) {
|
|
923
|
+
// Status unchanged, don't record
|
|
924
|
+
return false;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
this.saveTaskEvent(sessionId, 'a2a:task:updated', {
|
|
928
|
+
taskId,
|
|
929
|
+
rawStatus,
|
|
930
|
+
status,
|
|
931
|
+
previousStatus: lastEvent
|
|
932
|
+
? JSON.parse(lastEvent.payload_json).status
|
|
933
|
+
: undefined,
|
|
934
|
+
});
|
|
935
|
+
return true;
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Record task completion event
|
|
939
|
+
*
|
|
940
|
+
* @param sessionId - Session ID
|
|
941
|
+
* @param taskId - Task ID
|
|
942
|
+
* @param rawStatus - Raw status string
|
|
943
|
+
* @param messages - Messages (optional)
|
|
944
|
+
* @param artifacts - Artifacts (optional)
|
|
945
|
+
*/
|
|
946
|
+
recordTaskCompleted(sessionId, taskId, rawStatus, messages, artifacts) {
|
|
947
|
+
this.saveTaskEvent(sessionId, 'a2a:task:completed', {
|
|
948
|
+
taskId,
|
|
949
|
+
rawStatus,
|
|
950
|
+
status: 'completed',
|
|
951
|
+
messages,
|
|
952
|
+
artifacts,
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Record task failure event
|
|
957
|
+
*
|
|
958
|
+
* @param sessionId - Session ID
|
|
959
|
+
* @param taskId - Task ID
|
|
960
|
+
* @param rawStatus - Raw status string
|
|
961
|
+
* @param error - Error message
|
|
962
|
+
*/
|
|
963
|
+
recordTaskFailed(sessionId, taskId, rawStatus, error) {
|
|
964
|
+
this.saveTaskEvent(sessionId, 'a2a:task:failed', {
|
|
965
|
+
taskId,
|
|
966
|
+
rawStatus,
|
|
967
|
+
status: 'failed',
|
|
968
|
+
error,
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Record task cancellation event
|
|
973
|
+
*
|
|
974
|
+
* @param sessionId - Session ID
|
|
975
|
+
* @param taskId - Task ID
|
|
976
|
+
* @param rawStatus - Raw status string
|
|
977
|
+
*/
|
|
978
|
+
recordTaskCanceled(sessionId, taskId, rawStatus) {
|
|
979
|
+
this.saveTaskEvent(sessionId, 'a2a:task:canceled', {
|
|
980
|
+
taskId,
|
|
981
|
+
rawStatus,
|
|
982
|
+
status: 'canceled',
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* Record task wait timeout event
|
|
987
|
+
*
|
|
988
|
+
* @param sessionId - Session ID
|
|
989
|
+
* @param taskId - Task ID
|
|
990
|
+
* @param error - Error message
|
|
991
|
+
*/
|
|
992
|
+
recordTaskWaitTimeout(sessionId, taskId, error) {
|
|
993
|
+
this.saveTaskEvent(sessionId, 'a2a:task:wait_timeout', {
|
|
994
|
+
taskId,
|
|
995
|
+
rawStatus: 'timeout',
|
|
996
|
+
status: 'failed',
|
|
997
|
+
error: error || 'Task wait timeout',
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* Record task poll error event
|
|
1002
|
+
*
|
|
1003
|
+
* @param sessionId - Session ID
|
|
1004
|
+
* @param taskId - Task ID
|
|
1005
|
+
* @param error - Error message
|
|
1006
|
+
*/
|
|
1007
|
+
recordTaskPollError(sessionId, taskId, error) {
|
|
1008
|
+
this.saveTaskEvent(sessionId, 'a2a:task:poll_error', {
|
|
1009
|
+
taskId,
|
|
1010
|
+
rawStatus: 'poll_error',
|
|
1011
|
+
status: 'failed',
|
|
1012
|
+
error: error || 'Task poll error',
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
// ==================== UI Events (Phase 6.2) ====================
|
|
1016
|
+
/**
|
|
1017
|
+
* Save a UI tool request event
|
|
1018
|
+
*
|
|
1019
|
+
* @param uiSessionId - UI session ID (derived from sessionToken)
|
|
1020
|
+
* @param uiRpcId - UI RPC ID
|
|
1021
|
+
* @param correlationId - Correlation ID
|
|
1022
|
+
* @param toolCallFingerprint - Tool call fingerprint
|
|
1023
|
+
* @param toolName - Tool name
|
|
1024
|
+
* @param payload - Event payload (arguments, sessionToken, etc.)
|
|
1025
|
+
* @returns UI event record
|
|
1026
|
+
*/
|
|
1027
|
+
saveUiToolRequestEvent(uiSessionId, uiRpcId, correlationId, toolCallFingerprint, toolName, payload) {
|
|
1028
|
+
const event = {
|
|
1029
|
+
event_id: randomUUID(),
|
|
1030
|
+
ui_session_id: uiSessionId,
|
|
1031
|
+
ui_rpc_id: uiRpcId,
|
|
1032
|
+
correlation_id: correlationId,
|
|
1033
|
+
tool_call_fingerprint: toolCallFingerprint,
|
|
1034
|
+
event_type: 'ui_tool_request',
|
|
1035
|
+
tool_name: toolName,
|
|
1036
|
+
ts: Date.now(),
|
|
1037
|
+
payload_json: JSON.stringify(payload),
|
|
1038
|
+
};
|
|
1039
|
+
const stmt = this.db.prepare(`
|
|
1040
|
+
INSERT INTO ui_events (event_id, ui_session_id, ui_rpc_id, correlation_id, tool_call_fingerprint, event_type, tool_name, ts, payload_json)
|
|
1041
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1042
|
+
`);
|
|
1043
|
+
stmt.run(event.event_id, event.ui_session_id, event.ui_rpc_id, event.correlation_id, event.tool_call_fingerprint, event.event_type, event.tool_name, event.ts, event.payload_json);
|
|
1044
|
+
return { event_id: event.event_id, ts: event.ts };
|
|
1045
|
+
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Save a UI tool result event
|
|
1048
|
+
*
|
|
1049
|
+
* @param uiSessionId - UI session ID
|
|
1050
|
+
* @param uiRpcId - UI RPC ID
|
|
1051
|
+
* @param correlationId - Correlation ID
|
|
1052
|
+
* @param toolCallFingerprint - Tool call fingerprint
|
|
1053
|
+
* @param payload - Event payload (result, duration_ms, etc.)
|
|
1054
|
+
* @returns UI event record
|
|
1055
|
+
*/
|
|
1056
|
+
saveUiToolResultEvent(uiSessionId, uiRpcId, correlationId, toolCallFingerprint, payload) {
|
|
1057
|
+
const event = {
|
|
1058
|
+
event_id: randomUUID(),
|
|
1059
|
+
ui_session_id: uiSessionId,
|
|
1060
|
+
ui_rpc_id: uiRpcId,
|
|
1061
|
+
correlation_id: correlationId,
|
|
1062
|
+
tool_call_fingerprint: toolCallFingerprint,
|
|
1063
|
+
event_type: 'ui_tool_result',
|
|
1064
|
+
tool_name: null,
|
|
1065
|
+
ts: Date.now(),
|
|
1066
|
+
payload_json: JSON.stringify(payload),
|
|
1067
|
+
};
|
|
1068
|
+
const stmt = this.db.prepare(`
|
|
1069
|
+
INSERT INTO ui_events (event_id, ui_session_id, ui_rpc_id, correlation_id, tool_call_fingerprint, event_type, tool_name, ts, payload_json)
|
|
1070
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1071
|
+
`);
|
|
1072
|
+
stmt.run(event.event_id, event.ui_session_id, event.ui_rpc_id, event.correlation_id, event.tool_call_fingerprint, event.event_type, event.tool_name, event.ts, event.payload_json);
|
|
1073
|
+
return { event_id: event.event_id, ts: event.ts };
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Save a UI tool delivered event (sent to UI)
|
|
1077
|
+
*
|
|
1078
|
+
* @param uiSessionId - UI session ID
|
|
1079
|
+
* @param uiRpcId - UI RPC ID
|
|
1080
|
+
* @param correlationId - Correlation ID
|
|
1081
|
+
* @param toolCallFingerprint - Tool call fingerprint
|
|
1082
|
+
* @param payload - Event payload (result)
|
|
1083
|
+
* @returns UI event record
|
|
1084
|
+
*/
|
|
1085
|
+
saveUiToolDeliveredEvent(uiSessionId, uiRpcId, correlationId, toolCallFingerprint, payload) {
|
|
1086
|
+
const event = {
|
|
1087
|
+
event_id: randomUUID(),
|
|
1088
|
+
ui_session_id: uiSessionId,
|
|
1089
|
+
ui_rpc_id: uiRpcId,
|
|
1090
|
+
correlation_id: correlationId,
|
|
1091
|
+
tool_call_fingerprint: toolCallFingerprint,
|
|
1092
|
+
event_type: 'ui_tool_delivered',
|
|
1093
|
+
tool_name: null,
|
|
1094
|
+
ts: Date.now(),
|
|
1095
|
+
payload_json: JSON.stringify(payload),
|
|
1096
|
+
};
|
|
1097
|
+
const stmt = this.db.prepare(`
|
|
1098
|
+
INSERT INTO ui_events (event_id, ui_session_id, ui_rpc_id, correlation_id, tool_call_fingerprint, event_type, tool_name, ts, payload_json)
|
|
1099
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1100
|
+
`);
|
|
1101
|
+
stmt.run(event.event_id, event.ui_session_id, event.ui_rpc_id, event.correlation_id, event.tool_call_fingerprint, event.event_type, event.tool_name, event.ts, event.payload_json);
|
|
1102
|
+
return { event_id: event.event_id, ts: event.ts };
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Get UI events by correlation ID
|
|
1106
|
+
*
|
|
1107
|
+
* @param correlationId - Correlation ID
|
|
1108
|
+
* @returns UI events with matching correlation ID
|
|
1109
|
+
*/
|
|
1110
|
+
getUiEventsByCorrelationId(correlationId) {
|
|
1111
|
+
const stmt = this.db.prepare(`
|
|
1112
|
+
SELECT * FROM ui_events WHERE correlation_id = ? ORDER BY ts ASC
|
|
1113
|
+
`);
|
|
1114
|
+
return stmt.all(correlationId);
|
|
1115
|
+
}
|
|
1116
|
+
/**
|
|
1117
|
+
* Get UI events by session ID
|
|
1118
|
+
*
|
|
1119
|
+
* @param uiSessionId - UI session ID
|
|
1120
|
+
* @param limit - Maximum number of events to return
|
|
1121
|
+
* @returns UI events for the session
|
|
1122
|
+
*/
|
|
1123
|
+
getUiEventsBySession(uiSessionId, limit = 100) {
|
|
1124
|
+
const sql = `
|
|
1125
|
+
SELECT * FROM ui_events
|
|
1126
|
+
WHERE ui_session_id = ?
|
|
1127
|
+
ORDER BY ts DESC
|
|
1128
|
+
LIMIT ?
|
|
1129
|
+
`;
|
|
1130
|
+
const stmt = this.db.prepare(sql);
|
|
1131
|
+
return stmt.all(uiSessionId, limit);
|
|
1132
|
+
}
|
|
539
1133
|
}
|
|
540
1134
|
//# sourceMappingURL=events-store.js.map
|