langchain_agentx_stream_ui 0.1.3 → 0.1.9

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.
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  Agent,
3
+ AgentProgressLines,
3
4
  Bash,
4
5
  Edit,
5
6
  Glob,
@@ -7,9 +8,12 @@ import {
7
8
  INTERNAL_TOOL_NAMES,
8
9
  Read,
9
10
  SILENT_TASK_TOOL_NAMES,
11
+ SubagentTranscriptBlock,
10
12
  Write,
11
- createDefaultToolRegistry
12
- } from "./chunk-MHK53ZHC.js";
13
+ coerceSubagentProgressEntries,
14
+ createDefaultToolRegistry,
15
+ extractLastToolInfoFromProgress
16
+ } from "./chunk-7CLAU74Y.js";
13
17
 
14
18
  // src/types/tree.ts
15
19
  function createEmptyTree() {
@@ -37,7 +41,9 @@ function createEmptyTree() {
37
41
  completed: 0,
38
42
  customMessage: null
39
43
  },
40
- modelRetry: null
44
+ modelRetry: null,
45
+ parallelAgentTextGateCallIds: null,
46
+ deferredMainText: ""
41
47
  };
42
48
  }
43
49
 
@@ -65,6 +71,7 @@ var DEFAULT_EVENT_TIERS = {
65
71
  "subagent-end": "collapsed",
66
72
  "subagent-tool-call": "collapsed",
67
73
  "subagent-tool-result": "collapsed",
74
+ "subagent-transcript-message": "collapsed",
68
75
  "subagent-model-step": "collapsed",
69
76
  "hook-progress": "debug",
70
77
  "hook-finished": "debug",
@@ -102,7 +109,7 @@ function resolveToolParentId(event, ctx, eventIndex) {
102
109
  return toolNodeIdFromEvent(event, eventIndex);
103
110
  }
104
111
  function isSubagentFoldEvent(event) {
105
- 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-model-step") {
112
+ 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") {
106
113
  return true;
107
114
  }
108
115
  if (event.event_type === "tool-progress") {
@@ -132,11 +139,30 @@ function classifyEvent(event, ctx, overrides, eventIndex = 0) {
132
139
  return { event, tier, parentNodeId };
133
140
  }
134
141
 
142
+ // src/core/mainTextDefer.ts
143
+ function deferMainText(buffer, text) {
144
+ if (!text) return buffer ?? "";
145
+ return (buffer ?? "") + text;
146
+ }
147
+ function flushDeferredMainText(buffer) {
148
+ return buffer ?? "";
149
+ }
150
+
135
151
  // src/core/eventVisibility.ts
136
152
  var SUBAGENT_LEAK_FOLD_TOOLS = /* @__PURE__ */ new Set(["Bash", "Read", "Glob", "Grep"]);
137
153
  function isSubagentLeakFoldToolName(toolName) {
138
154
  return SUBAGENT_LEAK_FOLD_TOOLS.has(toolName);
139
155
  }
156
+ function findAgentToolCallNodeByCallId(tree, callId) {
157
+ const trimmed = callId.trim();
158
+ if (!trimmed) return null;
159
+ for (const node of Object.values(tree.byId)) {
160
+ if (node.kind !== "tool_call" || node.toolName !== "Agent") continue;
161
+ const id = (node.toolCallId ?? node.id.replace(/^tool:/, "")).trim();
162
+ if (id === trimmed) return node;
163
+ }
164
+ return null;
165
+ }
140
166
  function getRunningAgentParentCallIds(tree) {
141
167
  const ids = [];
142
168
  const seen = /* @__PURE__ */ new Set();
@@ -217,6 +243,65 @@ function isSubagentScopedTextEvent(data) {
217
243
  function isSubagentScopedReasoningEvent(data) {
218
244
  return isSubagentScopedTextEvent(data);
219
245
  }
246
+ var EXPLICIT_MAIN_QUERY_SOURCES = /* @__PURE__ */ new Set([
247
+ "repl_main",
248
+ "repl_main_thread",
249
+ "main_thread"
250
+ ]);
251
+ function isExplicitMainOrchestratorText(data) {
252
+ if (!data) return false;
253
+ const meta = bridgeEventDisplayMetadata(data);
254
+ const qs = meta?.query_source ?? data.query_source;
255
+ if (typeof qs === "string") {
256
+ const trimmed = qs.trim();
257
+ if (trimmed && !isAgentSubagentQuerySource(trimmed)) {
258
+ if (EXPLICIT_MAIN_QUERY_SOURCES.has(trimmed)) return true;
259
+ if (trimmed.startsWith("repl:")) return true;
260
+ }
261
+ }
262
+ if (data.emitter_route === "main") return true;
263
+ if (meta?.emitter_route === "main") return true;
264
+ return false;
265
+ }
266
+ function isParallelAgentTextGateActive(tree) {
267
+ const latched = tree.parallelAgentTextGateCallIds;
268
+ if (latched && latched.length >= 2) {
269
+ return latched.some((id) => {
270
+ const node = findAgentToolCallNodeByCallId(tree, id);
271
+ return !node || node.status === "running";
272
+ });
273
+ }
274
+ return getRunningAgentParentCallIds(tree).length >= 2;
275
+ }
276
+ function updateParallelAgentTextGate(tree) {
277
+ const running = getRunningAgentParentCallIds(tree);
278
+ let ids = tree.parallelAgentTextGateCallIds ?? [];
279
+ if (running.length >= 2) {
280
+ ids = [.../* @__PURE__ */ new Set([...ids, ...running])];
281
+ }
282
+ if (ids.length < 2) {
283
+ return tree.parallelAgentTextGateCallIds === null ? tree : { ...tree, parallelAgentTextGateCallIds: null };
284
+ }
285
+ const allTerminal = ids.every((id) => {
286
+ const node = findAgentToolCallNodeByCallId(tree, id);
287
+ return node != null && (node.status === "done" || node.status === "failed");
288
+ });
289
+ if (allTerminal) {
290
+ return { ...tree, parallelAgentTextGateCallIds: null };
291
+ }
292
+ const nextIds = [...ids];
293
+ if (tree.parallelAgentTextGateCallIds?.length === nextIds.length && tree.parallelAgentTextGateCallIds.every((id, i) => id === nextIds[i])) {
294
+ return tree;
295
+ }
296
+ return { ...tree, parallelAgentTextGateCallIds: nextIds };
297
+ }
298
+ function shouldDropParallelSubagentText(tree, data) {
299
+ if (!isParallelAgentTextGateActive(tree)) return false;
300
+ if (!data) return false;
301
+ if (isSubagentScopedTextEvent(data)) return true;
302
+ if (isExplicitMainOrchestratorText(data)) return false;
303
+ return true;
304
+ }
220
305
  function isDroppedByEmitterRoute(data) {
221
306
  if (!data) return false;
222
307
  if (isDropRouteValue(data.emitter_route)) return true;
@@ -296,6 +381,56 @@ function upsertSubagentSession(sessions, marker) {
296
381
  return { ...sessions, [marker.agentId]: marker };
297
382
  }
298
383
 
384
+ // src/core/subagentTranscriptLane.ts
385
+ function readField(row, camel, snake) {
386
+ const camelValue = row[camel];
387
+ if (camelValue !== void 0 && camelValue !== null) return camelValue;
388
+ const snakeValue = row[snake];
389
+ if (snakeValue !== void 0 && snakeValue !== null) return snakeValue;
390
+ return void 0;
391
+ }
392
+ function appendSubagentTranscriptMessage(entries, payload) {
393
+ const agentId = payload.agentId.trim();
394
+ if (!agentId) return entries;
395
+ const messageKind = payload.messageKind;
396
+ if (messageKind !== "assistant" && messageKind !== "user") return entries;
397
+ if (!payload.message || typeof payload.message !== "object") return entries;
398
+ return [
399
+ ...entries,
400
+ {
401
+ agentId,
402
+ messageKind,
403
+ message: payload.message,
404
+ step: payload.step,
405
+ toolName: payload.toolName,
406
+ subagentType: payload.subagentType
407
+ }
408
+ ];
409
+ }
410
+ function coerceSubagentTranscriptEntries(raw) {
411
+ if (!Array.isArray(raw)) return [];
412
+ const entries = [];
413
+ for (const item of raw) {
414
+ if (item == null || typeof item !== "object" || Array.isArray(item)) continue;
415
+ const row = item;
416
+ const agentId = readField(row, "agentId", "agent_id");
417
+ const kindRaw = readField(row, "messageKind", "message_kind");
418
+ const message = readField(row, "message", "message");
419
+ if (!agentId || !message) continue;
420
+ const messageKind = kindRaw === "user" ? "user" : kindRaw === "assistant" ? "assistant" : null;
421
+ if (!messageKind) continue;
422
+ entries.push({
423
+ agentId,
424
+ messageKind,
425
+ message,
426
+ step: readField(row, "step", "step"),
427
+ toolName: readField(row, "toolName", "tool_name"),
428
+ subagentType: readField(row, "subagentType", "subagent_type")
429
+ });
430
+ }
431
+ return entries;
432
+ }
433
+
299
434
  // src/core/taskSnapshot.ts
300
435
  var OPEN_TASK_STATUSES = /* @__PURE__ */ new Set(["pending", "in_progress"]);
301
436
  function normalizeTaskStatus(raw) {
@@ -514,6 +649,9 @@ function appendStreamChunk(current, data) {
514
649
  return (current ?? "") + streamChunk(data);
515
650
  }
516
651
  function handleStart(tree, event) {
652
+ if (tree.status === "done" || tree.status === "error") {
653
+ return;
654
+ }
517
655
  tree.status = "running";
518
656
  tree.meta.startedAt = eventTimeToMs(event.timestamp);
519
657
  if (event.session_id) tree.meta.sessionId = event.session_id;
@@ -578,10 +716,12 @@ function handleFinish(tree, event, seq) {
578
716
  appendFinishErrorNode(tree, event, data, seq);
579
717
  finalizeRunningToolCalls(tree, endedAt, "failed");
580
718
  finalizeStreamingNodes(tree);
719
+ tree.activeRoundId = null;
581
720
  return;
582
721
  }
583
722
  finalizeRunningToolCalls(tree, endedAt, "done");
584
723
  finalizeStreamingNodes(tree);
724
+ tree.activeRoundId = null;
585
725
  tree.status = "done";
586
726
  }
587
727
  var TASK_DEBUG_EVENT_TYPES = /* @__PURE__ */ new Set([
@@ -685,6 +825,26 @@ function handleHookFinished(tree, event) {
685
825
  };
686
826
  }
687
827
  }
828
+ function extractDeferText(data) {
829
+ if (typeof data.text === "string") return data.text;
830
+ if (typeof data.delta === "string") return data.delta;
831
+ return "";
832
+ }
833
+ function flushDeferredMainTextToTree(tree, event, seq) {
834
+ const text = flushDeferredMainText(tree.deferredMainText);
835
+ tree.deferredMainText = "";
836
+ if (!text) return;
837
+ const id = `text:defer-${seq}`;
838
+ const node = {
839
+ kind: "text",
840
+ id,
841
+ accumulated: text,
842
+ status: "done",
843
+ startedAt: eventTimeToMs(event.timestamp)
844
+ };
845
+ tree.byId[id] = node;
846
+ appendMainStageChild(tree, id, event, seq);
847
+ }
688
848
  function handleTextStart(tree, event, seq) {
689
849
  clearModelRetry(tree);
690
850
  const id = `text:${seq}`;
@@ -768,6 +928,7 @@ function handleReasoningEnd(tree, event) {
768
928
  elapsedSeconds,
769
929
  isCollapsible: true
770
930
  };
931
+ tree.activeRoundId = null;
771
932
  }
772
933
  function upsertToolNode(tree, id, event, init, seq, mountMain) {
773
934
  const data = event.data;
@@ -1039,6 +1200,24 @@ function handleSubagentToolResult(tree, _event, parentNodeId, data) {
1039
1200
  })
1040
1201
  });
1041
1202
  }
1203
+ function handleSubagentTranscriptMessage(tree, parentNodeId, data) {
1204
+ const tool = agentToolNode(tree, parentNodeId);
1205
+ if (!tool || !parentNodeId) return;
1206
+ const message = data.message;
1207
+ if (message == null || typeof message !== "object" || Array.isArray(message)) return;
1208
+ const messageKind = data.message_kind;
1209
+ if (messageKind !== "assistant" && messageKind !== "user") return;
1210
+ patchToolNode(tree, parentNodeId, {
1211
+ subagentTranscript: appendSubagentTranscriptMessage(tool.subagentTranscript ?? [], {
1212
+ agentId: data.agent_id,
1213
+ messageKind,
1214
+ message,
1215
+ step: data.step,
1216
+ toolName: data.tool_name,
1217
+ subagentType: data.subagent_type
1218
+ })
1219
+ });
1220
+ }
1042
1221
  function handleStepStart(tree, event, parentNodeId, seq) {
1043
1222
  const toolId = parentNodeId;
1044
1223
  if (toolId && tree.byId[toolId]?.kind === "tool_call") {
@@ -1268,6 +1447,13 @@ function applyClassified(tree, classified, eventIndex, options) {
1268
1447
  case "subagent-tool-result":
1269
1448
  handleSubagentToolResult(tree, event, parentNodeId, event.data);
1270
1449
  break;
1450
+ case "subagent-transcript-message":
1451
+ handleSubagentTranscriptMessage(
1452
+ tree,
1453
+ parentNodeId,
1454
+ event.data
1455
+ );
1456
+ break;
1271
1457
  case "subagent-model-step":
1272
1458
  break;
1273
1459
  case "start-step":
@@ -1283,21 +1469,36 @@ function applyClassified(tree, classified, eventIndex, options) {
1283
1469
  return;
1284
1470
  }
1285
1471
  switch (event.event_type) {
1286
- case "text-start":
1287
- if (isDroppedByEmitterRoute(event.data)) break;
1288
- if (isSubagentScopedTextEvent(event.data)) break;
1472
+ case "text-start": {
1473
+ const textData = event.data;
1474
+ if (isDroppedByEmitterRoute(textData)) break;
1475
+ if (isSubagentScopedTextEvent(textData)) break;
1476
+ if (shouldDropParallelSubagentText(tree, textData)) break;
1289
1477
  handleTextStart(tree, event, seq);
1290
1478
  break;
1291
- case "text-delta":
1292
- if (isDroppedByEmitterRoute(event.data)) break;
1293
- if (isSubagentScopedTextEvent(event.data)) break;
1479
+ }
1480
+ case "text-delta": {
1481
+ const textData = event.data;
1482
+ if (isDroppedByEmitterRoute(textData)) break;
1483
+ if (isSubagentScopedTextEvent(textData)) break;
1484
+ if (shouldDropParallelSubagentText(tree, textData)) {
1485
+ tree.deferredMainText = deferMainText(
1486
+ tree.deferredMainText,
1487
+ extractDeferText(textData)
1488
+ );
1489
+ break;
1490
+ }
1294
1491
  handleTextDelta(tree, event, seq);
1295
1492
  break;
1296
- case "text-end":
1297
- if (isDroppedByEmitterRoute(event.data)) break;
1298
- if (isSubagentScopedTextEvent(event.data)) break;
1493
+ }
1494
+ case "text-end": {
1495
+ const textData = event.data;
1496
+ if (isDroppedByEmitterRoute(textData)) break;
1497
+ if (isSubagentScopedTextEvent(textData)) break;
1498
+ if (shouldDropParallelSubagentText(tree, textData)) break;
1299
1499
  handleTextEnd(tree, event);
1300
1500
  break;
1501
+ }
1301
1502
  case "reasoning-start":
1302
1503
  if (isDroppedByEmitterRoute(event.data)) break;
1303
1504
  if (isSubagentScopedReasoningEvent(event.data)) break;
@@ -1369,7 +1570,12 @@ function reduceTree(tree, event, eventIndex, options) {
1369
1570
  if (event.session_id && !next.meta.sessionId) {
1370
1571
  next.meta.sessionId = event.session_id;
1371
1572
  }
1372
- return next;
1573
+ const latchedBeforeGateUpdate = next.parallelAgentTextGateCallIds;
1574
+ const updated = updateParallelAgentTextGate(next);
1575
+ if (latchedBeforeGateUpdate !== null && updated.parallelAgentTextGateCallIds === null) {
1576
+ flushDeferredMainTextToTree(updated, event, eventIndex);
1577
+ }
1578
+ return updated;
1373
1579
  }
1374
1580
  var reduceAgentLoopEvent = reduceTree;
1375
1581
  function reduceEvents(events, options) {
@@ -2793,7 +2999,7 @@ var GroupedToolUseAccumulator = class {
2793
2999
  for (const item of bucket.toolUses) {
2794
3000
  const payload = item.entry.payload;
2795
3001
  nodeIds.push(item.nodeId);
2796
- toolUses.push({
3002
+ const toolUse = {
2797
3003
  tool_call_id: item.toolCallId,
2798
3004
  tool_name: item.toolName,
2799
3005
  tool_input: payload.tool_input ?? {},
@@ -2802,7 +3008,14 @@ var GroupedToolUseAccumulator = class {
2802
3008
  is_error: payload.is_error,
2803
3009
  display: payload.display,
2804
3010
  meta: payload.meta
2805
- });
3011
+ };
3012
+ if (Array.isArray(payload.subagent_progress) && payload.subagent_progress.length > 0) {
3013
+ toolUse.subagent_progress = payload.subagent_progress;
3014
+ }
3015
+ if (Array.isArray(payload.subagent_transcript) && payload.subagent_transcript.length > 0) {
3016
+ toolUse.subagent_transcript = payload.subagent_transcript;
3017
+ }
3018
+ toolUses.push(toolUse);
2806
3019
  if (isResolved(payload)) {
2807
3020
  resolvedCallIds.push(item.toolCallId);
2808
3021
  toolResults.push({
@@ -3315,6 +3528,9 @@ function mapToolCall(node, pendingPermissionTools) {
3315
3528
  if (node.subagentProgress?.length) {
3316
3529
  payload.subagent_progress = node.subagentProgress;
3317
3530
  }
3531
+ if (node.subagentTranscript?.length) {
3532
+ payload.subagent_transcript = node.subagentTranscript;
3533
+ }
3318
3534
  if (responseId) {
3319
3535
  payload.message_id = responseId;
3320
3536
  }
@@ -4298,8 +4514,7 @@ function SpinnerGlimmerVerb({
4298
4514
  mode,
4299
4515
  reducedMotion,
4300
4516
  stalledIntensity,
4301
- flashOpacity,
4302
- shimmerActive
4517
+ flashOpacity
4303
4518
  }) {
4304
4519
  const classes = ["lax-spinner-verb"];
4305
4520
  if (reducedMotion) {
@@ -4308,11 +4523,8 @@ function SpinnerGlimmerVerb({
4308
4523
  classes.push("lax-spinner-verb--stalled");
4309
4524
  } else if (mode === "tool-use") {
4310
4525
  classes.push("lax-spinner-verb--tool-use");
4311
- } else if (shimmerActive) {
4312
- classes.push("lax-spinner-verb--shimmer");
4313
- if (mode === "requesting") {
4314
- classes.push("lax-spinner-verb--shimmer-fast");
4315
- }
4526
+ } else {
4527
+ classes.push("lax-spinner-verb--static");
4316
4528
  }
4317
4529
  const style = {
4318
4530
  ...stalledIntensity > 0 && {
@@ -4496,7 +4708,6 @@ function SpinnerAnimationRow({
4496
4708
  );
4497
4709
  const frameIndex = getSpinnerFrameIndex(time, reducedMotion);
4498
4710
  const frame = SPINNER_FRAMES[frameIndex];
4499
- const shimmerActive = !reducedMotion && stalledIntensity === 0 && (mode === "requesting" || mode === "thinking");
4500
4711
  const flashOpacity = reducedMotion || mode !== "tool-use" ? 0 : (Math.sin(time / 1e3 * Math.PI) + 1) / 2;
4501
4712
  if (reducedMotion) {
4502
4713
  tokenCounterRef.current = targetTokenCount;
@@ -4539,8 +4750,7 @@ function SpinnerAnimationRow({
4539
4750
  mode,
4540
4751
  reducedMotion,
4541
4752
  stalledIntensity,
4542
- flashOpacity,
4543
- shimmerActive
4753
+ flashOpacity
4544
4754
  }
4545
4755
  ),
4546
4756
  statusParts.length > 0 && /* @__PURE__ */ jsxs5("span", { className: "lax-spinner-status", children: [
@@ -4817,6 +5027,7 @@ function TaskListFooter() {
4817
5027
  }
4818
5028
 
4819
5029
  // src/view/GroupedToolCallRow.tsx
5030
+ import { useCallback, useState as useState9 } from "react";
4820
5031
  import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
4821
5032
  var INITIALIZING = "Initializing\u2026";
4822
5033
  function readGroupMeta(payload) {
@@ -4831,7 +5042,7 @@ function readToolUses(payload) {
4831
5042
  (item) => item != null && typeof item === "object" && !Array.isArray(item)
4832
5043
  );
4833
5044
  }
4834
- function sublineStatus(callId, payload) {
5045
+ function sublineStatus(callId, entry, payload) {
4835
5046
  const pending = new Set(
4836
5047
  Array.isArray(payload.pendingCallIds) ? payload.pendingCallIds : []
4837
5048
  );
@@ -4841,7 +5052,9 @@ function sublineStatus(callId, payload) {
4841
5052
  const resolved = new Set(
4842
5053
  Array.isArray(payload.resolvedCallIds) ? payload.resolvedCallIds : []
4843
5054
  );
4844
- if (pending.has(callId)) return INITIALIZING;
5055
+ if (pending.has(callId)) {
5056
+ return extractLastToolInfoFromProgress(entry.subagent_progress) ?? INITIALIZING;
5057
+ }
4845
5058
  if (errored.has(callId)) return "Error";
4846
5059
  if (resolved.has(callId)) {
4847
5060
  const results = Array.isArray(payload.toolResults) ? payload.toolResults : [];
@@ -4863,6 +5076,67 @@ function sublineStatus(callId, payload) {
4863
5076
  }
4864
5077
  return null;
4865
5078
  }
5079
+ function GroupedSubline({
5080
+ callId,
5081
+ entry,
5082
+ payload,
5083
+ hideType,
5084
+ treeChar,
5085
+ index,
5086
+ enableTranscript
5087
+ }) {
5088
+ const [expanded, setExpanded] = useState9(false);
5089
+ const subTitle = formatAgentSublineTitle(entry, hideType);
5090
+ const status = sublineStatus(callId, entry, payload);
5091
+ const transcript = coerceSubagentTranscriptEntries(entry.subagent_transcript);
5092
+ const progress = coerceSubagentProgressEntries(entry.subagent_progress);
5093
+ const hasTranscriptLane = transcript.length > 0;
5094
+ const canExpand = enableTranscript && (hasTranscriptLane || progress.length > 0);
5095
+ const toggleExpanded = useCallback(() => {
5096
+ setExpanded((prev) => !prev);
5097
+ }, []);
5098
+ return /* @__PURE__ */ jsxs8(
5099
+ "div",
5100
+ {
5101
+ className: "lax-tool-group__item lax-tool-group__subline-block",
5102
+ "data-group-index": index + 1,
5103
+ "data-tool-call-id": callId,
5104
+ children: [
5105
+ /* @__PURE__ */ jsxs8("div", { className: "lax-tool-group__subline", children: [
5106
+ /* @__PURE__ */ jsx9("span", { className: "lax-tool-group__tree", "aria-hidden": true, children: treeChar }),
5107
+ /* @__PURE__ */ jsx9("span", { className: "lax-tool-group__subline-title", children: subTitle }),
5108
+ status && /* @__PURE__ */ jsxs8("span", { className: "lax-tool-group__subline-status", children: [
5109
+ " \xB7 ",
5110
+ status
5111
+ ] })
5112
+ ] }),
5113
+ canExpand && !expanded ? /* @__PURE__ */ jsx9(
5114
+ "button",
5115
+ {
5116
+ type: "button",
5117
+ className: "lax-tool-group__transcript-link",
5118
+ onClick: toggleExpanded,
5119
+ "aria-expanded": false,
5120
+ children: "Show transcript"
5121
+ }
5122
+ ) : null,
5123
+ canExpand && expanded ? /* @__PURE__ */ jsxs8("div", { className: "lax-tool-group__transcript-panel", "data-testid": "lax-grouped-transcript", children: [
5124
+ hasTranscriptLane ? /* @__PURE__ */ jsx9(SubagentTranscriptBlock, { entries: transcript, dataSource: "transcript-lane" }) : /* @__PURE__ */ jsx9(AgentProgressLines, { entries: progress, mode: "full" }),
5125
+ /* @__PURE__ */ jsx9(
5126
+ "button",
5127
+ {
5128
+ type: "button",
5129
+ className: "lax-tool-group__transcript-link",
5130
+ onClick: toggleExpanded,
5131
+ "aria-expanded": true,
5132
+ children: "Hide transcript"
5133
+ }
5134
+ )
5135
+ ] }) : null
5136
+ ]
5137
+ }
5138
+ );
5139
+ }
4866
5140
  function GroupedToolCallRow({ payload }) {
4867
5141
  const toolName = String(payload.toolName ?? payload.tool_name ?? "Agent");
4868
5142
  const groupMeta = readGroupMeta(payload);
@@ -4871,6 +5145,7 @@ function GroupedToolCallRow({ payload }) {
4871
5145
  const title = groupMeta?.title ?? `${toolName} \xD7 ${toolUses.length}`;
4872
5146
  const anyPending = Array.isArray(payload.pendingCallIds) && payload.pendingCallIds.length > 0;
4873
5147
  const anyError = Array.isArray(payload.erroredCallIds) && payload.erroredCallIds.length > 0;
5148
+ const enableTranscript = toolUses.length >= 2;
4874
5149
  return /* @__PURE__ */ jsxs8("div", { className: "lax-tool-group", "data-tool-name": toolName, "data-kind": "grouped_tool_use", children: [
4875
5150
  /* @__PURE__ */ jsxs8(
4876
5151
  "div",
@@ -4888,24 +5163,18 @@ function GroupedToolCallRow({ payload }) {
4888
5163
  ),
4889
5164
  /* @__PURE__ */ jsx9("div", { className: "lax-tool-group__items", children: toolUses.map((entry, index) => {
4890
5165
  const callId = String(entry.tool_call_id ?? "");
4891
- const subTitle = formatAgentSublineTitle(entry, hideType);
4892
- const status = sublineStatus(callId, payload);
4893
5166
  const isLast = index === toolUses.length - 1;
4894
5167
  const treeChar = isLast ? "\u2514\u2500" : "\u251C\u2500";
4895
- return /* @__PURE__ */ jsxs8(
4896
- "div",
5168
+ return /* @__PURE__ */ jsx9(
5169
+ GroupedSubline,
4897
5170
  {
4898
- className: "lax-tool-group__item lax-tool-group__subline",
4899
- "data-group-index": index + 1,
4900
- "data-tool-call-id": callId,
4901
- children: [
4902
- /* @__PURE__ */ jsx9("span", { className: "lax-tool-group__tree", "aria-hidden": true, children: treeChar }),
4903
- /* @__PURE__ */ jsx9("span", { className: "lax-tool-group__subline-title", children: subTitle }),
4904
- status && /* @__PURE__ */ jsxs8("span", { className: "lax-tool-group__subline-status", children: [
4905
- " \xB7 ",
4906
- status
4907
- ] })
4908
- ]
5171
+ callId,
5172
+ entry,
5173
+ payload,
5174
+ hideType,
5175
+ treeChar,
5176
+ index,
5177
+ enableTranscript
4909
5178
  },
4910
5179
  callId || `group-item-${index}`
4911
5180
  );
@@ -5294,4 +5563,4 @@ export {
5294
5563
  VirtualTimeline,
5295
5564
  SessionTimeline
5296
5565
  };
5297
- //# sourceMappingURL=chunk-3B4WC67E.js.map
5566
+ //# sourceMappingURL=chunk-ZNXAQ4ZZ.js.map