@botbotgo/agent-harness 0.0.309 → 0.0.311

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 (195) hide show
  1. package/README.md +14 -0
  2. package/README.zh.md +14 -0
  3. package/dist/acp.d.ts +1 -116
  4. package/dist/acp.js +1 -310
  5. package/dist/api.d.ts +1 -1
  6. package/dist/api.js +1 -1
  7. package/dist/cli/chat-interactive.d.ts +24 -0
  8. package/dist/cli/chat-interactive.js +244 -0
  9. package/dist/cli/chat-rendering.d.ts +9 -0
  10. package/dist/cli/chat-rendering.js +102 -0
  11. package/dist/cli/chat-stream.d.ts +23 -0
  12. package/dist/cli/chat-stream.js +330 -0
  13. package/dist/cli/chat-ui.d.ts +20 -0
  14. package/dist/cli/chat-ui.js +198 -0
  15. package/dist/cli/chat-workspace.d.ts +15 -0
  16. package/dist/cli/chat-workspace.js +205 -0
  17. package/dist/cli/main.d.ts +52 -0
  18. package/dist/cli/main.js +323 -0
  19. package/dist/cli/managed-service-commands.d.ts +23 -0
  20. package/dist/cli/managed-service-commands.js +63 -0
  21. package/dist/cli/managed-service.d.ts +27 -0
  22. package/dist/cli/managed-service.js +61 -0
  23. package/dist/cli/options-init-chat.d.ts +16 -0
  24. package/dist/cli/options-init-chat.js +108 -0
  25. package/dist/cli/options-runtime.d.ts +27 -0
  26. package/dist/cli/options-runtime.js +158 -0
  27. package/dist/cli/options-serve.d.ts +24 -0
  28. package/dist/cli/options-serve.js +166 -0
  29. package/dist/cli/options.d.ts +5 -0
  30. package/dist/cli/options.js +47 -0
  31. package/dist/cli/process-guards.d.ts +14 -0
  32. package/dist/cli/process-guards.js +139 -0
  33. package/dist/cli/request-tree.d.ts +12 -0
  34. package/dist/cli/request-tree.js +296 -0
  35. package/dist/cli/runtime-commands.d.ts +15 -0
  36. package/dist/cli/runtime-commands.js +247 -0
  37. package/dist/cli/runtime-output.d.ts +5 -0
  38. package/dist/cli/runtime-output.js +124 -0
  39. package/dist/cli/server-commands.d.ts +36 -0
  40. package/dist/cli/server-commands.js +250 -0
  41. package/dist/cli/workspace.d.ts +6 -0
  42. package/dist/cli/workspace.js +71 -0
  43. package/dist/cli.d.ts +1 -77
  44. package/dist/cli.js +2 -3023
  45. package/dist/client/acp.d.ts +1 -50
  46. package/dist/client/acp.js +1 -219
  47. package/dist/client/in-process.d.ts +5 -5
  48. package/dist/client/index.d.ts +2 -2
  49. package/dist/client/index.js +1 -1
  50. package/dist/contracts/runtime-evaluation.d.ts +103 -0
  51. package/dist/contracts/runtime-evaluation.js +1 -0
  52. package/dist/contracts/runtime-memory.d.ts +162 -0
  53. package/dist/contracts/runtime-memory.js +1 -0
  54. package/dist/contracts/runtime-observability.d.ts +248 -0
  55. package/dist/contracts/runtime-observability.js +1 -0
  56. package/dist/contracts/runtime-requests.d.ts +342 -0
  57. package/dist/contracts/runtime-requests.js +1 -0
  58. package/dist/contracts/runtime-scheduling.d.ts +146 -0
  59. package/dist/contracts/runtime-scheduling.js +1 -0
  60. package/dist/contracts/runtime.d.ts +5 -1042
  61. package/dist/contracts/runtime.js +27 -1
  62. package/dist/flow/build-flow-graph.js +4 -875
  63. package/dist/flow/flow-graph-normalization.d.ts +56 -0
  64. package/dist/flow/flow-graph-normalization.js +214 -0
  65. package/dist/flow/flow-graph-runtime.d.ts +8 -0
  66. package/dist/flow/flow-graph-runtime.js +107 -0
  67. package/dist/flow/flow-graph-upstream.d.ts +18 -0
  68. package/dist/flow/flow-graph-upstream.js +498 -0
  69. package/dist/flow/types.d.ts +1 -1
  70. package/dist/index.d.ts +3 -3
  71. package/dist/index.js +1 -1
  72. package/dist/init-project.d.ts +1 -12
  73. package/dist/init-project.js +1 -651
  74. package/dist/{procedural → knowledge/procedural}/manager.d.ts +3 -3
  75. package/dist/{procedural → knowledge/procedural}/manager.js +6 -6
  76. package/dist/mcp.d.ts +2 -76
  77. package/dist/mcp.js +2 -428
  78. package/dist/package-version.d.ts +1 -1
  79. package/dist/package-version.js +1 -1
  80. package/dist/persistence/file-store.js +1 -1
  81. package/dist/persistence/sqlite-runtime.d.ts +19 -0
  82. package/dist/persistence/sqlite-runtime.js +86 -0
  83. package/dist/persistence/sqlite-store.js +11 -99
  84. package/dist/{request-events.d.ts → projections/request-events.d.ts} +1 -1
  85. package/dist/{upstream-events.js → projections/upstream-events.js} +1 -1
  86. package/dist/protocol/a2a/http-discovery.d.ts +39 -0
  87. package/dist/protocol/a2a/http-discovery.js +178 -0
  88. package/dist/protocol/a2a/http-rpc.d.ts +28 -0
  89. package/dist/protocol/a2a/http-rpc.js +623 -0
  90. package/dist/protocol/a2a/http.d.ts +72 -1
  91. package/dist/protocol/a2a/http.js +14 -1124
  92. package/dist/protocol/a2a/task-state.d.ts +29 -0
  93. package/dist/protocol/a2a/task-state.js +317 -0
  94. package/dist/protocol/acp/client.js +1 -1
  95. package/dist/protocol/acp/harness-client.d.ts +50 -0
  96. package/dist/protocol/acp/harness-client.js +219 -0
  97. package/dist/protocol/acp/server.d.ts +116 -0
  98. package/dist/protocol/acp/server.js +310 -0
  99. package/dist/protocol/ag-ui/http.js +1 -1
  100. package/dist/protocol/mcp/server.d.ts +76 -0
  101. package/dist/protocol/mcp/server.js +428 -0
  102. package/dist/resource/backend/workspace-scoped-backend.d.ts +40 -0
  103. package/dist/resource/backend/workspace-scoped-backend.js +296 -0
  104. package/dist/resource/mcp/tool-support.d.ts +35 -0
  105. package/dist/resource/mcp/tool-support.js +296 -0
  106. package/dist/resource/mcp-tool-support.d.ts +2 -35
  107. package/dist/resource/mcp-tool-support.js +2 -296
  108. package/dist/resource/providers/resource-provider.d.ts +22 -0
  109. package/dist/resource/providers/resource-provider.js +215 -0
  110. package/dist/resource/resource-impl.d.ts +3 -33
  111. package/dist/resource/resource-impl.js +2 -808
  112. package/dist/resource/resource-types.d.ts +33 -0
  113. package/dist/resource/resource-types.js +1 -0
  114. package/dist/resource/tools/function-tool-resolver.d.ts +2 -0
  115. package/dist/resource/tools/function-tool-resolver.js +306 -0
  116. package/dist/runtime/adapter/middleware-assembly.js +1 -1
  117. package/dist/runtime/adapter/model/invocation-request.js +2 -2
  118. package/dist/runtime/adapter/model/message-assembly.js +1 -1
  119. package/dist/runtime/agent-runtime-adapter.d.ts +3 -63
  120. package/dist/runtime/agent-runtime-adapter.js +7 -235
  121. package/dist/runtime/agent-runtime-assembly.d.ts +67 -0
  122. package/dist/runtime/agent-runtime-assembly.js +211 -0
  123. package/dist/runtime/harness/background-runtime.d.ts +1 -1
  124. package/dist/runtime/harness/events/event-sink.js +1 -1
  125. package/dist/runtime/harness/events/runtime-event-operations.d.ts +1 -1
  126. package/dist/runtime/harness/events/streaming.js +1 -1
  127. package/dist/runtime/harness/public-shapes.d.ts +43 -0
  128. package/dist/runtime/harness/public-shapes.js +186 -0
  129. package/dist/runtime/harness/run/inspection.js +2 -2
  130. package/dist/runtime/harness/run/resources.js +1 -1
  131. package/dist/runtime/harness/run/surface-semantics.js +1 -1
  132. package/dist/runtime/harness/system/inventory.d.ts +1 -1
  133. package/dist/runtime/harness/system/inventory.js +2 -2
  134. package/dist/runtime/harness/system/policy-engine.js +1 -1
  135. package/dist/runtime/harness/system/runtime-memory-manager.js +1 -1
  136. package/dist/runtime/harness/system/skill-requirements.d.ts +1 -1
  137. package/dist/runtime/harness/system/skill-requirements.js +1 -1
  138. package/dist/runtime/harness.d.ts +2 -2
  139. package/dist/runtime/harness.js +7 -191
  140. package/dist/runtime/maintenance/checkpoint-maintenance.js +1 -1
  141. package/dist/runtime/maintenance/runtime-record-maintenance.js +1 -1
  142. package/dist/runtime/parsing/output-content.d.ts +11 -0
  143. package/dist/runtime/parsing/output-content.js +442 -0
  144. package/dist/runtime/parsing/output-parsing.d.ts +3 -29
  145. package/dist/runtime/parsing/output-parsing.js +3 -806
  146. package/dist/runtime/parsing/output-recovery.d.ts +14 -0
  147. package/dist/runtime/parsing/output-recovery.js +288 -0
  148. package/dist/runtime/parsing/output-tool-args.d.ts +4 -0
  149. package/dist/runtime/parsing/output-tool-args.js +120 -0
  150. package/dist/runtime/support/runtime-factories.js +1 -1
  151. package/dist/scaffold/init-project.d.ts +12 -0
  152. package/dist/scaffold/init-project.js +651 -0
  153. package/dist/{extensions.d.ts → tooling/extensions.d.ts} +1 -1
  154. package/dist/{extensions.js → tooling/extensions.js} +3 -3
  155. package/dist/{tool-modules.d.ts → tooling/module-loader.d.ts} +1 -1
  156. package/dist/{tool-modules.js → tooling/module-loader.js} +2 -2
  157. package/dist/workspace/agent-binding-compiler.js +2 -2
  158. package/dist/workspace/compile.js +2 -2
  159. package/dist/workspace/object-loader-paths.d.ts +11 -0
  160. package/dist/workspace/object-loader-paths.js +75 -0
  161. package/dist/workspace/object-loader-readers.d.ts +21 -0
  162. package/dist/workspace/object-loader-readers.js +187 -0
  163. package/dist/workspace/object-loader.d.ts +0 -1
  164. package/dist/workspace/object-loader.js +6 -260
  165. package/dist/workspace/resource-compilers.js +1 -1
  166. package/dist/workspace/support/discovery.js +1 -1
  167. package/package.json +1 -1
  168. package/dist/runtime/adapter/index.d.ts +0 -13
  169. package/dist/runtime/adapter/index.js +0 -13
  170. package/dist/runtime/harness/index.d.ts +0 -19
  171. package/dist/runtime/harness/index.js +0 -19
  172. package/dist/runtime/maintenance/index.d.ts +0 -4
  173. package/dist/runtime/maintenance/index.js +0 -4
  174. package/dist/runtime/parsing/index.d.ts +0 -2
  175. package/dist/runtime/parsing/index.js +0 -2
  176. package/dist/runtime/support/index.d.ts +0 -4
  177. package/dist/runtime/support/index.js +0 -4
  178. package/dist/workspace/support/index.d.ts +0 -2
  179. package/dist/workspace/support/index.js +0 -2
  180. /package/dist/{procedural → knowledge/procedural}/config.d.ts +0 -0
  181. /package/dist/{procedural → knowledge/procedural}/config.js +0 -0
  182. /package/dist/{procedural → knowledge/procedural}/index.d.ts +0 -0
  183. /package/dist/{procedural → knowledge/procedural}/index.js +0 -0
  184. /package/dist/{presentation.d.ts → projections/presentation.d.ts} +0 -0
  185. /package/dist/{presentation.js → projections/presentation.js} +0 -0
  186. /package/dist/{request-events.js → projections/request-events.js} +0 -0
  187. /package/dist/{upstream-events.d.ts → projections/upstream-events.d.ts} +0 -0
  188. /package/dist/runtime/{support → env}/runtime-env.d.ts +0 -0
  189. /package/dist/runtime/{support → env}/runtime-env.js +0 -0
  190. /package/dist/runtime/{support → layout}/runtime-layout.d.ts +0 -0
  191. /package/dist/runtime/{support → layout}/runtime-layout.js +0 -0
  192. /package/dist/runtime/{support → prompts}/runtime-prompts.d.ts +0 -0
  193. /package/dist/runtime/{support → prompts}/runtime-prompts.js +0 -0
  194. /package/dist/runtime/{support → skills}/skill-metadata.d.ts +0 -0
  195. /package/dist/runtime/{support → skills}/skill-metadata.js +0 -0
@@ -1,853 +1,7 @@
1
1
  import { projectRuntimeTimeline } from "../runtime/harness/events/timeline.js";
2
- import { createUpstreamTimelineReducer } from "../upstream-events.js";
3
- import { formatAgentName } from "../utils/agent-display.js";
4
- import { buildSurfaceId, resolveSurfaceAction, stripStepPrefix, } from "../runtime/harness/run/surface-semantics.js";
5
- function asObject(value) {
6
- return typeof value === "object" && value !== null ? value : null;
7
- }
8
- function readString(value) {
9
- return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
10
- }
11
- function extractUpstreamEventEnvelope(value) {
12
- const typed = asObject(value);
13
- const nestedEvent = typed && Object.prototype.hasOwnProperty.call(typed, "event") ? typed.event : undefined;
14
- const surfaceItem = asObject(typed?.surfaceItem);
15
- const event = typed
16
- && nestedEvent
17
- && typeof nestedEvent === "object"
18
- && !Array.isArray(nestedEvent)
19
- ? nestedEvent
20
- : value;
21
- const agentId = readString(typed?.agentId) ?? readString(surfaceItem?.agentId);
22
- const agentName = readString(typed?.agentName) ?? readString(surfaceItem?.agentName);
23
- return {
24
- event,
25
- agentId: agentId ?? undefined,
26
- agentName: agentName ?? undefined,
27
- ...(surfaceItem ? { surfaceItem } : {}),
28
- };
29
- }
30
- function normalizeRuntimeEventType(eventType) {
31
- return eventType;
32
- }
33
- function normalizeRuntimeEvents(events) {
34
- return events.map((event) => {
35
- const typed = event;
36
- const sessionId = readString(typed.sessionId) ?? "";
37
- const requestId = readString(typed.requestId) ?? "";
38
- return {
39
- eventId: String(event.eventId),
40
- eventType: normalizeRuntimeEventType(String(event.eventType)),
41
- timestamp: String(event.timestamp),
42
- sessionId,
43
- requestId,
44
- sequence: Number(event.sequence),
45
- source: event.source,
46
- payload: event.payload ?? {},
47
- };
48
- });
49
- }
50
- function collectNestedAgentNames(value, names = new Set()) {
51
- if (Array.isArray(value)) {
52
- for (const item of value) {
53
- collectNestedAgentNames(item, names);
54
- }
55
- return names;
56
- }
57
- const typed = asObject(value);
58
- if (!typed) {
59
- return names;
60
- }
61
- const idParts = Array.isArray(typed.id) ? typed.id.filter((item) => typeof item === "string") : [];
62
- const kwargs = asObject(typed.kwargs);
63
- const kwargsName = idParts.includes("AIMessage") ? readString(kwargs?.name) : null;
64
- if (kwargsName && kwargsName !== "assistant") {
65
- names.add(kwargsName);
66
- }
67
- for (const nested of Object.values(typed)) {
68
- collectNestedAgentNames(nested, names);
69
- }
70
- return names;
71
- }
72
- function slugify(value) {
73
- return value
74
- .toLowerCase()
75
- .replace(/[^a-z0-9]+/g, "-")
76
- .replace(/^-+|-+$/g, "")
77
- .slice(0, 80) || "node";
78
- }
79
- function titleCase(value) {
80
- return value
81
- .replace(/[_-]+/g, " ")
82
- .replace(/\s+/g, " ")
83
- .trim()
84
- .split(" ")
85
- .filter(Boolean)
86
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
87
- .join(" ");
88
- }
89
- function normalizeLabel(value) {
90
- return value.replace(/\s+/g, " ").trim();
91
- }
92
- function readSessionId(input) {
93
- return input.sessionId;
94
- }
95
- function readRequestId(input) {
96
- return input.requestId;
97
- }
98
- function readProjectionLabel(projection) {
99
- if (projection.type === "step") {
100
- return projection.step;
101
- }
102
- if (projection.type === "tool-result") {
103
- return `Tool result ${titleCase(projection.toolName)}`;
104
- }
105
- return projection.text;
106
- }
107
- function deriveNodeKindFromProjection(projection) {
108
- if (projection.type === "tool-result") {
109
- return "result";
110
- }
111
- if (projection.type === "thinking") {
112
- return "thinking";
113
- }
114
- return projection.category;
115
- }
116
- function deriveStatusFromProjection(projection) {
117
- if (projection.type === "thinking" || projection.type === "tool-result") {
118
- return "completed";
119
- }
120
- return projection.category === "approval" && projection.status === "started" ? "waiting" : projection.status;
121
- }
122
- function deriveRuntimeNode(input) {
123
- if (input.eventType === "request.created") {
124
- return {
125
- kind: "request",
126
- status: "started",
127
- label: "Request created",
128
- detail: input.payload,
129
- };
130
- }
131
- if (input.eventType === "request.queued") {
132
- return {
133
- kind: "queue",
134
- status: "waiting",
135
- label: "Queued",
136
- detail: input.payload,
137
- };
138
- }
139
- if (input.eventType === "request.dequeued") {
140
- return {
141
- kind: "queue",
142
- status: "completed",
143
- label: "Dequeued",
144
- detail: input.payload,
145
- };
146
- }
147
- if (input.eventType === "approval.requested") {
148
- return {
149
- kind: "approval",
150
- status: "waiting",
151
- label: "Approval requested",
152
- detail: input.payload,
153
- };
154
- }
155
- if (input.eventType === "approval.resolved") {
156
- return {
157
- kind: "approval",
158
- status: "resolved",
159
- label: "Approval resolved",
160
- detail: input.payload,
161
- };
162
- }
163
- if (input.eventType === "request.resumed") {
164
- return {
165
- kind: "recovery",
166
- status: "completed",
167
- label: "Request resumed",
168
- detail: input.payload,
169
- };
170
- }
171
- if (input.eventType === "artifact.created") {
172
- return {
173
- kind: "artifact",
174
- status: "completed",
175
- label: "Artifact created",
176
- detail: input.payload,
177
- };
178
- }
179
- if (input.eventType === "request.state.changed") {
180
- const state = typeof input.payload.state === "string" ? input.payload.state : "";
181
- if (state === "waiting_for_approval") {
182
- return {
183
- kind: "approval",
184
- status: "waiting",
185
- label: "Waiting for approval",
186
- detail: input.payload,
187
- };
188
- }
189
- if (state === "failed") {
190
- return {
191
- kind: "request",
192
- status: "failed",
193
- label: "Request failed",
194
- detail: input.payload,
195
- };
196
- }
197
- if (state === "completed") {
198
- return {
199
- kind: "request",
200
- status: "completed",
201
- label: "Request completed",
202
- detail: input.payload,
203
- };
204
- }
205
- return {
206
- kind: "request",
207
- status: "started",
208
- label: state ? `Request ${state}` : "Request state changed",
209
- detail: input.payload,
210
- };
211
- }
212
- return {
213
- kind: input.kind,
214
- status: "completed",
215
- label: input.eventType,
216
- detail: input.payload,
217
- };
218
- }
219
- function buildRuntimeNodes(timeline) {
220
- const nodes = [];
221
- const edges = [];
222
- const groups = [];
223
- let previousNode = null;
224
- let segmentOrdinal = 0;
225
- let approvalOrdinal = 0;
226
- let activeExecutionGroup = null;
227
- let activeApprovalGroup = null;
228
- for (const item of timeline) {
229
- const mapped = deriveRuntimeNode(item);
230
- const node = {
231
- id: `rt:${item.requestId}:${item.sequence}:${slugify(item.eventType)}`,
232
- layer: "runtime",
233
- kind: mapped.kind,
234
- label: mapped.label,
235
- status: mapped.status,
236
- sessionId: item.sessionId,
237
- requestId: item.requestId,
238
- startedAt: item.timestamp,
239
- endedAt: item.timestamp,
240
- sequenceStart: item.sequence,
241
- sequenceEnd: item.sequence,
242
- sourceEventIds: [item.eventId],
243
- detail: { ...mapped.detail, eventType: item.eventType, source: item.source },
244
- };
245
- nodes.push(node);
246
- if (previousNode) {
247
- const kind = item.eventType === "approval.resolved"
248
- ? "approval"
249
- : item.eventType === "request.resumed"
250
- ? "resume"
251
- : "sequence";
252
- edges.push({
253
- id: `edge:${previousNode.id}->${node.id}`,
254
- from: previousNode.id,
255
- to: node.id,
256
- kind,
257
- ...(kind === "approval" ? { label: typeof item.payload.decision === "string" ? item.payload.decision : "resolved" } : {}),
258
- sourceEventIds: [previousNode.sourceEventIds[0], item.eventId],
259
- });
260
- }
261
- previousNode = node;
262
- if (item.eventType === "request.created" || item.eventType === "request.dequeued" || item.eventType === "request.resumed") {
263
- segmentOrdinal += 1;
264
- activeExecutionGroup = {
265
- id: `group:${item.requestId}:segment:${segmentOrdinal}`,
266
- kind: "segment",
267
- label: item.eventType === "request.created"
268
- ? `Execution segment ${segmentOrdinal}`
269
- : item.eventType === "request.resumed"
270
- ? `Resumed segment ${segmentOrdinal}`
271
- : `Dequeued segment ${segmentOrdinal}`,
272
- nodeIds: [node.id],
273
- startedAt: item.timestamp,
274
- anchorNodeId: node.id,
275
- };
276
- groups.push(activeExecutionGroup);
277
- activeApprovalGroup = null;
278
- node.groupId = activeExecutionGroup.id;
279
- continue;
280
- }
281
- if (item.eventType === "approval.requested") {
282
- approvalOrdinal += 1;
283
- activeApprovalGroup = {
284
- id: `group:${item.requestId}:approval:${approvalOrdinal}`,
285
- kind: "approval-window",
286
- label: `Approval window ${approvalOrdinal}`,
287
- nodeIds: [node.id],
288
- startedAt: item.timestamp,
289
- anchorNodeId: node.id,
290
- };
291
- groups.push(activeApprovalGroup);
292
- node.groupId = activeApprovalGroup.id;
293
- continue;
294
- }
295
- if (item.eventType === "approval.resolved") {
296
- if (!activeApprovalGroup) {
297
- approvalOrdinal += 1;
298
- activeApprovalGroup = {
299
- id: `group:${item.requestId}:approval:${approvalOrdinal}`,
300
- kind: "approval-window",
301
- label: `Approval window ${approvalOrdinal}`,
302
- nodeIds: [],
303
- anchorNodeId: node.id,
304
- };
305
- groups.push(activeApprovalGroup);
306
- }
307
- activeApprovalGroup.nodeIds.push(node.id);
308
- activeApprovalGroup.endedAt = item.timestamp;
309
- node.groupId = activeApprovalGroup.id;
310
- continue;
311
- }
312
- if (activeApprovalGroup && !activeApprovalGroup.endedAt) {
313
- activeApprovalGroup.nodeIds.push(node.id);
314
- node.groupId = activeApprovalGroup.id;
315
- continue;
316
- }
317
- if (activeExecutionGroup) {
318
- activeExecutionGroup.nodeIds.push(node.id);
319
- activeExecutionGroup.endedAt = item.timestamp;
320
- node.groupId = activeExecutionGroup.id;
321
- }
322
- }
323
- return { nodes, edges, groups };
324
- }
325
- function normalizeAttemptLabel(kind, projection) {
326
- if (projection.type === "step") {
327
- const label = normalizeLabel(projection.step);
328
- if (label) {
329
- return label;
330
- }
331
- }
332
- if (projection.type === "tool-result") {
333
- return `Tool ${titleCase(projection.toolName)}`;
334
- }
335
- if (projection.type === "thinking") {
336
- return "Model reasoning";
337
- }
338
- return titleCase(kind);
339
- }
340
- function semanticNameFromLabel(kind, label) {
341
- const normalized = normalizeLabel(label)
342
- .replace(/^Calling LLM\s+/i, "")
343
- .replace(/^Completed LLM\s+/i, "")
344
- .replace(/^Calling tool\s+/i, "")
345
- .replace(/^Completed tool\s+/i, "")
346
- .replace(/^Tool\s+/i, "")
347
- .replace(/\s+failed$/i, "")
348
- .replace(/^Calling skill\s+/i, "")
349
- .replace(/^Completed skill\s+/i, "")
350
- .replace(/^Accessing memory\s+/i, "")
351
- .replace(/^Completed memory\s+/i, "")
352
- .replace(/^Running\s+/i, "")
353
- .replace(/^Completed\s+/i, "");
354
- return `${kind}:${normalized.toLowerCase()}`;
355
- }
356
- function normalizeToolIdentity(value) {
357
- return value
358
- .toLowerCase()
359
- .replace(/[_-]+/g, " ")
360
- .replace(/\s+/g, " ")
361
- .trim();
362
- }
363
- function buildAttemptKey(kind, label, groupId) {
364
- return `${semanticNameFromLabel(kind, label)}:${groupId ?? "ungrouped"}`;
365
- }
366
- function deriveInitialAgentId(input, runtimeTimeline) {
367
- const candidate = runtimeTimeline.find((item) => {
368
- const payload = asObject(item.payload);
369
- return typeof payload?.agentId === "string" && payload.agentId.trim().length > 0;
370
- });
371
- const payload = candidate ? asObject(candidate.payload) : null;
372
- const metadataAgentId = typeof input.metadata?.currentAgentId === "string" ? input.metadata.currentAgentId : null;
373
- if (metadataAgentId && metadataAgentId.trim().length > 0) {
374
- return metadataAgentId.trim();
375
- }
376
- if (payload?.agentId && typeof payload.agentId === "string" && payload.agentId.trim().length > 0) {
377
- return payload.agentId.trim();
378
- }
379
- return "agent";
380
- }
381
- function deriveAgentName(agentId, explicitName) {
382
- return explicitName && explicitName.trim().length > 0 ? explicitName.trim() : formatAgentName(agentId);
383
- }
384
- function buildSurfaceStepLabel(surfaceItem) {
385
- const kind = surfaceItem.kind;
386
- const name = typeof surfaceItem.name === "string" && surfaceItem.name.trim().length > 0
387
- ? surfaceItem.name.trim()
388
- : typeof surfaceItem.id === "string"
389
- ? surfaceItem.id
390
- : "";
391
- const status = surfaceItem.status;
392
- if (!kind || !name || !status || (status !== "started" && status !== "completed" && status !== "failed")) {
393
- return null;
394
- }
395
- if (kind === "llm") {
396
- return status === "started" ? `Calling LLM ${name}` : `Completed LLM ${name}`;
397
- }
398
- if (kind === "tool") {
399
- if (status === "failed") {
400
- return `Tool ${name} failed`;
401
- }
402
- return status === "started" ? `Calling tool ${name}` : `Completed tool ${name}`;
403
- }
404
- if (kind === "skill") {
405
- return status === "started" ? `Calling skill ${name}` : `Completed skill ${name}`;
406
- }
407
- if (kind === "memory") {
408
- return status === "started" ? `Accessing memory ${name}` : `Completed memory ${name}`;
409
- }
410
- return null;
411
- }
412
- function createDelegationNodeFromSurfaceItem(surfaceItem, fallbackAgentId, fallbackAgentName, sourceEventId, ordinal) {
413
- if (surfaceItem.kind !== "agent") {
414
- return null;
415
- }
416
- const toAgentId = typeof surfaceItem.agentId === "string" && surfaceItem.agentId.trim().length > 0
417
- ? surfaceItem.agentId.trim()
418
- : fallbackAgentId;
419
- const toAgentName = deriveAgentName(toAgentId, typeof surfaceItem.agentName === "string" ? surfaceItem.agentName : undefined);
420
- const fromAgentId = typeof surfaceItem.ownerAgentId === "string" && surfaceItem.ownerAgentId.trim().length > 0
421
- ? surfaceItem.ownerAgentId.trim()
422
- : fallbackAgentId;
423
- const fromAgentName = deriveAgentName(fromAgentId, typeof surfaceItem.ownerAgentName === "string" ? surfaceItem.ownerAgentName : fallbackAgentName);
424
- return {
425
- id: `delegate:${slugify(fromAgentId)}:${slugify(toAgentId)}:${ordinal}`,
426
- layer: "execution",
427
- kind: "agent",
428
- label: `Delegate to ${titleCase(typeof surfaceItem.name === "string" ? surfaceItem.name : toAgentId)}`,
429
- status: surfaceItem.status === "failed" ? "failed" : surfaceItem.status === "started" ? "started" : "completed",
430
- sessionId: "",
431
- requestId: "",
432
- agentId: toAgentId,
433
- agentName: toAgentName,
434
- sourceEventIds: [sourceEventId],
435
- detail: {
436
- fromAgentId,
437
- fromAgentName,
438
- toAgentId,
439
- toAgentName,
440
- ...(typeof surfaceItem.action === "string" ? { action: surfaceItem.action } : {}),
441
- },
442
- };
443
- }
444
- function extractDelegatedAgentId(event) {
445
- const typed = asObject(event);
446
- if (!typed) {
447
- return null;
448
- }
449
- const eventName = typeof typed.event === "string" ? typed.event : "";
450
- const toolName = typeof typed.name === "string" ? typed.name : "";
451
- if (toolName !== "task" || (eventName !== "on_tool_start" && !(eventName === "on_chain_start" && typed.run_type === "tool"))) {
452
- return null;
453
- }
454
- const data = asObject(typed.data);
455
- const input = asObject(data?.input);
456
- const nestedInput = typeof input?.input === "string"
457
- ? asObject(JSON.parse(input.input))
458
- : asObject(input?.input);
459
- const subagentType = typeof input?.subagent_type === "string"
460
- ? input.subagent_type
461
- : typeof input?.subagentType === "string"
462
- ? input.subagentType
463
- : typeof nestedInput?.subagent_type === "string"
464
- ? nestedInput.subagent_type
465
- : typeof nestedInput?.subagentType === "string"
466
- ? nestedInput.subagentType
467
- : null;
468
- return subagentType && subagentType.trim().length > 0 ? subagentType.trim() : null;
469
- }
470
- function convertUpstreamEventsWithAgents(upstreamEvents, initialAgentId) {
471
- const reducer = createUpstreamTimelineReducer();
472
- const projections = [];
473
- const delegationNodes = [];
474
- let currentAgentId = initialAgentId;
475
- let currentAgentName = deriveAgentName(initialAgentId);
476
- let ordinal = 0;
477
- upstreamEvents.forEach((event, index) => {
478
- const sourceEventId = `upstream:${index + 1}`;
479
- const envelope = extractUpstreamEventEnvelope(event);
480
- if (envelope.agentId && envelope.agentId !== currentAgentId) {
481
- currentAgentId = envelope.agentId;
482
- currentAgentName = deriveAgentName(currentAgentId, envelope.agentName);
483
- }
484
- else if (envelope.agentName) {
485
- currentAgentName = deriveAgentName(currentAgentId, envelope.agentName);
486
- }
487
- const emitted = reducer.consume(envelope.event);
488
- for (const projection of emitted) {
489
- if (envelope.surfaceItem && projection.type === "step") {
490
- continue;
491
- }
492
- projections.push({
493
- projection,
494
- agentId: currentAgentId,
495
- agentName: currentAgentName,
496
- sourceEventId,
497
- });
498
- }
499
- if (envelope.surfaceItem) {
500
- const delegationNode = createDelegationNodeFromSurfaceItem(envelope.surfaceItem, currentAgentId, currentAgentName, sourceEventId, ordinal + 1);
501
- if (delegationNode) {
502
- ordinal += 1;
503
- delegationNodes.push(delegationNode);
504
- }
505
- else {
506
- const step = buildSurfaceStepLabel(envelope.surfaceItem);
507
- if (step) {
508
- projections.push({
509
- projection: {
510
- type: "step",
511
- key: `surface:${index + 1}:${envelope.surfaceItem.id ?? step}`,
512
- category: envelope.surfaceItem.kind,
513
- status: envelope.surfaceItem.status,
514
- step,
515
- },
516
- agentId: currentAgentId,
517
- agentName: currentAgentName,
518
- sourceEventId,
519
- });
520
- }
521
- }
522
- }
523
- if (envelope.surfaceItem) {
524
- return;
525
- }
526
- const delegatedAgentId = extractDelegatedAgentId(envelope.event);
527
- if (!delegatedAgentId || delegatedAgentId === currentAgentId) {
528
- return;
529
- }
530
- const delegatedAgentName = deriveAgentName(delegatedAgentId);
531
- ordinal += 1;
532
- delegationNodes.push({
533
- id: `delegate:${slugify(initialAgentId)}:${slugify(delegatedAgentId)}:${ordinal}`,
534
- layer: "execution",
535
- kind: "agent",
536
- label: `Delegate to ${titleCase(delegatedAgentId)}`,
537
- status: "completed",
538
- sessionId: "",
539
- requestId: "",
540
- agentId: delegatedAgentId,
541
- agentName: delegatedAgentName,
542
- sourceEventIds: [sourceEventId],
543
- detail: {
544
- fromAgentId: currentAgentId,
545
- fromAgentName: currentAgentName,
546
- toAgentId: delegatedAgentId,
547
- toAgentName: delegatedAgentName,
548
- },
549
- });
550
- currentAgentId = delegatedAgentId;
551
- currentAgentName = delegatedAgentName;
552
- });
553
- return { projections, delegationNodes };
554
- }
555
- function selectInitialGroup(groups) {
556
- return groups.find((group) => group.kind === "segment") ?? groups[0] ?? null;
557
- }
558
- function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, sessionId, requestId) {
559
- const nodes = [];
560
- const edges = [];
561
- const groups = [];
562
- const attempts = [];
563
- const activeAttemptsByKey = new Map();
564
- const toolAttemptsByName = new Map();
565
- const attemptSetGroups = new Map();
566
- let currentGroup = selectInitialGroup(runtimeGroups);
567
- let awaitingResumeAfterApproval = false;
568
- let previousAttempt = null;
569
- let ordinal = 0;
570
- let pendingDelegationNode = null;
571
- let delegationIndex = 0;
572
- const segmentGroups = runtimeGroups.filter((group) => group.kind === "segment");
573
- let nextSegmentIndex = currentGroup && currentGroup.kind === "segment"
574
- ? Math.max(segmentGroups.findIndex((group) => group.id === currentGroup?.id), 0)
575
- : 0;
576
- function promoteToNextSegment() {
577
- if (nextSegmentIndex + 1 < segmentGroups.length) {
578
- nextSegmentIndex += 1;
579
- currentGroup = segmentGroups[nextSegmentIndex] ?? currentGroup;
580
- }
581
- }
582
- function createAttempt(kind, label, projection, agentId, agentName) {
583
- ordinal += 1;
584
- const attempt = {
585
- id: `attempt:${requestId}:${slugify(kind)}:${slugify(label)}:${ordinal}`,
586
- kind,
587
- label,
588
- status: deriveStatusFromProjection(projection),
589
- agentId,
590
- agentName,
591
- groupId: currentGroup?.id,
592
- sourceEventIds: [],
593
- attemptKey: buildAttemptKey(kind, label, currentGroup?.id),
594
- detail: {},
595
- projectionKeys: [],
596
- ...(projection.type === "tool-result" ? { toolName: projection.toolName } : {}),
597
- };
598
- attempts.push(attempt);
599
- if (kind === "tool" || (projection.type === "tool-result" && projection.toolName)) {
600
- const toolName = projection.type === "tool-result"
601
- ? normalizeToolIdentity(projection.toolName)
602
- : normalizeToolIdentity(semanticNameFromLabel("tool", label).replace(/^tool:/, ""));
603
- const existing = toolAttemptsByName.get(toolName) ?? [];
604
- if (existing.length > 0) {
605
- const prior = existing[existing.length - 1];
606
- const edgeKind = prior.status === "failed" ? "retry" : "fallback";
607
- edges.push({
608
- id: `edge:${prior.id}->${attempt.id}`,
609
- from: prior.id,
610
- to: attempt.id,
611
- kind: edgeKind,
612
- sourceEventIds: [],
613
- confidence: 0.55,
614
- });
615
- }
616
- existing.push(attempt);
617
- toolAttemptsByName.set(toolName, existing);
618
- }
619
- return attempt;
620
- }
621
- for (const record of projectionRecords) {
622
- const projection = record.projection;
623
- if (!pendingDelegationNode
624
- && delegationIndex < delegationNodes.length
625
- && delegationNodes[delegationIndex]?.agentId === record.agentId
626
- && (!previousAttempt || previousAttempt.agentId !== record.agentId)) {
627
- const sourceNode = delegationNodes[delegationIndex];
628
- delegationIndex += 1;
629
- pendingDelegationNode = {
630
- ...sourceNode,
631
- sessionId,
632
- requestId,
633
- groupId: currentGroup?.id,
634
- };
635
- nodes.push(pendingDelegationNode);
636
- if (previousAttempt) {
637
- edges.push({
638
- id: `edge:${previousAttempt.id}->${pendingDelegationNode.id}`,
639
- from: previousAttempt.id,
640
- to: pendingDelegationNode.id,
641
- kind: "spawn",
642
- label: "delegate",
643
- sourceEventIds: [...pendingDelegationNode.sourceEventIds],
644
- confidence: 0.9,
645
- });
646
- }
647
- else if (currentGroup?.anchorNodeId) {
648
- edges.push({
649
- id: `edge:${currentGroup.anchorNodeId}->${pendingDelegationNode.id}`,
650
- from: currentGroup.anchorNodeId,
651
- to: pendingDelegationNode.id,
652
- kind: "spawn",
653
- label: "delegate",
654
- sourceEventIds: [...pendingDelegationNode.sourceEventIds],
655
- confidence: 0.9,
656
- });
657
- }
658
- }
659
- if (previousAttempt
660
- && previousAttempt.agentId
661
- && record.agentId !== previousAttempt.agentId
662
- && delegationIndex < delegationNodes.length) {
663
- const sourceNode = delegationNodes[delegationIndex];
664
- delegationIndex += 1;
665
- pendingDelegationNode = {
666
- ...sourceNode,
667
- sessionId,
668
- requestId,
669
- groupId: currentGroup?.id,
670
- };
671
- nodes.push(pendingDelegationNode);
672
- edges.push({
673
- id: `edge:${previousAttempt.id}->${pendingDelegationNode.id}`,
674
- from: previousAttempt.id,
675
- to: pendingDelegationNode.id,
676
- kind: "spawn",
677
- label: "delegate",
678
- sourceEventIds: [...pendingDelegationNode.sourceEventIds],
679
- confidence: 0.9,
680
- });
681
- }
682
- if (projection.type === "thinking") {
683
- ordinal += 1;
684
- const detailNode = {
685
- id: `detail:${requestId}:thinking:${ordinal}`,
686
- layer: "detail",
687
- kind: "thinking",
688
- label: "Model reasoning",
689
- status: "completed",
690
- sessionId,
691
- requestId,
692
- groupId: currentGroup?.id,
693
- sourceEventIds: [],
694
- detail: { text: projection.text },
695
- };
696
- nodes.push(detailNode);
697
- if (previousAttempt) {
698
- edges.push({
699
- id: `edge:${previousAttempt.id}->${detailNode.id}`,
700
- from: previousAttempt.id,
701
- to: detailNode.id,
702
- kind: "result",
703
- sourceEventIds: [],
704
- confidence: 0.6,
705
- });
706
- }
707
- continue;
708
- }
709
- const kind = deriveNodeKindFromProjection(projection);
710
- const label = normalizeAttemptLabel(kind, projection);
711
- if (kind === "approval") {
712
- const activeApproval = runtimeGroups.find((group) => group.kind === "approval-window");
713
- if (activeApproval) {
714
- currentGroup = activeApproval;
715
- }
716
- awaitingResumeAfterApproval = true;
717
- }
718
- else if (awaitingResumeAfterApproval && currentGroup?.kind === "approval-window") {
719
- promoteToNextSegment();
720
- awaitingResumeAfterApproval = false;
721
- }
722
- const attemptKey = buildAttemptKey(kind, label, currentGroup?.id);
723
- let attempt;
724
- if (projection.type === "step" && projection.status === "started") {
725
- attempt = createAttempt(kind, label, projection, record.agentId, record.agentName);
726
- activeAttemptsByKey.set(attemptKey, attempt);
727
- }
728
- else if (projection.type === "tool-result") {
729
- const toolName = normalizeToolIdentity(projection.toolName);
730
- const existing = toolAttemptsByName.get(toolName) ?? [];
731
- attempt = [...existing].reverse().find((candidate) => candidate.groupId === currentGroup?.id) ?? existing[existing.length - 1];
732
- if (!attempt) {
733
- attempt = createAttempt("tool", `Calling tool ${titleCase(toolName)}`, projection, record.agentId, record.agentName);
734
- }
735
- }
736
- else {
737
- attempt = activeAttemptsByKey.get(attemptKey);
738
- if (!attempt) {
739
- attempt = createAttempt(kind, label, projection, record.agentId, record.agentName);
740
- }
741
- }
742
- attempt.agentId = attempt.agentId ?? record.agentId;
743
- attempt.agentName = attempt.agentName ?? record.agentName;
744
- attempt.projectionKeys.push(projection.key);
745
- attempt.sourceEventIds.push(record.sourceEventId);
746
- if (projection.type === "step") {
747
- attempt.status = deriveStatusFromProjection(projection);
748
- attempt.detail.category = projection.category;
749
- attempt.detail.step = projection.step;
750
- }
751
- else if (projection.type === "tool-result") {
752
- attempt.status = projection.isError ? "failed" : "completed";
753
- attempt.toolName = projection.toolName;
754
- attempt.detail.toolName = projection.toolName;
755
- attempt.detail.result = projection.output;
756
- attempt.detail.resultIsError = projection.isError === true;
757
- if (projection.isError) {
758
- activeAttemptsByKey.delete(buildAttemptKey("tool", attempt.label, attempt.groupId));
759
- }
760
- }
761
- if (!attemptSetGroups.has(`${kind}:${currentGroup?.id ?? "ungrouped"}`)) {
762
- attemptSetGroups.set(`${kind}:${currentGroup?.id ?? "ungrouped"}`, {
763
- id: `group:${requestId}:attempt-set:${slugify(kind)}:${attemptSetGroups.size + 1}`,
764
- kind: "attempt-set",
765
- label: `${titleCase(kind)} attempts`,
766
- nodeIds: [],
767
- });
768
- }
769
- const attemptGroup = attemptSetGroups.get(`${kind}:${currentGroup?.id ?? "ungrouped"}`);
770
- if (!attemptGroup.nodeIds.includes(attempt.id)) {
771
- attemptGroup.nodeIds.push(attempt.id);
772
- }
773
- if (pendingDelegationNode && pendingDelegationNode.id !== attempt.id) {
774
- edges.push({
775
- id: `edge:${pendingDelegationNode.id}->${attempt.id}`,
776
- from: pendingDelegationNode.id,
777
- to: attempt.id,
778
- kind: "spawn",
779
- sourceEventIds: [...pendingDelegationNode.sourceEventIds, ...attempt.sourceEventIds],
780
- confidence: 0.9,
781
- });
782
- pendingDelegationNode = null;
783
- }
784
- else if (previousAttempt && previousAttempt.id !== attempt.id) {
785
- edges.push({
786
- id: `edge:${previousAttempt.id}->${attempt.id}`,
787
- from: previousAttempt.id,
788
- to: attempt.id,
789
- kind: kind === "approval" ? "approval" : "sequence",
790
- sourceEventIds: [],
791
- confidence: 0.7,
792
- });
793
- }
794
- else if (!previousAttempt && currentGroup?.anchorNodeId) {
795
- edges.push({
796
- id: `edge:${currentGroup.anchorNodeId}->${attempt.id}`,
797
- from: currentGroup.anchorNodeId,
798
- to: attempt.id,
799
- kind: "contains",
800
- sourceEventIds: [],
801
- confidence: 0.8,
802
- });
803
- }
804
- previousAttempt = attempt;
805
- if (projection.type === "step" && projection.status !== "started") {
806
- activeAttemptsByKey.delete(attemptKey);
807
- }
808
- }
809
- for (const attempt of attempts) {
810
- nodes.push({
811
- id: attempt.id,
812
- layer: "attempt",
813
- kind: attempt.kind,
814
- label: attempt.label,
815
- status: attempt.status,
816
- sessionId,
817
- requestId,
818
- agentId: attempt.agentId,
819
- agentName: attempt.agentName,
820
- groupId: attempt.groupId,
821
- sequenceStart: attempt.sequenceStart,
822
- sequenceEnd: attempt.sequenceEnd,
823
- startedAt: attempt.startedAt,
824
- endedAt: attempt.endedAt,
825
- sourceEventIds: [...new Set(attempt.sourceEventIds)],
826
- detail: { ...attempt.detail, projectionKeys: attempt.projectionKeys },
827
- });
828
- }
829
- groups.push(...attemptSetGroups.values());
830
- return { nodes, edges, groups };
831
- }
832
- function resolveContext(input, runtimeTimeline, projections) {
833
- const timelineHead = runtimeTimeline[0];
834
- const inputSessionId = readSessionId(input);
835
- const inputRequestId = readRequestId(input);
836
- if (inputSessionId && inputRequestId) {
837
- return { sessionId: inputSessionId, requestId: inputRequestId };
838
- }
839
- if (timelineHead) {
840
- return {
841
- sessionId: inputSessionId ?? timelineHead.sessionId,
842
- requestId: inputRequestId ?? timelineHead.requestId,
843
- };
844
- }
845
- const firstProjection = projections[0];
846
- if (!inputSessionId || !inputRequestId) {
847
- throw new Error(`buildFlowGraph requires sessionId and requestId when runtime timeline data is absent${firstProjection ? "" : " or empty"}.`);
848
- }
849
- return { sessionId: inputSessionId, requestId: inputRequestId };
850
- }
2
+ import { buildRuntimeSurface, buildAttempts, convertUpstreamEventsWithAgents, resolveContext, } from "./flow-graph-upstream.js";
3
+ import { deriveAgentName, deriveInitialAgentId, normalizeRuntimeEvents, readRequestId, readSessionId, } from "./flow-graph-normalization.js";
4
+ import { buildRuntimeNodes } from "./flow-graph-runtime.js";
851
5
  export function buildFlowGraph(input) {
852
6
  const runtimeData = input.runtimeTimeline
853
7
  ?? (input.runtimeEvents ? projectRuntimeTimeline(normalizeRuntimeEvents(input.runtimeEvents), {
@@ -874,32 +28,7 @@ export function buildFlowGraph(input) {
874
28
  }))
875
29
  : upstreamContext.projections;
876
30
  const { nodes: attemptNodes, edges: attemptEdges, groups: attemptGroups } = buildAttempts(projectionRecords, upstreamContext.delegationNodes, runtimeGroups, sessionId, requestId);
877
- const runtimeSurface = [...upstreamContext.delegationNodes, ...attemptNodes]
878
- .filter((node) => node.layer !== "detail"
879
- && (node.kind === "agent" || node.kind === "llm" || node.kind === "memory" || node.kind === "skill" || node.kind === "tool"))
880
- .map((node) => ({
881
- kind: node.kind,
882
- id: buildSurfaceId(node.kind, node.kind === "agent" ? (node.agentId ?? node.agentName ?? "agent") : node.label),
883
- name: node.kind === "agent"
884
- ? (node.agentName ?? node.agentId ?? "Agent")
885
- : stripStepPrefix(node.label),
886
- action: resolveSurfaceAction({
887
- kind: node.kind,
888
- step: node.label,
889
- event: node.detail,
890
- }),
891
- status: node.status === "resolved" ? "completed" : node.status,
892
- agentId: node.agentId,
893
- agentName: node.agentName,
894
- ownerAgentId: node.kind === "agent"
895
- ? (typeof node.detail.fromAgentId === "string" ? node.detail.fromAgentId : node.agentId)
896
- : node.agentId,
897
- ownerAgentName: node.kind === "agent"
898
- ? (typeof node.detail.fromAgentName === "string" ? node.detail.fromAgentName : node.agentName)
899
- : node.agentName,
900
- sourceEventId: node.sourceEventIds[0],
901
- detail: { ...node.detail },
902
- }));
31
+ const runtimeSurface = buildRuntimeSurface([...upstreamContext.delegationNodes, ...attemptNodes]);
903
32
  return {
904
33
  graphId: `${sessionId}/${requestId}`,
905
34
  scope: input.scope === "session" || input.scope === "request" ? input.scope : "request",