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.mjs
CHANGED
|
@@ -125,6 +125,10 @@ var BaseExecutor = class {
|
|
|
125
125
|
*/
|
|
126
126
|
__publicField(this, "hooks");
|
|
127
127
|
__publicField(this, "allowedHooks", [hookOnComplete, hookOnError, hookOnSuccess]);
|
|
128
|
+
/**
|
|
129
|
+
* @property maxHooksPerEvent - Maximum number of hooks allowed per event
|
|
130
|
+
*/
|
|
131
|
+
__publicField(this, "maxHooksPerEvent", 100);
|
|
128
132
|
this.id = uuidv4();
|
|
129
133
|
this.type = type;
|
|
130
134
|
this.name = name;
|
|
@@ -230,6 +234,11 @@ var BaseExecutor = class {
|
|
|
230
234
|
const _hooks = Array.isArray(hookInput) ? hookInput : [hookInput];
|
|
231
235
|
for (const hook of _hooks) {
|
|
232
236
|
if (hook && typeof hook === "function" && !this.hooks[hookKey].find((h) => h === hook)) {
|
|
237
|
+
if (this.hooks[hookKey].length >= this.maxHooksPerEvent) {
|
|
238
|
+
throw new Error(
|
|
239
|
+
`Maximum number of hooks (${this.maxHooksPerEvent}) reached for event "${String(hookKey)}". Consider removing unused hooks or increasing the limit.`
|
|
240
|
+
);
|
|
241
|
+
}
|
|
233
242
|
this.hooks[hookKey].push(hook);
|
|
234
243
|
}
|
|
235
244
|
}
|
|
@@ -257,10 +266,18 @@ var BaseExecutor = class {
|
|
|
257
266
|
}
|
|
258
267
|
once(eventName, fn) {
|
|
259
268
|
if (typeof fn !== "function") return this;
|
|
269
|
+
if (this.hooks[eventName] && this.hooks[eventName].length >= this.maxHooksPerEvent) {
|
|
270
|
+
throw new Error(
|
|
271
|
+
`Maximum number of hooks (${this.maxHooksPerEvent}) reached for event "${String(eventName)}". Consider removing unused hooks or increasing the limit.`
|
|
272
|
+
);
|
|
273
|
+
}
|
|
260
274
|
const onceWrapper = (...args) => {
|
|
261
275
|
fn(...args);
|
|
262
276
|
this.off(eventName, onceWrapper);
|
|
263
277
|
};
|
|
278
|
+
if (!this.hooks[eventName]) {
|
|
279
|
+
this.hooks[eventName] = [];
|
|
280
|
+
}
|
|
264
281
|
this.hooks[eventName].push(onceWrapper);
|
|
265
282
|
return this;
|
|
266
283
|
}
|
|
@@ -271,6 +288,40 @@ var BaseExecutor = class {
|
|
|
271
288
|
getTraceId() {
|
|
272
289
|
return this.traceId;
|
|
273
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Clear all hooks for a specific event or all events
|
|
293
|
+
* Useful for preventing memory leaks in long-running processes
|
|
294
|
+
* @param eventName - The event name to clear hooks for
|
|
295
|
+
*/
|
|
296
|
+
clearHooks(eventName) {
|
|
297
|
+
if (eventName) {
|
|
298
|
+
if (this.hooks[eventName]) {
|
|
299
|
+
this.hooks[eventName] = [];
|
|
300
|
+
}
|
|
301
|
+
} else {
|
|
302
|
+
for (const key of this.allowedHooks) {
|
|
303
|
+
if (this.hooks[key]) {
|
|
304
|
+
this.hooks[key] = [];
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return this;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Get the count of hooks for monitoring memory usage
|
|
312
|
+
* @param eventName - Optional event name to get count for
|
|
313
|
+
* @returns Hook count for specific event or all events
|
|
314
|
+
*/
|
|
315
|
+
getHookCount(eventName) {
|
|
316
|
+
if (eventName) {
|
|
317
|
+
return this.hooks[eventName]?.length || 0;
|
|
318
|
+
}
|
|
319
|
+
const counts = {};
|
|
320
|
+
for (const key of this.allowedHooks) {
|
|
321
|
+
counts[key] = this.hooks[key]?.length || 0;
|
|
322
|
+
}
|
|
323
|
+
return counts;
|
|
324
|
+
}
|
|
274
325
|
};
|
|
275
326
|
|
|
276
327
|
// src/utils/modules/inferFunctionName.ts
|
|
@@ -416,7 +467,7 @@ var BooleanParser = class extends BaseParser {
|
|
|
416
467
|
`Invalid input. Expected string. Received ${typeof text}.`
|
|
417
468
|
);
|
|
418
469
|
const clean = text.toLowerCase().trim();
|
|
419
|
-
if (clean === "true") {
|
|
470
|
+
if (clean === "true" || clean === "yes" || clean === "y" || clean === "1") {
|
|
420
471
|
return true;
|
|
421
472
|
}
|
|
422
473
|
return false;
|
|
@@ -445,7 +496,7 @@ var NumberParser = class extends BaseParser {
|
|
|
445
496
|
super("number", options);
|
|
446
497
|
}
|
|
447
498
|
parse(text) {
|
|
448
|
-
const match = text.match(
|
|
499
|
+
const match = text.match(/-?\d+(\.\d+)?/);
|
|
449
500
|
return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
|
|
450
501
|
}
|
|
451
502
|
};
|
|
@@ -1347,9 +1398,8 @@ var asyncCallWithTimeout = async (asyncPromise, timeLimit = 1e4) => {
|
|
|
1347
1398
|
);
|
|
1348
1399
|
}, timeLimit);
|
|
1349
1400
|
});
|
|
1350
|
-
return Promise.race([asyncPromise, timeoutPromise]).
|
|
1401
|
+
return Promise.race([asyncPromise, timeoutPromise]).finally(() => {
|
|
1351
1402
|
clearTimeout(timeoutHandle);
|
|
1352
|
-
return result;
|
|
1353
1403
|
});
|
|
1354
1404
|
};
|
|
1355
1405
|
|
|
@@ -1495,9 +1545,13 @@ var ListToJsonParser = class extends BaseParserWithJson {
|
|
|
1495
1545
|
const lines = text.split("\n");
|
|
1496
1546
|
const output = {};
|
|
1497
1547
|
lines.forEach((line) => {
|
|
1498
|
-
const
|
|
1499
|
-
if (
|
|
1500
|
-
|
|
1548
|
+
const colonIndex = line.indexOf(":");
|
|
1549
|
+
if (colonIndex !== -1) {
|
|
1550
|
+
const key = line.slice(0, colonIndex);
|
|
1551
|
+
const value = line.slice(colonIndex + 1).trim();
|
|
1552
|
+
if (value) {
|
|
1553
|
+
output[camelCase(key)] = value;
|
|
1554
|
+
}
|
|
1501
1555
|
}
|
|
1502
1556
|
});
|
|
1503
1557
|
if (this.schema) {
|
|
@@ -1569,7 +1623,7 @@ var ListToArrayParser = class extends BaseParser {
|
|
|
1569
1623
|
super("listToArray");
|
|
1570
1624
|
}
|
|
1571
1625
|
parse(text) {
|
|
1572
|
-
const lines = text.split("\n").map((s) => s.replace(
|
|
1626
|
+
const lines = text.split("\n").map((s) => s.replace(/^(?:[-*] |\d+\. )/, "").replace(/'/g, "\u2019").trim());
|
|
1573
1627
|
return lines;
|
|
1574
1628
|
}
|
|
1575
1629
|
};
|
|
@@ -1697,8 +1751,11 @@ function createParser(type, options = {}) {
|
|
|
1697
1751
|
case "stringExtract":
|
|
1698
1752
|
return new StringExtractParser(options);
|
|
1699
1753
|
case "string":
|
|
1700
|
-
default:
|
|
1701
1754
|
return new StringParser();
|
|
1755
|
+
default:
|
|
1756
|
+
throw new Error(
|
|
1757
|
+
`Invalid parser type: "${type}". Valid types are: json, string, boolean, number, stringExtract, listToArray, listToJson, listToKeyValue, replaceStringTemplate, markdownCodeBlock, markdownCodeBlocks`
|
|
1758
|
+
);
|
|
1702
1759
|
}
|
|
1703
1760
|
}
|
|
1704
1761
|
function createCustomParser(name, parserFn) {
|
|
@@ -2057,6 +2114,63 @@ function getEnvironmentVariable(name) {
|
|
|
2057
2114
|
}
|
|
2058
2115
|
}
|
|
2059
2116
|
|
|
2117
|
+
// src/llm/output/_util.ts
|
|
2118
|
+
function formatOptions(response, handler) {
|
|
2119
|
+
const out = [];
|
|
2120
|
+
for (const item of response) {
|
|
2121
|
+
const result = handler(item);
|
|
2122
|
+
if (result) {
|
|
2123
|
+
out.push([result]);
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
return out;
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
// src/llm/output/openai.ts
|
|
2130
|
+
function formatResult(result) {
|
|
2131
|
+
const out = [];
|
|
2132
|
+
if (typeof result?.message?.content === "string") {
|
|
2133
|
+
out.push({
|
|
2134
|
+
type: "text",
|
|
2135
|
+
text: result.message.content
|
|
2136
|
+
});
|
|
2137
|
+
}
|
|
2138
|
+
if (result?.message?.tool_calls) {
|
|
2139
|
+
for (const call of result.message.tool_calls) {
|
|
2140
|
+
out.push({
|
|
2141
|
+
functionId: call.id,
|
|
2142
|
+
type: "function_use",
|
|
2143
|
+
name: call.function.name,
|
|
2144
|
+
input: maybeParseJSON(call.function.arguments)
|
|
2145
|
+
});
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
return out;
|
|
2149
|
+
}
|
|
2150
|
+
function OutputOpenAIChat(result, _config) {
|
|
2151
|
+
const id = result.id;
|
|
2152
|
+
const name = result.model || _config?.options.model?.default || "openai.unknown";
|
|
2153
|
+
const created = result.created;
|
|
2154
|
+
const [_content, ..._options] = result?.choices || [];
|
|
2155
|
+
const stopReason = _content?.finish_reason;
|
|
2156
|
+
const content = formatResult(_content);
|
|
2157
|
+
const options = formatOptions(_options, formatResult);
|
|
2158
|
+
const usage = {
|
|
2159
|
+
output_tokens: result?.usage?.completion_tokens,
|
|
2160
|
+
input_tokens: result?.usage?.prompt_tokens,
|
|
2161
|
+
total_tokens: result?.usage?.total_tokens
|
|
2162
|
+
};
|
|
2163
|
+
return {
|
|
2164
|
+
id,
|
|
2165
|
+
name,
|
|
2166
|
+
created,
|
|
2167
|
+
usage,
|
|
2168
|
+
stopReason,
|
|
2169
|
+
content,
|
|
2170
|
+
options
|
|
2171
|
+
};
|
|
2172
|
+
}
|
|
2173
|
+
|
|
2060
2174
|
// src/llm/config/openai/promptSanitizeMessageCallback.ts
|
|
2061
2175
|
function openaiPromptMessageCallback(_message) {
|
|
2062
2176
|
let message = { ..._message };
|
|
@@ -2090,38 +2204,127 @@ function openaiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
|
2090
2204
|
return _messages.map(openaiPromptMessageCallback);
|
|
2091
2205
|
}
|
|
2092
2206
|
|
|
2093
|
-
// src/llm/
|
|
2094
|
-
var
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2207
|
+
// src/llm/output/_utils/cleanJsonSchemaFor.ts
|
|
2208
|
+
var providerFieldExclusions = {
|
|
2209
|
+
"openai.chat": ["default"],
|
|
2210
|
+
// fields to exclude for openai.chat, xai, deepseek
|
|
2211
|
+
"anthropic.chat": [],
|
|
2212
|
+
"google.chat": ["additionalProperties"]
|
|
2213
|
+
};
|
|
2214
|
+
function cleanJsonSchemaFor(schema = {}, provider) {
|
|
2215
|
+
const clone = deepClone(schema);
|
|
2216
|
+
if (Object.keys(clone).length === 0) {
|
|
2217
|
+
return {
|
|
2218
|
+
type: "object",
|
|
2219
|
+
properties: {},
|
|
2220
|
+
required: []
|
|
2221
|
+
};
|
|
2222
|
+
}
|
|
2223
|
+
const exclusions = providerFieldExclusions[provider] || [];
|
|
2224
|
+
function removeDisallowedFields(obj) {
|
|
2225
|
+
if (Array.isArray(obj)) {
|
|
2226
|
+
return obj.map(removeDisallowedFields);
|
|
2227
|
+
} else if (typeof obj === "object" && obj !== null) {
|
|
2228
|
+
return Object.keys(obj).reduce((acc, key) => {
|
|
2229
|
+
if (!exclusions.includes(key)) {
|
|
2230
|
+
acc[key] = removeDisallowedFields(obj[key]);
|
|
2231
|
+
}
|
|
2232
|
+
return acc;
|
|
2233
|
+
}, {});
|
|
2104
2234
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2235
|
+
return obj;
|
|
2236
|
+
}
|
|
2237
|
+
return removeDisallowedFields(clone);
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
// src/llm/config/openai/compatible.ts
|
|
2241
|
+
function createOpenAiCompatibleConfiguration(overrides) {
|
|
2242
|
+
const [apiKeyPropertyKey, apiKeyPropertyValue] = overrides.apiKeyMapping;
|
|
2243
|
+
const config = {
|
|
2244
|
+
key: overrides.key,
|
|
2245
|
+
provider: overrides.provider,
|
|
2246
|
+
endpoint: overrides.endpoint,
|
|
2247
|
+
options: {
|
|
2248
|
+
prompt: {},
|
|
2249
|
+
effort: {},
|
|
2250
|
+
topP: {},
|
|
2251
|
+
useJson: {},
|
|
2252
|
+
[apiKeyPropertyKey]: {
|
|
2253
|
+
default: getEnvironmentVariable(apiKeyPropertyValue)
|
|
2254
|
+
}
|
|
2112
2255
|
},
|
|
2113
|
-
|
|
2114
|
-
|
|
2256
|
+
method: "POST",
|
|
2257
|
+
headers: `{"Authorization":"Bearer {{${apiKeyPropertyKey}}}", "Content-Type": "application/json" }`,
|
|
2258
|
+
mapBody: {
|
|
2259
|
+
prompt: {
|
|
2260
|
+
key: "messages",
|
|
2261
|
+
transform: openaiPromptSanitize
|
|
2262
|
+
},
|
|
2263
|
+
model: {
|
|
2264
|
+
key: "model"
|
|
2265
|
+
},
|
|
2266
|
+
topP: {
|
|
2267
|
+
key: "top_p"
|
|
2268
|
+
},
|
|
2269
|
+
useJson: {
|
|
2270
|
+
key: "response_format.type",
|
|
2271
|
+
transform: (v) => v ? "json_object" : "text"
|
|
2272
|
+
},
|
|
2273
|
+
effort: {
|
|
2274
|
+
key: "reasoning_effort",
|
|
2275
|
+
transform: (v, _s) => {
|
|
2276
|
+
if (
|
|
2277
|
+
// only supported reasoning models
|
|
2278
|
+
["gpt-5"].includes(_s.model) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
|
|
2279
|
+
) {
|
|
2280
|
+
return v;
|
|
2281
|
+
}
|
|
2282
|
+
return void 0;
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2115
2285
|
},
|
|
2116
|
-
|
|
2117
|
-
|
|
2286
|
+
mapOptions: {
|
|
2287
|
+
jsonSchema: (schema, options, currentInput) => ({
|
|
2288
|
+
response_format: {
|
|
2289
|
+
...currentInput?.response_format || {},
|
|
2290
|
+
type: "json_schema",
|
|
2291
|
+
json_schema: {
|
|
2292
|
+
name: "output",
|
|
2293
|
+
strict: !!options?.functionCallStrictInput,
|
|
2294
|
+
schema: cleanJsonSchemaFor(schema, "openai.chat")
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
}),
|
|
2298
|
+
functionCall: (call) => {
|
|
2299
|
+
if (call === "any") return { tool_choice: "required" };
|
|
2300
|
+
if (call === "none") return { tool_choice: "none" };
|
|
2301
|
+
if (call === "auto") return { tool_choice: "auto" };
|
|
2302
|
+
return { tool_choice: call };
|
|
2303
|
+
},
|
|
2304
|
+
functions: (functions, options) => ({
|
|
2305
|
+
tools: functions.map((f) => ({
|
|
2306
|
+
type: "function",
|
|
2307
|
+
function: {
|
|
2308
|
+
name: f.name,
|
|
2309
|
+
description: f.description,
|
|
2310
|
+
parameters: cleanJsonSchemaFor(f.parameters, "openai.chat"),
|
|
2311
|
+
strict: !!options?.functionCallStrictInput
|
|
2312
|
+
}
|
|
2313
|
+
}))
|
|
2314
|
+
})
|
|
2118
2315
|
},
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2316
|
+
transformResponse: overrides.transformResponse ?? OutputOpenAIChat
|
|
2317
|
+
};
|
|
2318
|
+
return config;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
// src/llm/config/openai/index.ts
|
|
2322
|
+
var openAiChatV1 = createOpenAiCompatibleConfiguration({
|
|
2323
|
+
key: "openai.chat.v1",
|
|
2324
|
+
provider: "openai.chat",
|
|
2325
|
+
endpoint: `https://api.openai.com/v1/chat/completions`,
|
|
2326
|
+
apiKeyMapping: ["openAiApiKey", "OPENAI_API_KEY"]
|
|
2327
|
+
});
|
|
2125
2328
|
var openAiChatMockV1 = {
|
|
2126
2329
|
key: "openai.chat-mock.v1",
|
|
2127
2330
|
provider: "openai.chat-mock",
|
|
@@ -2148,13 +2351,26 @@ var openAiChatMockV1 = {
|
|
|
2148
2351
|
},
|
|
2149
2352
|
useJson: {
|
|
2150
2353
|
key: "response_format.type",
|
|
2151
|
-
|
|
2354
|
+
transform: (v) => v ? "json_object" : "text"
|
|
2152
2355
|
}
|
|
2153
|
-
}
|
|
2356
|
+
},
|
|
2357
|
+
transformResponse: OutputOpenAIChat
|
|
2154
2358
|
};
|
|
2155
2359
|
var openai = {
|
|
2156
2360
|
"openai.chat.v1": openAiChatV1,
|
|
2157
2361
|
"openai.chat-mock.v1": openAiChatMockV1,
|
|
2362
|
+
// GPT-5 family
|
|
2363
|
+
"openai.gpt-5.2": withDefaultModel(openAiChatV1, "gpt-5.2"),
|
|
2364
|
+
"openai.gpt-5-mini": withDefaultModel(openAiChatV1, "gpt-5-mini"),
|
|
2365
|
+
"openai.gpt-5-nano": withDefaultModel(openAiChatV1, "gpt-5-nano"),
|
|
2366
|
+
// GPT-4.1 family
|
|
2367
|
+
"openai.gpt-4.1": withDefaultModel(openAiChatV1, "gpt-4.1"),
|
|
2368
|
+
"openai.gpt-4.1-mini": withDefaultModel(openAiChatV1, "gpt-4.1-mini"),
|
|
2369
|
+
"openai.gpt-4.1-nano": withDefaultModel(openAiChatV1, "gpt-4.1-nano"),
|
|
2370
|
+
// Reasoning models
|
|
2371
|
+
"openai.o3": withDefaultModel(openAiChatV1, "o3"),
|
|
2372
|
+
"openai.o4-mini": withDefaultModel(openAiChatV1, "o4-mini"),
|
|
2373
|
+
// GPT-4o family
|
|
2158
2374
|
"openai.gpt-4o": withDefaultModel(openAiChatV1, "gpt-4o"),
|
|
2159
2375
|
"openai.gpt-4o-mini": withDefaultModel(openAiChatV1, "gpt-4o-mini")
|
|
2160
2376
|
};
|
|
@@ -2193,6 +2409,20 @@ function anthropicPromptMessageCallback(_message) {
|
|
|
2193
2409
|
}
|
|
2194
2410
|
|
|
2195
2411
|
// src/llm/config/anthropic/promptSanitize.ts
|
|
2412
|
+
function mergeConsecutiveSameRole(messages) {
|
|
2413
|
+
if (messages.length <= 1) return messages;
|
|
2414
|
+
const merged = [messages[0]];
|
|
2415
|
+
for (let i = 1; i < messages.length; i++) {
|
|
2416
|
+
const prev = merged[merged.length - 1];
|
|
2417
|
+
const curr = messages[i];
|
|
2418
|
+
if (curr.role === prev.role && Array.isArray(prev.content) && Array.isArray(curr.content)) {
|
|
2419
|
+
prev.content = [...prev.content, ...curr.content];
|
|
2420
|
+
} else {
|
|
2421
|
+
merged.push(curr);
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
return merged;
|
|
2425
|
+
}
|
|
2196
2426
|
function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
2197
2427
|
if (typeof _messages === "string") {
|
|
2198
2428
|
return [{ role: "user", content: _messages }].map(
|
|
@@ -2210,14 +2440,15 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
|
2210
2440
|
}
|
|
2211
2441
|
if (first.role === "system" && messages.length > 0) {
|
|
2212
2442
|
_outputObj.system = first.content;
|
|
2213
|
-
|
|
2443
|
+
const result2 = messages.map((m) => {
|
|
2214
2444
|
if (m.role === "system") {
|
|
2215
2445
|
return { ...m, role: "user" };
|
|
2216
2446
|
}
|
|
2217
2447
|
return m;
|
|
2218
2448
|
}).map(anthropicPromptMessageCallback);
|
|
2449
|
+
return mergeConsecutiveSameRole(result2);
|
|
2219
2450
|
}
|
|
2220
|
-
|
|
2451
|
+
const result = [
|
|
2221
2452
|
first,
|
|
2222
2453
|
...messages.map((m) => {
|
|
2223
2454
|
if (m.role === "system") {
|
|
@@ -2226,10 +2457,78 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
|
2226
2457
|
return m;
|
|
2227
2458
|
})
|
|
2228
2459
|
].map(anthropicPromptMessageCallback);
|
|
2460
|
+
return mergeConsecutiveSameRole(result);
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
// src/llm/output/claude.ts
|
|
2464
|
+
function formatResult2(response) {
|
|
2465
|
+
const content = response?.content || [];
|
|
2466
|
+
const out = [];
|
|
2467
|
+
for (let i = 0; i < content.length; i++) {
|
|
2468
|
+
const result = content[i];
|
|
2469
|
+
if (result.type === "text") {
|
|
2470
|
+
out.push({
|
|
2471
|
+
type: "text",
|
|
2472
|
+
text: result.text
|
|
2473
|
+
});
|
|
2474
|
+
} else if (result.type === "tool_use") {
|
|
2475
|
+
out.push({
|
|
2476
|
+
functionId: result.id,
|
|
2477
|
+
type: "function_use",
|
|
2478
|
+
name: result.name,
|
|
2479
|
+
input: result.input
|
|
2480
|
+
});
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
return out;
|
|
2484
|
+
}
|
|
2485
|
+
function OutputAnthropicClaude3Chat(result, _config) {
|
|
2486
|
+
const id = result.id;
|
|
2487
|
+
const name = result.model || _config?.options.model?.default || "anthropic.unknown";
|
|
2488
|
+
const stopReason = result.stop_reason;
|
|
2489
|
+
const content = formatResult2(result);
|
|
2490
|
+
const usage = {
|
|
2491
|
+
input_tokens: result?.usage?.input_tokens,
|
|
2492
|
+
output_tokens: result?.usage?.output_tokens,
|
|
2493
|
+
total_tokens: result?.usage?.input_tokens + result?.usage?.output_tokens
|
|
2494
|
+
};
|
|
2495
|
+
return {
|
|
2496
|
+
id,
|
|
2497
|
+
name,
|
|
2498
|
+
created: Date.now(),
|
|
2499
|
+
usage,
|
|
2500
|
+
stopReason,
|
|
2501
|
+
content
|
|
2502
|
+
};
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
// src/llm/output/llama.ts
|
|
2506
|
+
function OutputMetaLlama3Chat(result, _config) {
|
|
2507
|
+
const id = uuidv4();
|
|
2508
|
+
const name = _config?.options?.model?.default || "meta";
|
|
2509
|
+
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
2510
|
+
const stopReason = result.stop_reason;
|
|
2511
|
+
const content = [
|
|
2512
|
+
{ type: "text", text: result.generation }
|
|
2513
|
+
];
|
|
2514
|
+
const usage = {
|
|
2515
|
+
output_tokens: result?.generation_token_count,
|
|
2516
|
+
input_tokens: result?.prompt_token_count,
|
|
2517
|
+
total_tokens: result?.generation_token_count + result?.prompt_token_count
|
|
2518
|
+
};
|
|
2519
|
+
return {
|
|
2520
|
+
id,
|
|
2521
|
+
name,
|
|
2522
|
+
created,
|
|
2523
|
+
usage,
|
|
2524
|
+
stopReason,
|
|
2525
|
+
content,
|
|
2526
|
+
options: []
|
|
2527
|
+
};
|
|
2229
2528
|
}
|
|
2230
2529
|
|
|
2231
2530
|
// src/llm/config/bedrock/index.ts
|
|
2232
|
-
var
|
|
2531
|
+
var ANTHROPIC_BEDROCK_VERSION = "bedrock-2023-05-31";
|
|
2233
2532
|
var amazonAnthropicChatV1 = {
|
|
2234
2533
|
key: "amazon:anthropic.chat.v1",
|
|
2235
2534
|
provider: "amazon:anthropic.chat",
|
|
@@ -2250,7 +2549,7 @@ var amazonAnthropicChatV1 = {
|
|
|
2250
2549
|
mapBody: {
|
|
2251
2550
|
prompt: {
|
|
2252
2551
|
key: "messages",
|
|
2253
|
-
|
|
2552
|
+
transform: anthropicPromptSanitize
|
|
2254
2553
|
},
|
|
2255
2554
|
topP: {
|
|
2256
2555
|
key: "top_p"
|
|
@@ -2261,9 +2560,26 @@ var amazonAnthropicChatV1 = {
|
|
|
2261
2560
|
},
|
|
2262
2561
|
anthropic_version: {
|
|
2263
2562
|
key: "anthropic_version",
|
|
2264
|
-
default:
|
|
2563
|
+
default: ANTHROPIC_BEDROCK_VERSION
|
|
2265
2564
|
}
|
|
2266
|
-
}
|
|
2565
|
+
},
|
|
2566
|
+
mapOptions: {
|
|
2567
|
+
functionCall: (call, _options) => {
|
|
2568
|
+
if (call === "none") return { _clearFunctions: true };
|
|
2569
|
+
if (call === "auto" || call === "any") {
|
|
2570
|
+
return { tool_choice: { type: call } };
|
|
2571
|
+
}
|
|
2572
|
+
return { tool_choice: call };
|
|
2573
|
+
},
|
|
2574
|
+
functions: (functions) => ({
|
|
2575
|
+
tools: functions.map((f) => ({
|
|
2576
|
+
name: f.name,
|
|
2577
|
+
description: f.description,
|
|
2578
|
+
input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
|
|
2579
|
+
}))
|
|
2580
|
+
})
|
|
2581
|
+
},
|
|
2582
|
+
transformResponse: OutputAnthropicClaude3Chat
|
|
2267
2583
|
};
|
|
2268
2584
|
var amazonMetaChatV1 = {
|
|
2269
2585
|
key: "amazon:meta.chat.v1",
|
|
@@ -2285,7 +2601,7 @@ var amazonMetaChatV1 = {
|
|
|
2285
2601
|
mapBody: {
|
|
2286
2602
|
prompt: {
|
|
2287
2603
|
key: "prompt",
|
|
2288
|
-
|
|
2604
|
+
transform: (messages) => {
|
|
2289
2605
|
if (typeof messages === "string") {
|
|
2290
2606
|
return messages;
|
|
2291
2607
|
} else {
|
|
@@ -2305,7 +2621,8 @@ var amazonMetaChatV1 = {
|
|
|
2305
2621
|
key: "max_gen_len",
|
|
2306
2622
|
default: 2048
|
|
2307
2623
|
}
|
|
2308
|
-
}
|
|
2624
|
+
},
|
|
2625
|
+
transformResponse: OutputMetaLlama3Chat
|
|
2309
2626
|
};
|
|
2310
2627
|
var bedrock = {
|
|
2311
2628
|
"amazon:anthropic.chat.v1": amazonAnthropicChatV1,
|
|
@@ -2344,24 +2661,74 @@ var anthropicChatV1 = {
|
|
|
2344
2661
|
},
|
|
2345
2662
|
prompt: {
|
|
2346
2663
|
key: "messages",
|
|
2347
|
-
|
|
2348
|
-
}
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2664
|
+
transform: anthropicPromptSanitize
|
|
2665
|
+
},
|
|
2666
|
+
temperature: {
|
|
2667
|
+
key: "temperature"
|
|
2668
|
+
},
|
|
2669
|
+
topP: {
|
|
2670
|
+
key: "top_p"
|
|
2671
|
+
},
|
|
2672
|
+
topK: {
|
|
2673
|
+
key: "top_k"
|
|
2674
|
+
},
|
|
2675
|
+
stopSequences: {
|
|
2676
|
+
key: "stop_sequences"
|
|
2677
|
+
},
|
|
2678
|
+
stream: {
|
|
2679
|
+
key: "stream"
|
|
2680
|
+
},
|
|
2681
|
+
metadata: {
|
|
2682
|
+
key: "metadata"
|
|
2683
|
+
},
|
|
2684
|
+
serviceTier: {
|
|
2685
|
+
key: "service_tier"
|
|
2686
|
+
// Map camelCase to snake_case
|
|
2687
|
+
}
|
|
2688
|
+
},
|
|
2689
|
+
mapOptions: {
|
|
2690
|
+
functionCall: (call, _options) => {
|
|
2691
|
+
if (call === "none") return { _clearFunctions: true };
|
|
2692
|
+
if (call === "auto" || call === "any") {
|
|
2693
|
+
return { tool_choice: { type: call } };
|
|
2694
|
+
}
|
|
2695
|
+
return { tool_choice: call };
|
|
2696
|
+
},
|
|
2697
|
+
functions: (functions) => ({
|
|
2698
|
+
tools: functions.map((f) => ({
|
|
2699
|
+
name: f.name,
|
|
2700
|
+
description: f.description,
|
|
2701
|
+
input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
|
|
2702
|
+
}))
|
|
2703
|
+
})
|
|
2704
|
+
},
|
|
2705
|
+
transformResponse: OutputAnthropicClaude3Chat
|
|
2706
|
+
};
|
|
2707
|
+
var anthropic = {
|
|
2708
|
+
"anthropic.chat.v1": anthropicChatV1,
|
|
2709
|
+
// Claude 4.6 models
|
|
2710
|
+
"anthropic.claude-opus-4-6": withDefaultModel(
|
|
2711
|
+
anthropicChatV1,
|
|
2712
|
+
"claude-opus-4-6"
|
|
2713
|
+
),
|
|
2714
|
+
"anthropic.claude-sonnet-4-6": withDefaultModel(
|
|
2715
|
+
anthropicChatV1,
|
|
2716
|
+
"claude-sonnet-4-6"
|
|
2717
|
+
),
|
|
2718
|
+
// Claude 4 models
|
|
2719
|
+
"anthropic.claude-sonnet-4": withDefaultModel(
|
|
2358
2720
|
anthropicChatV1,
|
|
2359
2721
|
"claude-sonnet-4-0"
|
|
2360
2722
|
),
|
|
2723
|
+
"anthropic.claude-opus-4": withDefaultModel(
|
|
2724
|
+
anthropicChatV1,
|
|
2725
|
+
"claude-opus-4-0"
|
|
2726
|
+
),
|
|
2361
2727
|
"anthropic.claude-3-7-sonnet": withDefaultModel(
|
|
2362
2728
|
anthropicChatV1,
|
|
2363
|
-
"claude-3-7-sonnet-
|
|
2729
|
+
"claude-3-7-sonnet-20250219"
|
|
2364
2730
|
),
|
|
2731
|
+
// Claude 3.5 models
|
|
2365
2732
|
"anthropic.claude-3-5-sonnet": withDefaultModel(
|
|
2366
2733
|
anthropicChatV1,
|
|
2367
2734
|
"claude-3-5-sonnet-latest"
|
|
@@ -2373,49 +2740,102 @@ var anthropic = {
|
|
|
2373
2740
|
// Deprecated
|
|
2374
2741
|
"anthropic.claude-3-opus": withDefaultModel(
|
|
2375
2742
|
anthropicChatV1,
|
|
2376
|
-
"claude-3-opus-
|
|
2743
|
+
"claude-3-opus-20240229"
|
|
2744
|
+
),
|
|
2745
|
+
"anthropic.claude-3-haiku": withDefaultModel(
|
|
2746
|
+
anthropicChatV1,
|
|
2747
|
+
"claude-3-haiku-20240307"
|
|
2377
2748
|
)
|
|
2378
2749
|
};
|
|
2379
2750
|
|
|
2380
2751
|
// src/llm/config/x/index.ts
|
|
2381
|
-
var xaiChatV1 = {
|
|
2752
|
+
var xaiChatV1 = createOpenAiCompatibleConfiguration({
|
|
2382
2753
|
key: "xai.chat.v1",
|
|
2383
2754
|
provider: "xai.chat",
|
|
2384
2755
|
endpoint: `https://api.x.ai/v1/chat/completions`,
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
topP: {},
|
|
2388
|
-
useJson: {},
|
|
2389
|
-
xAiApiKey: {
|
|
2390
|
-
default: getEnvironmentVariable("XAI_API_KEY")
|
|
2391
|
-
}
|
|
2392
|
-
},
|
|
2393
|
-
method: "POST",
|
|
2394
|
-
headers: `{"Authorization":"Bearer {{xAiApiKey}}", "Content-Type": "application/json" }`,
|
|
2395
|
-
mapBody: {
|
|
2396
|
-
prompt: {
|
|
2397
|
-
key: "messages",
|
|
2398
|
-
sanitize: openaiPromptSanitize
|
|
2399
|
-
},
|
|
2400
|
-
model: {
|
|
2401
|
-
key: "model"
|
|
2402
|
-
},
|
|
2403
|
-
topP: {
|
|
2404
|
-
key: "top_p"
|
|
2405
|
-
},
|
|
2406
|
-
useJson: {
|
|
2407
|
-
key: "response_format.type",
|
|
2408
|
-
sanitize: (v) => v ? "json_object" : "text"
|
|
2409
|
-
}
|
|
2410
|
-
}
|
|
2411
|
-
};
|
|
2756
|
+
apiKeyMapping: ["xAiApiKey", "XAI_API_KEY"]
|
|
2757
|
+
});
|
|
2412
2758
|
var xai = {
|
|
2413
2759
|
"xai.chat.v1": xaiChatV1,
|
|
2414
2760
|
"xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest"),
|
|
2415
2761
|
"xai.grok-3": withDefaultModel(xaiChatV1, "grok-3"),
|
|
2416
|
-
"xai.grok-
|
|
2762
|
+
"xai.grok-3-mini": withDefaultModel(xaiChatV1, "grok-3-mini"),
|
|
2763
|
+
"xai.grok-4": withDefaultModel(xaiChatV1, "grok-4"),
|
|
2764
|
+
"xai.grok-4-fast": withDefaultModel(xaiChatV1, "grok-4-fast-non-reasoning")
|
|
2417
2765
|
};
|
|
2418
2766
|
|
|
2767
|
+
// src/llm/output/_utils/combineJsonl.ts
|
|
2768
|
+
function combineJsonl(jsonl) {
|
|
2769
|
+
const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
2770
|
+
try {
|
|
2771
|
+
return JSON.parse(line);
|
|
2772
|
+
} catch (e) {
|
|
2773
|
+
throw new Error(`Invalid JSON: ${line}`);
|
|
2774
|
+
}
|
|
2775
|
+
});
|
|
2776
|
+
if (lines.length === 0) {
|
|
2777
|
+
throw new Error("No JSON lines provided.");
|
|
2778
|
+
}
|
|
2779
|
+
lines.sort(
|
|
2780
|
+
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
|
|
2781
|
+
);
|
|
2782
|
+
let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
|
|
2783
|
+
combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
|
|
2784
|
+
const finalLine = lines.find((line) => line.done === true);
|
|
2785
|
+
if (!finalLine) {
|
|
2786
|
+
throw new Error("No line found where done = true.");
|
|
2787
|
+
}
|
|
2788
|
+
const result = {
|
|
2789
|
+
model: finalLine.model,
|
|
2790
|
+
created_at: finalLine.created_at,
|
|
2791
|
+
message: {
|
|
2792
|
+
role: finalLine?.message?.role || "assistant",
|
|
2793
|
+
content: combinedContent
|
|
2794
|
+
},
|
|
2795
|
+
done_reason: finalLine.done_reason,
|
|
2796
|
+
done: finalLine.done,
|
|
2797
|
+
total_duration: finalLine.total_duration,
|
|
2798
|
+
load_duration: finalLine.load_duration,
|
|
2799
|
+
prompt_eval_count: finalLine.prompt_eval_count,
|
|
2800
|
+
prompt_eval_duration: finalLine.prompt_eval_duration,
|
|
2801
|
+
eval_count: finalLine.eval_count,
|
|
2802
|
+
eval_duration: finalLine.eval_duration
|
|
2803
|
+
};
|
|
2804
|
+
const content = {
|
|
2805
|
+
type: "text",
|
|
2806
|
+
text: combinedContent
|
|
2807
|
+
};
|
|
2808
|
+
return {
|
|
2809
|
+
lines,
|
|
2810
|
+
result,
|
|
2811
|
+
content
|
|
2812
|
+
};
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
// src/llm/output/ollama.ts
|
|
2816
|
+
function OutputOllamaChat(result, _config) {
|
|
2817
|
+
const combined = combineJsonl(result);
|
|
2818
|
+
const id = `${combined.result.model}.${combined.result.created_at}`;
|
|
2819
|
+
const name = combined.result.model || _config?.options.model?.default || "ollama.unknown";
|
|
2820
|
+
const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
|
|
2821
|
+
const stopReason = `${combined?.result?.done_reason || "stop"}`;
|
|
2822
|
+
const content = [combined.content];
|
|
2823
|
+
const usage = {
|
|
2824
|
+
output_tokens: 0,
|
|
2825
|
+
input_tokens: 0,
|
|
2826
|
+
total_tokens: 0
|
|
2827
|
+
};
|
|
2828
|
+
return {
|
|
2829
|
+
id,
|
|
2830
|
+
name,
|
|
2831
|
+
created,
|
|
2832
|
+
usage,
|
|
2833
|
+
stopReason,
|
|
2834
|
+
content,
|
|
2835
|
+
options: []
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2419
2839
|
// src/llm/config/ollama/index.ts
|
|
2420
2840
|
var ollamaChatV1 = {
|
|
2421
2841
|
key: "ollama.chat.v1",
|
|
@@ -2429,7 +2849,7 @@ var ollamaChatV1 = {
|
|
|
2429
2849
|
mapBody: {
|
|
2430
2850
|
prompt: {
|
|
2431
2851
|
key: "messages",
|
|
2432
|
-
|
|
2852
|
+
transform: (v) => {
|
|
2433
2853
|
if (typeof v === "string") {
|
|
2434
2854
|
return [{ role: "user", content: v }];
|
|
2435
2855
|
}
|
|
@@ -2439,7 +2859,8 @@ var ollamaChatV1 = {
|
|
|
2439
2859
|
model: {
|
|
2440
2860
|
key: "model"
|
|
2441
2861
|
}
|
|
2442
|
-
}
|
|
2862
|
+
},
|
|
2863
|
+
transformResponse: OutputOllamaChat
|
|
2443
2864
|
};
|
|
2444
2865
|
var ollama = {
|
|
2445
2866
|
"ollama.chat.v1": ollamaChatV1,
|
|
@@ -2461,7 +2882,7 @@ function googleGeminiPromptMessageCallback(_message) {
|
|
|
2461
2882
|
message.role = "model";
|
|
2462
2883
|
}
|
|
2463
2884
|
let { role, ...payload } = message;
|
|
2464
|
-
if (typeof payload.content === "string") {
|
|
2885
|
+
if (typeof payload.content === "string" && message.role !== "function") {
|
|
2465
2886
|
parts.push({ text: message.content });
|
|
2466
2887
|
}
|
|
2467
2888
|
if (message.role === "function") {
|
|
@@ -2484,487 +2905,75 @@ function googleGeminiPromptMessageCallback(_message) {
|
|
|
2484
2905
|
...toolsArr.map((call) => {
|
|
2485
2906
|
const { name, arguments: input } = call;
|
|
2486
2907
|
return {
|
|
2487
|
-
functionCall: {
|
|
2488
|
-
name,
|
|
2489
|
-
args: maybeParseJSON(input)
|
|
2490
|
-
}
|
|
2491
|
-
};
|
|
2492
|
-
})
|
|
2493
|
-
);
|
|
2494
|
-
delete message.function_call;
|
|
2495
|
-
}
|
|
2496
|
-
return {
|
|
2497
|
-
role,
|
|
2498
|
-
parts
|
|
2499
|
-
};
|
|
2500
|
-
}
|
|
2501
|
-
|
|
2502
|
-
// src/llm/config/google/promptSanitize.ts
|
|
2503
|
-
function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
2504
|
-
if (typeof _messages === "string") {
|
|
2505
|
-
return [{ role: "user", parts: [{ text: _messages }] }];
|
|
2506
|
-
}
|
|
2507
|
-
if (Array.isArray(_messages)) {
|
|
2508
|
-
if (_messages.length === 0) {
|
|
2509
|
-
throw new Error("Empty messages array");
|
|
2510
|
-
}
|
|
2511
|
-
if (_messages.length === 1 && _messages[0].role === "system") {
|
|
2512
|
-
return [{ role: "user", parts: [{ text: _messages[0].content }] }];
|
|
2513
|
-
}
|
|
2514
|
-
const hasSystemInstruction = _messages.some(
|
|
2515
|
-
(message) => message.role === "system"
|
|
2516
|
-
);
|
|
2517
|
-
if (hasSystemInstruction) {
|
|
2518
|
-
const theSystemInstructions = _messages.filter(
|
|
2519
|
-
(message) => message.role === "system"
|
|
2520
|
-
);
|
|
2521
|
-
const withoutSystemInstructions = _messages.filter(
|
|
2522
|
-
(message) => message.role !== "system"
|
|
2523
|
-
);
|
|
2524
|
-
_outputObj.system_instruction = {
|
|
2525
|
-
parts: theSystemInstructions.map((message) => ({
|
|
2526
|
-
text: message.content
|
|
2527
|
-
}))
|
|
2528
|
-
};
|
|
2529
|
-
return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
|
|
2530
|
-
}
|
|
2531
|
-
return _messages.map(googleGeminiPromptMessageCallback);
|
|
2532
|
-
}
|
|
2533
|
-
throw new Error("Invalid messages format");
|
|
2534
|
-
}
|
|
2535
|
-
|
|
2536
|
-
// src/llm/config/google/index.ts
|
|
2537
|
-
var googleGeminiChatV1 = {
|
|
2538
|
-
key: "google.chat.v1",
|
|
2539
|
-
provider: "google.chat",
|
|
2540
|
-
endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
|
|
2541
|
-
options: {
|
|
2542
|
-
prompt: {},
|
|
2543
|
-
// topP: {},
|
|
2544
|
-
geminiApiKey: {
|
|
2545
|
-
default: getEnvironmentVariable("GEMINI_API_KEY")
|
|
2546
|
-
}
|
|
2547
|
-
},
|
|
2548
|
-
method: "POST",
|
|
2549
|
-
headers: `{"Content-Type": "application/json" }`,
|
|
2550
|
-
mapBody: {
|
|
2551
|
-
prompt: {
|
|
2552
|
-
key: "contents",
|
|
2553
|
-
sanitize: googleGeminiPromptSanitize
|
|
2554
|
-
}
|
|
2555
|
-
// topP: {
|
|
2556
|
-
// key: "top_p",
|
|
2557
|
-
// }
|
|
2558
|
-
}
|
|
2559
|
-
};
|
|
2560
|
-
var google = {
|
|
2561
|
-
"google.chat.v1": googleGeminiChatV1,
|
|
2562
|
-
"google.gemini-2.0-flash": withDefaultModel(
|
|
2563
|
-
googleGeminiChatV1,
|
|
2564
|
-
"gemini-2.0-flash"
|
|
2565
|
-
),
|
|
2566
|
-
"google.gemini-2.0-flash-lite": withDefaultModel(
|
|
2567
|
-
googleGeminiChatV1,
|
|
2568
|
-
"gemini-2.0-flash-lite"
|
|
2569
|
-
),
|
|
2570
|
-
"google.gemini-2.5-flash": withDefaultModel(
|
|
2571
|
-
googleGeminiChatV1,
|
|
2572
|
-
"gemini-2.5-flash"
|
|
2573
|
-
),
|
|
2574
|
-
"google.gemini-2.5-flash-lite": withDefaultModel(
|
|
2575
|
-
googleGeminiChatV1,
|
|
2576
|
-
"gemini-2.5-flash-lite"
|
|
2577
|
-
),
|
|
2578
|
-
"google.gemini-1.5-pro": withDefaultModel(
|
|
2579
|
-
googleGeminiChatV1,
|
|
2580
|
-
"gemini-1.5-pro"
|
|
2581
|
-
),
|
|
2582
|
-
"google.gemini-2.5-pro": withDefaultModel(
|
|
2583
|
-
googleGeminiChatV1,
|
|
2584
|
-
"gemini-2.5-pro"
|
|
2585
|
-
)
|
|
2586
|
-
};
|
|
2587
|
-
|
|
2588
|
-
// src/llm/config/deepseek/index.ts
|
|
2589
|
-
var deepseekChatV1 = {
|
|
2590
|
-
key: "deepseek.chat.v1",
|
|
2591
|
-
provider: "deepseek.chat",
|
|
2592
|
-
endpoint: `https://api.deepseek.com/v1/chat/completions`,
|
|
2593
|
-
options: {
|
|
2594
|
-
prompt: {},
|
|
2595
|
-
topP: {},
|
|
2596
|
-
useJson: {},
|
|
2597
|
-
deepseekApiKey: {
|
|
2598
|
-
default: getEnvironmentVariable("DEEPSEEK_API_KEY")
|
|
2599
|
-
}
|
|
2600
|
-
},
|
|
2601
|
-
method: "POST",
|
|
2602
|
-
headers: `{"Authorization":"Bearer {{deepseekApiKey}}", "Content-Type": "application/json" }`,
|
|
2603
|
-
mapBody: {
|
|
2604
|
-
prompt: {
|
|
2605
|
-
key: "messages",
|
|
2606
|
-
sanitize: openaiPromptSanitize
|
|
2607
|
-
},
|
|
2608
|
-
model: {
|
|
2609
|
-
key: "model"
|
|
2610
|
-
},
|
|
2611
|
-
topP: {
|
|
2612
|
-
key: "top_p"
|
|
2613
|
-
},
|
|
2614
|
-
useJson: {
|
|
2615
|
-
key: "response_format.type",
|
|
2616
|
-
sanitize: (v) => v ? "json_object" : "text"
|
|
2617
|
-
}
|
|
2618
|
-
}
|
|
2619
|
-
};
|
|
2620
|
-
var deepseek = {
|
|
2621
|
-
"deepseek.chat.v1": deepseekChatV1,
|
|
2622
|
-
"deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
|
|
2623
|
-
};
|
|
2624
|
-
|
|
2625
|
-
// src/llm/config.ts
|
|
2626
|
-
var configs = {
|
|
2627
|
-
...openai,
|
|
2628
|
-
...anthropic,
|
|
2629
|
-
...bedrock,
|
|
2630
|
-
...xai,
|
|
2631
|
-
...ollama,
|
|
2632
|
-
...google,
|
|
2633
|
-
...deepseek
|
|
2634
|
-
};
|
|
2635
|
-
function getLlmConfig(provider) {
|
|
2636
|
-
if (!provider) {
|
|
2637
|
-
throw new LlmExeError(`Missing provider`, "unknown", {
|
|
2638
|
-
error: "Missing provider",
|
|
2639
|
-
resolution: "Provide a valid provider"
|
|
2640
|
-
});
|
|
2641
|
-
}
|
|
2642
|
-
const pick2 = configs[provider];
|
|
2643
|
-
if (pick2) {
|
|
2644
|
-
return pick2;
|
|
2645
|
-
}
|
|
2646
|
-
throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
|
|
2647
|
-
provider,
|
|
2648
|
-
error: `Invalid provider: ${provider}`,
|
|
2649
|
-
resolution: "Provide a valid provider"
|
|
2650
|
-
});
|
|
2651
|
-
}
|
|
2652
|
-
|
|
2653
|
-
// src/llm/output/_utils/getResultContent.ts
|
|
2654
|
-
function getResultContent(result, index) {
|
|
2655
|
-
if (typeof index === "number" && index > 0) {
|
|
2656
|
-
const arr = result?.options || [];
|
|
2657
|
-
const val = arr[index];
|
|
2658
|
-
return val ? val : [];
|
|
2659
|
-
}
|
|
2660
|
-
return [...result.content];
|
|
2661
|
-
}
|
|
2662
|
-
|
|
2663
|
-
// src/llm/output/_utils/getResultText.ts
|
|
2664
|
-
function getResultText(result, index) {
|
|
2665
|
-
if (typeof index === "number" && index > 0) {
|
|
2666
|
-
const arr = result?.options || [];
|
|
2667
|
-
const val = arr[index];
|
|
2668
|
-
return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
|
|
2669
|
-
}
|
|
2670
|
-
return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
|
|
2671
|
-
}
|
|
2672
|
-
|
|
2673
|
-
// src/llm/output/base.ts
|
|
2674
|
-
function BaseLlmOutput2(result) {
|
|
2675
|
-
const __result = Object.freeze({
|
|
2676
|
-
id: result.id || uuidv4(),
|
|
2677
|
-
name: result.name,
|
|
2678
|
-
usage: result.usage,
|
|
2679
|
-
stopReason: result.stopReason,
|
|
2680
|
-
options: [...result?.options || []],
|
|
2681
|
-
content: [...result.content],
|
|
2682
|
-
created: result?.created || (/* @__PURE__ */ new Date()).getTime()
|
|
2683
|
-
});
|
|
2684
|
-
function getResult() {
|
|
2685
|
-
return {
|
|
2686
|
-
id: __result.id,
|
|
2687
|
-
name: __result.name,
|
|
2688
|
-
created: __result.created,
|
|
2689
|
-
usage: __result.usage,
|
|
2690
|
-
options: __result.options,
|
|
2691
|
-
content: __result.content,
|
|
2692
|
-
stopReason: __result.stopReason
|
|
2693
|
-
};
|
|
2694
|
-
}
|
|
2695
|
-
return {
|
|
2696
|
-
getResultContent: (index) => getResultContent(__result, index),
|
|
2697
|
-
getResultText: (index) => getResultText(__result, index),
|
|
2698
|
-
getResult
|
|
2699
|
-
};
|
|
2700
|
-
}
|
|
2701
|
-
|
|
2702
|
-
// src/llm/output/_util.ts
|
|
2703
|
-
function normalizeFunctionCall(input, provider) {
|
|
2704
|
-
if (input === "any") {
|
|
2705
|
-
if (provider === "openai") {
|
|
2706
|
-
return "required";
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
return input;
|
|
2710
|
-
}
|
|
2711
|
-
function formatOptions(response, handler) {
|
|
2712
|
-
const out = [];
|
|
2713
|
-
for (const item of response) {
|
|
2714
|
-
const result = handler(item);
|
|
2715
|
-
if (result) {
|
|
2716
|
-
out.push([result]);
|
|
2717
|
-
}
|
|
2718
|
-
}
|
|
2719
|
-
return out;
|
|
2720
|
-
}
|
|
2721
|
-
|
|
2722
|
-
// src/llm/output/openai.ts
|
|
2723
|
-
function formatResult(result) {
|
|
2724
|
-
const out = [];
|
|
2725
|
-
if (typeof result?.message?.content === "string") {
|
|
2726
|
-
out.push({
|
|
2727
|
-
type: "text",
|
|
2728
|
-
text: result.message.content
|
|
2729
|
-
});
|
|
2730
|
-
}
|
|
2731
|
-
if (result?.message?.tool_calls) {
|
|
2732
|
-
for (const call of result.message.tool_calls) {
|
|
2733
|
-
out.push({
|
|
2734
|
-
functionId: call.id,
|
|
2735
|
-
type: "function_use",
|
|
2736
|
-
name: call.function.name,
|
|
2737
|
-
input: maybeParseJSON(call.function.arguments)
|
|
2738
|
-
});
|
|
2739
|
-
}
|
|
2740
|
-
}
|
|
2741
|
-
return out;
|
|
2742
|
-
}
|
|
2743
|
-
function OutputOpenAIChat(result, _config) {
|
|
2744
|
-
const id = result.id;
|
|
2745
|
-
const name = result.model || _config?.model || "openai.unknown";
|
|
2746
|
-
const created = result.created;
|
|
2747
|
-
const [_content, ..._options] = result?.choices || [];
|
|
2748
|
-
const stopReason = _content?.finish_reason;
|
|
2749
|
-
const content = formatResult(_content);
|
|
2750
|
-
const options = formatOptions(_options, formatResult);
|
|
2751
|
-
const usage = {
|
|
2752
|
-
output_tokens: result?.usage?.completion_tokens,
|
|
2753
|
-
input_tokens: result?.usage?.prompt_tokens,
|
|
2754
|
-
total_tokens: result?.usage?.total_tokens
|
|
2755
|
-
};
|
|
2756
|
-
return BaseLlmOutput2({
|
|
2757
|
-
id,
|
|
2758
|
-
name,
|
|
2759
|
-
created,
|
|
2760
|
-
usage,
|
|
2761
|
-
stopReason,
|
|
2762
|
-
content,
|
|
2763
|
-
options
|
|
2764
|
-
});
|
|
2765
|
-
}
|
|
2766
|
-
|
|
2767
|
-
// src/llm/output/claude.ts
|
|
2768
|
-
function formatResult2(response) {
|
|
2769
|
-
const content = response?.content || [];
|
|
2770
|
-
const out = [];
|
|
2771
|
-
for (let i = 0; i < content.length; i++) {
|
|
2772
|
-
const result = content[i];
|
|
2773
|
-
if (result.type === "text") {
|
|
2774
|
-
out.push({
|
|
2775
|
-
type: "text",
|
|
2776
|
-
text: result.text
|
|
2777
|
-
});
|
|
2778
|
-
} else if (result.type === "tool_use") {
|
|
2779
|
-
out.push({
|
|
2780
|
-
functionId: result.id,
|
|
2781
|
-
type: "function_use",
|
|
2782
|
-
name: result.name,
|
|
2783
|
-
input: result.input
|
|
2784
|
-
});
|
|
2785
|
-
}
|
|
2786
|
-
}
|
|
2787
|
-
return out;
|
|
2788
|
-
}
|
|
2789
|
-
function OutputAnthropicClaude3Chat(result, _config) {
|
|
2790
|
-
const id = result.id;
|
|
2791
|
-
const name = result.model || _config?.model || "anthropic.unknown";
|
|
2792
|
-
const stopReason = result.stop_reason;
|
|
2793
|
-
const content = formatResult2(result);
|
|
2794
|
-
const usage = {
|
|
2795
|
-
input_tokens: result?.usage?.input_tokens,
|
|
2796
|
-
output_tokens: result?.usage?.output_tokens,
|
|
2797
|
-
total_tokens: result?.usage?.input_tokens + result?.usage?.input_tokens
|
|
2798
|
-
};
|
|
2799
|
-
return BaseLlmOutput2({
|
|
2800
|
-
id,
|
|
2801
|
-
name,
|
|
2802
|
-
usage,
|
|
2803
|
-
stopReason,
|
|
2804
|
-
content
|
|
2805
|
-
});
|
|
2806
|
-
}
|
|
2807
|
-
|
|
2808
|
-
// src/llm/output/llama.ts
|
|
2809
|
-
function OutputMetaLlama3Chat(result, _config) {
|
|
2810
|
-
const name = _config?.model || "meta";
|
|
2811
|
-
const stopReason = result.stop_reason;
|
|
2812
|
-
const content = [
|
|
2813
|
-
{ type: "text", text: result.generation }
|
|
2814
|
-
];
|
|
2815
|
-
const usage = {
|
|
2816
|
-
output_tokens: result?.generation_token_count,
|
|
2817
|
-
input_tokens: result?.prompt_token_count,
|
|
2818
|
-
total_tokens: result?.generation_token_count + result?.prompt_token_count
|
|
2819
|
-
};
|
|
2820
|
-
return BaseLlmOutput2({
|
|
2821
|
-
name,
|
|
2822
|
-
usage,
|
|
2823
|
-
stopReason,
|
|
2824
|
-
content
|
|
2825
|
-
});
|
|
2826
|
-
}
|
|
2827
|
-
|
|
2828
|
-
// src/llm/output/default.ts
|
|
2829
|
-
function OutputDefault(result, _config) {
|
|
2830
|
-
const name = _config.model || "unknown";
|
|
2831
|
-
const stopReason = result?.stopReason || "stop";
|
|
2832
|
-
const content = [];
|
|
2833
|
-
if (result?.text) {
|
|
2834
|
-
content.push({ type: "text", text: result.text });
|
|
2835
|
-
}
|
|
2836
|
-
const usage = {
|
|
2837
|
-
output_tokens: result?.output_tokens || 0,
|
|
2838
|
-
input_tokens: result?.input_tokens || 0,
|
|
2839
|
-
total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
|
|
2840
|
-
};
|
|
2841
|
-
return BaseLlmOutput2({
|
|
2842
|
-
name,
|
|
2843
|
-
usage,
|
|
2844
|
-
stopReason,
|
|
2845
|
-
content
|
|
2846
|
-
});
|
|
2847
|
-
}
|
|
2848
|
-
|
|
2849
|
-
// src/llm/output/xai.ts
|
|
2850
|
-
function formatResult3(result) {
|
|
2851
|
-
const out = [];
|
|
2852
|
-
if (typeof result?.message?.content === "string") {
|
|
2853
|
-
out.push({
|
|
2854
|
-
type: "text",
|
|
2855
|
-
text: result.message.content
|
|
2856
|
-
});
|
|
2857
|
-
}
|
|
2858
|
-
if (result?.message?.tool_calls) {
|
|
2859
|
-
for (const call of result.message.tool_calls) {
|
|
2860
|
-
out.push({
|
|
2861
|
-
functionId: call.id,
|
|
2862
|
-
type: "function_use",
|
|
2863
|
-
name: call.function.name,
|
|
2864
|
-
input: maybeParseJSON(call.function.arguments)
|
|
2865
|
-
});
|
|
2866
|
-
}
|
|
2867
|
-
}
|
|
2868
|
-
return out;
|
|
2869
|
-
}
|
|
2870
|
-
function OutputXAIChat(result, _config) {
|
|
2871
|
-
const id = result.id;
|
|
2872
|
-
const name = result.model || _config?.model || "openai.unknown";
|
|
2873
|
-
const created = result.created;
|
|
2874
|
-
const [_content, ..._options] = result?.choices || [];
|
|
2875
|
-
const stopReason = _content?.finish_reason;
|
|
2876
|
-
const content = formatResult3(_content);
|
|
2877
|
-
const options = formatOptions(_options, formatResult3);
|
|
2878
|
-
const usage = {
|
|
2879
|
-
output_tokens: result?.usage?.completion_tokens,
|
|
2880
|
-
input_tokens: result?.usage?.prompt_tokens,
|
|
2881
|
-
total_tokens: result?.usage?.total_tokens
|
|
2882
|
-
};
|
|
2883
|
-
return BaseLlmOutput2({
|
|
2884
|
-
id,
|
|
2885
|
-
name,
|
|
2886
|
-
created,
|
|
2887
|
-
usage,
|
|
2888
|
-
stopReason,
|
|
2889
|
-
content,
|
|
2890
|
-
options
|
|
2891
|
-
});
|
|
2892
|
-
}
|
|
2893
|
-
|
|
2894
|
-
// src/llm/output/_utils/combineJsonl.ts
|
|
2895
|
-
function combineJsonl(jsonl) {
|
|
2896
|
-
const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
2897
|
-
try {
|
|
2898
|
-
return JSON.parse(line);
|
|
2899
|
-
} catch (e) {
|
|
2900
|
-
throw new Error(`Invalid JSON: ${line}`);
|
|
2901
|
-
}
|
|
2902
|
-
});
|
|
2903
|
-
if (lines.length === 0) {
|
|
2904
|
-
throw new Error("No JSON lines provided.");
|
|
2905
|
-
}
|
|
2906
|
-
lines.sort(
|
|
2907
|
-
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
|
|
2908
|
-
);
|
|
2909
|
-
let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
|
|
2910
|
-
combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
|
|
2911
|
-
const finalLine = lines.find((line) => line.done === true);
|
|
2912
|
-
if (!finalLine) {
|
|
2913
|
-
throw new Error("No line found where done = true.");
|
|
2914
|
-
}
|
|
2915
|
-
const result = {
|
|
2916
|
-
model: finalLine.model,
|
|
2917
|
-
created_at: finalLine.created_at,
|
|
2918
|
-
message: {
|
|
2919
|
-
role: finalLine?.message?.role || "assistant",
|
|
2920
|
-
content: combinedContent
|
|
2921
|
-
},
|
|
2922
|
-
done_reason: finalLine.done_reason,
|
|
2923
|
-
done: finalLine.done,
|
|
2924
|
-
total_duration: finalLine.total_duration,
|
|
2925
|
-
load_duration: finalLine.load_duration,
|
|
2926
|
-
prompt_eval_count: finalLine.prompt_eval_count,
|
|
2927
|
-
prompt_eval_duration: finalLine.prompt_eval_duration,
|
|
2928
|
-
eval_count: finalLine.eval_count,
|
|
2929
|
-
eval_duration: finalLine.eval_duration
|
|
2930
|
-
};
|
|
2931
|
-
const content = {
|
|
2932
|
-
type: "text",
|
|
2933
|
-
text: combinedContent
|
|
2934
|
-
};
|
|
2908
|
+
functionCall: {
|
|
2909
|
+
name,
|
|
2910
|
+
args: maybeParseJSON(input)
|
|
2911
|
+
}
|
|
2912
|
+
};
|
|
2913
|
+
})
|
|
2914
|
+
);
|
|
2915
|
+
delete message.function_call;
|
|
2916
|
+
}
|
|
2935
2917
|
return {
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
content
|
|
2918
|
+
role,
|
|
2919
|
+
parts
|
|
2939
2920
|
};
|
|
2940
2921
|
}
|
|
2941
2922
|
|
|
2942
|
-
// src/llm/
|
|
2943
|
-
function
|
|
2944
|
-
|
|
2945
|
-
const
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
}
|
|
2955
|
-
return
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2923
|
+
// src/llm/config/google/promptSanitize.ts
|
|
2924
|
+
function mergeConsecutiveSameRole2(messages) {
|
|
2925
|
+
if (messages.length <= 1) return messages;
|
|
2926
|
+
const merged = [messages[0]];
|
|
2927
|
+
for (let i = 1; i < messages.length; i++) {
|
|
2928
|
+
const prev = merged[merged.length - 1];
|
|
2929
|
+
const curr = messages[i];
|
|
2930
|
+
if (curr.role === prev.role && Array.isArray(prev.parts) && Array.isArray(curr.parts)) {
|
|
2931
|
+
prev.parts = [...prev.parts, ...curr.parts];
|
|
2932
|
+
} else {
|
|
2933
|
+
merged.push(curr);
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2936
|
+
return merged;
|
|
2937
|
+
}
|
|
2938
|
+
function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
2939
|
+
if (typeof _messages === "string") {
|
|
2940
|
+
return [{ role: "user", parts: [{ text: _messages }] }];
|
|
2941
|
+
}
|
|
2942
|
+
if (Array.isArray(_messages)) {
|
|
2943
|
+
if (_messages.length === 0) {
|
|
2944
|
+
throw new Error("Empty messages array");
|
|
2945
|
+
}
|
|
2946
|
+
if (_messages.length === 1 && _messages[0].role === "system") {
|
|
2947
|
+
return [{ role: "user", parts: [{ text: _messages[0].content }] }];
|
|
2948
|
+
}
|
|
2949
|
+
const hasSystemInstruction = _messages.some(
|
|
2950
|
+
(message) => message.role === "system"
|
|
2951
|
+
);
|
|
2952
|
+
if (hasSystemInstruction) {
|
|
2953
|
+
const theSystemInstructions = _messages.filter(
|
|
2954
|
+
(message) => message.role === "system"
|
|
2955
|
+
);
|
|
2956
|
+
const withoutSystemInstructions = _messages.filter(
|
|
2957
|
+
(message) => message.role !== "system"
|
|
2958
|
+
);
|
|
2959
|
+
_outputObj.system_instruction = {
|
|
2960
|
+
parts: theSystemInstructions.map((message) => ({
|
|
2961
|
+
text: message.content
|
|
2962
|
+
}))
|
|
2963
|
+
};
|
|
2964
|
+
const result2 = withoutSystemInstructions.map(
|
|
2965
|
+
googleGeminiPromptMessageCallback
|
|
2966
|
+
);
|
|
2967
|
+
return mergeConsecutiveSameRole2(result2);
|
|
2968
|
+
}
|
|
2969
|
+
const result = _messages.map(googleGeminiPromptMessageCallback);
|
|
2970
|
+
return mergeConsecutiveSameRole2(result);
|
|
2971
|
+
}
|
|
2972
|
+
throw new Error("Invalid messages format");
|
|
2964
2973
|
}
|
|
2965
2974
|
|
|
2966
2975
|
// src/llm/output/google.gemini/formatResult.ts
|
|
2967
|
-
function
|
|
2976
|
+
function formatResult3(result, id) {
|
|
2968
2977
|
const { parts = [] } = result?.content || {};
|
|
2969
2978
|
const out = [];
|
|
2970
2979
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -2989,18 +2998,18 @@ function formatResult4(result, id) {
|
|
|
2989
2998
|
// src/llm/output/google.gemini/index.ts
|
|
2990
2999
|
function OutputGoogleGeminiChat(result, _config) {
|
|
2991
3000
|
const id = result.responseId;
|
|
2992
|
-
const name = result.modelVersion || _config?.model || "gemini";
|
|
3001
|
+
const name = result.modelVersion || _config?.options.model?.default || "gemini";
|
|
2993
3002
|
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
2994
3003
|
const [_content, ..._options] = result?.candidates || [];
|
|
2995
3004
|
const stopReason = _content?.finishReason?.toLowerCase();
|
|
2996
|
-
const content =
|
|
2997
|
-
const options = formatOptions(_options,
|
|
3005
|
+
const content = formatResult3(_content, id);
|
|
3006
|
+
const options = formatOptions(_options, formatResult3);
|
|
2998
3007
|
const usage = {
|
|
2999
3008
|
output_tokens: result?.usageMetadata?.candidatesTokenCount,
|
|
3000
3009
|
input_tokens: result?.usageMetadata?.promptTokenCount,
|
|
3001
3010
|
total_tokens: result?.usageMetadata?.totalTokenCount
|
|
3002
3011
|
};
|
|
3003
|
-
return
|
|
3012
|
+
return {
|
|
3004
3013
|
id,
|
|
3005
3014
|
name,
|
|
3006
3015
|
created,
|
|
@@ -3008,83 +3017,152 @@ function OutputGoogleGeminiChat(result, _config) {
|
|
|
3008
3017
|
stopReason,
|
|
3009
3018
|
content,
|
|
3010
3019
|
options
|
|
3011
|
-
}
|
|
3020
|
+
};
|
|
3012
3021
|
}
|
|
3013
3022
|
|
|
3014
|
-
// src/llm/
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3023
|
+
// src/llm/config/google/index.ts
|
|
3024
|
+
var googleGeminiChatV1 = {
|
|
3025
|
+
key: "google.chat.v1",
|
|
3026
|
+
provider: "google.chat",
|
|
3027
|
+
endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
|
|
3028
|
+
options: {
|
|
3029
|
+
effort: {},
|
|
3030
|
+
prompt: {},
|
|
3031
|
+
// topP: {},
|
|
3032
|
+
geminiApiKey: {
|
|
3033
|
+
default: getEnvironmentVariable("GEMINI_API_KEY")
|
|
3034
|
+
}
|
|
3035
|
+
},
|
|
3036
|
+
method: "POST",
|
|
3037
|
+
headers: `{"Content-Type": "application/json" }`,
|
|
3038
|
+
mapBody: {
|
|
3039
|
+
prompt: {
|
|
3040
|
+
key: "contents",
|
|
3041
|
+
transform: googleGeminiPromptSanitize
|
|
3042
|
+
},
|
|
3043
|
+
effort: {
|
|
3044
|
+
key: "config.thinkingConfig.thinkingBudget",
|
|
3045
|
+
transform: (v, _s) => {
|
|
3046
|
+
if (
|
|
3047
|
+
// only supported reasoning models
|
|
3048
|
+
["gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-light"].includes(
|
|
3049
|
+
_s.model
|
|
3050
|
+
) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
|
|
3051
|
+
) {
|
|
3052
|
+
if (v === "low" || v === "minimal") {
|
|
3053
|
+
return 1024;
|
|
3054
|
+
} else if (v === "medium") {
|
|
3055
|
+
return 8192;
|
|
3056
|
+
} else if (v === "high") {
|
|
3057
|
+
return 24576;
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
return void 0;
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
},
|
|
3064
|
+
mapOptions: {
|
|
3065
|
+
functionCall: (call) => ({
|
|
3066
|
+
toolConfig: {
|
|
3067
|
+
functionCallingConfig: {
|
|
3068
|
+
mode: call === "any" ? "any" : call === "none" ? "none" : "auto"
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
}),
|
|
3072
|
+
functions: (functions) => ({
|
|
3073
|
+
tools: [
|
|
3074
|
+
{
|
|
3075
|
+
functionDeclarations: functions.map((f) => ({
|
|
3076
|
+
name: f.name,
|
|
3077
|
+
description: f.description,
|
|
3078
|
+
parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
|
|
3079
|
+
}))
|
|
3080
|
+
}
|
|
3081
|
+
]
|
|
3082
|
+
})
|
|
3083
|
+
},
|
|
3084
|
+
transformResponse: OutputGoogleGeminiChat
|
|
3085
|
+
};
|
|
3086
|
+
var google = {
|
|
3087
|
+
"google.chat.v1": googleGeminiChatV1,
|
|
3088
|
+
"google.gemini-2.0-flash": withDefaultModel(
|
|
3089
|
+
googleGeminiChatV1,
|
|
3090
|
+
"gemini-2.0-flash"
|
|
3091
|
+
),
|
|
3092
|
+
"google.gemini-2.0-flash-lite": withDefaultModel(
|
|
3093
|
+
googleGeminiChatV1,
|
|
3094
|
+
"gemini-2.0-flash-lite"
|
|
3095
|
+
),
|
|
3096
|
+
"google.gemini-2.5-flash": withDefaultModel(
|
|
3097
|
+
googleGeminiChatV1,
|
|
3098
|
+
"gemini-2.5-flash"
|
|
3099
|
+
),
|
|
3100
|
+
"google.gemini-2.5-flash-lite": withDefaultModel(
|
|
3101
|
+
googleGeminiChatV1,
|
|
3102
|
+
"gemini-2.5-flash-lite"
|
|
3103
|
+
),
|
|
3104
|
+
"google.gemini-1.5-pro": withDefaultModel(
|
|
3105
|
+
googleGeminiChatV1,
|
|
3106
|
+
"gemini-1.5-pro"
|
|
3107
|
+
),
|
|
3108
|
+
"google.gemini-2.5-pro": withDefaultModel(
|
|
3109
|
+
googleGeminiChatV1,
|
|
3110
|
+
"gemini-2.5-pro"
|
|
3111
|
+
)
|
|
3112
|
+
};
|
|
3113
|
+
|
|
3114
|
+
// src/llm/config/deepseek/index.ts
|
|
3115
|
+
var deepseekChatV1 = createOpenAiCompatibleConfiguration({
|
|
3116
|
+
key: "deepseek.chat.v1",
|
|
3117
|
+
provider: "deepseek.chat",
|
|
3118
|
+
endpoint: `https://api.deepseek.com/v1/chat/completions`,
|
|
3119
|
+
apiKeyMapping: ["deepseekApiKey", "DEEPSEEK_API_KEY"]
|
|
3120
|
+
});
|
|
3121
|
+
var deepseek = {
|
|
3122
|
+
"deepseek.chat.v1": deepseekChatV1,
|
|
3123
|
+
"deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
|
|
3124
|
+
};
|
|
3125
|
+
|
|
3126
|
+
// src/llm/config.ts
|
|
3127
|
+
var configs = {
|
|
3128
|
+
...openai,
|
|
3129
|
+
...anthropic,
|
|
3130
|
+
...bedrock,
|
|
3131
|
+
...xai,
|
|
3132
|
+
...ollama,
|
|
3133
|
+
...google,
|
|
3134
|
+
...deepseek
|
|
3135
|
+
};
|
|
3136
|
+
function getLlmConfig(provider) {
|
|
3137
|
+
if (!provider) {
|
|
3138
|
+
throw new LlmExeError(`Missing provider`, "unknown", {
|
|
3139
|
+
error: "Missing provider",
|
|
3140
|
+
resolution: "Provide a valid provider"
|
|
3021
3141
|
});
|
|
3022
3142
|
}
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
functionId: call.id,
|
|
3027
|
-
type: "function_use",
|
|
3028
|
-
name: call.function.name,
|
|
3029
|
-
input: maybeParseJSON(call.function.arguments)
|
|
3030
|
-
});
|
|
3031
|
-
}
|
|
3143
|
+
const pick2 = configs[provider];
|
|
3144
|
+
if (pick2) {
|
|
3145
|
+
return pick2;
|
|
3032
3146
|
}
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
const name = result.model || _config?.model || "deepseek.unknown";
|
|
3038
|
-
const created = result.created;
|
|
3039
|
-
const [_content, ..._options] = result?.choices || [];
|
|
3040
|
-
const stopReason = _content?.finish_reason;
|
|
3041
|
-
const content = formatResult5(_content);
|
|
3042
|
-
const options = formatOptions(_options, formatResult5);
|
|
3043
|
-
const usage = {
|
|
3044
|
-
output_tokens: result?.usage?.completion_tokens,
|
|
3045
|
-
input_tokens: result?.usage?.prompt_tokens,
|
|
3046
|
-
total_tokens: result?.usage?.total_tokens
|
|
3047
|
-
};
|
|
3048
|
-
return BaseLlmOutput2({
|
|
3049
|
-
id,
|
|
3050
|
-
name,
|
|
3051
|
-
created,
|
|
3052
|
-
usage,
|
|
3053
|
-
stopReason,
|
|
3054
|
-
content,
|
|
3055
|
-
options
|
|
3147
|
+
throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
|
|
3148
|
+
provider,
|
|
3149
|
+
error: `Invalid provider: ${provider}`,
|
|
3150
|
+
resolution: "Provide a valid provider"
|
|
3056
3151
|
});
|
|
3057
3152
|
}
|
|
3058
3153
|
|
|
3059
|
-
// src/
|
|
3060
|
-
function
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
return OutputMetaLlama3Chat(response, config);
|
|
3070
|
-
// case "amazon:nova.chat.v1":
|
|
3071
|
-
// return OutputDefault(response, config);
|
|
3072
|
-
case "xai.chat.v1":
|
|
3073
|
-
return OutputXAIChat(response, config);
|
|
3074
|
-
case "ollama.chat.v1":
|
|
3075
|
-
return OutputOllamaChat(response, config);
|
|
3076
|
-
case "google.chat.v1":
|
|
3077
|
-
return OutputGoogleGeminiChat(response, config);
|
|
3078
|
-
case "deepseek.chat.v1":
|
|
3079
|
-
return OutputDeepSeekChat(response, config);
|
|
3080
|
-
// use oai for now
|
|
3081
|
-
default: {
|
|
3082
|
-
if (config?.key?.startsWith("custom:")) {
|
|
3083
|
-
return OutputDefault(response, config);
|
|
3084
|
-
}
|
|
3085
|
-
throw new Error("Unsupported provider");
|
|
3154
|
+
// src/utils/modules/maskApiKeysInDebug.ts
|
|
3155
|
+
function maskApiKeys(log) {
|
|
3156
|
+
return log.replace(
|
|
3157
|
+
/\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,
|
|
3158
|
+
(match) => {
|
|
3159
|
+
if (match.length <= 8) return match;
|
|
3160
|
+
const prefix = match.substring(0, 4);
|
|
3161
|
+
const suffix = match.substring(match.length - 4);
|
|
3162
|
+
const maskLength = match.length - 8;
|
|
3163
|
+
return `${prefix}${"*".repeat(maskLength)}${suffix}`;
|
|
3086
3164
|
}
|
|
3087
|
-
|
|
3165
|
+
);
|
|
3088
3166
|
}
|
|
3089
3167
|
|
|
3090
3168
|
// src/utils/modules/debug.ts
|
|
@@ -3110,7 +3188,15 @@ function debug(...args) {
|
|
|
3110
3188
|
logs.push(arg.toString());
|
|
3111
3189
|
} else {
|
|
3112
3190
|
try {
|
|
3113
|
-
|
|
3191
|
+
let shouldMask = false;
|
|
3192
|
+
if (arg.headers && arg.headers.Authorization) {
|
|
3193
|
+
shouldMask = true;
|
|
3194
|
+
}
|
|
3195
|
+
let str = JSON.stringify(arg, null, 2);
|
|
3196
|
+
if (shouldMask) {
|
|
3197
|
+
str = maskApiKeys(str);
|
|
3198
|
+
}
|
|
3199
|
+
logs.push(str);
|
|
3114
3200
|
} catch (error) {
|
|
3115
3201
|
console.error("Error parsing object:", error);
|
|
3116
3202
|
}
|
|
@@ -3158,7 +3244,8 @@ async function apiRequest(url, options) {
|
|
|
3158
3244
|
}
|
|
3159
3245
|
throw new Error(message);
|
|
3160
3246
|
}
|
|
3161
|
-
|
|
3247
|
+
const contentType = response.headers.get("content-type");
|
|
3248
|
+
if (contentType?.includes("application/json")) {
|
|
3162
3249
|
const responseData = await response.json();
|
|
3163
3250
|
return responseData;
|
|
3164
3251
|
} else {
|
|
@@ -3175,20 +3262,26 @@ async function apiRequest(url, options) {
|
|
|
3175
3262
|
function convertDotNotation(obj) {
|
|
3176
3263
|
const result = {};
|
|
3177
3264
|
for (const key in obj) {
|
|
3178
|
-
if (
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3265
|
+
if (Object.prototype.hasOwnProperty.call(obj, key) && !key.includes(".")) {
|
|
3266
|
+
result[key] = obj[key];
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
for (const key in obj) {
|
|
3270
|
+
if (Object.prototype.hasOwnProperty.call(obj, key) && key.includes(".")) {
|
|
3271
|
+
const keys = key.split(".");
|
|
3272
|
+
let currentLevel = result;
|
|
3273
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3274
|
+
const currentKey = keys[i];
|
|
3275
|
+
if (i === keys.length - 1) {
|
|
3276
|
+
currentLevel[currentKey] = obj[key];
|
|
3277
|
+
} else {
|
|
3278
|
+
if (!(currentKey in currentLevel)) {
|
|
3279
|
+
currentLevel[currentKey] = {};
|
|
3280
|
+
} else if (typeof currentLevel[currentKey] !== "object" || currentLevel[currentKey] === null || Array.isArray(currentLevel[currentKey])) {
|
|
3281
|
+
currentLevel[currentKey] = {};
|
|
3188
3282
|
}
|
|
3283
|
+
currentLevel = currentLevel[currentKey];
|
|
3189
3284
|
}
|
|
3190
|
-
} else {
|
|
3191
|
-
result[key] = obj[key];
|
|
3192
3285
|
}
|
|
3193
3286
|
}
|
|
3194
3287
|
}
|
|
@@ -3205,8 +3298,8 @@ function mapBody(template, body) {
|
|
|
3205
3298
|
const { key: providerSpecificKey, default: defaultValue } = providerSpecificSettings;
|
|
3206
3299
|
if (providerSpecificKey) {
|
|
3207
3300
|
let valueForThisKey = body[genericInputKey];
|
|
3208
|
-
if (providerSpecificSettings.
|
|
3209
|
-
valueForThisKey = providerSpecificSettings.
|
|
3301
|
+
if (providerSpecificSettings.transform && typeof providerSpecificSettings.transform === "function") {
|
|
3302
|
+
valueForThisKey = providerSpecificSettings.transform(
|
|
3210
3303
|
valueForThisKey,
|
|
3211
3304
|
Object.freeze({ ...body }),
|
|
3212
3305
|
output
|
|
@@ -3230,28 +3323,70 @@ import { Sha256 } from "@aws-crypto/sha256-js";
|
|
|
3230
3323
|
|
|
3231
3324
|
// src/utils/modules/runWithTemporaryEnv.ts
|
|
3232
3325
|
async function runWithTemporaryEnv(env, handler) {
|
|
3233
|
-
const
|
|
3326
|
+
const modifiedKeys = [];
|
|
3327
|
+
const originalValues = {};
|
|
3328
|
+
const envBefore = { ...process.env };
|
|
3234
3329
|
try {
|
|
3235
|
-
|
|
3330
|
+
try {
|
|
3331
|
+
env();
|
|
3332
|
+
} catch (envError) {
|
|
3333
|
+
const envAfter2 = process.env;
|
|
3334
|
+
for (const key in envAfter2) {
|
|
3335
|
+
if (envBefore[key] !== envAfter2[key]) {
|
|
3336
|
+
modifiedKeys.push(key);
|
|
3337
|
+
originalValues[key] = envBefore[key];
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
for (const key in envBefore) {
|
|
3341
|
+
if (!(key in envAfter2) && !modifiedKeys.includes(key)) {
|
|
3342
|
+
modifiedKeys.push(key);
|
|
3343
|
+
originalValues[key] = envBefore[key];
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
throw envError;
|
|
3347
|
+
}
|
|
3348
|
+
const envAfter = process.env;
|
|
3349
|
+
for (const key in envAfter) {
|
|
3350
|
+
if (envBefore[key] !== envAfter[key]) {
|
|
3351
|
+
modifiedKeys.push(key);
|
|
3352
|
+
originalValues[key] = envBefore[key];
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
for (const key in envBefore) {
|
|
3356
|
+
if (!(key in envAfter) && !modifiedKeys.includes(key)) {
|
|
3357
|
+
modifiedKeys.push(key);
|
|
3358
|
+
originalValues[key] = envBefore[key];
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3236
3361
|
const value = await handler();
|
|
3237
3362
|
return value;
|
|
3238
3363
|
} finally {
|
|
3239
|
-
|
|
3364
|
+
for (const key of modifiedKeys) {
|
|
3365
|
+
const originalValue = originalValues[key];
|
|
3366
|
+
if (originalValue === void 0) {
|
|
3367
|
+
delete process.env[key];
|
|
3368
|
+
} else {
|
|
3369
|
+
process.env[key] = originalValue;
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3240
3372
|
}
|
|
3241
3373
|
}
|
|
3242
3374
|
|
|
3243
3375
|
// src/utils/modules/getAwsAuthorizationHeaders.ts
|
|
3244
3376
|
async function getAwsAuthorizationHeaders(req, props) {
|
|
3377
|
+
if (!props.url || !props.regionName) {
|
|
3378
|
+
throw new Error("URL and region name are required for AWS authorization");
|
|
3379
|
+
}
|
|
3245
3380
|
const providerChain = fromNodeProviderChain();
|
|
3246
3381
|
const credentials = await runWithTemporaryEnv(
|
|
3247
3382
|
() => {
|
|
3248
|
-
if (props.awsAccessKey) {
|
|
3383
|
+
if (props.awsAccessKey && typeof props.awsAccessKey === "string") {
|
|
3249
3384
|
process.env["AWS_ACCESS_KEY_ID"] = props.awsAccessKey;
|
|
3250
3385
|
}
|
|
3251
|
-
if (props.awsSecretKey) {
|
|
3386
|
+
if (props.awsSecretKey && typeof props.awsSecretKey === "string") {
|
|
3252
3387
|
process.env["AWS_SECRET_ACCESS_KEY"] = props.awsSecretKey;
|
|
3253
3388
|
}
|
|
3254
|
-
if (props.awsSessionToken) {
|
|
3389
|
+
if (props.awsSessionToken && typeof props.awsSessionToken === "string") {
|
|
3255
3390
|
process.env["AWS_SESSION_TOKEN"] = props.awsSessionToken;
|
|
3256
3391
|
}
|
|
3257
3392
|
},
|
|
@@ -3281,8 +3416,21 @@ async function getAwsAuthorizationHeaders(req, props) {
|
|
|
3281
3416
|
// src/llm/_utils.parseHeaders.ts
|
|
3282
3417
|
async function parseHeaders(config, replacements, payload) {
|
|
3283
3418
|
const replace = replaceTemplateStringSimple(config.headers, replacements);
|
|
3284
|
-
|
|
3285
|
-
|
|
3419
|
+
let parsedHeaders = {};
|
|
3420
|
+
if (replace) {
|
|
3421
|
+
try {
|
|
3422
|
+
parsedHeaders = JSON.parse(replace);
|
|
3423
|
+
if (typeof parsedHeaders !== "object" || parsedHeaders === null || Array.isArray(parsedHeaders)) {
|
|
3424
|
+
throw new Error("Headers must be a JSON object");
|
|
3425
|
+
}
|
|
3426
|
+
} catch (error) {
|
|
3427
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
3428
|
+
throw new Error(
|
|
3429
|
+
`Failed to parse headers configuration: ${errorMessage}. Headers template: "${config.headers}". After replacement: "${replace}"`
|
|
3430
|
+
);
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
const headers = Object.assign({}, payload.headers, parsedHeaders);
|
|
3286
3434
|
if (config.provider.startsWith("amazon:") || config.provider.startsWith("amazon.")) {
|
|
3287
3435
|
const url = payload.url;
|
|
3288
3436
|
return getAwsAuthorizationHeaders(
|
|
@@ -3303,122 +3451,129 @@ async function parseHeaders(config, replacements, payload) {
|
|
|
3303
3451
|
}
|
|
3304
3452
|
}
|
|
3305
3453
|
|
|
3306
|
-
// src/llm/output/
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
};
|
|
3313
|
-
|
|
3314
|
-
const
|
|
3315
|
-
|
|
3454
|
+
// src/llm/output/default.ts
|
|
3455
|
+
function OutputDefault(result, _config) {
|
|
3456
|
+
const name = _config?.options.model?.default || "unknown";
|
|
3457
|
+
const stopReason = result?.stopReason || "stop";
|
|
3458
|
+
const content = [];
|
|
3459
|
+
if (result?.text) {
|
|
3460
|
+
content.push({ type: "text", text: result.text });
|
|
3461
|
+
}
|
|
3462
|
+
const usage = {
|
|
3463
|
+
output_tokens: result?.output_tokens || 0,
|
|
3464
|
+
input_tokens: result?.input_tokens || 0,
|
|
3465
|
+
total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
|
|
3466
|
+
};
|
|
3467
|
+
return {
|
|
3468
|
+
name,
|
|
3469
|
+
usage,
|
|
3470
|
+
stopReason,
|
|
3471
|
+
content
|
|
3472
|
+
};
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
// src/llm/output/_utils/getResultContent.ts
|
|
3476
|
+
function getResultContent(result, index) {
|
|
3477
|
+
if (typeof index === "number" && index > 0) {
|
|
3478
|
+
const arr = result?.options || [];
|
|
3479
|
+
const val = arr[index];
|
|
3480
|
+
return val ? val : [];
|
|
3481
|
+
}
|
|
3482
|
+
return [...result.content];
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
// src/llm/output/_utils/getResultText.ts
|
|
3486
|
+
function getResultText(result, index) {
|
|
3487
|
+
if (typeof index === "number" && index > 0) {
|
|
3488
|
+
const arr = result?.options || [];
|
|
3489
|
+
const val = arr[index];
|
|
3490
|
+
return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
|
|
3491
|
+
}
|
|
3492
|
+
return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
|
|
3493
|
+
}
|
|
3494
|
+
|
|
3495
|
+
// src/llm/output/base.ts
|
|
3496
|
+
function BaseLlmOutput(result) {
|
|
3497
|
+
const __result = Object.freeze({
|
|
3498
|
+
id: result.id || uuidv4(),
|
|
3499
|
+
name: result.name,
|
|
3500
|
+
usage: result.usage,
|
|
3501
|
+
stopReason: result.stopReason,
|
|
3502
|
+
options: [...result?.options || []],
|
|
3503
|
+
content: [...result.content],
|
|
3504
|
+
created: result?.created || (/* @__PURE__ */ new Date()).getTime()
|
|
3505
|
+
});
|
|
3506
|
+
function getResult() {
|
|
3316
3507
|
return {
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3508
|
+
id: __result.id,
|
|
3509
|
+
name: __result.name,
|
|
3510
|
+
created: __result.created,
|
|
3511
|
+
usage: __result.usage,
|
|
3512
|
+
options: __result.options,
|
|
3513
|
+
content: __result.content,
|
|
3514
|
+
stopReason: __result.stopReason
|
|
3320
3515
|
};
|
|
3321
3516
|
}
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3517
|
+
return {
|
|
3518
|
+
getResultContent: (index) => getResultContent(__result, index),
|
|
3519
|
+
getResultText: (index) => getResultText(__result, index),
|
|
3520
|
+
getResult
|
|
3521
|
+
};
|
|
3522
|
+
}
|
|
3523
|
+
|
|
3524
|
+
// src/llm/_utils.mapOptions.ts
|
|
3525
|
+
function mapOptions(input, options, config) {
|
|
3526
|
+
if (!config?.mapOptions || !options) {
|
|
3527
|
+
return input;
|
|
3528
|
+
}
|
|
3529
|
+
let result = { ...input };
|
|
3530
|
+
let processedOptions = options;
|
|
3531
|
+
if (options.functionCall && config.mapOptions.functionCall) {
|
|
3532
|
+
const mapping = config.mapOptions.functionCall(
|
|
3533
|
+
options.functionCall,
|
|
3534
|
+
options,
|
|
3535
|
+
result,
|
|
3536
|
+
config
|
|
3537
|
+
);
|
|
3538
|
+
if (mapping._clearFunctions) {
|
|
3539
|
+
processedOptions = { ...options, functions: [] };
|
|
3540
|
+
const { _clearFunctions, ...rest } = mapping;
|
|
3541
|
+
result = { ...result, ...rest };
|
|
3542
|
+
} else {
|
|
3543
|
+
result = { ...result, ...mapping };
|
|
3333
3544
|
}
|
|
3334
|
-
return obj;
|
|
3335
3545
|
}
|
|
3336
|
-
|
|
3546
|
+
if (processedOptions.functions?.length && config.mapOptions.functions) {
|
|
3547
|
+
result = {
|
|
3548
|
+
...result,
|
|
3549
|
+
...config.mapOptions.functions(
|
|
3550
|
+
processedOptions.functions,
|
|
3551
|
+
processedOptions,
|
|
3552
|
+
result,
|
|
3553
|
+
config
|
|
3554
|
+
)
|
|
3555
|
+
};
|
|
3556
|
+
}
|
|
3557
|
+
if (options.jsonSchema && config.mapOptions.jsonSchema) {
|
|
3558
|
+
result = {
|
|
3559
|
+
...result,
|
|
3560
|
+
...config.mapOptions.jsonSchema(options.jsonSchema, options, result, config)
|
|
3561
|
+
};
|
|
3562
|
+
}
|
|
3563
|
+
return result;
|
|
3337
3564
|
}
|
|
3338
3565
|
|
|
3339
3566
|
// src/llm/llm.call.ts
|
|
3340
3567
|
async function useLlm_call(state, messages, _options) {
|
|
3341
3568
|
const config = getLlmConfig(state.key);
|
|
3342
|
-
const
|
|
3343
|
-
const input = mapBody(
|
|
3569
|
+
const transformBody = mapBody(
|
|
3344
3570
|
config.mapBody,
|
|
3345
3571
|
Object.assign({}, state, {
|
|
3346
3572
|
prompt: messages
|
|
3347
3573
|
})
|
|
3348
3574
|
);
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
const curr = input["response_format"] || {};
|
|
3352
|
-
input["response_format"] = Object.assign(curr, {
|
|
3353
|
-
type: "json_schema",
|
|
3354
|
-
json_schema: {
|
|
3355
|
-
name: "output",
|
|
3356
|
-
strict: !!functionCallStrictInput,
|
|
3357
|
-
schema: cleanJsonSchemaFor(_options?.jsonSchema, "openai.chat")
|
|
3358
|
-
}
|
|
3359
|
-
});
|
|
3360
|
-
}
|
|
3361
|
-
}
|
|
3362
|
-
if (_options && _options?.functionCall) {
|
|
3363
|
-
if (state.provider.startsWith("anthropic")) {
|
|
3364
|
-
if (_options?.functionCall === "none") {
|
|
3365
|
-
_options.functions = [];
|
|
3366
|
-
} else if (_options?.functionCall === "auto" || _options?.functionCall === "any") {
|
|
3367
|
-
input["tool_choice"] = { type: _options?.functionCall };
|
|
3368
|
-
} else {
|
|
3369
|
-
input["tool_choice"] = _options?.functionCall;
|
|
3370
|
-
}
|
|
3371
|
-
} else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
|
|
3372
|
-
input["tool_choice"] = normalizeFunctionCall(
|
|
3373
|
-
_options?.functionCall,
|
|
3374
|
-
"openai"
|
|
3375
|
-
);
|
|
3376
|
-
} else if (state.provider.startsWith("google")) {
|
|
3377
|
-
input["toolConfig"] = {
|
|
3378
|
-
functionCallingConfig: {
|
|
3379
|
-
mode: normalizeFunctionCall(_options?.functionCall, "google")
|
|
3380
|
-
}
|
|
3381
|
-
};
|
|
3382
|
-
}
|
|
3383
|
-
}
|
|
3384
|
-
if (_options && _options?.functions?.length) {
|
|
3385
|
-
if (state.provider.startsWith("anthropic")) {
|
|
3386
|
-
input["tools"] = _options.functions.map((f) => ({
|
|
3387
|
-
name: f.name,
|
|
3388
|
-
description: f.description,
|
|
3389
|
-
input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
|
|
3390
|
-
}));
|
|
3391
|
-
} else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
|
|
3392
|
-
input["tools"] = _options.functions.map((f) => {
|
|
3393
|
-
const props = {
|
|
3394
|
-
name: f?.name,
|
|
3395
|
-
description: f?.description,
|
|
3396
|
-
parameters: f?.parameters
|
|
3397
|
-
};
|
|
3398
|
-
return {
|
|
3399
|
-
type: "function",
|
|
3400
|
-
function: Object.assign(
|
|
3401
|
-
props,
|
|
3402
|
-
{
|
|
3403
|
-
parameters: cleanJsonSchemaFor(props.parameters, "openai.chat")
|
|
3404
|
-
},
|
|
3405
|
-
{ strict: functionCallStrictInput }
|
|
3406
|
-
)
|
|
3407
|
-
};
|
|
3408
|
-
});
|
|
3409
|
-
} else if (state.provider.startsWith("google")) {
|
|
3410
|
-
input["tools"] = [
|
|
3411
|
-
{
|
|
3412
|
-
functionDeclarations: _options.functions.map((f) => ({
|
|
3413
|
-
name: f.name,
|
|
3414
|
-
description: f.description,
|
|
3415
|
-
parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
|
|
3416
|
-
}))
|
|
3417
|
-
}
|
|
3418
|
-
];
|
|
3419
|
-
}
|
|
3420
|
-
}
|
|
3421
|
-
const body = JSON.stringify(input);
|
|
3575
|
+
const applyOptions = mapOptions(transformBody, _options, config);
|
|
3576
|
+
const body = JSON.stringify(applyOptions);
|
|
3422
3577
|
const url = replaceTemplateStringSimple(config.endpoint, state);
|
|
3423
3578
|
const headers = await parseHeaders(config, state, {
|
|
3424
3579
|
url,
|
|
@@ -3445,7 +3600,9 @@ async function useLlm_call(state, messages, _options) {
|
|
|
3445
3600
|
body,
|
|
3446
3601
|
headers
|
|
3447
3602
|
});
|
|
3448
|
-
|
|
3603
|
+
const { transformResponse = OutputDefault } = config;
|
|
3604
|
+
const normalized = transformResponse(response, config);
|
|
3605
|
+
return BaseLlmOutput(normalized);
|
|
3449
3606
|
}
|
|
3450
3607
|
|
|
3451
3608
|
// src/llm/_utils.stateFromOptions.ts
|
|
@@ -3588,6 +3745,80 @@ function useLlm(provider, options = {}) {
|
|
|
3588
3745
|
const config = getLlmConfig(provider);
|
|
3589
3746
|
return apiRequestWrapper(config, options, useLlm_call);
|
|
3590
3747
|
}
|
|
3748
|
+
function useLlmConfiguration(config) {
|
|
3749
|
+
return (options = {}) => apiRequestWrapper(config, options, useLlm_call);
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3752
|
+
// src/embedding/output/BaseEmbeddingOutput.ts
|
|
3753
|
+
function BaseEmbeddingOutput(result) {
|
|
3754
|
+
const __result = Object.freeze({
|
|
3755
|
+
id: result.id || uuidv4(),
|
|
3756
|
+
model: result.model,
|
|
3757
|
+
usage: result.usage,
|
|
3758
|
+
embedding: [...result?.embedding || []],
|
|
3759
|
+
created: result?.created || (/* @__PURE__ */ new Date()).getTime()
|
|
3760
|
+
});
|
|
3761
|
+
function getResult() {
|
|
3762
|
+
return {
|
|
3763
|
+
id: __result.id,
|
|
3764
|
+
model: __result.model,
|
|
3765
|
+
created: __result.created,
|
|
3766
|
+
usage: __result.usage,
|
|
3767
|
+
embedding: __result.embedding
|
|
3768
|
+
};
|
|
3769
|
+
}
|
|
3770
|
+
function getEmbedding(index) {
|
|
3771
|
+
if (index && index > 0) {
|
|
3772
|
+
const arr = __result?.embedding;
|
|
3773
|
+
const val = arr[index];
|
|
3774
|
+
return val ? val : [];
|
|
3775
|
+
}
|
|
3776
|
+
return __result.embedding[0];
|
|
3777
|
+
}
|
|
3778
|
+
return {
|
|
3779
|
+
getEmbedding,
|
|
3780
|
+
getResult
|
|
3781
|
+
};
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3784
|
+
// src/embedding/output/OpenAiEmbedding.ts
|
|
3785
|
+
function OpenAiEmbedding(result, config) {
|
|
3786
|
+
const __result = deepClone(result);
|
|
3787
|
+
const model = __result.model || config.model || "openai.unknown";
|
|
3788
|
+
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3789
|
+
const results = result?.data || [];
|
|
3790
|
+
const embedding = results.map((a) => a.embedding);
|
|
3791
|
+
const usage = {
|
|
3792
|
+
output_tokens: 0,
|
|
3793
|
+
input_tokens: result?.usage?.prompt_tokens,
|
|
3794
|
+
total_tokens: result?.usage?.total_tokens
|
|
3795
|
+
};
|
|
3796
|
+
return BaseEmbeddingOutput({
|
|
3797
|
+
model,
|
|
3798
|
+
created,
|
|
3799
|
+
usage,
|
|
3800
|
+
embedding
|
|
3801
|
+
});
|
|
3802
|
+
}
|
|
3803
|
+
|
|
3804
|
+
// src/embedding/output/AmazonTitan.ts
|
|
3805
|
+
function AmazonTitanEmbedding(result, config) {
|
|
3806
|
+
const __result = deepClone(result);
|
|
3807
|
+
const model = config.model || "amazon.unknown";
|
|
3808
|
+
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3809
|
+
const embedding = [__result.embedding];
|
|
3810
|
+
const usage = {
|
|
3811
|
+
output_tokens: 0,
|
|
3812
|
+
input_tokens: __result.inputTextTokenCount,
|
|
3813
|
+
total_tokens: __result.inputTextTokenCount
|
|
3814
|
+
};
|
|
3815
|
+
return BaseEmbeddingOutput({
|
|
3816
|
+
model,
|
|
3817
|
+
created,
|
|
3818
|
+
usage,
|
|
3819
|
+
embedding
|
|
3820
|
+
});
|
|
3821
|
+
}
|
|
3591
3822
|
|
|
3592
3823
|
// src/embedding/config.ts
|
|
3593
3824
|
var embeddingConfigs = {
|
|
@@ -3620,7 +3851,8 @@ var embeddingConfigs = {
|
|
|
3620
3851
|
encodingFormat: {
|
|
3621
3852
|
key: "encoding_format"
|
|
3622
3853
|
}
|
|
3623
|
-
}
|
|
3854
|
+
},
|
|
3855
|
+
transformResponse: OpenAiEmbedding
|
|
3624
3856
|
},
|
|
3625
3857
|
"amazon.embedding.v1": {
|
|
3626
3858
|
key: "amazon.embedding.v1",
|
|
@@ -3647,7 +3879,8 @@ var embeddingConfigs = {
|
|
|
3647
3879
|
dimensions: {
|
|
3648
3880
|
key: "dimensions"
|
|
3649
3881
|
}
|
|
3650
|
-
}
|
|
3882
|
+
},
|
|
3883
|
+
transformResponse: AmazonTitanEmbedding
|
|
3651
3884
|
}
|
|
3652
3885
|
};
|
|
3653
3886
|
function getEmbeddingConfig(provider) {
|
|
@@ -3661,77 +3894,6 @@ function getEmbeddingConfig(provider) {
|
|
|
3661
3894
|
throw new Error(`Invalid provider: ${provider}`);
|
|
3662
3895
|
}
|
|
3663
3896
|
|
|
3664
|
-
// src/embedding/output/BaseEmbeddingOutput.ts
|
|
3665
|
-
function BaseEmbeddingOutput(result) {
|
|
3666
|
-
const __result = Object.freeze({
|
|
3667
|
-
id: result.id || uuidv4(),
|
|
3668
|
-
model: result.model,
|
|
3669
|
-
usage: result.usage,
|
|
3670
|
-
embedding: [...result?.embedding || []],
|
|
3671
|
-
created: result?.created || (/* @__PURE__ */ new Date()).getTime()
|
|
3672
|
-
});
|
|
3673
|
-
function getResult() {
|
|
3674
|
-
return {
|
|
3675
|
-
id: __result.id,
|
|
3676
|
-
model: __result.model,
|
|
3677
|
-
created: __result.created,
|
|
3678
|
-
usage: __result.usage,
|
|
3679
|
-
embedding: __result.embedding
|
|
3680
|
-
};
|
|
3681
|
-
}
|
|
3682
|
-
function getEmbedding(index) {
|
|
3683
|
-
if (index && index > 0) {
|
|
3684
|
-
const arr = __result?.embedding;
|
|
3685
|
-
const val = arr[index];
|
|
3686
|
-
return val ? val : [];
|
|
3687
|
-
}
|
|
3688
|
-
return __result.embedding[0];
|
|
3689
|
-
}
|
|
3690
|
-
return {
|
|
3691
|
-
getEmbedding,
|
|
3692
|
-
getResult
|
|
3693
|
-
};
|
|
3694
|
-
}
|
|
3695
|
-
|
|
3696
|
-
// src/embedding/output/AmazonTitan.ts
|
|
3697
|
-
function AmazonTitanEmbedding(result, config) {
|
|
3698
|
-
const __result = deepClone(result);
|
|
3699
|
-
const model = config.model || "amazon.unknown";
|
|
3700
|
-
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3701
|
-
const embedding = [__result.embedding];
|
|
3702
|
-
const usage = {
|
|
3703
|
-
output_tokens: 0,
|
|
3704
|
-
input_tokens: __result.inputTextTokenCount,
|
|
3705
|
-
total_tokens: __result.inputTextTokenCount
|
|
3706
|
-
};
|
|
3707
|
-
return BaseEmbeddingOutput({
|
|
3708
|
-
model,
|
|
3709
|
-
created,
|
|
3710
|
-
usage,
|
|
3711
|
-
embedding
|
|
3712
|
-
});
|
|
3713
|
-
}
|
|
3714
|
-
|
|
3715
|
-
// src/embedding/output/OpenAiEmbedding.ts
|
|
3716
|
-
function OpenAiEmbedding(result, config) {
|
|
3717
|
-
const __result = deepClone(result);
|
|
3718
|
-
const model = __result.model || config.model || "openai.unknown";
|
|
3719
|
-
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
3720
|
-
const results = result?.data || [];
|
|
3721
|
-
const embedding = results.map((a) => a.embedding);
|
|
3722
|
-
const usage = {
|
|
3723
|
-
output_tokens: 0,
|
|
3724
|
-
input_tokens: result?.usage?.prompt_tokens,
|
|
3725
|
-
total_tokens: result?.usage?.total_tokens
|
|
3726
|
-
};
|
|
3727
|
-
return BaseEmbeddingOutput({
|
|
3728
|
-
model,
|
|
3729
|
-
created,
|
|
3730
|
-
usage,
|
|
3731
|
-
embedding
|
|
3732
|
-
});
|
|
3733
|
-
}
|
|
3734
|
-
|
|
3735
3897
|
// src/embedding/output/getEmbeddingOutputParser.ts
|
|
3736
3898
|
function getEmbeddingOutputParser(config, response) {
|
|
3737
3899
|
switch (config.key) {
|
|
@@ -4009,8 +4171,8 @@ var ChatPrompt = class extends BasePrompt {
|
|
|
4009
4171
|
__publicField(this, "type", "chat");
|
|
4010
4172
|
/**
|
|
4011
4173
|
* @property parseUserTemplates - Whether or not to allow parsing
|
|
4012
|
-
* user messages with the template engine.
|
|
4013
|
-
*
|
|
4174
|
+
* user messages with the template engine. Defaults to true.
|
|
4175
|
+
* Set `allowUnsafeUserTemplate: false` in options to disable.
|
|
4014
4176
|
*/
|
|
4015
4177
|
__publicField(this, "parseUserTemplates", true);
|
|
4016
4178
|
if (typeof options?.allowUnsafeUserTemplate === "boolean") {
|
|
@@ -4071,7 +4233,7 @@ var ChatPrompt = class extends BasePrompt {
|
|
|
4071
4233
|
return this;
|
|
4072
4234
|
}
|
|
4073
4235
|
/**
|
|
4074
|
-
* addFunctionMessage Helper to add
|
|
4236
|
+
* addFunctionMessage Helper to add a function message to the prompt.
|
|
4075
4237
|
* @param content The message content.
|
|
4076
4238
|
* @return ChatPrompt so it can be chained.
|
|
4077
4239
|
*/
|
|
@@ -4085,7 +4247,7 @@ var ChatPrompt = class extends BasePrompt {
|
|
|
4085
4247
|
return this;
|
|
4086
4248
|
}
|
|
4087
4249
|
/**
|
|
4088
|
-
* addFunctionCallMessage Helper to add
|
|
4250
|
+
* addFunctionCallMessage Helper to add a function_call message to the prompt.
|
|
4089
4251
|
* @param content The message content.
|
|
4090
4252
|
* @return ChatPrompt so it can be chained.
|
|
4091
4253
|
*/
|
|
@@ -4640,7 +4802,7 @@ var Dialogue = class extends BaseStateItem {
|
|
|
4640
4802
|
return this;
|
|
4641
4803
|
}
|
|
4642
4804
|
setToolMessage(content, name, id) {
|
|
4643
|
-
this.setFunctionMessage(content, name, id);
|
|
4805
|
+
return this.setFunctionMessage(content, name, id);
|
|
4644
4806
|
}
|
|
4645
4807
|
setFunctionMessage(content, name, id) {
|
|
4646
4808
|
if (content) {
|
|
@@ -4657,7 +4819,7 @@ var Dialogue = class extends BaseStateItem {
|
|
|
4657
4819
|
* Set
|
|
4658
4820
|
*/
|
|
4659
4821
|
setToolCallMessage(input) {
|
|
4660
|
-
this.setFunctionCallMessage(input);
|
|
4822
|
+
return this.setFunctionCallMessage(input);
|
|
4661
4823
|
}
|
|
4662
4824
|
setFunctionCallMessage(input) {
|
|
4663
4825
|
if (!input || typeof input !== "object") {
|
|
@@ -4749,6 +4911,9 @@ var Dialogue = class extends BaseStateItem {
|
|
|
4749
4911
|
* @returns this for chaining
|
|
4750
4912
|
*/
|
|
4751
4913
|
addFromOutput(output) {
|
|
4914
|
+
if (!output || typeof output !== "object") {
|
|
4915
|
+
return this;
|
|
4916
|
+
}
|
|
4752
4917
|
const result = "getResult" in output ? output.getResult() : output;
|
|
4753
4918
|
if (!result || typeof result !== "object") {
|
|
4754
4919
|
return this;
|
|
@@ -4884,6 +5049,7 @@ export {
|
|
|
4884
5049
|
createEmbedding,
|
|
4885
5050
|
createLlmExecutor,
|
|
4886
5051
|
createLlmFunctionExecutor,
|
|
5052
|
+
createOpenAiCompatibleConfiguration,
|
|
4887
5053
|
createParser,
|
|
4888
5054
|
createPrompt,
|
|
4889
5055
|
createState,
|
|
@@ -4894,5 +5060,6 @@ export {
|
|
|
4894
5060
|
registerPartials,
|
|
4895
5061
|
useExecutors,
|
|
4896
5062
|
useLlm,
|
|
5063
|
+
useLlmConfiguration,
|
|
4897
5064
|
utils_exports as utils
|
|
4898
5065
|
};
|