llmist 3.1.0 → 4.0.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.
package/dist/cli.cjs CHANGED
@@ -3496,7 +3496,7 @@ var init_executor = __esm({
3496
3496
  init_exceptions();
3497
3497
  init_parser();
3498
3498
  GadgetExecutor = class {
3499
- constructor(registry, requestHumanInput, logger, defaultGadgetTimeoutMs, errorFormatterOptions, client, mediaStore, agentConfig, subagentConfig, onNestedEvent) {
3499
+ constructor(registry, requestHumanInput, logger, defaultGadgetTimeoutMs, errorFormatterOptions, client, mediaStore, agentConfig, subagentConfig, onSubagentEvent) {
3500
3500
  this.registry = registry;
3501
3501
  this.requestHumanInput = requestHumanInput;
3502
3502
  this.defaultGadgetTimeoutMs = defaultGadgetTimeoutMs;
@@ -3504,7 +3504,7 @@ var init_executor = __esm({
3504
3504
  this.mediaStore = mediaStore;
3505
3505
  this.agentConfig = agentConfig;
3506
3506
  this.subagentConfig = subagentConfig;
3507
- this.onNestedEvent = onNestedEvent;
3507
+ this.onSubagentEvent = onSubagentEvent;
3508
3508
  this.logger = logger ?? createLogger({ name: "llmist:executor" });
3509
3509
  this.errorFormatter = new GadgetExecutionErrorFormatter(errorFormatterOptions);
3510
3510
  this.argPrefix = errorFormatterOptions?.argPrefix ?? GADGET_ARG_PREFIX;
@@ -3652,7 +3652,7 @@ var init_executor = __esm({
3652
3652
  agentConfig: this.agentConfig,
3653
3653
  subagentConfig: this.subagentConfig,
3654
3654
  invocationId: call.invocationId,
3655
- onNestedEvent: this.onNestedEvent
3655
+ onSubagentEvent: this.onSubagentEvent
3656
3656
  };
3657
3657
  let rawResult;
3658
3658
  if (timeoutMs && timeoutMs > 0) {
@@ -3892,7 +3892,7 @@ var init_stream_processor = __esm({
3892
3892
  options.mediaStore,
3893
3893
  options.agentConfig,
3894
3894
  options.subagentConfig,
3895
- options.onNestedEvent
3895
+ options.onSubagentEvent
3896
3896
  );
3897
3897
  }
3898
3898
  /**
@@ -4851,8 +4851,12 @@ var init_agent = __esm({
4851
4851
  // Subagent configuration
4852
4852
  agentContextConfig;
4853
4853
  subagentConfig;
4854
- // Nested event callback for subagent gadgets
4855
- onNestedEvent;
4854
+ // Subagent event callback for subagent gadgets
4855
+ userSubagentEventCallback;
4856
+ // Internal queue for yielding subagent events in run()
4857
+ pendingSubagentEvents = [];
4858
+ // Combined callback that queues events AND calls user callback
4859
+ onSubagentEvent;
4856
4860
  /**
4857
4861
  * Creates a new Agent instance.
4858
4862
  * @internal This constructor is private. Use LLMist.createAgent() or AgentBuilder instead.
@@ -4930,7 +4934,71 @@ var init_agent = __esm({
4930
4934
  temperature: this.temperature
4931
4935
  };
4932
4936
  this.subagentConfig = options.subagentConfig;
4933
- this.onNestedEvent = options.onNestedEvent;
4937
+ this.userSubagentEventCallback = options.onSubagentEvent;
4938
+ this.onSubagentEvent = (event) => {
4939
+ this.pendingSubagentEvents.push(event);
4940
+ this.userSubagentEventCallback?.(event);
4941
+ const subagentContext = {
4942
+ parentGadgetInvocationId: event.gadgetInvocationId,
4943
+ depth: event.depth
4944
+ };
4945
+ if (event.type === "llm_call_start") {
4946
+ const info = event.event;
4947
+ void this.hooks?.observers?.onLLMCallStart?.({
4948
+ iteration: info.iteration,
4949
+ options: { model: info.model, messages: [] },
4950
+ logger: this.logger,
4951
+ subagentContext
4952
+ });
4953
+ } else if (event.type === "llm_call_end") {
4954
+ const info = event.event;
4955
+ void this.hooks?.observers?.onLLMCallComplete?.({
4956
+ iteration: info.iteration,
4957
+ options: { model: info.model, messages: [] },
4958
+ finishReason: info.finishReason ?? null,
4959
+ usage: info.outputTokens ? {
4960
+ inputTokens: info.inputTokens ?? 0,
4961
+ outputTokens: info.outputTokens,
4962
+ totalTokens: (info.inputTokens ?? 0) + info.outputTokens
4963
+ } : void 0,
4964
+ rawResponse: "",
4965
+ finalMessage: "",
4966
+ logger: this.logger,
4967
+ subagentContext
4968
+ });
4969
+ } else if (event.type === "gadget_call") {
4970
+ const gadgetEvent = event.event;
4971
+ void this.hooks?.observers?.onGadgetExecutionStart?.({
4972
+ iteration: 0,
4973
+ gadgetName: gadgetEvent.call.gadgetName,
4974
+ invocationId: gadgetEvent.call.invocationId,
4975
+ parameters: gadgetEvent.call.parameters ?? {},
4976
+ logger: this.logger,
4977
+ subagentContext
4978
+ });
4979
+ } else if (event.type === "gadget_result") {
4980
+ const resultEvent = event.event;
4981
+ void this.hooks?.observers?.onGadgetExecutionComplete?.({
4982
+ iteration: 0,
4983
+ gadgetName: resultEvent.result.gadgetName ?? "unknown",
4984
+ invocationId: resultEvent.result.invocationId,
4985
+ parameters: {},
4986
+ executionTimeMs: resultEvent.result.executionTimeMs ?? 0,
4987
+ logger: this.logger,
4988
+ subagentContext
4989
+ });
4990
+ }
4991
+ };
4992
+ }
4993
+ /**
4994
+ * Flush pending subagent events as StreamEvents.
4995
+ * Called from run() to yield queued subagent events from subagent gadgets.
4996
+ */
4997
+ *flushPendingSubagentEvents() {
4998
+ while (this.pendingSubagentEvents.length > 0) {
4999
+ const event = this.pendingSubagentEvents.shift();
5000
+ yield { type: "subagent_event", subagentEvent: event };
5001
+ }
4934
5002
  }
4935
5003
  /**
4936
5004
  * Get the gadget registry for this agent.
@@ -5162,7 +5230,7 @@ var init_agent = __esm({
5162
5230
  mediaStore: this.mediaStore,
5163
5231
  agentConfig: this.agentContextConfig,
5164
5232
  subagentConfig: this.subagentConfig,
5165
- onNestedEvent: this.onNestedEvent
5233
+ onSubagentEvent: this.onSubagentEvent
5166
5234
  });
5167
5235
  let streamMetadata = null;
5168
5236
  let gadgetCallCount = 0;
@@ -5180,6 +5248,7 @@ var init_agent = __esm({
5180
5248
  gadgetResults.push(event);
5181
5249
  }
5182
5250
  yield event;
5251
+ yield* this.flushPendingSubagentEvents();
5183
5252
  }
5184
5253
  if (!streamMetadata) {
5185
5254
  throw new Error("Stream processing completed without metadata event");
@@ -8756,7 +8825,7 @@ var init_builder = __esm({
8756
8825
  signal;
8757
8826
  trailingMessage;
8758
8827
  subagentConfig;
8759
- nestedEventCallback;
8828
+ subagentEventCallback;
8760
8829
  parentContext;
8761
8830
  constructor(client) {
8762
8831
  this.client = client;
@@ -9255,38 +9324,38 @@ var init_builder = __esm({
9255
9324
  return this;
9256
9325
  }
9257
9326
  /**
9258
- * Set the callback for nested subagent events.
9327
+ * Set the callback for subagent events.
9259
9328
  *
9260
- * Subagent gadgets (like BrowseWeb) can use ExecutionContext.onNestedEvent
9329
+ * Subagent gadgets (like BrowseWeb) can use ExecutionContext.onSubagentEvent
9261
9330
  * to report their internal LLM calls and gadget executions in real-time.
9262
9331
  * This callback receives those events, enabling hierarchical progress display.
9263
9332
  *
9264
- * @param callback - Function to handle nested agent events
9333
+ * @param callback - Function to handle subagent events
9265
9334
  * @returns This builder for chaining
9266
9335
  *
9267
9336
  * @example
9268
9337
  * ```typescript
9269
- * .withNestedEventCallback((event) => {
9338
+ * .withSubagentEventCallback((event) => {
9270
9339
  * if (event.type === "llm_call_start") {
9271
- * console.log(` Nested LLM #${event.event.iteration} starting...`);
9340
+ * console.log(` Subagent LLM #${event.event.iteration} starting...`);
9272
9341
  * } else if (event.type === "gadget_call") {
9273
9342
  * console.log(` ⏵ ${event.event.call.gadgetName}...`);
9274
9343
  * }
9275
9344
  * })
9276
9345
  * ```
9277
9346
  */
9278
- withNestedEventCallback(callback) {
9279
- this.nestedEventCallback = callback;
9347
+ withSubagentEventCallback(callback) {
9348
+ this.subagentEventCallback = callback;
9280
9349
  return this;
9281
9350
  }
9282
9351
  /**
9283
- * Enable automatic nested event forwarding to parent agent.
9352
+ * Enable automatic subagent event forwarding to parent agent.
9284
9353
  *
9285
9354
  * When building a subagent inside a gadget, call this method to automatically
9286
9355
  * forward all LLM calls and gadget events to the parent agent. This enables
9287
9356
  * hierarchical progress display without any manual event handling.
9288
9357
  *
9289
- * The method extracts `invocationId` and `onNestedEvent` from the execution
9358
+ * The method extracts `invocationId` and `onSubagentEvent` from the execution
9290
9359
  * context and sets up automatic forwarding via hooks and event wrapping.
9291
9360
  *
9292
9361
  * @param ctx - ExecutionContext passed to the gadget's execute() method
@@ -9313,10 +9382,10 @@ var init_builder = __esm({
9313
9382
  * ```
9314
9383
  */
9315
9384
  withParentContext(ctx, depth = 1) {
9316
- if (ctx.onNestedEvent && ctx.invocationId) {
9385
+ if (ctx.onSubagentEvent && ctx.invocationId) {
9317
9386
  this.parentContext = {
9318
9387
  invocationId: ctx.invocationId,
9319
- onNestedEvent: ctx.onNestedEvent,
9388
+ onSubagentEvent: ctx.onSubagentEvent,
9320
9389
  depth
9321
9390
  };
9322
9391
  }
@@ -9391,20 +9460,22 @@ ${endPrefix}`
9391
9460
  /**
9392
9461
  * Compose the final hooks, including:
9393
9462
  * - Trailing message injection (if configured)
9394
- * - Nested event forwarding for LLM calls (if parentContext is set)
9463
+ * - Subagent event forwarding for LLM calls (if parentContext is set)
9395
9464
  */
9396
9465
  composeHooks() {
9397
9466
  let hooks = this.hooks;
9398
9467
  if (this.parentContext) {
9399
- const { invocationId, onNestedEvent, depth } = this.parentContext;
9468
+ const { invocationId, onSubagentEvent, depth } = this.parentContext;
9400
9469
  const existingOnLLMCallStart = hooks?.observers?.onLLMCallStart;
9401
9470
  const existingOnLLMCallComplete = hooks?.observers?.onLLMCallComplete;
9471
+ const existingOnGadgetExecutionStart = hooks?.observers?.onGadgetExecutionStart;
9472
+ const existingOnGadgetExecutionComplete = hooks?.observers?.onGadgetExecutionComplete;
9402
9473
  hooks = {
9403
9474
  ...hooks,
9404
9475
  observers: {
9405
9476
  ...hooks?.observers,
9406
9477
  onLLMCallStart: async (context) => {
9407
- onNestedEvent({
9478
+ onSubagentEvent({
9408
9479
  type: "llm_call_start",
9409
9480
  gadgetInvocationId: invocationId,
9410
9481
  depth,
@@ -9418,7 +9489,7 @@ ${endPrefix}`
9418
9489
  }
9419
9490
  },
9420
9491
  onLLMCallComplete: async (context) => {
9421
- onNestedEvent({
9492
+ onSubagentEvent({
9422
9493
  type: "llm_call_end",
9423
9494
  gadgetInvocationId: invocationId,
9424
9495
  depth,
@@ -9432,6 +9503,38 @@ ${endPrefix}`
9432
9503
  if (existingOnLLMCallComplete) {
9433
9504
  await existingOnLLMCallComplete(context);
9434
9505
  }
9506
+ },
9507
+ onGadgetExecutionStart: async (context) => {
9508
+ onSubagentEvent({
9509
+ type: "gadget_call",
9510
+ gadgetInvocationId: invocationId,
9511
+ depth,
9512
+ event: {
9513
+ call: {
9514
+ invocationId: context.invocationId,
9515
+ gadgetName: context.gadgetName,
9516
+ parameters: context.parameters
9517
+ }
9518
+ }
9519
+ });
9520
+ if (existingOnGadgetExecutionStart) {
9521
+ await existingOnGadgetExecutionStart(context);
9522
+ }
9523
+ },
9524
+ onGadgetExecutionComplete: async (context) => {
9525
+ onSubagentEvent({
9526
+ type: "gadget_result",
9527
+ gadgetInvocationId: invocationId,
9528
+ depth,
9529
+ event: {
9530
+ result: {
9531
+ invocationId: context.invocationId
9532
+ }
9533
+ }
9534
+ });
9535
+ if (existingOnGadgetExecutionComplete) {
9536
+ await existingOnGadgetExecutionComplete(context);
9537
+ }
9435
9538
  }
9436
9539
  }
9437
9540
  };
@@ -9518,11 +9621,11 @@ ${endPrefix}`
9518
9621
  this.client = new LLMistClass();
9519
9622
  }
9520
9623
  const registry = GadgetRegistry.from(this.gadgets);
9521
- let onNestedEvent = this.nestedEventCallback;
9624
+ let onSubagentEvent = this.subagentEventCallback;
9522
9625
  if (this.parentContext) {
9523
- const { invocationId, onNestedEvent: parentCallback, depth } = this.parentContext;
9524
- const existingCallback = this.nestedEventCallback;
9525
- onNestedEvent = (event) => {
9626
+ const { invocationId, onSubagentEvent: parentCallback, depth } = this.parentContext;
9627
+ const existingCallback = this.subagentEventCallback;
9628
+ onSubagentEvent = (event) => {
9526
9629
  parentCallback({
9527
9630
  ...event,
9528
9631
  gadgetInvocationId: invocationId,
@@ -9557,7 +9660,7 @@ ${endPrefix}`
9557
9660
  compactionConfig: this.compactionConfig,
9558
9661
  signal: this.signal,
9559
9662
  subagentConfig: this.subagentConfig,
9560
- onNestedEvent
9663
+ onSubagentEvent
9561
9664
  };
9562
9665
  }
9563
9666
  ask(userPrompt) {
@@ -9714,11 +9817,11 @@ ${endPrefix}`
9714
9817
  this.client = new LLMistClass();
9715
9818
  }
9716
9819
  const registry = GadgetRegistry.from(this.gadgets);
9717
- let onNestedEvent = this.nestedEventCallback;
9820
+ let onSubagentEvent = this.subagentEventCallback;
9718
9821
  if (this.parentContext) {
9719
- const { invocationId, onNestedEvent: parentCallback, depth } = this.parentContext;
9720
- const existingCallback = this.nestedEventCallback;
9721
- onNestedEvent = (event) => {
9822
+ const { invocationId, onSubagentEvent: parentCallback, depth } = this.parentContext;
9823
+ const existingCallback = this.subagentEventCallback;
9824
+ onSubagentEvent = (event) => {
9722
9825
  parentCallback({
9723
9826
  ...event,
9724
9827
  gadgetInvocationId: invocationId,
@@ -9753,7 +9856,7 @@ ${endPrefix}`
9753
9856
  compactionConfig: this.compactionConfig,
9754
9857
  signal: this.signal,
9755
9858
  subagentConfig: this.subagentConfig,
9756
- onNestedEvent
9859
+ onSubagentEvent
9757
9860
  };
9758
9861
  return new Agent(AGENT_INTERNAL_KEY, options);
9759
9862
  }
@@ -9848,7 +9951,7 @@ var import_commander2 = require("commander");
9848
9951
  // package.json
9849
9952
  var package_default = {
9850
9953
  name: "llmist",
9851
- version: "3.0.0",
9954
+ version: "3.1.0",
9852
9955
  description: "TypeScript LLM client with streaming tool execution. Tools fire mid-stream. Built-in function calling works with any model\u2014no structured outputs or native tool support required.",
9853
9956
  type: "module",
9854
9957
  main: "dist/index.cjs",
@@ -12859,20 +12962,53 @@ function renderOverallSummary(metadata) {
12859
12962
  }
12860
12963
  return parts.join(import_chalk3.default.dim(" | "));
12861
12964
  }
12862
- function formatParametersInline(params) {
12965
+ function getRawValue(value) {
12966
+ if (typeof value === "string") {
12967
+ return value;
12968
+ }
12969
+ if (typeof value === "boolean" || typeof value === "number") {
12970
+ return String(value);
12971
+ }
12972
+ return JSON.stringify(value);
12973
+ }
12974
+ function truncateValue(str, maxLen) {
12975
+ if (maxLen <= 0) return "";
12976
+ if (str.length <= maxLen) return str;
12977
+ return `${str.slice(0, maxLen)}\u2026`;
12978
+ }
12979
+ function formatParametersInline(params, maxWidth) {
12863
12980
  if (!params || Object.keys(params).length === 0) {
12864
12981
  return "";
12865
12982
  }
12866
- return Object.entries(params).map(([key, value]) => {
12867
- let formatted;
12868
- if (typeof value === "string") {
12869
- formatted = value.length > 30 ? `${value.slice(0, 30)}\u2026` : value;
12870
- } else if (typeof value === "boolean" || typeof value === "number") {
12871
- formatted = String(value);
12983
+ const entries = Object.entries(params);
12984
+ const defaultLimit = 30;
12985
+ const rawValues = entries.map(([, value]) => getRawValue(value));
12986
+ const overhead = entries.reduce((sum, [key], i) => {
12987
+ return sum + key.length + 1 + (i > 0 ? 2 : 0);
12988
+ }, 0);
12989
+ let limits;
12990
+ if (maxWidth && maxWidth > overhead) {
12991
+ const availableForValues = maxWidth - overhead;
12992
+ const totalRawLength = rawValues.reduce((sum, v) => sum + v.length, 0);
12993
+ if (totalRawLength <= availableForValues) {
12994
+ limits = rawValues.map(() => Infinity);
12872
12995
  } else {
12873
- const json = JSON.stringify(value);
12874
- formatted = json.length > 30 ? `${json.slice(0, 30)}\u2026` : json;
12996
+ const minPerValue = 10;
12997
+ const minTotal = entries.length * minPerValue;
12998
+ if (availableForValues <= minTotal) {
12999
+ limits = rawValues.map(() => Math.max(1, Math.floor(availableForValues / entries.length)));
13000
+ } else {
13001
+ limits = rawValues.map((v) => {
13002
+ const proportion = v.length / totalRawLength;
13003
+ return Math.max(minPerValue, Math.floor(proportion * availableForValues));
13004
+ });
13005
+ }
12875
13006
  }
13007
+ } else {
13008
+ limits = rawValues.map(() => defaultLimit);
13009
+ }
13010
+ return entries.map(([key, _], i) => {
13011
+ const formatted = truncateValue(rawValues[i], limits[i]);
12876
13012
  return `${import_chalk3.default.dim(key)}${import_chalk3.default.dim("=")}${import_chalk3.default.cyan(formatted)}`;
12877
13013
  }).join(import_chalk3.default.dim(", "));
12878
13014
  }
@@ -12908,25 +13044,28 @@ function formatMediaLine(media) {
12908
13044
  return `${import_chalk3.default.dim("[")}${icon} ${id} ${mimeType} ${size}${import_chalk3.default.dim("]")} ${import_chalk3.default.dim("\u2192")} ${path6}`;
12909
13045
  }
12910
13046
  function formatGadgetSummary2(result) {
13047
+ const terminalWidth = process.stdout.columns || 80;
12911
13048
  const gadgetLabel = import_chalk3.default.magenta.bold(result.gadgetName);
12912
- const timeLabel = import_chalk3.default.dim(
12913
- result.executionTimeMs >= 1e3 ? `${(result.executionTimeMs / 1e3).toFixed(1)}s` : `${Math.round(result.executionTimeMs)}ms`
12914
- );
12915
- const paramsStr = formatParametersInline(result.parameters);
12916
- const paramsLabel = paramsStr ? `${import_chalk3.default.dim("(")}${paramsStr}${import_chalk3.default.dim(")")}` : "";
12917
- if (result.error) {
12918
- const errorMsg = result.error.length > 50 ? `${result.error.slice(0, 50)}\u2026` : result.error;
12919
- return `${import_chalk3.default.red("\u2717")} ${gadgetLabel}${paramsLabel} ${import_chalk3.default.red("error:")} ${errorMsg} ${timeLabel}`;
12920
- }
12921
- let outputLabel;
13049
+ const timeStr = result.executionTimeMs >= 1e3 ? `${(result.executionTimeMs / 1e3).toFixed(1)}s` : `${Math.round(result.executionTimeMs)}ms`;
13050
+ const timeLabel = import_chalk3.default.dim(timeStr);
13051
+ let outputStr;
12922
13052
  if (result.tokenCount !== void 0 && result.tokenCount > 0) {
12923
- outputLabel = import_chalk3.default.green(`${formatTokens(result.tokenCount)} tokens`);
13053
+ outputStr = `${formatTokens(result.tokenCount)} tokens`;
12924
13054
  } else if (result.result) {
12925
13055
  const outputBytes = Buffer.byteLength(result.result, "utf-8");
12926
- outputLabel = outputBytes > 0 ? import_chalk3.default.green(formatBytes(outputBytes)) : import_chalk3.default.dim("no output");
13056
+ outputStr = outputBytes > 0 ? formatBytes(outputBytes) : "no output";
12927
13057
  } else {
12928
- outputLabel = import_chalk3.default.dim("no output");
13058
+ outputStr = "no output";
12929
13059
  }
13060
+ const fixedLength = 2 + result.gadgetName.length + 2 + 3 + outputStr.length + 1 + timeStr.length;
13061
+ const availableForParams = Math.max(40, terminalWidth - fixedLength - 2);
13062
+ const paramsStr = formatParametersInline(result.parameters, availableForParams);
13063
+ const paramsLabel = paramsStr ? `${import_chalk3.default.dim("(")}${paramsStr}${import_chalk3.default.dim(")")}` : "";
13064
+ if (result.error) {
13065
+ const errorMsg = result.error.length > 50 ? `${result.error.slice(0, 50)}\u2026` : result.error;
13066
+ return `${import_chalk3.default.red("\u2717")} ${gadgetLabel}${paramsLabel} ${import_chalk3.default.red("error:")} ${errorMsg} ${timeLabel}`;
13067
+ }
13068
+ const outputLabel = outputStr === "no output" ? import_chalk3.default.dim(outputStr) : import_chalk3.default.green(outputStr);
12930
13069
  const icon = result.breaksLoop ? import_chalk3.default.yellow("\u23F9") : import_chalk3.default.green("\u2713");
12931
13070
  let summaryLine = `${icon} ${gadgetLabel}${paramsLabel} ${import_chalk3.default.dim("\u2192")} ${outputLabel} ${timeLabel}`;
12932
13071
  if (result.media && result.media.length > 0) {
@@ -13193,6 +13332,18 @@ var StreamProgress = class {
13193
13332
  this.render();
13194
13333
  }
13195
13334
  }
13335
+ /**
13336
+ * Mark a nested gadget as completed (keeps it visible with ✓ indicator).
13337
+ */
13338
+ completeNestedGadget(id) {
13339
+ const gadget = this.nestedGadgets.get(id);
13340
+ if (gadget) {
13341
+ gadget.completed = true;
13342
+ if (this.isRunning && this.isTTY) {
13343
+ this.render();
13344
+ }
13345
+ }
13346
+ }
13196
13347
  /**
13197
13348
  * Starts a new LLM call. Switches to streaming mode.
13198
13349
  * @param model - Model name being used
@@ -13341,11 +13492,12 @@ var StreamProgress = class {
13341
13492
  const nestedLine = `${indent}${import_chalk4.default.cyan(`#${nested.iteration}`)} ${import_chalk4.default.dim(nested.model)}${tokens}${outTokens} ${import_chalk4.default.dim(nestedElapsed + "s")} ${import_chalk4.default.cyan(spinner)}`;
13342
13493
  lines.push(nestedLine);
13343
13494
  }
13344
- for (const [_nestedId, nestedGadget] of this.nestedGadgets) {
13495
+ for (const [nestedId, nestedGadget] of this.nestedGadgets) {
13345
13496
  if (nestedGadget.parentInvocationId === gadgetId) {
13346
13497
  const indent = " ".repeat(nestedGadget.depth + 1);
13347
13498
  const nestedElapsed = ((Date.now() - nestedGadget.startTime) / 1e3).toFixed(1);
13348
- const nestedGadgetLine = `${indent}${import_chalk4.default.blue("\u23F5")} ${import_chalk4.default.dim(nestedGadget.name + "(...)")} ${import_chalk4.default.dim(nestedElapsed + "s")}`;
13499
+ const icon = nestedGadget.completed ? import_chalk4.default.green("\u2713") : import_chalk4.default.blue("\u23F5");
13500
+ const nestedGadgetLine = `${indent}${icon} ${import_chalk4.default.dim(nestedGadget.name + "(...)")} ${import_chalk4.default.dim(nestedElapsed + "s")}`;
13349
13501
  lines.push(nestedGadgetLine);
13350
13502
  }
13351
13503
  }
@@ -14056,34 +14208,34 @@ Denied: ${result.reason ?? "by user"}`
14056
14208
  ].join(" ")
14057
14209
  );
14058
14210
  if (!options.quiet) {
14059
- builder.withNestedEventCallback((event) => {
14060
- if (event.type === "llm_call_start") {
14061
- const info = event.event;
14062
- const nestedId = `${event.gadgetInvocationId}:${info.iteration}`;
14211
+ builder.withSubagentEventCallback((subagentEvent) => {
14212
+ if (subagentEvent.type === "llm_call_start") {
14213
+ const info = subagentEvent.event;
14214
+ const subagentId = `${subagentEvent.gadgetInvocationId}:${info.iteration}`;
14063
14215
  progress.addNestedAgent(
14064
- nestedId,
14065
- event.gadgetInvocationId,
14066
- event.depth,
14216
+ subagentId,
14217
+ subagentEvent.gadgetInvocationId,
14218
+ subagentEvent.depth,
14067
14219
  info.model,
14068
14220
  info.iteration,
14069
14221
  info.inputTokens
14070
14222
  );
14071
- } else if (event.type === "llm_call_end") {
14072
- const info = event.event;
14073
- const nestedId = `${event.gadgetInvocationId}:${info.iteration}`;
14074
- progress.updateNestedAgent(nestedId, info.outputTokens);
14075
- setTimeout(() => progress.removeNestedAgent(nestedId), 100);
14076
- } else if (event.type === "gadget_call") {
14077
- const gadgetEvent = event.event;
14223
+ } else if (subagentEvent.type === "llm_call_end") {
14224
+ const info = subagentEvent.event;
14225
+ const subagentId = `${subagentEvent.gadgetInvocationId}:${info.iteration}`;
14226
+ progress.updateNestedAgent(subagentId, info.outputTokens);
14227
+ setTimeout(() => progress.removeNestedAgent(subagentId), 100);
14228
+ } else if (subagentEvent.type === "gadget_call") {
14229
+ const gadgetEvent = subagentEvent.event;
14078
14230
  progress.addNestedGadget(
14079
14231
  gadgetEvent.call.invocationId,
14080
- event.depth,
14081
- event.gadgetInvocationId,
14232
+ subagentEvent.depth,
14233
+ subagentEvent.gadgetInvocationId,
14082
14234
  gadgetEvent.call.gadgetName
14083
14235
  );
14084
- } else if (event.type === "gadget_result") {
14085
- const resultEvent = event.event;
14086
- progress.removeNestedGadget(resultEvent.result.invocationId);
14236
+ } else if (subagentEvent.type === "gadget_result") {
14237
+ const resultEvent = subagentEvent.event;
14238
+ progress.completeNestedGadget(resultEvent.result.invocationId);
14087
14239
  }
14088
14240
  });
14089
14241
  }
@@ -14144,6 +14296,7 @@ Denied: ${result.reason ?? "by user"}`
14144
14296
  if (progress.hasInFlightGadgets()) {
14145
14297
  progress.start();
14146
14298
  }
14299
+ } else if (event.type === "subagent_event") {
14147
14300
  }
14148
14301
  }
14149
14302
  } catch (error) {