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.
@@ -3485,7 +3485,7 @@ var init_executor = __esm({
3485
3485
  init_exceptions();
3486
3486
  init_parser();
3487
3487
  GadgetExecutor = class {
3488
- constructor(registry, requestHumanInput, logger, defaultGadgetTimeoutMs, errorFormatterOptions, client, mediaStore, agentConfig, subagentConfig, onNestedEvent) {
3488
+ constructor(registry, requestHumanInput, logger, defaultGadgetTimeoutMs, errorFormatterOptions, client, mediaStore, agentConfig, subagentConfig, onSubagentEvent) {
3489
3489
  this.registry = registry;
3490
3490
  this.requestHumanInput = requestHumanInput;
3491
3491
  this.defaultGadgetTimeoutMs = defaultGadgetTimeoutMs;
@@ -3493,7 +3493,7 @@ var init_executor = __esm({
3493
3493
  this.mediaStore = mediaStore;
3494
3494
  this.agentConfig = agentConfig;
3495
3495
  this.subagentConfig = subagentConfig;
3496
- this.onNestedEvent = onNestedEvent;
3496
+ this.onSubagentEvent = onSubagentEvent;
3497
3497
  this.logger = logger ?? createLogger({ name: "llmist:executor" });
3498
3498
  this.errorFormatter = new GadgetExecutionErrorFormatter(errorFormatterOptions);
3499
3499
  this.argPrefix = errorFormatterOptions?.argPrefix ?? GADGET_ARG_PREFIX;
@@ -3641,7 +3641,7 @@ var init_executor = __esm({
3641
3641
  agentConfig: this.agentConfig,
3642
3642
  subagentConfig: this.subagentConfig,
3643
3643
  invocationId: call.invocationId,
3644
- onNestedEvent: this.onNestedEvent
3644
+ onSubagentEvent: this.onSubagentEvent
3645
3645
  };
3646
3646
  let rawResult;
3647
3647
  if (timeoutMs && timeoutMs > 0) {
@@ -3881,7 +3881,7 @@ var init_stream_processor = __esm({
3881
3881
  options.mediaStore,
3882
3882
  options.agentConfig,
3883
3883
  options.subagentConfig,
3884
- options.onNestedEvent
3884
+ options.onSubagentEvent
3885
3885
  );
3886
3886
  }
3887
3887
  /**
@@ -4840,8 +4840,12 @@ var init_agent = __esm({
4840
4840
  // Subagent configuration
4841
4841
  agentContextConfig;
4842
4842
  subagentConfig;
4843
- // Nested event callback for subagent gadgets
4844
- onNestedEvent;
4843
+ // Subagent event callback for subagent gadgets
4844
+ userSubagentEventCallback;
4845
+ // Internal queue for yielding subagent events in run()
4846
+ pendingSubagentEvents = [];
4847
+ // Combined callback that queues events AND calls user callback
4848
+ onSubagentEvent;
4845
4849
  /**
4846
4850
  * Creates a new Agent instance.
4847
4851
  * @internal This constructor is private. Use LLMist.createAgent() or AgentBuilder instead.
@@ -4919,7 +4923,72 @@ var init_agent = __esm({
4919
4923
  temperature: this.temperature
4920
4924
  };
4921
4925
  this.subagentConfig = options.subagentConfig;
4922
- this.onNestedEvent = options.onNestedEvent;
4926
+ this.userSubagentEventCallback = options.onSubagentEvent;
4927
+ this.onSubagentEvent = (event) => {
4928
+ this.pendingSubagentEvents.push(event);
4929
+ this.userSubagentEventCallback?.(event);
4930
+ const subagentContext = {
4931
+ parentGadgetInvocationId: event.gadgetInvocationId,
4932
+ depth: event.depth
4933
+ };
4934
+ if (event.type === "llm_call_start") {
4935
+ const info = event.event;
4936
+ void this.hooks?.observers?.onLLMCallStart?.({
4937
+ iteration: info.iteration,
4938
+ options: { model: info.model, messages: [] },
4939
+ logger: this.logger,
4940
+ subagentContext
4941
+ });
4942
+ } else if (event.type === "llm_call_end") {
4943
+ const info = event.event;
4944
+ const usage = info.usage ?? (info.outputTokens ? {
4945
+ inputTokens: info.inputTokens ?? 0,
4946
+ outputTokens: info.outputTokens,
4947
+ totalTokens: (info.inputTokens ?? 0) + info.outputTokens
4948
+ } : void 0);
4949
+ void this.hooks?.observers?.onLLMCallComplete?.({
4950
+ iteration: info.iteration,
4951
+ options: { model: info.model, messages: [] },
4952
+ finishReason: info.finishReason ?? null,
4953
+ usage,
4954
+ rawResponse: "",
4955
+ finalMessage: "",
4956
+ logger: this.logger,
4957
+ subagentContext
4958
+ });
4959
+ } else if (event.type === "gadget_call") {
4960
+ const gadgetEvent = event.event;
4961
+ void this.hooks?.observers?.onGadgetExecutionStart?.({
4962
+ iteration: 0,
4963
+ gadgetName: gadgetEvent.call.gadgetName,
4964
+ invocationId: gadgetEvent.call.invocationId,
4965
+ parameters: gadgetEvent.call.parameters ?? {},
4966
+ logger: this.logger,
4967
+ subagentContext
4968
+ });
4969
+ } else if (event.type === "gadget_result") {
4970
+ const resultEvent = event.event;
4971
+ void this.hooks?.observers?.onGadgetExecutionComplete?.({
4972
+ iteration: 0,
4973
+ gadgetName: resultEvent.result.gadgetName ?? "unknown",
4974
+ invocationId: resultEvent.result.invocationId,
4975
+ parameters: {},
4976
+ executionTimeMs: resultEvent.result.executionTimeMs ?? 0,
4977
+ logger: this.logger,
4978
+ subagentContext
4979
+ });
4980
+ }
4981
+ };
4982
+ }
4983
+ /**
4984
+ * Flush pending subagent events as StreamEvents.
4985
+ * Called from run() to yield queued subagent events from subagent gadgets.
4986
+ */
4987
+ *flushPendingSubagentEvents() {
4988
+ while (this.pendingSubagentEvents.length > 0) {
4989
+ const event = this.pendingSubagentEvents.shift();
4990
+ yield { type: "subagent_event", subagentEvent: event };
4991
+ }
4923
4992
  }
4924
4993
  /**
4925
4994
  * Get the gadget registry for this agent.
@@ -5151,7 +5220,7 @@ var init_agent = __esm({
5151
5220
  mediaStore: this.mediaStore,
5152
5221
  agentConfig: this.agentContextConfig,
5153
5222
  subagentConfig: this.subagentConfig,
5154
- onNestedEvent: this.onNestedEvent
5223
+ onSubagentEvent: this.onSubagentEvent
5155
5224
  });
5156
5225
  let streamMetadata = null;
5157
5226
  let gadgetCallCount = 0;
@@ -5169,6 +5238,7 @@ var init_agent = __esm({
5169
5238
  gadgetResults.push(event);
5170
5239
  }
5171
5240
  yield event;
5241
+ yield* this.flushPendingSubagentEvents();
5172
5242
  }
5173
5243
  if (!streamMetadata) {
5174
5244
  throw new Error("Stream processing completed without metadata event");
@@ -5474,7 +5544,7 @@ var init_builder = __esm({
5474
5544
  signal;
5475
5545
  trailingMessage;
5476
5546
  subagentConfig;
5477
- nestedEventCallback;
5547
+ subagentEventCallback;
5478
5548
  parentContext;
5479
5549
  constructor(client) {
5480
5550
  this.client = client;
@@ -5973,38 +6043,38 @@ var init_builder = __esm({
5973
6043
  return this;
5974
6044
  }
5975
6045
  /**
5976
- * Set the callback for nested subagent events.
6046
+ * Set the callback for subagent events.
5977
6047
  *
5978
- * Subagent gadgets (like BrowseWeb) can use ExecutionContext.onNestedEvent
6048
+ * Subagent gadgets (like BrowseWeb) can use ExecutionContext.onSubagentEvent
5979
6049
  * to report their internal LLM calls and gadget executions in real-time.
5980
6050
  * This callback receives those events, enabling hierarchical progress display.
5981
6051
  *
5982
- * @param callback - Function to handle nested agent events
6052
+ * @param callback - Function to handle subagent events
5983
6053
  * @returns This builder for chaining
5984
6054
  *
5985
6055
  * @example
5986
6056
  * ```typescript
5987
- * .withNestedEventCallback((event) => {
6057
+ * .withSubagentEventCallback((event) => {
5988
6058
  * if (event.type === "llm_call_start") {
5989
- * console.log(` Nested LLM #${event.event.iteration} starting...`);
6059
+ * console.log(` Subagent LLM #${event.event.iteration} starting...`);
5990
6060
  * } else if (event.type === "gadget_call") {
5991
6061
  * console.log(` ⏵ ${event.event.call.gadgetName}...`);
5992
6062
  * }
5993
6063
  * })
5994
6064
  * ```
5995
6065
  */
5996
- withNestedEventCallback(callback) {
5997
- this.nestedEventCallback = callback;
6066
+ withSubagentEventCallback(callback) {
6067
+ this.subagentEventCallback = callback;
5998
6068
  return this;
5999
6069
  }
6000
6070
  /**
6001
- * Enable automatic nested event forwarding to parent agent.
6071
+ * Enable automatic subagent event forwarding to parent agent.
6002
6072
  *
6003
6073
  * When building a subagent inside a gadget, call this method to automatically
6004
6074
  * forward all LLM calls and gadget events to the parent agent. This enables
6005
6075
  * hierarchical progress display without any manual event handling.
6006
6076
  *
6007
- * The method extracts `invocationId` and `onNestedEvent` from the execution
6077
+ * The method extracts `invocationId` and `onSubagentEvent` from the execution
6008
6078
  * context and sets up automatic forwarding via hooks and event wrapping.
6009
6079
  *
6010
6080
  * @param ctx - ExecutionContext passed to the gadget's execute() method
@@ -6031,10 +6101,10 @@ var init_builder = __esm({
6031
6101
  * ```
6032
6102
  */
6033
6103
  withParentContext(ctx, depth = 1) {
6034
- if (ctx.onNestedEvent && ctx.invocationId) {
6104
+ if (ctx.onSubagentEvent && ctx.invocationId) {
6035
6105
  this.parentContext = {
6036
6106
  invocationId: ctx.invocationId,
6037
- onNestedEvent: ctx.onNestedEvent,
6107
+ onSubagentEvent: ctx.onSubagentEvent,
6038
6108
  depth
6039
6109
  };
6040
6110
  }
@@ -6109,20 +6179,22 @@ ${endPrefix}`
6109
6179
  /**
6110
6180
  * Compose the final hooks, including:
6111
6181
  * - Trailing message injection (if configured)
6112
- * - Nested event forwarding for LLM calls (if parentContext is set)
6182
+ * - Subagent event forwarding for LLM calls (if parentContext is set)
6113
6183
  */
6114
6184
  composeHooks() {
6115
6185
  let hooks = this.hooks;
6116
6186
  if (this.parentContext) {
6117
- const { invocationId, onNestedEvent, depth } = this.parentContext;
6187
+ const { invocationId, onSubagentEvent, depth } = this.parentContext;
6118
6188
  const existingOnLLMCallStart = hooks?.observers?.onLLMCallStart;
6119
6189
  const existingOnLLMCallComplete = hooks?.observers?.onLLMCallComplete;
6190
+ const existingOnGadgetExecutionStart = hooks?.observers?.onGadgetExecutionStart;
6191
+ const existingOnGadgetExecutionComplete = hooks?.observers?.onGadgetExecutionComplete;
6120
6192
  hooks = {
6121
6193
  ...hooks,
6122
6194
  observers: {
6123
6195
  ...hooks?.observers,
6124
6196
  onLLMCallStart: async (context) => {
6125
- onNestedEvent({
6197
+ onSubagentEvent({
6126
6198
  type: "llm_call_start",
6127
6199
  gadgetInvocationId: invocationId,
6128
6200
  depth,
@@ -6136,20 +6208,57 @@ ${endPrefix}`
6136
6208
  }
6137
6209
  },
6138
6210
  onLLMCallComplete: async (context) => {
6139
- onNestedEvent({
6211
+ onSubagentEvent({
6140
6212
  type: "llm_call_end",
6141
6213
  gadgetInvocationId: invocationId,
6142
6214
  depth,
6143
6215
  event: {
6144
6216
  iteration: context.iteration,
6145
6217
  model: context.options.model,
6218
+ // Backward compat fields
6219
+ inputTokens: context.usage?.inputTokens,
6146
6220
  outputTokens: context.usage?.outputTokens,
6147
- finishReason: context.finishReason
6221
+ finishReason: context.finishReason ?? void 0,
6222
+ // Full usage object with cache details (for first-class display)
6223
+ usage: context.usage
6224
+ // Cost will be calculated by parent if it has model registry
6148
6225
  }
6149
6226
  });
6150
6227
  if (existingOnLLMCallComplete) {
6151
6228
  await existingOnLLMCallComplete(context);
6152
6229
  }
6230
+ },
6231
+ onGadgetExecutionStart: async (context) => {
6232
+ onSubagentEvent({
6233
+ type: "gadget_call",
6234
+ gadgetInvocationId: invocationId,
6235
+ depth,
6236
+ event: {
6237
+ call: {
6238
+ invocationId: context.invocationId,
6239
+ gadgetName: context.gadgetName,
6240
+ parameters: context.parameters
6241
+ }
6242
+ }
6243
+ });
6244
+ if (existingOnGadgetExecutionStart) {
6245
+ await existingOnGadgetExecutionStart(context);
6246
+ }
6247
+ },
6248
+ onGadgetExecutionComplete: async (context) => {
6249
+ onSubagentEvent({
6250
+ type: "gadget_result",
6251
+ gadgetInvocationId: invocationId,
6252
+ depth,
6253
+ event: {
6254
+ result: {
6255
+ invocationId: context.invocationId
6256
+ }
6257
+ }
6258
+ });
6259
+ if (existingOnGadgetExecutionComplete) {
6260
+ await existingOnGadgetExecutionComplete(context);
6261
+ }
6153
6262
  }
6154
6263
  }
6155
6264
  };
@@ -6236,11 +6345,11 @@ ${endPrefix}`
6236
6345
  this.client = new LLMistClass();
6237
6346
  }
6238
6347
  const registry = GadgetRegistry.from(this.gadgets);
6239
- let onNestedEvent = this.nestedEventCallback;
6348
+ let onSubagentEvent = this.subagentEventCallback;
6240
6349
  if (this.parentContext) {
6241
- const { invocationId, onNestedEvent: parentCallback, depth } = this.parentContext;
6242
- const existingCallback = this.nestedEventCallback;
6243
- onNestedEvent = (event) => {
6350
+ const { invocationId, onSubagentEvent: parentCallback, depth } = this.parentContext;
6351
+ const existingCallback = this.subagentEventCallback;
6352
+ onSubagentEvent = (event) => {
6244
6353
  parentCallback({
6245
6354
  ...event,
6246
6355
  gadgetInvocationId: invocationId,
@@ -6275,7 +6384,7 @@ ${endPrefix}`
6275
6384
  compactionConfig: this.compactionConfig,
6276
6385
  signal: this.signal,
6277
6386
  subagentConfig: this.subagentConfig,
6278
- onNestedEvent
6387
+ onSubagentEvent
6279
6388
  };
6280
6389
  }
6281
6390
  ask(userPrompt) {
@@ -6432,11 +6541,11 @@ ${endPrefix}`
6432
6541
  this.client = new LLMistClass();
6433
6542
  }
6434
6543
  const registry = GadgetRegistry.from(this.gadgets);
6435
- let onNestedEvent = this.nestedEventCallback;
6544
+ let onSubagentEvent = this.subagentEventCallback;
6436
6545
  if (this.parentContext) {
6437
- const { invocationId, onNestedEvent: parentCallback, depth } = this.parentContext;
6438
- const existingCallback = this.nestedEventCallback;
6439
- onNestedEvent = (event) => {
6546
+ const { invocationId, onSubagentEvent: parentCallback, depth } = this.parentContext;
6547
+ const existingCallback = this.subagentEventCallback;
6548
+ onSubagentEvent = (event) => {
6440
6549
  parentCallback({
6441
6550
  ...event,
6442
6551
  gadgetInvocationId: invocationId,
@@ -6471,7 +6580,7 @@ ${endPrefix}`
6471
6580
  compactionConfig: this.compactionConfig,
6472
6581
  signal: this.signal,
6473
6582
  subagentConfig: this.subagentConfig,
6474
- onNestedEvent
6583
+ onSubagentEvent
6475
6584
  };
6476
6585
  return new Agent(AGENT_INTERNAL_KEY, options);
6477
6586
  }
@@ -7966,6 +8075,9 @@ var init_gemini = __esm({
7966
8075
  async countTokens(messages, descriptor, _spec) {
7967
8076
  const client = this.client;
7968
8077
  const contents = this.convertMessagesToContents(messages);
8078
+ if (!contents || contents.length === 0) {
8079
+ return 0;
8080
+ }
7969
8081
  try {
7970
8082
  const response = await client.models.countTokens({
7971
8083
  model: descriptor.name,