langchain_agentx_stream_ui 0.2.0 → 0.2.2

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.
@@ -13,7 +13,7 @@ import {
13
13
  coerceSubagentProgressEntries,
14
14
  createDefaultToolRegistry,
15
15
  extractLastToolInfoFromProgress
16
- } from "./chunk-7CLAU74Y.js";
16
+ } from "./chunk-YUZXTGJJ.js";
17
17
 
18
18
  // src/types/tree.ts
19
19
  function createEmptyTree() {
@@ -2238,6 +2238,77 @@ function iterMountCandidates(entries, options) {
2238
2238
  return out;
2239
2239
  }
2240
2240
 
2241
+ // src/core/projection/systemSummaryText.ts
2242
+ function isRecord3(value) {
2243
+ return value !== null && typeof value === "object" && !Array.isArray(value);
2244
+ }
2245
+ function hookLabel(data) {
2246
+ const raw = data.hook ?? data.hook_name ?? data.hookName;
2247
+ return typeof raw === "string" ? raw.trim() : "hook";
2248
+ }
2249
+ function normalizedHookLabel(data) {
2250
+ return hookLabel(data).toLowerCase().replace(/-/g, "_");
2251
+ }
2252
+ function isOkStopHook(data) {
2253
+ const label = normalizedHookLabel(data);
2254
+ if (label !== "stop" && label !== "stop_hook") return false;
2255
+ const status = String(data.status ?? "").toLowerCase();
2256
+ if (status === "blocked" || status === "prevented") return false;
2257
+ if (data.prevented === true) return false;
2258
+ return true;
2259
+ }
2260
+ function isPreToolHook(data) {
2261
+ const label = normalizedHookLabel(data);
2262
+ return label === "pre_tool" || label.includes("pre_tool") || label === "pretooluse";
2263
+ }
2264
+ function isHookVisibleInTimeline(data) {
2265
+ if (isOkStopHook(data)) return false;
2266
+ if (isPreToolHook(data)) return false;
2267
+ return true;
2268
+ }
2269
+ function formatHookFinishedSummary(data) {
2270
+ const label = hookLabel(data).toLowerCase();
2271
+ const status = String(data.status ?? "").toLowerCase();
2272
+ if (label === "stop" || label === "stop_hook") {
2273
+ if (status === "blocked" || status === "prevented" || data.prevented === true) {
2274
+ return "Stop hook blocked";
2275
+ }
2276
+ return "Ran stop hook";
2277
+ }
2278
+ const readable = hookLabel(data).replace(/_/g, "-");
2279
+ return `Ran ${readable} hook`;
2280
+ }
2281
+ function formatSystemEventSummary(eventType, data) {
2282
+ const payload = isRecord3(data) ? data : {};
2283
+ switch (eventType) {
2284
+ case "hook-finished":
2285
+ return formatHookFinishedSummary(payload);
2286
+ default:
2287
+ return null;
2288
+ }
2289
+ }
2290
+ function mergeSystemSummaryLines(lines) {
2291
+ const counts = /* @__PURE__ */ new Map();
2292
+ for (const line of lines) {
2293
+ counts.set(line, (counts.get(line) ?? 0) + 1);
2294
+ }
2295
+ return [...counts.entries()].map(([line, count]) => count > 1 ? `${line} (\xD7${count})` : line).join(" \xB7 ");
2296
+ }
2297
+ function summarizeSystemEvents(events) {
2298
+ const lines = [];
2299
+ for (const evt of events) {
2300
+ if (evt.eventType === "compact-start" || evt.eventType === "compact-end") {
2301
+ continue;
2302
+ }
2303
+ if (evt.eventType === "hook-finished" && isRecord3(evt.data) && !isHookVisibleInTimeline(evt.data)) {
2304
+ continue;
2305
+ }
2306
+ const line = formatSystemEventSummary(evt.eventType, evt.data);
2307
+ if (line) lines.push(line);
2308
+ }
2309
+ return mergeSystemSummaryLines(lines);
2310
+ }
2311
+
2241
2312
  // src/core/projection/exploreSummary.ts
2242
2313
  function memoryReadTotal(counts) {
2243
2314
  if (counts.memoryReadCount === 0 && counts.relevantRecallCount > 0) {
@@ -2451,11 +2522,14 @@ function resolveShellProgressFromPayload(payload) {
2451
2522
  }
2452
2523
 
2453
2524
  // src/core/projection/accumulators/exploreCollapse.ts
2525
+ function hookPayload(entry) {
2526
+ return isRecord4(entry.payload) ? entry.payload : {};
2527
+ }
2454
2528
  var WAITING_PERMISSION = "Waiting for permission\u2026";
2455
2529
  function normalizeDisplayPath(filePath) {
2456
2530
  return filePath.replace(/\\/g, "/");
2457
2531
  }
2458
- function isRecord3(value) {
2532
+ function isRecord4(value) {
2459
2533
  return value !== null && typeof value === "object" && !Array.isArray(value);
2460
2534
  }
2461
2535
  function readPayloadString(payload, key) {
@@ -2513,6 +2587,25 @@ var ExploreCollapseAccumulator = class {
2513
2587
  }
2514
2588
  continue;
2515
2589
  }
2590
+ if (entry.kind === "node" && entry.payload.canonicalType === "compact") {
2591
+ continue;
2592
+ }
2593
+ if (entry.kind === "node" && entry.payload.canonicalType === "hook") {
2594
+ const payload = hookPayload(entry);
2595
+ if (isPreToolHook(payload) || isOkStopHook(payload)) {
2596
+ if (group && group.sourceNodeIds.length > 0 && isPreToolHook(payload)) {
2597
+ this.absorbHookEntry(group, entry);
2598
+ }
2599
+ continue;
2600
+ }
2601
+ if (isHookVisibleInTimeline(payload)) {
2602
+ flush();
2603
+ this.currentRoundId = null;
2604
+ this.currentReasoningNodeId = null;
2605
+ result.push(entry);
2606
+ }
2607
+ continue;
2608
+ }
2516
2609
  if (this.breaksGroup(entry)) {
2517
2610
  flush();
2518
2611
  this.currentRoundId = null;
@@ -2580,6 +2673,8 @@ var ExploreCollapseAccumulator = class {
2580
2673
  relevantRecallCount: 0,
2581
2674
  gitOpBashCount: 0,
2582
2675
  mcpCallCount: 0,
2676
+ hookCount: 0,
2677
+ hookTotalMs: 0,
2583
2678
  searchArgs: [],
2584
2679
  latestDisplayHint: null
2585
2680
  };
@@ -2594,15 +2689,27 @@ var ExploreCollapseAccumulator = class {
2594
2689
  }
2595
2690
  toolKind(entry) {
2596
2691
  const toolName = readPayloadString(entry.payload, "tool_name");
2597
- const toolInput = isRecord3(entry.payload.tool_input) ? entry.payload.tool_input : null;
2598
- const display = isRecord3(entry.payload.display) ? entry.payload.display : null;
2692
+ const toolInput = isRecord4(entry.payload.tool_input) ? entry.payload.tool_input : null;
2693
+ const display = isRecord4(entry.payload.display) ? entry.payload.display : null;
2599
2694
  return this.classifier.classifyTool(toolName, toolInput, display);
2600
2695
  }
2696
+ absorbHookEntry(group, entry) {
2697
+ const payload = hookPayload(entry);
2698
+ group.hookCount += 1;
2699
+ const durationMs = Number(
2700
+ payload.duration_ms ?? payload.durationMs ?? payload.total_duration_ms ?? 0
2701
+ );
2702
+ if (Number.isFinite(durationMs) && durationMs > 0) {
2703
+ group.hookTotalMs += durationMs;
2704
+ }
2705
+ group.sourceNodeIds.push(entry.sourceNodeIds[0] ?? "hook");
2706
+ group.absorbed.push(entry);
2707
+ }
2601
2708
  absorbToolEntry(group, entry, kind) {
2602
2709
  const payload = entry.payload;
2603
2710
  const toolName = String(payload.tool_name ?? "");
2604
- const toolInput = isRecord3(payload.tool_input) ? payload.tool_input : {};
2605
- const display = isRecord3(payload.display) ? payload.display : null;
2711
+ const toolInput = isRecord4(payload.tool_input) ? payload.tool_input : {};
2712
+ const display = isRecord4(payload.display) ? payload.display : null;
2606
2713
  const callId = readPayloadString(payload, "tool_call_id") ?? entry.sourceNodeIds[0] ?? "";
2607
2714
  group.sourceNodeIds.push(entry.sourceNodeIds[0] ?? callId);
2608
2715
  group.absorbed.push(entry);
@@ -2703,6 +2810,8 @@ var ExploreCollapseAccumulator = class {
2703
2810
  relevantRecallCount: counts.relevantRecallCount,
2704
2811
  gitOpBashCount: counts.gitOpBashCount,
2705
2812
  mcpCallCount: counts.mcpCallCount,
2813
+ hookCount: group.hookCount,
2814
+ hookTotalMs: group.hookTotalMs,
2706
2815
  readPaths: [...group.readPaths].sort(),
2707
2816
  memoryReadPaths: [...group.memoryReadPaths].sort(),
2708
2817
  searchArgs: [...group.searchArgs],
@@ -2717,7 +2826,7 @@ var ExploreCollapseAccumulator = class {
2717
2826
  if (!isToolUseEntry2(entry)) continue;
2718
2827
  const payload = entry.payload;
2719
2828
  const callId = readPayloadString(payload, "tool_call_id") ?? entry.sourceNodeIds[0] ?? "";
2720
- const toolInput = isRecord3(payload.tool_input) ? { ...payload.tool_input } : {};
2829
+ const toolInput = isRecord4(payload.tool_input) ? { ...payload.tool_input } : {};
2721
2830
  const item = {
2722
2831
  tool_call_id: callId,
2723
2832
  tool_name: payload.tool_name,
@@ -2729,8 +2838,8 @@ var ExploreCollapseAccumulator = class {
2729
2838
  }
2730
2839
  if ("output" in payload) item.output = String(payload.output ?? "");
2731
2840
  if ("is_error" in payload) item.is_error = Boolean(payload.is_error);
2732
- if (isRecord3(payload.display)) item.display = { ...payload.display };
2733
- if (isRecord3(payload.meta)) item.meta = { ...payload.meta };
2841
+ if (isRecord4(payload.display)) item.display = { ...payload.display };
2842
+ if (isRecord4(payload.meta)) item.meta = { ...payload.meta };
2734
2843
  out.push(item);
2735
2844
  }
2736
2845
  return out;
@@ -3056,54 +3165,6 @@ var GroupedToolUseAccumulator = class {
3056
3165
  }
3057
3166
  };
3058
3167
 
3059
- // src/core/projection/systemSummaryText.ts
3060
- function isRecord4(value) {
3061
- return value !== null && typeof value === "object" && !Array.isArray(value);
3062
- }
3063
- function hookLabel(data) {
3064
- const raw = data.hook ?? data.hook_name ?? data.hookName;
3065
- return typeof raw === "string" ? raw.trim() : "hook";
3066
- }
3067
- function formatHookFinishedSummary(data) {
3068
- const label = hookLabel(data).toLowerCase();
3069
- const status = String(data.status ?? "").toLowerCase();
3070
- if (label === "stop" || label === "stop_hook") {
3071
- if (status === "blocked" || status === "prevented" || data.prevented === true) {
3072
- return "Stop hook blocked";
3073
- }
3074
- return "Ran stop hook";
3075
- }
3076
- const readable = hookLabel(data).replace(/_/g, "-");
3077
- return `Ran ${readable} hook`;
3078
- }
3079
- function formatSystemEventSummary(eventType, data) {
3080
- const payload = isRecord4(data) ? data : {};
3081
- switch (eventType) {
3082
- case "hook-finished":
3083
- return formatHookFinishedSummary(payload);
3084
- default:
3085
- return null;
3086
- }
3087
- }
3088
- function mergeSystemSummaryLines(lines) {
3089
- const counts = /* @__PURE__ */ new Map();
3090
- for (const line of lines) {
3091
- counts.set(line, (counts.get(line) ?? 0) + 1);
3092
- }
3093
- return [...counts.entries()].map(([line, count]) => count > 1 ? `${line} (\xD7${count})` : line).join(" \xB7 ");
3094
- }
3095
- function summarizeSystemEvents(events) {
3096
- const lines = [];
3097
- for (const evt of events) {
3098
- if (evt.eventType === "compact-start" || evt.eventType === "compact-end") {
3099
- continue;
3100
- }
3101
- const line = formatSystemEventSummary(evt.eventType, evt.data);
3102
- if (line) lines.push(line);
3103
- }
3104
- return mergeSystemSummaryLines(lines);
3105
- }
3106
-
3107
3168
  // src/core/projection/accumulators/systemSummary.ts
3108
3169
  var SYSTEM_CANONICAL_TYPES = /* @__PURE__ */ new Set(["hook", "compact"]);
3109
3170
  function isRecord5(value) {
@@ -3124,21 +3185,27 @@ var SystemSummaryAccumulator = class {
3124
3185
  let buffer = [];
3125
3186
  const flush = () => {
3126
3187
  if (buffer.length === 0) return;
3188
+ const visibleBuffer = buffer.filter((entry) => {
3189
+ if (canonicalType2(entry) !== "hook") return true;
3190
+ return isHookVisibleInTimeline(entry.payload);
3191
+ });
3192
+ buffer = [];
3193
+ if (visibleBuffer.length === 0) return;
3127
3194
  const summaryText = summarizeSystemEvents(
3128
- buffer.map((entry) => ({
3195
+ visibleBuffer.map((entry) => ({
3129
3196
  eventType: String(entry.payload.event_type ?? ""),
3130
3197
  data: entry.payload
3131
3198
  }))
3132
3199
  );
3133
3200
  if (!summaryText) {
3134
- result.push(...buffer);
3201
+ result.push(...visibleBuffer);
3135
3202
  } else {
3136
3203
  result.push({
3137
3204
  kind: "system_summary",
3138
- sourceNodeIds: buffer.map((entry) => entry.sourceNodeIds[0]).filter((id) => typeof id === "string"),
3205
+ sourceNodeIds: visibleBuffer.map((entry) => entry.sourceNodeIds[0]).filter((id) => typeof id === "string"),
3139
3206
  payload: {
3140
3207
  summaryText,
3141
- events: buffer.map((entry) => ({
3208
+ events: visibleBuffer.map((entry) => ({
3142
3209
  nodeId: entry.sourceNodeIds[0],
3143
3210
  event_type: entry.payload.event_type,
3144
3211
  ...isRecord5(entry.payload) ? entry.payload : {}
@@ -3146,7 +3213,6 @@ var SystemSummaryAccumulator = class {
3146
3213
  }
3147
3214
  });
3148
3215
  }
3149
- buffer = [];
3150
3216
  };
3151
3217
  for (const entry of entries) {
3152
3218
  if (isSystemSummaryEntry(entry)) {
@@ -3845,6 +3911,13 @@ function countsFromPayload(payload) {
3845
3911
  mcpCallCount: Number(payload.mcpCallCount ?? 0)
3846
3912
  };
3847
3913
  }
3914
+ function formatHookDuration(totalMs) {
3915
+ if (totalMs >= 1e3) {
3916
+ const seconds = totalMs / 1e3;
3917
+ return seconds >= 10 ? `${Math.round(seconds)}s` : `${seconds.toFixed(1)}s`;
3918
+ }
3919
+ return `${Math.round(totalMs)}ms`;
3920
+ }
3848
3921
  function toolUseNodeIds(entry) {
3849
3922
  const toolUses = entry.payload.toolUses;
3850
3923
  if (!Array.isArray(toolUses) || toolUses.length === 0) {
@@ -3893,6 +3966,9 @@ function CollapsedExploreNode({ entry, registry }) {
3893
3966
  const hint = typeof payload.latestDisplayHint === "string" ? payload.latestDisplayHint : null;
3894
3967
  const displayedHint = useMinDisplayTime(hint, MIN_HINT_DISPLAY_MS);
3895
3968
  const shellProgressSuffix = typeof payload.shellProgressSuffix === "string" ? payload.shellProgressSuffix : "";
3969
+ const hookCount = Number(payload.hookCount ?? 0);
3970
+ const hookTotalMs = Number(payload.hookTotalMs ?? 0);
3971
+ const hookSubline = !showDetail && hookCount > 0 && hookTotalMs > 0 ? `Ran ${hookCount} PreToolUse ${hookCount === 1 ? "hook" : "hooks"} (${formatHookDuration(hookTotalMs)})` : null;
3896
3972
  const thoughtPrefix = hasThoughtPrefix ? formatThoughtDurationPrefix(thoughtSeconds) : "";
3897
3973
  const summaryLine = `${thoughtPrefix}${exploreSummary}${shellProgressSuffix}`;
3898
3974
  useEffect2(() => {
@@ -3934,6 +4010,10 @@ function CollapsedExploreNode({ entry, registry }) {
3934
4010
  /* @__PURE__ */ jsx2("span", { className: "lax-collapsed-explore__hint-prefix", children: "\u23BF" }),
3935
4011
  /* @__PURE__ */ jsx2("span", { className: "lax-collapsed-explore__hint-text", children: displayedHint })
3936
4012
  ] }) : null,
4013
+ !active && hookSubline && !showDetail ? /* @__PURE__ */ jsxs("div", { className: "lax-collapsed-explore__hint lax-collapsed-explore__hint--dim", children: [
4014
+ /* @__PURE__ */ jsx2("span", { className: "lax-collapsed-explore__hint-prefix", children: "\u23BF" }),
4015
+ /* @__PURE__ */ jsx2("span", { className: "lax-collapsed-explore__hint-text", children: hookSubline })
4016
+ ] }) : null,
3937
4017
  showDetail && verboseNodeIds.length > 0 ? /* @__PURE__ */ jsx2("div", { className: "lax-collapsed-explore__verbose", children: verboseNodeIds.map((nodeId) => /* @__PURE__ */ jsx2(TimelineItem, { nodeId, registry }, nodeId)) }) : null
3938
4018
  ]
3939
4019
  }
@@ -5522,13 +5602,13 @@ export {
5522
5602
  isGroupableToolName,
5523
5603
  entryKey,
5524
5604
  iterMountCandidates,
5605
+ formatHookFinishedSummary,
5525
5606
  formatExploreSummaryText,
5526
5607
  SHELL_PROGRESS_MIN_ELAPSED_SECONDS,
5527
5608
  formatShellProgressSuffix,
5528
5609
  resolveShellProgressFromPayload,
5529
5610
  ExploreCollapseAccumulator,
5530
5611
  GroupedToolUseAccumulator,
5531
- formatHookFinishedSummary,
5532
5612
  SystemSummaryAccumulator,
5533
5613
  RenderableTimelineProjector,
5534
5614
  resolveResponseId,
@@ -5563,4 +5643,4 @@ export {
5563
5643
  VirtualTimeline,
5564
5644
  SessionTimeline
5565
5645
  };
5566
- //# sourceMappingURL=chunk-ZNXAQ4ZZ.js.map
5646
+ //# sourceMappingURL=chunk-OFXC2GZI.js.map