llmist 1.2.0 → 1.3.1

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.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  resolveModel,
27
27
  schemaToJSONSchema,
28
28
  validateGadgetSchema
29
- } from "./chunk-KORMY3CD.js";
29
+ } from "./chunk-RZTAKIDE.js";
30
30
 
31
31
  // src/cli/constants.ts
32
32
  var CLI_NAME = "llmist";
@@ -79,7 +79,7 @@ import { Command, InvalidArgumentError as InvalidArgumentError2 } from "commande
79
79
  // package.json
80
80
  var package_default = {
81
81
  name: "llmist",
82
- version: "1.1.0",
82
+ version: "1.3.0",
83
83
  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.",
84
84
  type: "module",
85
85
  main: "dist/index.cjs",
@@ -226,26 +226,16 @@ var askUser = createGadget({
226
226
  });
227
227
  var tellUser = createGadget({
228
228
  name: "TellUser",
229
- description: "Tell the user something important. Set done=true when your work is complete and you want to end the conversation.",
229
+ description: "Tell the user something important.",
230
230
  schema: z.object({
231
231
  message: z.string().optional().describe("The message to display to the user in Markdown"),
232
- done: z.boolean().default(false).describe("Set to true to end the conversation, false to continue"),
233
232
  type: z.enum(["info", "success", "warning", "error"]).default("info").describe("Message type: info, success, warning, or error")
234
233
  }),
235
234
  examples: [
236
235
  {
237
- comment: "Report successful completion and end the conversation",
238
- params: {
239
- message: "I've completed the refactoring. All tests pass.",
240
- done: true,
241
- type: "success"
242
- }
243
- },
244
- {
245
- comment: "Warn the user about something without ending",
236
+ comment: "Warn the user about something",
246
237
  params: {
247
238
  message: "Found 3 files with potential issues. Continuing analysis...",
248
- done: false,
249
239
  type: "warning"
250
240
  }
251
241
  },
@@ -253,12 +243,11 @@ var tellUser = createGadget({
253
243
  comment: "Share detailed analysis with bullet points (use heredoc for multiline)",
254
244
  params: {
255
245
  message: "Here's what I found in the codebase:\n\n1. **Main entry point**: `src/index.ts` exports all public APIs\n2. **Core logic**: Located in `src/core/` with 5 modules\n3. **Tests**: Good coverage in `src/__tests__/`\n\nI'll continue exploring the core modules.",
256
- done: false,
257
246
  type: "info"
258
247
  }
259
248
  }
260
249
  ],
261
- execute: ({ message, done, type }) => {
250
+ execute: ({ message, type }) => {
262
251
  if (!message || message.trim() === "") {
263
252
  return "\u26A0\uFE0F TellUser was called without a message. Please provide content in the 'message' field.";
264
253
  }
@@ -268,14 +257,24 @@ var tellUser = createGadget({
268
257
  warning: "\u26A0\uFE0F ",
269
258
  error: "\u274C "
270
259
  };
271
- const plainResult = prefixes[type] + message;
272
- if (done) {
273
- throw new BreakLoopException(plainResult);
260
+ return prefixes[type] + message;
261
+ }
262
+ });
263
+ var finish = createGadget({
264
+ name: "Finish",
265
+ description: "Signal that you have completed your task. Call this when your work is done.",
266
+ schema: z.object({}),
267
+ examples: [
268
+ {
269
+ comment: "Signal task completion",
270
+ params: {}
274
271
  }
275
- return plainResult;
272
+ ],
273
+ execute: () => {
274
+ throw new BreakLoopException("Task completed");
276
275
  }
277
276
  });
278
- var builtinGadgets = [askUser, tellUser];
277
+ var builtinGadgets = [askUser, tellUser, finish];
279
278
 
280
279
  // src/cli/gadgets.ts
281
280
  init_gadget();
@@ -831,6 +830,17 @@ var StreamProgress = class {
831
830
  } else {
832
831
  parts.push(iterPart);
833
832
  }
833
+ const usagePercent = this.getContextUsagePercent();
834
+ if (usagePercent !== null) {
835
+ const formatted = `${Math.round(usagePercent)}%`;
836
+ if (usagePercent >= 80) {
837
+ parts.push(chalk2.red(formatted));
838
+ } else if (usagePercent >= 50) {
839
+ parts.push(chalk2.yellow(formatted));
840
+ } else {
841
+ parts.push(chalk2.green(formatted));
842
+ }
843
+ }
834
844
  if (this.callInputTokens > 0) {
835
845
  const prefix = this.callInputTokensEstimated ? "~" : "";
836
846
  parts.push(chalk2.dim("\u2191") + chalk2.yellow(` ${prefix}${formatTokens(this.callInputTokens)}`));
@@ -866,6 +876,21 @@ var StreamProgress = class {
866
876
  return 0;
867
877
  }
868
878
  }
879
+ /**
880
+ * Calculates context window usage percentage.
881
+ * Returns null if model is unknown or context window unavailable.
882
+ */
883
+ getContextUsagePercent() {
884
+ if (!this.modelRegistry || !this.model || this.callInputTokens === 0) {
885
+ return null;
886
+ }
887
+ const modelName = this.model.includes(":") ? this.model.split(":")[1] : this.model;
888
+ const limits = this.modelRegistry.getModelLimits(modelName);
889
+ if (!limits?.contextWindow) {
890
+ return null;
891
+ }
892
+ return this.callInputTokens / limits.contextWindow * 100;
893
+ }
869
894
  renderCumulativeMode(spinner) {
870
895
  const elapsed = ((Date.now() - this.totalStartTime) / 1e3).toFixed(1);
871
896
  const parts = [];
@@ -1493,7 +1518,9 @@ function resolveTemplate(eta, template, context = {}, configPath) {
1493
1518
  try {
1494
1519
  const fullContext = {
1495
1520
  ...context,
1496
- env: process.env
1521
+ env: process.env,
1522
+ date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0]
1523
+ // "2025-12-01"
1497
1524
  };
1498
1525
  return eta.renderString(template, fullContext);
1499
1526
  } catch (error) {