@botbotgo/agent-harness 0.0.268 → 0.0.270

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 (44) hide show
  1. package/README.md +3 -2
  2. package/README.zh.md +3 -2
  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 +42 -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 +69 -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/adapter/tool/tool-hitl.d.ts +3 -1
  18. package/dist/runtime/adapter/tool/tool-hitl.js +75 -6
  19. package/dist/runtime/harness/events/listener-runtime.d.ts +2 -2
  20. package/dist/runtime/harness/events/streaming.d.ts +8 -8
  21. package/dist/runtime/harness/events/streaming.js +10 -10
  22. package/dist/runtime/harness/events/timeline.js +4 -4
  23. package/dist/runtime/harness/run/governance.js +33 -4
  24. package/dist/runtime/harness/run/helpers.js +2 -2
  25. package/dist/runtime/harness/run/operator-overview.js +6 -0
  26. package/dist/runtime/harness/run/recovery.js +20 -20
  27. package/dist/runtime/harness/run/resume.js +3 -3
  28. package/dist/runtime/harness/run/run-lifecycle.js +5 -5
  29. package/dist/runtime/harness/run/run-operations.d.ts +2 -2
  30. package/dist/runtime/harness/run/run-operations.js +21 -21
  31. package/dist/runtime/harness/run/start-run.d.ts +3 -3
  32. package/dist/runtime/harness/run/start-run.js +3 -3
  33. package/dist/runtime/harness/run/startup-runtime.js +1 -1
  34. package/dist/runtime/harness/run/stream-run.js +37 -27
  35. package/dist/runtime/harness/run/thread-records.js +12 -33
  36. package/dist/runtime/harness/system/mem0-ingestion-sync.js +2 -2
  37. package/dist/runtime/harness/system/runtime-memory-manager.js +4 -4
  38. package/dist/runtime/harness/system/runtime-memory-records.js +6 -6
  39. package/dist/runtime/harness/system/runtime-memory-sync.js +6 -4
  40. package/dist/runtime/harness/system/thread-memory-sync.js +7 -5
  41. package/dist/runtime/harness.d.ts +2 -2
  42. package/dist/runtime/harness.js +161 -156
  43. package/dist/runtime/support/harness-support.js +4 -4
  44. package/package.json +1 -1
@@ -51,6 +51,70 @@ const ACTIVE_RUN_STATES = [
51
51
  "resuming",
52
52
  "cancelling",
53
53
  ];
54
+ function toPublicRunResultShape(result) {
55
+ return {
56
+ sessionId: result.sessionId ?? result.threadId ?? "",
57
+ requestId: result.requestId ?? result.runId ?? "",
58
+ state: result.state,
59
+ output: result.output,
60
+ finalMessageText: result.finalMessageText,
61
+ outputContent: result.outputContent,
62
+ contentBlocks: result.contentBlocks,
63
+ structuredResponse: result.structuredResponse,
64
+ interruptContent: result.interruptContent,
65
+ agentId: result.agentId,
66
+ approvalId: result.approvalId,
67
+ pendingActionId: result.pendingActionId,
68
+ delegationId: result.delegationId,
69
+ artifacts: result.artifacts,
70
+ metadata: result.metadata,
71
+ };
72
+ }
73
+ function toPublicHarnessStreamItem(item) {
74
+ switch (item.type) {
75
+ case "content":
76
+ return {
77
+ type: "content",
78
+ sessionId: item.sessionId,
79
+ requestId: item.requestId,
80
+ agentId: item.agentId,
81
+ content: item.content,
82
+ };
83
+ case "content-blocks":
84
+ return {
85
+ type: "content-blocks",
86
+ sessionId: item.sessionId,
87
+ requestId: item.requestId,
88
+ agentId: item.agentId,
89
+ contentBlocks: item.contentBlocks,
90
+ };
91
+ case "tool-result":
92
+ return {
93
+ type: "tool-result",
94
+ sessionId: item.sessionId,
95
+ requestId: item.requestId,
96
+ agentId: item.agentId,
97
+ toolName: item.toolName,
98
+ output: item.output,
99
+ ...(item.isError !== undefined ? { isError: item.isError } : {}),
100
+ };
101
+ case "upstream-event":
102
+ return {
103
+ type: "upstream-event",
104
+ sessionId: item.sessionId,
105
+ requestId: item.requestId,
106
+ ...(item.surfaceItem ? { surfaceItem: item.surfaceItem } : {}),
107
+ event: item.event,
108
+ };
109
+ case "result":
110
+ return {
111
+ type: "result",
112
+ result: toPublicRunResultShape(item.result),
113
+ };
114
+ default:
115
+ return item;
116
+ }
117
+ }
54
118
  function normalizeSessionListText(content, limit) {
55
119
  if (!content) {
56
120
  return undefined;
@@ -66,8 +130,8 @@ function toSessionListSummary(session) {
66
130
  return {
67
131
  agentId: session.agentId,
68
132
  entryAgentId: session.entryAgentId,
69
- sessionId: session.threadId,
70
- latestRequestId: session.latestRunId,
133
+ sessionId: session.sessionId,
134
+ latestRequestId: session.latestRequestId,
71
135
  createdAt: session.createdAt,
72
136
  updatedAt: session.updatedAt,
73
137
  status: session.status,
@@ -363,8 +427,8 @@ export class AgentHarnessRuntime {
363
427
  const sessions = await this.persistence.listSessions(filter);
364
428
  return sessions.map((session) => ({
365
429
  agentId: session.agentId,
366
- sessionId: session.threadId,
367
- latestRequestId: session.latestRunId,
430
+ sessionId: session.sessionId,
431
+ latestRequestId: session.latestRequestId,
368
432
  createdAt: session.createdAt,
369
433
  updatedAt: session.updatedAt,
370
434
  status: session.status,
@@ -376,16 +440,7 @@ export class AgentHarnessRuntime {
376
440
  return sessions.map((session) => toSessionListSummary(session));
377
441
  }
378
442
  async listThreads(filter) {
379
- const sessions = await this.listSessions(filter);
380
- return sessions.map((session) => ({
381
- agentId: session.agentId,
382
- threadId: session.sessionId,
383
- latestRunId: session.latestRequestId,
384
- createdAt: session.createdAt,
385
- updatedAt: session.updatedAt,
386
- status: session.status,
387
- currentAgentId: session.currentAgentId,
388
- }));
443
+ return this.listSessions(filter);
389
444
  }
390
445
  async listRequests(filter) {
391
446
  const requests = await this.persistence.listRuns({
@@ -394,8 +449,8 @@ export class AgentHarnessRuntime {
394
449
  state: filter?.state,
395
450
  });
396
451
  return requests.map((request) => ({
397
- requestId: request.runId,
398
- sessionId: request.threadId,
452
+ requestId: request.requestId,
453
+ sessionId: request.sessionId,
399
454
  agentId: request.agentId,
400
455
  parentRunId: request.parentRunId,
401
456
  executionMode: request.executionMode,
@@ -414,30 +469,11 @@ export class AgentHarnessRuntime {
414
469
  }));
415
470
  }
416
471
  async listRuns(filter) {
417
- const requests = await this.listRequests({
472
+ return this.listRequests({
418
473
  agentId: filter?.agentId,
419
474
  sessionId: filter?.threadId,
420
475
  state: filter?.state,
421
476
  });
422
- return requests.map((request) => ({
423
- runId: request.requestId,
424
- threadId: request.sessionId,
425
- agentId: request.agentId,
426
- parentRunId: request.parentRunId,
427
- executionMode: request.executionMode,
428
- adapterKind: request.adapterKind,
429
- createdAt: request.createdAt,
430
- updatedAt: request.updatedAt,
431
- state: request.state,
432
- checkpointRef: request.checkpointRef,
433
- resumable: request.resumable,
434
- startedAt: request.startedAt,
435
- endedAt: request.endedAt,
436
- lastActivityAt: request.lastActivityAt,
437
- currentAgentId: request.currentAgentId,
438
- delegationChain: request.delegationChain,
439
- runtimeSnapshot: request.runtimeSnapshot,
440
- }));
441
477
  }
442
478
  async memorize(input) {
443
479
  const binding = this.defaultRuntimeEntryBinding;
@@ -456,10 +492,10 @@ export class AgentHarnessRuntime {
456
492
  if (candidates.some((record) => typeof record.content !== "string" || record.content.trim().length === 0)) {
457
493
  throw new Error("memorize requires every record to include non-empty content.");
458
494
  }
459
- const sessionId = input.sessionId ?? input.threadId;
460
- const requestId = input.requestId ?? input.runId;
495
+ const sessionId = input.sessionId;
496
+ const requestId = input.requestId;
461
497
  if (candidates.some((record) => (record.scope ?? "thread") === "thread") && !sessionId) {
462
- throw new Error("memorize requires sessionId (or legacy threadId) when storing thread-scoped memory.");
498
+ throw new Error("memorize requires sessionId when storing thread-scoped memory.");
463
499
  }
464
500
  const recordedAt = input.recordedAt ?? new Date().toISOString();
465
501
  const runId = requestId ?? createPersistentId(new Date(recordedAt));
@@ -483,7 +519,7 @@ export class AgentHarnessRuntime {
483
519
  if (typeof input.query !== "string" || input.query.trim().length === 0) {
484
520
  throw new Error("recall requires a non-empty query.");
485
521
  }
486
- const sessionId = input.sessionId ?? input.threadId;
522
+ const sessionId = input.sessionId;
487
523
  const workspaceId = this.getWorkspaceId(binding);
488
524
  const agentId = input.agentId ?? binding.agent.id;
489
525
  const userId = input.userId ?? "default";
@@ -516,7 +552,7 @@ export class AgentHarnessRuntime {
516
552
  if (!binding) {
517
553
  throw new Error("listMemories requires a runtime entry binding.");
518
554
  }
519
- const sessionId = input.sessionId ?? input.threadId;
555
+ const sessionId = input.sessionId;
520
556
  const workspaceId = this.getWorkspaceId(binding);
521
557
  const scopes = Array.isArray(input.scopes) && input.scopes.length > 0
522
558
  ? Array.from(new Set(input.scopes))
@@ -609,37 +645,15 @@ export class AgentHarnessRuntime {
609
645
  return request ? buildRequestInspectionRecord(this.persistence, request) : null;
610
646
  }
611
647
  async getRun(runId) {
612
- const request = await this.getRequest(runId);
613
- return request
614
- ? {
615
- runId: request.requestId,
616
- threadId: request.sessionId,
617
- agentId: request.agentId,
618
- executionMode: request.executionMode,
619
- adapterKind: request.adapterKind,
620
- createdAt: request.createdAt,
621
- updatedAt: request.updatedAt,
622
- state: request.state,
623
- checkpointRef: request.checkpointRef,
624
- resumable: request.resumable,
625
- startedAt: request.startedAt,
626
- endedAt: request.endedAt,
627
- lastActivityAt: request.lastActivityAt,
628
- currentAgentId: request.currentAgentId,
629
- delegationChain: request.delegationChain,
630
- runtimeSnapshot: request.runtimeSnapshot,
631
- traceItems: request.traceItems,
632
- runtimeTimeline: request.runtimeTimeline,
633
- }
634
- : null;
648
+ return this.getRequest(runId);
635
649
  }
636
650
  async getSessionSummary(sessionId) {
637
651
  const session = await this.persistence.getSession(sessionId);
638
652
  return session
639
653
  ? {
640
654
  agentId: session.agentId,
641
- sessionId: session.threadId,
642
- latestRequestId: session.latestRunId,
655
+ sessionId: session.sessionId,
656
+ latestRequestId: session.latestRequestId,
643
657
  createdAt: session.createdAt,
644
658
  updatedAt: session.updatedAt,
645
659
  status: session.status,
@@ -648,18 +662,7 @@ export class AgentHarnessRuntime {
648
662
  : null;
649
663
  }
650
664
  async getSession(threadId) {
651
- const session = await this.getSessionSummary(threadId);
652
- return session
653
- ? {
654
- agentId: session.agentId,
655
- threadId: session.sessionId,
656
- latestRunId: session.latestRequestId,
657
- createdAt: session.createdAt,
658
- updatedAt: session.updatedAt,
659
- status: session.status,
660
- currentAgentId: session.currentAgentId,
661
- }
662
- : null;
665
+ return this.getSessionSummary(threadId);
663
666
  }
664
667
  async getSessionRecord(sessionId) {
665
668
  return buildSessionInspectionRecord({
@@ -668,45 +671,17 @@ export class AgentHarnessRuntime {
668
671
  }, sessionId);
669
672
  }
670
673
  async getThread(threadId) {
671
- const session = await this.getSessionRecord(threadId);
672
- return session
673
- ? {
674
- threadId: session.sessionId,
675
- entryAgentId: session.entryAgentId,
676
- currentAgentId: session.currentAgentId,
677
- currentState: session.currentState,
678
- latestRunId: session.latestRequestId,
679
- createdAt: session.createdAt,
680
- updatedAt: session.updatedAt,
681
- messages: session.messages,
682
- runs: session.requests.map((request) => ({
683
- runId: request.requestId,
684
- threadId: request.sessionId,
685
- agentId: request.agentId,
686
- executionMode: request.executionMode,
687
- adapterKind: request.adapterKind,
688
- createdAt: request.createdAt,
689
- updatedAt: request.updatedAt,
690
- state: request.state,
691
- checkpointRef: request.checkpointRef,
692
- resumable: request.resumable,
693
- startedAt: request.startedAt,
694
- endedAt: request.endedAt,
695
- lastActivityAt: request.lastActivityAt,
696
- currentAgentId: request.currentAgentId,
697
- delegationChain: request.delegationChain,
698
- runtimeSnapshot: request.runtimeSnapshot,
699
- traceItems: request.traceItems,
700
- runtimeTimeline: request.runtimeTimeline,
701
- })),
702
- pendingDecision: session.pendingDecision,
703
- }
704
- : null;
674
+ return this.getSessionRecord(threadId);
705
675
  }
706
676
  async listApprovals(filter) {
707
- return listPublicApprovals({
677
+ const approvals = await listPublicApprovals({
708
678
  persistence: this.persistence,
709
- }, filter);
679
+ }, {
680
+ status: filter?.status,
681
+ threadId: filter?.sessionId,
682
+ runId: filter?.requestId,
683
+ });
684
+ return approvals;
710
685
  }
711
686
  async getApproval(approvalId) {
712
687
  return getPublicApproval({
@@ -714,7 +689,12 @@ export class AgentHarnessRuntime {
714
689
  }, approvalId);
715
690
  }
716
691
  async listArtifacts(threadId, runId) {
717
- return this.persistence.listArtifacts(threadId, runId);
692
+ const listing = await this.persistence.listArtifacts(threadId, runId);
693
+ return {
694
+ sessionId: listing.sessionId,
695
+ requestId: listing.requestId,
696
+ items: listing.items,
697
+ };
718
698
  }
719
699
  async readArtifact(threadId, runId, artifactPath) {
720
700
  return this.persistence.readArtifact(threadId, runId, artifactPath);
@@ -728,7 +708,7 @@ export class AgentHarnessRuntime {
728
708
  async exportRequestPackage(input) {
729
709
  const session = await this.getSessionRecord(input.sessionId);
730
710
  const request = await this.getRequest(input.requestId);
731
- const approvals = await this.listApprovals({ threadId: input.sessionId, runId: input.requestId });
711
+ const approvals = await this.listApprovals({ sessionId: input.sessionId, requestId: input.requestId });
732
712
  const transcript = await this.persistence.listThreadMessages(input.sessionId, 500);
733
713
  const events = await this.listRequestEvents(input.sessionId, input.requestId);
734
714
  const artifactsListing = input.includeArtifacts === false
@@ -777,7 +757,7 @@ export class AgentHarnessRuntime {
777
757
  includeArtifactContents: input.includeArtifactContents,
778
758
  includeRuntimeHealth: false,
779
759
  })));
780
- const approvals = await this.listApprovals({ threadId: input.sessionId });
760
+ const approvals = await this.listApprovals({ sessionId: input.sessionId });
781
761
  const approvalSummary = summarizeApprovalEvidence(approvals);
782
762
  const governanceRuns = runs
783
763
  .filter((item) => item.request?.requestId)
@@ -803,7 +783,7 @@ export class AgentHarnessRuntime {
803
783
  const thread = await this.getThread(input.sessionId);
804
784
  const run = await this.getRun(input.requestId);
805
785
  const runRequest = await this.persistence.getRunRequest(input.sessionId, input.requestId);
806
- const approvals = await this.listApprovals({ threadId: input.sessionId, runId: input.requestId });
786
+ const approvals = await this.listApprovals({ sessionId: input.sessionId, requestId: input.requestId });
807
787
  const transcript = await this.persistence.listThreadMessages(input.sessionId, 500);
808
788
  const events = await this.persistence.listRunEvents(input.sessionId, input.requestId);
809
789
  const runtimeHealth = await this.getHealth();
@@ -979,11 +959,11 @@ export class AgentHarnessRuntime {
979
959
  }
980
960
  async loadPriorHistory(threadId, runId) {
981
961
  const history = await this.persistence.listThreadMessages(threadId);
982
- return history.filter((message) => message.runId !== runId);
962
+ return history.filter((message) => message.requestId !== runId);
983
963
  }
984
964
  async loadRunInput(threadId, runId) {
985
965
  const history = await this.persistence.listThreadMessages(threadId, 100);
986
- const userTurn = history.find((message) => message.runId === runId && message.role === "user");
966
+ const userTurn = history.find((message) => message.requestId === runId && message.role === "user");
987
967
  return userTurn?.content ?? "";
988
968
  }
989
969
  async getRunCancellation(runId) {
@@ -1037,7 +1017,8 @@ export class AgentHarnessRuntime {
1037
1017
  return (content.trim().split("\n")[0] || content.trim()).slice(0, 240);
1038
1018
  }
1039
1019
  matchesMemoryFilters(record, filters) {
1040
- if (filters.threadId && record.provenance.threadId !== filters.threadId) {
1020
+ const sessionId = String(record.provenance.sessionId ?? record.provenance.threadId ?? "");
1021
+ if (filters.threadId && sessionId !== filters.threadId) {
1041
1022
  return false;
1042
1023
  }
1043
1024
  if (filters.agentId && record.provenance.agentId !== filters.agentId) {
@@ -1069,7 +1050,8 @@ export class AgentHarnessRuntime {
1069
1050
  }
1070
1051
  matchesRecallScope(record, filters) {
1071
1052
  if (record.scope === "thread") {
1072
- return typeof filters.threadId === "string" && String(record.provenance.threadId ?? "") === filters.threadId;
1053
+ return typeof filters.threadId === "string"
1054
+ && String(record.provenance.sessionId ?? record.provenance.threadId ?? "") === filters.threadId;
1073
1055
  }
1074
1056
  if (record.scope === "agent") {
1075
1057
  return String(record.provenance.agentId ?? "") === filters.agentId;
@@ -1153,8 +1135,16 @@ export class AgentHarnessRuntime {
1153
1135
  tags: hit.categories,
1154
1136
  provenance: {
1155
1137
  source: "mem0",
1156
- threadId: typeof hit.metadata.threadId === "string" ? hit.metadata.threadId : filters.threadId,
1157
- runId: hit.runId ?? (typeof hit.metadata.runId === "string" ? hit.metadata.runId : undefined),
1138
+ sessionId: typeof hit.metadata.sessionId === "string"
1139
+ ? hit.metadata.sessionId
1140
+ : typeof hit.metadata.threadId === "string"
1141
+ ? hit.metadata.threadId
1142
+ : filters.threadId,
1143
+ requestId: (typeof hit.metadata.requestId === "string"
1144
+ ? hit.metadata.requestId
1145
+ : typeof hit.metadata.runId === "string"
1146
+ ? hit.metadata.runId
1147
+ : undefined),
1158
1148
  agentId: hit.agentId ?? (typeof hit.metadata.agentId === "string" ? hit.metadata.agentId : filters.agentId),
1159
1149
  workspaceId: filters.workspaceId,
1160
1150
  userId: filters.userId,
@@ -1271,7 +1261,7 @@ export class AgentHarnessRuntime {
1271
1261
  scope: record.scope,
1272
1262
  kind: record.kind,
1273
1263
  status: record.status,
1274
- threadId: record.provenance.threadId,
1264
+ sessionId: record.provenance.sessionId ?? record.provenance.threadId,
1275
1265
  agentId: record.provenance.agentId,
1276
1266
  workspaceId: record.provenance.workspaceId,
1277
1267
  userId: record.provenance.userId,
@@ -1298,7 +1288,7 @@ export class AgentHarnessRuntime {
1298
1288
  await consolidateStructuredMemoryScope({
1299
1289
  store: this.runtimeMemoryStore,
1300
1290
  namespace: this.resolveMemoryNamespace(record.scope, binding, {
1301
- threadId: provenance.threadId,
1291
+ threadId: provenance.sessionId,
1302
1292
  agentId: provenance.agentId,
1303
1293
  userId: provenance.userId,
1304
1294
  projectId: provenance.projectId,
@@ -1594,8 +1584,8 @@ export class AgentHarnessRuntime {
1594
1584
  async run(options) {
1595
1585
  if (this.isDecisionRun(options)) {
1596
1586
  const resumeOptions = {
1597
- threadId: options.threadId,
1598
- runId: options.runId,
1587
+ sessionId: options.sessionId,
1588
+ requestId: options.requestId,
1599
1589
  approvalId: options.approvalId,
1600
1590
  decision: options.decision,
1601
1591
  editedInput: options.editedInput,
@@ -1604,10 +1594,23 @@ export class AgentHarnessRuntime {
1604
1594
  }
1605
1595
  const resolvedListeners = resolveRunListeners(options);
1606
1596
  if (resolvedListeners) {
1607
- return createListenerDispatchRuntime({
1597
+ const result = await createListenerDispatchRuntime({
1608
1598
  notifyListener: (listener, value) => this.notifyListener(listener, value),
1609
- getThread: (threadId) => this.getThread(threadId),
1599
+ getThread: async (threadId) => {
1600
+ const thread = await this.getThread(threadId);
1601
+ return thread
1602
+ ? {
1603
+ currentState: thread.currentState,
1604
+ latestRequestId: thread.latestRequestId,
1605
+ entryAgentId: thread.entryAgentId,
1606
+ currentAgentId: thread.currentAgentId,
1607
+ requests: thread.requests.map((run) => ({ agentId: run.agentId })),
1608
+ pendingDecision: thread.pendingDecision,
1609
+ }
1610
+ : null;
1611
+ },
1610
1612
  }).dispatchRunListeners(this.streamEvents(options), resolvedListeners);
1613
+ return toPublicRunResultShape(result);
1611
1614
  }
1612
1615
  const invocation = normalizeInvocationEnvelope(options);
1613
1616
  const { binding, selectedAgentId, threadId, runId, isNewThread, runCreatedEventPromise, releaseRunSlotPromise, } = await prepareRunStart(this.createPrepareRunStartRuntime(), {
@@ -1623,7 +1626,7 @@ export class AgentHarnessRuntime {
1623
1626
  await runCreatedEventPromise;
1624
1627
  const releaseRunSlot = await releaseRunSlotPromise;
1625
1628
  try {
1626
- return await this.executeQueuedRun(binding, options.input, threadId, runId, selectedAgentId, {
1629
+ return toPublicRunResultShape(await this.executeQueuedRun(binding, options.input, threadId, runId, selectedAgentId, {
1627
1630
  context: invocation.context,
1628
1631
  state: invocation.state,
1629
1632
  files: invocation.files,
@@ -1631,7 +1634,7 @@ export class AgentHarnessRuntime {
1631
1634
  stateSequence: 6,
1632
1635
  approvalSequence: 7,
1633
1636
  priorHistory: isNewThread ? [] : undefined,
1634
- });
1637
+ }));
1635
1638
  }
1636
1639
  finally {
1637
1640
  await releaseRunSlot();
@@ -1639,7 +1642,7 @@ export class AgentHarnessRuntime {
1639
1642
  }
1640
1643
  async *streamEvents(options) {
1641
1644
  const invocation = normalizeInvocationEnvelope(options);
1642
- const selectedAgentId = await this.resolveSelectedAgentId(options.input, options.agentId, options.threadId);
1645
+ const selectedAgentId = await this.resolveSelectedAgentId(options.input, options.agentId, options.sessionId);
1643
1646
  const binding = getWorkspaceBinding(this.workspace, selectedAgentId);
1644
1647
  if (!binding) {
1645
1648
  const result = await this.run(options);
@@ -1687,11 +1690,11 @@ export class AgentHarnessRuntime {
1687
1690
  emitSyntheticFallback: (threadId, runId, selectedAgentId, error) => this.runtimeEventOperations.emitSyntheticFallback(threadId, runId, selectedAgentId, error),
1688
1691
  });
1689
1692
  for await (const item of stream) {
1690
- yield item;
1693
+ yield toPublicHarnessStreamItem(item);
1691
1694
  }
1692
1695
  }
1693
1696
  async resume(options) {
1694
- return resumeRun({
1697
+ return toPublicRunResultShape(await resumeRun({
1695
1698
  getApprovalById: (approvalId) => this.persistence.getApproval(approvalId),
1696
1699
  getSession: (threadId) => this.getSession(threadId),
1697
1700
  resolveApprovalRecord: (resumeOptions, thread) => resolveHarnessApprovalRecord(this.persistence, resumeOptions, thread),
@@ -1712,30 +1715,32 @@ export class AgentHarnessRuntime {
1712
1715
  recordLlmFailure: (startedAt) => this.recordLlmFailure(startedAt),
1713
1716
  clearRecoveryIntent: (threadId, runId) => this.persistence.clearRecoveryIntent(threadId, runId),
1714
1717
  finalizeContinuedRun: (binding, threadId, runId, input, actual, operationOptions) => this.finalizeContinuedRun(binding, threadId, runId, input, actual, operationOptions),
1715
- }, options);
1718
+ }, {
1719
+ ...options,
1720
+ }));
1716
1721
  }
1717
1722
  async restartConversation(options) {
1718
- const thread = await this.getSession(options.threadId);
1719
- if (!thread) {
1720
- throw new Error(`Unknown thread ${options.threadId}`);
1723
+ const session = await this.getSession(options.sessionId);
1724
+ if (!session) {
1725
+ throw new Error(`Unknown session ${options.sessionId}`);
1721
1726
  }
1722
- const sourceRunId = thread.latestRunId;
1723
- const targetThreadId = options.mode === "restart-new-thread" ? createPersistentId() : options.threadId;
1727
+ const sourceRequestId = session.latestRequestId;
1728
+ const targetSessionId = options.mode === "restart-new-thread" ? createPersistentId() : options.sessionId;
1724
1729
  const result = await this.run({
1725
- agentId: thread.agentId,
1730
+ agentId: session.agentId,
1726
1731
  input: options.input,
1727
- threadId: options.mode === "restart-new-thread" ? undefined : targetThreadId,
1732
+ sessionId: options.mode === "restart-new-thread" ? undefined : targetSessionId,
1728
1733
  });
1729
1734
  return {
1730
1735
  ...result,
1731
1736
  restart: {
1732
- sourceThreadId: options.threadId,
1733
- sourceRunId,
1737
+ sourceSessionId: options.sessionId,
1738
+ sourceRequestId,
1734
1739
  restartMode: options.mode,
1735
1740
  restartedBy: "console",
1736
1741
  restartedAt: new Date().toISOString(),
1737
- newThreadId: result.threadId,
1738
- newRunId: result.runId,
1742
+ newSessionId: result.sessionId,
1743
+ newRequestId: result.requestId,
1739
1744
  },
1740
1745
  };
1741
1746
  }
@@ -1761,13 +1766,13 @@ export class AgentHarnessRuntime {
1761
1766
  await this.close();
1762
1767
  }
1763
1768
  async cancelRun(options) {
1764
- return cancelRunOperation({
1769
+ return toPublicRunResultShape(await cancelRunOperation({
1765
1770
  getRun: (runId) => this.persistence.getRun(runId),
1766
1771
  requestRunCancel: (runId, reason) => this.persistence.requestRunCancel(runId, reason),
1767
1772
  dropPendingRunSlot: (runId) => this.dropPendingRunSlot(runId),
1768
1773
  finalizeCancelledRun: (threadId, runId, previousState, reason) => this.finalizeCancelledRun(threadId, runId, previousState, reason),
1769
1774
  setRunStateAndEmit: (threadId, runId, sequence, state, stateOptions) => this.setRunStateAndEmit(threadId, runId, sequence, state, stateOptions),
1770
- }, options);
1775
+ }, options));
1771
1776
  }
1772
1777
  async recoverStartupRuns() {
1773
1778
  await recoverHarnessStartupRuns({
@@ -1812,8 +1817,8 @@ export class AgentHarnessRuntime {
1812
1817
  }
1813
1818
  function toRequestSummary(summary) {
1814
1819
  return {
1815
- requestId: summary.runId,
1816
- sessionId: summary.threadId,
1820
+ requestId: summary.requestId,
1821
+ sessionId: summary.sessionId,
1817
1822
  agentId: summary.agentId,
1818
1823
  parentRunId: summary.parentRunId,
1819
1824
  executionMode: summary.executionMode,
@@ -1833,15 +1838,15 @@ function toRequestSummary(summary) {
1833
1838
  }
1834
1839
  function toSessionRecord(record) {
1835
1840
  return {
1836
- sessionId: record.threadId,
1841
+ sessionId: record.sessionId,
1837
1842
  entryAgentId: record.entryAgentId,
1838
1843
  currentAgentId: record.currentAgentId,
1839
1844
  currentState: record.currentState,
1840
- latestRequestId: record.latestRunId,
1845
+ latestRequestId: record.latestRequestId,
1841
1846
  createdAt: record.createdAt,
1842
1847
  updatedAt: record.updatedAt,
1843
1848
  messages: record.messages,
1844
- requests: record.runs.map(toRequestRecord),
1849
+ requests: record.requests.map(toRequestRecord),
1845
1850
  pendingDecision: record.pendingDecision,
1846
1851
  };
1847
1852
  }
@@ -1852,9 +1857,9 @@ function toRequestRecord(record) {
1852
1857
  runtimeTimeline: record.runtimeTimeline,
1853
1858
  };
1854
1859
  }
1855
- function deriveRunRequestFromTranscript(transcript, runId) {
1860
+ function deriveRunRequestFromTranscript(transcript, requestId) {
1856
1861
  const candidate = [...transcript]
1857
1862
  .reverse()
1858
- .find((message) => message.role === "user" && (!runId || message.runId === runId));
1863
+ .find((message) => message.role === "user" && (!requestId || message.requestId === requestId));
1859
1864
  return candidate ? { input: candidate.content } : null;
1860
1865
  }
@@ -59,8 +59,8 @@ export function createHarnessEvent(threadId, runId, sequence, eventType, payload
59
59
  eventId: `evt-${String(sequence).padStart(6, "0")}`,
60
60
  eventType,
61
61
  timestamp: new Date().toISOString(),
62
- threadId,
63
- runId,
62
+ sessionId: threadId,
63
+ requestId: runId,
64
64
  sequence,
65
65
  source,
66
66
  payload,
@@ -73,8 +73,8 @@ export function createPendingApproval(threadId, runId, checkpointRef, input, int
73
73
  return {
74
74
  approvalId,
75
75
  pendingActionId: approvalId,
76
- threadId,
77
- runId,
76
+ sessionId: threadId,
77
+ requestId: runId,
78
78
  toolCallId: interrupt.toolId ?? `tool-${runId}`,
79
79
  toolName: interrupt.toolName ?? "write_file",
80
80
  status: "pending",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.268",
3
+ "version": "0.0.270",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "license": "MIT",
6
6
  "type": "module",