langchain_agentx_stream_ui 0.3.5 → 0.4.0

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 (36) hide show
  1. package/dist/{AskUserQuestionToolBody-CUXqUkar.d.ts → AskUserQuestionToolBody-J8MqSUEs.d.ts} +2 -2
  2. package/dist/{MarkdownBlock-CcXZ5nTm.d.ts → MarkdownBlock-DeICJUtu.d.ts} +1 -1
  3. package/dist/{chunk-GBY5DJ7L.js → chunk-4RIOBLGB.js} +1 -1
  4. package/dist/chunk-4RIOBLGB.js.map +1 -0
  5. package/dist/{chunk-FT6UUKPS.js → chunk-7X7IF2A4.js} +5 -5
  6. package/dist/chunk-7X7IF2A4.js.map +1 -0
  7. package/dist/{chunk-6PWGGGUK.js → chunk-AY7QLXFB.js} +222 -14
  8. package/dist/chunk-AY7QLXFB.js.map +1 -0
  9. package/dist/{chunk-6Z4ZF36Z.js → chunk-DP7V33X7.js} +1 -1
  10. package/dist/chunk-DP7V33X7.js.map +1 -0
  11. package/dist/{chunk-TCKOXX7O.js → chunk-MRGHYRSV.js} +4 -4
  12. package/dist/chunk-MRGHYRSV.js.map +1 -0
  13. package/dist/{chunk-FL2G7SV3.js → chunk-QL3DIGFI.js} +2 -2
  14. package/dist/chunk-QL3DIGFI.js.map +1 -0
  15. package/dist/index.d.ts +92 -239
  16. package/dist/index.js +1835 -1705
  17. package/dist/index.js.map +1 -1
  18. package/dist/{multi-session-CerO558Y.d.ts → multi-session--0z_-ut1.d.ts} +276 -7
  19. package/dist/multi-session.d.ts +4 -4
  20. package/dist/multi-session.js +6 -6
  21. package/dist/{nodes-BcyPw6Fr.d.ts → nodes-7_0rCAc4.d.ts} +2 -0
  22. package/dist/{sessionViewOptions-DQRzPuN_.d.ts → sessionViewOptions-EIBugOkf.d.ts} +1 -1
  23. package/dist/tools-presentation.d.ts +3 -3
  24. package/dist/tools-presentation.js +2 -2
  25. package/dist/tools.d.ts +5 -5
  26. package/dist/tools.js +4 -4
  27. package/dist/{types-BEXSHQG7.d.ts → types-DAkw2VOv.d.ts} +1 -1
  28. package/dist/virtual.d.ts +1 -1
  29. package/dist/virtual.js +3 -3
  30. package/package.json +4 -2
  31. package/dist/chunk-6PWGGGUK.js.map +0 -1
  32. package/dist/chunk-6Z4ZF36Z.js.map +0 -1
  33. package/dist/chunk-FL2G7SV3.js.map +0 -1
  34. package/dist/chunk-FT6UUKPS.js.map +0 -1
  35. package/dist/chunk-GBY5DJ7L.js.map +0 -1
  36. package/dist/chunk-TCKOXX7O.js.map +0 -1
@@ -15,7 +15,7 @@ import {
15
15
  extractLastToolInfoFromProgress,
16
16
  formatExploreSummaryText,
17
17
  formatThoughtDurationPrefix
18
- } from "./chunk-FL2G7SV3.js";
18
+ } from "./chunk-QL3DIGFI.js";
19
19
 
20
20
  // src/types/tree.ts
21
21
  function createEmptyTree() {
@@ -77,6 +77,8 @@ var DEFAULT_EVENT_TIERS = {
77
77
  "subagent-model-step": "collapsed",
78
78
  "hook-progress": "debug",
79
79
  "hook-finished": "debug",
80
+ "api-retry": "debug",
81
+ "assistant-turn-superseded": "main",
80
82
  "compact-start": "debug",
81
83
  "compact-end": "debug",
82
84
  "task-started": "debug",
@@ -483,23 +485,31 @@ function parseSnapshotTasks(rawTasks) {
483
485
  }
484
486
 
485
487
  // src/types/modelRetry.ts
486
- function parseModelRetryHookData(data, timestampMs) {
487
- if (data.name !== "model_retry") return null;
488
+ function parseModelRetryFields(data, timestampMs) {
488
489
  const attempt = typeof data.attempt === "number" ? data.attempt : Number(data.attempt);
489
490
  const maxRetries = typeof data.max_retries === "number" ? data.max_retries : Number(data.max_retries);
490
491
  const retryDelayMs = typeof data.retry_delay_ms === "number" ? data.retry_delay_ms : Number(data.retry_delay_ms ?? 0);
491
492
  if (!Number.isFinite(attempt) || !Number.isFinite(maxRetries)) return null;
493
+ const errorCategory = typeof data.error_category === "string" ? data.error_category : typeof data.error === "string" ? data.error : "api_error";
492
494
  return {
493
495
  attempt: Math.max(1, Math.floor(attempt)),
494
496
  maxRetries: Math.max(1, Math.floor(maxRetries)),
495
497
  retryDelayMs: Number.isFinite(retryDelayMs) ? Math.max(0, retryDelayMs) : 0,
496
- errorCategory: typeof data.error_category === "string" ? data.error_category : "api_error",
498
+ errorCategory,
497
499
  errorMessage: typeof data.error_message === "string" ? data.error_message : "",
498
500
  errorStatus: typeof data.error_status === "number" ? data.error_status : data.error_status != null ? Number(data.error_status) : null,
499
501
  phase: typeof data.phase === "string" ? data.phase : "scheduled",
500
502
  updatedAt: timestampMs
501
503
  };
502
504
  }
505
+ function parseApiRetryEventData(data, timestampMs) {
506
+ if (data.subtype !== "api_retry") return null;
507
+ return parseModelRetryFields(data, timestampMs);
508
+ }
509
+ function parseModelRetryHookData(data, timestampMs) {
510
+ if (data.name !== "model_retry") return null;
511
+ return parseModelRetryFields(data, timestampMs);
512
+ }
503
513
  function formatModelRetryCategoryLabel(category) {
504
514
  switch (category) {
505
515
  case "server_overload":
@@ -579,6 +589,38 @@ function agentToolNode(tree, parentNodeId) {
579
589
  const node = tree.byId[parentNodeId];
580
590
  return node?.kind === "tool_call" ? node : void 0;
581
591
  }
592
+ function warnSubagentOrphanParent(eventType, data) {
593
+ if (import.meta.env?.DEV) {
594
+ console.warn("[langchain_agentx_stream_ui] subagent orphan", {
595
+ eventType,
596
+ tool_call_id: data.tool_call_id,
597
+ agent_id: data.agent_id
598
+ });
599
+ }
600
+ }
601
+ function ensureSyntheticAgentToolParent(tree, parentNodeId, event, data) {
602
+ const existing = tree.byId[parentNodeId];
603
+ if (existing?.kind === "tool_call") return;
604
+ const toolCallId = parentNodeId.startsWith("tool:") ? parentNodeId.slice("tool:".length) : "";
605
+ if (!toolCallId) return;
606
+ const node = {
607
+ kind: "tool_call",
608
+ id: parentNodeId,
609
+ toolCallId,
610
+ toolName: "Agent",
611
+ input: data.subagent_type ? { subagent_type: data.subagent_type } : null,
612
+ status: "running",
613
+ startedAt: eventTimeToMs(event.timestamp),
614
+ endedAt: null,
615
+ result: null,
616
+ progress: null,
617
+ inputDelta: "",
618
+ onMainStage: true,
619
+ syntheticParent: true
620
+ };
621
+ tree.byId[parentNodeId] = node;
622
+ appendToActiveParent(tree, parentNodeId);
623
+ }
582
624
  function stepNameKey(event) {
583
625
  const step = event.step_index ?? 0;
584
626
  const name = event.tool_name ?? "unknown";
@@ -717,6 +759,7 @@ function finalizeStreamingNodes(tree) {
717
759
  }
718
760
  }
719
761
  function handleFinish(tree, event, seq) {
762
+ flushDeferredMainTextToTree(tree, event, seq);
720
763
  clearModelRetry(tree);
721
764
  const data = event.data;
722
765
  const endedAt = eventTimeToMs(event.timestamp);
@@ -787,6 +830,43 @@ function appendTaskDebugEvent(tree, event, eventIndex) {
787
830
  data: event.data
788
831
  });
789
832
  }
833
+ function findLastMainStageTextNodeId(tree) {
834
+ const childIds = getActiveChildIds(tree);
835
+ for (let i = childIds.length - 1; i >= 0; i -= 1) {
836
+ const node = tree.byId[childIds[i]];
837
+ if (node?.kind === "text") {
838
+ return node.id;
839
+ }
840
+ }
841
+ return void 0;
842
+ }
843
+ function removeMainStageTextNode(tree, nodeId) {
844
+ delete tree.byId[nodeId];
845
+ tree.rootChildren = tree.rootChildren.filter((id) => id !== nodeId);
846
+ }
847
+ function handleAssistantTurnSuperseded(tree) {
848
+ clearModelRetry(tree);
849
+ const hadDeferredPartial = Boolean(tree.deferredMainText);
850
+ tree.deferredMainText = "";
851
+ const streaming = findStreamingNode(tree, "text");
852
+ if (streaming) {
853
+ removeMainStageTextNode(tree, streaming.id);
854
+ return;
855
+ }
856
+ if (!hadDeferredPartial) {
857
+ const lastTextId = findLastMainStageTextNodeId(tree);
858
+ if (lastTextId) {
859
+ removeMainStageTextNode(tree, lastTextId);
860
+ }
861
+ }
862
+ }
863
+ function handleApiRetry(tree, event) {
864
+ const data = event.data;
865
+ const modelRetry = parseApiRetryEventData(data, eventTimeToMs(event.timestamp));
866
+ if (modelRetry) {
867
+ tree.modelRetry = modelRetry;
868
+ }
869
+ }
790
870
  function handleHookProgress(tree, event) {
791
871
  const data = event.data;
792
872
  const modelRetry = parseModelRetryHookData(data, eventTimeToMs(event.timestamp));
@@ -1184,11 +1264,19 @@ function handleToolProgress(tree, event, parentNodeId, _seq) {
1184
1264
  }
1185
1265
  });
1186
1266
  }
1187
- function handleSubagentBoundaryStart(tree, event, parentNodeId) {
1188
- const tool = agentToolNode(tree, parentNodeId);
1189
- if (!tool || !parentNodeId) return;
1267
+ function handleSubagentBoundaryStart(tree, event, parentNodeId, options) {
1190
1268
  const data = event.data;
1191
- patchToolNode(tree, parentNodeId, {
1269
+ let parentId = parentNodeId;
1270
+ if (options?.syntheticAgentToolOnSubagentStart && data.tool_call_id && (!parentId || !agentToolNode(tree, parentId))) {
1271
+ parentId = `tool:${data.tool_call_id}`;
1272
+ ensureSyntheticAgentToolParent(tree, parentId, event, data);
1273
+ }
1274
+ const tool = agentToolNode(tree, parentId);
1275
+ if (!tool || !parentId) {
1276
+ warnSubagentOrphanParent("subagent-start", event.data);
1277
+ return;
1278
+ }
1279
+ patchToolNode(tree, parentId, {
1192
1280
  subagentSessions: upsertSubagentSession(tool.subagentSessions ?? {}, {
1193
1281
  agentId: data.agent_id,
1194
1282
  subagentType: data.subagent_type,
@@ -1200,7 +1288,10 @@ function handleSubagentBoundaryStart(tree, event, parentNodeId) {
1200
1288
  }
1201
1289
  function handleSubagentBoundaryEnd(tree, event, parentNodeId) {
1202
1290
  const tool = agentToolNode(tree, parentNodeId);
1203
- if (!tool || !parentNodeId) return;
1291
+ if (!tool || !parentNodeId) {
1292
+ warnSubagentOrphanParent("subagent-end", event.data);
1293
+ return;
1294
+ }
1204
1295
  const data = event.data;
1205
1296
  const existing = tool.subagentSessions?.[data.agent_id];
1206
1297
  patchToolNode(tree, parentNodeId, {
@@ -1215,7 +1306,10 @@ function handleSubagentBoundaryEnd(tree, event, parentNodeId) {
1215
1306
  }
1216
1307
  function handleSubagentToolCall(tree, _event, parentNodeId, data) {
1217
1308
  const tool = agentToolNode(tree, parentNodeId);
1218
- if (!tool || !parentNodeId) return;
1309
+ if (!tool || !parentNodeId) {
1310
+ warnSubagentOrphanParent("subagent-tool-call", data);
1311
+ return;
1312
+ }
1219
1313
  const toolInput = data.tool_input ?? (typeof data.input === "object" ? data.input : void 0);
1220
1314
  const nestedInput = toolInput && typeof toolInput === "object" && !Array.isArray(toolInput) ? toolInput : null;
1221
1315
  const childToolCallId = typeof data.child_tool_call_id === "string" && data.child_tool_call_id || (nestedInput && typeof nestedInput.tool_call_id === "string" ? nestedInput.tool_call_id : void 0);
@@ -1233,7 +1327,10 @@ function handleSubagentToolCall(tree, _event, parentNodeId, data) {
1233
1327
  }
1234
1328
  function handleSubagentToolResult(tree, _event, parentNodeId, data) {
1235
1329
  const tool = agentToolNode(tree, parentNodeId);
1236
- if (!tool || !parentNodeId) return;
1330
+ if (!tool || !parentNodeId) {
1331
+ warnSubagentOrphanParent("subagent-tool-result", data);
1332
+ return;
1333
+ }
1237
1334
  patchToolNode(tree, parentNodeId, {
1238
1335
  subagentProgress: applySubagentToolResult(tool.subagentProgress ?? [], {
1239
1336
  agentId: data.agent_id,
@@ -1346,6 +1443,9 @@ function handleDebug(tree, event, eventIndex, parentNodeId, collectDebug) {
1346
1443
  appendTaskDebugEvent(tree, event, eventIndex);
1347
1444
  }
1348
1445
  switch (event.event_type) {
1446
+ case "api-retry":
1447
+ handleApiRetry(tree, event);
1448
+ break;
1349
1449
  case "hook-progress":
1350
1450
  handleHookProgress(tree, event);
1351
1451
  break;
@@ -1479,7 +1579,7 @@ function applyClassified(tree, classified, eventIndex, options) {
1479
1579
  handleToolProgress(tree, event, parentNodeId, seq);
1480
1580
  break;
1481
1581
  case "subagent-start":
1482
- handleSubagentBoundaryStart(tree, event, parentNodeId);
1582
+ handleSubagentBoundaryStart(tree, event, parentNodeId, options);
1483
1583
  break;
1484
1584
  case "subagent-end":
1485
1585
  handleSubagentBoundaryEnd(tree, event, parentNodeId);
@@ -1542,6 +1642,9 @@ function applyClassified(tree, classified, eventIndex, options) {
1542
1642
  handleTextEnd(tree, event);
1543
1643
  break;
1544
1644
  }
1645
+ case "assistant-turn-superseded":
1646
+ handleAssistantTurnSuperseded(tree);
1647
+ break;
1545
1648
  case "reasoning-start":
1546
1649
  if (isDroppedByEmitterRoute(event.data)) break;
1547
1650
  if (isSubagentScopedReasoningEvent(event.data)) break;
@@ -1669,6 +1772,78 @@ function replayTree(initialTree, events, options) {
1669
1772
  );
1670
1773
  }
1671
1774
 
1775
+ // src/core/workflow/workflowAuthoritySelectors.ts
1776
+ var AUTHORITY_TERMINAL = /* @__PURE__ */ new Set([
1777
+ "done",
1778
+ "error",
1779
+ "canceled",
1780
+ "partial_success"
1781
+ ]);
1782
+ function isAuthorityTerminalStatus(status) {
1783
+ return status != null && AUTHORITY_TERMINAL.has(status);
1784
+ }
1785
+ function isAuthorityTerminal(state) {
1786
+ return isAuthorityTerminalStatus(state.authority?.status);
1787
+ }
1788
+ function shouldShowGlobalSpinner(state) {
1789
+ const auth = state.authority?.status;
1790
+ if (auth === "canceled") return false;
1791
+ if (isAuthorityTerminalStatus(auth)) return false;
1792
+ if (state.display.awaitingAuthority) return false;
1793
+ if (auth == null || auth === "pending" || auth === "running") {
1794
+ return true;
1795
+ }
1796
+ const proj = state.display.projectionStatus;
1797
+ return proj === "running" || proj === "connecting";
1798
+ }
1799
+ function resolveWorkflowBanner(state) {
1800
+ if (state.display.authoritySubscribeFailed) {
1801
+ return { kind: "sync_failed", message: "\u72B6\u6001\u540C\u6B65\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5" };
1802
+ }
1803
+ if (state.display.authoritySyncFailed) {
1804
+ return { kind: "sync_failed", message: "\u540C\u6B65\u72B6\u6001\u5931\u8D25\uFF0C\u8BF7\u5237\u65B0" };
1805
+ }
1806
+ const auth = state.authority?.status;
1807
+ if (auth === "error") {
1808
+ return { kind: "authority_error", message: "Workflow \u6267\u884C\u5931\u8D25" };
1809
+ }
1810
+ if (state.snapshotHydrateFailed) {
1811
+ return {
1812
+ kind: "snapshot_unavailable",
1813
+ message: "\u65E0\u6CD5\u52A0\u8F7D projection snapshot\uFF0C\u5C55\u793A\u53EF\u80FD\u4E0D\u5B8C\u6574"
1814
+ };
1815
+ }
1816
+ if (state.display.awaitingAuthority) {
1817
+ return { kind: "awaiting_authority", message: "\u6536\u5C3E\u4E2D\u2026" };
1818
+ }
1819
+ if (auth === "partial_success") {
1820
+ const forced = state.display.terminalKind === "forced_closeout";
1821
+ return {
1822
+ kind: "partial_success",
1823
+ 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"
1824
+ };
1825
+ }
1826
+ const meta = state.authority?.metadata;
1827
+ if (auth === "done" && meta?.projection_status === "degraded") {
1828
+ const dropped = meta.projection_dropped_count;
1829
+ const suffix = dropped != null && dropped > 0 ? `\uFF08\u7EA6 ${dropped} \u6761\u4E8B\u4EF6\u672A\u5B8C\u6574\u5C55\u793A\uFF09` : "";
1830
+ return {
1831
+ kind: "projection_degraded",
1832
+ message: `\u5C55\u793A\u53EF\u80FD\u4E0D\u5B8C\u6574${suffix}`
1833
+ };
1834
+ }
1835
+ if (state.display.terminalKind === "forced_closeout" && auth === "done") {
1836
+ return { kind: "forced_closeout", message: "Workflow \u5DF2\u7ED3\u675F\uFF08\u90E8\u5206\u5BB9\u5668\u672A\u6B63\u5E38\u5173\u95ED\uFF09" };
1837
+ }
1838
+ return { kind: "none", message: "" };
1839
+ }
1840
+ function getDisplayProjectionStatus(state) {
1841
+ return state.display.projectionStatus;
1842
+ }
1843
+ function applyAuthoritySnapshotToState(state, snapshot) {
1844
+ return { ...state, authority: snapshot };
1845
+ }
1846
+
1672
1847
  // src/core/projection/renderModel.ts
1673
1848
  var ProjectionContext = class _ProjectionContext {
1674
1849
  displayMode;
@@ -3726,6 +3901,14 @@ function useSessionMeta() {
3726
3901
  const store = useSessionStoreApi();
3727
3902
  return useStore5(store, (state) => state.tree.meta);
3728
3903
  }
3904
+ function useAgentAuthority() {
3905
+ const store = useSessionStoreApi();
3906
+ return useStore5(store, (state) => state.authority);
3907
+ }
3908
+ function useAgentAuthoritySubscribeFailed() {
3909
+ const store = useSessionStoreApi();
3910
+ return useStore5(store, (state) => state.authoritySubscribeFailed);
3911
+ }
3729
3912
 
3730
3913
  // src/view/hooks/useMinDisplayTime.ts
3731
3914
  import { useEffect, useRef, useState } from "react";
@@ -3891,6 +4074,18 @@ function SystemSummaryNode({ summaryText }) {
3891
4074
  return /* @__PURE__ */ jsx3("div", { className: "lax-system-summary", "data-kind": "system_summary", children: summaryText });
3892
4075
  }
3893
4076
 
4077
+ // src/core/agent/agentAuthoritySelectors.ts
4078
+ function shouldShowAgentSpinner(state) {
4079
+ if (!state.authorityBindingActive) {
4080
+ const status = state.tree.status;
4081
+ return status === "running" || status === "connecting";
4082
+ }
4083
+ const auth = state.authority?.status;
4084
+ if (auth === "canceled") return false;
4085
+ if (isAuthorityTerminalStatus(auth)) return false;
4086
+ return true;
4087
+ }
4088
+
3894
4089
  // src/view/TaskList.tsx
3895
4090
  import { useEffect as useEffect3, useMemo as useMemo4, useRef as useRef2, useState as useState3 } from "react";
3896
4091
 
@@ -4769,7 +4964,11 @@ function Spinner({
4769
4964
  }) {
4770
4965
  const status = useSessionStatus();
4771
4966
  const store = useSessionStoreApi();
4772
- const isRunning = status === "running" || status === "connecting";
4967
+ const showSpinner = useSyncExternalStore(
4968
+ (callback) => store.subscribe(callback),
4969
+ () => shouldShowAgentSpinner(store.getState())
4970
+ );
4971
+ const isRunning = showSpinner;
4773
4972
  const activeRoundId = useSyncExternalStore(
4774
4973
  (callback) => store.subscribe(callback),
4775
4974
  () => store.getState().tree.activeRoundId
@@ -5438,6 +5637,12 @@ export {
5438
5637
  getChildIds,
5439
5638
  replayEvents,
5440
5639
  replayTree,
5640
+ isAuthorityTerminalStatus,
5641
+ isAuthorityTerminal,
5642
+ shouldShowGlobalSpinner,
5643
+ resolveWorkflowBanner,
5644
+ getDisplayProjectionStatus,
5645
+ applyAuthoritySnapshotToState,
5441
5646
  ProjectionContext,
5442
5647
  createProjectionContext,
5443
5648
  DEFAULT_SESSION_VIEW_OPTIONS,
@@ -5489,11 +5694,14 @@ export {
5489
5694
  useSessionStatus,
5490
5695
  useInternalErrors,
5491
5696
  useSessionMeta,
5697
+ useAgentAuthority,
5698
+ useAgentAuthoritySubscribeFailed,
5492
5699
  MIN_HINT_DISPLAY_MS,
5493
5700
  useMinDisplayTime,
5494
5701
  TimelineItem,
5495
5702
  CollapsedExploreNode,
5496
5703
  SystemSummaryNode,
5704
+ shouldShowAgentSpinner,
5497
5705
  TaskList,
5498
5706
  Spinner,
5499
5707
  formatTaskFooterLabel,
@@ -5507,4 +5715,4 @@ export {
5507
5715
  VirtualTimeline,
5508
5716
  SessionTimeline
5509
5717
  };
5510
- //# sourceMappingURL=chunk-6PWGGGUK.js.map
5718
+ //# sourceMappingURL=chunk-AY7QLXFB.js.map