langchain_agentx_stream_ui 0.6.4 → 0.7.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 (37) hide show
  1. package/dist/{AskUserQuestionToolBody-J8MqSUEs.d.ts → AskUserQuestionToolBody-C6J742a2.d.ts} +2 -2
  2. package/dist/{MarkdownBlock-DeICJUtu.d.ts → MarkdownBlock-B_wNhCB4.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-YHCK76OU.js → chunk-7TBPTIAP.js} +78 -37
  6. package/dist/chunk-7TBPTIAP.js.map +1 -0
  7. package/dist/{chunk-6Z4ZF36Z.js → chunk-DP7V33X7.js} +1 -1
  8. package/dist/chunk-DP7V33X7.js.map +1 -0
  9. package/dist/{chunk-O5GERXTY.js → chunk-EFJMU4WW.js} +213 -23
  10. package/dist/chunk-EFJMU4WW.js.map +1 -0
  11. package/dist/{chunk-GYFC2DI7.js → chunk-GLUQUP3A.js} +218 -5
  12. package/dist/chunk-GLUQUP3A.js.map +1 -0
  13. package/dist/{chunk-5XELRP3S.js → chunk-OV6UUIA3.js} +4 -4
  14. package/dist/chunk-OV6UUIA3.js.map +1 -0
  15. package/dist/default.css +16 -0
  16. package/dist/index.d.ts +36 -14
  17. package/dist/index.js +221 -18
  18. package/dist/index.js.map +1 -1
  19. package/dist/{multi-session-4GMo1sLl.d.ts → multi-session-DhTXvNpi.d.ts} +22 -3
  20. package/dist/multi-session.d.ts +4 -4
  21. package/dist/multi-session.js +6 -6
  22. package/dist/{nodes-7_0rCAc4.d.ts → nodes-MpVB9C5d.d.ts} +7 -1
  23. package/dist/{sessionViewOptions-EIBugOkf.d.ts → sessionViewOptions-DeTrGjRM.d.ts} +1 -1
  24. package/dist/tools-presentation.d.ts +3 -3
  25. package/dist/tools-presentation.js +2 -2
  26. package/dist/tools.d.ts +5 -5
  27. package/dist/tools.js +4 -4
  28. package/dist/{types-DAkw2VOv.d.ts → types-SVtInovH.d.ts} +1 -1
  29. package/dist/virtual.d.ts +1 -1
  30. package/dist/virtual.js +3 -3
  31. package/package.json +1 -1
  32. package/dist/chunk-5XELRP3S.js.map +0 -1
  33. package/dist/chunk-6Z4ZF36Z.js.map +0 -1
  34. package/dist/chunk-GBY5DJ7L.js.map +0 -1
  35. package/dist/chunk-GYFC2DI7.js.map +0 -1
  36. package/dist/chunk-O5GERXTY.js.map +0 -1
  37. package/dist/chunk-YHCK76OU.js.map +0 -1
@@ -10,12 +10,18 @@ import {
10
10
  SILENT_TASK_TOOL_NAMES,
11
11
  SubagentTranscriptBlock,
12
12
  Write,
13
+ classifyFinishErrorPresentation,
14
+ classifyToolCancelSoftKind,
13
15
  coerceSubagentProgressEntries,
14
16
  createDefaultToolRegistry,
15
17
  extractLastToolInfoFromProgress,
18
+ extractToolCancelSignals,
16
19
  formatExploreSummaryText,
17
- formatThoughtDurationPrefix
18
- } from "./chunk-GYFC2DI7.js";
20
+ formatThoughtDurationPrefix,
21
+ resolveHookStoppedMessage,
22
+ resolveInterruptDisplayText,
23
+ resolveToolCancelDisplayText
24
+ } from "./chunk-GLUQUP3A.js";
19
25
 
20
26
  // src/types/tree.ts
21
27
  function createEmptyTree() {
@@ -85,6 +91,8 @@ var DEFAULT_EVENT_TIERS = {
85
91
  "task-progress": "debug",
86
92
  "task-notification-enqueued": "debug",
87
93
  "task-notification-consumed": "debug",
94
+ /** 与 subagent-end 同级 collapsed(不可当可丢 debug) */
95
+ "task-notification": "collapsed",
88
96
  "task-terminated": "debug",
89
97
  "task-list-snapshot": "state",
90
98
  error: "main",
@@ -113,7 +121,7 @@ function resolveToolParentId(event, ctx, eventIndex) {
113
121
  return toolNodeIdFromEvent(event, eventIndex);
114
122
  }
115
123
  function isSubagentFoldEvent(event) {
116
- if (event.event_type === "subagent-start" || event.event_type === "subagent-end" || event.event_type === "subagent-tool-call" || event.event_type === "subagent-tool-result" || event.event_type === "subagent-transcript-message" || event.event_type === "subagent-model-step") {
124
+ if (event.event_type === "subagent-start" || event.event_type === "subagent-end" || event.event_type === "subagent-tool-call" || event.event_type === "subagent-tool-result" || event.event_type === "subagent-transcript-message" || event.event_type === "subagent-model-step" || event.event_type === "task-notification") {
117
125
  return true;
118
126
  }
119
127
  if (event.event_type === "tool-progress") {
@@ -124,7 +132,12 @@ function isSubagentFoldEvent(event) {
124
132
  }
125
133
  function resolveAgentToolParentId(event) {
126
134
  const data = event.data;
127
- if (data.tool_call_id) return `tool:${data.tool_call_id}`;
135
+ if (typeof data.tool_call_id === "string" && data.tool_call_id) {
136
+ return `tool:${data.tool_call_id}`;
137
+ }
138
+ if (typeof data.tool_use_id === "string" && data.tool_use_id) {
139
+ return `tool:${data.tool_use_id}`;
140
+ }
128
141
  return void 0;
129
142
  }
130
143
  function classifyEvent(event, ctx, overrides, eventIndex = 0) {
@@ -288,7 +301,7 @@ function updateParallelAgentTextGate(tree) {
288
301
  }
289
302
  const allTerminal = ids.every((id) => {
290
303
  const node = findAgentToolCallNodeByCallId(tree, id);
291
- return node != null && (node.status === "done" || node.status === "failed");
304
+ return node != null && (node.status === "done" || node.status === "failed" || node.status === "cancelled");
292
305
  });
293
306
  if (allTerminal) {
294
307
  return { ...tree, parallelAgentTextGateCallIds: null };
@@ -525,6 +538,116 @@ function formatModelRetryCategoryLabel(category) {
525
538
  }
526
539
  }
527
540
 
541
+ // src/core/taskNotification.ts
542
+ function trimStr(value) {
543
+ return typeof value === "string" ? value.trim() : "";
544
+ }
545
+ function markTaskNotificationClosed(tree, taskId) {
546
+ tree.meta.taskNotificationClosedIds = {
547
+ ...tree.meta.taskNotificationClosedIds ?? {},
548
+ [taskId]: true
549
+ };
550
+ }
551
+ function isTaskNotificationClosed(tree, taskId) {
552
+ return tree.meta.taskNotificationClosedIds?.[taskId] === true;
553
+ }
554
+ function findTaskNotificationTarget(tree, data) {
555
+ const toolUseId = trimStr(data.tool_use_id);
556
+ const agentId = trimStr(data.agent_id);
557
+ const taskId = trimStr(data.task_id);
558
+ if (toolUseId) {
559
+ const byTool = findAgentToolCallNodeByCallId(tree, toolUseId);
560
+ if (byTool) {
561
+ return { nodeId: byTool.id, agentId: agentId || taskId || null };
562
+ }
563
+ }
564
+ const sessionKey = agentId || taskId;
565
+ if (sessionKey) {
566
+ for (const node of Object.values(tree.byId)) {
567
+ if (node?.kind !== "tool_call" || node.toolName !== "Agent") continue;
568
+ if (node.subagentSessions?.[sessionKey]) {
569
+ return { nodeId: node.id, agentId: sessionKey };
570
+ }
571
+ }
572
+ }
573
+ if (taskId) {
574
+ const byTaskAsCall = findAgentToolCallNodeByCallId(tree, taskId);
575
+ if (byTaskAsCall) {
576
+ return { nodeId: byTaskAsCall.id, agentId: agentId || null };
577
+ }
578
+ }
579
+ return null;
580
+ }
581
+ function finalizeRunningProgressForAgent(tool, agentId, terminal) {
582
+ const progress = tool.subagentProgress;
583
+ if (!progress?.length || !agentId) return progress;
584
+ return progress.map(
585
+ (entry) => entry.agentId === agentId && entry.status === "running" ? { ...entry, status: terminal } : entry
586
+ );
587
+ }
588
+ function hasRunningSession(sessions) {
589
+ return Object.values(sessions).some((marker) => marker.status === "running");
590
+ }
591
+ function applyTaskNotification(tree, data, endedAt) {
592
+ const taskId = trimStr(data.task_id);
593
+ if (!taskId) return false;
594
+ if (isTaskNotificationClosed(tree, taskId)) return false;
595
+ const status = data.status;
596
+ if (status !== "stopped" && status !== "completed" && status !== "failed") {
597
+ return false;
598
+ }
599
+ const target = findTaskNotificationTarget(tree, data);
600
+ if (!target) return false;
601
+ const tool = tree.byId[target.nodeId];
602
+ if (!tool || tool.kind !== "tool_call") return false;
603
+ const agentKey = target.agentId;
604
+ let nextSessions = tool.subagentSessions ?? {};
605
+ let sessionChanged = false;
606
+ if (agentKey) {
607
+ const existing = nextSessions[agentKey];
608
+ if (!existing || existing.status === "running") {
609
+ nextSessions = upsertSubagentSession(nextSessions, {
610
+ agentId: agentKey,
611
+ subagentType: existing?.subagentType,
612
+ status: "done",
613
+ startedAt: existing?.startedAt ?? endedAt,
614
+ endedAt
615
+ });
616
+ sessionChanged = true;
617
+ }
618
+ }
619
+ const progressTerminal = status === "completed" ? "completed" : "error";
620
+ const hasRunningProgress = !!agentKey && !!tool.subagentProgress?.some(
621
+ (entry) => entry.agentId === agentKey && entry.status === "running"
622
+ );
623
+ const nextProgress = hasRunningProgress ? finalizeRunningProgressForAgent(tool, agentKey, progressTerminal) : tool.subagentProgress;
624
+ const progressChanged = nextProgress !== tool.subagentProgress;
625
+ let nextToolStatus = tool.status;
626
+ let nextEndedAt = tool.endedAt;
627
+ let toolStatusChanged = false;
628
+ if (tool.status === "running") {
629
+ const shouldCloseParent = !agentKey || !hasRunningSession(nextSessions);
630
+ if (shouldCloseParent) {
631
+ nextToolStatus = status === "completed" ? "done" : "failed";
632
+ nextEndedAt = endedAt;
633
+ toolStatusChanged = true;
634
+ }
635
+ }
636
+ if (!sessionChanged && !progressChanged && !toolStatusChanged) {
637
+ markTaskNotificationClosed(tree, taskId);
638
+ return false;
639
+ }
640
+ tree.byId[target.nodeId] = {
641
+ ...tool,
642
+ status: nextToolStatus,
643
+ endedAt: nextEndedAt,
644
+ subagentSessions: nextSessions,
645
+ subagentProgress: nextProgress
646
+ };
647
+ markTaskNotificationClosed(tree, taskId);
648
+ return true;
649
+ }
650
+
528
651
  // src/core/reducer.ts
529
652
  function isInternalTool(toolName) {
530
653
  return INTERNAL_TOOL_NAMES.has(toolName);
@@ -722,17 +845,34 @@ function resolveFinishErrorMessage(data) {
722
845
  return "Agent finished with an error";
723
846
  }
724
847
  function appendFinishErrorNode(tree, event, data, seq) {
725
- const { message, type } = resolveErrorEventFields({
726
- message: resolveFinishErrorMessage(data),
727
- type: typeof data.error_kind === "string" && data.error_kind || typeof data.terminal_reason === "string" && data.terminal_reason || void 0
728
- });
848
+ const presentation = classifyFinishErrorPresentation(data);
849
+ let message;
850
+ let type;
851
+ let variant = "error";
852
+ if (presentation === "interrupt") {
853
+ message = resolveInterruptDisplayText(data);
854
+ type = typeof data.error_kind === "string" && data.error_kind || typeof data.terminal_reason === "string" && data.terminal_reason || "user_cancelled";
855
+ variant = "interrupt";
856
+ } else if (presentation === "hook_stopped") {
857
+ message = resolveHookStoppedMessage(data);
858
+ type = "hook_stopped";
859
+ variant = "hook_stopped";
860
+ } else {
861
+ const resolved = resolveErrorEventFields({
862
+ message: resolveFinishErrorMessage(data),
863
+ type: typeof data.error_kind === "string" && data.error_kind || typeof data.terminal_reason === "string" && data.terminal_reason || void 0
864
+ });
865
+ message = resolved.message;
866
+ type = resolved.type;
867
+ }
729
868
  const id = `finish-error:${seq}`;
730
869
  const node = {
731
870
  kind: "error",
732
871
  id,
733
872
  message,
734
873
  errorType: type,
735
- startedAt: eventTimeToMs(event.timestamp)
874
+ startedAt: eventTimeToMs(event.timestamp),
875
+ variant
736
876
  };
737
877
  tree.byId[id] = node;
738
878
  appendMainStageChild(tree, id, event, seq);
@@ -1183,22 +1323,47 @@ function handleToolResult(tree, event, seq) {
1183
1323
  }
1184
1324
  function handleToolError(tree, event, seq) {
1185
1325
  const id = toolNodeId(tree, event);
1186
- const data = event.data;
1326
+ const raw = event.data ?? {};
1187
1327
  const existing = tree.byId[id];
1188
- const toolName = resolveToolName(event, data, existing);
1189
- const dataRecord = data;
1328
+ const toolName = resolveToolName(event, raw, existing);
1329
+ const dataRecord = raw;
1190
1330
  const isSubagentLeak = resolveSubagentToolLeak(tree, dataRecord, toolName, existing);
1191
1331
  const isHidden = isInternalTool(toolName) || existing?.hidden === true || isSubagentLeak;
1192
- const failedResult = {
1332
+ const cancelSignals = extractToolCancelSignals(raw);
1333
+ const softKind = classifyToolCancelSoftKind(cancelSignals);
1334
+ const cancelled = softKind != null;
1335
+ const message = cancelSignals.message || typeof raw.message === "string" && raw.message || typeof raw.error === "string" && raw.error || "Unknown error";
1336
+ const errType = cancelSignals.error_type || cancelSignals.type || (typeof raw.type === "string" ? raw.type : void 0);
1337
+ const failedResult = cancelled ? {
1338
+ schema_version: "2",
1339
+ status: "error",
1340
+ summary: resolveToolCancelDisplayText(softKind),
1341
+ payload: cancelSignals.payload ?? message,
1342
+ blocks: [],
1343
+ artifacts: [],
1344
+ hints: null,
1345
+ meta: {
1346
+ error_kind: cancelSignals.error_kind ?? (softKind === "canceled" ? "user_cancelled" : "aborted"),
1347
+ terminal_state: "cancelled",
1348
+ cancel_ui_kind: softKind
1349
+ },
1350
+ // 保留 type=cancelled,供 AgentToolBody / finalize 识别;文案用 soft Interrupted
1351
+ error: {
1352
+ message: resolveToolCancelDisplayText(softKind),
1353
+ type: "cancelled"
1354
+ },
1355
+ truncated: false,
1356
+ overflow_file: null
1357
+ } : {
1193
1358
  schema_version: "1",
1194
1359
  status: "failed",
1195
- summary: data.message,
1360
+ summary: message,
1196
1361
  payload: null,
1197
1362
  blocks: [],
1198
1363
  artifacts: [],
1199
1364
  hints: null,
1200
1365
  meta: null,
1201
- error: { message: data.message, type: data.type },
1366
+ error: { message, type: errType },
1202
1367
  truncated: false,
1203
1368
  overflow_file: null
1204
1369
  };
@@ -1207,7 +1372,7 @@ function handleToolError(tree, event, seq) {
1207
1372
  id,
1208
1373
  event,
1209
1374
  {
1210
- status: "failed",
1375
+ status: cancelled ? "cancelled" : "failed",
1211
1376
  endedAt: eventTimeToMs(event.timestamp),
1212
1377
  result: failedResult,
1213
1378
  hidden: isHidden || void 0
@@ -1266,6 +1431,13 @@ function handleToolProgress(tree, event, parentNodeId, _seq) {
1266
1431
  }
1267
1432
  });
1268
1433
  }
1434
+ function handleTaskNotification(tree, event) {
1435
+ applyTaskNotification(
1436
+ tree,
1437
+ event.data,
1438
+ eventTimeToMs(event.timestamp)
1439
+ );
1440
+ }
1269
1441
  function handleSubagentBoundaryStart(tree, event, parentNodeId, options) {
1270
1442
  const data = event.data;
1271
1443
  let parentId = parentNodeId;
@@ -1601,6 +1773,9 @@ function applyClassified(tree, classified, eventIndex, options) {
1601
1773
  break;
1602
1774
  case "subagent-model-step":
1603
1775
  break;
1776
+ case "task-notification":
1777
+ handleTaskNotification(tree, event);
1778
+ break;
1604
1779
  case "start-step":
1605
1780
  handleStepStart(tree, event, parentNodeId, seq);
1606
1781
  break;
@@ -1681,13 +1856,17 @@ function applyClassified(tree, classified, eventIndex, options) {
1681
1856
  case "error": {
1682
1857
  const data = event.data;
1683
1858
  const { message, type } = resolveErrorEventFields(data);
1859
+ const softKind = classifyToolCancelSoftKind(
1860
+ extractToolCancelSignals(data)
1861
+ );
1684
1862
  const id = `error:${seq}`;
1685
1863
  const node = {
1686
1864
  kind: "error",
1687
1865
  id,
1688
- message,
1689
- errorType: type,
1690
- startedAt: eventTimeToMs(event.timestamp)
1866
+ message: softKind ? resolveToolCancelDisplayText(softKind) : message,
1867
+ errorType: softKind ? "cancelled" : type,
1868
+ startedAt: eventTimeToMs(event.timestamp),
1869
+ ...softKind ? { variant: "interrupt" } : {}
1691
1870
  };
1692
1871
  tree.byId[id] = node;
1693
1872
  appendMainStageChild(tree, id, event, seq);
@@ -1806,6 +1985,9 @@ function resolveWorkflowBanner(state) {
1806
1985
  return { kind: "sync_failed", message: "\u540C\u6B65\u72B6\u6001\u5931\u8D25\uFF0C\u8BF7\u5237\u65B0" };
1807
1986
  }
1808
1987
  const auth = state.authority?.status;
1988
+ if (auth === "canceled") {
1989
+ return { kind: "canceled", message: "\u5DF2\u53D6\u6D88" };
1990
+ }
1809
1991
  if (auth === "error") {
1810
1992
  return { kind: "authority_error", message: "Workflow \u6267\u884C\u5931\u8D25" };
1811
1993
  }
@@ -3089,10 +3271,10 @@ function toolUseEntry(entry) {
3089
3271
  }
3090
3272
  function isResolved(payload) {
3091
3273
  const status = payload.status;
3092
- return status === "done" || status === "failed";
3274
+ return status === "done" || status === "failed" || status === "cancelled";
3093
3275
  }
3094
3276
  function isErrored(payload) {
3095
- return payload.status === "failed" || payload.is_error === true || payload.error != null;
3277
+ return (payload.status === "failed" || payload.is_error === true || payload.error != null) && payload.status !== "cancelled";
3096
3278
  }
3097
3279
  var GroupedToolUseAccumulator = class {
3098
3280
  group(entries) {
@@ -4093,6 +4275,13 @@ function shouldShowAgentSpinner(state) {
4093
4275
  if (isAuthorityTerminalStatus(auth)) return false;
4094
4276
  return true;
4095
4277
  }
4278
+ function isAgentInputLocked(state) {
4279
+ if (!state.authorityBindingActive) {
4280
+ const status = state.tree.status;
4281
+ return status === "running" || status === "connecting";
4282
+ }
4283
+ return !isAuthorityTerminalStatus(state.authority?.status);
4284
+ }
4096
4285
 
4097
4286
  // src/view/TaskList.tsx
4098
4287
  import { useEffect as useEffect3, useMemo as useMemo4, useRef as useRef2, useState as useState3 } from "react";
@@ -5700,6 +5889,7 @@ export {
5700
5889
  CollapsedExploreNode,
5701
5890
  SystemSummaryNode,
5702
5891
  shouldShowAgentSpinner,
5892
+ isAgentInputLocked,
5703
5893
  TaskList,
5704
5894
  Spinner,
5705
5895
  formatTaskFooterLabel,
@@ -5713,4 +5903,4 @@ export {
5713
5903
  VirtualTimeline,
5714
5904
  SessionTimeline
5715
5905
  };
5716
- //# sourceMappingURL=chunk-O5GERXTY.js.map
5906
+ //# sourceMappingURL=chunk-EFJMU4WW.js.map