llmist 0.6.2 → 0.8.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-TSR25DAY.js → chunk-4IMGADVY.js} +2 -2
- package/dist/{chunk-DVK6ZQOV.js → chunk-62M4TDAK.js} +501 -78
- package/dist/chunk-62M4TDAK.js.map +1 -0
- package/dist/cli.cjs +946 -197
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +436 -110
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +511 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -9
- package/dist/index.d.ts +6 -9
- package/dist/index.js +2 -2
- package/dist/{mock-stream-B5R6XPif.d.cts → mock-stream-CjmvWDc3.d.cts} +91 -20
- package/dist/{mock-stream-B5R6XPif.d.ts → mock-stream-CjmvWDc3.d.ts} +91 -20
- package/dist/testing/index.cjs +497 -74
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +2 -2
- package/package.json +2 -1
- package/dist/chunk-DVK6ZQOV.js.map +0 -1
- /package/dist/{chunk-TSR25DAY.js.map → chunk-4IMGADVY.js.map} +0 -0
package/dist/cli.cjs
CHANGED
|
@@ -31,6 +31,20 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
));
|
|
32
32
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
33
|
|
|
34
|
+
// src/core/constants.ts
|
|
35
|
+
var GADGET_START_PREFIX, GADGET_END_PREFIX, DEFAULT_GADGET_OUTPUT_LIMIT, DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT, CHARS_PER_TOKEN, FALLBACK_CONTEXT_WINDOW;
|
|
36
|
+
var init_constants = __esm({
|
|
37
|
+
"src/core/constants.ts"() {
|
|
38
|
+
"use strict";
|
|
39
|
+
GADGET_START_PREFIX = "!!!GADGET_START:";
|
|
40
|
+
GADGET_END_PREFIX = "!!!GADGET_END";
|
|
41
|
+
DEFAULT_GADGET_OUTPUT_LIMIT = true;
|
|
42
|
+
DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT = 15;
|
|
43
|
+
CHARS_PER_TOKEN = 4;
|
|
44
|
+
FALLBACK_CONTEXT_WINDOW = 128e3;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
34
48
|
// src/core/model-shortcuts.ts
|
|
35
49
|
function isKnownModelPattern(model) {
|
|
36
50
|
const normalized = model.toLowerCase();
|
|
@@ -328,20 +342,6 @@ var init_registry = __esm({
|
|
|
328
342
|
}
|
|
329
343
|
});
|
|
330
344
|
|
|
331
|
-
// src/core/constants.ts
|
|
332
|
-
var GADGET_START_PREFIX, GADGET_END_PREFIX, DEFAULT_GADGET_OUTPUT_LIMIT, DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT, CHARS_PER_TOKEN, FALLBACK_CONTEXT_WINDOW;
|
|
333
|
-
var init_constants = __esm({
|
|
334
|
-
"src/core/constants.ts"() {
|
|
335
|
-
"use strict";
|
|
336
|
-
GADGET_START_PREFIX = "!!!GADGET_START:";
|
|
337
|
-
GADGET_END_PREFIX = "!!!GADGET_END";
|
|
338
|
-
DEFAULT_GADGET_OUTPUT_LIMIT = true;
|
|
339
|
-
DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT = 15;
|
|
340
|
-
CHARS_PER_TOKEN = 4;
|
|
341
|
-
FALLBACK_CONTEXT_WINDOW = 128e3;
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
|
|
345
345
|
// src/core/prompt-config.ts
|
|
346
346
|
function resolvePromptTemplate(template, defaultValue, context) {
|
|
347
347
|
const resolved = template ?? defaultValue;
|
|
@@ -865,7 +865,7 @@ function findSafeDelimiter(content) {
|
|
|
865
865
|
}
|
|
866
866
|
let counter = 1;
|
|
867
867
|
while (counter < 1e3) {
|
|
868
|
-
const delimiter = `
|
|
868
|
+
const delimiter = `__GADGET_PARAM_${counter}__`;
|
|
869
869
|
const regex = new RegExp(`^${delimiter}\\s*$`);
|
|
870
870
|
const isUsed = lines.some((line) => regex.test(line));
|
|
871
871
|
if (!isUsed) {
|
|
@@ -923,6 +923,10 @@ function formatParamsAsYaml(params) {
|
|
|
923
923
|
}
|
|
924
924
|
return lines.join("\n");
|
|
925
925
|
}
|
|
926
|
+
function formatTomlInlineTable(obj) {
|
|
927
|
+
const entries = Object.entries(obj).map(([k, v]) => `${k} = ${formatTomlValue(v)}`);
|
|
928
|
+
return `{ ${entries.join(", ")} }`;
|
|
929
|
+
}
|
|
926
930
|
function formatTomlValue(value) {
|
|
927
931
|
if (typeof value === "string") {
|
|
928
932
|
if (value.includes("\n")) {
|
|
@@ -940,10 +944,17 @@ ${delimiter}`;
|
|
|
940
944
|
return '""';
|
|
941
945
|
}
|
|
942
946
|
if (Array.isArray(value)) {
|
|
943
|
-
|
|
947
|
+
if (value.length === 0) return "[]";
|
|
948
|
+
const items = value.map((item) => {
|
|
949
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
950
|
+
return formatTomlInlineTable(item);
|
|
951
|
+
}
|
|
952
|
+
return formatTomlValue(item);
|
|
953
|
+
});
|
|
954
|
+
return `[${items.join(", ")}]`;
|
|
944
955
|
}
|
|
945
956
|
if (typeof value === "object") {
|
|
946
|
-
return
|
|
957
|
+
return formatTomlInlineTable(value);
|
|
947
958
|
}
|
|
948
959
|
return JSON.stringify(value);
|
|
949
960
|
}
|
|
@@ -961,7 +972,16 @@ var init_gadget = __esm({
|
|
|
961
972
|
yaml = __toESM(require("js-yaml"), 1);
|
|
962
973
|
init_schema_to_json();
|
|
963
974
|
init_schema_validator();
|
|
964
|
-
HEREDOC_DELIMITERS = [
|
|
975
|
+
HEREDOC_DELIMITERS = [
|
|
976
|
+
"__GADGET_PARAM_EOF__",
|
|
977
|
+
"__GADGET_PARAM_END__",
|
|
978
|
+
"__GADGET_PARAM_DOC__",
|
|
979
|
+
"__GADGET_PARAM_CONTENT__",
|
|
980
|
+
"__GADGET_PARAM_TEXT__",
|
|
981
|
+
"__GADGET_PARAM_HEREDOC__",
|
|
982
|
+
"__GADGET_PARAM_DATA__",
|
|
983
|
+
"__GADGET_PARAM_BLOCK__"
|
|
984
|
+
];
|
|
965
985
|
BaseGadget = class {
|
|
966
986
|
/**
|
|
967
987
|
* The name of the gadget. Used for identification when LLM calls it.
|
|
@@ -1959,6 +1979,14 @@ function preprocessTomlHeredoc(tomlStr) {
|
|
|
1959
1979
|
}
|
|
1960
1980
|
return result.join("\n");
|
|
1961
1981
|
}
|
|
1982
|
+
function stripMarkdownFences(content) {
|
|
1983
|
+
let cleaned = content.trim();
|
|
1984
|
+
const openingFence = /^```(?:toml|yaml|json)?\s*\n/i;
|
|
1985
|
+
const closingFence = /\n?```\s*$/;
|
|
1986
|
+
cleaned = cleaned.replace(openingFence, "");
|
|
1987
|
+
cleaned = cleaned.replace(closingFence, "");
|
|
1988
|
+
return cleaned.trim();
|
|
1989
|
+
}
|
|
1962
1990
|
var yaml2, import_js_toml, globalInvocationCounter, StreamParser;
|
|
1963
1991
|
var init_parser = __esm({
|
|
1964
1992
|
"src/gadgets/parser.ts"() {
|
|
@@ -2014,35 +2042,36 @@ var init_parser = __esm({
|
|
|
2014
2042
|
* Parse parameter string according to configured format
|
|
2015
2043
|
*/
|
|
2016
2044
|
parseParameters(raw) {
|
|
2045
|
+
const cleaned = stripMarkdownFences(raw);
|
|
2017
2046
|
if (this.parameterFormat === "json") {
|
|
2018
2047
|
try {
|
|
2019
|
-
return { parameters: JSON.parse(
|
|
2048
|
+
return { parameters: JSON.parse(cleaned) };
|
|
2020
2049
|
} catch (error) {
|
|
2021
2050
|
return { parseError: this.truncateParseError(error, "JSON") };
|
|
2022
2051
|
}
|
|
2023
2052
|
}
|
|
2024
2053
|
if (this.parameterFormat === "yaml") {
|
|
2025
2054
|
try {
|
|
2026
|
-
return { parameters: yaml2.load(preprocessYaml(
|
|
2055
|
+
return { parameters: yaml2.load(preprocessYaml(cleaned)) };
|
|
2027
2056
|
} catch (error) {
|
|
2028
2057
|
return { parseError: this.truncateParseError(error, "YAML") };
|
|
2029
2058
|
}
|
|
2030
2059
|
}
|
|
2031
2060
|
if (this.parameterFormat === "toml") {
|
|
2032
2061
|
try {
|
|
2033
|
-
return { parameters: (0, import_js_toml.load)(preprocessTomlHeredoc(
|
|
2062
|
+
return { parameters: (0, import_js_toml.load)(preprocessTomlHeredoc(cleaned)) };
|
|
2034
2063
|
} catch (error) {
|
|
2035
2064
|
return { parseError: this.truncateParseError(error, "TOML") };
|
|
2036
2065
|
}
|
|
2037
2066
|
}
|
|
2038
2067
|
try {
|
|
2039
|
-
return { parameters: JSON.parse(
|
|
2068
|
+
return { parameters: JSON.parse(cleaned) };
|
|
2040
2069
|
} catch {
|
|
2041
2070
|
try {
|
|
2042
|
-
return { parameters: (0, import_js_toml.load)(preprocessTomlHeredoc(
|
|
2071
|
+
return { parameters: (0, import_js_toml.load)(preprocessTomlHeredoc(cleaned)) };
|
|
2043
2072
|
} catch {
|
|
2044
2073
|
try {
|
|
2045
|
-
return { parameters: yaml2.load(preprocessYaml(
|
|
2074
|
+
return { parameters: yaml2.load(preprocessYaml(cleaned)) };
|
|
2046
2075
|
} catch (error) {
|
|
2047
2076
|
return { parseError: this.truncateParseError(error, "auto") };
|
|
2048
2077
|
}
|
|
@@ -2588,6 +2617,7 @@ var init_agent = __esm({
|
|
|
2588
2617
|
gadgetEndPrefix;
|
|
2589
2618
|
onHumanInputRequired;
|
|
2590
2619
|
textOnlyHandler;
|
|
2620
|
+
textWithGadgetsHandler;
|
|
2591
2621
|
stopOnGadgetError;
|
|
2592
2622
|
shouldContinueAfterError;
|
|
2593
2623
|
defaultGadgetTimeoutMs;
|
|
@@ -2618,6 +2648,7 @@ var init_agent = __esm({
|
|
|
2618
2648
|
this.gadgetEndPrefix = options.gadgetEndPrefix;
|
|
2619
2649
|
this.onHumanInputRequired = options.onHumanInputRequired;
|
|
2620
2650
|
this.textOnlyHandler = options.textOnlyHandler ?? "terminate";
|
|
2651
|
+
this.textWithGadgetsHandler = options.textWithGadgetsHandler;
|
|
2621
2652
|
this.stopOnGadgetError = options.stopOnGadgetError ?? true;
|
|
2622
2653
|
this.shouldContinueAfterError = options.shouldContinueAfterError;
|
|
2623
2654
|
this.defaultGadgetTimeoutMs = options.defaultGadgetTimeoutMs;
|
|
@@ -2805,6 +2836,17 @@ var init_agent = __esm({
|
|
|
2805
2836
|
}
|
|
2806
2837
|
}
|
|
2807
2838
|
if (result.didExecuteGadgets) {
|
|
2839
|
+
if (this.textWithGadgetsHandler) {
|
|
2840
|
+
const textContent = result.outputs.filter((output) => output.type === "text").map((output) => output.content).join("");
|
|
2841
|
+
if (textContent.trim()) {
|
|
2842
|
+
const { gadgetName, parameterMapping, resultMapping } = this.textWithGadgetsHandler;
|
|
2843
|
+
this.conversation.addGadgetCall(
|
|
2844
|
+
gadgetName,
|
|
2845
|
+
parameterMapping(textContent),
|
|
2846
|
+
resultMapping ? resultMapping(textContent) : textContent
|
|
2847
|
+
);
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2808
2850
|
for (const output of result.outputs) {
|
|
2809
2851
|
if (output.type === "gadget_result") {
|
|
2810
2852
|
const gadgetResult = output.result;
|
|
@@ -2816,7 +2858,13 @@ var init_agent = __esm({
|
|
|
2816
2858
|
}
|
|
2817
2859
|
}
|
|
2818
2860
|
} else {
|
|
2819
|
-
|
|
2861
|
+
if (finalMessage.trim()) {
|
|
2862
|
+
this.conversation.addGadgetCall(
|
|
2863
|
+
"TellUser",
|
|
2864
|
+
{ message: finalMessage, done: false, type: "info" },
|
|
2865
|
+
`\u2139\uFE0F ${finalMessage}`
|
|
2866
|
+
);
|
|
2867
|
+
}
|
|
2820
2868
|
const shouldBreak = await this.handleTextOnlyResponse(finalMessage);
|
|
2821
2869
|
if (shouldBreak) {
|
|
2822
2870
|
break;
|
|
@@ -3011,7 +3059,8 @@ var init_anthropic_models = __esm({
|
|
|
3011
3059
|
pricing: {
|
|
3012
3060
|
input: 3,
|
|
3013
3061
|
output: 15,
|
|
3014
|
-
cachedInput: 0.3
|
|
3062
|
+
cachedInput: 0.3,
|
|
3063
|
+
cacheWriteInput: 3.75
|
|
3015
3064
|
},
|
|
3016
3065
|
knowledgeCutoff: "2025-01",
|
|
3017
3066
|
features: {
|
|
@@ -3035,7 +3084,8 @@ var init_anthropic_models = __esm({
|
|
|
3035
3084
|
pricing: {
|
|
3036
3085
|
input: 1,
|
|
3037
3086
|
output: 5,
|
|
3038
|
-
cachedInput: 0.1
|
|
3087
|
+
cachedInput: 0.1,
|
|
3088
|
+
cacheWriteInput: 1.25
|
|
3039
3089
|
},
|
|
3040
3090
|
knowledgeCutoff: "2025-02",
|
|
3041
3091
|
features: {
|
|
@@ -3059,7 +3109,8 @@ var init_anthropic_models = __esm({
|
|
|
3059
3109
|
pricing: {
|
|
3060
3110
|
input: 3,
|
|
3061
3111
|
output: 15,
|
|
3062
|
-
cachedInput: 0.3
|
|
3112
|
+
cachedInput: 0.3,
|
|
3113
|
+
cacheWriteInput: 3.75
|
|
3063
3114
|
},
|
|
3064
3115
|
knowledgeCutoff: "2025-03",
|
|
3065
3116
|
features: {
|
|
@@ -3083,7 +3134,8 @@ var init_anthropic_models = __esm({
|
|
|
3083
3134
|
pricing: {
|
|
3084
3135
|
input: 3,
|
|
3085
3136
|
output: 15,
|
|
3086
|
-
cachedInput: 0.3
|
|
3137
|
+
cachedInput: 0.3,
|
|
3138
|
+
cacheWriteInput: 3.75
|
|
3087
3139
|
},
|
|
3088
3140
|
knowledgeCutoff: "2024-11",
|
|
3089
3141
|
features: {
|
|
@@ -3107,7 +3159,8 @@ var init_anthropic_models = __esm({
|
|
|
3107
3159
|
pricing: {
|
|
3108
3160
|
input: 15,
|
|
3109
3161
|
output: 75,
|
|
3110
|
-
cachedInput: 1.5
|
|
3162
|
+
cachedInput: 1.5,
|
|
3163
|
+
cacheWriteInput: 18.75
|
|
3111
3164
|
},
|
|
3112
3165
|
knowledgeCutoff: "2025-01",
|
|
3113
3166
|
features: {
|
|
@@ -3131,7 +3184,8 @@ var init_anthropic_models = __esm({
|
|
|
3131
3184
|
pricing: {
|
|
3132
3185
|
input: 15,
|
|
3133
3186
|
output: 75,
|
|
3134
|
-
cachedInput: 1.5
|
|
3187
|
+
cachedInput: 1.5,
|
|
3188
|
+
cacheWriteInput: 18.75
|
|
3135
3189
|
},
|
|
3136
3190
|
knowledgeCutoff: "2025-03",
|
|
3137
3191
|
features: {
|
|
@@ -3154,7 +3208,8 @@ var init_anthropic_models = __esm({
|
|
|
3154
3208
|
pricing: {
|
|
3155
3209
|
input: 0.8,
|
|
3156
3210
|
output: 4,
|
|
3157
|
-
cachedInput: 0.08
|
|
3211
|
+
cachedInput: 0.08,
|
|
3212
|
+
cacheWriteInput: 1
|
|
3158
3213
|
},
|
|
3159
3214
|
knowledgeCutoff: "2024-07",
|
|
3160
3215
|
features: {
|
|
@@ -3177,7 +3232,8 @@ var init_anthropic_models = __esm({
|
|
|
3177
3232
|
pricing: {
|
|
3178
3233
|
input: 0.25,
|
|
3179
3234
|
output: 1.25,
|
|
3180
|
-
cachedInput: 0.025
|
|
3235
|
+
cachedInput: 0.025,
|
|
3236
|
+
cacheWriteInput: 0.3125
|
|
3181
3237
|
},
|
|
3182
3238
|
knowledgeCutoff: "2023-08",
|
|
3183
3239
|
features: {
|
|
@@ -3201,7 +3257,8 @@ var init_anthropic_models = __esm({
|
|
|
3201
3257
|
pricing: {
|
|
3202
3258
|
input: 1,
|
|
3203
3259
|
output: 5,
|
|
3204
|
-
cachedInput: 0.1
|
|
3260
|
+
cachedInput: 0.1,
|
|
3261
|
+
cacheWriteInput: 1.25
|
|
3205
3262
|
},
|
|
3206
3263
|
knowledgeCutoff: "2025-02",
|
|
3207
3264
|
features: {
|
|
@@ -3225,7 +3282,8 @@ var init_anthropic_models = __esm({
|
|
|
3225
3282
|
pricing: {
|
|
3226
3283
|
input: 3,
|
|
3227
3284
|
output: 15,
|
|
3228
|
-
cachedInput: 0.3
|
|
3285
|
+
cachedInput: 0.3,
|
|
3286
|
+
cacheWriteInput: 3.75
|
|
3229
3287
|
},
|
|
3230
3288
|
knowledgeCutoff: "2025-01",
|
|
3231
3289
|
features: {
|
|
@@ -3249,7 +3307,8 @@ var init_anthropic_models = __esm({
|
|
|
3249
3307
|
pricing: {
|
|
3250
3308
|
input: 5,
|
|
3251
3309
|
output: 25,
|
|
3252
|
-
cachedInput: 0.5
|
|
3310
|
+
cachedInput: 0.5,
|
|
3311
|
+
cacheWriteInput: 6.25
|
|
3253
3312
|
},
|
|
3254
3313
|
knowledgeCutoff: "2025-03",
|
|
3255
3314
|
features: {
|
|
@@ -3364,15 +3423,27 @@ var init_anthropic = __esm({
|
|
|
3364
3423
|
}
|
|
3365
3424
|
buildRequestPayload(options, descriptor, spec, messages) {
|
|
3366
3425
|
const systemMessages = messages.filter((message) => message.role === "system");
|
|
3367
|
-
const system = systemMessages.length > 0 ? systemMessages.map((m) =>
|
|
3368
|
-
|
|
3426
|
+
const system = systemMessages.length > 0 ? systemMessages.map((m, index) => ({
|
|
3427
|
+
type: "text",
|
|
3428
|
+
text: m.content,
|
|
3429
|
+
// Add cache_control to the LAST system message block
|
|
3430
|
+
...index === systemMessages.length - 1 ? { cache_control: { type: "ephemeral" } } : {}
|
|
3431
|
+
})) : void 0;
|
|
3432
|
+
const nonSystemMessages = messages.filter(
|
|
3369
3433
|
(message) => message.role !== "system"
|
|
3370
|
-
)
|
|
3434
|
+
);
|
|
3435
|
+
const lastUserIndex = nonSystemMessages.reduce(
|
|
3436
|
+
(lastIdx, msg, idx) => msg.role === "user" ? idx : lastIdx,
|
|
3437
|
+
-1
|
|
3438
|
+
);
|
|
3439
|
+
const conversation = nonSystemMessages.map((message, index) => ({
|
|
3371
3440
|
role: message.role,
|
|
3372
3441
|
content: [
|
|
3373
3442
|
{
|
|
3374
3443
|
type: "text",
|
|
3375
|
-
text: message.content
|
|
3444
|
+
text: message.content,
|
|
3445
|
+
// Add cache_control to the LAST user message
|
|
3446
|
+
...message.role === "user" && index === lastUserIndex ? { cache_control: { type: "ephemeral" } } : {}
|
|
3376
3447
|
}
|
|
3377
3448
|
]
|
|
3378
3449
|
}));
|
|
@@ -3398,15 +3469,22 @@ var init_anthropic = __esm({
|
|
|
3398
3469
|
async *wrapStream(iterable) {
|
|
3399
3470
|
const stream2 = iterable;
|
|
3400
3471
|
let inputTokens = 0;
|
|
3472
|
+
let cachedInputTokens = 0;
|
|
3473
|
+
let cacheCreationInputTokens = 0;
|
|
3401
3474
|
for await (const event of stream2) {
|
|
3402
3475
|
if (event.type === "message_start") {
|
|
3403
|
-
|
|
3476
|
+
const usage = event.message.usage;
|
|
3477
|
+
cachedInputTokens = usage.cache_read_input_tokens ?? 0;
|
|
3478
|
+
cacheCreationInputTokens = usage.cache_creation_input_tokens ?? 0;
|
|
3479
|
+
inputTokens = usage.input_tokens + cachedInputTokens + cacheCreationInputTokens;
|
|
3404
3480
|
yield {
|
|
3405
3481
|
text: "",
|
|
3406
3482
|
usage: {
|
|
3407
3483
|
inputTokens,
|
|
3408
3484
|
outputTokens: 0,
|
|
3409
|
-
totalTokens: inputTokens
|
|
3485
|
+
totalTokens: inputTokens,
|
|
3486
|
+
cachedInputTokens,
|
|
3487
|
+
cacheCreationInputTokens
|
|
3410
3488
|
},
|
|
3411
3489
|
rawEvent: event
|
|
3412
3490
|
};
|
|
@@ -3420,7 +3498,9 @@ var init_anthropic = __esm({
|
|
|
3420
3498
|
const usage = event.usage ? {
|
|
3421
3499
|
inputTokens,
|
|
3422
3500
|
outputTokens: event.usage.output_tokens,
|
|
3423
|
-
totalTokens: inputTokens + event.usage.output_tokens
|
|
3501
|
+
totalTokens: inputTokens + event.usage.output_tokens,
|
|
3502
|
+
cachedInputTokens,
|
|
3503
|
+
cacheCreationInputTokens
|
|
3424
3504
|
} : void 0;
|
|
3425
3505
|
if (event.delta.stop_reason || usage) {
|
|
3426
3506
|
yield {
|
|
@@ -3501,6 +3581,7 @@ var init_gemini_models = __esm({
|
|
|
3501
3581
|
"src/providers/gemini-models.ts"() {
|
|
3502
3582
|
"use strict";
|
|
3503
3583
|
GEMINI_MODELS = [
|
|
3584
|
+
// Gemini 3 Pro (Preview)
|
|
3504
3585
|
{
|
|
3505
3586
|
provider: "gemini",
|
|
3506
3587
|
modelId: "gemini-3-pro-preview",
|
|
@@ -3509,8 +3590,11 @@ var init_gemini_models = __esm({
|
|
|
3509
3590
|
maxOutputTokens: 65536,
|
|
3510
3591
|
pricing: {
|
|
3511
3592
|
input: 2,
|
|
3593
|
+
// $2.00 for prompts <= 200k, $4.00 for > 200k (using lower tier)
|
|
3512
3594
|
output: 12,
|
|
3595
|
+
// $12.00 for prompts <= 200k, $18.00 for > 200k
|
|
3513
3596
|
cachedInput: 0.2
|
|
3597
|
+
// $0.20 for prompts <= 200k
|
|
3514
3598
|
},
|
|
3515
3599
|
knowledgeCutoff: "2025-01",
|
|
3516
3600
|
features: {
|
|
@@ -3523,9 +3607,10 @@ var init_gemini_models = __esm({
|
|
|
3523
3607
|
metadata: {
|
|
3524
3608
|
family: "Gemini 3",
|
|
3525
3609
|
releaseDate: "2025-11-18",
|
|
3526
|
-
notes: "
|
|
3610
|
+
notes: "Best model for multimodal understanding, agentic and vibe-coding. Deep Think mode available."
|
|
3527
3611
|
}
|
|
3528
3612
|
},
|
|
3613
|
+
// Gemini 2.5 Pro
|
|
3529
3614
|
{
|
|
3530
3615
|
provider: "gemini",
|
|
3531
3616
|
modelId: "gemini-2.5-pro",
|
|
@@ -3534,8 +3619,11 @@ var init_gemini_models = __esm({
|
|
|
3534
3619
|
maxOutputTokens: 65536,
|
|
3535
3620
|
pricing: {
|
|
3536
3621
|
input: 1.25,
|
|
3622
|
+
// $1.25 for prompts <= 200k, $2.50 for > 200k
|
|
3537
3623
|
output: 10,
|
|
3624
|
+
// $10.00 for prompts <= 200k, $15.00 for > 200k
|
|
3538
3625
|
cachedInput: 0.125
|
|
3626
|
+
// $0.125 for prompts <= 200k
|
|
3539
3627
|
},
|
|
3540
3628
|
knowledgeCutoff: "2025-01",
|
|
3541
3629
|
features: {
|
|
@@ -3548,9 +3636,10 @@ var init_gemini_models = __esm({
|
|
|
3548
3636
|
metadata: {
|
|
3549
3637
|
family: "Gemini 2.5",
|
|
3550
3638
|
releaseDate: "2025-06",
|
|
3551
|
-
notes: "
|
|
3639
|
+
notes: "State-of-the-art multipurpose model. Excels at coding and complex reasoning."
|
|
3552
3640
|
}
|
|
3553
3641
|
},
|
|
3642
|
+
// Gemini 2.5 Flash
|
|
3554
3643
|
{
|
|
3555
3644
|
provider: "gemini",
|
|
3556
3645
|
modelId: "gemini-2.5-flash",
|
|
@@ -3559,8 +3648,10 @@ var init_gemini_models = __esm({
|
|
|
3559
3648
|
maxOutputTokens: 65536,
|
|
3560
3649
|
pricing: {
|
|
3561
3650
|
input: 0.3,
|
|
3651
|
+
// $0.30 for text/image/video, $1.00 for audio
|
|
3562
3652
|
output: 2.5,
|
|
3563
3653
|
cachedInput: 0.03
|
|
3654
|
+
// $0.03 for text/image/video
|
|
3564
3655
|
},
|
|
3565
3656
|
knowledgeCutoff: "2025-01",
|
|
3566
3657
|
features: {
|
|
@@ -3573,9 +3664,10 @@ var init_gemini_models = __esm({
|
|
|
3573
3664
|
metadata: {
|
|
3574
3665
|
family: "Gemini 2.5",
|
|
3575
3666
|
releaseDate: "2025-06",
|
|
3576
|
-
notes: "
|
|
3667
|
+
notes: "First hybrid reasoning model with 1M context and thinking budgets."
|
|
3577
3668
|
}
|
|
3578
3669
|
},
|
|
3670
|
+
// Gemini 2.5 Flash-Lite
|
|
3579
3671
|
{
|
|
3580
3672
|
provider: "gemini",
|
|
3581
3673
|
modelId: "gemini-2.5-flash-lite",
|
|
@@ -3584,8 +3676,10 @@ var init_gemini_models = __esm({
|
|
|
3584
3676
|
maxOutputTokens: 65536,
|
|
3585
3677
|
pricing: {
|
|
3586
3678
|
input: 0.1,
|
|
3679
|
+
// $0.10 for text/image/video, $0.30 for audio
|
|
3587
3680
|
output: 0.4,
|
|
3588
3681
|
cachedInput: 0.01
|
|
3682
|
+
// $0.01 for text/image/video
|
|
3589
3683
|
},
|
|
3590
3684
|
knowledgeCutoff: "2025-01",
|
|
3591
3685
|
features: {
|
|
@@ -3597,9 +3691,10 @@ var init_gemini_models = __esm({
|
|
|
3597
3691
|
metadata: {
|
|
3598
3692
|
family: "Gemini 2.5",
|
|
3599
3693
|
releaseDate: "2025-06",
|
|
3600
|
-
notes: "
|
|
3694
|
+
notes: "Smallest and most cost effective model, built for at scale usage."
|
|
3601
3695
|
}
|
|
3602
3696
|
},
|
|
3697
|
+
// Gemini 2.0 Flash
|
|
3603
3698
|
{
|
|
3604
3699
|
provider: "gemini",
|
|
3605
3700
|
modelId: "gemini-2.0-flash",
|
|
@@ -3608,8 +3703,10 @@ var init_gemini_models = __esm({
|
|
|
3608
3703
|
maxOutputTokens: 8192,
|
|
3609
3704
|
pricing: {
|
|
3610
3705
|
input: 0.1,
|
|
3706
|
+
// $0.10 for text/image/video, $0.70 for audio
|
|
3611
3707
|
output: 0.4,
|
|
3612
|
-
cachedInput: 0.
|
|
3708
|
+
cachedInput: 0.025
|
|
3709
|
+
// $0.025 for text/image/video
|
|
3613
3710
|
},
|
|
3614
3711
|
knowledgeCutoff: "2024-08",
|
|
3615
3712
|
features: {
|
|
@@ -3620,9 +3717,10 @@ var init_gemini_models = __esm({
|
|
|
3620
3717
|
},
|
|
3621
3718
|
metadata: {
|
|
3622
3719
|
family: "Gemini 2.0",
|
|
3623
|
-
notes: "
|
|
3720
|
+
notes: "Balanced multimodal model with 1M context, built for the era of Agents."
|
|
3624
3721
|
}
|
|
3625
3722
|
},
|
|
3723
|
+
// Gemini 2.0 Flash-Lite
|
|
3626
3724
|
{
|
|
3627
3725
|
provider: "gemini",
|
|
3628
3726
|
modelId: "gemini-2.0-flash-lite",
|
|
@@ -3631,8 +3729,8 @@ var init_gemini_models = __esm({
|
|
|
3631
3729
|
maxOutputTokens: 8192,
|
|
3632
3730
|
pricing: {
|
|
3633
3731
|
input: 0.075,
|
|
3634
|
-
output: 0.3
|
|
3635
|
-
|
|
3732
|
+
output: 0.3
|
|
3733
|
+
// No context caching available for 2.0-flash-lite
|
|
3636
3734
|
},
|
|
3637
3735
|
knowledgeCutoff: "2024-08",
|
|
3638
3736
|
features: {
|
|
@@ -3643,7 +3741,7 @@ var init_gemini_models = __esm({
|
|
|
3643
3741
|
},
|
|
3644
3742
|
metadata: {
|
|
3645
3743
|
family: "Gemini 2.0",
|
|
3646
|
-
notes: "
|
|
3744
|
+
notes: "Smallest and most cost effective 2.0 model for at scale usage."
|
|
3647
3745
|
}
|
|
3648
3746
|
}
|
|
3649
3747
|
];
|
|
@@ -3813,7 +3911,9 @@ var init_gemini = __esm({
|
|
|
3813
3911
|
return {
|
|
3814
3912
|
inputTokens: usageMetadata.promptTokenCount ?? 0,
|
|
3815
3913
|
outputTokens: usageMetadata.candidatesTokenCount ?? 0,
|
|
3816
|
-
totalTokens: usageMetadata.totalTokenCount ?? 0
|
|
3914
|
+
totalTokens: usageMetadata.totalTokenCount ?? 0,
|
|
3915
|
+
// Gemini returns cached token count in cachedContentTokenCount
|
|
3916
|
+
cachedInputTokens: usageMetadata.cachedContentTokenCount ?? 0
|
|
3817
3917
|
};
|
|
3818
3918
|
}
|
|
3819
3919
|
/**
|
|
@@ -3869,10 +3969,11 @@ var init_openai_models = __esm({
|
|
|
3869
3969
|
"src/providers/openai-models.ts"() {
|
|
3870
3970
|
"use strict";
|
|
3871
3971
|
OPENAI_MODELS = [
|
|
3972
|
+
// GPT-5 Family
|
|
3872
3973
|
{
|
|
3873
3974
|
provider: "openai",
|
|
3874
3975
|
modelId: "gpt-5.1",
|
|
3875
|
-
displayName: "GPT-5.1
|
|
3976
|
+
displayName: "GPT-5.1",
|
|
3876
3977
|
contextWindow: 128e3,
|
|
3877
3978
|
maxOutputTokens: 32768,
|
|
3878
3979
|
pricing: {
|
|
@@ -3892,34 +3993,7 @@ var init_openai_models = __esm({
|
|
|
3892
3993
|
metadata: {
|
|
3893
3994
|
family: "GPT-5",
|
|
3894
3995
|
releaseDate: "2025-11-12",
|
|
3895
|
-
notes: "
|
|
3896
|
-
supportsTemperature: false
|
|
3897
|
-
}
|
|
3898
|
-
},
|
|
3899
|
-
{
|
|
3900
|
-
provider: "openai",
|
|
3901
|
-
modelId: "gpt-5.1-thinking",
|
|
3902
|
-
displayName: "GPT-5.1 Thinking",
|
|
3903
|
-
contextWindow: 196e3,
|
|
3904
|
-
maxOutputTokens: 32768,
|
|
3905
|
-
pricing: {
|
|
3906
|
-
input: 1.25,
|
|
3907
|
-
output: 10,
|
|
3908
|
-
cachedInput: 0.125
|
|
3909
|
-
},
|
|
3910
|
-
knowledgeCutoff: "2024-09-30",
|
|
3911
|
-
features: {
|
|
3912
|
-
streaming: true,
|
|
3913
|
-
functionCalling: true,
|
|
3914
|
-
vision: true,
|
|
3915
|
-
reasoning: true,
|
|
3916
|
-
structuredOutputs: true,
|
|
3917
|
-
fineTuning: true
|
|
3918
|
-
},
|
|
3919
|
-
metadata: {
|
|
3920
|
-
family: "GPT-5",
|
|
3921
|
-
releaseDate: "2025-11-12",
|
|
3922
|
-
notes: "Advanced reasoning with thinking levels: Light, Standard, Extended, Heavy. Best for complex tasks.",
|
|
3996
|
+
notes: "Latest GPT-5 with improved instruction following. 2-3x faster than GPT-5.",
|
|
3923
3997
|
supportsTemperature: false
|
|
3924
3998
|
}
|
|
3925
3999
|
},
|
|
@@ -3999,6 +4073,255 @@ var init_openai_models = __esm({
|
|
|
3999
4073
|
notes: "Fastest, most cost-efficient version for well-defined tasks",
|
|
4000
4074
|
supportsTemperature: false
|
|
4001
4075
|
}
|
|
4076
|
+
},
|
|
4077
|
+
{
|
|
4078
|
+
provider: "openai",
|
|
4079
|
+
modelId: "gpt-5-pro",
|
|
4080
|
+
displayName: "GPT-5 Pro",
|
|
4081
|
+
contextWindow: 272e3,
|
|
4082
|
+
maxOutputTokens: 128e3,
|
|
4083
|
+
pricing: {
|
|
4084
|
+
input: 15,
|
|
4085
|
+
output: 120
|
|
4086
|
+
// No cached input pricing for gpt-5-pro
|
|
4087
|
+
},
|
|
4088
|
+
knowledgeCutoff: "2024-09-30",
|
|
4089
|
+
features: {
|
|
4090
|
+
streaming: true,
|
|
4091
|
+
functionCalling: true,
|
|
4092
|
+
vision: true,
|
|
4093
|
+
reasoning: true,
|
|
4094
|
+
structuredOutputs: true
|
|
4095
|
+
},
|
|
4096
|
+
metadata: {
|
|
4097
|
+
family: "GPT-5",
|
|
4098
|
+
notes: "Premium tier with enhanced capabilities. Does not support prompt caching.",
|
|
4099
|
+
supportsTemperature: false
|
|
4100
|
+
}
|
|
4101
|
+
},
|
|
4102
|
+
// GPT-4.1 Family
|
|
4103
|
+
{
|
|
4104
|
+
provider: "openai",
|
|
4105
|
+
modelId: "gpt-4.1",
|
|
4106
|
+
displayName: "GPT-4.1",
|
|
4107
|
+
contextWindow: 128e3,
|
|
4108
|
+
maxOutputTokens: 32768,
|
|
4109
|
+
pricing: {
|
|
4110
|
+
input: 2,
|
|
4111
|
+
output: 8,
|
|
4112
|
+
cachedInput: 0.5
|
|
4113
|
+
},
|
|
4114
|
+
knowledgeCutoff: "2024-04-01",
|
|
4115
|
+
features: {
|
|
4116
|
+
streaming: true,
|
|
4117
|
+
functionCalling: true,
|
|
4118
|
+
vision: true,
|
|
4119
|
+
structuredOutputs: true,
|
|
4120
|
+
fineTuning: true
|
|
4121
|
+
},
|
|
4122
|
+
metadata: {
|
|
4123
|
+
family: "GPT-4.1",
|
|
4124
|
+
notes: "Improved GPT-4 with better instruction following"
|
|
4125
|
+
}
|
|
4126
|
+
},
|
|
4127
|
+
{
|
|
4128
|
+
provider: "openai",
|
|
4129
|
+
modelId: "gpt-4.1-mini",
|
|
4130
|
+
displayName: "GPT-4.1 Mini",
|
|
4131
|
+
contextWindow: 128e3,
|
|
4132
|
+
maxOutputTokens: 32768,
|
|
4133
|
+
pricing: {
|
|
4134
|
+
input: 0.4,
|
|
4135
|
+
output: 1.6,
|
|
4136
|
+
cachedInput: 0.1
|
|
4137
|
+
},
|
|
4138
|
+
knowledgeCutoff: "2024-04-01",
|
|
4139
|
+
features: {
|
|
4140
|
+
streaming: true,
|
|
4141
|
+
functionCalling: true,
|
|
4142
|
+
vision: true,
|
|
4143
|
+
structuredOutputs: true,
|
|
4144
|
+
fineTuning: true
|
|
4145
|
+
},
|
|
4146
|
+
metadata: {
|
|
4147
|
+
family: "GPT-4.1",
|
|
4148
|
+
notes: "Cost-efficient GPT-4.1 variant"
|
|
4149
|
+
}
|
|
4150
|
+
},
|
|
4151
|
+
{
|
|
4152
|
+
provider: "openai",
|
|
4153
|
+
modelId: "gpt-4.1-nano",
|
|
4154
|
+
displayName: "GPT-4.1 Nano",
|
|
4155
|
+
contextWindow: 128e3,
|
|
4156
|
+
maxOutputTokens: 32768,
|
|
4157
|
+
pricing: {
|
|
4158
|
+
input: 0.1,
|
|
4159
|
+
output: 0.4,
|
|
4160
|
+
cachedInput: 0.025
|
|
4161
|
+
},
|
|
4162
|
+
knowledgeCutoff: "2024-04-01",
|
|
4163
|
+
features: {
|
|
4164
|
+
streaming: true,
|
|
4165
|
+
functionCalling: true,
|
|
4166
|
+
vision: true,
|
|
4167
|
+
structuredOutputs: true,
|
|
4168
|
+
fineTuning: true
|
|
4169
|
+
},
|
|
4170
|
+
metadata: {
|
|
4171
|
+
family: "GPT-4.1",
|
|
4172
|
+
notes: "Fastest GPT-4.1 variant for simple tasks"
|
|
4173
|
+
}
|
|
4174
|
+
},
|
|
4175
|
+
// GPT-4o Family
|
|
4176
|
+
{
|
|
4177
|
+
provider: "openai",
|
|
4178
|
+
modelId: "gpt-4o",
|
|
4179
|
+
displayName: "GPT-4o",
|
|
4180
|
+
contextWindow: 128e3,
|
|
4181
|
+
maxOutputTokens: 16384,
|
|
4182
|
+
pricing: {
|
|
4183
|
+
input: 2.5,
|
|
4184
|
+
output: 10,
|
|
4185
|
+
cachedInput: 1.25
|
|
4186
|
+
},
|
|
4187
|
+
knowledgeCutoff: "2024-04-01",
|
|
4188
|
+
features: {
|
|
4189
|
+
streaming: true,
|
|
4190
|
+
functionCalling: true,
|
|
4191
|
+
vision: true,
|
|
4192
|
+
structuredOutputs: true,
|
|
4193
|
+
fineTuning: true
|
|
4194
|
+
},
|
|
4195
|
+
metadata: {
|
|
4196
|
+
family: "GPT-4o",
|
|
4197
|
+
notes: "Multimodal model optimized for speed"
|
|
4198
|
+
}
|
|
4199
|
+
},
|
|
4200
|
+
{
|
|
4201
|
+
provider: "openai",
|
|
4202
|
+
modelId: "gpt-4o-mini",
|
|
4203
|
+
displayName: "GPT-4o Mini",
|
|
4204
|
+
contextWindow: 128e3,
|
|
4205
|
+
maxOutputTokens: 16384,
|
|
4206
|
+
pricing: {
|
|
4207
|
+
input: 0.15,
|
|
4208
|
+
output: 0.6,
|
|
4209
|
+
cachedInput: 0.075
|
|
4210
|
+
},
|
|
4211
|
+
knowledgeCutoff: "2024-04-01",
|
|
4212
|
+
features: {
|
|
4213
|
+
streaming: true,
|
|
4214
|
+
functionCalling: true,
|
|
4215
|
+
vision: true,
|
|
4216
|
+
structuredOutputs: true,
|
|
4217
|
+
fineTuning: true
|
|
4218
|
+
},
|
|
4219
|
+
metadata: {
|
|
4220
|
+
family: "GPT-4o",
|
|
4221
|
+
notes: "Fast and affordable multimodal model"
|
|
4222
|
+
}
|
|
4223
|
+
},
|
|
4224
|
+
// o-series (Reasoning models)
|
|
4225
|
+
{
|
|
4226
|
+
provider: "openai",
|
|
4227
|
+
modelId: "o1",
|
|
4228
|
+
displayName: "o1",
|
|
4229
|
+
contextWindow: 2e5,
|
|
4230
|
+
maxOutputTokens: 1e5,
|
|
4231
|
+
pricing: {
|
|
4232
|
+
input: 15,
|
|
4233
|
+
output: 60,
|
|
4234
|
+
cachedInput: 7.5
|
|
4235
|
+
},
|
|
4236
|
+
knowledgeCutoff: "2024-12-01",
|
|
4237
|
+
features: {
|
|
4238
|
+
streaming: true,
|
|
4239
|
+
functionCalling: true,
|
|
4240
|
+
vision: true,
|
|
4241
|
+
reasoning: true,
|
|
4242
|
+
structuredOutputs: true
|
|
4243
|
+
},
|
|
4244
|
+
metadata: {
|
|
4245
|
+
family: "o-series",
|
|
4246
|
+
notes: "Advanced reasoning model with chain-of-thought",
|
|
4247
|
+
supportsTemperature: false
|
|
4248
|
+
}
|
|
4249
|
+
},
|
|
4250
|
+
{
|
|
4251
|
+
provider: "openai",
|
|
4252
|
+
modelId: "o3",
|
|
4253
|
+
displayName: "o3",
|
|
4254
|
+
contextWindow: 2e5,
|
|
4255
|
+
maxOutputTokens: 1e5,
|
|
4256
|
+
pricing: {
|
|
4257
|
+
input: 2,
|
|
4258
|
+
output: 8,
|
|
4259
|
+
cachedInput: 0.5
|
|
4260
|
+
},
|
|
4261
|
+
knowledgeCutoff: "2025-01-01",
|
|
4262
|
+
features: {
|
|
4263
|
+
streaming: true,
|
|
4264
|
+
functionCalling: true,
|
|
4265
|
+
vision: true,
|
|
4266
|
+
reasoning: true,
|
|
4267
|
+
structuredOutputs: true
|
|
4268
|
+
},
|
|
4269
|
+
metadata: {
|
|
4270
|
+
family: "o-series",
|
|
4271
|
+
notes: "Next-gen reasoning model, more efficient than o1",
|
|
4272
|
+
supportsTemperature: false
|
|
4273
|
+
}
|
|
4274
|
+
},
|
|
4275
|
+
{
|
|
4276
|
+
provider: "openai",
|
|
4277
|
+
modelId: "o4-mini",
|
|
4278
|
+
displayName: "o4 Mini",
|
|
4279
|
+
contextWindow: 2e5,
|
|
4280
|
+
maxOutputTokens: 1e5,
|
|
4281
|
+
pricing: {
|
|
4282
|
+
input: 1.1,
|
|
4283
|
+
output: 4.4,
|
|
4284
|
+
cachedInput: 0.275
|
|
4285
|
+
},
|
|
4286
|
+
knowledgeCutoff: "2025-04-01",
|
|
4287
|
+
features: {
|
|
4288
|
+
streaming: true,
|
|
4289
|
+
functionCalling: true,
|
|
4290
|
+
vision: true,
|
|
4291
|
+
reasoning: true,
|
|
4292
|
+
structuredOutputs: true,
|
|
4293
|
+
fineTuning: true
|
|
4294
|
+
},
|
|
4295
|
+
metadata: {
|
|
4296
|
+
family: "o-series",
|
|
4297
|
+
notes: "Cost-efficient reasoning model",
|
|
4298
|
+
supportsTemperature: false
|
|
4299
|
+
}
|
|
4300
|
+
},
|
|
4301
|
+
{
|
|
4302
|
+
provider: "openai",
|
|
4303
|
+
modelId: "o3-mini",
|
|
4304
|
+
displayName: "o3 Mini",
|
|
4305
|
+
contextWindow: 2e5,
|
|
4306
|
+
maxOutputTokens: 1e5,
|
|
4307
|
+
pricing: {
|
|
4308
|
+
input: 1.1,
|
|
4309
|
+
output: 4.4,
|
|
4310
|
+
cachedInput: 0.55
|
|
4311
|
+
},
|
|
4312
|
+
knowledgeCutoff: "2025-01-01",
|
|
4313
|
+
features: {
|
|
4314
|
+
streaming: true,
|
|
4315
|
+
functionCalling: true,
|
|
4316
|
+
vision: true,
|
|
4317
|
+
reasoning: true,
|
|
4318
|
+
structuredOutputs: true
|
|
4319
|
+
},
|
|
4320
|
+
metadata: {
|
|
4321
|
+
family: "o-series",
|
|
4322
|
+
notes: "Compact reasoning model for cost-sensitive applications",
|
|
4323
|
+
supportsTemperature: false
|
|
4324
|
+
}
|
|
4002
4325
|
}
|
|
4003
4326
|
];
|
|
4004
4327
|
}
|
|
@@ -4079,7 +4402,8 @@ var init_openai = __esm({
|
|
|
4079
4402
|
const usage = chunk.usage ? {
|
|
4080
4403
|
inputTokens: chunk.usage.prompt_tokens,
|
|
4081
4404
|
outputTokens: chunk.usage.completion_tokens,
|
|
4082
|
-
totalTokens: chunk.usage.total_tokens
|
|
4405
|
+
totalTokens: chunk.usage.total_tokens,
|
|
4406
|
+
cachedInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0
|
|
4083
4407
|
} : void 0;
|
|
4084
4408
|
if (finishReason || usage) {
|
|
4085
4409
|
yield { text: "", finishReason, usage, rawEvent: chunk };
|
|
@@ -4296,20 +4620,28 @@ var init_model_registry = __esm({
|
|
|
4296
4620
|
/**
|
|
4297
4621
|
* Estimate API cost for a given model and token usage
|
|
4298
4622
|
* @param modelId - Full model identifier
|
|
4299
|
-
* @param inputTokens - Number of input tokens
|
|
4623
|
+
* @param inputTokens - Number of input tokens (total, including cached and cache creation)
|
|
4300
4624
|
* @param outputTokens - Number of output tokens
|
|
4301
|
-
* @param
|
|
4625
|
+
* @param cachedInputTokens - Number of cached input tokens (subset of inputTokens)
|
|
4626
|
+
* @param cacheCreationInputTokens - Number of cache creation tokens (subset of inputTokens, Anthropic only)
|
|
4302
4627
|
* @returns CostEstimate if model found, undefined otherwise
|
|
4303
4628
|
*/
|
|
4304
|
-
estimateCost(modelId, inputTokens, outputTokens,
|
|
4629
|
+
estimateCost(modelId, inputTokens, outputTokens, cachedInputTokens = 0, cacheCreationInputTokens = 0) {
|
|
4305
4630
|
const spec = this.getModelSpec(modelId);
|
|
4306
4631
|
if (!spec) return void 0;
|
|
4307
|
-
const
|
|
4308
|
-
const
|
|
4632
|
+
const cachedRate = spec.pricing.cachedInput ?? spec.pricing.input;
|
|
4633
|
+
const cacheWriteRate = spec.pricing.cacheWriteInput ?? spec.pricing.input;
|
|
4634
|
+
const uncachedInputTokens = inputTokens - cachedInputTokens - cacheCreationInputTokens;
|
|
4635
|
+
const uncachedInputCost = uncachedInputTokens / 1e6 * spec.pricing.input;
|
|
4636
|
+
const cachedInputCost = cachedInputTokens / 1e6 * cachedRate;
|
|
4637
|
+
const cacheCreationCost = cacheCreationInputTokens / 1e6 * cacheWriteRate;
|
|
4638
|
+
const inputCost = uncachedInputCost + cachedInputCost + cacheCreationCost;
|
|
4309
4639
|
const outputCost = outputTokens / 1e6 * spec.pricing.output;
|
|
4310
4640
|
const totalCost = inputCost + outputCost;
|
|
4311
4641
|
return {
|
|
4312
4642
|
inputCost,
|
|
4643
|
+
cachedInputCost,
|
|
4644
|
+
cacheCreationCost,
|
|
4313
4645
|
outputCost,
|
|
4314
4646
|
totalCost,
|
|
4315
4647
|
currency: "USD"
|
|
@@ -4690,6 +5022,7 @@ var AgentBuilder;
|
|
|
4690
5022
|
var init_builder = __esm({
|
|
4691
5023
|
"src/agent/builder.ts"() {
|
|
4692
5024
|
"use strict";
|
|
5025
|
+
init_constants();
|
|
4693
5026
|
init_model_shortcuts();
|
|
4694
5027
|
init_registry();
|
|
4695
5028
|
init_agent();
|
|
@@ -4711,6 +5044,7 @@ var init_builder = __esm({
|
|
|
4711
5044
|
gadgetStartPrefix;
|
|
4712
5045
|
gadgetEndPrefix;
|
|
4713
5046
|
textOnlyHandler;
|
|
5047
|
+
textWithGadgetsHandler;
|
|
4714
5048
|
stopOnGadgetError;
|
|
4715
5049
|
shouldContinueAfterError;
|
|
4716
5050
|
defaultGadgetTimeoutMs;
|
|
@@ -4973,6 +5307,30 @@ var init_builder = __esm({
|
|
|
4973
5307
|
this.textOnlyHandler = handler;
|
|
4974
5308
|
return this;
|
|
4975
5309
|
}
|
|
5310
|
+
/**
|
|
5311
|
+
* Set the handler for text content that appears alongside gadget calls.
|
|
5312
|
+
*
|
|
5313
|
+
* When set, text accompanying gadget responses will be wrapped as a
|
|
5314
|
+
* synthetic gadget call before the actual gadget results in the
|
|
5315
|
+
* conversation history.
|
|
5316
|
+
*
|
|
5317
|
+
* @param handler - Configuration for wrapping text
|
|
5318
|
+
* @returns This builder for chaining
|
|
5319
|
+
*
|
|
5320
|
+
* @example
|
|
5321
|
+
* ```typescript
|
|
5322
|
+
* // Wrap text as TellUser gadget
|
|
5323
|
+
* .withTextWithGadgetsHandler({
|
|
5324
|
+
* gadgetName: "TellUser",
|
|
5325
|
+
* parameterMapping: (text) => ({ message: text, done: false, type: "info" }),
|
|
5326
|
+
* resultMapping: (text) => `ℹ️ ${text}`,
|
|
5327
|
+
* })
|
|
5328
|
+
* ```
|
|
5329
|
+
*/
|
|
5330
|
+
withTextWithGadgetsHandler(handler) {
|
|
5331
|
+
this.textWithGadgetsHandler = handler;
|
|
5332
|
+
return this;
|
|
5333
|
+
}
|
|
4976
5334
|
/**
|
|
4977
5335
|
* Set whether to stop gadget execution on first error.
|
|
4978
5336
|
*
|
|
@@ -5087,6 +5445,69 @@ var init_builder = __esm({
|
|
|
5087
5445
|
this.gadgetOutputLimitPercent = percent;
|
|
5088
5446
|
return this;
|
|
5089
5447
|
}
|
|
5448
|
+
/**
|
|
5449
|
+
* Add a synthetic gadget call to the conversation history.
|
|
5450
|
+
*
|
|
5451
|
+
* This is useful for in-context learning - showing the LLM what "past self"
|
|
5452
|
+
* did correctly so it mimics the pattern. The call is formatted with proper
|
|
5453
|
+
* markers and parameter format.
|
|
5454
|
+
*
|
|
5455
|
+
* @param gadgetName - Name of the gadget
|
|
5456
|
+
* @param parameters - Parameters passed to the gadget
|
|
5457
|
+
* @param result - Result returned by the gadget
|
|
5458
|
+
* @returns This builder for chaining
|
|
5459
|
+
*
|
|
5460
|
+
* @example
|
|
5461
|
+
* ```typescript
|
|
5462
|
+
* .withSyntheticGadgetCall(
|
|
5463
|
+
* 'TellUser',
|
|
5464
|
+
* {
|
|
5465
|
+
* message: '👋 Hello!\n\nHere\'s what I can do:\n- Analyze code\n- Run commands',
|
|
5466
|
+
* done: false,
|
|
5467
|
+
* type: 'info'
|
|
5468
|
+
* },
|
|
5469
|
+
* 'ℹ️ 👋 Hello!\n\nHere\'s what I can do:\n- Analyze code\n- Run commands'
|
|
5470
|
+
* )
|
|
5471
|
+
* ```
|
|
5472
|
+
*/
|
|
5473
|
+
withSyntheticGadgetCall(gadgetName, parameters, result) {
|
|
5474
|
+
const startPrefix = this.gadgetStartPrefix ?? GADGET_START_PREFIX;
|
|
5475
|
+
const endPrefix = this.gadgetEndPrefix ?? GADGET_END_PREFIX;
|
|
5476
|
+
const format = this.parameterFormat ?? "yaml";
|
|
5477
|
+
const paramStr = this.formatSyntheticParameters(parameters, format);
|
|
5478
|
+
this.initialMessages.push({
|
|
5479
|
+
role: "assistant",
|
|
5480
|
+
content: `${startPrefix}${gadgetName}
|
|
5481
|
+
${paramStr}
|
|
5482
|
+
${endPrefix}`
|
|
5483
|
+
});
|
|
5484
|
+
this.initialMessages.push({
|
|
5485
|
+
role: "user",
|
|
5486
|
+
content: `Result: ${result}`
|
|
5487
|
+
});
|
|
5488
|
+
return this;
|
|
5489
|
+
}
|
|
5490
|
+
/**
|
|
5491
|
+
* Format parameters for synthetic gadget calls.
|
|
5492
|
+
* Uses heredoc for multiline string values.
|
|
5493
|
+
*/
|
|
5494
|
+
formatSyntheticParameters(parameters, format) {
|
|
5495
|
+
if (format === "json" || format === "auto") {
|
|
5496
|
+
return JSON.stringify(parameters);
|
|
5497
|
+
}
|
|
5498
|
+
return Object.entries(parameters).map(([key, value]) => {
|
|
5499
|
+
if (typeof value === "string" && value.includes("\n")) {
|
|
5500
|
+
const separator = format === "yaml" ? ":" : " =";
|
|
5501
|
+
return `${key}${separator} <<<EOF
|
|
5502
|
+
${value}
|
|
5503
|
+
EOF`;
|
|
5504
|
+
}
|
|
5505
|
+
if (format === "yaml") {
|
|
5506
|
+
return typeof value === "string" ? `${key}: ${value}` : `${key}: ${JSON.stringify(value)}`;
|
|
5507
|
+
}
|
|
5508
|
+
return `${key} = ${JSON.stringify(value)}`;
|
|
5509
|
+
}).join("\n");
|
|
5510
|
+
}
|
|
5090
5511
|
/**
|
|
5091
5512
|
* Build and create the agent with the given user prompt.
|
|
5092
5513
|
* Returns the Agent instance ready to run.
|
|
@@ -5129,6 +5550,7 @@ var init_builder = __esm({
|
|
|
5129
5550
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
5130
5551
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
5131
5552
|
textOnlyHandler: this.textOnlyHandler,
|
|
5553
|
+
textWithGadgetsHandler: this.textWithGadgetsHandler,
|
|
5132
5554
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
5133
5555
|
shouldContinueAfterError: this.shouldContinueAfterError,
|
|
5134
5556
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
@@ -5230,6 +5652,7 @@ var init_builder = __esm({
|
|
|
5230
5652
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
5231
5653
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
5232
5654
|
textOnlyHandler: this.textOnlyHandler,
|
|
5655
|
+
textWithGadgetsHandler: this.textWithGadgetsHandler,
|
|
5233
5656
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
5234
5657
|
shouldContinueAfterError: this.shouldContinueAfterError,
|
|
5235
5658
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
@@ -5265,7 +5688,8 @@ var OPTION_FLAGS = {
|
|
|
5265
5688
|
logFile: "--log-file <path>",
|
|
5266
5689
|
logReset: "--log-reset",
|
|
5267
5690
|
noBuiltins: "--no-builtins",
|
|
5268
|
-
noBuiltinInteraction: "--no-builtin-interaction"
|
|
5691
|
+
noBuiltinInteraction: "--no-builtin-interaction",
|
|
5692
|
+
quiet: "-q, --quiet"
|
|
5269
5693
|
};
|
|
5270
5694
|
var OPTION_DESCRIPTIONS = {
|
|
5271
5695
|
model: "Model identifier, e.g. openai:gpt-5-nano or anthropic:claude-sonnet-4-5.",
|
|
@@ -5279,7 +5703,8 @@ var OPTION_DESCRIPTIONS = {
|
|
|
5279
5703
|
logFile: "Path to log file. When set, logs are written to file instead of stderr.",
|
|
5280
5704
|
logReset: "Reset (truncate) the log file at session start instead of appending.",
|
|
5281
5705
|
noBuiltins: "Disable built-in gadgets (AskUser, TellUser).",
|
|
5282
|
-
noBuiltinInteraction: "Disable interactive gadgets (AskUser) while keeping TellUser."
|
|
5706
|
+
noBuiltinInteraction: "Disable interactive gadgets (AskUser) while keeping TellUser.",
|
|
5707
|
+
quiet: "Suppress all output except content (text and TellUser messages)."
|
|
5283
5708
|
};
|
|
5284
5709
|
var SUMMARY_PREFIX = "[llmist]";
|
|
5285
5710
|
|
|
@@ -5289,7 +5714,7 @@ var import_commander3 = require("commander");
|
|
|
5289
5714
|
// package.json
|
|
5290
5715
|
var package_default = {
|
|
5291
5716
|
name: "llmist",
|
|
5292
|
-
version: "0.
|
|
5717
|
+
version: "0.7.0",
|
|
5293
5718
|
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.",
|
|
5294
5719
|
type: "module",
|
|
5295
5720
|
main: "dist/index.cjs",
|
|
@@ -5373,6 +5798,7 @@ var package_default = {
|
|
|
5373
5798
|
"@google/genai": "^1.27.0",
|
|
5374
5799
|
chalk: "^5.6.2",
|
|
5375
5800
|
commander: "^12.1.0",
|
|
5801
|
+
eta: "^4.4.1",
|
|
5376
5802
|
"js-toml": "^1.0.2",
|
|
5377
5803
|
"js-yaml": "^4.1.0",
|
|
5378
5804
|
marked: "^15.0.12",
|
|
@@ -5437,7 +5863,7 @@ var tellUser = createGadget({
|
|
|
5437
5863
|
name: "TellUser",
|
|
5438
5864
|
description: "Tell the user something important. Set done=true when your work is complete and you want to end the conversation.",
|
|
5439
5865
|
schema: import_zod2.z.object({
|
|
5440
|
-
message: import_zod2.z.string().describe("The message to display to the user in Markdown"),
|
|
5866
|
+
message: import_zod2.z.string().optional().describe("The message to display to the user in Markdown"),
|
|
5441
5867
|
done: import_zod2.z.boolean().default(false).describe("Set to true to end the conversation, false to continue"),
|
|
5442
5868
|
type: import_zod2.z.enum(["info", "success", "warning", "error"]).default("info").describe("Message type: info, success, warning, or error")
|
|
5443
5869
|
}),
|
|
@@ -5457,9 +5883,20 @@ var tellUser = createGadget({
|
|
|
5457
5883
|
done: false,
|
|
5458
5884
|
type: "warning"
|
|
5459
5885
|
}
|
|
5886
|
+
},
|
|
5887
|
+
{
|
|
5888
|
+
comment: "Share detailed analysis with bullet points (use heredoc for multiline)",
|
|
5889
|
+
params: {
|
|
5890
|
+
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.",
|
|
5891
|
+
done: false,
|
|
5892
|
+
type: "info"
|
|
5893
|
+
}
|
|
5460
5894
|
}
|
|
5461
5895
|
],
|
|
5462
5896
|
execute: ({ message, done, type }) => {
|
|
5897
|
+
if (!message || message.trim() === "") {
|
|
5898
|
+
return "\u26A0\uFE0F TellUser was called without a message. Please provide content in the 'message' field.";
|
|
5899
|
+
}
|
|
5463
5900
|
const prefixes = {
|
|
5464
5901
|
info: "\u2139\uFE0F ",
|
|
5465
5902
|
success: "\u2705 ",
|
|
@@ -5481,12 +5918,19 @@ var import_node_path2 = __toESM(require("path"), 1);
|
|
|
5481
5918
|
var import_node_url = require("url");
|
|
5482
5919
|
init_gadget();
|
|
5483
5920
|
var PATH_PREFIXES = [".", "/", "~"];
|
|
5921
|
+
function isGadgetLike(value) {
|
|
5922
|
+
if (typeof value !== "object" || value === null) {
|
|
5923
|
+
return false;
|
|
5924
|
+
}
|
|
5925
|
+
const obj = value;
|
|
5926
|
+
return typeof obj.execute === "function" && typeof obj.description === "string" && ("parameterSchema" in obj || "schema" in obj);
|
|
5927
|
+
}
|
|
5484
5928
|
function isGadgetConstructor(value) {
|
|
5485
5929
|
if (typeof value !== "function") {
|
|
5486
5930
|
return false;
|
|
5487
5931
|
}
|
|
5488
5932
|
const prototype = value.prototype;
|
|
5489
|
-
return Boolean(prototype) && prototype instanceof BaseGadget;
|
|
5933
|
+
return Boolean(prototype) && (prototype instanceof BaseGadget || isGadgetLike(prototype));
|
|
5490
5934
|
}
|
|
5491
5935
|
function expandHomePath(input) {
|
|
5492
5936
|
if (!input.startsWith("~")) {
|
|
@@ -5523,7 +5967,7 @@ function extractGadgetsFromModule(moduleExports) {
|
|
|
5523
5967
|
return;
|
|
5524
5968
|
}
|
|
5525
5969
|
visited.add(value);
|
|
5526
|
-
if (value instanceof BaseGadget) {
|
|
5970
|
+
if (value instanceof BaseGadget || isGadgetLike(value)) {
|
|
5527
5971
|
results.push(value);
|
|
5528
5972
|
return;
|
|
5529
5973
|
}
|
|
@@ -5648,8 +6092,14 @@ function renderSummary(metadata) {
|
|
|
5648
6092
|
parts.push(import_chalk.default.magenta(metadata.model));
|
|
5649
6093
|
}
|
|
5650
6094
|
if (metadata.usage) {
|
|
5651
|
-
const { inputTokens, outputTokens } = metadata.usage;
|
|
6095
|
+
const { inputTokens, outputTokens, cachedInputTokens, cacheCreationInputTokens } = metadata.usage;
|
|
5652
6096
|
parts.push(import_chalk.default.dim("\u2191") + import_chalk.default.yellow(` ${formatTokens(inputTokens)}`));
|
|
6097
|
+
if (cachedInputTokens && cachedInputTokens > 0) {
|
|
6098
|
+
parts.push(import_chalk.default.dim("\u27F3") + import_chalk.default.blue(` ${formatTokens(cachedInputTokens)}`));
|
|
6099
|
+
}
|
|
6100
|
+
if (cacheCreationInputTokens && cacheCreationInputTokens > 0) {
|
|
6101
|
+
parts.push(import_chalk.default.dim("\u270E") + import_chalk.default.magenta(` ${formatTokens(cacheCreationInputTokens)}`));
|
|
6102
|
+
}
|
|
5653
6103
|
parts.push(import_chalk.default.dim("\u2193") + import_chalk.default.green(` ${formatTokens(outputTokens)}`));
|
|
5654
6104
|
}
|
|
5655
6105
|
if (metadata.elapsedSeconds !== void 0 && metadata.elapsedSeconds > 0) {
|
|
@@ -5741,53 +6191,6 @@ ${rendered}`;
|
|
|
5741
6191
|
}
|
|
5742
6192
|
|
|
5743
6193
|
// src/cli/utils.ts
|
|
5744
|
-
var RARE_EMOJI = [
|
|
5745
|
-
"\u{1F531}",
|
|
5746
|
-
"\u2697\uFE0F",
|
|
5747
|
-
"\u{1F9FF}",
|
|
5748
|
-
"\u{1F530}",
|
|
5749
|
-
"\u269B\uFE0F",
|
|
5750
|
-
"\u{1F3FA}",
|
|
5751
|
-
"\u{1F9EB}",
|
|
5752
|
-
"\u{1F52C}",
|
|
5753
|
-
"\u2695\uFE0F",
|
|
5754
|
-
"\u{1F5DD}\uFE0F",
|
|
5755
|
-
"\u2696\uFE0F",
|
|
5756
|
-
"\u{1F52E}",
|
|
5757
|
-
"\u{1FAAC}",
|
|
5758
|
-
"\u{1F9EC}",
|
|
5759
|
-
"\u2699\uFE0F",
|
|
5760
|
-
"\u{1F529}",
|
|
5761
|
-
"\u{1FA9B}",
|
|
5762
|
-
"\u26CF\uFE0F",
|
|
5763
|
-
"\u{1FA83}",
|
|
5764
|
-
"\u{1F3F9}",
|
|
5765
|
-
"\u{1F6E1}\uFE0F",
|
|
5766
|
-
"\u2694\uFE0F",
|
|
5767
|
-
"\u{1F5E1}\uFE0F",
|
|
5768
|
-
"\u{1FA93}",
|
|
5769
|
-
"\u{1F5C3}\uFE0F",
|
|
5770
|
-
"\u{1F4DC}",
|
|
5771
|
-
"\u{1F4EF}",
|
|
5772
|
-
"\u{1F3B4}",
|
|
5773
|
-
"\u{1F004}",
|
|
5774
|
-
"\u{1F3B2}"
|
|
5775
|
-
];
|
|
5776
|
-
function generateMarkers() {
|
|
5777
|
-
const pick = (count) => {
|
|
5778
|
-
const result = [];
|
|
5779
|
-
const pool = [...RARE_EMOJI];
|
|
5780
|
-
for (let i = 0; i < count && pool.length > 0; i++) {
|
|
5781
|
-
const idx = Math.floor(Math.random() * pool.length);
|
|
5782
|
-
result.push(pool.splice(idx, 1)[0]);
|
|
5783
|
-
}
|
|
5784
|
-
return result.join("");
|
|
5785
|
-
};
|
|
5786
|
-
return {
|
|
5787
|
-
startPrefix: pick(5),
|
|
5788
|
-
endPrefix: pick(5)
|
|
5789
|
-
};
|
|
5790
|
-
}
|
|
5791
6194
|
function createNumericParser({
|
|
5792
6195
|
label,
|
|
5793
6196
|
integer = false,
|
|
@@ -5865,6 +6268,9 @@ var StreamProgress = class {
|
|
|
5865
6268
|
callOutputTokensEstimated = true;
|
|
5866
6269
|
callOutputChars = 0;
|
|
5867
6270
|
isStreaming = false;
|
|
6271
|
+
// Cache token tracking for live cost estimation during streaming
|
|
6272
|
+
callCachedInputTokens = 0;
|
|
6273
|
+
callCacheCreationInputTokens = 0;
|
|
5868
6274
|
// Cumulative stats (cumulative mode)
|
|
5869
6275
|
totalStartTime = Date.now();
|
|
5870
6276
|
totalTokens = 0;
|
|
@@ -5890,11 +6296,13 @@ var StreamProgress = class {
|
|
|
5890
6296
|
this.callOutputTokensEstimated = true;
|
|
5891
6297
|
this.callOutputChars = 0;
|
|
5892
6298
|
this.isStreaming = false;
|
|
6299
|
+
this.callCachedInputTokens = 0;
|
|
6300
|
+
this.callCacheCreationInputTokens = 0;
|
|
5893
6301
|
this.start();
|
|
5894
6302
|
}
|
|
5895
6303
|
/**
|
|
5896
6304
|
* Ends the current LLM call. Updates cumulative stats and switches to cumulative mode.
|
|
5897
|
-
* @param usage - Final token usage from the call
|
|
6305
|
+
* @param usage - Final token usage from the call (including cached tokens if available)
|
|
5898
6306
|
*/
|
|
5899
6307
|
endCall(usage) {
|
|
5900
6308
|
this.iterations++;
|
|
@@ -5906,7 +6314,9 @@ var StreamProgress = class {
|
|
|
5906
6314
|
const cost = this.modelRegistry.estimateCost(
|
|
5907
6315
|
modelName,
|
|
5908
6316
|
usage.inputTokens,
|
|
5909
|
-
usage.outputTokens
|
|
6317
|
+
usage.outputTokens,
|
|
6318
|
+
usage.cachedInputTokens ?? 0,
|
|
6319
|
+
usage.cacheCreationInputTokens ?? 0
|
|
5910
6320
|
);
|
|
5911
6321
|
if (cost) {
|
|
5912
6322
|
this.totalCost += cost.totalCost;
|
|
@@ -5946,6 +6356,16 @@ var StreamProgress = class {
|
|
|
5946
6356
|
this.callOutputTokens = tokens;
|
|
5947
6357
|
this.callOutputTokensEstimated = estimated;
|
|
5948
6358
|
}
|
|
6359
|
+
/**
|
|
6360
|
+
* Sets cached token counts for the current call (from stream metadata).
|
|
6361
|
+
* Used for live cost estimation during streaming.
|
|
6362
|
+
* @param cachedInputTokens - Number of tokens read from cache (cheaper)
|
|
6363
|
+
* @param cacheCreationInputTokens - Number of tokens written to cache (more expensive)
|
|
6364
|
+
*/
|
|
6365
|
+
setCachedTokens(cachedInputTokens, cacheCreationInputTokens) {
|
|
6366
|
+
this.callCachedInputTokens = cachedInputTokens;
|
|
6367
|
+
this.callCacheCreationInputTokens = cacheCreationInputTokens;
|
|
6368
|
+
}
|
|
5949
6369
|
/**
|
|
5950
6370
|
* Get total elapsed time in seconds since the first call started.
|
|
5951
6371
|
* @returns Elapsed time in seconds with 1 decimal place
|
|
@@ -6010,11 +6430,32 @@ var StreamProgress = class {
|
|
|
6010
6430
|
parts.push(import_chalk2.default.dim("\u2193") + import_chalk2.default.green(` ${prefix}${formatTokens(outTokens)}`));
|
|
6011
6431
|
}
|
|
6012
6432
|
parts.push(import_chalk2.default.dim(`${elapsed}s`));
|
|
6013
|
-
|
|
6014
|
-
|
|
6433
|
+
const callCost = this.calculateCurrentCallCost(outTokens);
|
|
6434
|
+
if (callCost > 0) {
|
|
6435
|
+
parts.push(import_chalk2.default.cyan(`$${formatCost(callCost)}`));
|
|
6015
6436
|
}
|
|
6016
6437
|
this.target.write(`\r${parts.join(import_chalk2.default.dim(" | "))} ${import_chalk2.default.cyan(spinner)}`);
|
|
6017
6438
|
}
|
|
6439
|
+
/**
|
|
6440
|
+
* Calculates live cost estimate for the current streaming call.
|
|
6441
|
+
* Uses current input/output tokens and cached token counts.
|
|
6442
|
+
*/
|
|
6443
|
+
calculateCurrentCallCost(outputTokens) {
|
|
6444
|
+
if (!this.modelRegistry || !this.model) return 0;
|
|
6445
|
+
try {
|
|
6446
|
+
const modelName = this.model.includes(":") ? this.model.split(":")[1] : this.model;
|
|
6447
|
+
const cost = this.modelRegistry.estimateCost(
|
|
6448
|
+
modelName,
|
|
6449
|
+
this.callInputTokens,
|
|
6450
|
+
outputTokens,
|
|
6451
|
+
this.callCachedInputTokens,
|
|
6452
|
+
this.callCacheCreationInputTokens
|
|
6453
|
+
);
|
|
6454
|
+
return cost?.totalCost ?? 0;
|
|
6455
|
+
} catch {
|
|
6456
|
+
return 0;
|
|
6457
|
+
}
|
|
6458
|
+
}
|
|
6018
6459
|
renderCumulativeMode(spinner) {
|
|
6019
6460
|
const elapsed = ((Date.now() - this.totalStartTime) / 1e3).toFixed(1);
|
|
6020
6461
|
const parts = [];
|
|
@@ -6163,7 +6604,7 @@ function addCompleteOptions(cmd, defaults) {
|
|
|
6163
6604
|
OPTION_DESCRIPTIONS.maxTokens,
|
|
6164
6605
|
createNumericParser({ label: "Max tokens", integer: true, min: 1 }),
|
|
6165
6606
|
defaults?.["max-tokens"]
|
|
6166
|
-
);
|
|
6607
|
+
).option(OPTION_FLAGS.quiet, OPTION_DESCRIPTIONS.quiet, defaults?.quiet);
|
|
6167
6608
|
}
|
|
6168
6609
|
function addAgentOptions(cmd, defaults) {
|
|
6169
6610
|
const gadgetAccumulator = (value, previous = []) => [
|
|
@@ -6192,7 +6633,7 @@ function addAgentOptions(cmd, defaults) {
|
|
|
6192
6633
|
OPTION_FLAGS.noBuiltinInteraction,
|
|
6193
6634
|
OPTION_DESCRIPTIONS.noBuiltinInteraction,
|
|
6194
6635
|
defaults?.["builtin-interaction"] !== false
|
|
6195
|
-
);
|
|
6636
|
+
).option(OPTION_FLAGS.quiet, OPTION_DESCRIPTIONS.quiet, defaults?.quiet);
|
|
6196
6637
|
}
|
|
6197
6638
|
function configToCompleteOptions(config) {
|
|
6198
6639
|
const result = {};
|
|
@@ -6200,6 +6641,7 @@ function configToCompleteOptions(config) {
|
|
|
6200
6641
|
if (config.system !== void 0) result.system = config.system;
|
|
6201
6642
|
if (config.temperature !== void 0) result.temperature = config.temperature;
|
|
6202
6643
|
if (config["max-tokens"] !== void 0) result.maxTokens = config["max-tokens"];
|
|
6644
|
+
if (config.quiet !== void 0) result.quiet = config.quiet;
|
|
6203
6645
|
return result;
|
|
6204
6646
|
}
|
|
6205
6647
|
function configToAgentOptions(config) {
|
|
@@ -6213,6 +6655,11 @@ function configToAgentOptions(config) {
|
|
|
6213
6655
|
if (config.builtins !== void 0) result.builtins = config.builtins;
|
|
6214
6656
|
if (config["builtin-interaction"] !== void 0)
|
|
6215
6657
|
result.builtinInteraction = config["builtin-interaction"];
|
|
6658
|
+
if (config["gadget-start-prefix"] !== void 0)
|
|
6659
|
+
result.gadgetStartPrefix = config["gadget-start-prefix"];
|
|
6660
|
+
if (config["gadget-end-prefix"] !== void 0)
|
|
6661
|
+
result.gadgetEndPrefix = config["gadget-end-prefix"];
|
|
6662
|
+
if (config.quiet !== void 0) result.quiet = config.quiet;
|
|
6216
6663
|
return result;
|
|
6217
6664
|
}
|
|
6218
6665
|
|
|
@@ -6258,9 +6705,10 @@ async function executeAgent(promptArg, options, env) {
|
|
|
6258
6705
|
const prompt = await resolvePrompt(promptArg, env);
|
|
6259
6706
|
const client = env.createClient();
|
|
6260
6707
|
const registry = new GadgetRegistry();
|
|
6708
|
+
const stdinIsInteractive = isInteractive(env.stdin);
|
|
6261
6709
|
if (options.builtins !== false) {
|
|
6262
6710
|
for (const gadget of builtinGadgets) {
|
|
6263
|
-
if (
|
|
6711
|
+
if (gadget.name === "AskUser" && (options.builtinInteraction === false || !stdinIsInteractive)) {
|
|
6264
6712
|
continue;
|
|
6265
6713
|
}
|
|
6266
6714
|
registry.registerByClass(gadget);
|
|
@@ -6318,6 +6766,10 @@ async function executeAgent(promptArg, options, env) {
|
|
|
6318
6766
|
if (context.usage.outputTokens) {
|
|
6319
6767
|
progress.setOutputTokens(context.usage.outputTokens, false);
|
|
6320
6768
|
}
|
|
6769
|
+
progress.setCachedTokens(
|
|
6770
|
+
context.usage.cachedInputTokens ?? 0,
|
|
6771
|
+
context.usage.cacheCreationInputTokens ?? 0
|
|
6772
|
+
);
|
|
6321
6773
|
}
|
|
6322
6774
|
},
|
|
6323
6775
|
// onLLMCallComplete: Finalize metrics after each LLM call
|
|
@@ -6336,11 +6788,13 @@ async function executeAgent(promptArg, options, env) {
|
|
|
6336
6788
|
let callCost;
|
|
6337
6789
|
if (context.usage && client.modelRegistry) {
|
|
6338
6790
|
try {
|
|
6339
|
-
const modelName = options.model.includes(":") ? options.model.split(":")[1] : options.model;
|
|
6791
|
+
const modelName = context.options.model.includes(":") ? context.options.model.split(":")[1] : context.options.model;
|
|
6340
6792
|
const costResult = client.modelRegistry.estimateCost(
|
|
6341
6793
|
modelName,
|
|
6342
6794
|
context.usage.inputTokens,
|
|
6343
|
-
context.usage.outputTokens
|
|
6795
|
+
context.usage.outputTokens,
|
|
6796
|
+
context.usage.cachedInputTokens ?? 0,
|
|
6797
|
+
context.usage.cacheCreationInputTokens ?? 0
|
|
6344
6798
|
);
|
|
6345
6799
|
if (costResult) callCost = costResult.totalCost;
|
|
6346
6800
|
} catch {
|
|
@@ -6348,7 +6802,7 @@ async function executeAgent(promptArg, options, env) {
|
|
|
6348
6802
|
}
|
|
6349
6803
|
const callElapsed = progress.getCallElapsedSeconds();
|
|
6350
6804
|
progress.endCall(context.usage);
|
|
6351
|
-
if (
|
|
6805
|
+
if (!options.quiet) {
|
|
6352
6806
|
const summary = renderSummary({
|
|
6353
6807
|
iterations: context.iteration + 1,
|
|
6354
6808
|
model: options.model,
|
|
@@ -6427,9 +6881,27 @@ Command rejected by user with message: "${response}"`
|
|
|
6427
6881
|
builder.withGadgets(...gadgets);
|
|
6428
6882
|
}
|
|
6429
6883
|
builder.withParameterFormat(options.parameterFormat);
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6884
|
+
if (options.gadgetStartPrefix) {
|
|
6885
|
+
builder.withGadgetStartPrefix(options.gadgetStartPrefix);
|
|
6886
|
+
}
|
|
6887
|
+
if (options.gadgetEndPrefix) {
|
|
6888
|
+
builder.withGadgetEndPrefix(options.gadgetEndPrefix);
|
|
6889
|
+
}
|
|
6890
|
+
builder.withSyntheticGadgetCall(
|
|
6891
|
+
"TellUser",
|
|
6892
|
+
{
|
|
6893
|
+
message: "\u{1F44B} Hello! I'm ready to help.\n\nHere's what I can do:\n- Analyze your codebase\n- Execute commands\n- Answer questions\n\nWhat would you like me to work on?",
|
|
6894
|
+
done: false,
|
|
6895
|
+
type: "info"
|
|
6896
|
+
},
|
|
6897
|
+
"\u2139\uFE0F \u{1F44B} Hello! I'm ready to help.\n\nHere's what I can do:\n- Analyze your codebase\n- Execute commands\n- Answer questions\n\nWhat would you like me to work on?"
|
|
6898
|
+
);
|
|
6899
|
+
builder.withTextOnlyHandler("acknowledge");
|
|
6900
|
+
builder.withTextWithGadgetsHandler({
|
|
6901
|
+
gadgetName: "TellUser",
|
|
6902
|
+
parameterMapping: (text) => ({ message: text, done: false, type: "info" }),
|
|
6903
|
+
resultMapping: (text) => `\u2139\uFE0F ${text}`
|
|
6904
|
+
});
|
|
6433
6905
|
const agent = builder.ask(prompt);
|
|
6434
6906
|
for await (const event of agent.run()) {
|
|
6435
6907
|
if (event.type === "text") {
|
|
@@ -6437,7 +6909,14 @@ Command rejected by user with message: "${response}"`
|
|
|
6437
6909
|
printer.write(event.content);
|
|
6438
6910
|
} else if (event.type === "gadget_result") {
|
|
6439
6911
|
progress.pause();
|
|
6440
|
-
if (
|
|
6912
|
+
if (options.quiet) {
|
|
6913
|
+
if (event.result.gadgetName === "TellUser" && event.result.parameters?.message) {
|
|
6914
|
+
const message = String(event.result.parameters.message);
|
|
6915
|
+
const rendered = renderMarkdown(message);
|
|
6916
|
+
env.stdout.write(`${rendered}
|
|
6917
|
+
`);
|
|
6918
|
+
}
|
|
6919
|
+
} else {
|
|
6441
6920
|
const tokenCount = await countGadgetOutputTokens(event.result.result);
|
|
6442
6921
|
env.stderr.write(`${formatGadgetSummary({ ...event.result, tokenCount })}
|
|
6443
6922
|
`);
|
|
@@ -6446,7 +6925,7 @@ Command rejected by user with message: "${response}"`
|
|
|
6446
6925
|
}
|
|
6447
6926
|
progress.complete();
|
|
6448
6927
|
printer.ensureNewline();
|
|
6449
|
-
if (
|
|
6928
|
+
if (!options.quiet && iterations > 1) {
|
|
6450
6929
|
env.stderr.write(`${import_chalk3.default.dim("\u2500".repeat(40))}
|
|
6451
6930
|
`);
|
|
6452
6931
|
const summary = renderOverallSummary({
|
|
@@ -6519,7 +6998,7 @@ async function executeComplete(promptArg, options, env) {
|
|
|
6519
6998
|
progress.endCall(usage);
|
|
6520
6999
|
progress.complete();
|
|
6521
7000
|
printer.ensureNewline();
|
|
6522
|
-
if (stderrTTY) {
|
|
7001
|
+
if (stderrTTY && !options.quiet) {
|
|
6523
7002
|
const summary = renderSummary({ finishReason, usage, cost: progress.getTotalCost() });
|
|
6524
7003
|
if (summary) {
|
|
6525
7004
|
env.stderr.write(`${summary}
|
|
@@ -6540,9 +7019,102 @@ var import_node_fs3 = require("fs");
|
|
|
6540
7019
|
var import_node_os = require("os");
|
|
6541
7020
|
var import_node_path3 = require("path");
|
|
6542
7021
|
var import_js_toml2 = require("js-toml");
|
|
7022
|
+
|
|
7023
|
+
// src/cli/templates.ts
|
|
7024
|
+
var import_eta = require("eta");
|
|
7025
|
+
var TemplateError = class extends Error {
|
|
7026
|
+
constructor(message, promptName, configPath) {
|
|
7027
|
+
super(promptName ? `[prompts.${promptName}]: ${message}` : message);
|
|
7028
|
+
this.promptName = promptName;
|
|
7029
|
+
this.configPath = configPath;
|
|
7030
|
+
this.name = "TemplateError";
|
|
7031
|
+
}
|
|
7032
|
+
};
|
|
7033
|
+
function createTemplateEngine(prompts, configPath) {
|
|
7034
|
+
const eta = new import_eta.Eta({
|
|
7035
|
+
views: "/",
|
|
7036
|
+
// Required but we use named templates
|
|
7037
|
+
autoEscape: false,
|
|
7038
|
+
// Don't escape - these are prompts, not HTML
|
|
7039
|
+
autoTrim: false
|
|
7040
|
+
// Preserve whitespace in prompts
|
|
7041
|
+
});
|
|
7042
|
+
for (const [name, template] of Object.entries(prompts)) {
|
|
7043
|
+
try {
|
|
7044
|
+
eta.loadTemplate(`@${name}`, template);
|
|
7045
|
+
} catch (error) {
|
|
7046
|
+
throw new TemplateError(
|
|
7047
|
+
error instanceof Error ? error.message : String(error),
|
|
7048
|
+
name,
|
|
7049
|
+
configPath
|
|
7050
|
+
);
|
|
7051
|
+
}
|
|
7052
|
+
}
|
|
7053
|
+
return eta;
|
|
7054
|
+
}
|
|
7055
|
+
function resolveTemplate(eta, template, context = {}, configPath) {
|
|
7056
|
+
try {
|
|
7057
|
+
const fullContext = {
|
|
7058
|
+
...context,
|
|
7059
|
+
env: process.env
|
|
7060
|
+
};
|
|
7061
|
+
return eta.renderString(template, fullContext);
|
|
7062
|
+
} catch (error) {
|
|
7063
|
+
throw new TemplateError(
|
|
7064
|
+
error instanceof Error ? error.message : String(error),
|
|
7065
|
+
void 0,
|
|
7066
|
+
configPath
|
|
7067
|
+
);
|
|
7068
|
+
}
|
|
7069
|
+
}
|
|
7070
|
+
function validatePrompts(prompts, configPath) {
|
|
7071
|
+
const eta = createTemplateEngine(prompts, configPath);
|
|
7072
|
+
for (const [name, template] of Object.entries(prompts)) {
|
|
7073
|
+
try {
|
|
7074
|
+
eta.renderString(template, { env: {} });
|
|
7075
|
+
} catch (error) {
|
|
7076
|
+
throw new TemplateError(
|
|
7077
|
+
error instanceof Error ? error.message : String(error),
|
|
7078
|
+
name,
|
|
7079
|
+
configPath
|
|
7080
|
+
);
|
|
7081
|
+
}
|
|
7082
|
+
}
|
|
7083
|
+
}
|
|
7084
|
+
function validateEnvVars(template, promptName, configPath) {
|
|
7085
|
+
const envVarPattern = /<%=\s*it\.env\.(\w+)\s*%>/g;
|
|
7086
|
+
const matches = template.matchAll(envVarPattern);
|
|
7087
|
+
for (const match of matches) {
|
|
7088
|
+
const varName = match[1];
|
|
7089
|
+
if (process.env[varName] === void 0) {
|
|
7090
|
+
throw new TemplateError(
|
|
7091
|
+
`Environment variable '${varName}' is not set`,
|
|
7092
|
+
promptName,
|
|
7093
|
+
configPath
|
|
7094
|
+
);
|
|
7095
|
+
}
|
|
7096
|
+
}
|
|
7097
|
+
}
|
|
7098
|
+
function hasTemplateSyntax(str) {
|
|
7099
|
+
return str.includes("<%");
|
|
7100
|
+
}
|
|
7101
|
+
|
|
7102
|
+
// src/cli/config.ts
|
|
6543
7103
|
var GLOBAL_CONFIG_KEYS = /* @__PURE__ */ new Set(["log-level", "log-file", "log-reset"]);
|
|
6544
7104
|
var VALID_LOG_LEVELS = ["silly", "trace", "debug", "info", "warn", "error", "fatal"];
|
|
6545
|
-
var COMPLETE_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
7105
|
+
var COMPLETE_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
7106
|
+
"model",
|
|
7107
|
+
"system",
|
|
7108
|
+
"temperature",
|
|
7109
|
+
"max-tokens",
|
|
7110
|
+
"quiet",
|
|
7111
|
+
"inherits",
|
|
7112
|
+
"log-level",
|
|
7113
|
+
"log-file",
|
|
7114
|
+
"log-reset",
|
|
7115
|
+
"type"
|
|
7116
|
+
// Allowed for inheritance compatibility, ignored for built-in commands
|
|
7117
|
+
]);
|
|
6546
7118
|
var AGENT_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
6547
7119
|
"model",
|
|
6548
7120
|
"system",
|
|
@@ -6551,16 +7123,22 @@ var AGENT_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
6551
7123
|
"gadget",
|
|
6552
7124
|
"parameter-format",
|
|
6553
7125
|
"builtins",
|
|
6554
|
-
"builtin-interaction"
|
|
7126
|
+
"builtin-interaction",
|
|
7127
|
+
"gadget-start-prefix",
|
|
7128
|
+
"gadget-end-prefix",
|
|
7129
|
+
"quiet",
|
|
7130
|
+
"inherits",
|
|
7131
|
+
"log-level",
|
|
7132
|
+
"log-file",
|
|
7133
|
+
"log-reset",
|
|
7134
|
+
"type"
|
|
7135
|
+
// Allowed for inheritance compatibility, ignored for built-in commands
|
|
6555
7136
|
]);
|
|
6556
7137
|
var CUSTOM_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
6557
7138
|
...COMPLETE_CONFIG_KEYS,
|
|
6558
7139
|
...AGENT_CONFIG_KEYS,
|
|
6559
7140
|
"type",
|
|
6560
|
-
"description"
|
|
6561
|
-
"log-level",
|
|
6562
|
-
"log-file",
|
|
6563
|
-
"log-reset"
|
|
7141
|
+
"description"
|
|
6564
7142
|
]);
|
|
6565
7143
|
var VALID_PARAMETER_FORMATS = ["json", "yaml", "toml", "auto"];
|
|
6566
7144
|
function getConfigPath() {
|
|
@@ -6611,6 +7189,39 @@ function validateStringArray(value, key, section) {
|
|
|
6611
7189
|
}
|
|
6612
7190
|
return value;
|
|
6613
7191
|
}
|
|
7192
|
+
function validateInherits(value, section) {
|
|
7193
|
+
if (typeof value === "string") {
|
|
7194
|
+
return value;
|
|
7195
|
+
}
|
|
7196
|
+
if (Array.isArray(value)) {
|
|
7197
|
+
for (let i = 0; i < value.length; i++) {
|
|
7198
|
+
if (typeof value[i] !== "string") {
|
|
7199
|
+
throw new ConfigError(`[${section}].inherits[${i}] must be a string`);
|
|
7200
|
+
}
|
|
7201
|
+
}
|
|
7202
|
+
return value;
|
|
7203
|
+
}
|
|
7204
|
+
throw new ConfigError(`[${section}].inherits must be a string or array of strings`);
|
|
7205
|
+
}
|
|
7206
|
+
function validateLoggingConfig(raw, section) {
|
|
7207
|
+
const result = {};
|
|
7208
|
+
if ("log-level" in raw) {
|
|
7209
|
+
const level = validateString(raw["log-level"], "log-level", section);
|
|
7210
|
+
if (!VALID_LOG_LEVELS.includes(level)) {
|
|
7211
|
+
throw new ConfigError(
|
|
7212
|
+
`[${section}].log-level must be one of: ${VALID_LOG_LEVELS.join(", ")}`
|
|
7213
|
+
);
|
|
7214
|
+
}
|
|
7215
|
+
result["log-level"] = level;
|
|
7216
|
+
}
|
|
7217
|
+
if ("log-file" in raw) {
|
|
7218
|
+
result["log-file"] = validateString(raw["log-file"], "log-file", section);
|
|
7219
|
+
}
|
|
7220
|
+
if ("log-reset" in raw) {
|
|
7221
|
+
result["log-reset"] = validateBoolean(raw["log-reset"], "log-reset", section);
|
|
7222
|
+
}
|
|
7223
|
+
return result;
|
|
7224
|
+
}
|
|
6614
7225
|
function validateBaseConfig(raw, section) {
|
|
6615
7226
|
const result = {};
|
|
6616
7227
|
if ("model" in raw) {
|
|
@@ -6625,6 +7236,9 @@ function validateBaseConfig(raw, section) {
|
|
|
6625
7236
|
max: 2
|
|
6626
7237
|
});
|
|
6627
7238
|
}
|
|
7239
|
+
if ("inherits" in raw) {
|
|
7240
|
+
result.inherits = validateInherits(raw.inherits, section);
|
|
7241
|
+
}
|
|
6628
7242
|
return result;
|
|
6629
7243
|
}
|
|
6630
7244
|
function validateGlobalConfig(raw, section) {
|
|
@@ -6637,23 +7251,7 @@ function validateGlobalConfig(raw, section) {
|
|
|
6637
7251
|
throw new ConfigError(`[${section}].${key} is not a valid option`);
|
|
6638
7252
|
}
|
|
6639
7253
|
}
|
|
6640
|
-
|
|
6641
|
-
if ("log-level" in rawObj) {
|
|
6642
|
-
const level = validateString(rawObj["log-level"], "log-level", section);
|
|
6643
|
-
if (!VALID_LOG_LEVELS.includes(level)) {
|
|
6644
|
-
throw new ConfigError(
|
|
6645
|
-
`[${section}].log-level must be one of: ${VALID_LOG_LEVELS.join(", ")}`
|
|
6646
|
-
);
|
|
6647
|
-
}
|
|
6648
|
-
result["log-level"] = level;
|
|
6649
|
-
}
|
|
6650
|
-
if ("log-file" in rawObj) {
|
|
6651
|
-
result["log-file"] = validateString(rawObj["log-file"], "log-file", section);
|
|
6652
|
-
}
|
|
6653
|
-
if ("log-reset" in rawObj) {
|
|
6654
|
-
result["log-reset"] = validateBoolean(rawObj["log-reset"], "log-reset", section);
|
|
6655
|
-
}
|
|
6656
|
-
return result;
|
|
7254
|
+
return validateLoggingConfig(rawObj, section);
|
|
6657
7255
|
}
|
|
6658
7256
|
function validateCompleteConfig(raw, section) {
|
|
6659
7257
|
if (typeof raw !== "object" || raw === null) {
|
|
@@ -6665,13 +7263,19 @@ function validateCompleteConfig(raw, section) {
|
|
|
6665
7263
|
throw new ConfigError(`[${section}].${key} is not a valid option`);
|
|
6666
7264
|
}
|
|
6667
7265
|
}
|
|
6668
|
-
const result = {
|
|
7266
|
+
const result = {
|
|
7267
|
+
...validateBaseConfig(rawObj, section),
|
|
7268
|
+
...validateLoggingConfig(rawObj, section)
|
|
7269
|
+
};
|
|
6669
7270
|
if ("max-tokens" in rawObj) {
|
|
6670
7271
|
result["max-tokens"] = validateNumber(rawObj["max-tokens"], "max-tokens", section, {
|
|
6671
7272
|
integer: true,
|
|
6672
7273
|
min: 1
|
|
6673
7274
|
});
|
|
6674
7275
|
}
|
|
7276
|
+
if ("quiet" in rawObj) {
|
|
7277
|
+
result.quiet = validateBoolean(rawObj.quiet, "quiet", section);
|
|
7278
|
+
}
|
|
6675
7279
|
return result;
|
|
6676
7280
|
}
|
|
6677
7281
|
function validateAgentConfig(raw, section) {
|
|
@@ -6684,7 +7288,10 @@ function validateAgentConfig(raw, section) {
|
|
|
6684
7288
|
throw new ConfigError(`[${section}].${key} is not a valid option`);
|
|
6685
7289
|
}
|
|
6686
7290
|
}
|
|
6687
|
-
const result = {
|
|
7291
|
+
const result = {
|
|
7292
|
+
...validateBaseConfig(rawObj, section),
|
|
7293
|
+
...validateLoggingConfig(rawObj, section)
|
|
7294
|
+
};
|
|
6688
7295
|
if ("max-iterations" in rawObj) {
|
|
6689
7296
|
result["max-iterations"] = validateNumber(rawObj["max-iterations"], "max-iterations", section, {
|
|
6690
7297
|
integer: true,
|
|
@@ -6713,6 +7320,23 @@ function validateAgentConfig(raw, section) {
|
|
|
6713
7320
|
section
|
|
6714
7321
|
);
|
|
6715
7322
|
}
|
|
7323
|
+
if ("gadget-start-prefix" in rawObj) {
|
|
7324
|
+
result["gadget-start-prefix"] = validateString(
|
|
7325
|
+
rawObj["gadget-start-prefix"],
|
|
7326
|
+
"gadget-start-prefix",
|
|
7327
|
+
section
|
|
7328
|
+
);
|
|
7329
|
+
}
|
|
7330
|
+
if ("gadget-end-prefix" in rawObj) {
|
|
7331
|
+
result["gadget-end-prefix"] = validateString(
|
|
7332
|
+
rawObj["gadget-end-prefix"],
|
|
7333
|
+
"gadget-end-prefix",
|
|
7334
|
+
section
|
|
7335
|
+
);
|
|
7336
|
+
}
|
|
7337
|
+
if ("quiet" in rawObj) {
|
|
7338
|
+
result.quiet = validateBoolean(rawObj.quiet, "quiet", section);
|
|
7339
|
+
}
|
|
6716
7340
|
return result;
|
|
6717
7341
|
}
|
|
6718
7342
|
function validateCustomConfig(raw, section) {
|
|
@@ -6768,26 +7392,42 @@ function validateCustomConfig(raw, section) {
|
|
|
6768
7392
|
section
|
|
6769
7393
|
);
|
|
6770
7394
|
}
|
|
7395
|
+
if ("gadget-start-prefix" in rawObj) {
|
|
7396
|
+
result["gadget-start-prefix"] = validateString(
|
|
7397
|
+
rawObj["gadget-start-prefix"],
|
|
7398
|
+
"gadget-start-prefix",
|
|
7399
|
+
section
|
|
7400
|
+
);
|
|
7401
|
+
}
|
|
7402
|
+
if ("gadget-end-prefix" in rawObj) {
|
|
7403
|
+
result["gadget-end-prefix"] = validateString(
|
|
7404
|
+
rawObj["gadget-end-prefix"],
|
|
7405
|
+
"gadget-end-prefix",
|
|
7406
|
+
section
|
|
7407
|
+
);
|
|
7408
|
+
}
|
|
6771
7409
|
if ("max-tokens" in rawObj) {
|
|
6772
7410
|
result["max-tokens"] = validateNumber(rawObj["max-tokens"], "max-tokens", section, {
|
|
6773
7411
|
integer: true,
|
|
6774
7412
|
min: 1
|
|
6775
7413
|
});
|
|
6776
7414
|
}
|
|
6777
|
-
if ("
|
|
6778
|
-
|
|
6779
|
-
if (!VALID_LOG_LEVELS.includes(level)) {
|
|
6780
|
-
throw new ConfigError(
|
|
6781
|
-
`[${section}].log-level must be one of: ${VALID_LOG_LEVELS.join(", ")}`
|
|
6782
|
-
);
|
|
6783
|
-
}
|
|
6784
|
-
result["log-level"] = level;
|
|
7415
|
+
if ("quiet" in rawObj) {
|
|
7416
|
+
result.quiet = validateBoolean(rawObj.quiet, "quiet", section);
|
|
6785
7417
|
}
|
|
6786
|
-
|
|
6787
|
-
|
|
7418
|
+
Object.assign(result, validateLoggingConfig(rawObj, section));
|
|
7419
|
+
return result;
|
|
7420
|
+
}
|
|
7421
|
+
function validatePromptsConfig(raw, section) {
|
|
7422
|
+
if (typeof raw !== "object" || raw === null) {
|
|
7423
|
+
throw new ConfigError(`[${section}] must be a table`);
|
|
6788
7424
|
}
|
|
6789
|
-
|
|
6790
|
-
|
|
7425
|
+
const result = {};
|
|
7426
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
7427
|
+
if (typeof value !== "string") {
|
|
7428
|
+
throw new ConfigError(`[${section}].${key} must be a string`);
|
|
7429
|
+
}
|
|
7430
|
+
result[key] = value;
|
|
6791
7431
|
}
|
|
6792
7432
|
return result;
|
|
6793
7433
|
}
|
|
@@ -6805,6 +7445,8 @@ function validateConfig(raw, configPath) {
|
|
|
6805
7445
|
result.complete = validateCompleteConfig(value, key);
|
|
6806
7446
|
} else if (key === "agent") {
|
|
6807
7447
|
result.agent = validateAgentConfig(value, key);
|
|
7448
|
+
} else if (key === "prompts") {
|
|
7449
|
+
result.prompts = validatePromptsConfig(value, key);
|
|
6808
7450
|
} else {
|
|
6809
7451
|
result[key] = validateCustomConfig(value, key);
|
|
6810
7452
|
}
|
|
@@ -6840,12 +7482,119 @@ function loadConfig() {
|
|
|
6840
7482
|
configPath
|
|
6841
7483
|
);
|
|
6842
7484
|
}
|
|
6843
|
-
|
|
7485
|
+
const validated = validateConfig(raw, configPath);
|
|
7486
|
+
const inherited = resolveInheritance(validated, configPath);
|
|
7487
|
+
return resolveTemplatesInConfig(inherited, configPath);
|
|
6844
7488
|
}
|
|
6845
7489
|
function getCustomCommandNames(config) {
|
|
6846
|
-
const reserved = /* @__PURE__ */ new Set(["global", "complete", "agent"]);
|
|
7490
|
+
const reserved = /* @__PURE__ */ new Set(["global", "complete", "agent", "prompts"]);
|
|
6847
7491
|
return Object.keys(config).filter((key) => !reserved.has(key));
|
|
6848
7492
|
}
|
|
7493
|
+
function resolveTemplatesInConfig(config, configPath) {
|
|
7494
|
+
const prompts = config.prompts ?? {};
|
|
7495
|
+
const hasPrompts = Object.keys(prompts).length > 0;
|
|
7496
|
+
let hasTemplates = false;
|
|
7497
|
+
for (const [sectionName, section] of Object.entries(config)) {
|
|
7498
|
+
if (sectionName === "global" || sectionName === "prompts") continue;
|
|
7499
|
+
if (!section || typeof section !== "object") continue;
|
|
7500
|
+
const sectionObj = section;
|
|
7501
|
+
if (typeof sectionObj.system === "string" && hasTemplateSyntax(sectionObj.system)) {
|
|
7502
|
+
hasTemplates = true;
|
|
7503
|
+
break;
|
|
7504
|
+
}
|
|
7505
|
+
}
|
|
7506
|
+
for (const template of Object.values(prompts)) {
|
|
7507
|
+
if (hasTemplateSyntax(template)) {
|
|
7508
|
+
hasTemplates = true;
|
|
7509
|
+
break;
|
|
7510
|
+
}
|
|
7511
|
+
}
|
|
7512
|
+
if (!hasPrompts && !hasTemplates) {
|
|
7513
|
+
return config;
|
|
7514
|
+
}
|
|
7515
|
+
try {
|
|
7516
|
+
validatePrompts(prompts, configPath);
|
|
7517
|
+
} catch (error) {
|
|
7518
|
+
if (error instanceof TemplateError) {
|
|
7519
|
+
throw new ConfigError(error.message, configPath);
|
|
7520
|
+
}
|
|
7521
|
+
throw error;
|
|
7522
|
+
}
|
|
7523
|
+
for (const [name, template] of Object.entries(prompts)) {
|
|
7524
|
+
try {
|
|
7525
|
+
validateEnvVars(template, name, configPath);
|
|
7526
|
+
} catch (error) {
|
|
7527
|
+
if (error instanceof TemplateError) {
|
|
7528
|
+
throw new ConfigError(error.message, configPath);
|
|
7529
|
+
}
|
|
7530
|
+
throw error;
|
|
7531
|
+
}
|
|
7532
|
+
}
|
|
7533
|
+
const eta = createTemplateEngine(prompts, configPath);
|
|
7534
|
+
const result = { ...config };
|
|
7535
|
+
for (const [sectionName, section] of Object.entries(config)) {
|
|
7536
|
+
if (sectionName === "global" || sectionName === "prompts") continue;
|
|
7537
|
+
if (!section || typeof section !== "object") continue;
|
|
7538
|
+
const sectionObj = section;
|
|
7539
|
+
if (typeof sectionObj.system === "string" && hasTemplateSyntax(sectionObj.system)) {
|
|
7540
|
+
try {
|
|
7541
|
+
validateEnvVars(sectionObj.system, void 0, configPath);
|
|
7542
|
+
} catch (error) {
|
|
7543
|
+
if (error instanceof TemplateError) {
|
|
7544
|
+
throw new ConfigError(`[${sectionName}].system: ${error.message}`, configPath);
|
|
7545
|
+
}
|
|
7546
|
+
throw error;
|
|
7547
|
+
}
|
|
7548
|
+
try {
|
|
7549
|
+
const resolved = resolveTemplate(eta, sectionObj.system, {}, configPath);
|
|
7550
|
+
result[sectionName] = {
|
|
7551
|
+
...sectionObj,
|
|
7552
|
+
system: resolved
|
|
7553
|
+
};
|
|
7554
|
+
} catch (error) {
|
|
7555
|
+
if (error instanceof TemplateError) {
|
|
7556
|
+
throw new ConfigError(`[${sectionName}].system: ${error.message}`, configPath);
|
|
7557
|
+
}
|
|
7558
|
+
throw error;
|
|
7559
|
+
}
|
|
7560
|
+
}
|
|
7561
|
+
}
|
|
7562
|
+
return result;
|
|
7563
|
+
}
|
|
7564
|
+
function resolveInheritance(config, configPath) {
|
|
7565
|
+
const resolved = {};
|
|
7566
|
+
const resolving = /* @__PURE__ */ new Set();
|
|
7567
|
+
function resolveSection(name) {
|
|
7568
|
+
if (name in resolved) {
|
|
7569
|
+
return resolved[name];
|
|
7570
|
+
}
|
|
7571
|
+
if (resolving.has(name)) {
|
|
7572
|
+
throw new ConfigError(`Circular inheritance detected: ${name}`, configPath);
|
|
7573
|
+
}
|
|
7574
|
+
const section = config[name];
|
|
7575
|
+
if (section === void 0 || typeof section !== "object") {
|
|
7576
|
+
throw new ConfigError(`Cannot inherit from unknown section: ${name}`, configPath);
|
|
7577
|
+
}
|
|
7578
|
+
resolving.add(name);
|
|
7579
|
+
const sectionObj = section;
|
|
7580
|
+
const inheritsRaw = sectionObj.inherits;
|
|
7581
|
+
const inheritsList = inheritsRaw ? Array.isArray(inheritsRaw) ? inheritsRaw : [inheritsRaw] : [];
|
|
7582
|
+
let merged = {};
|
|
7583
|
+
for (const parent of inheritsList) {
|
|
7584
|
+
const parentResolved = resolveSection(parent);
|
|
7585
|
+
merged = { ...merged, ...parentResolved };
|
|
7586
|
+
}
|
|
7587
|
+
const { inherits: _inherits, ...ownValues } = sectionObj;
|
|
7588
|
+
merged = { ...merged, ...ownValues };
|
|
7589
|
+
resolving.delete(name);
|
|
7590
|
+
resolved[name] = merged;
|
|
7591
|
+
return merged;
|
|
7592
|
+
}
|
|
7593
|
+
for (const name of Object.keys(config)) {
|
|
7594
|
+
resolveSection(name);
|
|
7595
|
+
}
|
|
7596
|
+
return resolved;
|
|
7597
|
+
}
|
|
6849
7598
|
|
|
6850
7599
|
// src/cli/models-command.ts
|
|
6851
7600
|
var import_chalk4 = __toESM(require("chalk"), 1);
|