@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.
- package/README.md +8 -0
- package/README.zh.md +7 -0
- package/dist/acp.js +2 -2
- package/dist/api.d.ts +6 -11
- package/dist/api.js +20 -23
- package/dist/contracts/runtime.d.ts +38 -70
- package/dist/flow/build-flow-graph.js +29 -45
- package/dist/flow/types.d.ts +0 -6
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/file-store.js +24 -17
- package/dist/persistence/sqlite-run-context-store.js +2 -2
- package/dist/persistence/sqlite-store.js +18 -16
- package/dist/protocol/a2a/http.js +48 -46
- package/dist/protocol/ag-ui/http.js +9 -9
- package/dist/runtime/adapter/invocation-result.js +2 -2
- package/dist/runtime/harness/events/listener-runtime.d.ts +2 -2
- package/dist/runtime/harness/events/streaming.d.ts +8 -8
- package/dist/runtime/harness/events/streaming.js +10 -10
- package/dist/runtime/harness/events/timeline.js +4 -4
- package/dist/runtime/harness/run/helpers.js +2 -2
- package/dist/runtime/harness/run/recovery.js +20 -20
- package/dist/runtime/harness/run/resume.js +3 -3
- package/dist/runtime/harness/run/run-lifecycle.js +5 -5
- package/dist/runtime/harness/run/run-operations.d.ts +2 -2
- package/dist/runtime/harness/run/run-operations.js +21 -21
- package/dist/runtime/harness/run/start-run.d.ts +3 -3
- package/dist/runtime/harness/run/start-run.js +3 -3
- package/dist/runtime/harness/run/startup-runtime.js +1 -1
- package/dist/runtime/harness/run/stream-run.js +37 -27
- package/dist/runtime/harness/run/thread-records.js +12 -33
- package/dist/runtime/harness/system/mem0-ingestion-sync.js +2 -2
- package/dist/runtime/harness/system/runtime-memory-manager.js +4 -4
- package/dist/runtime/harness/system/runtime-memory-records.js +6 -6
- package/dist/runtime/harness/system/runtime-memory-sync.js +6 -4
- package/dist/runtime/harness/system/thread-memory-sync.js +7 -5
- package/dist/runtime/harness.d.ts +2 -2
- package/dist/runtime/harness.js +161 -156
- package/dist/runtime/support/harness-support.js +4 -4
- package/dist/workspace/compile.js +6 -5
- package/dist/workspace/object-loader.d.ts +4 -1
- package/dist/workspace/object-loader.js +13 -5
- package/dist/workspace/support/workspace-ref-utils.d.ts +5 -0
- package/dist/workspace/support/workspace-ref-utils.js +9 -0
- package/dist/workspace/tool-hydration.d.ts +2 -1
- package/dist/workspace/tool-hydration.js +4 -4
- 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
|
|
50
|
-
const
|
|
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
|
-
|
|
56
|
-
|
|
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
|
|
106
|
+
return input.sessionId;
|
|
107
107
|
}
|
|
108
108
|
function readRequestId(input) {
|
|
109
|
-
return input.requestId
|
|
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.
|
|
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.
|
|
250
|
-
requestId: item.
|
|
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.
|
|
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.
|
|
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.
|
|
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,
|
|
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:${
|
|
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
|
|
651
|
-
requestId
|
|
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
|
|
689
|
-
requestId
|
|
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:${
|
|
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
|
|
714
|
-
requestId
|
|
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:${
|
|
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
|
|
842
|
-
requestId
|
|
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.
|
|
869
|
-
requestId: inputRequestId ?? timelineHead.
|
|
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"}
|
|
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) ? {
|
|
882
|
-
...(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],
|
package/dist/flow/types.d.ts
CHANGED
|
@@ -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.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.268";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
225
|
-
|
|
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.
|
|
241
|
-
readJson(path.join(this.threadDir(session.
|
|
242
|
-
.catch(() => ({ threadId: session.
|
|
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
|
-
|
|
272
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
373
|
+
if (filter.threadId && approval.sessionId !== filter.threadId) {
|
|
374
374
|
return false;
|
|
375
375
|
}
|
|
376
|
-
if (filter.runId && approval.
|
|
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.
|
|
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(
|
|
492
|
-
writeJson(path.join(this.runRoot, "indexes", "approvals", `${record.approvalId}.json`),
|
|
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
|
-
|
|
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
|
-
|
|
417
|
-
|
|
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
|
-
|
|
428
|
-
|
|
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
|
-
|
|
462
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
981
|
-
|
|
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.
|
|
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),
|