llmist 3.1.0 → 5.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/index.cjs CHANGED
@@ -3562,7 +3562,7 @@ var init_executor = __esm({
3562
3562
  init_exceptions();
3563
3563
  init_parser();
3564
3564
  GadgetExecutor = class {
3565
- constructor(registry, requestHumanInput, logger, defaultGadgetTimeoutMs, errorFormatterOptions, client, mediaStore, agentConfig, subagentConfig, onNestedEvent) {
3565
+ constructor(registry, requestHumanInput, logger, defaultGadgetTimeoutMs, errorFormatterOptions, client, mediaStore, agentConfig, subagentConfig, onSubagentEvent) {
3566
3566
  this.registry = registry;
3567
3567
  this.requestHumanInput = requestHumanInput;
3568
3568
  this.defaultGadgetTimeoutMs = defaultGadgetTimeoutMs;
@@ -3570,7 +3570,7 @@ var init_executor = __esm({
3570
3570
  this.mediaStore = mediaStore;
3571
3571
  this.agentConfig = agentConfig;
3572
3572
  this.subagentConfig = subagentConfig;
3573
- this.onNestedEvent = onNestedEvent;
3573
+ this.onSubagentEvent = onSubagentEvent;
3574
3574
  this.logger = logger ?? createLogger({ name: "llmist:executor" });
3575
3575
  this.errorFormatter = new GadgetExecutionErrorFormatter(errorFormatterOptions);
3576
3576
  this.argPrefix = errorFormatterOptions?.argPrefix ?? GADGET_ARG_PREFIX;
@@ -3718,7 +3718,7 @@ var init_executor = __esm({
3718
3718
  agentConfig: this.agentConfig,
3719
3719
  subagentConfig: this.subagentConfig,
3720
3720
  invocationId: call.invocationId,
3721
- onNestedEvent: this.onNestedEvent
3721
+ onSubagentEvent: this.onSubagentEvent
3722
3722
  };
3723
3723
  let rawResult;
3724
3724
  if (timeoutMs && timeoutMs > 0) {
@@ -3958,7 +3958,7 @@ var init_stream_processor = __esm({
3958
3958
  options.mediaStore,
3959
3959
  options.agentConfig,
3960
3960
  options.subagentConfig,
3961
- options.onNestedEvent
3961
+ options.onSubagentEvent
3962
3962
  );
3963
3963
  }
3964
3964
  /**
@@ -4917,8 +4917,12 @@ var init_agent = __esm({
4917
4917
  // Subagent configuration
4918
4918
  agentContextConfig;
4919
4919
  subagentConfig;
4920
- // Nested event callback for subagent gadgets
4921
- onNestedEvent;
4920
+ // Subagent event callback for subagent gadgets
4921
+ userSubagentEventCallback;
4922
+ // Internal queue for yielding subagent events in run()
4923
+ pendingSubagentEvents = [];
4924
+ // Combined callback that queues events AND calls user callback
4925
+ onSubagentEvent;
4922
4926
  /**
4923
4927
  * Creates a new Agent instance.
4924
4928
  * @internal This constructor is private. Use LLMist.createAgent() or AgentBuilder instead.
@@ -4996,7 +5000,72 @@ var init_agent = __esm({
4996
5000
  temperature: this.temperature
4997
5001
  };
4998
5002
  this.subagentConfig = options.subagentConfig;
4999
- this.onNestedEvent = options.onNestedEvent;
5003
+ this.userSubagentEventCallback = options.onSubagentEvent;
5004
+ this.onSubagentEvent = (event) => {
5005
+ this.pendingSubagentEvents.push(event);
5006
+ this.userSubagentEventCallback?.(event);
5007
+ const subagentContext = {
5008
+ parentGadgetInvocationId: event.gadgetInvocationId,
5009
+ depth: event.depth
5010
+ };
5011
+ if (event.type === "llm_call_start") {
5012
+ const info = event.event;
5013
+ void this.hooks?.observers?.onLLMCallStart?.({
5014
+ iteration: info.iteration,
5015
+ options: { model: info.model, messages: [] },
5016
+ logger: this.logger,
5017
+ subagentContext
5018
+ });
5019
+ } else if (event.type === "llm_call_end") {
5020
+ const info = event.event;
5021
+ const usage = info.usage ?? (info.outputTokens ? {
5022
+ inputTokens: info.inputTokens ?? 0,
5023
+ outputTokens: info.outputTokens,
5024
+ totalTokens: (info.inputTokens ?? 0) + info.outputTokens
5025
+ } : void 0);
5026
+ void this.hooks?.observers?.onLLMCallComplete?.({
5027
+ iteration: info.iteration,
5028
+ options: { model: info.model, messages: [] },
5029
+ finishReason: info.finishReason ?? null,
5030
+ usage,
5031
+ rawResponse: "",
5032
+ finalMessage: "",
5033
+ logger: this.logger,
5034
+ subagentContext
5035
+ });
5036
+ } else if (event.type === "gadget_call") {
5037
+ const gadgetEvent = event.event;
5038
+ void this.hooks?.observers?.onGadgetExecutionStart?.({
5039
+ iteration: 0,
5040
+ gadgetName: gadgetEvent.call.gadgetName,
5041
+ invocationId: gadgetEvent.call.invocationId,
5042
+ parameters: gadgetEvent.call.parameters ?? {},
5043
+ logger: this.logger,
5044
+ subagentContext
5045
+ });
5046
+ } else if (event.type === "gadget_result") {
5047
+ const resultEvent = event.event;
5048
+ void this.hooks?.observers?.onGadgetExecutionComplete?.({
5049
+ iteration: 0,
5050
+ gadgetName: resultEvent.result.gadgetName ?? "unknown",
5051
+ invocationId: resultEvent.result.invocationId,
5052
+ parameters: {},
5053
+ executionTimeMs: resultEvent.result.executionTimeMs ?? 0,
5054
+ logger: this.logger,
5055
+ subagentContext
5056
+ });
5057
+ }
5058
+ };
5059
+ }
5060
+ /**
5061
+ * Flush pending subagent events as StreamEvents.
5062
+ * Called from run() to yield queued subagent events from subagent gadgets.
5063
+ */
5064
+ *flushPendingSubagentEvents() {
5065
+ while (this.pendingSubagentEvents.length > 0) {
5066
+ const event = this.pendingSubagentEvents.shift();
5067
+ yield { type: "subagent_event", subagentEvent: event };
5068
+ }
5000
5069
  }
5001
5070
  /**
5002
5071
  * Get the gadget registry for this agent.
@@ -5228,7 +5297,7 @@ var init_agent = __esm({
5228
5297
  mediaStore: this.mediaStore,
5229
5298
  agentConfig: this.agentContextConfig,
5230
5299
  subagentConfig: this.subagentConfig,
5231
- onNestedEvent: this.onNestedEvent
5300
+ onSubagentEvent: this.onSubagentEvent
5232
5301
  });
5233
5302
  let streamMetadata = null;
5234
5303
  let gadgetCallCount = 0;
@@ -5246,6 +5315,7 @@ var init_agent = __esm({
5246
5315
  gadgetResults.push(event);
5247
5316
  }
5248
5317
  yield event;
5318
+ yield* this.flushPendingSubagentEvents();
5249
5319
  }
5250
5320
  if (!streamMetadata) {
5251
5321
  throw new Error("Stream processing completed without metadata event");
@@ -7000,6 +7070,9 @@ var init_gemini = __esm({
7000
7070
  async countTokens(messages, descriptor, _spec) {
7001
7071
  const client = this.client;
7002
7072
  const contents = this.convertMessagesToContents(messages);
7073
+ if (!contents || contents.length === 0) {
7074
+ return 0;
7075
+ }
7003
7076
  try {
7004
7077
  const response = await client.models.countTokens({
7005
7078
  model: descriptor.name,
@@ -8822,7 +8895,7 @@ var init_builder = __esm({
8822
8895
  signal;
8823
8896
  trailingMessage;
8824
8897
  subagentConfig;
8825
- nestedEventCallback;
8898
+ subagentEventCallback;
8826
8899
  parentContext;
8827
8900
  constructor(client) {
8828
8901
  this.client = client;
@@ -9321,38 +9394,38 @@ var init_builder = __esm({
9321
9394
  return this;
9322
9395
  }
9323
9396
  /**
9324
- * Set the callback for nested subagent events.
9397
+ * Set the callback for subagent events.
9325
9398
  *
9326
- * Subagent gadgets (like BrowseWeb) can use ExecutionContext.onNestedEvent
9399
+ * Subagent gadgets (like BrowseWeb) can use ExecutionContext.onSubagentEvent
9327
9400
  * to report their internal LLM calls and gadget executions in real-time.
9328
9401
  * This callback receives those events, enabling hierarchical progress display.
9329
9402
  *
9330
- * @param callback - Function to handle nested agent events
9403
+ * @param callback - Function to handle subagent events
9331
9404
  * @returns This builder for chaining
9332
9405
  *
9333
9406
  * @example
9334
9407
  * ```typescript
9335
- * .withNestedEventCallback((event) => {
9408
+ * .withSubagentEventCallback((event) => {
9336
9409
  * if (event.type === "llm_call_start") {
9337
- * console.log(` Nested LLM #${event.event.iteration} starting...`);
9410
+ * console.log(` Subagent LLM #${event.event.iteration} starting...`);
9338
9411
  * } else if (event.type === "gadget_call") {
9339
9412
  * console.log(` ⏵ ${event.event.call.gadgetName}...`);
9340
9413
  * }
9341
9414
  * })
9342
9415
  * ```
9343
9416
  */
9344
- withNestedEventCallback(callback) {
9345
- this.nestedEventCallback = callback;
9417
+ withSubagentEventCallback(callback) {
9418
+ this.subagentEventCallback = callback;
9346
9419
  return this;
9347
9420
  }
9348
9421
  /**
9349
- * Enable automatic nested event forwarding to parent agent.
9422
+ * Enable automatic subagent event forwarding to parent agent.
9350
9423
  *
9351
9424
  * When building a subagent inside a gadget, call this method to automatically
9352
9425
  * forward all LLM calls and gadget events to the parent agent. This enables
9353
9426
  * hierarchical progress display without any manual event handling.
9354
9427
  *
9355
- * The method extracts `invocationId` and `onNestedEvent` from the execution
9428
+ * The method extracts `invocationId` and `onSubagentEvent` from the execution
9356
9429
  * context and sets up automatic forwarding via hooks and event wrapping.
9357
9430
  *
9358
9431
  * @param ctx - ExecutionContext passed to the gadget's execute() method
@@ -9379,10 +9452,10 @@ var init_builder = __esm({
9379
9452
  * ```
9380
9453
  */
9381
9454
  withParentContext(ctx, depth = 1) {
9382
- if (ctx.onNestedEvent && ctx.invocationId) {
9455
+ if (ctx.onSubagentEvent && ctx.invocationId) {
9383
9456
  this.parentContext = {
9384
9457
  invocationId: ctx.invocationId,
9385
- onNestedEvent: ctx.onNestedEvent,
9458
+ onSubagentEvent: ctx.onSubagentEvent,
9386
9459
  depth
9387
9460
  };
9388
9461
  }
@@ -9457,20 +9530,22 @@ ${endPrefix}`
9457
9530
  /**
9458
9531
  * Compose the final hooks, including:
9459
9532
  * - Trailing message injection (if configured)
9460
- * - Nested event forwarding for LLM calls (if parentContext is set)
9533
+ * - Subagent event forwarding for LLM calls (if parentContext is set)
9461
9534
  */
9462
9535
  composeHooks() {
9463
9536
  let hooks = this.hooks;
9464
9537
  if (this.parentContext) {
9465
- const { invocationId, onNestedEvent, depth } = this.parentContext;
9538
+ const { invocationId, onSubagentEvent, depth } = this.parentContext;
9466
9539
  const existingOnLLMCallStart = hooks?.observers?.onLLMCallStart;
9467
9540
  const existingOnLLMCallComplete = hooks?.observers?.onLLMCallComplete;
9541
+ const existingOnGadgetExecutionStart = hooks?.observers?.onGadgetExecutionStart;
9542
+ const existingOnGadgetExecutionComplete = hooks?.observers?.onGadgetExecutionComplete;
9468
9543
  hooks = {
9469
9544
  ...hooks,
9470
9545
  observers: {
9471
9546
  ...hooks?.observers,
9472
9547
  onLLMCallStart: async (context) => {
9473
- onNestedEvent({
9548
+ onSubagentEvent({
9474
9549
  type: "llm_call_start",
9475
9550
  gadgetInvocationId: invocationId,
9476
9551
  depth,
@@ -9484,20 +9559,57 @@ ${endPrefix}`
9484
9559
  }
9485
9560
  },
9486
9561
  onLLMCallComplete: async (context) => {
9487
- onNestedEvent({
9562
+ onSubagentEvent({
9488
9563
  type: "llm_call_end",
9489
9564
  gadgetInvocationId: invocationId,
9490
9565
  depth,
9491
9566
  event: {
9492
9567
  iteration: context.iteration,
9493
9568
  model: context.options.model,
9569
+ // Backward compat fields
9570
+ inputTokens: context.usage?.inputTokens,
9494
9571
  outputTokens: context.usage?.outputTokens,
9495
- finishReason: context.finishReason
9572
+ finishReason: context.finishReason ?? void 0,
9573
+ // Full usage object with cache details (for first-class display)
9574
+ usage: context.usage
9575
+ // Cost will be calculated by parent if it has model registry
9496
9576
  }
9497
9577
  });
9498
9578
  if (existingOnLLMCallComplete) {
9499
9579
  await existingOnLLMCallComplete(context);
9500
9580
  }
9581
+ },
9582
+ onGadgetExecutionStart: async (context) => {
9583
+ onSubagentEvent({
9584
+ type: "gadget_call",
9585
+ gadgetInvocationId: invocationId,
9586
+ depth,
9587
+ event: {
9588
+ call: {
9589
+ invocationId: context.invocationId,
9590
+ gadgetName: context.gadgetName,
9591
+ parameters: context.parameters
9592
+ }
9593
+ }
9594
+ });
9595
+ if (existingOnGadgetExecutionStart) {
9596
+ await existingOnGadgetExecutionStart(context);
9597
+ }
9598
+ },
9599
+ onGadgetExecutionComplete: async (context) => {
9600
+ onSubagentEvent({
9601
+ type: "gadget_result",
9602
+ gadgetInvocationId: invocationId,
9603
+ depth,
9604
+ event: {
9605
+ result: {
9606
+ invocationId: context.invocationId
9607
+ }
9608
+ }
9609
+ });
9610
+ if (existingOnGadgetExecutionComplete) {
9611
+ await existingOnGadgetExecutionComplete(context);
9612
+ }
9501
9613
  }
9502
9614
  }
9503
9615
  };
@@ -9584,11 +9696,11 @@ ${endPrefix}`
9584
9696
  this.client = new LLMistClass();
9585
9697
  }
9586
9698
  const registry = GadgetRegistry.from(this.gadgets);
9587
- let onNestedEvent = this.nestedEventCallback;
9699
+ let onSubagentEvent = this.subagentEventCallback;
9588
9700
  if (this.parentContext) {
9589
- const { invocationId, onNestedEvent: parentCallback, depth } = this.parentContext;
9590
- const existingCallback = this.nestedEventCallback;
9591
- onNestedEvent = (event) => {
9701
+ const { invocationId, onSubagentEvent: parentCallback, depth } = this.parentContext;
9702
+ const existingCallback = this.subagentEventCallback;
9703
+ onSubagentEvent = (event) => {
9592
9704
  parentCallback({
9593
9705
  ...event,
9594
9706
  gadgetInvocationId: invocationId,
@@ -9623,7 +9735,7 @@ ${endPrefix}`
9623
9735
  compactionConfig: this.compactionConfig,
9624
9736
  signal: this.signal,
9625
9737
  subagentConfig: this.subagentConfig,
9626
- onNestedEvent
9738
+ onSubagentEvent
9627
9739
  };
9628
9740
  }
9629
9741
  ask(userPrompt) {
@@ -9780,11 +9892,11 @@ ${endPrefix}`
9780
9892
  this.client = new LLMistClass();
9781
9893
  }
9782
9894
  const registry = GadgetRegistry.from(this.gadgets);
9783
- let onNestedEvent = this.nestedEventCallback;
9895
+ let onSubagentEvent = this.subagentEventCallback;
9784
9896
  if (this.parentContext) {
9785
- const { invocationId, onNestedEvent: parentCallback, depth } = this.parentContext;
9786
- const existingCallback = this.nestedEventCallback;
9787
- onNestedEvent = (event) => {
9897
+ const { invocationId, onSubagentEvent: parentCallback, depth } = this.parentContext;
9898
+ const existingCallback = this.subagentEventCallback;
9899
+ onSubagentEvent = (event) => {
9788
9900
  parentCallback({
9789
9901
  ...event,
9790
9902
  gadgetInvocationId: invocationId,
@@ -9819,7 +9931,7 @@ ${endPrefix}`
9819
9931
  compactionConfig: this.compactionConfig,
9820
9932
  signal: this.signal,
9821
9933
  subagentConfig: this.subagentConfig,
9822
- onNestedEvent
9934
+ onSubagentEvent
9823
9935
  };
9824
9936
  return new Agent(AGENT_INTERNAL_KEY, options);
9825
9937
  }