llmist 0.1.4 → 0.1.5
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/README.md +65 -11
- package/dist/cli.cjs +127 -56
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +127 -56
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +335 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +374 -48
- package/dist/index.d.ts +374 -48
- package/dist/index.js +335 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# llmist
|
|
2
2
|
|
|
3
3
|
[](https://github.com/zbigniewsobiecki/llmist/actions/workflows/ci.yml)
|
|
4
|
-
[](https://codecov.io/gh/zbigniewsobiecki/llmist)
|
|
5
|
+
[](https://www.npmjs.com/package/llmist)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
8
|
> **Universal TypeScript LLM client with streaming-first tool execution and simple, extensible agent framework**
|
|
@@ -153,31 +153,85 @@ const calculator = createGadget({
|
|
|
153
153
|
|
|
154
154
|
### 🪝 Lifecycle Hooks
|
|
155
155
|
|
|
156
|
+
Monitor, transform, and control agent execution with ready-to-use presets or custom hooks:
|
|
157
|
+
|
|
158
|
+
**Quick start with presets:**
|
|
159
|
+
|
|
156
160
|
```typescript
|
|
157
|
-
import { HookPresets } from 'llmist';
|
|
161
|
+
import { LLMist, HookPresets } from 'llmist';
|
|
162
|
+
|
|
163
|
+
// Full monitoring suite (recommended for development)
|
|
164
|
+
await LLMist.createAgent()
|
|
165
|
+
.withHooks(HookPresets.monitoring())
|
|
166
|
+
.ask('Your prompt');
|
|
167
|
+
// Output: Logs + timing + token tracking + error logging
|
|
158
168
|
|
|
159
|
-
//
|
|
169
|
+
// Combine specific presets for focused monitoring
|
|
160
170
|
await LLMist.createAgent()
|
|
161
|
-
.withHooks(HookPresets.
|
|
171
|
+
.withHooks(HookPresets.merge(
|
|
172
|
+
HookPresets.timing(),
|
|
173
|
+
HookPresets.tokenTracking()
|
|
174
|
+
))
|
|
162
175
|
.ask('Your prompt');
|
|
176
|
+
```
|
|
163
177
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
)
|
|
178
|
+
**Available presets:**
|
|
179
|
+
- `logging()` / `logging({ verbose: true })` - Event logging with optional details
|
|
180
|
+
- `timing()` - Execution time measurements
|
|
181
|
+
- `tokenTracking()` - Cumulative token usage and cost tracking
|
|
182
|
+
- `errorLogging()` - Detailed error information
|
|
183
|
+
- `silent()` - No output (for testing)
|
|
184
|
+
- `monitoring()` - All-in-one preset combining logging, timing, tokens, and errors
|
|
185
|
+
- `merge()` - Combine multiple presets or add custom hooks
|
|
169
186
|
|
|
170
|
-
|
|
187
|
+
**Production vs Development patterns:**
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
// Environment-based configuration
|
|
191
|
+
const isDev = process.env.NODE_ENV === 'development';
|
|
192
|
+
const hooks = isDev
|
|
193
|
+
? HookPresets.monitoring({ verbose: true }) // Full visibility in dev
|
|
194
|
+
: HookPresets.merge(
|
|
195
|
+
HookPresets.errorLogging(), // Only errors in prod
|
|
196
|
+
HookPresets.tokenTracking() // Track costs
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
await LLMist.createAgent()
|
|
200
|
+
.withHooks(hooks)
|
|
201
|
+
.ask('Your prompt');
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Custom hooks for advanced control:**
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// Observers: read-only monitoring
|
|
171
208
|
.withHooks({
|
|
172
209
|
observers: {
|
|
173
210
|
onLLMCallComplete: async (ctx) => {
|
|
174
211
|
console.log(`Used ${ctx.usage?.totalTokens} tokens`);
|
|
212
|
+
await sendMetricsToDataDog(ctx);
|
|
175
213
|
},
|
|
176
214
|
},
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
// Interceptors: transform data in flight
|
|
218
|
+
.withHooks({
|
|
177
219
|
interceptors: {
|
|
178
220
|
interceptTextChunk: (chunk) => chunk.toUpperCase(),
|
|
179
221
|
},
|
|
180
222
|
})
|
|
223
|
+
|
|
224
|
+
// Controllers: control execution flow
|
|
225
|
+
.withHooks({
|
|
226
|
+
controllers: {
|
|
227
|
+
beforeLLMCall: async (ctx) => {
|
|
228
|
+
if (shouldCache(ctx)) {
|
|
229
|
+
return { action: 'skip', syntheticResponse: cachedResponse };
|
|
230
|
+
}
|
|
231
|
+
return { action: 'proceed' };
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
})
|
|
181
235
|
```
|
|
182
236
|
|
|
183
237
|
📖 **[Hooks Guide](./docs/HOOKS.md)** | **[Examples](./examples/03-hooks.ts)**
|
package/dist/cli.cjs
CHANGED
|
@@ -4253,7 +4253,7 @@ var import_commander3 = require("commander");
|
|
|
4253
4253
|
// package.json
|
|
4254
4254
|
var package_default = {
|
|
4255
4255
|
name: "llmist",
|
|
4256
|
-
version: "0.1.
|
|
4256
|
+
version: "0.1.5",
|
|
4257
4257
|
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.",
|
|
4258
4258
|
type: "module",
|
|
4259
4259
|
main: "dist/index.cjs",
|
|
@@ -4356,14 +4356,13 @@ var package_default = {
|
|
|
4356
4356
|
|
|
4357
4357
|
// src/cli/agent-command.ts
|
|
4358
4358
|
var import_promises = require("readline/promises");
|
|
4359
|
-
var
|
|
4359
|
+
var import_chalk2 = __toESM(require("chalk"), 1);
|
|
4360
4360
|
var import_commander2 = require("commander");
|
|
4361
4361
|
init_builder();
|
|
4362
4362
|
init_registry();
|
|
4363
4363
|
init_constants2();
|
|
4364
4364
|
|
|
4365
4365
|
// src/cli/builtin-gadgets.ts
|
|
4366
|
-
var import_chalk = __toESM(require("chalk"), 1);
|
|
4367
4366
|
var import_zod = require("zod");
|
|
4368
4367
|
|
|
4369
4368
|
// src/gadgets/gadget.ts
|
|
@@ -4539,17 +4538,17 @@ var tellUser = createGadget({
|
|
|
4539
4538
|
type: import_zod.z.enum(["info", "success", "warning", "error"]).default("info").describe("Message type: info, success, warning, or error")
|
|
4540
4539
|
}),
|
|
4541
4540
|
execute: ({ message, done, type }) => {
|
|
4542
|
-
const
|
|
4543
|
-
info:
|
|
4544
|
-
success:
|
|
4545
|
-
warning:
|
|
4546
|
-
error:
|
|
4541
|
+
const prefixes = {
|
|
4542
|
+
info: "\u2139\uFE0F ",
|
|
4543
|
+
success: "\u2705 ",
|
|
4544
|
+
warning: "\u26A0\uFE0F ",
|
|
4545
|
+
error: "\u274C "
|
|
4547
4546
|
};
|
|
4548
|
-
const
|
|
4547
|
+
const plainResult = prefixes[type] + message;
|
|
4549
4548
|
if (done) {
|
|
4550
|
-
throw new BreakLoopException(
|
|
4549
|
+
throw new BreakLoopException(plainResult);
|
|
4551
4550
|
}
|
|
4552
|
-
return
|
|
4551
|
+
return plainResult;
|
|
4553
4552
|
}
|
|
4554
4553
|
});
|
|
4555
4554
|
var builtinGadgets = [askUser, tellUser];
|
|
@@ -4651,7 +4650,7 @@ async function loadGadgets(specifiers, cwd, importer = (specifier) => import(spe
|
|
|
4651
4650
|
}
|
|
4652
4651
|
|
|
4653
4652
|
// src/cli/utils.ts
|
|
4654
|
-
var
|
|
4653
|
+
var import_chalk = __toESM(require("chalk"), 1);
|
|
4655
4654
|
var import_commander = require("commander");
|
|
4656
4655
|
init_constants2();
|
|
4657
4656
|
function createNumericParser({
|
|
@@ -4710,9 +4709,10 @@ function isInteractive(stream2) {
|
|
|
4710
4709
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
4711
4710
|
var SPINNER_DELAY_MS = 500;
|
|
4712
4711
|
var StreamProgress = class {
|
|
4713
|
-
constructor(target, isTTY) {
|
|
4712
|
+
constructor(target, isTTY, modelRegistry) {
|
|
4714
4713
|
this.target = target;
|
|
4715
4714
|
this.isTTY = isTTY;
|
|
4715
|
+
this.modelRegistry = modelRegistry;
|
|
4716
4716
|
}
|
|
4717
4717
|
// Animation state
|
|
4718
4718
|
frameIndex = 0;
|
|
@@ -4733,6 +4733,7 @@ var StreamProgress = class {
|
|
|
4733
4733
|
// Cumulative stats (cumulative mode)
|
|
4734
4734
|
totalStartTime = Date.now();
|
|
4735
4735
|
totalTokens = 0;
|
|
4736
|
+
totalCost = 0;
|
|
4736
4737
|
iterations = 0;
|
|
4737
4738
|
/**
|
|
4738
4739
|
* Starts a new LLM call. Switches to streaming mode.
|
|
@@ -4759,6 +4760,20 @@ var StreamProgress = class {
|
|
|
4759
4760
|
this.iterations++;
|
|
4760
4761
|
if (usage) {
|
|
4761
4762
|
this.totalTokens += usage.totalTokens;
|
|
4763
|
+
if (this.modelRegistry && this.model) {
|
|
4764
|
+
try {
|
|
4765
|
+
const modelName = this.model.includes(":") ? this.model.split(":")[1] : this.model;
|
|
4766
|
+
const cost = this.modelRegistry.estimateCost(
|
|
4767
|
+
modelName,
|
|
4768
|
+
usage.inputTokens,
|
|
4769
|
+
usage.outputTokens
|
|
4770
|
+
);
|
|
4771
|
+
if (cost) {
|
|
4772
|
+
this.totalCost += cost.totalCost;
|
|
4773
|
+
}
|
|
4774
|
+
} catch {
|
|
4775
|
+
}
|
|
4776
|
+
}
|
|
4762
4777
|
}
|
|
4763
4778
|
this.pause();
|
|
4764
4779
|
this.mode = "cumulative";
|
|
@@ -4822,33 +4837,39 @@ var StreamProgress = class {
|
|
|
4822
4837
|
const outTokens = this.callOutputTokensEstimated ? Math.round(this.callOutputChars / FALLBACK_CHARS_PER_TOKEN) : this.callOutputTokens;
|
|
4823
4838
|
const parts = [];
|
|
4824
4839
|
if (this.model) {
|
|
4825
|
-
parts.push(
|
|
4840
|
+
parts.push(import_chalk.default.cyan(this.model));
|
|
4826
4841
|
}
|
|
4827
4842
|
if (this.callInputTokens > 0) {
|
|
4828
4843
|
const prefix = this.callInputTokensEstimated ? "~" : "";
|
|
4829
|
-
parts.push(
|
|
4844
|
+
parts.push(import_chalk.default.dim("out:") + import_chalk.default.yellow(` ${prefix}${this.callInputTokens}`));
|
|
4830
4845
|
}
|
|
4831
4846
|
if (this.isStreaming || outTokens > 0) {
|
|
4832
4847
|
const prefix = this.callOutputTokensEstimated ? "~" : "";
|
|
4833
|
-
parts.push(
|
|
4848
|
+
parts.push(import_chalk.default.dim("in:") + import_chalk.default.green(` ${prefix}${outTokens}`));
|
|
4849
|
+
}
|
|
4850
|
+
if (this.totalCost > 0) {
|
|
4851
|
+
parts.push(import_chalk.default.dim("cost:") + import_chalk.default.cyan(` $${this.formatCost(this.totalCost)}`));
|
|
4834
4852
|
}
|
|
4835
|
-
parts.push(
|
|
4836
|
-
this.target.write(`\r${
|
|
4853
|
+
parts.push(import_chalk.default.dim(`${elapsed}s`));
|
|
4854
|
+
this.target.write(`\r${import_chalk.default.cyan(spinner)} ${parts.join(import_chalk.default.dim(" | "))}`);
|
|
4837
4855
|
}
|
|
4838
4856
|
renderCumulativeMode(spinner) {
|
|
4839
4857
|
const elapsed = ((Date.now() - this.totalStartTime) / 1e3).toFixed(1);
|
|
4840
4858
|
const parts = [];
|
|
4841
4859
|
if (this.model) {
|
|
4842
|
-
parts.push(
|
|
4860
|
+
parts.push(import_chalk.default.cyan(this.model));
|
|
4843
4861
|
}
|
|
4844
4862
|
if (this.totalTokens > 0) {
|
|
4845
|
-
parts.push(
|
|
4863
|
+
parts.push(import_chalk.default.dim("total:") + import_chalk.default.magenta(` ${this.totalTokens}`));
|
|
4846
4864
|
}
|
|
4847
4865
|
if (this.iterations > 0) {
|
|
4848
|
-
parts.push(
|
|
4866
|
+
parts.push(import_chalk.default.dim("iter:") + import_chalk.default.blue(` ${this.iterations}`));
|
|
4849
4867
|
}
|
|
4850
|
-
|
|
4851
|
-
|
|
4868
|
+
if (this.totalCost > 0) {
|
|
4869
|
+
parts.push(import_chalk.default.dim("cost:") + import_chalk.default.cyan(` $${this.formatCost(this.totalCost)}`));
|
|
4870
|
+
}
|
|
4871
|
+
parts.push(import_chalk.default.dim(`${elapsed}s`));
|
|
4872
|
+
this.target.write(`\r${import_chalk.default.cyan(spinner)} ${parts.join(import_chalk.default.dim(" | "))}`);
|
|
4852
4873
|
}
|
|
4853
4874
|
/**
|
|
4854
4875
|
* Pauses the progress indicator and clears the line.
|
|
@@ -4876,6 +4897,12 @@ var StreamProgress = class {
|
|
|
4876
4897
|
complete() {
|
|
4877
4898
|
this.pause();
|
|
4878
4899
|
}
|
|
4900
|
+
/**
|
|
4901
|
+
* Returns the total accumulated cost across all calls.
|
|
4902
|
+
*/
|
|
4903
|
+
getTotalCost() {
|
|
4904
|
+
return this.totalCost;
|
|
4905
|
+
}
|
|
4879
4906
|
/**
|
|
4880
4907
|
* Returns a formatted prompt string with stats (like bash PS1).
|
|
4881
4908
|
* Shows current call stats during streaming, cumulative stats otherwise.
|
|
@@ -4890,25 +4917,28 @@ var StreamProgress = class {
|
|
|
4890
4917
|
if (this.callInputTokens > 0) {
|
|
4891
4918
|
const prefix = this.callInputTokensEstimated ? "~" : "";
|
|
4892
4919
|
parts.push(
|
|
4893
|
-
|
|
4920
|
+
import_chalk.default.dim("out:") + import_chalk.default.yellow(` ${prefix}${this.formatTokens(this.callInputTokens)}`)
|
|
4894
4921
|
);
|
|
4895
4922
|
}
|
|
4896
4923
|
if (outTokens > 0) {
|
|
4897
4924
|
const prefix = outEstimated ? "~" : "";
|
|
4898
|
-
parts.push(
|
|
4925
|
+
parts.push(import_chalk.default.dim("in:") + import_chalk.default.green(` ${prefix}${this.formatTokens(outTokens)}`));
|
|
4899
4926
|
}
|
|
4900
|
-
parts.push(
|
|
4927
|
+
parts.push(import_chalk.default.dim(`${elapsed}s`));
|
|
4901
4928
|
} else {
|
|
4902
4929
|
const elapsed = Math.round((Date.now() - this.totalStartTime) / 1e3);
|
|
4903
4930
|
if (this.totalTokens > 0) {
|
|
4904
|
-
parts.push(
|
|
4931
|
+
parts.push(import_chalk.default.magenta(this.formatTokens(this.totalTokens)));
|
|
4905
4932
|
}
|
|
4906
4933
|
if (this.iterations > 0) {
|
|
4907
|
-
parts.push(
|
|
4934
|
+
parts.push(import_chalk.default.blue(`i${this.iterations}`));
|
|
4908
4935
|
}
|
|
4909
|
-
|
|
4936
|
+
if (this.totalCost > 0) {
|
|
4937
|
+
parts.push(import_chalk.default.cyan(`$${this.formatCost(this.totalCost)}`));
|
|
4938
|
+
}
|
|
4939
|
+
parts.push(import_chalk.default.dim(`${elapsed}s`));
|
|
4910
4940
|
}
|
|
4911
|
-
return `${parts.join(
|
|
4941
|
+
return `${parts.join(import_chalk.default.dim(" \u2502 "))} ${import_chalk.default.green(">")} `;
|
|
4912
4942
|
}
|
|
4913
4943
|
/**
|
|
4914
4944
|
* Formats token count compactly (3625 -> "3.6k").
|
|
@@ -4916,6 +4946,21 @@ var StreamProgress = class {
|
|
|
4916
4946
|
formatTokens(tokens) {
|
|
4917
4947
|
return tokens >= 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : `${tokens}`;
|
|
4918
4948
|
}
|
|
4949
|
+
/**
|
|
4950
|
+
* Formats cost compactly (0.0001234 -> "0.00012", 0.1234 -> "0.12", 1.234 -> "1.23").
|
|
4951
|
+
*/
|
|
4952
|
+
formatCost(cost) {
|
|
4953
|
+
if (cost < 1e-3) {
|
|
4954
|
+
return cost.toFixed(5);
|
|
4955
|
+
}
|
|
4956
|
+
if (cost < 0.01) {
|
|
4957
|
+
return cost.toFixed(4);
|
|
4958
|
+
}
|
|
4959
|
+
if (cost < 1) {
|
|
4960
|
+
return cost.toFixed(3);
|
|
4961
|
+
}
|
|
4962
|
+
return cost.toFixed(2);
|
|
4963
|
+
}
|
|
4919
4964
|
};
|
|
4920
4965
|
async function readStream(stream2) {
|
|
4921
4966
|
const chunks = [];
|
|
@@ -4947,29 +4992,42 @@ async function resolvePrompt(promptArg, env) {
|
|
|
4947
4992
|
function renderSummary(metadata) {
|
|
4948
4993
|
const parts = [];
|
|
4949
4994
|
if (metadata.iterations !== void 0) {
|
|
4950
|
-
parts.push(
|
|
4995
|
+
parts.push(import_chalk.default.dim(`iterations: ${metadata.iterations}`));
|
|
4951
4996
|
}
|
|
4952
4997
|
if (metadata.finishReason) {
|
|
4953
|
-
parts.push(
|
|
4998
|
+
parts.push(import_chalk.default.dim(`finish: ${metadata.finishReason}`));
|
|
4954
4999
|
}
|
|
4955
5000
|
if (metadata.usage) {
|
|
4956
5001
|
const { inputTokens, outputTokens, totalTokens } = metadata.usage;
|
|
4957
5002
|
parts.push(
|
|
4958
|
-
|
|
5003
|
+
import_chalk.default.dim(`tokens: `) + import_chalk.default.cyan(`${totalTokens}`) + import_chalk.default.dim(` (in: ${inputTokens}, out: ${outputTokens})`)
|
|
4959
5004
|
);
|
|
4960
5005
|
}
|
|
5006
|
+
if (metadata.cost !== void 0 && metadata.cost > 0) {
|
|
5007
|
+
let formattedCost;
|
|
5008
|
+
if (metadata.cost < 1e-3) {
|
|
5009
|
+
formattedCost = metadata.cost.toFixed(5);
|
|
5010
|
+
} else if (metadata.cost < 0.01) {
|
|
5011
|
+
formattedCost = metadata.cost.toFixed(4);
|
|
5012
|
+
} else if (metadata.cost < 1) {
|
|
5013
|
+
formattedCost = metadata.cost.toFixed(3);
|
|
5014
|
+
} else {
|
|
5015
|
+
formattedCost = metadata.cost.toFixed(2);
|
|
5016
|
+
}
|
|
5017
|
+
parts.push(import_chalk.default.dim(`cost: `) + import_chalk.default.cyan(`$${formattedCost}`));
|
|
5018
|
+
}
|
|
4961
5019
|
if (parts.length === 0) {
|
|
4962
5020
|
return null;
|
|
4963
5021
|
}
|
|
4964
|
-
return `${
|
|
4965
|
-
${parts.join(
|
|
5022
|
+
return `${import_chalk.default.dim("\u2500".repeat(40))}
|
|
5023
|
+
${parts.join(import_chalk.default.dim(" \u2502 "))}`;
|
|
4966
5024
|
}
|
|
4967
5025
|
async function executeAction(action, env) {
|
|
4968
5026
|
try {
|
|
4969
5027
|
await action();
|
|
4970
5028
|
} catch (error) {
|
|
4971
5029
|
const message = error instanceof Error ? error.message : String(error);
|
|
4972
|
-
env.stderr.write(`${
|
|
5030
|
+
env.stderr.write(`${import_chalk.default.red.bold("Error:")} ${message}
|
|
4973
5031
|
`);
|
|
4974
5032
|
env.setExitCode(1);
|
|
4975
5033
|
}
|
|
@@ -5013,17 +5071,18 @@ ${statsPrompt}` : statsPrompt;
|
|
|
5013
5071
|
};
|
|
5014
5072
|
}
|
|
5015
5073
|
function formatGadgetSummary(result) {
|
|
5016
|
-
const gadgetLabel =
|
|
5017
|
-
const timeLabel =
|
|
5074
|
+
const gadgetLabel = import_chalk2.default.magenta.bold(result.gadgetName);
|
|
5075
|
+
const timeLabel = import_chalk2.default.dim(`${Math.round(result.executionTimeMs)}ms`);
|
|
5018
5076
|
if (result.error) {
|
|
5019
|
-
return `${
|
|
5077
|
+
return `${import_chalk2.default.red("\u2717")} ${gadgetLabel} ${import_chalk2.default.red("error:")} ${result.error} ${timeLabel}`;
|
|
5020
5078
|
}
|
|
5021
5079
|
if (result.breaksLoop) {
|
|
5022
|
-
return `${
|
|
5080
|
+
return `${import_chalk2.default.yellow("\u23F9")} ${gadgetLabel} ${import_chalk2.default.yellow("finished:")} ${result.result} ${timeLabel}`;
|
|
5023
5081
|
}
|
|
5024
5082
|
const maxLen = 80;
|
|
5025
|
-
const
|
|
5026
|
-
|
|
5083
|
+
const shouldTruncate = result.gadgetName !== "TellUser";
|
|
5084
|
+
const resultText = result.result ? shouldTruncate && result.result.length > maxLen ? `${result.result.slice(0, maxLen)}...` : result.result : "";
|
|
5085
|
+
return `${import_chalk2.default.green("\u2713")} ${gadgetLabel} ${import_chalk2.default.dim("\u2192")} ${resultText} ${timeLabel}`;
|
|
5027
5086
|
}
|
|
5028
5087
|
async function handleAgentCommand(promptArg, options, env) {
|
|
5029
5088
|
const prompt = await resolvePrompt(promptArg, env);
|
|
@@ -5043,7 +5102,7 @@ async function handleAgentCommand(promptArg, options, env) {
|
|
|
5043
5102
|
}
|
|
5044
5103
|
const printer = new StreamPrinter(env.stdout);
|
|
5045
5104
|
const stderrTTY = env.stderr.isTTY === true;
|
|
5046
|
-
const progress = new StreamProgress(env.stderr, stderrTTY);
|
|
5105
|
+
const progress = new StreamProgress(env.stderr, stderrTTY, client.modelRegistry);
|
|
5047
5106
|
let finishReason;
|
|
5048
5107
|
let usage;
|
|
5049
5108
|
let iterations = 0;
|
|
@@ -5100,16 +5159,25 @@ async function handleAgentCommand(promptArg, options, env) {
|
|
|
5100
5159
|
printer.write(event.content);
|
|
5101
5160
|
} else if (event.type === "gadget_result") {
|
|
5102
5161
|
progress.pause();
|
|
5103
|
-
|
|
5162
|
+
if (stderrTTY) {
|
|
5163
|
+
env.stderr.write(`${formatGadgetSummary(event.result)}
|
|
5104
5164
|
`);
|
|
5165
|
+
}
|
|
5105
5166
|
}
|
|
5106
5167
|
}
|
|
5107
5168
|
progress.complete();
|
|
5108
5169
|
printer.ensureNewline();
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5170
|
+
if (stderrTTY) {
|
|
5171
|
+
const summary = renderSummary({
|
|
5172
|
+
finishReason,
|
|
5173
|
+
usage,
|
|
5174
|
+
iterations,
|
|
5175
|
+
cost: progress.getTotalCost()
|
|
5176
|
+
});
|
|
5177
|
+
if (summary) {
|
|
5178
|
+
env.stderr.write(`${summary}
|
|
5112
5179
|
`);
|
|
5180
|
+
}
|
|
5113
5181
|
}
|
|
5114
5182
|
}
|
|
5115
5183
|
function registerAgentCommand(program, env) {
|
|
@@ -5155,7 +5223,7 @@ async function handleCompleteCommand(promptArg, options, env) {
|
|
|
5155
5223
|
});
|
|
5156
5224
|
const printer = new StreamPrinter(env.stdout);
|
|
5157
5225
|
const stderrTTY = env.stderr.isTTY === true;
|
|
5158
|
-
const progress = new StreamProgress(env.stderr, stderrTTY);
|
|
5226
|
+
const progress = new StreamProgress(env.stderr, stderrTTY, client.modelRegistry);
|
|
5159
5227
|
const estimatedInputTokens = Math.round(prompt.length / FALLBACK_CHARS_PER_TOKEN);
|
|
5160
5228
|
progress.startCall(options.model, estimatedInputTokens);
|
|
5161
5229
|
let finishReason;
|
|
@@ -5181,12 +5249,15 @@ async function handleCompleteCommand(promptArg, options, env) {
|
|
|
5181
5249
|
finishReason = chunk.finishReason;
|
|
5182
5250
|
}
|
|
5183
5251
|
}
|
|
5252
|
+
progress.endCall(usage);
|
|
5184
5253
|
progress.complete();
|
|
5185
5254
|
printer.ensureNewline();
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5255
|
+
if (stderrTTY) {
|
|
5256
|
+
const summary = renderSummary({ finishReason, usage, cost: progress.getTotalCost() });
|
|
5257
|
+
if (summary) {
|
|
5258
|
+
env.stderr.write(`${summary}
|
|
5189
5259
|
`);
|
|
5260
|
+
}
|
|
5190
5261
|
}
|
|
5191
5262
|
}
|
|
5192
5263
|
function registerCompleteCommand(program, env) {
|
|
@@ -5208,7 +5279,7 @@ function registerCompleteCommand(program, env) {
|
|
|
5208
5279
|
|
|
5209
5280
|
// src/cli/environment.ts
|
|
5210
5281
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
5211
|
-
var
|
|
5282
|
+
var import_chalk3 = __toESM(require("chalk"), 1);
|
|
5212
5283
|
init_client();
|
|
5213
5284
|
init_logger();
|
|
5214
5285
|
var LOG_LEVEL_MAP = {
|
|
@@ -5254,14 +5325,14 @@ function createPromptFunction(stdin, stdout) {
|
|
|
5254
5325
|
output: stdout
|
|
5255
5326
|
});
|
|
5256
5327
|
stdout.write("\n");
|
|
5257
|
-
stdout.write(`${
|
|
5328
|
+
stdout.write(`${import_chalk3.default.cyan("\u2500".repeat(60))}
|
|
5258
5329
|
`);
|
|
5259
|
-
stdout.write(
|
|
5330
|
+
stdout.write(import_chalk3.default.cyan.bold("\u{1F916} Agent asks:\n"));
|
|
5260
5331
|
stdout.write(`${question}
|
|
5261
5332
|
`);
|
|
5262
|
-
stdout.write(`${
|
|
5333
|
+
stdout.write(`${import_chalk3.default.cyan("\u2500".repeat(60))}
|
|
5263
5334
|
`);
|
|
5264
|
-
rl.question(
|
|
5335
|
+
rl.question(import_chalk3.default.green.bold("You: "), (answer) => {
|
|
5265
5336
|
rl.close();
|
|
5266
5337
|
resolve(answer);
|
|
5267
5338
|
});
|