llmist 0.3.1 → 0.4.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
@@ -4281,7 +4281,8 @@ var OPTION_FLAGS = {
4281
4281
  parameterFormat: "--parameter-format <format>",
4282
4282
  logLevel: "--log-level <level>",
4283
4283
  logFile: "--log-file <path>",
4284
- noBuiltins: "--no-builtins"
4284
+ noBuiltins: "--no-builtins",
4285
+ noBuiltinInteraction: "--no-builtin-interaction"
4285
4286
  };
4286
4287
  var OPTION_DESCRIPTIONS = {
4287
4288
  model: "Model identifier, e.g. openai:gpt-5-nano or anthropic:claude-sonnet-4-5.",
@@ -4293,7 +4294,8 @@ var OPTION_DESCRIPTIONS = {
4293
4294
  parameterFormat: "Format for gadget parameter schemas: 'json', 'yaml', or 'auto'.",
4294
4295
  logLevel: "Log level: silly, trace, debug, info, warn, error, fatal.",
4295
4296
  logFile: "Path to log file. When set, logs are written to file instead of stderr.",
4296
- noBuiltins: "Disable built-in gadgets (AskUser, TellUser)."
4297
+ noBuiltins: "Disable built-in gadgets (AskUser, TellUser).",
4298
+ noBuiltinInteraction: "Disable interactive gadgets (AskUser) while keeping TellUser."
4297
4299
  };
4298
4300
  var SUMMARY_PREFIX = "[llmist]";
4299
4301
 
@@ -4303,7 +4305,7 @@ var import_commander3 = require("commander");
4303
4305
  // package.json
4304
4306
  var package_default = {
4305
4307
  name: "llmist",
4306
- version: "0.3.0",
4308
+ version: "0.3.1",
4307
4309
  description: "Universal TypeScript LLM client with streaming-first agent framework. Works with any model - no structured outputs or native tool calling required. Implements its own flexible grammar for function calling.",
4308
4310
  type: "module",
4309
4311
  main: "dist/index.cjs",
@@ -4412,7 +4414,6 @@ var package_default = {
4412
4414
 
4413
4415
  // src/cli/agent-command.ts
4414
4416
  var import_promises = require("readline/promises");
4415
- var import_chalk2 = __toESM(require("chalk"), 1);
4416
4417
  var import_commander2 = require("commander");
4417
4418
  init_builder();
4418
4419
  init_registry();
@@ -4706,9 +4707,67 @@ async function loadGadgets(specifiers, cwd, importer = (specifier) => import(spe
4706
4707
  }
4707
4708
 
4708
4709
  // src/cli/utils.ts
4709
- var import_chalk = __toESM(require("chalk"), 1);
4710
+ var import_chalk2 = __toESM(require("chalk"), 1);
4710
4711
  var import_commander = require("commander");
4711
4712
  init_constants2();
4713
+
4714
+ // src/cli/ui/formatters.ts
4715
+ var import_chalk = __toESM(require("chalk"), 1);
4716
+ function formatTokens(tokens) {
4717
+ return tokens >= 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : `${tokens}`;
4718
+ }
4719
+ function formatCost(cost) {
4720
+ if (cost < 1e-3) {
4721
+ return cost.toFixed(5);
4722
+ }
4723
+ if (cost < 0.01) {
4724
+ return cost.toFixed(4);
4725
+ }
4726
+ if (cost < 1) {
4727
+ return cost.toFixed(3);
4728
+ }
4729
+ return cost.toFixed(2);
4730
+ }
4731
+ function renderSummary(metadata) {
4732
+ const parts = [];
4733
+ if (metadata.iterations !== void 0) {
4734
+ parts.push(import_chalk.default.cyan(`#${metadata.iterations}`));
4735
+ }
4736
+ if (metadata.usage) {
4737
+ const { inputTokens, outputTokens } = metadata.usage;
4738
+ parts.push(import_chalk.default.dim("\u2191") + import_chalk.default.yellow(` ${formatTokens(inputTokens)}`));
4739
+ parts.push(import_chalk.default.dim("\u2193") + import_chalk.default.green(` ${formatTokens(outputTokens)}`));
4740
+ }
4741
+ if (metadata.elapsedSeconds !== void 0 && metadata.elapsedSeconds > 0) {
4742
+ parts.push(import_chalk.default.dim(`${metadata.elapsedSeconds}s`));
4743
+ }
4744
+ if (metadata.cost !== void 0 && metadata.cost > 0) {
4745
+ parts.push(import_chalk.default.cyan(`$${formatCost(metadata.cost)}`));
4746
+ }
4747
+ if (metadata.finishReason) {
4748
+ parts.push(import_chalk.default.dim(metadata.finishReason));
4749
+ }
4750
+ if (parts.length === 0) {
4751
+ return null;
4752
+ }
4753
+ return parts.join(import_chalk.default.dim(" | "));
4754
+ }
4755
+ function formatGadgetSummary(result) {
4756
+ const gadgetLabel = import_chalk.default.magenta.bold(result.gadgetName);
4757
+ const timeLabel = import_chalk.default.dim(`${Math.round(result.executionTimeMs)}ms`);
4758
+ if (result.error) {
4759
+ return `${import_chalk.default.red("\u2717")} ${gadgetLabel} ${import_chalk.default.red("error:")} ${result.error} ${timeLabel}`;
4760
+ }
4761
+ if (result.breaksLoop) {
4762
+ return `${import_chalk.default.yellow("\u23F9")} ${gadgetLabel} ${import_chalk.default.yellow("finished:")} ${result.result} ${timeLabel}`;
4763
+ }
4764
+ const maxLen = 80;
4765
+ const shouldTruncate = result.gadgetName !== "TellUser";
4766
+ const resultText = result.result ? shouldTruncate && result.result.length > maxLen ? `${result.result.slice(0, maxLen)}...` : result.result : "";
4767
+ return `${import_chalk.default.green("\u2713")} ${gadgetLabel} ${import_chalk.default.dim("\u2192")} ${resultText} ${timeLabel}`;
4768
+ }
4769
+
4770
+ // src/cli/utils.ts
4712
4771
  function createNumericParser({
4713
4772
  label,
4714
4773
  integer = false,
@@ -4791,15 +4850,20 @@ var StreamProgress = class {
4791
4850
  totalTokens = 0;
4792
4851
  totalCost = 0;
4793
4852
  iterations = 0;
4853
+ currentIteration = 0;
4794
4854
  /**
4795
4855
  * Starts a new LLM call. Switches to streaming mode.
4796
4856
  * @param model - Model name being used
4797
- * @param estimatedInputTokens - Estimated input tokens based on prompt length
4857
+ * @param estimatedInputTokens - Initial input token count. Should come from
4858
+ * client.countTokens() for accuracy (provider-specific counting), not
4859
+ * character-based estimation. Will be updated with provider-returned counts
4860
+ * via setInputTokens() during streaming if available.
4798
4861
  */
4799
4862
  startCall(model, estimatedInputTokens) {
4800
4863
  this.mode = "streaming";
4801
4864
  this.model = model;
4802
4865
  this.callStartTime = Date.now();
4866
+ this.currentIteration++;
4803
4867
  this.callInputTokens = estimatedInputTokens ?? 0;
4804
4868
  this.callInputTokensEstimated = true;
4805
4869
  this.callOutputTokens = 0;
@@ -4836,8 +4900,10 @@ var StreamProgress = class {
4836
4900
  }
4837
4901
  /**
4838
4902
  * Sets the input token count for current call (from stream metadata).
4839
- * @param tokens - Token count
4840
- * @param estimated - If true, shown with ~ prefix until actual count arrives
4903
+ * @param tokens - Token count from provider or client.countTokens()
4904
+ * @param estimated - If true, this is a fallback estimate (character-based).
4905
+ * If false, this is an accurate count from the provider API or client.countTokens().
4906
+ * Display shows ~ prefix only when estimated=true.
4841
4907
  */
4842
4908
  setInputTokens(tokens, estimated = false) {
4843
4909
  if (estimated && !this.callInputTokensEstimated) {
@@ -4848,8 +4914,10 @@ var StreamProgress = class {
4848
4914
  }
4849
4915
  /**
4850
4916
  * Sets the output token count for current call (from stream metadata).
4851
- * @param tokens - Token count
4852
- * @param estimated - If true, shown with ~ prefix until actual count arrives
4917
+ * @param tokens - Token count from provider streaming response
4918
+ * @param estimated - If true, this is a fallback estimate (character-based).
4919
+ * If false, this is an accurate count from the provider's streaming metadata.
4920
+ * Display shows ~ prefix only when estimated=true.
4853
4921
  */
4854
4922
  setOutputTokens(tokens, estimated = false) {
4855
4923
  if (estimated && !this.callOutputTokensEstimated) {
@@ -4858,6 +4926,14 @@ var StreamProgress = class {
4858
4926
  this.callOutputTokens = tokens;
4859
4927
  this.callOutputTokensEstimated = estimated;
4860
4928
  }
4929
+ /**
4930
+ * Get total elapsed time in seconds since the first call started.
4931
+ * @returns Elapsed time in seconds with 1 decimal place
4932
+ */
4933
+ getTotalElapsedSeconds() {
4934
+ if (this.totalStartTime === 0) return 0;
4935
+ return Number(((Date.now() - this.totalStartTime) / 1e3).toFixed(1));
4936
+ }
4861
4937
  /**
4862
4938
  * Starts the progress indicator animation after a brief delay.
4863
4939
  */
@@ -4892,40 +4968,38 @@ var StreamProgress = class {
4892
4968
  const elapsed = ((Date.now() - this.callStartTime) / 1e3).toFixed(1);
4893
4969
  const outTokens = this.callOutputTokensEstimated ? Math.round(this.callOutputChars / FALLBACK_CHARS_PER_TOKEN) : this.callOutputTokens;
4894
4970
  const parts = [];
4895
- if (this.model) {
4896
- parts.push(import_chalk.default.cyan(this.model));
4897
- }
4971
+ parts.push(import_chalk2.default.cyan(`#${this.currentIteration}`));
4898
4972
  if (this.callInputTokens > 0) {
4899
4973
  const prefix = this.callInputTokensEstimated ? "~" : "";
4900
- parts.push(import_chalk.default.dim("out:") + import_chalk.default.yellow(` ${prefix}${this.callInputTokens}`));
4974
+ parts.push(import_chalk2.default.dim("\u2191") + import_chalk2.default.yellow(` ${prefix}${formatTokens(this.callInputTokens)}`));
4901
4975
  }
4902
4976
  if (this.isStreaming || outTokens > 0) {
4903
4977
  const prefix = this.callOutputTokensEstimated ? "~" : "";
4904
- parts.push(import_chalk.default.dim("in:") + import_chalk.default.green(` ${prefix}${outTokens}`));
4978
+ parts.push(import_chalk2.default.dim("\u2193") + import_chalk2.default.green(` ${prefix}${formatTokens(outTokens)}`));
4905
4979
  }
4980
+ parts.push(import_chalk2.default.dim(`${elapsed}s`));
4906
4981
  if (this.totalCost > 0) {
4907
- parts.push(import_chalk.default.dim("cost:") + import_chalk.default.cyan(` $${this.formatCost(this.totalCost)}`));
4982
+ parts.push(import_chalk2.default.cyan(`$${formatCost(this.totalCost)}`));
4908
4983
  }
4909
- parts.push(import_chalk.default.dim(`${elapsed}s`));
4910
- this.target.write(`\r${import_chalk.default.cyan(spinner)} ${parts.join(import_chalk.default.dim(" | "))}`);
4984
+ this.target.write(`\r${import_chalk2.default.cyan(spinner)} ${parts.join(import_chalk2.default.dim(" | "))}`);
4911
4985
  }
4912
4986
  renderCumulativeMode(spinner) {
4913
4987
  const elapsed = ((Date.now() - this.totalStartTime) / 1e3).toFixed(1);
4914
4988
  const parts = [];
4915
4989
  if (this.model) {
4916
- parts.push(import_chalk.default.cyan(this.model));
4990
+ parts.push(import_chalk2.default.cyan(this.model));
4917
4991
  }
4918
4992
  if (this.totalTokens > 0) {
4919
- parts.push(import_chalk.default.dim("total:") + import_chalk.default.magenta(` ${this.totalTokens}`));
4993
+ parts.push(import_chalk2.default.dim("total:") + import_chalk2.default.magenta(` ${this.totalTokens}`));
4920
4994
  }
4921
4995
  if (this.iterations > 0) {
4922
- parts.push(import_chalk.default.dim("iter:") + import_chalk.default.blue(` ${this.iterations}`));
4996
+ parts.push(import_chalk2.default.dim("iter:") + import_chalk2.default.blue(` ${this.iterations}`));
4923
4997
  }
4924
4998
  if (this.totalCost > 0) {
4925
- parts.push(import_chalk.default.dim("cost:") + import_chalk.default.cyan(` $${this.formatCost(this.totalCost)}`));
4999
+ parts.push(import_chalk2.default.dim("cost:") + import_chalk2.default.cyan(` $${formatCost(this.totalCost)}`));
4926
5000
  }
4927
- parts.push(import_chalk.default.dim(`${elapsed}s`));
4928
- this.target.write(`\r${import_chalk.default.cyan(spinner)} ${parts.join(import_chalk.default.dim(" | "))}`);
5001
+ parts.push(import_chalk2.default.dim(`${elapsed}s`));
5002
+ this.target.write(`\r${import_chalk2.default.cyan(spinner)} ${parts.join(import_chalk2.default.dim(" | "))}`);
4929
5003
  }
4930
5004
  /**
4931
5005
  * Pauses the progress indicator and clears the line.
@@ -4973,49 +5047,28 @@ var StreamProgress = class {
4973
5047
  if (this.callInputTokens > 0) {
4974
5048
  const prefix = this.callInputTokensEstimated ? "~" : "";
4975
5049
  parts.push(
4976
- import_chalk.default.dim("out:") + import_chalk.default.yellow(` ${prefix}${this.formatTokens(this.callInputTokens)}`)
5050
+ import_chalk2.default.dim("\u2191") + import_chalk2.default.yellow(` ${prefix}${formatTokens(this.callInputTokens)}`)
4977
5051
  );
4978
5052
  }
4979
5053
  if (outTokens > 0) {
4980
5054
  const prefix = outEstimated ? "~" : "";
4981
- parts.push(import_chalk.default.dim("in:") + import_chalk.default.green(` ${prefix}${this.formatTokens(outTokens)}`));
5055
+ parts.push(import_chalk2.default.dim("\u2193") + import_chalk2.default.green(` ${prefix}${formatTokens(outTokens)}`));
4982
5056
  }
4983
- parts.push(import_chalk.default.dim(`${elapsed}s`));
5057
+ parts.push(import_chalk2.default.dim(`${elapsed}s`));
4984
5058
  } else {
4985
5059
  const elapsed = Math.round((Date.now() - this.totalStartTime) / 1e3);
4986
5060
  if (this.totalTokens > 0) {
4987
- parts.push(import_chalk.default.magenta(this.formatTokens(this.totalTokens)));
5061
+ parts.push(import_chalk2.default.magenta(formatTokens(this.totalTokens)));
4988
5062
  }
4989
5063
  if (this.iterations > 0) {
4990
- parts.push(import_chalk.default.blue(`i${this.iterations}`));
5064
+ parts.push(import_chalk2.default.blue(`i${this.iterations}`));
4991
5065
  }
4992
5066
  if (this.totalCost > 0) {
4993
- parts.push(import_chalk.default.cyan(`$${this.formatCost(this.totalCost)}`));
5067
+ parts.push(import_chalk2.default.cyan(`$${formatCost(this.totalCost)}`));
4994
5068
  }
4995
- parts.push(import_chalk.default.dim(`${elapsed}s`));
4996
- }
4997
- return `${parts.join(import_chalk.default.dim(" \u2502 "))} ${import_chalk.default.green(">")} `;
4998
- }
4999
- /**
5000
- * Formats token count compactly (3625 -> "3.6k").
5001
- */
5002
- formatTokens(tokens) {
5003
- return tokens >= 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : `${tokens}`;
5004
- }
5005
- /**
5006
- * Formats cost compactly (0.0001234 -> "0.00012", 0.1234 -> "0.12", 1.234 -> "1.23").
5007
- */
5008
- formatCost(cost) {
5009
- if (cost < 1e-3) {
5010
- return cost.toFixed(5);
5011
- }
5012
- if (cost < 0.01) {
5013
- return cost.toFixed(4);
5014
- }
5015
- if (cost < 1) {
5016
- return cost.toFixed(3);
5069
+ parts.push(import_chalk2.default.dim(`${elapsed}s`));
5017
5070
  }
5018
- return cost.toFixed(2);
5071
+ return `${parts.join(import_chalk2.default.dim(" | "))} ${import_chalk2.default.green(">")} `;
5019
5072
  }
5020
5073
  };
5021
5074
  async function readStream(stream2) {
@@ -5045,44 +5098,12 @@ async function resolvePrompt(promptArg, env) {
5045
5098
  }
5046
5099
  return pipedInput;
5047
5100
  }
5048
- function renderSummary(metadata) {
5049
- const parts = [];
5050
- if (metadata.iterations !== void 0) {
5051
- parts.push(import_chalk.default.dim(`iterations: ${metadata.iterations}`));
5052
- }
5053
- if (metadata.finishReason) {
5054
- parts.push(import_chalk.default.dim(`finish: ${metadata.finishReason}`));
5055
- }
5056
- if (metadata.usage) {
5057
- const { inputTokens, outputTokens, totalTokens } = metadata.usage;
5058
- parts.push(
5059
- import_chalk.default.dim(`tokens: `) + import_chalk.default.cyan(`${totalTokens}`) + import_chalk.default.dim(` (in: ${inputTokens}, out: ${outputTokens})`)
5060
- );
5061
- }
5062
- if (metadata.cost !== void 0 && metadata.cost > 0) {
5063
- let formattedCost;
5064
- if (metadata.cost < 1e-3) {
5065
- formattedCost = metadata.cost.toFixed(5);
5066
- } else if (metadata.cost < 0.01) {
5067
- formattedCost = metadata.cost.toFixed(4);
5068
- } else if (metadata.cost < 1) {
5069
- formattedCost = metadata.cost.toFixed(3);
5070
- } else {
5071
- formattedCost = metadata.cost.toFixed(2);
5072
- }
5073
- parts.push(import_chalk.default.dim(`cost: `) + import_chalk.default.cyan(`$${formattedCost}`));
5074
- }
5075
- if (parts.length === 0) {
5076
- return null;
5077
- }
5078
- return parts.join(import_chalk.default.dim(" \u2502 "));
5079
- }
5080
5101
  async function executeAction(action, env) {
5081
5102
  try {
5082
5103
  await action();
5083
5104
  } catch (error) {
5084
5105
  const message = error instanceof Error ? error.message : String(error);
5085
- env.stderr.write(`${import_chalk.default.red.bold("Error:")} ${message}
5106
+ env.stderr.write(`${import_chalk2.default.red.bold("Error:")} ${message}
5086
5107
  `);
5087
5108
  env.setExitCode(1);
5088
5109
  }
@@ -5125,26 +5146,15 @@ ${statsPrompt}` : statsPrompt;
5125
5146
  }
5126
5147
  };
5127
5148
  }
5128
- function formatGadgetSummary(result) {
5129
- const gadgetLabel = import_chalk2.default.magenta.bold(result.gadgetName);
5130
- const timeLabel = import_chalk2.default.dim(`${Math.round(result.executionTimeMs)}ms`);
5131
- if (result.error) {
5132
- return `${import_chalk2.default.red("\u2717")} ${gadgetLabel} ${import_chalk2.default.red("error:")} ${result.error} ${timeLabel}`;
5133
- }
5134
- if (result.breaksLoop) {
5135
- return `${import_chalk2.default.yellow("\u23F9")} ${gadgetLabel} ${import_chalk2.default.yellow("finished:")} ${result.result} ${timeLabel}`;
5136
- }
5137
- const maxLen = 80;
5138
- const shouldTruncate = result.gadgetName !== "TellUser";
5139
- const resultText = result.result ? shouldTruncate && result.result.length > maxLen ? `${result.result.slice(0, maxLen)}...` : result.result : "";
5140
- return `${import_chalk2.default.green("\u2713")} ${gadgetLabel} ${import_chalk2.default.dim("\u2192")} ${resultText} ${timeLabel}`;
5141
- }
5142
5149
  async function handleAgentCommand(promptArg, options, env) {
5143
5150
  const prompt = await resolvePrompt(promptArg, env);
5144
5151
  const client = env.createClient();
5145
5152
  const registry = new GadgetRegistry();
5146
5153
  if (options.builtins !== false) {
5147
5154
  for (const gadget of builtinGadgets) {
5155
+ if (options.builtinInteraction === false && gadget.name === "AskUser") {
5156
+ continue;
5157
+ }
5148
5158
  registry.registerByClass(gadget);
5149
5159
  }
5150
5160
  }
@@ -5161,16 +5171,28 @@ async function handleAgentCommand(promptArg, options, env) {
5161
5171
  let finishReason;
5162
5172
  let usage;
5163
5173
  let iterations = 0;
5164
- const estimateMessagesTokens = (messages) => {
5165
- const totalChars = messages.reduce((sum, m) => sum + (m.content?.length ?? 0), 0);
5166
- return Math.round(totalChars / FALLBACK_CHARS_PER_TOKEN);
5174
+ const countMessagesTokens = async (model, messages) => {
5175
+ try {
5176
+ return await client.countTokens(model, messages);
5177
+ } catch {
5178
+ const totalChars = messages.reduce((sum, m) => sum + (m.content?.length ?? 0), 0);
5179
+ return Math.round(totalChars / FALLBACK_CHARS_PER_TOKEN);
5180
+ }
5167
5181
  };
5168
5182
  const builder = new AgentBuilder(client).withModel(options.model).withLogger(env.createLogger("llmist:cli:agent")).withHooks({
5169
5183
  observers: {
5184
+ // onLLMCallStart: Start progress indicator for each LLM call
5185
+ // This showcases how to react to agent lifecycle events
5170
5186
  onLLMCallStart: async (context) => {
5171
- const estimate = estimateMessagesTokens(context.options.messages);
5172
- progress.startCall(context.options.model, estimate);
5187
+ const inputTokens = await countMessagesTokens(
5188
+ context.options.model,
5189
+ context.options.messages
5190
+ );
5191
+ progress.startCall(context.options.model, inputTokens);
5192
+ progress.setInputTokens(inputTokens, false);
5173
5193
  },
5194
+ // onStreamChunk: Real-time updates as LLM generates tokens
5195
+ // This enables responsive UIs that show progress during generation
5174
5196
  onStreamChunk: async (context) => {
5175
5197
  progress.update(context.accumulatedText.length);
5176
5198
  if (context.usage) {
@@ -5182,10 +5204,20 @@ async function handleAgentCommand(promptArg, options, env) {
5182
5204
  }
5183
5205
  }
5184
5206
  },
5207
+ // onLLMCallComplete: Finalize metrics after each LLM call
5208
+ // This is where you'd typically log metrics or update dashboards
5185
5209
  onLLMCallComplete: async (context) => {
5186
5210
  finishReason = context.finishReason;
5187
5211
  usage = context.usage;
5188
5212
  iterations = Math.max(iterations, context.iteration + 1);
5213
+ if (context.usage) {
5214
+ if (context.usage.inputTokens) {
5215
+ progress.setInputTokens(context.usage.inputTokens, false);
5216
+ }
5217
+ if (context.usage.outputTokens) {
5218
+ progress.setOutputTokens(context.usage.outputTokens, false);
5219
+ }
5220
+ }
5189
5221
  progress.endCall(context.usage);
5190
5222
  }
5191
5223
  }
@@ -5227,7 +5259,8 @@ async function handleAgentCommand(promptArg, options, env) {
5227
5259
  finishReason,
5228
5260
  usage,
5229
5261
  iterations,
5230
- cost: progress.getTotalCost()
5262
+ cost: progress.getTotalCost(),
5263
+ elapsedSeconds: progress.getTotalElapsedSeconds()
5231
5264
  });
5232
5265
  if (summary) {
5233
5266
  env.stderr.write(`${summary}
@@ -5254,7 +5287,7 @@ function registerAgentCommand(program, env) {
5254
5287
  OPTION_DESCRIPTIONS.parameterFormat,
5255
5288
  parseParameterFormat,
5256
5289
  DEFAULT_PARAMETER_FORMAT
5257
- ).option(OPTION_FLAGS.noBuiltins, OPTION_DESCRIPTIONS.noBuiltins).action(
5290
+ ).option(OPTION_FLAGS.noBuiltins, OPTION_DESCRIPTIONS.noBuiltins).option(OPTION_FLAGS.noBuiltinInteraction, OPTION_DESCRIPTIONS.noBuiltinInteraction).action(
5258
5291
  (prompt, options) => executeAction(() => handleAgentCommand(prompt, options, env), env)
5259
5292
  );
5260
5293
  }
@@ -5392,7 +5425,7 @@ function renderCompactTable(models, stream2) {
5392
5425
  );
5393
5426
  stream2.write(import_chalk3.default.dim("\u2500".repeat(idWidth + nameWidth + contextWidth + inputWidth + outputWidth + 8)) + "\n");
5394
5427
  for (const model of models) {
5395
- const contextFormatted = formatTokens(model.contextWindow);
5428
+ const contextFormatted = formatTokens2(model.contextWindow);
5396
5429
  const inputPrice = `$${model.pricing.input.toFixed(2)}`;
5397
5430
  const outputPrice = `$${model.pricing.output.toFixed(2)}`;
5398
5431
  stream2.write(
@@ -5411,9 +5444,9 @@ function renderVerboseTable(models, stream2) {
5411
5444
  stream2.write(import_chalk3.default.dim(" " + "\u2500".repeat(60)) + "\n");
5412
5445
  stream2.write(` ${import_chalk3.default.dim("Name:")} ${import_chalk3.default.white(model.displayName)}
5413
5446
  `);
5414
- stream2.write(` ${import_chalk3.default.dim("Context:")} ${import_chalk3.default.yellow(formatTokens(model.contextWindow))}
5447
+ stream2.write(` ${import_chalk3.default.dim("Context:")} ${import_chalk3.default.yellow(formatTokens2(model.contextWindow))}
5415
5448
  `);
5416
- stream2.write(` ${import_chalk3.default.dim("Max Output:")} ${import_chalk3.default.yellow(formatTokens(model.maxOutputTokens))}
5449
+ stream2.write(` ${import_chalk3.default.dim("Max Output:")} ${import_chalk3.default.yellow(formatTokens2(model.maxOutputTokens))}
5417
5450
  `);
5418
5451
  stream2.write(` ${import_chalk3.default.dim("Pricing:")} ${import_chalk3.default.cyan(`$${model.pricing.input.toFixed(2)} input`)} ${import_chalk3.default.dim("/")} ${import_chalk3.default.cyan(`$${model.pricing.output.toFixed(2)} output`)} ${import_chalk3.default.dim("(per 1M tokens)")}
5419
5452
  `);
@@ -5476,7 +5509,7 @@ function renderJSON(models, stream2) {
5476
5509
  };
5477
5510
  stream2.write(JSON.stringify(output, null, 2) + "\n");
5478
5511
  }
5479
- function formatTokens(count) {
5512
+ function formatTokens2(count) {
5480
5513
  if (count >= 1e6) {
5481
5514
  return `${(count / 1e6).toFixed(1)}M tokens`;
5482
5515
  } else if (count >= 1e3) {