llmist 5.0.0 → 5.1.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/{chunk-UBPZUVIN.js → chunk-F5QK5YVI.js} +2 -2
- package/dist/{chunk-3SZIQI45.js → chunk-YJKUWFIC.js} +13 -2
- package/dist/chunk-YJKUWFIC.js.map +1 -0
- package/dist/cli.cjs +241 -70
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +231 -71
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/testing/index.cjs +12 -1
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3SZIQI45.js.map +0 -1
- /package/dist/{chunk-UBPZUVIN.js.map → chunk-F5QK5YVI.js.map} +0 -0
package/dist/cli.cjs
CHANGED
|
@@ -9479,13 +9479,24 @@ ${endPrefix}`
|
|
|
9479
9479
|
observers: {
|
|
9480
9480
|
...hooks?.observers,
|
|
9481
9481
|
onLLMCallStart: async (context) => {
|
|
9482
|
+
let inputTokens;
|
|
9483
|
+
try {
|
|
9484
|
+
if (this.client) {
|
|
9485
|
+
inputTokens = await this.client.countTokens(
|
|
9486
|
+
context.options.model,
|
|
9487
|
+
context.options.messages
|
|
9488
|
+
);
|
|
9489
|
+
}
|
|
9490
|
+
} catch {
|
|
9491
|
+
}
|
|
9482
9492
|
onSubagentEvent({
|
|
9483
9493
|
type: "llm_call_start",
|
|
9484
9494
|
gadgetInvocationId: invocationId,
|
|
9485
9495
|
depth,
|
|
9486
9496
|
event: {
|
|
9487
9497
|
iteration: context.iteration,
|
|
9488
|
-
model: context.options.model
|
|
9498
|
+
model: context.options.model,
|
|
9499
|
+
inputTokens
|
|
9489
9500
|
}
|
|
9490
9501
|
});
|
|
9491
9502
|
if (existingOnLLMCallStart) {
|
|
@@ -9958,7 +9969,7 @@ var import_commander2 = require("commander");
|
|
|
9958
9969
|
// package.json
|
|
9959
9970
|
var package_default = {
|
|
9960
9971
|
name: "llmist",
|
|
9961
|
-
version: "5.
|
|
9972
|
+
version: "5.1.0",
|
|
9962
9973
|
description: "TypeScript LLM client with streaming tool execution. Tools fire mid-stream. Built-in function calling works with any model\u2014no structured outputs or native tool support required.",
|
|
9963
9974
|
type: "module",
|
|
9964
9975
|
main: "dist/index.cjs",
|
|
@@ -12954,7 +12965,7 @@ function getRawValue(value) {
|
|
|
12954
12965
|
function truncateValue(str, maxLen) {
|
|
12955
12966
|
if (maxLen <= 0) return "";
|
|
12956
12967
|
if (str.length <= maxLen) return str;
|
|
12957
|
-
return `${str.slice(0, maxLen)}\u2026`;
|
|
12968
|
+
return `${str.slice(0, maxLen - 1)}\u2026`;
|
|
12958
12969
|
}
|
|
12959
12970
|
function formatParametersInline(params, maxWidth) {
|
|
12960
12971
|
if (!params || Object.keys(params).length === 0) {
|
|
@@ -12982,6 +12993,11 @@ function formatParametersInline(params, maxWidth) {
|
|
|
12982
12993
|
const proportion = v.length / totalRawLength;
|
|
12983
12994
|
return Math.max(minPerValue, Math.floor(proportion * availableForValues));
|
|
12984
12995
|
});
|
|
12996
|
+
const totalLimits = limits.reduce((sum, l) => sum + l, 0);
|
|
12997
|
+
if (totalLimits > availableForValues) {
|
|
12998
|
+
const scale = availableForValues / totalLimits;
|
|
12999
|
+
limits = limits.map((l) => Math.max(1, Math.floor(l * scale)));
|
|
13000
|
+
}
|
|
12985
13001
|
}
|
|
12986
13002
|
}
|
|
12987
13003
|
} else {
|
|
@@ -12997,8 +13013,8 @@ function formatGadgetLine(info, maxWidth) {
|
|
|
12997
13013
|
const gadgetLabel = import_chalk3.default.magenta.bold(info.name);
|
|
12998
13014
|
const timeStr = `${info.elapsedSeconds.toFixed(1)}s`;
|
|
12999
13015
|
const timeLabel = import_chalk3.default.dim(timeStr);
|
|
13000
|
-
const fixedLength =
|
|
13001
|
-
const availableForParams = Math.max(40, terminalWidth - fixedLength -
|
|
13016
|
+
const fixedLength = 3 + info.name.length + 2 + 1 + timeStr.length;
|
|
13017
|
+
const availableForParams = Math.max(40, terminalWidth - fixedLength - 3);
|
|
13002
13018
|
const paramsStr = formatParametersInline(info.parameters, availableForParams);
|
|
13003
13019
|
const paramsLabel = paramsStr ? `${import_chalk3.default.dim("(")}${paramsStr}${import_chalk3.default.dim(")")}` : "";
|
|
13004
13020
|
if (info.error) {
|
|
@@ -13008,17 +13024,21 @@ function formatGadgetLine(info, maxWidth) {
|
|
|
13008
13024
|
if (!info.isComplete) {
|
|
13009
13025
|
return `${import_chalk3.default.blue("\u23F5")} ${gadgetLabel}${paramsLabel} ${timeLabel}`;
|
|
13010
13026
|
}
|
|
13011
|
-
let
|
|
13027
|
+
let outputLabel;
|
|
13012
13028
|
if (info.tokenCount !== void 0 && info.tokenCount > 0) {
|
|
13013
|
-
|
|
13029
|
+
outputLabel = import_chalk3.default.dim("\u2193") + import_chalk3.default.green(` ${formatTokens(info.tokenCount)} `);
|
|
13014
13030
|
} else if (info.outputBytes !== void 0 && info.outputBytes > 0) {
|
|
13015
|
-
|
|
13031
|
+
outputLabel = import_chalk3.default.green(formatBytes(info.outputBytes)) + " ";
|
|
13016
13032
|
} else {
|
|
13017
|
-
|
|
13033
|
+
outputLabel = "";
|
|
13018
13034
|
}
|
|
13019
13035
|
const icon = info.breaksLoop ? import_chalk3.default.yellow("\u23F9") : import_chalk3.default.green("\u2713");
|
|
13020
|
-
const
|
|
13021
|
-
|
|
13036
|
+
const nameRef = import_chalk3.default.magenta(info.name);
|
|
13037
|
+
const line1 = `${icon} ${gadgetLabel}${paramsLabel}`;
|
|
13038
|
+
const line2Prefix = ` ${import_chalk3.default.dim("\u2192")} ${nameRef} ${outputLabel}`;
|
|
13039
|
+
const line2 = `${line2Prefix}${timeLabel}`;
|
|
13040
|
+
return `${line1}
|
|
13041
|
+
${line2}`;
|
|
13022
13042
|
}
|
|
13023
13043
|
function formatBytes(bytes) {
|
|
13024
13044
|
if (bytes < 1024) {
|
|
@@ -13029,6 +13049,11 @@ function formatBytes(bytes) {
|
|
|
13029
13049
|
}
|
|
13030
13050
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
13031
13051
|
}
|
|
13052
|
+
function truncateOutputPreview(output, maxWidth) {
|
|
13053
|
+
const normalized = output.replace(/\s+/g, " ").trim();
|
|
13054
|
+
if (normalized.length <= maxWidth) return normalized;
|
|
13055
|
+
return normalized.slice(0, maxWidth - 1) + "\u2026";
|
|
13056
|
+
}
|
|
13032
13057
|
function getMediaIcon(kind) {
|
|
13033
13058
|
switch (kind) {
|
|
13034
13059
|
case "image":
|
|
@@ -13056,37 +13081,99 @@ function formatGadgetSummary2(result) {
|
|
|
13056
13081
|
const gadgetLabel = import_chalk3.default.magenta.bold(result.gadgetName);
|
|
13057
13082
|
const timeStr = result.executionTimeMs >= 1e3 ? `${(result.executionTimeMs / 1e3).toFixed(1)}s` : `${Math.round(result.executionTimeMs)}ms`;
|
|
13058
13083
|
const timeLabel = import_chalk3.default.dim(timeStr);
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
|
|
13084
|
+
const fixedLength = 3 + result.gadgetName.length + 2;
|
|
13085
|
+
const availableForParams = Math.max(40, terminalWidth - fixedLength - 3);
|
|
13086
|
+
const paramsStr = formatParametersInline(result.parameters, availableForParams);
|
|
13087
|
+
const paramsLabel = paramsStr ? `${import_chalk3.default.dim("(")}${paramsStr}${import_chalk3.default.dim(")")}` : "";
|
|
13088
|
+
const icon = result.breaksLoop ? import_chalk3.default.yellow("\u23F9") : result.error ? import_chalk3.default.red("\u2717") : import_chalk3.default.green("\u2713");
|
|
13089
|
+
const line1 = `${icon} ${gadgetLabel}${paramsLabel}`;
|
|
13090
|
+
const nameRef = import_chalk3.default.magenta(result.gadgetName);
|
|
13091
|
+
const hasSubagentMetrics = result.subagentMetrics && result.subagentMetrics.callCount > 0;
|
|
13092
|
+
let outputLabel;
|
|
13093
|
+
let outputStrRaw;
|
|
13094
|
+
if (!hasSubagentMetrics && result.tokenCount !== void 0 && result.tokenCount > 0) {
|
|
13095
|
+
const tokenStr = formatTokens(result.tokenCount);
|
|
13096
|
+
outputLabel = import_chalk3.default.dim("\u2193") + import_chalk3.default.green(` ${tokenStr} `);
|
|
13097
|
+
outputStrRaw = `\u2193 ${tokenStr} `;
|
|
13098
|
+
} else if (!hasSubagentMetrics && result.result) {
|
|
13063
13099
|
const outputBytes = Buffer.byteLength(result.result, "utf-8");
|
|
13064
|
-
|
|
13100
|
+
if (outputBytes > 0) {
|
|
13101
|
+
const bytesStr = formatBytes(outputBytes);
|
|
13102
|
+
outputLabel = import_chalk3.default.green(bytesStr) + " ";
|
|
13103
|
+
outputStrRaw = bytesStr + " ";
|
|
13104
|
+
} else {
|
|
13105
|
+
outputLabel = "";
|
|
13106
|
+
outputStrRaw = "";
|
|
13107
|
+
}
|
|
13065
13108
|
} else {
|
|
13066
|
-
|
|
13109
|
+
outputLabel = "";
|
|
13110
|
+
outputStrRaw = "";
|
|
13067
13111
|
}
|
|
13068
|
-
const fixedLength = 2 + result.gadgetName.length + 2 + 3 + outputStr.length + 1 + timeStr.length;
|
|
13069
|
-
const availableForParams = Math.max(40, terminalWidth - fixedLength - 2);
|
|
13070
|
-
const paramsStr = formatParametersInline(result.parameters, availableForParams);
|
|
13071
|
-
const paramsLabel = paramsStr ? `${import_chalk3.default.dim("(")}${paramsStr}${import_chalk3.default.dim(")")}` : "";
|
|
13072
13112
|
if (result.error) {
|
|
13073
13113
|
const errorMsg = result.error.length > 50 ? `${result.error.slice(0, 50)}\u2026` : result.error;
|
|
13074
|
-
|
|
13114
|
+
const line22 = ` ${import_chalk3.default.dim("\u2192")} ${nameRef} ${import_chalk3.default.red("error:")} ${errorMsg} ${timeLabel}`;
|
|
13115
|
+
return `${line1}
|
|
13116
|
+
${line22}`;
|
|
13117
|
+
}
|
|
13118
|
+
const previewWidth = Math.floor(terminalWidth * 0.6);
|
|
13119
|
+
const prefixLength = 4 + result.gadgetName.length + 1 + outputStrRaw.length + 1 + timeStr.length + 2;
|
|
13120
|
+
const availablePreview = Math.max(20, previewWidth - prefixLength);
|
|
13121
|
+
let customPreview;
|
|
13122
|
+
if (result.gadgetName === "TodoUpsert" && result.parameters?.content) {
|
|
13123
|
+
const statusEmoji = result.parameters.status === "done" ? "\u2705" : result.parameters.status === "in_progress" ? "\u{1F504}" : "\u2B1C";
|
|
13124
|
+
const content = String(result.parameters.content);
|
|
13125
|
+
customPreview = `${statusEmoji} ${truncateOutputPreview(content, availablePreview - 3)}`;
|
|
13126
|
+
}
|
|
13127
|
+
if (result.gadgetName === "GoogleSearch" && result.parameters?.query) {
|
|
13128
|
+
const query = String(result.parameters.query);
|
|
13129
|
+
const countMatch = result.result?.match(/\((\d+)\s+of\s+[\d,]+\s+results?\)/i) || // "(10 of 36400000 results)"
|
|
13130
|
+
result.result?.match(/(\d+)\s+results?\s+found/i) || // "10 results found"
|
|
13131
|
+
result.result?.match(/found\s+(\d+)\s+results?/i);
|
|
13132
|
+
const count = countMatch?.[1] ?? (result.parameters.maxResults ? String(result.parameters.maxResults) : null);
|
|
13133
|
+
const countStr = count ? ` \u2192 ${count} results` : "";
|
|
13134
|
+
const queryPreview = truncateOutputPreview(query, availablePreview - 5 - countStr.length);
|
|
13135
|
+
customPreview = `\u{1F50D} "${queryPreview}"${countStr}`;
|
|
13136
|
+
}
|
|
13137
|
+
let subagentMetricsStr = "";
|
|
13138
|
+
if (result.subagentMetrics && result.subagentMetrics.callCount > 0) {
|
|
13139
|
+
const parts = [];
|
|
13140
|
+
const m = result.subagentMetrics;
|
|
13141
|
+
if (m.inputTokens > 0) {
|
|
13142
|
+
parts.push(import_chalk3.default.dim("\u2191") + import_chalk3.default.yellow(` ${formatTokens(m.inputTokens)}`));
|
|
13143
|
+
}
|
|
13144
|
+
if (m.cachedInputTokens > 0) {
|
|
13145
|
+
parts.push(import_chalk3.default.dim("\u27F3") + import_chalk3.default.blue(` ${formatTokens(m.cachedInputTokens)}`));
|
|
13146
|
+
}
|
|
13147
|
+
if (m.outputTokens > 0) {
|
|
13148
|
+
parts.push(import_chalk3.default.dim("\u2193") + import_chalk3.default.green(` ${formatTokens(m.outputTokens)}`));
|
|
13149
|
+
}
|
|
13150
|
+
if (m.cost > 0) {
|
|
13151
|
+
parts.push(import_chalk3.default.cyan(`$${formatCost(m.cost)}`));
|
|
13152
|
+
}
|
|
13153
|
+
if (parts.length > 0) {
|
|
13154
|
+
subagentMetricsStr = parts.join(import_chalk3.default.dim(" | ")) + import_chalk3.default.dim(" | ");
|
|
13155
|
+
}
|
|
13075
13156
|
}
|
|
13076
|
-
|
|
13077
|
-
const
|
|
13078
|
-
|
|
13157
|
+
let line2;
|
|
13158
|
+
const previewContent = customPreview ?? (result.result?.trim() ? truncateOutputPreview(result.result, availablePreview) : null);
|
|
13159
|
+
if (previewContent) {
|
|
13160
|
+
line2 = ` ${import_chalk3.default.dim("\u2192")} ${nameRef} ${outputLabel}${subagentMetricsStr}${timeLabel}${import_chalk3.default.dim(":")} ${import_chalk3.default.dim(previewContent)}`;
|
|
13161
|
+
} else {
|
|
13162
|
+
line2 = ` ${import_chalk3.default.dim("\u2192")} ${nameRef} ${outputLabel}${subagentMetricsStr}${timeLabel}`;
|
|
13163
|
+
}
|
|
13164
|
+
let output = `${line1}
|
|
13165
|
+
${line2}`;
|
|
13079
13166
|
if (result.media && result.media.length > 0) {
|
|
13080
13167
|
const mediaLines = result.media.map(formatMediaLine);
|
|
13081
|
-
|
|
13168
|
+
output += "\n" + mediaLines.join("\n");
|
|
13082
13169
|
}
|
|
13083
13170
|
if (result.gadgetName === "TellUser" && result.parameters?.message) {
|
|
13084
13171
|
const message = String(result.parameters.message);
|
|
13085
13172
|
const rendered = renderMarkdownWithSeparators(message);
|
|
13086
|
-
return `${
|
|
13173
|
+
return `${output}
|
|
13087
13174
|
${rendered}`;
|
|
13088
13175
|
}
|
|
13089
|
-
return
|
|
13176
|
+
return output;
|
|
13090
13177
|
}
|
|
13091
13178
|
|
|
13092
13179
|
// src/cli/utils.ts
|
|
@@ -13283,14 +13370,15 @@ var StreamProgress = class {
|
|
|
13283
13370
|
* Add a nested agent LLM call (called when nested llm_call_start event received).
|
|
13284
13371
|
* Used to display hierarchical progress for subagent gadgets.
|
|
13285
13372
|
*/
|
|
13286
|
-
addNestedAgent(id, parentInvocationId, depth, model, iteration,
|
|
13373
|
+
addNestedAgent(id, parentInvocationId, depth, model, iteration, info) {
|
|
13287
13374
|
this.nestedAgents.set(id, {
|
|
13288
13375
|
parentInvocationId,
|
|
13289
13376
|
depth,
|
|
13290
13377
|
model,
|
|
13291
13378
|
iteration,
|
|
13292
13379
|
startTime: Date.now(),
|
|
13293
|
-
inputTokens
|
|
13380
|
+
inputTokens: info?.inputTokens,
|
|
13381
|
+
cachedInputTokens: info?.cachedInputTokens
|
|
13294
13382
|
});
|
|
13295
13383
|
if (this.isRunning && this.isTTY) {
|
|
13296
13384
|
this.render();
|
|
@@ -13304,22 +13392,23 @@ var StreamProgress = class {
|
|
|
13304
13392
|
updateNestedAgent(id, info) {
|
|
13305
13393
|
const agent = this.nestedAgents.get(id);
|
|
13306
13394
|
if (agent) {
|
|
13307
|
-
agent.inputTokens = info.inputTokens;
|
|
13308
|
-
agent.outputTokens = info.outputTokens;
|
|
13309
|
-
agent.cachedInputTokens = info.cachedInputTokens;
|
|
13310
|
-
|
|
13311
|
-
|
|
13395
|
+
if (info.inputTokens !== void 0) agent.inputTokens = info.inputTokens;
|
|
13396
|
+
if (info.outputTokens !== void 0) agent.outputTokens = info.outputTokens;
|
|
13397
|
+
if (info.cachedInputTokens !== void 0) agent.cachedInputTokens = info.cachedInputTokens;
|
|
13398
|
+
if (info.cacheCreationInputTokens !== void 0)
|
|
13399
|
+
agent.cacheCreationInputTokens = info.cacheCreationInputTokens;
|
|
13400
|
+
if (info.finishReason !== void 0) agent.finishReason = info.finishReason;
|
|
13312
13401
|
if (info.cost !== void 0) {
|
|
13313
13402
|
agent.cost = info.cost;
|
|
13314
|
-
} else if (this.modelRegistry && agent.model &&
|
|
13403
|
+
} else if (this.modelRegistry && agent.model && agent.outputTokens) {
|
|
13315
13404
|
try {
|
|
13316
13405
|
const modelName = agent.model.includes(":") ? agent.model.split(":")[1] : agent.model;
|
|
13317
13406
|
const costResult = this.modelRegistry.estimateCost(
|
|
13318
13407
|
modelName,
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13322
|
-
|
|
13408
|
+
agent.inputTokens ?? 0,
|
|
13409
|
+
agent.outputTokens,
|
|
13410
|
+
agent.cachedInputTokens,
|
|
13411
|
+
agent.cacheCreationInputTokens
|
|
13323
13412
|
);
|
|
13324
13413
|
agent.cost = costResult?.totalCost;
|
|
13325
13414
|
} catch {
|
|
@@ -13341,6 +13430,27 @@ var StreamProgress = class {
|
|
|
13341
13430
|
this.render();
|
|
13342
13431
|
}
|
|
13343
13432
|
}
|
|
13433
|
+
/**
|
|
13434
|
+
* Get aggregated metrics from all nested agents for a parent gadget.
|
|
13435
|
+
* Used to show total token counts and cost for subagent gadgets like BrowseWeb.
|
|
13436
|
+
*/
|
|
13437
|
+
getAggregatedSubagentMetrics(parentInvocationId) {
|
|
13438
|
+
let inputTokens = 0;
|
|
13439
|
+
let outputTokens = 0;
|
|
13440
|
+
let cachedInputTokens = 0;
|
|
13441
|
+
let cost = 0;
|
|
13442
|
+
let callCount = 0;
|
|
13443
|
+
for (const [, nested] of this.nestedAgents) {
|
|
13444
|
+
if (nested.parentInvocationId === parentInvocationId) {
|
|
13445
|
+
inputTokens += nested.inputTokens ?? 0;
|
|
13446
|
+
outputTokens += nested.outputTokens ?? 0;
|
|
13447
|
+
cachedInputTokens += nested.cachedInputTokens ?? 0;
|
|
13448
|
+
cost += nested.cost ?? 0;
|
|
13449
|
+
callCount++;
|
|
13450
|
+
}
|
|
13451
|
+
}
|
|
13452
|
+
return { inputTokens, outputTokens, cachedInputTokens, cost, callCount };
|
|
13453
|
+
}
|
|
13344
13454
|
/**
|
|
13345
13455
|
* Add a nested gadget call (called when nested gadget_call event received).
|
|
13346
13456
|
*/
|
|
@@ -13508,20 +13618,22 @@ var StreamProgress = class {
|
|
|
13508
13618
|
this.clearRenderedLines();
|
|
13509
13619
|
const spinner = SPINNER_FRAMES[this.frameIndex++ % SPINNER_FRAMES.length];
|
|
13510
13620
|
const lines = [];
|
|
13511
|
-
|
|
13512
|
-
lines.push(this.formatStreamingLine(spinner));
|
|
13513
|
-
} else {
|
|
13514
|
-
lines.push(this.formatCumulativeLine(spinner));
|
|
13515
|
-
}
|
|
13621
|
+
const activeNestedStreams = [];
|
|
13516
13622
|
if (this.isTTY) {
|
|
13517
13623
|
for (const [gadgetId, gadget] of this.inFlightGadgets) {
|
|
13518
13624
|
const elapsedSeconds = (Date.now() - gadget.startTime) / 1e3;
|
|
13519
|
-
const
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13523
|
-
|
|
13524
|
-
|
|
13625
|
+
const termWidth = process.stdout.columns ?? 80;
|
|
13626
|
+
const gadgetIndent = " ";
|
|
13627
|
+
const line = formatGadgetLine(
|
|
13628
|
+
{
|
|
13629
|
+
name: gadget.name,
|
|
13630
|
+
parameters: gadget.params,
|
|
13631
|
+
elapsedSeconds,
|
|
13632
|
+
isComplete: false
|
|
13633
|
+
},
|
|
13634
|
+
termWidth - gadgetIndent.length
|
|
13635
|
+
);
|
|
13636
|
+
const gadgetLine = line.split("\n").map((l) => gadgetIndent + l).join("\n");
|
|
13525
13637
|
lines.push(gadgetLine);
|
|
13526
13638
|
const nestedOps = [];
|
|
13527
13639
|
for (const [_agentId, nested] of this.nestedAgents) {
|
|
@@ -13540,6 +13652,18 @@ var StreamProgress = class {
|
|
|
13540
13652
|
completed: nested.completed,
|
|
13541
13653
|
completedTime: nested.completedTime
|
|
13542
13654
|
});
|
|
13655
|
+
if (!nested.completed) {
|
|
13656
|
+
activeNestedStreams.push({
|
|
13657
|
+
depth: nested.depth,
|
|
13658
|
+
iteration: nested.iteration,
|
|
13659
|
+
model: nested.model,
|
|
13660
|
+
inputTokens: nested.inputTokens,
|
|
13661
|
+
cachedInputTokens: nested.cachedInputTokens,
|
|
13662
|
+
outputTokens: nested.outputTokens,
|
|
13663
|
+
cost: nested.cost,
|
|
13664
|
+
startTime: nested.startTime
|
|
13665
|
+
});
|
|
13666
|
+
}
|
|
13543
13667
|
}
|
|
13544
13668
|
}
|
|
13545
13669
|
for (const [_nestedId, nestedGadget] of this.nestedGadgets) {
|
|
@@ -13557,11 +13681,14 @@ var StreamProgress = class {
|
|
|
13557
13681
|
}
|
|
13558
13682
|
nestedOps.sort((a, b) => a.startTime - b.startTime);
|
|
13559
13683
|
for (const op of nestedOps) {
|
|
13560
|
-
|
|
13684
|
+
if (op.type === "agent" && !op.completed) {
|
|
13685
|
+
continue;
|
|
13686
|
+
}
|
|
13687
|
+
const indent = " ".repeat(op.depth + 2);
|
|
13561
13688
|
const endTime = op.completedTime ?? Date.now();
|
|
13562
13689
|
const elapsedSeconds2 = (endTime - op.startTime) / 1e3;
|
|
13563
13690
|
if (op.type === "agent") {
|
|
13564
|
-
const
|
|
13691
|
+
const line2 = formatLLMCallLine({
|
|
13565
13692
|
iteration: op.iteration ?? 0,
|
|
13566
13693
|
model: op.model ?? "",
|
|
13567
13694
|
inputTokens: op.inputTokens,
|
|
@@ -13573,21 +13700,48 @@ var StreamProgress = class {
|
|
|
13573
13700
|
isStreaming: !op.completed,
|
|
13574
13701
|
spinner
|
|
13575
13702
|
});
|
|
13576
|
-
lines.push(`${indent}${
|
|
13703
|
+
lines.push(`${indent}${line2}`);
|
|
13577
13704
|
} else {
|
|
13578
|
-
const
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
|
|
13584
|
-
|
|
13705
|
+
const termWidth2 = process.stdout.columns ?? 80;
|
|
13706
|
+
const line2 = formatGadgetLine(
|
|
13707
|
+
{
|
|
13708
|
+
name: op.name ?? "",
|
|
13709
|
+
parameters: op.parameters,
|
|
13710
|
+
elapsedSeconds: elapsedSeconds2,
|
|
13711
|
+
isComplete: op.completed ?? false
|
|
13712
|
+
},
|
|
13713
|
+
termWidth2 - indent.length
|
|
13714
|
+
);
|
|
13715
|
+
const indentedLine = line2.split("\n").map((l) => indent + l).join("\n");
|
|
13716
|
+
lines.push(indentedLine);
|
|
13585
13717
|
}
|
|
13586
13718
|
}
|
|
13587
13719
|
}
|
|
13588
13720
|
}
|
|
13589
|
-
|
|
13590
|
-
|
|
13721
|
+
for (const stream2 of activeNestedStreams) {
|
|
13722
|
+
const indent = " ".repeat(stream2.depth + 2);
|
|
13723
|
+
const elapsedSeconds = (Date.now() - stream2.startTime) / 1e3;
|
|
13724
|
+
const line = formatLLMCallLine({
|
|
13725
|
+
iteration: stream2.iteration,
|
|
13726
|
+
model: stream2.model,
|
|
13727
|
+
inputTokens: stream2.inputTokens,
|
|
13728
|
+
cachedInputTokens: stream2.cachedInputTokens,
|
|
13729
|
+
outputTokens: stream2.outputTokens,
|
|
13730
|
+
elapsedSeconds,
|
|
13731
|
+
cost: stream2.cost,
|
|
13732
|
+
isStreaming: true,
|
|
13733
|
+
spinner
|
|
13734
|
+
});
|
|
13735
|
+
lines.push(`${indent}${line}`);
|
|
13736
|
+
}
|
|
13737
|
+
if (this.mode === "streaming") {
|
|
13738
|
+
lines.push(this.formatStreamingLine(spinner));
|
|
13739
|
+
} else {
|
|
13740
|
+
lines.push(this.formatCumulativeLine(spinner));
|
|
13741
|
+
}
|
|
13742
|
+
const output = lines.join("\n");
|
|
13743
|
+
this.lastRenderLineCount = (output.match(/\n/g) || []).length + 1;
|
|
13744
|
+
this.target.write("\r" + output);
|
|
13591
13745
|
this.hasRendered = true;
|
|
13592
13746
|
}
|
|
13593
13747
|
/**
|
|
@@ -14199,6 +14353,7 @@ async function executeAgent(promptArg, options, env) {
|
|
|
14199
14353
|
env.stderr.write(`${summary}
|
|
14200
14354
|
`);
|
|
14201
14355
|
}
|
|
14356
|
+
env.stderr.write("\n");
|
|
14202
14357
|
}
|
|
14203
14358
|
if (llmSessionDir) {
|
|
14204
14359
|
const filename = `${formatCallNumber(llmCallCounter)}.response`;
|
|
@@ -14305,8 +14460,7 @@ Denied: ${result.reason ?? "by user"}`
|
|
|
14305
14460
|
builder.withTrailingMessage(
|
|
14306
14461
|
(ctx) => [
|
|
14307
14462
|
`[Iteration ${ctx.iteration + 1}/${ctx.maxIterations}]`,
|
|
14308
|
-
"Think carefully: what gadget invocations can
|
|
14309
|
-
"Maximize efficiency by batching independent operations in a single response."
|
|
14463
|
+
"Think carefully in two steps: 1. what gadget invocations we should be making next? 2. how do they depend on one another so we can run all of them in the right order? Then respond with all the gadget invocations you are able to do now."
|
|
14310
14464
|
].join(" ")
|
|
14311
14465
|
);
|
|
14312
14466
|
if (!options.quiet) {
|
|
@@ -14319,8 +14473,12 @@ Denied: ${result.reason ?? "by user"}`
|
|
|
14319
14473
|
subagentEvent.gadgetInvocationId,
|
|
14320
14474
|
subagentEvent.depth,
|
|
14321
14475
|
info.model,
|
|
14322
|
-
info.iteration,
|
|
14323
|
-
|
|
14476
|
+
info.iteration + 1,
|
|
14477
|
+
// Make 1-indexed like main agent
|
|
14478
|
+
{
|
|
14479
|
+
inputTokens: info.usage?.inputTokens ?? info.inputTokens,
|
|
14480
|
+
cachedInputTokens: info.usage?.cachedInputTokens
|
|
14481
|
+
}
|
|
14324
14482
|
);
|
|
14325
14483
|
} else if (subagentEvent.type === "llm_call_end") {
|
|
14326
14484
|
const info = subagentEvent.event;
|
|
@@ -14397,10 +14555,23 @@ Denied: ${result.reason ?? "by user"}`
|
|
|
14397
14555
|
}
|
|
14398
14556
|
} else {
|
|
14399
14557
|
const tokenCount = await countGadgetOutputTokens(event.result.result);
|
|
14400
|
-
|
|
14401
|
-
|
|
14402
|
-
`
|
|
14558
|
+
const subagentMetrics = progress.getAggregatedSubagentMetrics(
|
|
14559
|
+
event.result.invocationId
|
|
14403
14560
|
);
|
|
14561
|
+
const summary = formatGadgetSummary2({
|
|
14562
|
+
...event.result,
|
|
14563
|
+
tokenCount,
|
|
14564
|
+
media: event.result.storedMedia,
|
|
14565
|
+
subagentMetrics: subagentMetrics.callCount > 0 ? subagentMetrics : void 0
|
|
14566
|
+
});
|
|
14567
|
+
if (event.result.gadgetName === "TellUser") {
|
|
14568
|
+
env.stderr.write(`${summary}
|
|
14569
|
+
`);
|
|
14570
|
+
} else {
|
|
14571
|
+
const indentedSummary = summary.split("\n").map((line) => " " + line).join("\n");
|
|
14572
|
+
env.stderr.write(`${indentedSummary}
|
|
14573
|
+
`);
|
|
14574
|
+
}
|
|
14404
14575
|
}
|
|
14405
14576
|
if (progress.hasInFlightGadgets()) {
|
|
14406
14577
|
progress.start();
|