@botbotgo/agent-harness 0.0.267 → 0.0.269

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 (47) hide show
  1. package/README.md +8 -0
  2. package/README.zh.md +7 -0
  3. package/dist/acp.js +2 -2
  4. package/dist/api.d.ts +6 -11
  5. package/dist/api.js +20 -23
  6. package/dist/contracts/runtime.d.ts +38 -70
  7. package/dist/flow/build-flow-graph.js +29 -45
  8. package/dist/flow/types.d.ts +0 -6
  9. package/dist/package-version.d.ts +1 -1
  10. package/dist/package-version.js +1 -1
  11. package/dist/persistence/file-store.js +24 -17
  12. package/dist/persistence/sqlite-run-context-store.js +2 -2
  13. package/dist/persistence/sqlite-store.js +18 -16
  14. package/dist/protocol/a2a/http.js +48 -46
  15. package/dist/protocol/ag-ui/http.js +9 -9
  16. package/dist/runtime/adapter/invocation-result.js +2 -2
  17. package/dist/runtime/harness/events/listener-runtime.d.ts +2 -2
  18. package/dist/runtime/harness/events/streaming.d.ts +8 -8
  19. package/dist/runtime/harness/events/streaming.js +10 -10
  20. package/dist/runtime/harness/events/timeline.js +4 -4
  21. package/dist/runtime/harness/run/helpers.js +2 -2
  22. package/dist/runtime/harness/run/recovery.js +20 -20
  23. package/dist/runtime/harness/run/resume.js +3 -3
  24. package/dist/runtime/harness/run/run-lifecycle.js +5 -5
  25. package/dist/runtime/harness/run/run-operations.d.ts +2 -2
  26. package/dist/runtime/harness/run/run-operations.js +21 -21
  27. package/dist/runtime/harness/run/start-run.d.ts +3 -3
  28. package/dist/runtime/harness/run/start-run.js +3 -3
  29. package/dist/runtime/harness/run/startup-runtime.js +1 -1
  30. package/dist/runtime/harness/run/stream-run.js +37 -27
  31. package/dist/runtime/harness/run/thread-records.js +12 -33
  32. package/dist/runtime/harness/system/mem0-ingestion-sync.js +2 -2
  33. package/dist/runtime/harness/system/runtime-memory-manager.js +4 -4
  34. package/dist/runtime/harness/system/runtime-memory-records.js +6 -6
  35. package/dist/runtime/harness/system/runtime-memory-sync.js +6 -4
  36. package/dist/runtime/harness/system/thread-memory-sync.js +7 -5
  37. package/dist/runtime/harness.d.ts +2 -2
  38. package/dist/runtime/harness.js +161 -156
  39. package/dist/runtime/support/harness-support.js +4 -4
  40. package/dist/workspace/compile.js +6 -5
  41. package/dist/workspace/object-loader.d.ts +4 -1
  42. package/dist/workspace/object-loader.js +13 -5
  43. package/dist/workspace/support/workspace-ref-utils.d.ts +5 -0
  44. package/dist/workspace/support/workspace-ref-utils.js +9 -0
  45. package/dist/workspace/tool-hydration.d.ts +2 -1
  46. package/dist/workspace/tool-hydration.js +4 -4
  47. package/package.json +1 -1
@@ -46,14 +46,14 @@ function normalizeRuntimeEventType(eventType) {
46
46
  function normalizeRuntimeEvents(events) {
47
47
  return events.map((event) => {
48
48
  const typed = event;
49
- const threadId = readString(typed.threadId) ?? readString(typed.sessionId) ?? "";
50
- const runId = readString(typed.runId) ?? readString(typed.requestId) ?? "";
49
+ const sessionId = readString(typed.sessionId) ?? "";
50
+ const requestId = readString(typed.requestId) ?? "";
51
51
  return {
52
52
  eventId: String(event.eventId),
53
53
  eventType: normalizeRuntimeEventType(String(event.eventType)),
54
54
  timestamp: String(event.timestamp),
55
- threadId,
56
- runId,
55
+ sessionId,
56
+ requestId,
57
57
  sequence: Number(event.sequence),
58
58
  source: event.source,
59
59
  payload: event.payload ?? {},
@@ -103,10 +103,10 @@ function normalizeLabel(value) {
103
103
  return value.replace(/\s+/g, " ").trim();
104
104
  }
105
105
  function readSessionId(input) {
106
- return input.sessionId ?? input.threadId;
106
+ return input.sessionId;
107
107
  }
108
108
  function readRequestId(input) {
109
- return input.requestId ?? input.runId;
109
+ return input.requestId;
110
110
  }
111
111
  function readProjectionLabel(projection) {
112
112
  if (projection.type === "step") {
@@ -241,15 +241,13 @@ function buildRuntimeNodes(timeline) {
241
241
  for (const item of timeline) {
242
242
  const mapped = deriveRuntimeNode(item);
243
243
  const node = {
244
- id: `rt:${item.runId}:${item.sequence}:${slugify(item.eventType)}`,
244
+ id: `rt:${item.requestId}:${item.sequence}:${slugify(item.eventType)}`,
245
245
  layer: "runtime",
246
246
  kind: mapped.kind,
247
247
  label: mapped.label,
248
248
  status: mapped.status,
249
- sessionId: item.threadId,
250
- requestId: item.runId,
251
- threadId: item.threadId,
252
- runId: item.runId,
249
+ sessionId: item.sessionId,
250
+ requestId: item.requestId,
253
251
  startedAt: item.timestamp,
254
252
  endedAt: item.timestamp,
255
253
  sequenceStart: item.sequence,
@@ -277,7 +275,7 @@ function buildRuntimeNodes(timeline) {
277
275
  if (item.eventType === "run.created" || item.eventType === "run.dequeued" || item.eventType === "run.resumed") {
278
276
  segmentOrdinal += 1;
279
277
  activeExecutionGroup = {
280
- id: `group:${item.runId}:segment:${segmentOrdinal}`,
278
+ id: `group:${item.requestId}:segment:${segmentOrdinal}`,
281
279
  kind: "segment",
282
280
  label: item.eventType === "run.created"
283
281
  ? `Execution segment ${segmentOrdinal}`
@@ -296,7 +294,7 @@ function buildRuntimeNodes(timeline) {
296
294
  if (item.eventType === "approval.requested") {
297
295
  approvalOrdinal += 1;
298
296
  activeApprovalGroup = {
299
- id: `group:${item.runId}:approval:${approvalOrdinal}`,
297
+ id: `group:${item.requestId}:approval:${approvalOrdinal}`,
300
298
  kind: "approval-window",
301
299
  label: `Approval window ${approvalOrdinal}`,
302
300
  nodeIds: [node.id],
@@ -311,7 +309,7 @@ function buildRuntimeNodes(timeline) {
311
309
  if (!activeApprovalGroup) {
312
310
  approvalOrdinal += 1;
313
311
  activeApprovalGroup = {
314
- id: `group:${item.runId}:approval:${approvalOrdinal}`,
312
+ id: `group:${item.requestId}:approval:${approvalOrdinal}`,
315
313
  kind: "approval-window",
316
314
  label: `Approval window ${approvalOrdinal}`,
317
315
  nodeIds: [],
@@ -444,8 +442,6 @@ function createDelegationNodeFromSurfaceItem(surfaceItem, fallbackAgentId, fallb
444
442
  status: surfaceItem.status === "failed" ? "failed" : surfaceItem.status === "started" ? "started" : "completed",
445
443
  sessionId: "",
446
444
  requestId: "",
447
- threadId: "",
448
- runId: "",
449
445
  agentId: toAgentId,
450
446
  agentName: toAgentName,
451
447
  sourceEventIds: [sourceEventId],
@@ -554,8 +550,6 @@ function convertUpstreamEventsWithAgents(upstreamEvents, initialAgentId) {
554
550
  status: "completed",
555
551
  sessionId: "",
556
552
  requestId: "",
557
- threadId: "",
558
- runId: "",
559
553
  agentId: delegatedAgentId,
560
554
  agentName: delegatedAgentName,
561
555
  sourceEventIds: [sourceEventId],
@@ -574,7 +568,7 @@ function convertUpstreamEventsWithAgents(upstreamEvents, initialAgentId) {
574
568
  function selectInitialGroup(groups) {
575
569
  return groups.find((group) => group.kind === "segment") ?? groups[0] ?? null;
576
570
  }
577
- function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, threadId, runId) {
571
+ function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, sessionId, requestId) {
578
572
  const nodes = [];
579
573
  const edges = [];
580
574
  const groups = [];
@@ -601,7 +595,7 @@ function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, thread
601
595
  function createAttempt(kind, label, projection, agentId, agentName) {
602
596
  ordinal += 1;
603
597
  const attempt = {
604
- id: `attempt:${runId}:${slugify(kind)}:${slugify(label)}:${ordinal}`,
598
+ id: `attempt:${requestId}:${slugify(kind)}:${slugify(label)}:${ordinal}`,
605
599
  kind,
606
600
  label,
607
601
  status: deriveStatusFromProjection(projection),
@@ -647,10 +641,8 @@ function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, thread
647
641
  delegationIndex += 1;
648
642
  pendingDelegationNode = {
649
643
  ...sourceNode,
650
- sessionId: threadId,
651
- requestId: runId,
652
- threadId,
653
- runId,
644
+ sessionId,
645
+ requestId,
654
646
  groupId: currentGroup?.id,
655
647
  };
656
648
  nodes.push(pendingDelegationNode);
@@ -685,10 +677,8 @@ function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, thread
685
677
  delegationIndex += 1;
686
678
  pendingDelegationNode = {
687
679
  ...sourceNode,
688
- sessionId: threadId,
689
- requestId: runId,
690
- threadId,
691
- runId,
680
+ sessionId,
681
+ requestId,
692
682
  groupId: currentGroup?.id,
693
683
  };
694
684
  nodes.push(pendingDelegationNode);
@@ -705,15 +695,13 @@ function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, thread
705
695
  if (projection.type === "thinking") {
706
696
  ordinal += 1;
707
697
  const detailNode = {
708
- id: `detail:${runId}:thinking:${ordinal}`,
698
+ id: `detail:${requestId}:thinking:${ordinal}`,
709
699
  layer: "detail",
710
700
  kind: "thinking",
711
701
  label: "Model reasoning",
712
702
  status: "completed",
713
- sessionId: threadId,
714
- requestId: runId,
715
- threadId,
716
- runId,
703
+ sessionId,
704
+ requestId,
717
705
  groupId: currentGroup?.id,
718
706
  sourceEventIds: [],
719
707
  detail: { text: projection.text },
@@ -785,7 +773,7 @@ function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, thread
785
773
  }
786
774
  if (!attemptSetGroups.has(`${kind}:${currentGroup?.id ?? "ungrouped"}`)) {
787
775
  attemptSetGroups.set(`${kind}:${currentGroup?.id ?? "ungrouped"}`, {
788
- id: `group:${runId}:attempt-set:${slugify(kind)}:${attemptSetGroups.size + 1}`,
776
+ id: `group:${requestId}:attempt-set:${slugify(kind)}:${attemptSetGroups.size + 1}`,
789
777
  kind: "attempt-set",
790
778
  label: `${titleCase(kind)} attempts`,
791
779
  nodeIds: [],
@@ -838,10 +826,8 @@ function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, thread
838
826
  kind: attempt.kind,
839
827
  label: attempt.label,
840
828
  status: attempt.status,
841
- sessionId: threadId,
842
- requestId: runId,
843
- threadId,
844
- runId,
829
+ sessionId,
830
+ requestId,
845
831
  agentId: attempt.agentId,
846
832
  agentName: attempt.agentName,
847
833
  groupId: attempt.groupId,
@@ -865,21 +851,21 @@ function resolveContext(input, runtimeTimeline, projections) {
865
851
  }
866
852
  if (timelineHead) {
867
853
  return {
868
- sessionId: inputSessionId ?? timelineHead.threadId,
869
- requestId: inputRequestId ?? timelineHead.runId,
854
+ sessionId: inputSessionId ?? timelineHead.sessionId,
855
+ requestId: inputRequestId ?? timelineHead.requestId,
870
856
  };
871
857
  }
872
858
  const firstProjection = projections[0];
873
859
  if (!inputSessionId || !inputRequestId) {
874
- throw new Error(`buildFlowGraph requires sessionId and requestId when runtime timeline data is absent${firstProjection ? "" : " or empty"}; legacy threadId/runId inputs are still accepted.`);
860
+ throw new Error(`buildFlowGraph requires sessionId and requestId when runtime timeline data is absent${firstProjection ? "" : " or empty"}.`);
875
861
  }
876
862
  return { sessionId: inputSessionId, requestId: inputRequestId };
877
863
  }
878
864
  export function buildFlowGraph(input) {
879
865
  const runtimeData = input.runtimeTimeline
880
866
  ?? (input.runtimeEvents ? projectRuntimeTimeline(normalizeRuntimeEvents(input.runtimeEvents), {
881
- ...(readSessionId(input) ? { threadId: readSessionId(input) } : {}),
882
- ...(readRequestId(input) ? { runId: readRequestId(input) } : {}),
867
+ ...(readSessionId(input) ? { sessionId: readSessionId(input) } : {}),
868
+ ...(readRequestId(input) ? { requestId: readRequestId(input) } : {}),
883
869
  }) : []);
884
870
  const initialAgentId = deriveInitialAgentId(input, runtimeData);
885
871
  const upstreamContext = input.upstreamEvents
@@ -932,8 +918,6 @@ export function buildFlowGraph(input) {
932
918
  scope: input.scope ?? "run",
933
919
  sessionId,
934
920
  requestId,
935
- threadId: sessionId,
936
- runId: requestId,
937
921
  nodes: [...runtimeNodes, ...attemptNodes],
938
922
  edges: [...runtimeEdges, ...attemptEdges],
939
923
  groups: [...runtimeGroups, ...attemptGroups],
@@ -23,8 +23,6 @@ export type FlowNode = {
23
23
  status: FlowNodeStatus;
24
24
  sessionId: string;
25
25
  requestId: string;
26
- threadId: string;
27
- runId: string;
28
26
  agentId?: string;
29
27
  agentName?: string;
30
28
  startedAt?: string;
@@ -59,8 +57,6 @@ export type FlowGraph = {
59
57
  scope: "run" | "thread";
60
58
  sessionId: string;
61
59
  requestId: string;
62
- threadId: string;
63
- runId: string;
64
60
  nodes: FlowNode[];
65
61
  edges: FlowEdge[];
66
62
  groups: FlowGroup[];
@@ -69,8 +65,6 @@ export type FlowGraph = {
69
65
  export type BuildFlowGraphInput = {
70
66
  sessionId?: string;
71
67
  requestId?: string;
72
- threadId?: string;
73
- runId?: string;
74
68
  scope?: FlowGraph["scope"];
75
69
  runtimeEvents?: readonly BuildFlowGraphRuntimeEvent[];
76
70
  runtimeTimeline?: readonly RuntimeTimelineItem[];
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.266";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.268";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.266";
1
+ export const AGENT_HARNESS_VERSION = "0.0.268";
@@ -197,10 +197,10 @@ export class FilePersistence {
197
197
  }
198
198
  async appendEvent(event) {
199
199
  const sequenceId = String(event.sequence).padStart(6, "0");
200
- const inspectionPath = path.join(this.runDir(event.threadId, event.runId), "inspection.json");
200
+ const inspectionPath = path.join(this.runDir(event.sessionId, event.requestId), "inspection.json");
201
201
  const inspection = await readJson(inspectionPath);
202
202
  await Promise.all([
203
- writeJson(path.join(this.runDir(event.threadId, event.runId), "events", `${sequenceId}.json`), event),
203
+ writeJson(path.join(this.runDir(event.sessionId, event.requestId), "events", `${sequenceId}.json`), event),
204
204
  writeJson(inspectionPath, {
205
205
  ...inspection,
206
206
  lastActivityAt: event.timestamp,
@@ -221,8 +221,8 @@ export class FilePersistence {
221
221
  ]);
222
222
  return {
223
223
  agentId: meta.entryAgentId,
224
- threadId: index.threadId,
225
- latestRunId: index.latestRunId,
224
+ sessionId: index.threadId,
225
+ latestRequestId: index.latestRunId,
226
226
  createdAt: meta.createdAt,
227
227
  updatedAt: index.updatedAt,
228
228
  status: index.status,
@@ -237,9 +237,9 @@ export class FilePersistence {
237
237
  const sessions = await this.listSessions(filter);
238
238
  const summaries = await Promise.all(sessions.map(async (session) => {
239
239
  const [meta, messageBundle] = await Promise.all([
240
- readJson(path.join(this.threadDir(session.threadId), "meta.json")),
241
- readJson(path.join(this.threadDir(session.threadId), "messages.json"))
242
- .catch(() => ({ threadId: session.threadId, items: [] })),
240
+ readJson(path.join(this.threadDir(session.sessionId), "meta.json")),
241
+ readJson(path.join(this.threadDir(session.sessionId), "messages.json"))
242
+ .catch(() => ({ threadId: session.sessionId, items: [] })),
243
243
  ]);
244
244
  const items = messageBundle.items;
245
245
  return {
@@ -268,8 +268,8 @@ export class FilePersistence {
268
268
  readJson(path.join(runDir, "inspection.json")),
269
269
  ]);
270
270
  return {
271
- runId: meta.runId,
272
- threadId: meta.threadId,
271
+ requestId: meta.runId,
272
+ sessionId: meta.threadId,
273
273
  agentId: meta.agentId,
274
274
  ...(meta.parentRunId ? { parentRunId: meta.parentRunId } : {}),
275
275
  executionMode: meta.executionMode,
@@ -295,7 +295,7 @@ export class FilePersistence {
295
295
  if (filter.agentId && run.agentId !== filter.agentId) {
296
296
  return false;
297
297
  }
298
- if (filter.threadId && run.threadId !== filter.threadId) {
298
+ if (filter.threadId && run.sessionId !== filter.threadId) {
299
299
  return false;
300
300
  }
301
301
  if (filter.state && run.state !== filter.state) {
@@ -325,8 +325,8 @@ export class FilePersistence {
325
325
  const runInspection = await readJson(path.join(this.runDir(threadId, index.latestRunId), "inspection.json")).catch(() => null);
326
326
  return {
327
327
  agentId: meta.entryAgentId,
328
- threadId,
329
- latestRunId: index.latestRunId,
328
+ sessionId: threadId,
329
+ latestRequestId: index.latestRunId,
330
330
  createdAt: meta.createdAt,
331
331
  updatedAt: index.updatedAt,
332
332
  status: index.status,
@@ -370,10 +370,10 @@ export class FilePersistence {
370
370
  if (filter.status && approval.status !== filter.status) {
371
371
  return false;
372
372
  }
373
- if (filter.threadId && approval.threadId !== filter.threadId) {
373
+ if (filter.threadId && approval.sessionId !== filter.threadId) {
374
374
  return false;
375
375
  }
376
- if (filter.runId && approval.runId !== filter.runId) {
376
+ if (filter.runId && approval.requestId !== filter.runId) {
377
377
  return false;
378
378
  }
379
379
  return true;
@@ -460,7 +460,7 @@ export class FilePersistence {
460
460
  .filter((record) => record.threadId === threadId)
461
461
  .map((record) => rm(this.runIndexPath(record.runId), { force: true })),
462
462
  ...approvals
463
- .filter((record) => record.threadId === threadId)
463
+ .filter((record) => record.sessionId === threadId)
464
464
  .map((record) => rm(this.approvalIndexPath(record.approvalId), { force: true })),
465
465
  ...runIndexes
466
466
  .filter((record) => record.threadId === threadId)
@@ -487,9 +487,16 @@ export class FilePersistence {
487
487
  }
488
488
  }
489
489
  async createApproval(record) {
490
+ const sessionId = record.sessionId ?? record.threadId ?? "";
491
+ const requestId = record.requestId ?? record.runId ?? "";
492
+ const normalized = {
493
+ ...record,
494
+ sessionId,
495
+ requestId,
496
+ };
490
497
  await Promise.all([
491
- writeJson(path.join(this.runDir(record.threadId, record.runId), "approvals", `${record.approvalId}.json`), record),
492
- writeJson(path.join(this.runRoot, "indexes", "approvals", `${record.approvalId}.json`), record),
498
+ writeJson(path.join(this.runDir(sessionId, requestId), "approvals", `${record.approvalId}.json`), normalized),
499
+ writeJson(path.join(this.runRoot, "indexes", "approvals", `${record.approvalId}.json`), normalized),
493
500
  ]);
494
501
  }
495
502
  async resolveApproval(threadId, runId, approvalId, status) {
@@ -27,7 +27,7 @@ export class SqliteRunContextStore {
27
27
  async appendThreadMessage(threadId, message) {
28
28
  await this.db.execute(`INSERT INTO thread_messages
29
29
  (thread_id, role, content_json, run_id, created_at)
30
- VALUES (?, ?, ?, ?, ?)`, [threadId, message.role, JSON.stringify(message.content), message.runId, message.createdAt]);
30
+ VALUES (?, ?, ?, ?, ?)`, [threadId, message.role, JSON.stringify(message.content), message.requestId ?? message.runId, message.createdAt]);
31
31
  }
32
32
  async listThreadMessages(threadId, limit = 12) {
33
33
  const rows = await this.db.selectAll(`SELECT role, content_json, run_id, created_at
@@ -42,7 +42,7 @@ export class SqliteRunContextStore {
42
42
  return rows.map((row) => ({
43
43
  role: asString(row.role),
44
44
  content: parseJson(row.content_json),
45
- runId: asString(row.run_id),
45
+ requestId: asString(row.run_id),
46
46
  createdAt: asString(row.created_at),
47
47
  }));
48
48
  }
@@ -413,8 +413,8 @@ export class SqlitePersistence {
413
413
  mapThreadSummary(row) {
414
414
  return {
415
415
  agentId: asString(row.entry_agent_id),
416
- threadId: asString(row.thread_id),
417
- latestRunId: asString(row.latest_run_id),
416
+ sessionId: asString(row.thread_id),
417
+ latestRequestId: asString(row.latest_run_id),
418
418
  createdAt: asString(row.created_at),
419
419
  updatedAt: asString(row.updated_at),
420
420
  status: asString(row.status),
@@ -424,8 +424,8 @@ export class SqlitePersistence {
424
424
  mapRunSummary(row) {
425
425
  const runtimeSnapshot = row.runtime_snapshot_json ? parseJson(row.runtime_snapshot_json) : null;
426
426
  return {
427
- runId: asString(row.run_id),
428
- threadId: asString(row.thread_id),
427
+ requestId: asString(row.run_id),
428
+ sessionId: asString(row.thread_id),
429
429
  agentId: asString(row.agent_id),
430
430
  ...(asNullableString(row.parent_run_id) ? { parentRunId: asNullableString(row.parent_run_id) } : {}),
431
431
  executionMode: asString(row.execution_mode),
@@ -458,8 +458,8 @@ export class SqlitePersistence {
458
458
  return {
459
459
  approvalId: asString(row.approval_id),
460
460
  pendingActionId: asString(row.pending_action_id),
461
- threadId: asString(row.thread_id),
462
- runId: asString(row.run_id),
461
+ sessionId: asString(row.thread_id),
462
+ requestId: asString(row.run_id),
463
463
  toolCallId: asString(row.tool_call_id),
464
464
  toolName: asString(row.tool_name),
465
465
  status: asString(row.status),
@@ -612,7 +612,7 @@ export class SqlitePersistence {
612
612
  input.threadId,
613
613
  input.userMessage.role,
614
614
  JSON.stringify(input.userMessage.content),
615
- input.userMessage.runId,
615
+ input.userMessage.requestId ?? input.userMessage.runId,
616
616
  input.userMessage.createdAt,
617
617
  ],
618
618
  }, {
@@ -681,10 +681,10 @@ export class SqlitePersistence {
681
681
  async appendEvent(event) {
682
682
  await this.execute(`INSERT OR REPLACE INTO events
683
683
  (thread_id, run_id, sequence, event_json, created_at)
684
- VALUES (?, ?, ?, ?, ?)`, [event.threadId, event.runId, event.sequence, JSON.stringify(event), event.timestamp]);
684
+ VALUES (?, ?, ?, ?, ?)`, [event.sessionId, event.requestId, event.sequence, JSON.stringify(event), event.timestamp]);
685
685
  await this.execute(`UPDATE run_inspection
686
686
  SET last_activity_at = ?
687
- WHERE run_id = ? AND thread_id = ?`, [event.timestamp, event.runId, event.threadId]);
687
+ WHERE run_id = ? AND thread_id = ?`, [event.timestamp, event.requestId, event.sessionId]);
688
688
  }
689
689
  async listSessions(filter = {}) {
690
690
  const { clause, args } = buildWhereClause([
@@ -750,7 +750,7 @@ export class SqlitePersistence {
750
750
  ? {
751
751
  role: asString(row.first_message_role),
752
752
  content: parseJson(row.first_message_content_json),
753
- runId: asString(row.first_message_run_id),
753
+ requestId: asString(row.first_message_run_id),
754
754
  createdAt: asString(row.first_message_created_at),
755
755
  }
756
756
  : undefined,
@@ -758,7 +758,7 @@ export class SqlitePersistence {
758
758
  ? {
759
759
  role: asString(row.last_message_role),
760
760
  content: parseJson(row.last_message_content_json),
761
- runId: asString(row.last_message_run_id),
761
+ requestId: asString(row.last_message_run_id),
762
762
  createdAt: asString(row.last_message_created_at),
763
763
  }
764
764
  : undefined,
@@ -972,13 +972,15 @@ export class SqlitePersistence {
972
972
  await this.runContextStore.clearRunRequest(threadId, runId);
973
973
  }
974
974
  async createApproval(record) {
975
+ const sessionId = record.sessionId ?? record.threadId ?? "";
976
+ const requestId = record.requestId ?? record.runId ?? "";
975
977
  await this.execute(`INSERT OR REPLACE INTO approvals
976
978
  (approval_id, pending_action_id, thread_id, run_id, tool_call_id, tool_name, status, requested_at, resolved_at, allowed_decisions_json, input_preview_json, checkpoint_ref, event_refs_json)
977
979
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
978
980
  record.approvalId,
979
981
  record.pendingActionId,
980
- record.threadId,
981
- record.runId,
982
+ sessionId,
983
+ requestId,
982
984
  record.toolCallId,
983
985
  record.toolName,
984
986
  record.status,
@@ -992,7 +994,7 @@ export class SqlitePersistence {
992
994
  }
993
995
  async resolveApproval(threadId, runId, approvalId, status) {
994
996
  const current = await this.getApproval(approvalId);
995
- if (!current || current.threadId !== threadId || current.runId !== runId) {
997
+ if (!current || current.sessionId !== threadId || current.requestId !== runId) {
996
998
  throw new Error(`Missing approval ${approvalId} for run ${runId}`);
997
999
  }
998
1000
  const updated = {
@@ -1018,8 +1020,8 @@ export class SqlitePersistence {
1018
1020
  WHERE thread_id = ? AND run_id = ?
1019
1021
  ORDER BY created_at ASC, artifact_id ASC`, [threadId, runId]);
1020
1022
  return {
1021
- threadId,
1022
- runId,
1023
+ sessionId: threadId,
1024
+ requestId: runId,
1023
1025
  items: rows.map((row) => ({
1024
1026
  artifactId: asString(row.artifact_id),
1025
1027
  kind: asString(row.kind),