langchain_agentx_stream_ui 0.3.0 → 0.3.3
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/dist/{AskUserQuestionToolBody-BG1StdvE.d.ts → AskUserQuestionToolBody-CUXqUkar.d.ts} +1 -1
- package/dist/{chunk-SUEMZC4U.js → chunk-6ORA5RMV.js} +49 -194
- package/dist/chunk-6ORA5RMV.js.map +1 -0
- package/dist/{chunk-DP7V33X7.js → chunk-6Z4ZF36Z.js} +1 -1
- package/dist/chunk-6Z4ZF36Z.js.map +1 -0
- package/dist/{chunk-7CLAU74Y.js → chunk-FL2G7SV3.js} +378 -98
- package/dist/chunk-FL2G7SV3.js.map +1 -0
- package/dist/{chunk-4RIOBLGB.js → chunk-GBY5DJ7L.js} +1 -1
- package/dist/chunk-GBY5DJ7L.js.map +1 -0
- package/dist/{chunk-CUKNUCGU.js → chunk-ISQ7JWGD.js} +5 -5
- package/dist/chunk-ISQ7JWGD.js.map +1 -0
- package/dist/{chunk-6DYISADG.js → chunk-TCKOXX7O.js} +6 -33
- package/dist/chunk-TCKOXX7O.js.map +1 -0
- package/dist/index.d.ts +93 -12
- package/dist/index.js +218 -26
- package/dist/index.js.map +1 -1
- package/dist/{multi-session-xvSZstSN.d.ts → multi-session-CerO558Y.d.ts} +3 -1
- package/dist/multi-session.d.ts +2 -2
- package/dist/multi-session.js +6 -6
- package/dist/{sessionViewOptions-WM00Fpcn.d.ts → sessionViewOptions-DQRzPuN_.d.ts} +2 -0
- package/dist/tools-presentation.js +2 -2
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +4 -4
- package/dist/virtual.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-4RIOBLGB.js.map +0 -1
- package/dist/chunk-6DYISADG.js.map +0 -1
- package/dist/chunk-7CLAU74Y.js.map +0 -1
- package/dist/chunk-CUKNUCGU.js.map +0 -1
- package/dist/chunk-DP7V33X7.js.map +0 -1
- package/dist/chunk-SUEMZC4U.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
fixDiagramSvg,
|
|
24
24
|
markEventIdSeen,
|
|
25
25
|
shouldSkipDuplicateEvent
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-ISQ7JWGD.js";
|
|
27
27
|
import {
|
|
28
28
|
DefaultToolBody,
|
|
29
29
|
InteractionBusContext,
|
|
@@ -32,8 +32,8 @@ import {
|
|
|
32
32
|
getNoopInteractionBus,
|
|
33
33
|
resolveToolBody,
|
|
34
34
|
useInteractionBus
|
|
35
|
-
} from "./chunk-
|
|
36
|
-
import "./chunk-
|
|
35
|
+
} from "./chunk-TCKOXX7O.js";
|
|
36
|
+
import "./chunk-6Z4ZF36Z.js";
|
|
37
37
|
import {
|
|
38
38
|
CollapseKind,
|
|
39
39
|
CollapsedExploreNode,
|
|
@@ -72,7 +72,6 @@ import {
|
|
|
72
72
|
createEmptyTree,
|
|
73
73
|
createProjectionContext,
|
|
74
74
|
entryKey,
|
|
75
|
-
formatExploreSummaryText,
|
|
76
75
|
formatHookFinishedSummary,
|
|
77
76
|
formatShellProgressSuffix,
|
|
78
77
|
formatTaskFooterLabel,
|
|
@@ -111,7 +110,7 @@ import {
|
|
|
111
110
|
useSessionStatus,
|
|
112
111
|
useSessionViewOptions,
|
|
113
112
|
useTimeline
|
|
114
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-6ORA5RMV.js";
|
|
115
114
|
import {
|
|
116
115
|
Agent,
|
|
117
116
|
AgentToolBody,
|
|
@@ -137,8 +136,9 @@ import {
|
|
|
137
136
|
Write,
|
|
138
137
|
WriteToolBody,
|
|
139
138
|
createDefaultToolRegistry,
|
|
140
|
-
formatAgentTitle
|
|
141
|
-
|
|
139
|
+
formatAgentTitle,
|
|
140
|
+
formatExploreSummaryText
|
|
141
|
+
} from "./chunk-FL2G7SV3.js";
|
|
142
142
|
import {
|
|
143
143
|
BodyBlockList,
|
|
144
144
|
DiffView,
|
|
@@ -154,7 +154,7 @@ import {
|
|
|
154
154
|
formatTimeoutFooter,
|
|
155
155
|
parseDiffText,
|
|
156
156
|
truncateCommand
|
|
157
|
-
} from "./chunk-
|
|
157
|
+
} from "./chunk-GBY5DJ7L.js";
|
|
158
158
|
|
|
159
159
|
// src/view/AgentSession.tsx
|
|
160
160
|
import { useEffect as useEffect2, useMemo, useRef as useRef2 } from "react";
|
|
@@ -184,7 +184,8 @@ function safeReduce(tree, event, eventIndex, options) {
|
|
|
184
184
|
function createSessionStore(initialTree = createEmptyTree(), storeOptions) {
|
|
185
185
|
const reduceOpts = {
|
|
186
186
|
tierOverrides: storeOptions?.tierOverrides,
|
|
187
|
-
collectDebug: storeOptions?.debug === true
|
|
187
|
+
collectDebug: storeOptions?.debug === true,
|
|
188
|
+
subagentLeakGate: storeOptions?.subagentLeakGate === true
|
|
188
189
|
};
|
|
189
190
|
const initialEventCount = storeOptions?.initialEventCount ?? 0;
|
|
190
191
|
const seenEventIds = new Set(storeOptions?.initialSeenEventIds);
|
|
@@ -317,6 +318,15 @@ var PROFILE_PRESETS = {
|
|
|
317
318
|
...BOUNDED_DEFAULTS
|
|
318
319
|
},
|
|
319
320
|
terminal: WORKFLOW_TERMINAL_WITH_FALLBACK
|
|
321
|
+
},
|
|
322
|
+
"workflow-tail": {
|
|
323
|
+
profile: "workflow-tail",
|
|
324
|
+
replay: "none",
|
|
325
|
+
reconnect: {
|
|
326
|
+
mode: "bounded",
|
|
327
|
+
...BOUNDED_DEFAULTS
|
|
328
|
+
},
|
|
329
|
+
terminal: WORKFLOW_TERMINAL_WITH_FALLBACK
|
|
320
330
|
}
|
|
321
331
|
};
|
|
322
332
|
function legacyTerminal(expectedApplicationKind) {
|
|
@@ -778,19 +788,22 @@ function AgentSession({
|
|
|
778
788
|
exploreFullscreenBash = true,
|
|
779
789
|
memoryDir = null,
|
|
780
790
|
workspaceRoot = null,
|
|
791
|
+
subagentLeakGate = false,
|
|
781
792
|
children
|
|
782
793
|
}) {
|
|
783
794
|
const storeRef = useRef2(null);
|
|
784
795
|
if (storeRef.current === null) {
|
|
785
796
|
const replayOpts = {
|
|
786
797
|
tierOverrides: _tierOverrides,
|
|
787
|
-
collectDebug: debug
|
|
798
|
+
collectDebug: debug,
|
|
799
|
+
subagentLeakGate
|
|
788
800
|
};
|
|
789
801
|
const initialTree = initialEvents && initialEvents.length > 0 ? replayEvents(initialEvents, replayOpts) : void 0;
|
|
790
802
|
storeRef.current = createSessionStore(initialTree, {
|
|
791
803
|
tierOverrides: _tierOverrides,
|
|
792
804
|
debug,
|
|
793
|
-
initialEventCount: initialEvents?.length ?? 0
|
|
805
|
+
initialEventCount: initialEvents?.length ?? 0,
|
|
806
|
+
subagentLeakGate
|
|
794
807
|
});
|
|
795
808
|
}
|
|
796
809
|
const registryRef = useMemo(() => registry ?? createDefaultRegistry(), [registry]);
|
|
@@ -815,7 +828,8 @@ function AgentSession({
|
|
|
815
828
|
verbose,
|
|
816
829
|
exploreFullscreenBash,
|
|
817
830
|
memoryDir,
|
|
818
|
-
workspaceRoot
|
|
831
|
+
workspaceRoot,
|
|
832
|
+
subagentLeakGate
|
|
819
833
|
}),
|
|
820
834
|
[
|
|
821
835
|
groupParallelTools,
|
|
@@ -825,7 +839,8 @@ function AgentSession({
|
|
|
825
839
|
verbose,
|
|
826
840
|
exploreFullscreenBash,
|
|
827
841
|
memoryDir,
|
|
828
|
-
workspaceRoot
|
|
842
|
+
workspaceRoot,
|
|
843
|
+
subagentLeakGate
|
|
829
844
|
]
|
|
830
845
|
);
|
|
831
846
|
const onErrorRef = useRef2(onError);
|
|
@@ -901,10 +916,19 @@ function resolveWorkflowBanner(state) {
|
|
|
901
916
|
if (state.display.authoritySyncFailed) {
|
|
902
917
|
return { kind: "sync_failed", message: "\u540C\u6B65\u72B6\u6001\u5931\u8D25\uFF0C\u8BF7\u5237\u65B0" };
|
|
903
918
|
}
|
|
919
|
+
const auth = state.authority?.status;
|
|
920
|
+
if (auth === "error") {
|
|
921
|
+
return { kind: "authority_error", message: "Workflow \u6267\u884C\u5931\u8D25" };
|
|
922
|
+
}
|
|
923
|
+
if (state.snapshotHydrateFailed) {
|
|
924
|
+
return {
|
|
925
|
+
kind: "snapshot_unavailable",
|
|
926
|
+
message: "\u65E0\u6CD5\u52A0\u8F7D projection snapshot\uFF0C\u5C55\u793A\u53EF\u80FD\u4E0D\u5B8C\u6574"
|
|
927
|
+
};
|
|
928
|
+
}
|
|
904
929
|
if (state.display.awaitingAuthority) {
|
|
905
930
|
return { kind: "awaiting_authority", message: "\u6536\u5C3E\u4E2D\u2026" };
|
|
906
931
|
}
|
|
907
|
-
const auth = state.authority?.status;
|
|
908
932
|
if (auth === "partial_success") {
|
|
909
933
|
const forced = state.display.terminalKind === "forced_closeout";
|
|
910
934
|
return {
|
|
@@ -912,6 +936,15 @@ function resolveWorkflowBanner(state) {
|
|
|
912
936
|
message: forced ? "\u90E8\u5206\u5B8C\u6210\uFF08\u90E8\u5206\u5BB9\u5668\u672A\u6B63\u5E38\u7ED3\u675F\uFF09" : "\u90E8\u5206\u5B8C\u6210\uFF08\u6240\u6709\u5BB9\u5668\u6B63\u5E38\u7ED3\u675F\uFF09"
|
|
913
937
|
};
|
|
914
938
|
}
|
|
939
|
+
const meta = state.authority?.metadata;
|
|
940
|
+
if (auth === "done" && meta?.projection_status === "degraded") {
|
|
941
|
+
const dropped = meta.projection_dropped_count;
|
|
942
|
+
const suffix = dropped != null && dropped > 0 ? `\uFF08\u7EA6 ${dropped} \u6761\u4E8B\u4EF6\u672A\u5B8C\u6574\u5C55\u793A\uFF09` : "";
|
|
943
|
+
return {
|
|
944
|
+
kind: "projection_degraded",
|
|
945
|
+
message: `\u5C55\u793A\u53EF\u80FD\u4E0D\u5B8C\u6574${suffix}`
|
|
946
|
+
};
|
|
947
|
+
}
|
|
915
948
|
if (state.display.terminalKind === "forced_closeout" && auth === "done") {
|
|
916
949
|
return { kind: "forced_closeout", message: "Workflow \u5DF2\u7ED3\u675F\uFF08\u90E8\u5206\u5BB9\u5668\u672A\u6B63\u5E38\u5173\u95ED\uFF09" };
|
|
917
950
|
}
|
|
@@ -1031,6 +1064,10 @@ function createEmptyWorkflowSessionState() {
|
|
|
1031
1064
|
stageDoneSummariesByContainerId: {},
|
|
1032
1065
|
hotCompletedLoopSessionIds: [],
|
|
1033
1066
|
activeLoopSessionId: null,
|
|
1067
|
+
projectionCursor: null,
|
|
1068
|
+
snapshotVersion: null,
|
|
1069
|
+
reconnectSuppressedReason: null,
|
|
1070
|
+
snapshotHydrateFailed: false,
|
|
1034
1071
|
openScopeStack: [],
|
|
1035
1072
|
internalErrors: []
|
|
1036
1073
|
};
|
|
@@ -1389,6 +1426,35 @@ function contentBlockFromEvent(event) {
|
|
|
1389
1426
|
}
|
|
1390
1427
|
return null;
|
|
1391
1428
|
}
|
|
1429
|
+
function wouldAssignParentCreateCycle(containersById, containerId, parentId) {
|
|
1430
|
+
if (!parentId) return false;
|
|
1431
|
+
if (parentId === containerId) return true;
|
|
1432
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1433
|
+
let current = parentId;
|
|
1434
|
+
while (current) {
|
|
1435
|
+
if (current === containerId) return true;
|
|
1436
|
+
if (seen.has(current)) return true;
|
|
1437
|
+
seen.add(current);
|
|
1438
|
+
current = containersById[current]?.parent_container_id ?? null;
|
|
1439
|
+
}
|
|
1440
|
+
return false;
|
|
1441
|
+
}
|
|
1442
|
+
function sanitizeContainerTreeParentLinks(containersById) {
|
|
1443
|
+
const next = { ...containersById };
|
|
1444
|
+
for (const [containerId, node] of Object.entries(next)) {
|
|
1445
|
+
const seen = /* @__PURE__ */ new Set([containerId]);
|
|
1446
|
+
let current = node.parent_container_id;
|
|
1447
|
+
while (current) {
|
|
1448
|
+
if (seen.has(current)) {
|
|
1449
|
+
next[containerId] = { ...node, parent_container_id: null };
|
|
1450
|
+
break;
|
|
1451
|
+
}
|
|
1452
|
+
seen.add(current);
|
|
1453
|
+
current = next[current]?.parent_container_id ?? null;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
return next;
|
|
1457
|
+
}
|
|
1392
1458
|
function resolveContentScopeKey(data) {
|
|
1393
1459
|
for (const keyName of ["stage_key", "item_key", "branch_key", "aggregate_key", "debug_key"]) {
|
|
1394
1460
|
const value = readString(data, keyName);
|
|
@@ -1466,7 +1532,11 @@ var WorkflowContainerActiveSet = class {
|
|
|
1466
1532
|
);
|
|
1467
1533
|
}
|
|
1468
1534
|
}
|
|
1469
|
-
|
|
1535
|
+
const openNonWorkflow = this.openOrder.map((cid) => this.nodes[cid]).filter((node) => node.is_open && node.scope !== "workflow");
|
|
1536
|
+
if (openNonWorkflow.length === 1) {
|
|
1537
|
+
return openNonWorkflow[0].container_id;
|
|
1538
|
+
}
|
|
1539
|
+
return null;
|
|
1470
1540
|
}
|
|
1471
1541
|
closeDescendantsOfPath(workflowPath, status) {
|
|
1472
1542
|
const toClose = this.openOrder.filter((cid) => {
|
|
@@ -1544,7 +1614,12 @@ var WorkflowContainerStateMachine = class {
|
|
|
1544
1614
|
const subtitle = display?.description ?? "";
|
|
1545
1615
|
const pattern = display?.pattern ?? "";
|
|
1546
1616
|
const status = displayStatus(data, "running");
|
|
1547
|
-
const
|
|
1617
|
+
const existing = this.active.getNode(containerId);
|
|
1618
|
+
const computedParentId = this.resolveParentId(workflowPath, scope);
|
|
1619
|
+
let parentId = existing != null ? existing.parent_container_id : computedParentId;
|
|
1620
|
+
if (wouldAssignParentCreateCycle(this.active.nodesById, containerId, parentId)) {
|
|
1621
|
+
parentId = existing?.parent_container_id ?? null;
|
|
1622
|
+
}
|
|
1548
1623
|
const node = {
|
|
1549
1624
|
container_id: containerId,
|
|
1550
1625
|
scope,
|
|
@@ -1557,7 +1632,7 @@ var WorkflowContainerStateMachine = class {
|
|
|
1557
1632
|
pattern,
|
|
1558
1633
|
parent_container_id: parentId,
|
|
1559
1634
|
display,
|
|
1560
|
-
content_blocks: [],
|
|
1635
|
+
content_blocks: existing?.content_blocks ?? [],
|
|
1561
1636
|
is_open: true
|
|
1562
1637
|
};
|
|
1563
1638
|
this.active.open(node);
|
|
@@ -1635,9 +1710,7 @@ var WorkflowContainerStateMachine = class {
|
|
|
1635
1710
|
(best, node) => this.active.compareContainerRank(node.container_id, best.container_id) > 0 ? node : best
|
|
1636
1711
|
).container_id;
|
|
1637
1712
|
}
|
|
1638
|
-
return
|
|
1639
|
-
(best, node) => this.active.compareContainerRank(node.container_id, best.container_id) > 0 ? node : best
|
|
1640
|
-
).container_id;
|
|
1713
|
+
return null;
|
|
1641
1714
|
}
|
|
1642
1715
|
};
|
|
1643
1716
|
var WorkflowContainerTreeProjector = class {
|
|
@@ -2753,6 +2826,45 @@ function reduceWorkflowEvents(events, options) {
|
|
|
2753
2826
|
);
|
|
2754
2827
|
}
|
|
2755
2828
|
|
|
2829
|
+
// src/core/workflow/hydrateWorkflowSnapshot.ts
|
|
2830
|
+
function isAtOrBeforeProjectionCursor(projectionCursor, eventId) {
|
|
2831
|
+
if (!projectionCursor || !eventId) return false;
|
|
2832
|
+
const cursorNum = Number.parseInt(projectionCursor, 10);
|
|
2833
|
+
const eventNum = Number.parseInt(eventId, 10);
|
|
2834
|
+
if (!Number.isNaN(cursorNum) && !Number.isNaN(eventNum)) {
|
|
2835
|
+
return eventNum <= cursorNum;
|
|
2836
|
+
}
|
|
2837
|
+
return eventId <= projectionCursor;
|
|
2838
|
+
}
|
|
2839
|
+
function hydrateWorkflowFromSnapshot(state, snapshot, options = {}) {
|
|
2840
|
+
const authority = options.preserveAuthority ? state.authority : null;
|
|
2841
|
+
const containerTree = structuredClone(snapshot.containerTree);
|
|
2842
|
+
containerTree.containersById = sanitizeContainerTreeParentLinks(
|
|
2843
|
+
containerTree.containersById
|
|
2844
|
+
);
|
|
2845
|
+
return {
|
|
2846
|
+
...createEmptyWorkflowSessionState(),
|
|
2847
|
+
authority,
|
|
2848
|
+
display: {
|
|
2849
|
+
...snapshot.display,
|
|
2850
|
+
streamEnded: false
|
|
2851
|
+
},
|
|
2852
|
+
containerTree,
|
|
2853
|
+
projectionCursor: snapshot.cursor,
|
|
2854
|
+
snapshotVersion: snapshot.snapshotVersion,
|
|
2855
|
+
meta: {
|
|
2856
|
+
...state.meta,
|
|
2857
|
+
workflowRunId: snapshot.taskId,
|
|
2858
|
+
lastEventId: snapshot.cursor,
|
|
2859
|
+
startedAt: state.meta.startedAt ?? snapshot.capturedAt
|
|
2860
|
+
},
|
|
2861
|
+
loopTreesBySessionId: {},
|
|
2862
|
+
internalErrors: [],
|
|
2863
|
+
reconnectSuppressedReason: null,
|
|
2864
|
+
snapshotHydrateFailed: false
|
|
2865
|
+
};
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2756
2868
|
// src/core/workflowSessionStore.ts
|
|
2757
2869
|
var DEFAULT_HYDRATE_CHUNK_SIZE = 50;
|
|
2758
2870
|
function nextAnimationFrame() {
|
|
@@ -2841,8 +2953,12 @@ function createWorkflowSessionStore(initialState = createEmptyWorkflowSessionSta
|
|
|
2841
2953
|
hydratingLoopSessionIds: {},
|
|
2842
2954
|
applyEvent(event, ctx) {
|
|
2843
2955
|
const sseEventId = ctx?.sseEventId;
|
|
2844
|
-
if (shouldSkipDuplicateEvent(seenEventIds, sseEventId)) return;
|
|
2845
2956
|
const { state, eventCount } = get();
|
|
2957
|
+
if (isAtOrBeforeProjectionCursor(state.projectionCursor, sseEventId)) {
|
|
2958
|
+
markEventIdSeen(seenEventIds, sseEventId);
|
|
2959
|
+
return;
|
|
2960
|
+
}
|
|
2961
|
+
if (shouldSkipDuplicateEvent(seenEventIds, sseEventId)) return;
|
|
2846
2962
|
const { state: reduced } = safeReduceWorkflow(state, event, eventCount, reduceOpts);
|
|
2847
2963
|
const evicted = finalizeState(reduced);
|
|
2848
2964
|
const nextMeta = sseEventId ? { ...evicted.meta, lastEventId: sseEventId } : evicted.meta;
|
|
@@ -3039,6 +3155,23 @@ function createWorkflowSessionStore(initialState = createEmptyWorkflowSessionSta
|
|
|
3039
3155
|
loopSessionId
|
|
3040
3156
|
)
|
|
3041
3157
|
}));
|
|
3158
|
+
},
|
|
3159
|
+
hydrateFromSnapshot(snapshot, options) {
|
|
3160
|
+
const { state } = get();
|
|
3161
|
+
const next = finalizeState(
|
|
3162
|
+
hydrateWorkflowFromSnapshot(state, snapshot, options)
|
|
3163
|
+
);
|
|
3164
|
+
markEventIdSeen(seenEventIds, snapshot.cursor);
|
|
3165
|
+
set({ state: next });
|
|
3166
|
+
},
|
|
3167
|
+
markSnapshotHydrateFailed() {
|
|
3168
|
+
set((current) => ({
|
|
3169
|
+
state: {
|
|
3170
|
+
...current.state,
|
|
3171
|
+
snapshotHydrateFailed: true,
|
|
3172
|
+
reconnectSuppressedReason: "snapshot_unavailable"
|
|
3173
|
+
}
|
|
3174
|
+
}));
|
|
3042
3175
|
}
|
|
3043
3176
|
}));
|
|
3044
3177
|
}
|
|
@@ -4409,22 +4542,30 @@ function stageHasSubworkflowChild(stageId, containerTree) {
|
|
|
4409
4542
|
(node) => node.scope === "subworkflow"
|
|
4410
4543
|
);
|
|
4411
4544
|
}
|
|
4412
|
-
function renderContainerChildren(parentId, containerTree, loopTreesBySessionId, viewProps, depth) {
|
|
4545
|
+
function renderContainerChildren(parentId, containerTree, loopTreesBySessionId, viewProps, depth, ancestorVisited = /* @__PURE__ */ new Set()) {
|
|
4413
4546
|
const children = collectChildContainers(containerTree.containersById, parentId);
|
|
4414
4547
|
const items = children.filter((node) => node.scope === "item");
|
|
4415
4548
|
const rest = children.filter((node) => node.scope !== "item");
|
|
4416
4549
|
return /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
4417
4550
|
renderItemSiblings(items, parentId, depth, containerTree, loopTreesBySessionId, viewProps),
|
|
4418
|
-
rest.map(
|
|
4551
|
+
rest.map(
|
|
4552
|
+
(node) => renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, depth, ancestorVisited)
|
|
4553
|
+
)
|
|
4419
4554
|
] });
|
|
4420
4555
|
}
|
|
4421
|
-
function renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, depth) {
|
|
4556
|
+
function renderContainerNode(node, containerTree, loopTreesBySessionId, viewProps, depth, ancestorVisited = /* @__PURE__ */ new Set()) {
|
|
4557
|
+
if (ancestorVisited.has(node.container_id)) {
|
|
4558
|
+
return null;
|
|
4559
|
+
}
|
|
4560
|
+
const pathVisited = new Set(ancestorVisited);
|
|
4561
|
+
pathVisited.add(node.container_id);
|
|
4422
4562
|
const nested = renderContainerChildren(
|
|
4423
4563
|
node.container_id,
|
|
4424
4564
|
containerTree,
|
|
4425
4565
|
loopTreesBySessionId,
|
|
4426
4566
|
viewProps,
|
|
4427
|
-
depth + 1
|
|
4567
|
+
depth + 1,
|
|
4568
|
+
pathVisited
|
|
4428
4569
|
);
|
|
4429
4570
|
const hasNested = collectChildContainers(containerTree.containersById, node.container_id).length > 0;
|
|
4430
4571
|
if (node.scope === "subworkflow") {
|
|
@@ -4642,7 +4783,35 @@ function WorkflowSessionBanners({ state }) {
|
|
|
4642
4783
|
if (banner.kind === "none" && display.projectionStatus !== "error" && display.projectionStatus !== "done_with_warning" && state.internalErrors.length === 0) {
|
|
4643
4784
|
return null;
|
|
4644
4785
|
}
|
|
4786
|
+
const showTransportError = (display.projectionStatus === "error" || state.internalErrors.length > 0) && banner.kind !== "projection_degraded" && banner.kind !== "authority_error";
|
|
4645
4787
|
return /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
4788
|
+
banner.kind === "authority_error" ? /* @__PURE__ */ jsx17(
|
|
4789
|
+
"div",
|
|
4790
|
+
{
|
|
4791
|
+
className: "lax-workflow-banner lax-workflow-banner--authority-error",
|
|
4792
|
+
"data-testid": "lax-workflow-authority-error-banner",
|
|
4793
|
+
role: "alert",
|
|
4794
|
+
children: banner.message
|
|
4795
|
+
}
|
|
4796
|
+
) : null,
|
|
4797
|
+
banner.kind === "projection_degraded" ? /* @__PURE__ */ jsx17(
|
|
4798
|
+
"div",
|
|
4799
|
+
{
|
|
4800
|
+
className: "lax-workflow-banner lax-workflow-banner--projection-degraded",
|
|
4801
|
+
"data-testid": "lax-workflow-projection-degraded-banner",
|
|
4802
|
+
role: "status",
|
|
4803
|
+
children: banner.message
|
|
4804
|
+
}
|
|
4805
|
+
) : null,
|
|
4806
|
+
banner.kind === "snapshot_unavailable" ? /* @__PURE__ */ jsx17(
|
|
4807
|
+
"div",
|
|
4808
|
+
{
|
|
4809
|
+
className: "lax-workflow-banner lax-workflow-banner--snapshot-unavailable",
|
|
4810
|
+
"data-testid": "lax-workflow-snapshot-unavailable-banner",
|
|
4811
|
+
role: "status",
|
|
4812
|
+
children: banner.message
|
|
4813
|
+
}
|
|
4814
|
+
) : null,
|
|
4646
4815
|
banner.kind === "partial_success" ? /* @__PURE__ */ jsx17(
|
|
4647
4816
|
"div",
|
|
4648
4817
|
{
|
|
@@ -4686,7 +4855,7 @@ function WorkflowSessionBanners({ state }) {
|
|
|
4686
4855
|
children: banner.message
|
|
4687
4856
|
}
|
|
4688
4857
|
) : null,
|
|
4689
|
-
|
|
4858
|
+
showTransportError ? /* @__PURE__ */ jsx17(
|
|
4690
4859
|
"div",
|
|
4691
4860
|
{
|
|
4692
4861
|
className: "lax-workflow-error",
|
|
@@ -4825,6 +4994,8 @@ import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
|
4825
4994
|
function WorkflowSession({
|
|
4826
4995
|
source,
|
|
4827
4996
|
authoritySource,
|
|
4997
|
+
snapshotBootstrap,
|
|
4998
|
+
snapshotHydrateFailed = false,
|
|
4828
4999
|
initialEvents,
|
|
4829
5000
|
registry,
|
|
4830
5001
|
tierOverrides,
|
|
@@ -4863,6 +5034,16 @@ function WorkflowSession({
|
|
|
4863
5034
|
const streamEnded = useStore5(store, (s) => s.state.display.streamEnded);
|
|
4864
5035
|
const authorityStatus = useStore5(store, (s) => s.state.authority?.status);
|
|
4865
5036
|
useWorkflowAwaitingAuthorityTimers(store, streamEnded, authorityStatus);
|
|
5037
|
+
useEffect10(() => {
|
|
5038
|
+
if (snapshotBootstrap) {
|
|
5039
|
+
store.getState().hydrateFromSnapshot(snapshotBootstrap, { preserveAuthority: true });
|
|
5040
|
+
}
|
|
5041
|
+
}, [snapshotBootstrap, store]);
|
|
5042
|
+
useEffect10(() => {
|
|
5043
|
+
if (snapshotHydrateFailed) {
|
|
5044
|
+
store.getState().markSnapshotHydrateFailed();
|
|
5045
|
+
}
|
|
5046
|
+
}, [snapshotHydrateFailed, store]);
|
|
4866
5047
|
const scaleOptions = useMemo9(
|
|
4867
5048
|
() => ({ ...DEFAULT_WORKFLOW_SCALE_OPTIONS, ...workflowScale }),
|
|
4868
5049
|
[workflowScale]
|
|
@@ -4905,10 +5086,13 @@ function WorkflowSession({
|
|
|
4905
5086
|
const loopTreesBySessionId = sessionState.loopTreesBySessionId;
|
|
4906
5087
|
const onErrorRef = useRef4(onError);
|
|
4907
5088
|
const onDisplayStreamEndedRef = useRef4(onDisplayStreamEnded);
|
|
5089
|
+
const streamAbortRef = useRef4(null);
|
|
4908
5090
|
onErrorRef.current = onError;
|
|
4909
5091
|
onDisplayStreamEndedRef.current = onDisplayStreamEnded;
|
|
4910
5092
|
useEffect10(() => {
|
|
5093
|
+
if (!source) return void 0;
|
|
4911
5094
|
const controller = new AbortController();
|
|
5095
|
+
streamAbortRef.current = controller;
|
|
4912
5096
|
void source.start((event, ctx) => {
|
|
4913
5097
|
store.getState().applyEvent(event, ctx);
|
|
4914
5098
|
}, controller.signal).then(() => {
|
|
@@ -4924,8 +5108,14 @@ function WorkflowSession({
|
|
|
4924
5108
|
});
|
|
4925
5109
|
return () => {
|
|
4926
5110
|
controller.abort();
|
|
5111
|
+
streamAbortRef.current = null;
|
|
4927
5112
|
};
|
|
4928
5113
|
}, [source, store]);
|
|
5114
|
+
useEffect10(() => {
|
|
5115
|
+
if (isAuthorityTerminalStatus(authorityStatus)) {
|
|
5116
|
+
streamAbortRef.current?.abort();
|
|
5117
|
+
}
|
|
5118
|
+
}, [authorityStatus]);
|
|
4929
5119
|
return /* @__PURE__ */ jsx19(WorkflowSessionStoreContext.Provider, { value: store, children: /* @__PURE__ */ jsx19(WorkflowScaleContext.Provider, { value: scaleOptions, children: /* @__PURE__ */ jsx19(WorkflowLoopReplayProvider, { onRequestLoopReplay, children: /* @__PURE__ */ jsx19(InteractionBusContext.Provider, { value: busRef, children: /* @__PURE__ */ jsx19(NodeRegistryContext.Provider, { value: registryRef, children: /* @__PURE__ */ jsx19(MarkdownRendererContext.Provider, { value: markdownRenderer, children: /* @__PURE__ */ jsx19(ToolDisplayOptionsContext.Provider, { value: toolDisplayRef, children: /* @__PURE__ */ jsx19(SessionViewOptionsContext.Provider, { value: sessionViewRef, children: /* @__PURE__ */ jsxs14(
|
|
4930
5120
|
"div",
|
|
4931
5121
|
{
|
|
@@ -5315,7 +5505,9 @@ export {
|
|
|
5315
5505
|
getDisplayProjectionStatus,
|
|
5316
5506
|
getMainStageIds,
|
|
5317
5507
|
getNoopInteractionBus,
|
|
5508
|
+
hydrateWorkflowFromSnapshot,
|
|
5318
5509
|
isAgentLoopReplayEventType,
|
|
5510
|
+
isAtOrBeforeProjectionCursor,
|
|
5319
5511
|
isAuthorityTerminal,
|
|
5320
5512
|
isAuthorityTerminalStatus,
|
|
5321
5513
|
isGitOperationCommand,
|