@botbotgo/agent-harness 0.0.250 → 0.0.252
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 +13 -14
- package/README.zh.md +11 -12
- package/dist/api.d.ts +13 -6
- package/dist/api.js +70 -6
- package/dist/config/agents/direct.yaml +3 -3
- package/dist/config/agents/orchestra.yaml +3 -3
- package/dist/config/catalogs/stores.yaml +3 -9
- package/dist/config/runtime/workspace.yaml +1 -2
- package/dist/contracts/runtime.d.ts +9 -14
- package/dist/flow/build-flow-graph.js +198 -67
- package/dist/flow/export-mermaid.js +314 -4
- package/dist/flow/export-sequence-mermaid.js +149 -2
- package/dist/flow/types.d.ts +11 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -1
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/persistence/file-store.d.ts +3 -2
- package/dist/persistence/file-store.js +34 -8
- package/dist/persistence/sqlite-store.d.ts +2 -2
- package/dist/persistence/sqlite-store.js +64 -11
- package/dist/persistence/types.d.ts +3 -3
- package/dist/protocol/a2a/http.js +2 -4
- package/dist/resource/isolation.js +30 -2
- package/dist/resource/resource-impl.js +1 -4
- package/dist/runtime/harness/events/streaming.js +8 -8
- package/dist/runtime/harness/run/inspection.d.ts +2 -0
- package/dist/runtime/harness/run/inspection.js +91 -46
- package/dist/runtime/harness/run/stream-run.d.ts +2 -2
- package/dist/runtime/harness/run/stream-run.js +34 -23
- package/dist/runtime/harness/run/surface-semantics.d.ts +14 -0
- package/dist/runtime/harness/run/surface-semantics.js +106 -0
- package/dist/runtime/harness/run/thread-records.js +2 -34
- package/dist/runtime/harness/system/store.d.ts +6 -4
- package/dist/runtime/harness/system/store.js +76 -42
- package/dist/runtime/harness.js +7 -7
- package/dist/runtime/maintenance/checkpoint-maintenance.js +4 -119
- package/dist/runtime/maintenance/index.d.ts +0 -1
- package/dist/runtime/maintenance/index.js +0 -1
- package/dist/runtime/support/runtime-env.d.ts +1 -0
- package/dist/runtime/support/runtime-env.js +5 -0
- package/dist/runtime/support/runtime-factories.js +2 -42
- package/dist/upstream-events.js +14 -0
- package/package.json +1 -3
- package/dist/runtime/maintenance/sqlite-maintained-checkpoint-saver.d.ts +0 -9
- package/dist/runtime/maintenance/sqlite-maintained-checkpoint-saver.js +0 -39
- package/dist/runtime/support/sqlite-drivers.d.ts +0 -12
- package/dist/runtime/support/sqlite-drivers.js +0 -24
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { projectRuntimeTimeline } from "../runtime/harness/events/timeline.js";
|
|
2
2
|
import { createUpstreamTimelineReducer } from "../upstream-events.js";
|
|
3
3
|
import { formatAgentName } from "../utils/agent-display.js";
|
|
4
|
+
import { buildSurfaceId, resolveSurfaceAction, stripStepPrefix, } from "../runtime/harness/run/surface-semantics.js";
|
|
4
5
|
function asObject(value) {
|
|
5
6
|
return typeof value === "object" && value !== null ? value : null;
|
|
6
7
|
}
|
|
@@ -10,16 +11,54 @@ function readString(value) {
|
|
|
10
11
|
function extractUpstreamEventEnvelope(value) {
|
|
11
12
|
const typed = asObject(value);
|
|
12
13
|
const nestedEvent = typed && Object.prototype.hasOwnProperty.call(typed, "event") ? typed.event : undefined;
|
|
14
|
+
const surfaceItem = asObject(typed?.surfaceItem);
|
|
13
15
|
const event = typed
|
|
14
16
|
&& nestedEvent
|
|
15
17
|
&& typeof nestedEvent === "object"
|
|
16
18
|
&& !Array.isArray(nestedEvent)
|
|
17
|
-
&& Object.prototype.hasOwnProperty.call(typed, "agentId")
|
|
18
19
|
? nestedEvent
|
|
19
20
|
: value;
|
|
20
|
-
const agentId = readString(typed?.agentId);
|
|
21
|
-
const agentName = readString(typed?.agentName);
|
|
22
|
-
return {
|
|
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
|
+
switch (eventType) {
|
|
32
|
+
case "request.created":
|
|
33
|
+
return "run.created";
|
|
34
|
+
case "request.queued":
|
|
35
|
+
return "run.queued";
|
|
36
|
+
case "request.dequeued":
|
|
37
|
+
return "run.dequeued";
|
|
38
|
+
case "request.state.changed":
|
|
39
|
+
return "run.state.changed";
|
|
40
|
+
case "request.resumed":
|
|
41
|
+
return "run.resumed";
|
|
42
|
+
default:
|
|
43
|
+
return eventType;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function normalizeRuntimeEvents(events) {
|
|
47
|
+
return events.map((event) => {
|
|
48
|
+
const typed = event;
|
|
49
|
+
const threadId = readString(typed.threadId) ?? readString(typed.sessionId) ?? "";
|
|
50
|
+
const runId = readString(typed.runId) ?? readString(typed.requestId) ?? "";
|
|
51
|
+
return {
|
|
52
|
+
eventId: String(event.eventId),
|
|
53
|
+
eventType: normalizeRuntimeEventType(String(event.eventType)),
|
|
54
|
+
timestamp: String(event.timestamp),
|
|
55
|
+
threadId,
|
|
56
|
+
runId,
|
|
57
|
+
sequence: Number(event.sequence),
|
|
58
|
+
source: event.source,
|
|
59
|
+
payload: event.payload ?? {},
|
|
60
|
+
};
|
|
61
|
+
});
|
|
23
62
|
}
|
|
24
63
|
function collectNestedAgentNames(value, names = new Set()) {
|
|
25
64
|
if (Array.isArray(value)) {
|
|
@@ -50,9 +89,6 @@ function slugify(value) {
|
|
|
50
89
|
.replace(/^-+|-+$/g, "")
|
|
51
90
|
.slice(0, 80) || "node";
|
|
52
91
|
}
|
|
53
|
-
function buildSurfaceId(kind, value) {
|
|
54
|
-
return `${kind}:${slugify(value)}`;
|
|
55
|
-
}
|
|
56
92
|
function titleCase(value) {
|
|
57
93
|
return value
|
|
58
94
|
.replace(/[_-]+/g, " ")
|
|
@@ -360,6 +396,68 @@ function deriveInitialAgentId(input, runtimeTimeline) {
|
|
|
360
396
|
function deriveAgentName(agentId, explicitName) {
|
|
361
397
|
return explicitName && explicitName.trim().length > 0 ? explicitName.trim() : formatAgentName(agentId);
|
|
362
398
|
}
|
|
399
|
+
function buildSurfaceStepLabel(surfaceItem) {
|
|
400
|
+
const kind = surfaceItem.kind;
|
|
401
|
+
const name = typeof surfaceItem.name === "string" && surfaceItem.name.trim().length > 0
|
|
402
|
+
? surfaceItem.name.trim()
|
|
403
|
+
: typeof surfaceItem.id === "string"
|
|
404
|
+
? surfaceItem.id
|
|
405
|
+
: "";
|
|
406
|
+
const status = surfaceItem.status;
|
|
407
|
+
if (!kind || !name || !status || (status !== "started" && status !== "completed" && status !== "failed")) {
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
if (kind === "llm") {
|
|
411
|
+
return status === "started" ? `Calling LLM ${name}` : `Completed LLM ${name}`;
|
|
412
|
+
}
|
|
413
|
+
if (kind === "tool") {
|
|
414
|
+
if (status === "failed") {
|
|
415
|
+
return `Tool ${name} failed`;
|
|
416
|
+
}
|
|
417
|
+
return status === "started" ? `Calling tool ${name}` : `Completed tool ${name}`;
|
|
418
|
+
}
|
|
419
|
+
if (kind === "skill") {
|
|
420
|
+
return status === "started" ? `Calling skill ${name}` : `Completed skill ${name}`;
|
|
421
|
+
}
|
|
422
|
+
if (kind === "memory") {
|
|
423
|
+
return status === "started" ? `Accessing memory ${name}` : `Completed memory ${name}`;
|
|
424
|
+
}
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
function createDelegationNodeFromSurfaceItem(surfaceItem, fallbackAgentId, fallbackAgentName, sourceEventId, ordinal) {
|
|
428
|
+
if (surfaceItem.kind !== "agent") {
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
const toAgentId = typeof surfaceItem.agentId === "string" && surfaceItem.agentId.trim().length > 0
|
|
432
|
+
? surfaceItem.agentId.trim()
|
|
433
|
+
: fallbackAgentId;
|
|
434
|
+
const toAgentName = deriveAgentName(toAgentId, typeof surfaceItem.agentName === "string" ? surfaceItem.agentName : undefined);
|
|
435
|
+
const fromAgentId = typeof surfaceItem.ownerAgentId === "string" && surfaceItem.ownerAgentId.trim().length > 0
|
|
436
|
+
? surfaceItem.ownerAgentId.trim()
|
|
437
|
+
: fallbackAgentId;
|
|
438
|
+
const fromAgentName = deriveAgentName(fromAgentId, typeof surfaceItem.ownerAgentName === "string" ? surfaceItem.ownerAgentName : fallbackAgentName);
|
|
439
|
+
return {
|
|
440
|
+
id: `delegate:${slugify(fromAgentId)}:${slugify(toAgentId)}:${ordinal}`,
|
|
441
|
+
layer: "execution",
|
|
442
|
+
kind: "agent",
|
|
443
|
+
label: `Delegate to ${titleCase(typeof surfaceItem.name === "string" ? surfaceItem.name : toAgentId)}`,
|
|
444
|
+
status: surfaceItem.status === "failed" ? "failed" : surfaceItem.status === "started" ? "started" : "completed",
|
|
445
|
+
sessionId: "",
|
|
446
|
+
requestId: "",
|
|
447
|
+
threadId: "",
|
|
448
|
+
runId: "",
|
|
449
|
+
agentId: toAgentId,
|
|
450
|
+
agentName: toAgentName,
|
|
451
|
+
sourceEventIds: [sourceEventId],
|
|
452
|
+
detail: {
|
|
453
|
+
fromAgentId,
|
|
454
|
+
fromAgentName,
|
|
455
|
+
toAgentId,
|
|
456
|
+
toAgentName,
|
|
457
|
+
...(typeof surfaceItem.action === "string" ? { action: surfaceItem.action } : {}),
|
|
458
|
+
},
|
|
459
|
+
};
|
|
460
|
+
}
|
|
363
461
|
function extractDelegatedAgentId(event) {
|
|
364
462
|
const typed = asObject(event);
|
|
365
463
|
if (!typed) {
|
|
@@ -372,26 +470,20 @@ function extractDelegatedAgentId(event) {
|
|
|
372
470
|
}
|
|
373
471
|
const data = asObject(typed.data);
|
|
374
472
|
const input = asObject(data?.input);
|
|
473
|
+
const nestedInput = typeof input?.input === "string"
|
|
474
|
+
? asObject(JSON.parse(input.input))
|
|
475
|
+
: asObject(input?.input);
|
|
375
476
|
const subagentType = typeof input?.subagent_type === "string"
|
|
376
477
|
? input.subagent_type
|
|
377
478
|
: typeof input?.subagentType === "string"
|
|
378
479
|
? input.subagentType
|
|
379
|
-
:
|
|
480
|
+
: typeof nestedInput?.subagent_type === "string"
|
|
481
|
+
? nestedInput.subagent_type
|
|
482
|
+
: typeof nestedInput?.subagentType === "string"
|
|
483
|
+
? nestedInput.subagentType
|
|
484
|
+
: null;
|
|
380
485
|
return subagentType && subagentType.trim().length > 0 ? subagentType.trim() : null;
|
|
381
486
|
}
|
|
382
|
-
function extractAgentFromNestedMessages(event, currentAgentId) {
|
|
383
|
-
const typed = asObject(event);
|
|
384
|
-
if (!typed) {
|
|
385
|
-
return null;
|
|
386
|
-
}
|
|
387
|
-
const data = asObject(typed.data);
|
|
388
|
-
const input = asObject(data?.input);
|
|
389
|
-
const output = asObject(data?.output);
|
|
390
|
-
const names = new Set();
|
|
391
|
-
collectNestedAgentNames(input?.messages, names);
|
|
392
|
-
collectNestedAgentNames(output?.messages, names);
|
|
393
|
-
return [...names].find((name) => name !== currentAgentId) ?? null;
|
|
394
|
-
}
|
|
395
487
|
function convertUpstreamEventsWithAgents(upstreamEvents, initialAgentId) {
|
|
396
488
|
const reducer = createUpstreamTimelineReducer();
|
|
397
489
|
const projections = [];
|
|
@@ -409,35 +501,11 @@ function convertUpstreamEventsWithAgents(upstreamEvents, initialAgentId) {
|
|
|
409
501
|
else if (envelope.agentName) {
|
|
410
502
|
currentAgentName = deriveAgentName(currentAgentId, envelope.agentName);
|
|
411
503
|
}
|
|
412
|
-
const nestedAgentId = extractAgentFromNestedMessages(envelope.event, currentAgentId);
|
|
413
|
-
if (nestedAgentId && nestedAgentId !== currentAgentId) {
|
|
414
|
-
const nestedAgentName = deriveAgentName(nestedAgentId);
|
|
415
|
-
ordinal += 1;
|
|
416
|
-
delegationNodes.push({
|
|
417
|
-
id: `delegate:${slugify(currentAgentId)}:${slugify(nestedAgentId)}:${ordinal}`,
|
|
418
|
-
layer: "execution",
|
|
419
|
-
kind: "agent",
|
|
420
|
-
label: `Delegate to ${titleCase(nestedAgentId)}`,
|
|
421
|
-
status: "completed",
|
|
422
|
-
sessionId: "",
|
|
423
|
-
requestId: "",
|
|
424
|
-
threadId: "",
|
|
425
|
-
runId: "",
|
|
426
|
-
agentId: nestedAgentId,
|
|
427
|
-
agentName: nestedAgentName,
|
|
428
|
-
sourceEventIds: [sourceEventId],
|
|
429
|
-
detail: {
|
|
430
|
-
fromAgentId: currentAgentId,
|
|
431
|
-
fromAgentName: currentAgentName,
|
|
432
|
-
toAgentId: nestedAgentId,
|
|
433
|
-
toAgentName: nestedAgentName,
|
|
434
|
-
},
|
|
435
|
-
});
|
|
436
|
-
currentAgentId = nestedAgentId;
|
|
437
|
-
currentAgentName = nestedAgentName;
|
|
438
|
-
}
|
|
439
504
|
const emitted = reducer.consume(envelope.event);
|
|
440
505
|
for (const projection of emitted) {
|
|
506
|
+
if (envelope.surfaceItem && projection.type === "step") {
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
441
509
|
projections.push({
|
|
442
510
|
projection,
|
|
443
511
|
agentId: currentAgentId,
|
|
@@ -445,6 +513,33 @@ function convertUpstreamEventsWithAgents(upstreamEvents, initialAgentId) {
|
|
|
445
513
|
sourceEventId,
|
|
446
514
|
});
|
|
447
515
|
}
|
|
516
|
+
if (envelope.surfaceItem) {
|
|
517
|
+
const delegationNode = createDelegationNodeFromSurfaceItem(envelope.surfaceItem, currentAgentId, currentAgentName, sourceEventId, ordinal + 1);
|
|
518
|
+
if (delegationNode) {
|
|
519
|
+
ordinal += 1;
|
|
520
|
+
delegationNodes.push(delegationNode);
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
const step = buildSurfaceStepLabel(envelope.surfaceItem);
|
|
524
|
+
if (step) {
|
|
525
|
+
projections.push({
|
|
526
|
+
projection: {
|
|
527
|
+
type: "step",
|
|
528
|
+
key: `surface:${index + 1}:${envelope.surfaceItem.id ?? step}`,
|
|
529
|
+
category: envelope.surfaceItem.kind,
|
|
530
|
+
status: envelope.surfaceItem.status,
|
|
531
|
+
step,
|
|
532
|
+
},
|
|
533
|
+
agentId: currentAgentId,
|
|
534
|
+
agentName: currentAgentName,
|
|
535
|
+
sourceEventId,
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
if (envelope.surfaceItem) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
448
543
|
const delegatedAgentId = extractDelegatedAgentId(envelope.event);
|
|
449
544
|
if (!delegatedAgentId || delegatedAgentId === currentAgentId) {
|
|
450
545
|
return;
|
|
@@ -544,6 +639,44 @@ function buildAttempts(projectionRecords, delegationNodes, runtimeGroups, thread
|
|
|
544
639
|
}
|
|
545
640
|
for (const record of projectionRecords) {
|
|
546
641
|
const projection = record.projection;
|
|
642
|
+
if (!pendingDelegationNode
|
|
643
|
+
&& delegationIndex < delegationNodes.length
|
|
644
|
+
&& delegationNodes[delegationIndex]?.agentId === record.agentId
|
|
645
|
+
&& (!previousAttempt || previousAttempt.agentId !== record.agentId)) {
|
|
646
|
+
const sourceNode = delegationNodes[delegationIndex];
|
|
647
|
+
delegationIndex += 1;
|
|
648
|
+
pendingDelegationNode = {
|
|
649
|
+
...sourceNode,
|
|
650
|
+
sessionId: threadId,
|
|
651
|
+
requestId: runId,
|
|
652
|
+
threadId,
|
|
653
|
+
runId,
|
|
654
|
+
groupId: currentGroup?.id,
|
|
655
|
+
};
|
|
656
|
+
nodes.push(pendingDelegationNode);
|
|
657
|
+
if (previousAttempt) {
|
|
658
|
+
edges.push({
|
|
659
|
+
id: `edge:${previousAttempt.id}->${pendingDelegationNode.id}`,
|
|
660
|
+
from: previousAttempt.id,
|
|
661
|
+
to: pendingDelegationNode.id,
|
|
662
|
+
kind: "spawn",
|
|
663
|
+
label: "delegate",
|
|
664
|
+
sourceEventIds: [...pendingDelegationNode.sourceEventIds],
|
|
665
|
+
confidence: 0.9,
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
else if (currentGroup?.anchorNodeId) {
|
|
669
|
+
edges.push({
|
|
670
|
+
id: `edge:${currentGroup.anchorNodeId}->${pendingDelegationNode.id}`,
|
|
671
|
+
from: currentGroup.anchorNodeId,
|
|
672
|
+
to: pendingDelegationNode.id,
|
|
673
|
+
kind: "spawn",
|
|
674
|
+
label: "delegate",
|
|
675
|
+
sourceEventIds: [...pendingDelegationNode.sourceEventIds],
|
|
676
|
+
confidence: 0.9,
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
}
|
|
547
680
|
if (previousAttempt
|
|
548
681
|
&& previousAttempt.agentId
|
|
549
682
|
&& record.agentId !== previousAttempt.agentId
|
|
@@ -743,18 +876,18 @@ function resolveContext(input, runtimeTimeline, projections) {
|
|
|
743
876
|
return { sessionId: inputSessionId, requestId: inputRequestId };
|
|
744
877
|
}
|
|
745
878
|
export function buildFlowGraph(input) {
|
|
746
|
-
const
|
|
747
|
-
?? (input.runtimeEvents ? projectRuntimeTimeline(input.runtimeEvents, {
|
|
879
|
+
const runtimeData = input.runtimeTimeline
|
|
880
|
+
?? (input.runtimeEvents ? projectRuntimeTimeline(normalizeRuntimeEvents(input.runtimeEvents), {
|
|
748
881
|
...(readSessionId(input) ? { threadId: readSessionId(input) } : {}),
|
|
749
882
|
...(readRequestId(input) ? { runId: readRequestId(input) } : {}),
|
|
750
883
|
}) : []);
|
|
751
|
-
const initialAgentId = deriveInitialAgentId(input,
|
|
884
|
+
const initialAgentId = deriveInitialAgentId(input, runtimeData);
|
|
752
885
|
const upstreamContext = input.upstreamEvents
|
|
753
886
|
? convertUpstreamEventsWithAgents(input.upstreamEvents, initialAgentId)
|
|
754
887
|
: { projections: [], delegationNodes: [] };
|
|
755
888
|
const upstreamProjections = input.upstreamProjections ?? upstreamContext.projections.map((record) => record.projection);
|
|
756
|
-
const { sessionId, requestId } = resolveContext(input,
|
|
757
|
-
const { nodes: runtimeNodes, edges: runtimeEdges, groups: runtimeGroups } = buildRuntimeNodes(
|
|
889
|
+
const { sessionId, requestId } = resolveContext(input, runtimeData, upstreamProjections);
|
|
890
|
+
const { nodes: runtimeNodes, edges: runtimeEdges, groups: runtimeGroups } = buildRuntimeNodes(runtimeData);
|
|
758
891
|
for (const node of runtimeNodes) {
|
|
759
892
|
node.agentId = typeof node.detail.agentId === "string" ? node.detail.agentId : initialAgentId;
|
|
760
893
|
node.agentName = deriveAgentName(node.agentId);
|
|
@@ -776,20 +909,15 @@ export function buildFlowGraph(input) {
|
|
|
776
909
|
id: buildSurfaceId(node.kind, node.kind === "agent" ? (node.agentId ?? node.agentName ?? "agent") : node.label),
|
|
777
910
|
name: node.kind === "agent"
|
|
778
911
|
? (node.agentName ?? node.agentId ?? "Agent")
|
|
779
|
-
:
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
.replace(/^Tool\s+/i, "")
|
|
786
|
-
.replace(/\s+failed$/i, "")
|
|
787
|
-
.replace(/^Calling skill\s+/i, "")
|
|
788
|
-
.replace(/^Completed skill\s+/i, "")
|
|
789
|
-
.replace(/^Accessing memory\s+/i, "")
|
|
790
|
-
.replace(/^Completed memory\s+/i, ""),
|
|
791
|
-
label: node.label,
|
|
912
|
+
: stripStepPrefix(node.label),
|
|
913
|
+
action: resolveSurfaceAction({
|
|
914
|
+
kind: node.kind,
|
|
915
|
+
step: node.label,
|
|
916
|
+
event: node.detail,
|
|
917
|
+
}),
|
|
792
918
|
status: node.status === "resolved" ? "completed" : node.status,
|
|
919
|
+
agentId: node.agentId,
|
|
920
|
+
agentName: node.agentName,
|
|
793
921
|
ownerAgentId: node.kind === "agent"
|
|
794
922
|
? (typeof node.detail.fromAgentId === "string" ? node.detail.fromAgentId : node.agentId)
|
|
795
923
|
: node.agentId,
|
|
@@ -797,6 +925,7 @@ export function buildFlowGraph(input) {
|
|
|
797
925
|
? (typeof node.detail.fromAgentName === "string" ? node.detail.fromAgentName : node.agentName)
|
|
798
926
|
: node.agentName,
|
|
799
927
|
sourceEventId: node.sourceEventIds[0],
|
|
928
|
+
detail: { ...node.detail },
|
|
800
929
|
}));
|
|
801
930
|
return {
|
|
802
931
|
graphId: `${sessionId}/${requestId}`,
|
|
@@ -809,7 +938,9 @@ export function buildFlowGraph(input) {
|
|
|
809
938
|
edges: [...runtimeEdges, ...attemptEdges],
|
|
810
939
|
groups: [...runtimeGroups, ...attemptGroups],
|
|
811
940
|
metadata: {
|
|
812
|
-
|
|
941
|
+
initialAgentId,
|
|
942
|
+
initialAgentName: deriveAgentName(initialAgentId),
|
|
943
|
+
runtimeTimelineCount: runtimeData.length,
|
|
813
944
|
upstreamProjectionCount: upstreamProjections.length,
|
|
814
945
|
delegationCount: upstreamContext.delegationNodes.length,
|
|
815
946
|
runtimeSurface,
|