llm-exe 2.3.1 → 2.3.3
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/index.d.mts +195 -22
- package/dist/index.d.ts +195 -22
- package/dist/index.js +1012 -843
- package/dist/index.mjs +1010 -843
- package/package.json +5 -3
- package/readme.md +23 -7
package/dist/index.js
CHANGED
|
@@ -59,6 +59,7 @@ __export(index_exports, {
|
|
|
59
59
|
createEmbedding: () => createEmbedding,
|
|
60
60
|
createLlmExecutor: () => createLlmExecutor,
|
|
61
61
|
createLlmFunctionExecutor: () => createLlmFunctionExecutor,
|
|
62
|
+
createOpenAiCompatibleConfiguration: () => createOpenAiCompatibleConfiguration,
|
|
62
63
|
createParser: () => createParser,
|
|
63
64
|
createPrompt: () => createPrompt,
|
|
64
65
|
createState: () => createState,
|
|
@@ -69,6 +70,7 @@ __export(index_exports, {
|
|
|
69
70
|
registerPartials: () => registerPartials,
|
|
70
71
|
useExecutors: () => useExecutors,
|
|
71
72
|
useLlm: () => useLlm,
|
|
73
|
+
useLlmConfiguration: () => useLlmConfiguration,
|
|
72
74
|
utils: () => utils_exports
|
|
73
75
|
});
|
|
74
76
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -186,6 +188,10 @@ var BaseExecutor = class {
|
|
|
186
188
|
*/
|
|
187
189
|
__publicField(this, "hooks");
|
|
188
190
|
__publicField(this, "allowedHooks", [hookOnComplete, hookOnError, hookOnSuccess]);
|
|
191
|
+
/**
|
|
192
|
+
* @property maxHooksPerEvent - Maximum number of hooks allowed per event
|
|
193
|
+
*/
|
|
194
|
+
__publicField(this, "maxHooksPerEvent", 100);
|
|
189
195
|
this.id = (0, import_uuid.v4)();
|
|
190
196
|
this.type = type;
|
|
191
197
|
this.name = name;
|
|
@@ -291,6 +297,11 @@ var BaseExecutor = class {
|
|
|
291
297
|
const _hooks = Array.isArray(hookInput) ? hookInput : [hookInput];
|
|
292
298
|
for (const hook of _hooks) {
|
|
293
299
|
if (hook && typeof hook === "function" && !this.hooks[hookKey].find((h) => h === hook)) {
|
|
300
|
+
if (this.hooks[hookKey].length >= this.maxHooksPerEvent) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
`Maximum number of hooks (${this.maxHooksPerEvent}) reached for event "${String(hookKey)}". Consider removing unused hooks or increasing the limit.`
|
|
303
|
+
);
|
|
304
|
+
}
|
|
294
305
|
this.hooks[hookKey].push(hook);
|
|
295
306
|
}
|
|
296
307
|
}
|
|
@@ -318,10 +329,18 @@ var BaseExecutor = class {
|
|
|
318
329
|
}
|
|
319
330
|
once(eventName, fn) {
|
|
320
331
|
if (typeof fn !== "function") return this;
|
|
332
|
+
if (this.hooks[eventName] && this.hooks[eventName].length >= this.maxHooksPerEvent) {
|
|
333
|
+
throw new Error(
|
|
334
|
+
`Maximum number of hooks (${this.maxHooksPerEvent}) reached for event "${String(eventName)}". Consider removing unused hooks or increasing the limit.`
|
|
335
|
+
);
|
|
336
|
+
}
|
|
321
337
|
const onceWrapper = (...args) => {
|
|
322
338
|
fn(...args);
|
|
323
339
|
this.off(eventName, onceWrapper);
|
|
324
340
|
};
|
|
341
|
+
if (!this.hooks[eventName]) {
|
|
342
|
+
this.hooks[eventName] = [];
|
|
343
|
+
}
|
|
325
344
|
this.hooks[eventName].push(onceWrapper);
|
|
326
345
|
return this;
|
|
327
346
|
}
|
|
@@ -332,6 +351,40 @@ var BaseExecutor = class {
|
|
|
332
351
|
getTraceId() {
|
|
333
352
|
return this.traceId;
|
|
334
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Clear all hooks for a specific event or all events
|
|
356
|
+
* Useful for preventing memory leaks in long-running processes
|
|
357
|
+
* @param eventName - The event name to clear hooks for
|
|
358
|
+
*/
|
|
359
|
+
clearHooks(eventName) {
|
|
360
|
+
if (eventName) {
|
|
361
|
+
if (this.hooks[eventName]) {
|
|
362
|
+
this.hooks[eventName] = [];
|
|
363
|
+
}
|
|
364
|
+
} else {
|
|
365
|
+
for (const key of this.allowedHooks) {
|
|
366
|
+
if (this.hooks[key]) {
|
|
367
|
+
this.hooks[key] = [];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return this;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Get the count of hooks for monitoring memory usage
|
|
375
|
+
* @param eventName - Optional event name to get count for
|
|
376
|
+
* @returns Hook count for specific event or all events
|
|
377
|
+
*/
|
|
378
|
+
getHookCount(eventName) {
|
|
379
|
+
if (eventName) {
|
|
380
|
+
return this.hooks[eventName]?.length || 0;
|
|
381
|
+
}
|
|
382
|
+
const counts = {};
|
|
383
|
+
for (const key of this.allowedHooks) {
|
|
384
|
+
counts[key] = this.hooks[key]?.length || 0;
|
|
385
|
+
}
|
|
386
|
+
return counts;
|
|
387
|
+
}
|
|
335
388
|
};
|
|
336
389
|
|
|
337
390
|
// src/utils/modules/inferFunctionName.ts
|
|
@@ -477,7 +530,7 @@ var BooleanParser = class extends BaseParser {
|
|
|
477
530
|
`Invalid input. Expected string. Received ${typeof text}.`
|
|
478
531
|
);
|
|
479
532
|
const clean = text.toLowerCase().trim();
|
|
480
|
-
if (clean === "true") {
|
|
533
|
+
if (clean === "true" || clean === "yes" || clean === "y" || clean === "1") {
|
|
481
534
|
return true;
|
|
482
535
|
}
|
|
483
536
|
return false;
|
|
@@ -506,7 +559,7 @@ var NumberParser = class extends BaseParser {
|
|
|
506
559
|
super("number", options);
|
|
507
560
|
}
|
|
508
561
|
parse(text) {
|
|
509
|
-
const match = text.match(
|
|
562
|
+
const match = text.match(/-?\d+(\.\d+)?/);
|
|
510
563
|
return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
|
|
511
564
|
}
|
|
512
565
|
};
|
|
@@ -1408,9 +1461,8 @@ var asyncCallWithTimeout = async (asyncPromise, timeLimit = 1e4) => {
|
|
|
1408
1461
|
);
|
|
1409
1462
|
}, timeLimit);
|
|
1410
1463
|
});
|
|
1411
|
-
return Promise.race([asyncPromise, timeoutPromise]).
|
|
1464
|
+
return Promise.race([asyncPromise, timeoutPromise]).finally(() => {
|
|
1412
1465
|
clearTimeout(timeoutHandle);
|
|
1413
|
-
return result;
|
|
1414
1466
|
});
|
|
1415
1467
|
};
|
|
1416
1468
|
|
|
@@ -1556,9 +1608,13 @@ var ListToJsonParser = class extends BaseParserWithJson {
|
|
|
1556
1608
|
const lines = text.split("\n");
|
|
1557
1609
|
const output = {};
|
|
1558
1610
|
lines.forEach((line) => {
|
|
1559
|
-
const
|
|
1560
|
-
if (
|
|
1561
|
-
|
|
1611
|
+
const colonIndex = line.indexOf(":");
|
|
1612
|
+
if (colonIndex !== -1) {
|
|
1613
|
+
const key = line.slice(0, colonIndex);
|
|
1614
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
1615
|
+
if (value) {
|
|
1616
|
+
output[camelCase(key)] = value;
|
|
1617
|
+
}
|
|
1562
1618
|
}
|
|
1563
1619
|
});
|
|
1564
1620
|
if (this.schema) {
|
|
@@ -1630,7 +1686,7 @@ var ListToArrayParser = class extends BaseParser {
|
|
|
1630
1686
|
super("listToArray");
|
|
1631
1687
|
}
|
|
1632
1688
|
parse(text) {
|
|
1633
|
-
const lines = text.split("\n").map((s) => s.replace(
|
|
1689
|
+
const lines = text.split("\n").map((s) => s.replace(/^(?:[-*] |\d+\. )/, "").replace(/'/g, "\u2019").trim());
|
|
1634
1690
|
return lines;
|
|
1635
1691
|
}
|
|
1636
1692
|
};
|
|
@@ -1758,8 +1814,11 @@ function createParser(type, options = {}) {
|
|
|
1758
1814
|
case "stringExtract":
|
|
1759
1815
|
return new StringExtractParser(options);
|
|
1760
1816
|
case "string":
|
|
1761
|
-
default:
|
|
1762
1817
|
return new StringParser();
|
|
1818
|
+
default:
|
|
1819
|
+
throw new Error(
|
|
1820
|
+
`Invalid parser type: "${type}". Valid types are: json, string, boolean, number, stringExtract, listToArray, listToJson, listToKeyValue, replaceStringTemplate, markdownCodeBlock, markdownCodeBlocks`
|
|
1821
|
+
);
|
|
1763
1822
|
}
|
|
1764
1823
|
}
|
|
1765
1824
|
function createCustomParser(name, parserFn) {
|
|
@@ -2118,6 +2177,63 @@ function getEnvironmentVariable(name) {
|
|
|
2118
2177
|
}
|
|
2119
2178
|
}
|
|
2120
2179
|
|
|
2180
|
+
// src/llm/output/_util.ts
|
|
2181
|
+
function formatOptions(response, handler) {
|
|
2182
|
+
const out = [];
|
|
2183
|
+
for (const item of response) {
|
|
2184
|
+
const result = handler(item);
|
|
2185
|
+
if (result) {
|
|
2186
|
+
out.push([result]);
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
return out;
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
// src/llm/output/openai.ts
|
|
2193
|
+
function formatResult(result) {
|
|
2194
|
+
const out = [];
|
|
2195
|
+
if (typeof result?.message?.content === "string") {
|
|
2196
|
+
out.push({
|
|
2197
|
+
type: "text",
|
|
2198
|
+
text: result.message.content
|
|
2199
|
+
});
|
|
2200
|
+
}
|
|
2201
|
+
if (result?.message?.tool_calls) {
|
|
2202
|
+
for (const call of result.message.tool_calls) {
|
|
2203
|
+
out.push({
|
|
2204
|
+
functionId: call.id,
|
|
2205
|
+
type: "function_use",
|
|
2206
|
+
name: call.function.name,
|
|
2207
|
+
input: maybeParseJSON(call.function.arguments)
|
|
2208
|
+
});
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
return out;
|
|
2212
|
+
}
|
|
2213
|
+
function OutputOpenAIChat(result, _config) {
|
|
2214
|
+
const id = result.id;
|
|
2215
|
+
const name = result.model || _config?.options.model?.default || "openai.unknown";
|
|
2216
|
+
const created = result.created;
|
|
2217
|
+
const [_content, ..._options] = result?.choices || [];
|
|
2218
|
+
const stopReason = _content?.finish_reason;
|
|
2219
|
+
const content = formatResult(_content);
|
|
2220
|
+
const options = formatOptions(_options, formatResult);
|
|
2221
|
+
const usage = {
|
|
2222
|
+
output_tokens: result?.usage?.completion_tokens,
|
|
2223
|
+
input_tokens: result?.usage?.prompt_tokens,
|
|
2224
|
+
total_tokens: result?.usage?.total_tokens
|
|
2225
|
+
};
|
|
2226
|
+
return {
|
|
2227
|
+
id,
|
|
2228
|
+
name,
|
|
2229
|
+
created,
|
|
2230
|
+
usage,
|
|
2231
|
+
stopReason,
|
|
2232
|
+
content,
|
|
2233
|
+
options
|
|
2234
|
+
};
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2121
2237
|
// src/llm/config/openai/promptSanitizeMessageCallback.ts
|
|
2122
2238
|
function openaiPromptMessageCallback(_message) {
|
|
2123
2239
|
let message = { ..._message };
|
|
@@ -2151,38 +2267,127 @@ function openaiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
|
2151
2267
|
return _messages.map(openaiPromptMessageCallback);
|
|
2152
2268
|
}
|
|
2153
2269
|
|
|
2154
|
-
// src/llm/
|
|
2155
|
-
var
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2270
|
+
// src/llm/output/_utils/cleanJsonSchemaFor.ts
|
|
2271
|
+
var providerFieldExclusions = {
|
|
2272
|
+
"openai.chat": ["default"],
|
|
2273
|
+
// fields to exclude for openai.chat, xai, deepseek
|
|
2274
|
+
"anthropic.chat": [],
|
|
2275
|
+
"google.chat": ["additionalProperties"]
|
|
2276
|
+
};
|
|
2277
|
+
function cleanJsonSchemaFor(schema = {}, provider) {
|
|
2278
|
+
const clone = deepClone(schema);
|
|
2279
|
+
if (Object.keys(clone).length === 0) {
|
|
2280
|
+
return {
|
|
2281
|
+
type: "object",
|
|
2282
|
+
properties: {},
|
|
2283
|
+
required: []
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
const exclusions = providerFieldExclusions[provider] || [];
|
|
2287
|
+
function removeDisallowedFields(obj) {
|
|
2288
|
+
if (Array.isArray(obj)) {
|
|
2289
|
+
return obj.map(removeDisallowedFields);
|
|
2290
|
+
} else if (typeof obj === "object" && obj !== null) {
|
|
2291
|
+
return Object.keys(obj).reduce((acc, key) => {
|
|
2292
|
+
if (!exclusions.includes(key)) {
|
|
2293
|
+
acc[key] = removeDisallowedFields(obj[key]);
|
|
2294
|
+
}
|
|
2295
|
+
return acc;
|
|
2296
|
+
}, {});
|
|
2165
2297
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2298
|
+
return obj;
|
|
2299
|
+
}
|
|
2300
|
+
return removeDisallowedFields(clone);
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
// src/llm/config/openai/compatible.ts
|
|
2304
|
+
function createOpenAiCompatibleConfiguration(overrides) {
|
|
2305
|
+
const [apiKeyPropertyKey, apiKeyPropertyValue] = overrides.apiKeyMapping;
|
|
2306
|
+
const config = {
|
|
2307
|
+
key: overrides.key,
|
|
2308
|
+
provider: overrides.provider,
|
|
2309
|
+
endpoint: overrides.endpoint,
|
|
2310
|
+
options: {
|
|
2311
|
+
prompt: {},
|
|
2312
|
+
effort: {},
|
|
2313
|
+
topP: {},
|
|
2314
|
+
useJson: {},
|
|
2315
|
+
[apiKeyPropertyKey]: {
|
|
2316
|
+
default: getEnvironmentVariable(apiKeyPropertyValue)
|
|
2317
|
+
}
|
|
2173
2318
|
},
|
|
2174
|
-
|
|
2175
|
-
|
|
2319
|
+
method: "POST",
|
|
2320
|
+
headers: `{"Authorization":"Bearer {{${apiKeyPropertyKey}}}", "Content-Type": "application/json" }`,
|
|
2321
|
+
mapBody: {
|
|
2322
|
+
prompt: {
|
|
2323
|
+
key: "messages",
|
|
2324
|
+
transform: openaiPromptSanitize
|
|
2325
|
+
},
|
|
2326
|
+
model: {
|
|
2327
|
+
key: "model"
|
|
2328
|
+
},
|
|
2329
|
+
topP: {
|
|
2330
|
+
key: "top_p"
|
|
2331
|
+
},
|
|
2332
|
+
useJson: {
|
|
2333
|
+
key: "response_format.type",
|
|
2334
|
+
transform: (v) => v ? "json_object" : "text"
|
|
2335
|
+
},
|
|
2336
|
+
effort: {
|
|
2337
|
+
key: "reasoning_effort",
|
|
2338
|
+
transform: (v, _s) => {
|
|
2339
|
+
if (
|
|
2340
|
+
// only supported reasoning models
|
|
2341
|
+
["gpt-5"].includes(_s.model) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
|
|
2342
|
+
) {
|
|
2343
|
+
return v;
|
|
2344
|
+
}
|
|
2345
|
+
return void 0;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2176
2348
|
},
|
|
2177
|
-
|
|
2178
|
-
|
|
2349
|
+
mapOptions: {
|
|
2350
|
+
jsonSchema: (schema, options, currentInput) => ({
|
|
2351
|
+
response_format: {
|
|
2352
|
+
...currentInput?.response_format || {},
|
|
2353
|
+
type: "json_schema",
|
|
2354
|
+
json_schema: {
|
|
2355
|
+
name: "output",
|
|
2356
|
+
strict: !!options?.functionCallStrictInput,
|
|
2357
|
+
schema: cleanJsonSchemaFor(schema, "openai.chat")
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
}),
|
|
2361
|
+
functionCall: (call) => {
|
|
2362
|
+
if (call === "any") return { tool_choice: "required" };
|
|
2363
|
+
if (call === "none") return { tool_choice: "none" };
|
|
2364
|
+
if (call === "auto") return { tool_choice: "auto" };
|
|
2365
|
+
return { tool_choice: call };
|
|
2366
|
+
},
|
|
2367
|
+
functions: (functions, options) => ({
|
|
2368
|
+
tools: functions.map((f) => ({
|
|
2369
|
+
type: "function",
|
|
2370
|
+
function: {
|
|
2371
|
+
name: f.name,
|
|
2372
|
+
description: f.description,
|
|
2373
|
+
parameters: cleanJsonSchemaFor(f.parameters, "openai.chat"),
|
|
2374
|
+
strict: !!options?.functionCallStrictInput
|
|
2375
|
+
}
|
|
2376
|
+
}))
|
|
2377
|
+
})
|
|
2179
2378
|
},
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2379
|
+
transformResponse: overrides.transformResponse ?? OutputOpenAIChat
|
|
2380
|
+
};
|
|
2381
|
+
return config;
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
// src/llm/config/openai/index.ts
|
|
2385
|
+
var openAiChatV1 = createOpenAiCompatibleConfiguration({
|
|
2386
|
+
key: "openai.chat.v1",
|
|
2387
|
+
provider: "openai.chat",
|
|
2388
|
+
endpoint: `https://api.openai.com/v1/chat/completions`,
|
|
2389
|
+
apiKeyMapping: ["openAiApiKey", "OPENAI_API_KEY"]
|
|
2390
|
+
});
|
|
2186
2391
|
var openAiChatMockV1 = {
|
|
2187
2392
|
key: "openai.chat-mock.v1",
|
|
2188
2393
|
provider: "openai.chat-mock",
|
|
@@ -2209,13 +2414,26 @@ var openAiChatMockV1 = {
|
|
|
2209
2414
|
},
|
|
2210
2415
|
useJson: {
|
|
2211
2416
|
key: "response_format.type",
|
|
2212
|
-
|
|
2417
|
+
transform: (v) => v ? "json_object" : "text"
|
|
2213
2418
|
}
|
|
2214
|
-
}
|
|
2419
|
+
},
|
|
2420
|
+
transformResponse: OutputOpenAIChat
|
|
2215
2421
|
};
|
|
2216
2422
|
var openai = {
|
|
2217
2423
|
"openai.chat.v1": openAiChatV1,
|
|
2218
2424
|
"openai.chat-mock.v1": openAiChatMockV1,
|
|
2425
|
+
// GPT-5 family
|
|
2426
|
+
"openai.gpt-5.2": withDefaultModel(openAiChatV1, "gpt-5.2"),
|
|
2427
|
+
"openai.gpt-5-mini": withDefaultModel(openAiChatV1, "gpt-5-mini"),
|
|
2428
|
+
"openai.gpt-5-nano": withDefaultModel(openAiChatV1, "gpt-5-nano"),
|
|
2429
|
+
// GPT-4.1 family
|
|
2430
|
+
"openai.gpt-4.1": withDefaultModel(openAiChatV1, "gpt-4.1"),
|
|
2431
|
+
"openai.gpt-4.1-mini": withDefaultModel(openAiChatV1, "gpt-4.1-mini"),
|
|
2432
|
+
"openai.gpt-4.1-nano": withDefaultModel(openAiChatV1, "gpt-4.1-nano"),
|
|
2433
|
+
// Reasoning models
|
|
2434
|
+
"openai.o3": withDefaultModel(openAiChatV1, "o3"),
|
|
2435
|
+
"openai.o4-mini": withDefaultModel(openAiChatV1, "o4-mini"),
|
|
2436
|
+
// GPT-4o family
|
|
2219
2437
|
"openai.gpt-4o": withDefaultModel(openAiChatV1, "gpt-4o"),
|
|
2220
2438
|
"openai.gpt-4o-mini": withDefaultModel(openAiChatV1, "gpt-4o-mini")
|
|
2221
2439
|
};
|
|
@@ -2254,6 +2472,20 @@ function anthropicPromptMessageCallback(_message) {
|
|
|
2254
2472
|
}
|
|
2255
2473
|
|
|
2256
2474
|
// src/llm/config/anthropic/promptSanitize.ts
|
|
2475
|
+
function mergeConsecutiveSameRole(messages) {
|
|
2476
|
+
if (messages.length <= 1) return messages;
|
|
2477
|
+
const merged = [messages[0]];
|
|
2478
|
+
for (let i = 1; i < messages.length; i++) {
|
|
2479
|
+
const prev = merged[merged.length - 1];
|
|
2480
|
+
const curr = messages[i];
|
|
2481
|
+
if (curr.role === prev.role && Array.isArray(prev.content) && Array.isArray(curr.content)) {
|
|
2482
|
+
prev.content = [...prev.content, ...curr.content];
|
|
2483
|
+
} else {
|
|
2484
|
+
merged.push(curr);
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
return merged;
|
|
2488
|
+
}
|
|
2257
2489
|
function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
2258
2490
|
if (typeof _messages === "string") {
|
|
2259
2491
|
return [{ role: "user", content: _messages }].map(
|
|
@@ -2271,14 +2503,15 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
|
2271
2503
|
}
|
|
2272
2504
|
if (first.role === "system" && messages.length > 0) {
|
|
2273
2505
|
_outputObj.system = first.content;
|
|
2274
|
-
|
|
2506
|
+
const result2 = messages.map((m) => {
|
|
2275
2507
|
if (m.role === "system") {
|
|
2276
2508
|
return { ...m, role: "user" };
|
|
2277
2509
|
}
|
|
2278
2510
|
return m;
|
|
2279
2511
|
}).map(anthropicPromptMessageCallback);
|
|
2512
|
+
return mergeConsecutiveSameRole(result2);
|
|
2280
2513
|
}
|
|
2281
|
-
|
|
2514
|
+
const result = [
|
|
2282
2515
|
first,
|
|
2283
2516
|
...messages.map((m) => {
|
|
2284
2517
|
if (m.role === "system") {
|
|
@@ -2287,10 +2520,78 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
|
2287
2520
|
return m;
|
|
2288
2521
|
})
|
|
2289
2522
|
].map(anthropicPromptMessageCallback);
|
|
2523
|
+
return mergeConsecutiveSameRole(result);
|
|
2524
|
+
}
|
|
2525
|
+
|
|
2526
|
+
// src/llm/output/claude.ts
|
|
2527
|
+
function formatResult2(response) {
|
|
2528
|
+
const content = response?.content || [];
|
|
2529
|
+
const out = [];
|
|
2530
|
+
for (let i = 0; i < content.length; i++) {
|
|
2531
|
+
const result = content[i];
|
|
2532
|
+
if (result.type === "text") {
|
|
2533
|
+
out.push({
|
|
2534
|
+
type: "text",
|
|
2535
|
+
text: result.text
|
|
2536
|
+
});
|
|
2537
|
+
} else if (result.type === "tool_use") {
|
|
2538
|
+
out.push({
|
|
2539
|
+
functionId: result.id,
|
|
2540
|
+
type: "function_use",
|
|
2541
|
+
name: result.name,
|
|
2542
|
+
input: result.input
|
|
2543
|
+
});
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2546
|
+
return out;
|
|
2547
|
+
}
|
|
2548
|
+
function OutputAnthropicClaude3Chat(result, _config) {
|
|
2549
|
+
const id = result.id;
|
|
2550
|
+
const name = result.model || _config?.options.model?.default || "anthropic.unknown";
|
|
2551
|
+
const stopReason = result.stop_reason;
|
|
2552
|
+
const content = formatResult2(result);
|
|
2553
|
+
const usage = {
|
|
2554
|
+
input_tokens: result?.usage?.input_tokens,
|
|
2555
|
+
output_tokens: result?.usage?.output_tokens,
|
|
2556
|
+
total_tokens: result?.usage?.input_tokens + result?.usage?.output_tokens
|
|
2557
|
+
};
|
|
2558
|
+
return {
|
|
2559
|
+
id,
|
|
2560
|
+
name,
|
|
2561
|
+
created: Date.now(),
|
|
2562
|
+
usage,
|
|
2563
|
+
stopReason,
|
|
2564
|
+
content
|
|
2565
|
+
};
|
|
2566
|
+
}
|
|
2567
|
+
|
|
2568
|
+
// src/llm/output/llama.ts
|
|
2569
|
+
function OutputMetaLlama3Chat(result, _config) {
|
|
2570
|
+
const id = (0, import_uuid.v4)();
|
|
2571
|
+
const name = _config?.options?.model?.default || "meta";
|
|
2572
|
+
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
2573
|
+
const stopReason = result.stop_reason;
|
|
2574
|
+
const content = [
|
|
2575
|
+
{ type: "text", text: result.generation }
|
|
2576
|
+
];
|
|
2577
|
+
const usage = {
|
|
2578
|
+
output_tokens: result?.generation_token_count,
|
|
2579
|
+
input_tokens: result?.prompt_token_count,
|
|
2580
|
+
total_tokens: result?.generation_token_count + result?.prompt_token_count
|
|
2581
|
+
};
|
|
2582
|
+
return {
|
|
2583
|
+
id,
|
|
2584
|
+
name,
|
|
2585
|
+
created,
|
|
2586
|
+
usage,
|
|
2587
|
+
stopReason,
|
|
2588
|
+
content,
|
|
2589
|
+
options: []
|
|
2590
|
+
};
|
|
2290
2591
|
}
|
|
2291
2592
|
|
|
2292
2593
|
// src/llm/config/bedrock/index.ts
|
|
2293
|
-
var
|
|
2594
|
+
var ANTHROPIC_BEDROCK_VERSION = "bedrock-2023-05-31";
|
|
2294
2595
|
var amazonAnthropicChatV1 = {
|
|
2295
2596
|
key: "amazon:anthropic.chat.v1",
|
|
2296
2597
|
provider: "amazon:anthropic.chat",
|
|
@@ -2311,7 +2612,7 @@ var amazonAnthropicChatV1 = {
|
|
|
2311
2612
|
mapBody: {
|
|
2312
2613
|
prompt: {
|
|
2313
2614
|
key: "messages",
|
|
2314
|
-
|
|
2615
|
+
transform: anthropicPromptSanitize
|
|
2315
2616
|
},
|
|
2316
2617
|
topP: {
|
|
2317
2618
|
key: "top_p"
|
|
@@ -2322,9 +2623,26 @@ var amazonAnthropicChatV1 = {
|
|
|
2322
2623
|
},
|
|
2323
2624
|
anthropic_version: {
|
|
2324
2625
|
key: "anthropic_version",
|
|
2325
|
-
default:
|
|
2626
|
+
default: ANTHROPIC_BEDROCK_VERSION
|
|
2326
2627
|
}
|
|
2327
|
-
}
|
|
2628
|
+
},
|
|
2629
|
+
mapOptions: {
|
|
2630
|
+
functionCall: (call, _options) => {
|
|
2631
|
+
if (call === "none") return { _clearFunctions: true };
|
|
2632
|
+
if (call === "auto" || call === "any") {
|
|
2633
|
+
return { tool_choice: { type: call } };
|
|
2634
|
+
}
|
|
2635
|
+
return { tool_choice: call };
|
|
2636
|
+
},
|
|
2637
|
+
functions: (functions) => ({
|
|
2638
|
+
tools: functions.map((f) => ({
|
|
2639
|
+
name: f.name,
|
|
2640
|
+
description: f.description,
|
|
2641
|
+
input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
|
|
2642
|
+
}))
|
|
2643
|
+
})
|
|
2644
|
+
},
|
|
2645
|
+
transformResponse: OutputAnthropicClaude3Chat
|
|
2328
2646
|
};
|
|
2329
2647
|
var amazonMetaChatV1 = {
|
|
2330
2648
|
key: "amazon:meta.chat.v1",
|
|
@@ -2346,7 +2664,7 @@ var amazonMetaChatV1 = {
|
|
|
2346
2664
|
mapBody: {
|
|
2347
2665
|
prompt: {
|
|
2348
2666
|
key: "prompt",
|
|
2349
|
-
|
|
2667
|
+
transform: (messages) => {
|
|
2350
2668
|
if (typeof messages === "string") {
|
|
2351
2669
|
return messages;
|
|
2352
2670
|
} else {
|
|
@@ -2366,7 +2684,8 @@ var amazonMetaChatV1 = {
|
|
|
2366
2684
|
key: "max_gen_len",
|
|
2367
2685
|
default: 2048
|
|
2368
2686
|
}
|
|
2369
|
-
}
|
|
2687
|
+
},
|
|
2688
|
+
transformResponse: OutputMetaLlama3Chat
|
|
2370
2689
|
};
|
|
2371
2690
|
var bedrock = {
|
|
2372
2691
|
"amazon:anthropic.chat.v1": amazonAnthropicChatV1,
|
|
@@ -2405,24 +2724,74 @@ var anthropicChatV1 = {
|
|
|
2405
2724
|
},
|
|
2406
2725
|
prompt: {
|
|
2407
2726
|
key: "messages",
|
|
2408
|
-
|
|
2409
|
-
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2727
|
+
transform: anthropicPromptSanitize
|
|
2728
|
+
},
|
|
2729
|
+
temperature: {
|
|
2730
|
+
key: "temperature"
|
|
2731
|
+
},
|
|
2732
|
+
topP: {
|
|
2733
|
+
key: "top_p"
|
|
2734
|
+
},
|
|
2735
|
+
topK: {
|
|
2736
|
+
key: "top_k"
|
|
2737
|
+
},
|
|
2738
|
+
stopSequences: {
|
|
2739
|
+
key: "stop_sequences"
|
|
2740
|
+
},
|
|
2741
|
+
stream: {
|
|
2742
|
+
key: "stream"
|
|
2743
|
+
},
|
|
2744
|
+
metadata: {
|
|
2745
|
+
key: "metadata"
|
|
2746
|
+
},
|
|
2747
|
+
serviceTier: {
|
|
2748
|
+
key: "service_tier"
|
|
2749
|
+
// Map camelCase to snake_case
|
|
2750
|
+
}
|
|
2751
|
+
},
|
|
2752
|
+
mapOptions: {
|
|
2753
|
+
functionCall: (call, _options) => {
|
|
2754
|
+
if (call === "none") return { _clearFunctions: true };
|
|
2755
|
+
if (call === "auto" || call === "any") {
|
|
2756
|
+
return { tool_choice: { type: call } };
|
|
2757
|
+
}
|
|
2758
|
+
return { tool_choice: call };
|
|
2759
|
+
},
|
|
2760
|
+
functions: (functions) => ({
|
|
2761
|
+
tools: functions.map((f) => ({
|
|
2762
|
+
name: f.name,
|
|
2763
|
+
description: f.description,
|
|
2764
|
+
input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
|
|
2765
|
+
}))
|
|
2766
|
+
})
|
|
2767
|
+
},
|
|
2768
|
+
transformResponse: OutputAnthropicClaude3Chat
|
|
2769
|
+
};
|
|
2770
|
+
var anthropic = {
|
|
2771
|
+
"anthropic.chat.v1": anthropicChatV1,
|
|
2772
|
+
// Claude 4.6 models
|
|
2773
|
+
"anthropic.claude-opus-4-6": withDefaultModel(
|
|
2774
|
+
anthropicChatV1,
|
|
2775
|
+
"claude-opus-4-6"
|
|
2776
|
+
),
|
|
2777
|
+
"anthropic.claude-sonnet-4-6": withDefaultModel(
|
|
2778
|
+
anthropicChatV1,
|
|
2779
|
+
"claude-sonnet-4-6"
|
|
2780
|
+
),
|
|
2781
|
+
// Claude 4 models
|
|
2782
|
+
"anthropic.claude-sonnet-4": withDefaultModel(
|
|
2419
2783
|
anthropicChatV1,
|
|
2420
2784
|
"claude-sonnet-4-0"
|
|
2421
2785
|
),
|
|
2786
|
+
"anthropic.claude-opus-4": withDefaultModel(
|
|
2787
|
+
anthropicChatV1,
|
|
2788
|
+
"claude-opus-4-0"
|
|
2789
|
+
),
|
|
2422
2790
|
"anthropic.claude-3-7-sonnet": withDefaultModel(
|
|
2423
2791
|
anthropicChatV1,
|
|
2424
|
-
"claude-3-7-sonnet-
|
|
2792
|
+
"claude-3-7-sonnet-20250219"
|
|
2425
2793
|
),
|
|
2794
|
+
// Claude 3.5 models
|
|
2426
2795
|
"anthropic.claude-3-5-sonnet": withDefaultModel(
|
|
2427
2796
|
anthropicChatV1,
|
|
2428
2797
|
"claude-3-5-sonnet-latest"
|
|
@@ -2434,49 +2803,102 @@ var anthropic = {
|
|
|
2434
2803
|
// Deprecated
|
|
2435
2804
|
"anthropic.claude-3-opus": withDefaultModel(
|
|
2436
2805
|
anthropicChatV1,
|
|
2437
|
-
"claude-3-opus-
|
|
2806
|
+
"claude-3-opus-20240229"
|
|
2807
|
+
),
|
|
2808
|
+
"anthropic.claude-3-haiku": withDefaultModel(
|
|
2809
|
+
anthropicChatV1,
|
|
2810
|
+
"claude-3-haiku-20240307"
|
|
2438
2811
|
)
|
|
2439
2812
|
};
|
|
2440
2813
|
|
|
2441
2814
|
// src/llm/config/x/index.ts
|
|
2442
|
-
var xaiChatV1 = {
|
|
2815
|
+
var xaiChatV1 = createOpenAiCompatibleConfiguration({
|
|
2443
2816
|
key: "xai.chat.v1",
|
|
2444
2817
|
provider: "xai.chat",
|
|
2445
2818
|
endpoint: `https://api.x.ai/v1/chat/completions`,
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
topP: {},
|
|
2449
|
-
useJson: {},
|
|
2450
|
-
xAiApiKey: {
|
|
2451
|
-
default: getEnvironmentVariable("XAI_API_KEY")
|
|
2452
|
-
}
|
|
2453
|
-
},
|
|
2454
|
-
method: "POST",
|
|
2455
|
-
headers: `{"Authorization":"Bearer {{xAiApiKey}}", "Content-Type": "application/json" }`,
|
|
2456
|
-
mapBody: {
|
|
2457
|
-
prompt: {
|
|
2458
|
-
key: "messages",
|
|
2459
|
-
sanitize: openaiPromptSanitize
|
|
2460
|
-
},
|
|
2461
|
-
model: {
|
|
2462
|
-
key: "model"
|
|
2463
|
-
},
|
|
2464
|
-
topP: {
|
|
2465
|
-
key: "top_p"
|
|
2466
|
-
},
|
|
2467
|
-
useJson: {
|
|
2468
|
-
key: "response_format.type",
|
|
2469
|
-
sanitize: (v) => v ? "json_object" : "text"
|
|
2470
|
-
}
|
|
2471
|
-
}
|
|
2472
|
-
};
|
|
2819
|
+
apiKeyMapping: ["xAiApiKey", "XAI_API_KEY"]
|
|
2820
|
+
});
|
|
2473
2821
|
var xai = {
|
|
2474
2822
|
"xai.chat.v1": xaiChatV1,
|
|
2475
2823
|
"xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest"),
|
|
2476
2824
|
"xai.grok-3": withDefaultModel(xaiChatV1, "grok-3"),
|
|
2477
|
-
"xai.grok-
|
|
2825
|
+
"xai.grok-3-mini": withDefaultModel(xaiChatV1, "grok-3-mini"),
|
|
2826
|
+
"xai.grok-4": withDefaultModel(xaiChatV1, "grok-4"),
|
|
2827
|
+
"xai.grok-4-fast": withDefaultModel(xaiChatV1, "grok-4-fast-non-reasoning")
|
|
2478
2828
|
};
|
|
2479
2829
|
|
|
2830
|
+
// src/llm/output/_utils/combineJsonl.ts
|
|
2831
|
+
function combineJsonl(jsonl) {
|
|
2832
|
+
const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
2833
|
+
try {
|
|
2834
|
+
return JSON.parse(line);
|
|
2835
|
+
} catch (e) {
|
|
2836
|
+
throw new Error(`Invalid JSON: ${line}`);
|
|
2837
|
+
}
|
|
2838
|
+
});
|
|
2839
|
+
if (lines.length === 0) {
|
|
2840
|
+
throw new Error("No JSON lines provided.");
|
|
2841
|
+
}
|
|
2842
|
+
lines.sort(
|
|
2843
|
+
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
|
|
2844
|
+
);
|
|
2845
|
+
let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
|
|
2846
|
+
combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
|
|
2847
|
+
const finalLine = lines.find((line) => line.done === true);
|
|
2848
|
+
if (!finalLine) {
|
|
2849
|
+
throw new Error("No line found where done = true.");
|
|
2850
|
+
}
|
|
2851
|
+
const result = {
|
|
2852
|
+
model: finalLine.model,
|
|
2853
|
+
created_at: finalLine.created_at,
|
|
2854
|
+
message: {
|
|
2855
|
+
role: finalLine?.message?.role || "assistant",
|
|
2856
|
+
content: combinedContent
|
|
2857
|
+
},
|
|
2858
|
+
done_reason: finalLine.done_reason,
|
|
2859
|
+
done: finalLine.done,
|
|
2860
|
+
total_duration: finalLine.total_duration,
|
|
2861
|
+
load_duration: finalLine.load_duration,
|
|
2862
|
+
prompt_eval_count: finalLine.prompt_eval_count,
|
|
2863
|
+
prompt_eval_duration: finalLine.prompt_eval_duration,
|
|
2864
|
+
eval_count: finalLine.eval_count,
|
|
2865
|
+
eval_duration: finalLine.eval_duration
|
|
2866
|
+
};
|
|
2867
|
+
const content = {
|
|
2868
|
+
type: "text",
|
|
2869
|
+
text: combinedContent
|
|
2870
|
+
};
|
|
2871
|
+
return {
|
|
2872
|
+
lines,
|
|
2873
|
+
result,
|
|
2874
|
+
content
|
|
2875
|
+
};
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
// src/llm/output/ollama.ts
|
|
2879
|
+
function OutputOllamaChat(result, _config) {
|
|
2880
|
+
const combined = combineJsonl(result);
|
|
2881
|
+
const id = `${combined.result.model}.${combined.result.created_at}`;
|
|
2882
|
+
const name = combined.result.model || _config?.options.model?.default || "ollama.unknown";
|
|
2883
|
+
const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
|
|
2884
|
+
const stopReason = `${combined?.result?.done_reason || "stop"}`;
|
|
2885
|
+
const content = [combined.content];
|
|
2886
|
+
const usage = {
|
|
2887
|
+
output_tokens: 0,
|
|
2888
|
+
input_tokens: 0,
|
|
2889
|
+
total_tokens: 0
|
|
2890
|
+
};
|
|
2891
|
+
return {
|
|
2892
|
+
id,
|
|
2893
|
+
name,
|
|
2894
|
+
created,
|
|
2895
|
+
usage,
|
|
2896
|
+
stopReason,
|
|
2897
|
+
content,
|
|
2898
|
+
options: []
|
|
2899
|
+
};
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2480
2902
|
// src/llm/config/ollama/index.ts
|
|
2481
2903
|
var ollamaChatV1 = {
|
|
2482
2904
|
key: "ollama.chat.v1",
|
|
@@ -2490,7 +2912,7 @@ var ollamaChatV1 = {
|
|
|
2490
2912
|
mapBody: {
|
|
2491
2913
|
prompt: {
|
|
2492
2914
|
key: "messages",
|
|
2493
|
-
|
|
2915
|
+
transform: (v) => {
|
|
2494
2916
|
if (typeof v === "string") {
|
|
2495
2917
|
return [{ role: "user", content: v }];
|
|
2496
2918
|
}
|
|
@@ -2500,7 +2922,8 @@ var ollamaChatV1 = {
|
|
|
2500
2922
|
model: {
|
|
2501
2923
|
key: "model"
|
|
2502
2924
|
}
|
|
2503
|
-
}
|
|
2925
|
+
},
|
|
2926
|
+
transformResponse: OutputOllamaChat
|
|
2504
2927
|
};
|
|
2505
2928
|
var ollama = {
|
|
2506
2929
|
"ollama.chat.v1": ollamaChatV1,
|
|
@@ -2522,7 +2945,7 @@ function googleGeminiPromptMessageCallback(_message) {
|
|
|
2522
2945
|
message.role = "model";
|
|
2523
2946
|
}
|
|
2524
2947
|
let { role, ...payload } = message;
|
|
2525
|
-
if (typeof payload.content === "string") {
|
|
2948
|
+
if (typeof payload.content === "string" && message.role !== "function") {
|
|
2526
2949
|
parts.push({ text: message.content });
|
|
2527
2950
|
}
|
|
2528
2951
|
if (message.role === "function") {
|
|
@@ -2545,487 +2968,75 @@ function googleGeminiPromptMessageCallback(_message) {
|
|
|
2545
2968
|
...toolsArr.map((call) => {
|
|
2546
2969
|
const { name, arguments: input } = call;
|
|
2547
2970
|
return {
|
|
2548
|
-
functionCall: {
|
|
2549
|
-
name,
|
|
2550
|
-
args: maybeParseJSON(input)
|
|
2551
|
-
}
|
|
2552
|
-
};
|
|
2553
|
-
})
|
|
2554
|
-
);
|
|
2555
|
-
delete message.function_call;
|
|
2556
|
-
}
|
|
2557
|
-
return {
|
|
2558
|
-
role,
|
|
2559
|
-
parts
|
|
2560
|
-
};
|
|
2561
|
-
}
|
|
2562
|
-
|
|
2563
|
-
// src/llm/config/google/promptSanitize.ts
|
|
2564
|
-
function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
2565
|
-
if (typeof _messages === "string") {
|
|
2566
|
-
return [{ role: "user", parts: [{ text: _messages }] }];
|
|
2567
|
-
}
|
|
2568
|
-
if (Array.isArray(_messages)) {
|
|
2569
|
-
if (_messages.length === 0) {
|
|
2570
|
-
throw new Error("Empty messages array");
|
|
2571
|
-
}
|
|
2572
|
-
if (_messages.length === 1 && _messages[0].role === "system") {
|
|
2573
|
-
return [{ role: "user", parts: [{ text: _messages[0].content }] }];
|
|
2574
|
-
}
|
|
2575
|
-
const hasSystemInstruction = _messages.some(
|
|
2576
|
-
(message) => message.role === "system"
|
|
2577
|
-
);
|
|
2578
|
-
if (hasSystemInstruction) {
|
|
2579
|
-
const theSystemInstructions = _messages.filter(
|
|
2580
|
-
(message) => message.role === "system"
|
|
2581
|
-
);
|
|
2582
|
-
const withoutSystemInstructions = _messages.filter(
|
|
2583
|
-
(message) => message.role !== "system"
|
|
2584
|
-
);
|
|
2585
|
-
_outputObj.system_instruction = {
|
|
2586
|
-
parts: theSystemInstructions.map((message) => ({
|
|
2587
|
-
text: message.content
|
|
2588
|
-
}))
|
|
2589
|
-
};
|
|
2590
|
-
return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
|
|
2591
|
-
}
|
|
2592
|
-
return _messages.map(googleGeminiPromptMessageCallback);
|
|
2593
|
-
}
|
|
2594
|
-
throw new Error("Invalid messages format");
|
|
2595
|
-
}
|
|
2596
|
-
|
|
2597
|
-
// src/llm/config/google/index.ts
|
|
2598
|
-
var googleGeminiChatV1 = {
|
|
2599
|
-
key: "google.chat.v1",
|
|
2600
|
-
provider: "google.chat",
|
|
2601
|
-
endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
|
|
2602
|
-
options: {
|
|
2603
|
-
prompt: {},
|
|
2604
|
-
// topP: {},
|
|
2605
|
-
geminiApiKey: {
|
|
2606
|
-
default: getEnvironmentVariable("GEMINI_API_KEY")
|
|
2607
|
-
}
|
|
2608
|
-
},
|
|
2609
|
-
method: "POST",
|
|
2610
|
-
headers: `{"Content-Type": "application/json" }`,
|
|
2611
|
-
mapBody: {
|
|
2612
|
-
prompt: {
|
|
2613
|
-
key: "contents",
|
|
2614
|
-
sanitize: googleGeminiPromptSanitize
|
|
2615
|
-
}
|
|
2616
|
-
// topP: {
|
|
2617
|
-
// key: "top_p",
|
|
2618
|
-
// }
|
|
2619
|
-
}
|
|
2620
|
-
};
|
|
2621
|
-
var google = {
|
|
2622
|
-
"google.chat.v1": googleGeminiChatV1,
|
|
2623
|
-
"google.gemini-2.0-flash": withDefaultModel(
|
|
2624
|
-
googleGeminiChatV1,
|
|
2625
|
-
"gemini-2.0-flash"
|
|
2626
|
-
),
|
|
2627
|
-
"google.gemini-2.0-flash-lite": withDefaultModel(
|
|
2628
|
-
googleGeminiChatV1,
|
|
2629
|
-
"gemini-2.0-flash-lite"
|
|
2630
|
-
),
|
|
2631
|
-
"google.gemini-2.5-flash": withDefaultModel(
|
|
2632
|
-
googleGeminiChatV1,
|
|
2633
|
-
"gemini-2.5-flash"
|
|
2634
|
-
),
|
|
2635
|
-
"google.gemini-2.5-flash-lite": withDefaultModel(
|
|
2636
|
-
googleGeminiChatV1,
|
|
2637
|
-
"gemini-2.5-flash-lite"
|
|
2638
|
-
),
|
|
2639
|
-
"google.gemini-1.5-pro": withDefaultModel(
|
|
2640
|
-
googleGeminiChatV1,
|
|
2641
|
-
"gemini-1.5-pro"
|
|
2642
|
-
),
|
|
2643
|
-
"google.gemini-2.5-pro": withDefaultModel(
|
|
2644
|
-
googleGeminiChatV1,
|
|
2645
|
-
"gemini-2.5-pro"
|
|
2646
|
-
)
|
|
2647
|
-
};
|
|
2648
|
-
|
|
2649
|
-
// src/llm/config/deepseek/index.ts
|
|
2650
|
-
var deepseekChatV1 = {
|
|
2651
|
-
key: "deepseek.chat.v1",
|
|
2652
|
-
provider: "deepseek.chat",
|
|
2653
|
-
endpoint: `https://api.deepseek.com/v1/chat/completions`,
|
|
2654
|
-
options: {
|
|
2655
|
-
prompt: {},
|
|
2656
|
-
topP: {},
|
|
2657
|
-
useJson: {},
|
|
2658
|
-
deepseekApiKey: {
|
|
2659
|
-
default: getEnvironmentVariable("DEEPSEEK_API_KEY")
|
|
2660
|
-
}
|
|
2661
|
-
},
|
|
2662
|
-
method: "POST",
|
|
2663
|
-
headers: `{"Authorization":"Bearer {{deepseekApiKey}}", "Content-Type": "application/json" }`,
|
|
2664
|
-
mapBody: {
|
|
2665
|
-
prompt: {
|
|
2666
|
-
key: "messages",
|
|
2667
|
-
sanitize: openaiPromptSanitize
|
|
2668
|
-
},
|
|
2669
|
-
model: {
|
|
2670
|
-
key: "model"
|
|
2671
|
-
},
|
|
2672
|
-
topP: {
|
|
2673
|
-
key: "top_p"
|
|
2674
|
-
},
|
|
2675
|
-
useJson: {
|
|
2676
|
-
key: "response_format.type",
|
|
2677
|
-
sanitize: (v) => v ? "json_object" : "text"
|
|
2678
|
-
}
|
|
2679
|
-
}
|
|
2680
|
-
};
|
|
2681
|
-
var deepseek = {
|
|
2682
|
-
"deepseek.chat.v1": deepseekChatV1,
|
|
2683
|
-
"deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
|
|
2684
|
-
};
|
|
2685
|
-
|
|
2686
|
-
// src/llm/config.ts
|
|
2687
|
-
var configs = {
|
|
2688
|
-
...openai,
|
|
2689
|
-
...anthropic,
|
|
2690
|
-
...bedrock,
|
|
2691
|
-
...xai,
|
|
2692
|
-
...ollama,
|
|
2693
|
-
...google,
|
|
2694
|
-
...deepseek
|
|
2695
|
-
};
|
|
2696
|
-
function getLlmConfig(provider) {
|
|
2697
|
-
if (!provider) {
|
|
2698
|
-
throw new LlmExeError(`Missing provider`, "unknown", {
|
|
2699
|
-
error: "Missing provider",
|
|
2700
|
-
resolution: "Provide a valid provider"
|
|
2701
|
-
});
|
|
2702
|
-
}
|
|
2703
|
-
const pick2 = configs[provider];
|
|
2704
|
-
if (pick2) {
|
|
2705
|
-
return pick2;
|
|
2706
|
-
}
|
|
2707
|
-
throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
|
|
2708
|
-
provider,
|
|
2709
|
-
error: `Invalid provider: ${provider}`,
|
|
2710
|
-
resolution: "Provide a valid provider"
|
|
2711
|
-
});
|
|
2712
|
-
}
|
|
2713
|
-
|
|
2714
|
-
// src/llm/output/_utils/getResultContent.ts
|
|
2715
|
-
function getResultContent(result, index) {
|
|
2716
|
-
if (typeof index === "number" && index > 0) {
|
|
2717
|
-
const arr = result?.options || [];
|
|
2718
|
-
const val = arr[index];
|
|
2719
|
-
return val ? val : [];
|
|
2720
|
-
}
|
|
2721
|
-
return [...result.content];
|
|
2722
|
-
}
|
|
2723
|
-
|
|
2724
|
-
// src/llm/output/_utils/getResultText.ts
|
|
2725
|
-
function getResultText(result, index) {
|
|
2726
|
-
if (typeof index === "number" && index > 0) {
|
|
2727
|
-
const arr = result?.options || [];
|
|
2728
|
-
const val = arr[index];
|
|
2729
|
-
return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
|
|
2730
|
-
}
|
|
2731
|
-
return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
|
|
2732
|
-
}
|
|
2733
|
-
|
|
2734
|
-
// src/llm/output/base.ts
|
|
2735
|
-
function BaseLlmOutput2(result) {
|
|
2736
|
-
const __result = Object.freeze({
|
|
2737
|
-
id: result.id || (0, import_uuid.v4)(),
|
|
2738
|
-
name: result.name,
|
|
2739
|
-
usage: result.usage,
|
|
2740
|
-
stopReason: result.stopReason,
|
|
2741
|
-
options: [...result?.options || []],
|
|
2742
|
-
content: [...result.content],
|
|
2743
|
-
created: result?.created || (/* @__PURE__ */ new Date()).getTime()
|
|
2744
|
-
});
|
|
2745
|
-
function getResult() {
|
|
2746
|
-
return {
|
|
2747
|
-
id: __result.id,
|
|
2748
|
-
name: __result.name,
|
|
2749
|
-
created: __result.created,
|
|
2750
|
-
usage: __result.usage,
|
|
2751
|
-
options: __result.options,
|
|
2752
|
-
content: __result.content,
|
|
2753
|
-
stopReason: __result.stopReason
|
|
2754
|
-
};
|
|
2755
|
-
}
|
|
2756
|
-
return {
|
|
2757
|
-
getResultContent: (index) => getResultContent(__result, index),
|
|
2758
|
-
getResultText: (index) => getResultText(__result, index),
|
|
2759
|
-
getResult
|
|
2760
|
-
};
|
|
2761
|
-
}
|
|
2762
|
-
|
|
2763
|
-
// src/llm/output/_util.ts
|
|
2764
|
-
function normalizeFunctionCall(input, provider) {
|
|
2765
|
-
if (input === "any") {
|
|
2766
|
-
if (provider === "openai") {
|
|
2767
|
-
return "required";
|
|
2768
|
-
}
|
|
2769
|
-
}
|
|
2770
|
-
return input;
|
|
2771
|
-
}
|
|
2772
|
-
function formatOptions(response, handler) {
|
|
2773
|
-
const out = [];
|
|
2774
|
-
for (const item of response) {
|
|
2775
|
-
const result = handler(item);
|
|
2776
|
-
if (result) {
|
|
2777
|
-
out.push([result]);
|
|
2778
|
-
}
|
|
2779
|
-
}
|
|
2780
|
-
return out;
|
|
2781
|
-
}
|
|
2782
|
-
|
|
2783
|
-
// src/llm/output/openai.ts
|
|
2784
|
-
function formatResult(result) {
|
|
2785
|
-
const out = [];
|
|
2786
|
-
if (typeof result?.message?.content === "string") {
|
|
2787
|
-
out.push({
|
|
2788
|
-
type: "text",
|
|
2789
|
-
text: result.message.content
|
|
2790
|
-
});
|
|
2791
|
-
}
|
|
2792
|
-
if (result?.message?.tool_calls) {
|
|
2793
|
-
for (const call of result.message.tool_calls) {
|
|
2794
|
-
out.push({
|
|
2795
|
-
functionId: call.id,
|
|
2796
|
-
type: "function_use",
|
|
2797
|
-
name: call.function.name,
|
|
2798
|
-
input: maybeParseJSON(call.function.arguments)
|
|
2799
|
-
});
|
|
2800
|
-
}
|
|
2801
|
-
}
|
|
2802
|
-
return out;
|
|
2803
|
-
}
|
|
2804
|
-
function OutputOpenAIChat(result, _config) {
|
|
2805
|
-
const id = result.id;
|
|
2806
|
-
const name = result.model || _config?.model || "openai.unknown";
|
|
2807
|
-
const created = result.created;
|
|
2808
|
-
const [_content, ..._options] = result?.choices || [];
|
|
2809
|
-
const stopReason = _content?.finish_reason;
|
|
2810
|
-
const content = formatResult(_content);
|
|
2811
|
-
const options = formatOptions(_options, formatResult);
|
|
2812
|
-
const usage = {
|
|
2813
|
-
output_tokens: result?.usage?.completion_tokens,
|
|
2814
|
-
input_tokens: result?.usage?.prompt_tokens,
|
|
2815
|
-
total_tokens: result?.usage?.total_tokens
|
|
2816
|
-
};
|
|
2817
|
-
return BaseLlmOutput2({
|
|
2818
|
-
id,
|
|
2819
|
-
name,
|
|
2820
|
-
created,
|
|
2821
|
-
usage,
|
|
2822
|
-
stopReason,
|
|
2823
|
-
content,
|
|
2824
|
-
options
|
|
2825
|
-
});
|
|
2826
|
-
}
|
|
2827
|
-
|
|
2828
|
-
// src/llm/output/claude.ts
|
|
2829
|
-
function formatResult2(response) {
|
|
2830
|
-
const content = response?.content || [];
|
|
2831
|
-
const out = [];
|
|
2832
|
-
for (let i = 0; i < content.length; i++) {
|
|
2833
|
-
const result = content[i];
|
|
2834
|
-
if (result.type === "text") {
|
|
2835
|
-
out.push({
|
|
2836
|
-
type: "text",
|
|
2837
|
-
text: result.text
|
|
2838
|
-
});
|
|
2839
|
-
} else if (result.type === "tool_use") {
|
|
2840
|
-
out.push({
|
|
2841
|
-
functionId: result.id,
|
|
2842
|
-
type: "function_use",
|
|
2843
|
-
name: result.name,
|
|
2844
|
-
input: result.input
|
|
2845
|
-
});
|
|
2846
|
-
}
|
|
2847
|
-
}
|
|
2848
|
-
return out;
|
|
2849
|
-
}
|
|
2850
|
-
function OutputAnthropicClaude3Chat(result, _config) {
|
|
2851
|
-
const id = result.id;
|
|
2852
|
-
const name = result.model || _config?.model || "anthropic.unknown";
|
|
2853
|
-
const stopReason = result.stop_reason;
|
|
2854
|
-
const content = formatResult2(result);
|
|
2855
|
-
const usage = {
|
|
2856
|
-
input_tokens: result?.usage?.input_tokens,
|
|
2857
|
-
output_tokens: result?.usage?.output_tokens,
|
|
2858
|
-
total_tokens: result?.usage?.input_tokens + result?.usage?.input_tokens
|
|
2859
|
-
};
|
|
2860
|
-
return BaseLlmOutput2({
|
|
2861
|
-
id,
|
|
2862
|
-
name,
|
|
2863
|
-
usage,
|
|
2864
|
-
stopReason,
|
|
2865
|
-
content
|
|
2866
|
-
});
|
|
2867
|
-
}
|
|
2868
|
-
|
|
2869
|
-
// src/llm/output/llama.ts
|
|
2870
|
-
function OutputMetaLlama3Chat(result, _config) {
|
|
2871
|
-
const name = _config?.model || "meta";
|
|
2872
|
-
const stopReason = result.stop_reason;
|
|
2873
|
-
const content = [
|
|
2874
|
-
{ type: "text", text: result.generation }
|
|
2875
|
-
];
|
|
2876
|
-
const usage = {
|
|
2877
|
-
output_tokens: result?.generation_token_count,
|
|
2878
|
-
input_tokens: result?.prompt_token_count,
|
|
2879
|
-
total_tokens: result?.generation_token_count + result?.prompt_token_count
|
|
2880
|
-
};
|
|
2881
|
-
return BaseLlmOutput2({
|
|
2882
|
-
name,
|
|
2883
|
-
usage,
|
|
2884
|
-
stopReason,
|
|
2885
|
-
content
|
|
2886
|
-
});
|
|
2887
|
-
}
|
|
2888
|
-
|
|
2889
|
-
// src/llm/output/default.ts
|
|
2890
|
-
function OutputDefault(result, _config) {
|
|
2891
|
-
const name = _config.model || "unknown";
|
|
2892
|
-
const stopReason = result?.stopReason || "stop";
|
|
2893
|
-
const content = [];
|
|
2894
|
-
if (result?.text) {
|
|
2895
|
-
content.push({ type: "text", text: result.text });
|
|
2896
|
-
}
|
|
2897
|
-
const usage = {
|
|
2898
|
-
output_tokens: result?.output_tokens || 0,
|
|
2899
|
-
input_tokens: result?.input_tokens || 0,
|
|
2900
|
-
total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
|
|
2901
|
-
};
|
|
2902
|
-
return BaseLlmOutput2({
|
|
2903
|
-
name,
|
|
2904
|
-
usage,
|
|
2905
|
-
stopReason,
|
|
2906
|
-
content
|
|
2907
|
-
});
|
|
2908
|
-
}
|
|
2909
|
-
|
|
2910
|
-
// src/llm/output/xai.ts
|
|
2911
|
-
function formatResult3(result) {
|
|
2912
|
-
const out = [];
|
|
2913
|
-
if (typeof result?.message?.content === "string") {
|
|
2914
|
-
out.push({
|
|
2915
|
-
type: "text",
|
|
2916
|
-
text: result.message.content
|
|
2917
|
-
});
|
|
2918
|
-
}
|
|
2919
|
-
if (result?.message?.tool_calls) {
|
|
2920
|
-
for (const call of result.message.tool_calls) {
|
|
2921
|
-
out.push({
|
|
2922
|
-
functionId: call.id,
|
|
2923
|
-
type: "function_use",
|
|
2924
|
-
name: call.function.name,
|
|
2925
|
-
input: maybeParseJSON(call.function.arguments)
|
|
2926
|
-
});
|
|
2927
|
-
}
|
|
2928
|
-
}
|
|
2929
|
-
return out;
|
|
2930
|
-
}
|
|
2931
|
-
function OutputXAIChat(result, _config) {
|
|
2932
|
-
const id = result.id;
|
|
2933
|
-
const name = result.model || _config?.model || "openai.unknown";
|
|
2934
|
-
const created = result.created;
|
|
2935
|
-
const [_content, ..._options] = result?.choices || [];
|
|
2936
|
-
const stopReason = _content?.finish_reason;
|
|
2937
|
-
const content = formatResult3(_content);
|
|
2938
|
-
const options = formatOptions(_options, formatResult3);
|
|
2939
|
-
const usage = {
|
|
2940
|
-
output_tokens: result?.usage?.completion_tokens,
|
|
2941
|
-
input_tokens: result?.usage?.prompt_tokens,
|
|
2942
|
-
total_tokens: result?.usage?.total_tokens
|
|
2943
|
-
};
|
|
2944
|
-
return BaseLlmOutput2({
|
|
2945
|
-
id,
|
|
2946
|
-
name,
|
|
2947
|
-
created,
|
|
2948
|
-
usage,
|
|
2949
|
-
stopReason,
|
|
2950
|
-
content,
|
|
2951
|
-
options
|
|
2952
|
-
});
|
|
2953
|
-
}
|
|
2954
|
-
|
|
2955
|
-
// src/llm/output/_utils/combineJsonl.ts
|
|
2956
|
-
function combineJsonl(jsonl) {
|
|
2957
|
-
const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
2958
|
-
try {
|
|
2959
|
-
return JSON.parse(line);
|
|
2960
|
-
} catch (e) {
|
|
2961
|
-
throw new Error(`Invalid JSON: ${line}`);
|
|
2962
|
-
}
|
|
2963
|
-
});
|
|
2964
|
-
if (lines.length === 0) {
|
|
2965
|
-
throw new Error("No JSON lines provided.");
|
|
2966
|
-
}
|
|
2967
|
-
lines.sort(
|
|
2968
|
-
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
|
|
2969
|
-
);
|
|
2970
|
-
let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
|
|
2971
|
-
combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
|
|
2972
|
-
const finalLine = lines.find((line) => line.done === true);
|
|
2973
|
-
if (!finalLine) {
|
|
2974
|
-
throw new Error("No line found where done = true.");
|
|
2975
|
-
}
|
|
2976
|
-
const result = {
|
|
2977
|
-
model: finalLine.model,
|
|
2978
|
-
created_at: finalLine.created_at,
|
|
2979
|
-
message: {
|
|
2980
|
-
role: finalLine?.message?.role || "assistant",
|
|
2981
|
-
content: combinedContent
|
|
2982
|
-
},
|
|
2983
|
-
done_reason: finalLine.done_reason,
|
|
2984
|
-
done: finalLine.done,
|
|
2985
|
-
total_duration: finalLine.total_duration,
|
|
2986
|
-
load_duration: finalLine.load_duration,
|
|
2987
|
-
prompt_eval_count: finalLine.prompt_eval_count,
|
|
2988
|
-
prompt_eval_duration: finalLine.prompt_eval_duration,
|
|
2989
|
-
eval_count: finalLine.eval_count,
|
|
2990
|
-
eval_duration: finalLine.eval_duration
|
|
2991
|
-
};
|
|
2992
|
-
const content = {
|
|
2993
|
-
type: "text",
|
|
2994
|
-
text: combinedContent
|
|
2995
|
-
};
|
|
2971
|
+
functionCall: {
|
|
2972
|
+
name,
|
|
2973
|
+
args: maybeParseJSON(input)
|
|
2974
|
+
}
|
|
2975
|
+
};
|
|
2976
|
+
})
|
|
2977
|
+
);
|
|
2978
|
+
delete message.function_call;
|
|
2979
|
+
}
|
|
2996
2980
|
return {
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
content
|
|
2981
|
+
role,
|
|
2982
|
+
parts
|
|
3000
2983
|
};
|
|
3001
2984
|
}
|
|
3002
2985
|
|
|
3003
|
-
// src/llm/
|
|
3004
|
-
function
|
|
3005
|
-
|
|
3006
|
-
const
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
}
|
|
3016
|
-
return
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
2986
|
+
// src/llm/config/google/promptSanitize.ts
|
|
2987
|
+
function mergeConsecutiveSameRole2(messages) {
|
|
2988
|
+
if (messages.length <= 1) return messages;
|
|
2989
|
+
const merged = [messages[0]];
|
|
2990
|
+
for (let i = 1; i < messages.length; i++) {
|
|
2991
|
+
const prev = merged[merged.length - 1];
|
|
2992
|
+
const curr = messages[i];
|
|
2993
|
+
if (curr.role === prev.role && Array.isArray(prev.parts) && Array.isArray(curr.parts)) {
|
|
2994
|
+
prev.parts = [...prev.parts, ...curr.parts];
|
|
2995
|
+
} else {
|
|
2996
|
+
merged.push(curr);
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
return merged;
|
|
3000
|
+
}
|
|
3001
|
+
function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
3002
|
+
if (typeof _messages === "string") {
|
|
3003
|
+
return [{ role: "user", parts: [{ text: _messages }] }];
|
|
3004
|
+
}
|
|
3005
|
+
if (Array.isArray(_messages)) {
|
|
3006
|
+
if (_messages.length === 0) {
|
|
3007
|
+
throw new Error("Empty messages array");
|
|
3008
|
+
}
|
|
3009
|
+
if (_messages.length === 1 && _messages[0].role === "system") {
|
|
3010
|
+
return [{ role: "user", parts: [{ text: _messages[0].content }] }];
|
|
3011
|
+
}
|
|
3012
|
+
const hasSystemInstruction = _messages.some(
|
|
3013
|
+
(message) => message.role === "system"
|
|
3014
|
+
);
|
|
3015
|
+
if (hasSystemInstruction) {
|
|
3016
|
+
const theSystemInstructions = _messages.filter(
|
|
3017
|
+
(message) => message.role === "system"
|
|
3018
|
+
);
|
|
3019
|
+
const withoutSystemInstructions = _messages.filter(
|
|
3020
|
+
(message) => message.role !== "system"
|
|
3021
|
+
);
|
|
3022
|
+
_outputObj.system_instruction = {
|
|
3023
|
+
parts: theSystemInstructions.map((message) => ({
|
|
3024
|
+
text: message.content
|
|
3025
|
+
}))
|
|
3026
|
+
};
|
|
3027
|
+
const result2 = withoutSystemInstructions.map(
|
|
3028
|
+
googleGeminiPromptMessageCallback
|
|
3029
|
+
);
|
|
3030
|
+
return mergeConsecutiveSameRole2(result2);
|
|
3031
|
+
}
|
|
3032
|
+
const result = _messages.map(googleGeminiPromptMessageCallback);
|
|
3033
|
+
return mergeConsecutiveSameRole2(result);
|
|
3034
|
+
}
|
|
3035
|
+
throw new Error("Invalid messages format");
|
|
3025
3036
|
}
|
|
3026
3037
|
|
|
3027
3038
|
// src/llm/output/google.gemini/formatResult.ts
|
|
3028
|
-
function
|
|
3039
|
+
function formatResult3(result, id) {
|
|
3029
3040
|
const { parts = [] } = result?.content || {};
|
|
3030
3041
|
const out = [];
|
|
3031
3042
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -3050,18 +3061,18 @@ function formatResult4(result, id) {
|
|
|
3050
3061
|
// src/llm/output/google.gemini/index.ts
|
|
3051
3062
|
function OutputGoogleGeminiChat(result, _config) {
|
|
3052
3063
|
const id = result.responseId;
|
|
3053
|
-
const name = result.modelVersion || _config?.model || "gemini";
|
|
3064
|
+
const name = result.modelVersion || _config?.options.model?.default || "gemini";
|
|
3054
3065
|
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3055
3066
|
const [_content, ..._options] = result?.candidates || [];
|
|
3056
3067
|
const stopReason = _content?.finishReason?.toLowerCase();
|
|
3057
|
-
const content =
|
|
3058
|
-
const options = formatOptions(_options,
|
|
3068
|
+
const content = formatResult3(_content, id);
|
|
3069
|
+
const options = formatOptions(_options, formatResult3);
|
|
3059
3070
|
const usage = {
|
|
3060
3071
|
output_tokens: result?.usageMetadata?.candidatesTokenCount,
|
|
3061
3072
|
input_tokens: result?.usageMetadata?.promptTokenCount,
|
|
3062
3073
|
total_tokens: result?.usageMetadata?.totalTokenCount
|
|
3063
3074
|
};
|
|
3064
|
-
return
|
|
3075
|
+
return {
|
|
3065
3076
|
id,
|
|
3066
3077
|
name,
|
|
3067
3078
|
created,
|
|
@@ -3069,83 +3080,152 @@ function OutputGoogleGeminiChat(result, _config) {
|
|
|
3069
3080
|
stopReason,
|
|
3070
3081
|
content,
|
|
3071
3082
|
options
|
|
3072
|
-
}
|
|
3083
|
+
};
|
|
3073
3084
|
}
|
|
3074
3085
|
|
|
3075
|
-
// src/llm/
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3086
|
+
// src/llm/config/google/index.ts
|
|
3087
|
+
var googleGeminiChatV1 = {
|
|
3088
|
+
key: "google.chat.v1",
|
|
3089
|
+
provider: "google.chat",
|
|
3090
|
+
endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
|
|
3091
|
+
options: {
|
|
3092
|
+
effort: {},
|
|
3093
|
+
prompt: {},
|
|
3094
|
+
// topP: {},
|
|
3095
|
+
geminiApiKey: {
|
|
3096
|
+
default: getEnvironmentVariable("GEMINI_API_KEY")
|
|
3097
|
+
}
|
|
3098
|
+
},
|
|
3099
|
+
method: "POST",
|
|
3100
|
+
headers: `{"Content-Type": "application/json" }`,
|
|
3101
|
+
mapBody: {
|
|
3102
|
+
prompt: {
|
|
3103
|
+
key: "contents",
|
|
3104
|
+
transform: googleGeminiPromptSanitize
|
|
3105
|
+
},
|
|
3106
|
+
effort: {
|
|
3107
|
+
key: "config.thinkingConfig.thinkingBudget",
|
|
3108
|
+
transform: (v, _s) => {
|
|
3109
|
+
if (
|
|
3110
|
+
// only supported reasoning models
|
|
3111
|
+
["gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-light"].includes(
|
|
3112
|
+
_s.model
|
|
3113
|
+
) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
|
|
3114
|
+
) {
|
|
3115
|
+
if (v === "low" || v === "minimal") {
|
|
3116
|
+
return 1024;
|
|
3117
|
+
} else if (v === "medium") {
|
|
3118
|
+
return 8192;
|
|
3119
|
+
} else if (v === "high") {
|
|
3120
|
+
return 24576;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
return void 0;
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
},
|
|
3127
|
+
mapOptions: {
|
|
3128
|
+
functionCall: (call) => ({
|
|
3129
|
+
toolConfig: {
|
|
3130
|
+
functionCallingConfig: {
|
|
3131
|
+
mode: call === "any" ? "any" : call === "none" ? "none" : "auto"
|
|
3132
|
+
}
|
|
3133
|
+
}
|
|
3134
|
+
}),
|
|
3135
|
+
functions: (functions) => ({
|
|
3136
|
+
tools: [
|
|
3137
|
+
{
|
|
3138
|
+
functionDeclarations: functions.map((f) => ({
|
|
3139
|
+
name: f.name,
|
|
3140
|
+
description: f.description,
|
|
3141
|
+
parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
|
|
3142
|
+
}))
|
|
3143
|
+
}
|
|
3144
|
+
]
|
|
3145
|
+
})
|
|
3146
|
+
},
|
|
3147
|
+
transformResponse: OutputGoogleGeminiChat
|
|
3148
|
+
};
|
|
3149
|
+
var google = {
|
|
3150
|
+
"google.chat.v1": googleGeminiChatV1,
|
|
3151
|
+
"google.gemini-2.0-flash": withDefaultModel(
|
|
3152
|
+
googleGeminiChatV1,
|
|
3153
|
+
"gemini-2.0-flash"
|
|
3154
|
+
),
|
|
3155
|
+
"google.gemini-2.0-flash-lite": withDefaultModel(
|
|
3156
|
+
googleGeminiChatV1,
|
|
3157
|
+
"gemini-2.0-flash-lite"
|
|
3158
|
+
),
|
|
3159
|
+
"google.gemini-2.5-flash": withDefaultModel(
|
|
3160
|
+
googleGeminiChatV1,
|
|
3161
|
+
"gemini-2.5-flash"
|
|
3162
|
+
),
|
|
3163
|
+
"google.gemini-2.5-flash-lite": withDefaultModel(
|
|
3164
|
+
googleGeminiChatV1,
|
|
3165
|
+
"gemini-2.5-flash-lite"
|
|
3166
|
+
),
|
|
3167
|
+
"google.gemini-1.5-pro": withDefaultModel(
|
|
3168
|
+
googleGeminiChatV1,
|
|
3169
|
+
"gemini-1.5-pro"
|
|
3170
|
+
),
|
|
3171
|
+
"google.gemini-2.5-pro": withDefaultModel(
|
|
3172
|
+
googleGeminiChatV1,
|
|
3173
|
+
"gemini-2.5-pro"
|
|
3174
|
+
)
|
|
3175
|
+
};
|
|
3176
|
+
|
|
3177
|
+
// src/llm/config/deepseek/index.ts
|
|
3178
|
+
var deepseekChatV1 = createOpenAiCompatibleConfiguration({
|
|
3179
|
+
key: "deepseek.chat.v1",
|
|
3180
|
+
provider: "deepseek.chat",
|
|
3181
|
+
endpoint: `https://api.deepseek.com/v1/chat/completions`,
|
|
3182
|
+
apiKeyMapping: ["deepseekApiKey", "DEEPSEEK_API_KEY"]
|
|
3183
|
+
});
|
|
3184
|
+
var deepseek = {
|
|
3185
|
+
"deepseek.chat.v1": deepseekChatV1,
|
|
3186
|
+
"deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
|
|
3187
|
+
};
|
|
3188
|
+
|
|
3189
|
+
// src/llm/config.ts
|
|
3190
|
+
var configs = {
|
|
3191
|
+
...openai,
|
|
3192
|
+
...anthropic,
|
|
3193
|
+
...bedrock,
|
|
3194
|
+
...xai,
|
|
3195
|
+
...ollama,
|
|
3196
|
+
...google,
|
|
3197
|
+
...deepseek
|
|
3198
|
+
};
|
|
3199
|
+
function getLlmConfig(provider) {
|
|
3200
|
+
if (!provider) {
|
|
3201
|
+
throw new LlmExeError(`Missing provider`, "unknown", {
|
|
3202
|
+
error: "Missing provider",
|
|
3203
|
+
resolution: "Provide a valid provider"
|
|
3082
3204
|
});
|
|
3083
3205
|
}
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
functionId: call.id,
|
|
3088
|
-
type: "function_use",
|
|
3089
|
-
name: call.function.name,
|
|
3090
|
-
input: maybeParseJSON(call.function.arguments)
|
|
3091
|
-
});
|
|
3092
|
-
}
|
|
3206
|
+
const pick2 = configs[provider];
|
|
3207
|
+
if (pick2) {
|
|
3208
|
+
return pick2;
|
|
3093
3209
|
}
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
const name = result.model || _config?.model || "deepseek.unknown";
|
|
3099
|
-
const created = result.created;
|
|
3100
|
-
const [_content, ..._options] = result?.choices || [];
|
|
3101
|
-
const stopReason = _content?.finish_reason;
|
|
3102
|
-
const content = formatResult5(_content);
|
|
3103
|
-
const options = formatOptions(_options, formatResult5);
|
|
3104
|
-
const usage = {
|
|
3105
|
-
output_tokens: result?.usage?.completion_tokens,
|
|
3106
|
-
input_tokens: result?.usage?.prompt_tokens,
|
|
3107
|
-
total_tokens: result?.usage?.total_tokens
|
|
3108
|
-
};
|
|
3109
|
-
return BaseLlmOutput2({
|
|
3110
|
-
id,
|
|
3111
|
-
name,
|
|
3112
|
-
created,
|
|
3113
|
-
usage,
|
|
3114
|
-
stopReason,
|
|
3115
|
-
content,
|
|
3116
|
-
options
|
|
3210
|
+
throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
|
|
3211
|
+
provider,
|
|
3212
|
+
error: `Invalid provider: ${provider}`,
|
|
3213
|
+
resolution: "Provide a valid provider"
|
|
3117
3214
|
});
|
|
3118
3215
|
}
|
|
3119
3216
|
|
|
3120
|
-
// src/
|
|
3121
|
-
function
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
return OutputMetaLlama3Chat(response, config);
|
|
3131
|
-
// case "amazon:nova.chat.v1":
|
|
3132
|
-
// return OutputDefault(response, config);
|
|
3133
|
-
case "xai.chat.v1":
|
|
3134
|
-
return OutputXAIChat(response, config);
|
|
3135
|
-
case "ollama.chat.v1":
|
|
3136
|
-
return OutputOllamaChat(response, config);
|
|
3137
|
-
case "google.chat.v1":
|
|
3138
|
-
return OutputGoogleGeminiChat(response, config);
|
|
3139
|
-
case "deepseek.chat.v1":
|
|
3140
|
-
return OutputDeepSeekChat(response, config);
|
|
3141
|
-
// use oai for now
|
|
3142
|
-
default: {
|
|
3143
|
-
if (config?.key?.startsWith("custom:")) {
|
|
3144
|
-
return OutputDefault(response, config);
|
|
3145
|
-
}
|
|
3146
|
-
throw new Error("Unsupported provider");
|
|
3217
|
+
// src/utils/modules/maskApiKeysInDebug.ts
|
|
3218
|
+
function maskApiKeys(log) {
|
|
3219
|
+
return log.replace(
|
|
3220
|
+
/\b(Bearer\s+[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+|Bearer\s+[A-Za-z0-9\-_]{20,}|sk-[A-Za-z0-9]{20,}|AKIA[A-Z0-9]{16}|[A-Za-z0-9]{32,})\b/g,
|
|
3221
|
+
(match) => {
|
|
3222
|
+
if (match.length <= 8) return match;
|
|
3223
|
+
const prefix = match.substring(0, 4);
|
|
3224
|
+
const suffix = match.substring(match.length - 4);
|
|
3225
|
+
const maskLength = match.length - 8;
|
|
3226
|
+
return `${prefix}${"*".repeat(maskLength)}${suffix}`;
|
|
3147
3227
|
}
|
|
3148
|
-
|
|
3228
|
+
);
|
|
3149
3229
|
}
|
|
3150
3230
|
|
|
3151
3231
|
// src/utils/modules/debug.ts
|
|
@@ -3171,7 +3251,15 @@ function debug(...args) {
|
|
|
3171
3251
|
logs.push(arg.toString());
|
|
3172
3252
|
} else {
|
|
3173
3253
|
try {
|
|
3174
|
-
|
|
3254
|
+
let shouldMask = false;
|
|
3255
|
+
if (arg.headers && arg.headers.Authorization) {
|
|
3256
|
+
shouldMask = true;
|
|
3257
|
+
}
|
|
3258
|
+
let str = JSON.stringify(arg, null, 2);
|
|
3259
|
+
if (shouldMask) {
|
|
3260
|
+
str = maskApiKeys(str);
|
|
3261
|
+
}
|
|
3262
|
+
logs.push(str);
|
|
3175
3263
|
} catch (error) {
|
|
3176
3264
|
console.error("Error parsing object:", error);
|
|
3177
3265
|
}
|
|
@@ -3219,7 +3307,8 @@ async function apiRequest(url, options) {
|
|
|
3219
3307
|
}
|
|
3220
3308
|
throw new Error(message);
|
|
3221
3309
|
}
|
|
3222
|
-
|
|
3310
|
+
const contentType = response.headers.get("content-type");
|
|
3311
|
+
if (contentType?.includes("application/json")) {
|
|
3223
3312
|
const responseData = await response.json();
|
|
3224
3313
|
return responseData;
|
|
3225
3314
|
} else {
|
|
@@ -3236,20 +3325,26 @@ async function apiRequest(url, options) {
|
|
|
3236
3325
|
function convertDotNotation(obj) {
|
|
3237
3326
|
const result = {};
|
|
3238
3327
|
for (const key in obj) {
|
|
3239
|
-
if (
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3328
|
+
if (Object.prototype.hasOwnProperty.call(obj, key) && !key.includes(".")) {
|
|
3329
|
+
result[key] = obj[key];
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
for (const key in obj) {
|
|
3333
|
+
if (Object.prototype.hasOwnProperty.call(obj, key) && key.includes(".")) {
|
|
3334
|
+
const keys = key.split(".");
|
|
3335
|
+
let currentLevel = result;
|
|
3336
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3337
|
+
const currentKey = keys[i];
|
|
3338
|
+
if (i === keys.length - 1) {
|
|
3339
|
+
currentLevel[currentKey] = obj[key];
|
|
3340
|
+
} else {
|
|
3341
|
+
if (!(currentKey in currentLevel)) {
|
|
3342
|
+
currentLevel[currentKey] = {};
|
|
3343
|
+
} else if (typeof currentLevel[currentKey] !== "object" || currentLevel[currentKey] === null || Array.isArray(currentLevel[currentKey])) {
|
|
3344
|
+
currentLevel[currentKey] = {};
|
|
3249
3345
|
}
|
|
3346
|
+
currentLevel = currentLevel[currentKey];
|
|
3250
3347
|
}
|
|
3251
|
-
} else {
|
|
3252
|
-
result[key] = obj[key];
|
|
3253
3348
|
}
|
|
3254
3349
|
}
|
|
3255
3350
|
}
|
|
@@ -3266,8 +3361,8 @@ function mapBody(template, body) {
|
|
|
3266
3361
|
const { key: providerSpecificKey, default: defaultValue } = providerSpecificSettings;
|
|
3267
3362
|
if (providerSpecificKey) {
|
|
3268
3363
|
let valueForThisKey = body[genericInputKey];
|
|
3269
|
-
if (providerSpecificSettings.
|
|
3270
|
-
valueForThisKey = providerSpecificSettings.
|
|
3364
|
+
if (providerSpecificSettings.transform && typeof providerSpecificSettings.transform === "function") {
|
|
3365
|
+
valueForThisKey = providerSpecificSettings.transform(
|
|
3271
3366
|
valueForThisKey,
|
|
3272
3367
|
Object.freeze({ ...body }),
|
|
3273
3368
|
output
|
|
@@ -3291,28 +3386,70 @@ var import_sha256_js = require("@aws-crypto/sha256-js");
|
|
|
3291
3386
|
|
|
3292
3387
|
// src/utils/modules/runWithTemporaryEnv.ts
|
|
3293
3388
|
async function runWithTemporaryEnv(env, handler) {
|
|
3294
|
-
const
|
|
3389
|
+
const modifiedKeys = [];
|
|
3390
|
+
const originalValues = {};
|
|
3391
|
+
const envBefore = { ...process.env };
|
|
3295
3392
|
try {
|
|
3296
|
-
|
|
3393
|
+
try {
|
|
3394
|
+
env();
|
|
3395
|
+
} catch (envError) {
|
|
3396
|
+
const envAfter2 = process.env;
|
|
3397
|
+
for (const key in envAfter2) {
|
|
3398
|
+
if (envBefore[key] !== envAfter2[key]) {
|
|
3399
|
+
modifiedKeys.push(key);
|
|
3400
|
+
originalValues[key] = envBefore[key];
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
for (const key in envBefore) {
|
|
3404
|
+
if (!(key in envAfter2) && !modifiedKeys.includes(key)) {
|
|
3405
|
+
modifiedKeys.push(key);
|
|
3406
|
+
originalValues[key] = envBefore[key];
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
throw envError;
|
|
3410
|
+
}
|
|
3411
|
+
const envAfter = process.env;
|
|
3412
|
+
for (const key in envAfter) {
|
|
3413
|
+
if (envBefore[key] !== envAfter[key]) {
|
|
3414
|
+
modifiedKeys.push(key);
|
|
3415
|
+
originalValues[key] = envBefore[key];
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
for (const key in envBefore) {
|
|
3419
|
+
if (!(key in envAfter) && !modifiedKeys.includes(key)) {
|
|
3420
|
+
modifiedKeys.push(key);
|
|
3421
|
+
originalValues[key] = envBefore[key];
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3297
3424
|
const value = await handler();
|
|
3298
3425
|
return value;
|
|
3299
3426
|
} finally {
|
|
3300
|
-
|
|
3427
|
+
for (const key of modifiedKeys) {
|
|
3428
|
+
const originalValue = originalValues[key];
|
|
3429
|
+
if (originalValue === void 0) {
|
|
3430
|
+
delete process.env[key];
|
|
3431
|
+
} else {
|
|
3432
|
+
process.env[key] = originalValue;
|
|
3433
|
+
}
|
|
3434
|
+
}
|
|
3301
3435
|
}
|
|
3302
3436
|
}
|
|
3303
3437
|
|
|
3304
3438
|
// src/utils/modules/getAwsAuthorizationHeaders.ts
|
|
3305
3439
|
async function getAwsAuthorizationHeaders(req, props) {
|
|
3440
|
+
if (!props.url || !props.regionName) {
|
|
3441
|
+
throw new Error("URL and region name are required for AWS authorization");
|
|
3442
|
+
}
|
|
3306
3443
|
const providerChain = (0, import_credential_providers.fromNodeProviderChain)();
|
|
3307
3444
|
const credentials = await runWithTemporaryEnv(
|
|
3308
3445
|
() => {
|
|
3309
|
-
if (props.awsAccessKey) {
|
|
3446
|
+
if (props.awsAccessKey && typeof props.awsAccessKey === "string") {
|
|
3310
3447
|
process.env["AWS_ACCESS_KEY_ID"] = props.awsAccessKey;
|
|
3311
3448
|
}
|
|
3312
|
-
if (props.awsSecretKey) {
|
|
3449
|
+
if (props.awsSecretKey && typeof props.awsSecretKey === "string") {
|
|
3313
3450
|
process.env["AWS_SECRET_ACCESS_KEY"] = props.awsSecretKey;
|
|
3314
3451
|
}
|
|
3315
|
-
if (props.awsSessionToken) {
|
|
3452
|
+
if (props.awsSessionToken && typeof props.awsSessionToken === "string") {
|
|
3316
3453
|
process.env["AWS_SESSION_TOKEN"] = props.awsSessionToken;
|
|
3317
3454
|
}
|
|
3318
3455
|
},
|
|
@@ -3342,8 +3479,21 @@ async function getAwsAuthorizationHeaders(req, props) {
|
|
|
3342
3479
|
// src/llm/_utils.parseHeaders.ts
|
|
3343
3480
|
async function parseHeaders(config, replacements, payload) {
|
|
3344
3481
|
const replace = replaceTemplateStringSimple(config.headers, replacements);
|
|
3345
|
-
|
|
3346
|
-
|
|
3482
|
+
let parsedHeaders = {};
|
|
3483
|
+
if (replace) {
|
|
3484
|
+
try {
|
|
3485
|
+
parsedHeaders = JSON.parse(replace);
|
|
3486
|
+
if (typeof parsedHeaders !== "object" || parsedHeaders === null || Array.isArray(parsedHeaders)) {
|
|
3487
|
+
throw new Error("Headers must be a JSON object");
|
|
3488
|
+
}
|
|
3489
|
+
} catch (error) {
|
|
3490
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
3491
|
+
throw new Error(
|
|
3492
|
+
`Failed to parse headers configuration: ${errorMessage}. Headers template: "${config.headers}". After replacement: "${replace}"`
|
|
3493
|
+
);
|
|
3494
|
+
}
|
|
3495
|
+
}
|
|
3496
|
+
const headers = Object.assign({}, payload.headers, parsedHeaders);
|
|
3347
3497
|
if (config.provider.startsWith("amazon:") || config.provider.startsWith("amazon.")) {
|
|
3348
3498
|
const url = payload.url;
|
|
3349
3499
|
return getAwsAuthorizationHeaders(
|
|
@@ -3364,122 +3514,129 @@ async function parseHeaders(config, replacements, payload) {
|
|
|
3364
3514
|
}
|
|
3365
3515
|
}
|
|
3366
3516
|
|
|
3367
|
-
// src/llm/output/
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
};
|
|
3374
|
-
|
|
3375
|
-
const
|
|
3376
|
-
|
|
3517
|
+
// src/llm/output/default.ts
|
|
3518
|
+
function OutputDefault(result, _config) {
|
|
3519
|
+
const name = _config?.options.model?.default || "unknown";
|
|
3520
|
+
const stopReason = result?.stopReason || "stop";
|
|
3521
|
+
const content = [];
|
|
3522
|
+
if (result?.text) {
|
|
3523
|
+
content.push({ type: "text", text: result.text });
|
|
3524
|
+
}
|
|
3525
|
+
const usage = {
|
|
3526
|
+
output_tokens: result?.output_tokens || 0,
|
|
3527
|
+
input_tokens: result?.input_tokens || 0,
|
|
3528
|
+
total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
|
|
3529
|
+
};
|
|
3530
|
+
return {
|
|
3531
|
+
name,
|
|
3532
|
+
usage,
|
|
3533
|
+
stopReason,
|
|
3534
|
+
content
|
|
3535
|
+
};
|
|
3536
|
+
}
|
|
3537
|
+
|
|
3538
|
+
// src/llm/output/_utils/getResultContent.ts
|
|
3539
|
+
function getResultContent(result, index) {
|
|
3540
|
+
if (typeof index === "number" && index > 0) {
|
|
3541
|
+
const arr = result?.options || [];
|
|
3542
|
+
const val = arr[index];
|
|
3543
|
+
return val ? val : [];
|
|
3544
|
+
}
|
|
3545
|
+
return [...result.content];
|
|
3546
|
+
}
|
|
3547
|
+
|
|
3548
|
+
// src/llm/output/_utils/getResultText.ts
|
|
3549
|
+
function getResultText(result, index) {
|
|
3550
|
+
if (typeof index === "number" && index > 0) {
|
|
3551
|
+
const arr = result?.options || [];
|
|
3552
|
+
const val = arr[index];
|
|
3553
|
+
return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
|
|
3554
|
+
}
|
|
3555
|
+
return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
|
|
3556
|
+
}
|
|
3557
|
+
|
|
3558
|
+
// src/llm/output/base.ts
|
|
3559
|
+
function BaseLlmOutput(result) {
|
|
3560
|
+
const __result = Object.freeze({
|
|
3561
|
+
id: result.id || (0, import_uuid.v4)(),
|
|
3562
|
+
name: result.name,
|
|
3563
|
+
usage: result.usage,
|
|
3564
|
+
stopReason: result.stopReason,
|
|
3565
|
+
options: [...result?.options || []],
|
|
3566
|
+
content: [...result.content],
|
|
3567
|
+
created: result?.created || (/* @__PURE__ */ new Date()).getTime()
|
|
3568
|
+
});
|
|
3569
|
+
function getResult() {
|
|
3377
3570
|
return {
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3571
|
+
id: __result.id,
|
|
3572
|
+
name: __result.name,
|
|
3573
|
+
created: __result.created,
|
|
3574
|
+
usage: __result.usage,
|
|
3575
|
+
options: __result.options,
|
|
3576
|
+
content: __result.content,
|
|
3577
|
+
stopReason: __result.stopReason
|
|
3381
3578
|
};
|
|
3382
3579
|
}
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3580
|
+
return {
|
|
3581
|
+
getResultContent: (index) => getResultContent(__result, index),
|
|
3582
|
+
getResultText: (index) => getResultText(__result, index),
|
|
3583
|
+
getResult
|
|
3584
|
+
};
|
|
3585
|
+
}
|
|
3586
|
+
|
|
3587
|
+
// src/llm/_utils.mapOptions.ts
|
|
3588
|
+
function mapOptions(input, options, config) {
|
|
3589
|
+
if (!config?.mapOptions || !options) {
|
|
3590
|
+
return input;
|
|
3591
|
+
}
|
|
3592
|
+
let result = { ...input };
|
|
3593
|
+
let processedOptions = options;
|
|
3594
|
+
if (options.functionCall && config.mapOptions.functionCall) {
|
|
3595
|
+
const mapping = config.mapOptions.functionCall(
|
|
3596
|
+
options.functionCall,
|
|
3597
|
+
options,
|
|
3598
|
+
result,
|
|
3599
|
+
config
|
|
3600
|
+
);
|
|
3601
|
+
if (mapping._clearFunctions) {
|
|
3602
|
+
processedOptions = { ...options, functions: [] };
|
|
3603
|
+
const { _clearFunctions, ...rest } = mapping;
|
|
3604
|
+
result = { ...result, ...rest };
|
|
3605
|
+
} else {
|
|
3606
|
+
result = { ...result, ...mapping };
|
|
3394
3607
|
}
|
|
3395
|
-
return obj;
|
|
3396
3608
|
}
|
|
3397
|
-
|
|
3609
|
+
if (processedOptions.functions?.length && config.mapOptions.functions) {
|
|
3610
|
+
result = {
|
|
3611
|
+
...result,
|
|
3612
|
+
...config.mapOptions.functions(
|
|
3613
|
+
processedOptions.functions,
|
|
3614
|
+
processedOptions,
|
|
3615
|
+
result,
|
|
3616
|
+
config
|
|
3617
|
+
)
|
|
3618
|
+
};
|
|
3619
|
+
}
|
|
3620
|
+
if (options.jsonSchema && config.mapOptions.jsonSchema) {
|
|
3621
|
+
result = {
|
|
3622
|
+
...result,
|
|
3623
|
+
...config.mapOptions.jsonSchema(options.jsonSchema, options, result, config)
|
|
3624
|
+
};
|
|
3625
|
+
}
|
|
3626
|
+
return result;
|
|
3398
3627
|
}
|
|
3399
3628
|
|
|
3400
3629
|
// src/llm/llm.call.ts
|
|
3401
3630
|
async function useLlm_call(state, messages, _options) {
|
|
3402
3631
|
const config = getLlmConfig(state.key);
|
|
3403
|
-
const
|
|
3404
|
-
const input = mapBody(
|
|
3632
|
+
const transformBody = mapBody(
|
|
3405
3633
|
config.mapBody,
|
|
3406
3634
|
Object.assign({}, state, {
|
|
3407
3635
|
prompt: messages
|
|
3408
3636
|
})
|
|
3409
3637
|
);
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
const curr = input["response_format"] || {};
|
|
3413
|
-
input["response_format"] = Object.assign(curr, {
|
|
3414
|
-
type: "json_schema",
|
|
3415
|
-
json_schema: {
|
|
3416
|
-
name: "output",
|
|
3417
|
-
strict: !!functionCallStrictInput,
|
|
3418
|
-
schema: cleanJsonSchemaFor(_options?.jsonSchema, "openai.chat")
|
|
3419
|
-
}
|
|
3420
|
-
});
|
|
3421
|
-
}
|
|
3422
|
-
}
|
|
3423
|
-
if (_options && _options?.functionCall) {
|
|
3424
|
-
if (state.provider.startsWith("anthropic")) {
|
|
3425
|
-
if (_options?.functionCall === "none") {
|
|
3426
|
-
_options.functions = [];
|
|
3427
|
-
} else if (_options?.functionCall === "auto" || _options?.functionCall === "any") {
|
|
3428
|
-
input["tool_choice"] = { type: _options?.functionCall };
|
|
3429
|
-
} else {
|
|
3430
|
-
input["tool_choice"] = _options?.functionCall;
|
|
3431
|
-
}
|
|
3432
|
-
} else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
|
|
3433
|
-
input["tool_choice"] = normalizeFunctionCall(
|
|
3434
|
-
_options?.functionCall,
|
|
3435
|
-
"openai"
|
|
3436
|
-
);
|
|
3437
|
-
} else if (state.provider.startsWith("google")) {
|
|
3438
|
-
input["toolConfig"] = {
|
|
3439
|
-
functionCallingConfig: {
|
|
3440
|
-
mode: normalizeFunctionCall(_options?.functionCall, "google")
|
|
3441
|
-
}
|
|
3442
|
-
};
|
|
3443
|
-
}
|
|
3444
|
-
}
|
|
3445
|
-
if (_options && _options?.functions?.length) {
|
|
3446
|
-
if (state.provider.startsWith("anthropic")) {
|
|
3447
|
-
input["tools"] = _options.functions.map((f) => ({
|
|
3448
|
-
name: f.name,
|
|
3449
|
-
description: f.description,
|
|
3450
|
-
input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
|
|
3451
|
-
}));
|
|
3452
|
-
} else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
|
|
3453
|
-
input["tools"] = _options.functions.map((f) => {
|
|
3454
|
-
const props = {
|
|
3455
|
-
name: f?.name,
|
|
3456
|
-
description: f?.description,
|
|
3457
|
-
parameters: f?.parameters
|
|
3458
|
-
};
|
|
3459
|
-
return {
|
|
3460
|
-
type: "function",
|
|
3461
|
-
function: Object.assign(
|
|
3462
|
-
props,
|
|
3463
|
-
{
|
|
3464
|
-
parameters: cleanJsonSchemaFor(props.parameters, "openai.chat")
|
|
3465
|
-
},
|
|
3466
|
-
{ strict: functionCallStrictInput }
|
|
3467
|
-
)
|
|
3468
|
-
};
|
|
3469
|
-
});
|
|
3470
|
-
} else if (state.provider.startsWith("google")) {
|
|
3471
|
-
input["tools"] = [
|
|
3472
|
-
{
|
|
3473
|
-
functionDeclarations: _options.functions.map((f) => ({
|
|
3474
|
-
name: f.name,
|
|
3475
|
-
description: f.description,
|
|
3476
|
-
parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
|
|
3477
|
-
}))
|
|
3478
|
-
}
|
|
3479
|
-
];
|
|
3480
|
-
}
|
|
3481
|
-
}
|
|
3482
|
-
const body = JSON.stringify(input);
|
|
3638
|
+
const applyOptions = mapOptions(transformBody, _options, config);
|
|
3639
|
+
const body = JSON.stringify(applyOptions);
|
|
3483
3640
|
const url = replaceTemplateStringSimple(config.endpoint, state);
|
|
3484
3641
|
const headers = await parseHeaders(config, state, {
|
|
3485
3642
|
url,
|
|
@@ -3506,7 +3663,9 @@ async function useLlm_call(state, messages, _options) {
|
|
|
3506
3663
|
body,
|
|
3507
3664
|
headers
|
|
3508
3665
|
});
|
|
3509
|
-
|
|
3666
|
+
const { transformResponse = OutputDefault } = config;
|
|
3667
|
+
const normalized = transformResponse(response, config);
|
|
3668
|
+
return BaseLlmOutput(normalized);
|
|
3510
3669
|
}
|
|
3511
3670
|
|
|
3512
3671
|
// src/llm/_utils.stateFromOptions.ts
|
|
@@ -3649,6 +3808,80 @@ function useLlm(provider, options = {}) {
|
|
|
3649
3808
|
const config = getLlmConfig(provider);
|
|
3650
3809
|
return apiRequestWrapper(config, options, useLlm_call);
|
|
3651
3810
|
}
|
|
3811
|
+
function useLlmConfiguration(config) {
|
|
3812
|
+
return (options = {}) => apiRequestWrapper(config, options, useLlm_call);
|
|
3813
|
+
}
|
|
3814
|
+
|
|
3815
|
+
// src/embedding/output/BaseEmbeddingOutput.ts
|
|
3816
|
+
function BaseEmbeddingOutput(result) {
|
|
3817
|
+
const __result = Object.freeze({
|
|
3818
|
+
id: result.id || (0, import_uuid.v4)(),
|
|
3819
|
+
model: result.model,
|
|
3820
|
+
usage: result.usage,
|
|
3821
|
+
embedding: [...result?.embedding || []],
|
|
3822
|
+
created: result?.created || (/* @__PURE__ */ new Date()).getTime()
|
|
3823
|
+
});
|
|
3824
|
+
function getResult() {
|
|
3825
|
+
return {
|
|
3826
|
+
id: __result.id,
|
|
3827
|
+
model: __result.model,
|
|
3828
|
+
created: __result.created,
|
|
3829
|
+
usage: __result.usage,
|
|
3830
|
+
embedding: __result.embedding
|
|
3831
|
+
};
|
|
3832
|
+
}
|
|
3833
|
+
function getEmbedding(index) {
|
|
3834
|
+
if (index && index > 0) {
|
|
3835
|
+
const arr = __result?.embedding;
|
|
3836
|
+
const val = arr[index];
|
|
3837
|
+
return val ? val : [];
|
|
3838
|
+
}
|
|
3839
|
+
return __result.embedding[0];
|
|
3840
|
+
}
|
|
3841
|
+
return {
|
|
3842
|
+
getEmbedding,
|
|
3843
|
+
getResult
|
|
3844
|
+
};
|
|
3845
|
+
}
|
|
3846
|
+
|
|
3847
|
+
// src/embedding/output/OpenAiEmbedding.ts
|
|
3848
|
+
function OpenAiEmbedding(result, config) {
|
|
3849
|
+
const __result = deepClone(result);
|
|
3850
|
+
const model = __result.model || config.model || "openai.unknown";
|
|
3851
|
+
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3852
|
+
const results = result?.data || [];
|
|
3853
|
+
const embedding = results.map((a) => a.embedding);
|
|
3854
|
+
const usage = {
|
|
3855
|
+
output_tokens: 0,
|
|
3856
|
+
input_tokens: result?.usage?.prompt_tokens,
|
|
3857
|
+
total_tokens: result?.usage?.total_tokens
|
|
3858
|
+
};
|
|
3859
|
+
return BaseEmbeddingOutput({
|
|
3860
|
+
model,
|
|
3861
|
+
created,
|
|
3862
|
+
usage,
|
|
3863
|
+
embedding
|
|
3864
|
+
});
|
|
3865
|
+
}
|
|
3866
|
+
|
|
3867
|
+
// src/embedding/output/AmazonTitan.ts
|
|
3868
|
+
function AmazonTitanEmbedding(result, config) {
|
|
3869
|
+
const __result = deepClone(result);
|
|
3870
|
+
const model = config.model || "amazon.unknown";
|
|
3871
|
+
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3872
|
+
const embedding = [__result.embedding];
|
|
3873
|
+
const usage = {
|
|
3874
|
+
output_tokens: 0,
|
|
3875
|
+
input_tokens: __result.inputTextTokenCount,
|
|
3876
|
+
total_tokens: __result.inputTextTokenCount
|
|
3877
|
+
};
|
|
3878
|
+
return BaseEmbeddingOutput({
|
|
3879
|
+
model,
|
|
3880
|
+
created,
|
|
3881
|
+
usage,
|
|
3882
|
+
embedding
|
|
3883
|
+
});
|
|
3884
|
+
}
|
|
3652
3885
|
|
|
3653
3886
|
// src/embedding/config.ts
|
|
3654
3887
|
var embeddingConfigs = {
|
|
@@ -3681,7 +3914,8 @@ var embeddingConfigs = {
|
|
|
3681
3914
|
encodingFormat: {
|
|
3682
3915
|
key: "encoding_format"
|
|
3683
3916
|
}
|
|
3684
|
-
}
|
|
3917
|
+
},
|
|
3918
|
+
transformResponse: OpenAiEmbedding
|
|
3685
3919
|
},
|
|
3686
3920
|
"amazon.embedding.v1": {
|
|
3687
3921
|
key: "amazon.embedding.v1",
|
|
@@ -3708,7 +3942,8 @@ var embeddingConfigs = {
|
|
|
3708
3942
|
dimensions: {
|
|
3709
3943
|
key: "dimensions"
|
|
3710
3944
|
}
|
|
3711
|
-
}
|
|
3945
|
+
},
|
|
3946
|
+
transformResponse: AmazonTitanEmbedding
|
|
3712
3947
|
}
|
|
3713
3948
|
};
|
|
3714
3949
|
function getEmbeddingConfig(provider) {
|
|
@@ -3722,77 +3957,6 @@ function getEmbeddingConfig(provider) {
|
|
|
3722
3957
|
throw new Error(`Invalid provider: ${provider}`);
|
|
3723
3958
|
}
|
|
3724
3959
|
|
|
3725
|
-
// src/embedding/output/BaseEmbeddingOutput.ts
|
|
3726
|
-
function BaseEmbeddingOutput(result) {
|
|
3727
|
-
const __result = Object.freeze({
|
|
3728
|
-
id: result.id || (0, import_uuid.v4)(),
|
|
3729
|
-
model: result.model,
|
|
3730
|
-
usage: result.usage,
|
|
3731
|
-
embedding: [...result?.embedding || []],
|
|
3732
|
-
created: result?.created || (/* @__PURE__ */ new Date()).getTime()
|
|
3733
|
-
});
|
|
3734
|
-
function getResult() {
|
|
3735
|
-
return {
|
|
3736
|
-
id: __result.id,
|
|
3737
|
-
model: __result.model,
|
|
3738
|
-
created: __result.created,
|
|
3739
|
-
usage: __result.usage,
|
|
3740
|
-
embedding: __result.embedding
|
|
3741
|
-
};
|
|
3742
|
-
}
|
|
3743
|
-
function getEmbedding(index) {
|
|
3744
|
-
if (index && index > 0) {
|
|
3745
|
-
const arr = __result?.embedding;
|
|
3746
|
-
const val = arr[index];
|
|
3747
|
-
return val ? val : [];
|
|
3748
|
-
}
|
|
3749
|
-
return __result.embedding[0];
|
|
3750
|
-
}
|
|
3751
|
-
return {
|
|
3752
|
-
getEmbedding,
|
|
3753
|
-
getResult
|
|
3754
|
-
};
|
|
3755
|
-
}
|
|
3756
|
-
|
|
3757
|
-
// src/embedding/output/AmazonTitan.ts
|
|
3758
|
-
function AmazonTitanEmbedding(result, config) {
|
|
3759
|
-
const __result = deepClone(result);
|
|
3760
|
-
const model = config.model || "amazon.unknown";
|
|
3761
|
-
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3762
|
-
const embedding = [__result.embedding];
|
|
3763
|
-
const usage = {
|
|
3764
|
-
output_tokens: 0,
|
|
3765
|
-
input_tokens: __result.inputTextTokenCount,
|
|
3766
|
-
total_tokens: __result.inputTextTokenCount
|
|
3767
|
-
};
|
|
3768
|
-
return BaseEmbeddingOutput({
|
|
3769
|
-
model,
|
|
3770
|
-
created,
|
|
3771
|
-
usage,
|
|
3772
|
-
embedding
|
|
3773
|
-
});
|
|
3774
|
-
}
|
|
3775
|
-
|
|
3776
|
-
// src/embedding/output/OpenAiEmbedding.ts
|
|
3777
|
-
function OpenAiEmbedding(result, config) {
|
|
3778
|
-
const __result = deepClone(result);
|
|
3779
|
-
const model = __result.model || config.model || "openai.unknown";
|
|
3780
|
-
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3781
|
-
const results = result?.data || [];
|
|
3782
|
-
const embedding = results.map((a) => a.embedding);
|
|
3783
|
-
const usage = {
|
|
3784
|
-
output_tokens: 0,
|
|
3785
|
-
input_tokens: result?.usage?.prompt_tokens,
|
|
3786
|
-
total_tokens: result?.usage?.total_tokens
|
|
3787
|
-
};
|
|
3788
|
-
return BaseEmbeddingOutput({
|
|
3789
|
-
model,
|
|
3790
|
-
created,
|
|
3791
|
-
usage,
|
|
3792
|
-
embedding
|
|
3793
|
-
});
|
|
3794
|
-
}
|
|
3795
|
-
|
|
3796
3960
|
// src/embedding/output/getEmbeddingOutputParser.ts
|
|
3797
3961
|
function getEmbeddingOutputParser(config, response) {
|
|
3798
3962
|
switch (config.key) {
|
|
@@ -4070,8 +4234,8 @@ var ChatPrompt = class extends BasePrompt {
|
|
|
4070
4234
|
__publicField(this, "type", "chat");
|
|
4071
4235
|
/**
|
|
4072
4236
|
* @property parseUserTemplates - Whether or not to allow parsing
|
|
4073
|
-
* user messages with the template engine.
|
|
4074
|
-
*
|
|
4237
|
+
* user messages with the template engine. Defaults to true.
|
|
4238
|
+
* Set `allowUnsafeUserTemplate: false` in options to disable.
|
|
4075
4239
|
*/
|
|
4076
4240
|
__publicField(this, "parseUserTemplates", true);
|
|
4077
4241
|
if (typeof options?.allowUnsafeUserTemplate === "boolean") {
|
|
@@ -4132,7 +4296,7 @@ var ChatPrompt = class extends BasePrompt {
|
|
|
4132
4296
|
return this;
|
|
4133
4297
|
}
|
|
4134
4298
|
/**
|
|
4135
|
-
* addFunctionMessage Helper to add
|
|
4299
|
+
* addFunctionMessage Helper to add a function message to the prompt.
|
|
4136
4300
|
* @param content The message content.
|
|
4137
4301
|
* @return ChatPrompt so it can be chained.
|
|
4138
4302
|
*/
|
|
@@ -4146,7 +4310,7 @@ var ChatPrompt = class extends BasePrompt {
|
|
|
4146
4310
|
return this;
|
|
4147
4311
|
}
|
|
4148
4312
|
/**
|
|
4149
|
-
* addFunctionCallMessage Helper to add
|
|
4313
|
+
* addFunctionCallMessage Helper to add a function_call message to the prompt.
|
|
4150
4314
|
* @param content The message content.
|
|
4151
4315
|
* @return ChatPrompt so it can be chained.
|
|
4152
4316
|
*/
|
|
@@ -4701,7 +4865,7 @@ var Dialogue = class extends BaseStateItem {
|
|
|
4701
4865
|
return this;
|
|
4702
4866
|
}
|
|
4703
4867
|
setToolMessage(content, name, id) {
|
|
4704
|
-
this.setFunctionMessage(content, name, id);
|
|
4868
|
+
return this.setFunctionMessage(content, name, id);
|
|
4705
4869
|
}
|
|
4706
4870
|
setFunctionMessage(content, name, id) {
|
|
4707
4871
|
if (content) {
|
|
@@ -4718,7 +4882,7 @@ var Dialogue = class extends BaseStateItem {
|
|
|
4718
4882
|
* Set
|
|
4719
4883
|
*/
|
|
4720
4884
|
setToolCallMessage(input) {
|
|
4721
|
-
this.setFunctionCallMessage(input);
|
|
4885
|
+
return this.setFunctionCallMessage(input);
|
|
4722
4886
|
}
|
|
4723
4887
|
setFunctionCallMessage(input) {
|
|
4724
4888
|
if (!input || typeof input !== "object") {
|
|
@@ -4810,6 +4974,9 @@ var Dialogue = class extends BaseStateItem {
|
|
|
4810
4974
|
* @returns this for chaining
|
|
4811
4975
|
*/
|
|
4812
4976
|
addFromOutput(output) {
|
|
4977
|
+
if (!output || typeof output !== "object") {
|
|
4978
|
+
return this;
|
|
4979
|
+
}
|
|
4813
4980
|
const result = "getResult" in output ? output.getResult() : output;
|
|
4814
4981
|
if (!result || typeof result !== "object") {
|
|
4815
4982
|
return this;
|
|
@@ -4946,6 +5113,7 @@ function createStateItem(name, defaultValue) {
|
|
|
4946
5113
|
createEmbedding,
|
|
4947
5114
|
createLlmExecutor,
|
|
4948
5115
|
createLlmFunctionExecutor,
|
|
5116
|
+
createOpenAiCompatibleConfiguration,
|
|
4949
5117
|
createParser,
|
|
4950
5118
|
createPrompt,
|
|
4951
5119
|
createState,
|
|
@@ -4956,5 +5124,6 @@ function createStateItem(name, defaultValue) {
|
|
|
4956
5124
|
registerPartials,
|
|
4957
5125
|
useExecutors,
|
|
4958
5126
|
useLlm,
|
|
5127
|
+
useLlmConfiguration,
|
|
4959
5128
|
utils
|
|
4960
5129
|
});
|