llm-exe 3.0.0-beta.1 → 3.0.0-beta.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 +44 -21
- package/dist/index.d.ts +44 -21
- package/dist/index.js +299 -78
- package/dist/index.mjs +299 -78
- package/package.json +1 -1
- package/readme.md +2 -2
package/dist/index.js
CHANGED
|
@@ -1266,9 +1266,12 @@ var BOOLEAN_VALUES = ["true", "false", "yes", "no", "y", "n", "1", "0"];
|
|
|
1266
1266
|
var TRUTHY_VALUES = /* @__PURE__ */ new Set(["true", "yes", "y", "1"]);
|
|
1267
1267
|
var FALSY_VALUES = /* @__PURE__ */ new Set(["false", "no", "n", "0"]);
|
|
1268
1268
|
var MAX_ERROR_INPUT_EXCERPT_LENGTH = 500;
|
|
1269
|
+
var BOOLEAN_TOKEN_PATTERN = /(?<![\p{L}\p{N}])(?:true|false|yes|no|y|n|1|0)(?![\p{L}\p{N}])/giu;
|
|
1269
1270
|
var BooleanParser = class extends BaseParser {
|
|
1270
|
-
constructor() {
|
|
1271
|
+
constructor(options) {
|
|
1271
1272
|
super("boolean");
|
|
1273
|
+
__publicField(this, "match");
|
|
1274
|
+
this.match = options?.match ?? "exact";
|
|
1272
1275
|
}
|
|
1273
1276
|
getInputErrorContext(text) {
|
|
1274
1277
|
const context = {
|
|
@@ -1316,6 +1319,36 @@ var BooleanParser = class extends BaseParser {
|
|
|
1316
1319
|
if (FALSY_VALUES.has(clean)) {
|
|
1317
1320
|
return false;
|
|
1318
1321
|
}
|
|
1322
|
+
if (this.match === "extract") {
|
|
1323
|
+
const matches = Array.from(
|
|
1324
|
+
text.toLowerCase().matchAll(BOOLEAN_TOKEN_PATTERN)
|
|
1325
|
+
).map((match) => match[0]);
|
|
1326
|
+
const values = Array.from(
|
|
1327
|
+
new Set(
|
|
1328
|
+
matches.map((match) => {
|
|
1329
|
+
if (TRUTHY_VALUES.has(match)) return true;
|
|
1330
|
+
return false;
|
|
1331
|
+
})
|
|
1332
|
+
)
|
|
1333
|
+
);
|
|
1334
|
+
if (values.length === 1) {
|
|
1335
|
+
return values[0];
|
|
1336
|
+
}
|
|
1337
|
+
if (values.length > 1) {
|
|
1338
|
+
throw new LlmExeError(`Multiple boolean values found in input.`, {
|
|
1339
|
+
code: "parser.parse_failed",
|
|
1340
|
+
context: {
|
|
1341
|
+
operation: "BooleanParser.parse",
|
|
1342
|
+
parser: "boolean",
|
|
1343
|
+
reason: "ambiguous_boolean",
|
|
1344
|
+
expected: "one boolean value",
|
|
1345
|
+
match: this.match,
|
|
1346
|
+
matchCount: values.length,
|
|
1347
|
+
...this.getInputErrorContext(text)
|
|
1348
|
+
}
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1319
1352
|
throw new LlmExeError(`No boolean value found in input.`, {
|
|
1320
1353
|
code: "parser.parse_failed",
|
|
1321
1354
|
context: {
|
|
@@ -1323,6 +1356,7 @@ var BooleanParser = class extends BaseParser {
|
|
|
1323
1356
|
parser: "boolean",
|
|
1324
1357
|
reason: "unrecognized_boolean",
|
|
1325
1358
|
expected: BOOLEAN_VALUES,
|
|
1359
|
+
match: this.match,
|
|
1326
1360
|
...this.getInputErrorContext(text)
|
|
1327
1361
|
}
|
|
1328
1362
|
});
|
|
@@ -1347,7 +1381,7 @@ function toNumber(value) {
|
|
|
1347
1381
|
|
|
1348
1382
|
// src/parser/parsers/NumberParser.ts
|
|
1349
1383
|
var NUMERIC_TOKEN_PATTERN = /(^|[^\w.,])([+-]?(?:(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?)(?![\w,])/g;
|
|
1350
|
-
var
|
|
1384
|
+
var EXACT_NUMERIC_PATTERN = /^[+-]?(?:(?:\d{1,3}(?:,\d{3})+|\d+)(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
1351
1385
|
var NumberParser = class extends BaseParser {
|
|
1352
1386
|
constructor(options) {
|
|
1353
1387
|
super("number");
|
|
@@ -1382,16 +1416,16 @@ var NumberParser = class extends BaseParser {
|
|
|
1382
1416
|
}
|
|
1383
1417
|
});
|
|
1384
1418
|
}
|
|
1385
|
-
if (this.match === "
|
|
1419
|
+
if (this.match === "exact") {
|
|
1386
1420
|
const trimmed = text.trim();
|
|
1387
|
-
if (!
|
|
1388
|
-
throw new LlmExeError(`Input is not
|
|
1421
|
+
if (!EXACT_NUMERIC_PATTERN.test(trimmed)) {
|
|
1422
|
+
throw new LlmExeError(`Input is not an exact numeric value.`, {
|
|
1389
1423
|
code: "parser.parse_failed",
|
|
1390
1424
|
context: {
|
|
1391
1425
|
operation: "NumberParser.parse",
|
|
1392
1426
|
parser: "number",
|
|
1393
1427
|
reason: "no_numeric_value",
|
|
1394
|
-
expected: "
|
|
1428
|
+
expected: "exact number",
|
|
1395
1429
|
match: this.match,
|
|
1396
1430
|
inputLength: text.length
|
|
1397
1431
|
}
|
|
@@ -1658,9 +1692,11 @@ function isPlainObject2(value) {
|
|
|
1658
1692
|
const proto = Object.getPrototypeOf(value);
|
|
1659
1693
|
return proto === Object.prototype || proto === null;
|
|
1660
1694
|
}
|
|
1661
|
-
function
|
|
1695
|
+
function normalizeExactResponseJsonText(input) {
|
|
1662
1696
|
const trimmed = input.trim();
|
|
1663
|
-
const fenceMatch = trimmed.match(
|
|
1697
|
+
const fenceMatch = trimmed.match(
|
|
1698
|
+
/^```([a-zA-Z]*)[^\S\r\n]*\r?\n([\s\S]*)```$/
|
|
1699
|
+
);
|
|
1664
1700
|
if (!fenceMatch) {
|
|
1665
1701
|
return trimmed;
|
|
1666
1702
|
}
|
|
@@ -1670,19 +1706,82 @@ function normalizeWholeResponseJsonText(input) {
|
|
|
1670
1706
|
}
|
|
1671
1707
|
return body.trim();
|
|
1672
1708
|
}
|
|
1709
|
+
function findBalancedJsonEnd(input, start) {
|
|
1710
|
+
const first = input[start];
|
|
1711
|
+
const stack = first === "{" ? ["}"] : first === "[" ? ["]"] : [];
|
|
1712
|
+
let inString = false;
|
|
1713
|
+
let escaping = false;
|
|
1714
|
+
for (let index = start + 1; index < input.length; index += 1) {
|
|
1715
|
+
const char = input[index];
|
|
1716
|
+
if (inString) {
|
|
1717
|
+
if (escaping) {
|
|
1718
|
+
escaping = false;
|
|
1719
|
+
} else if (char === "\\") {
|
|
1720
|
+
escaping = true;
|
|
1721
|
+
} else if (char === '"') {
|
|
1722
|
+
inString = false;
|
|
1723
|
+
}
|
|
1724
|
+
continue;
|
|
1725
|
+
}
|
|
1726
|
+
if (char === '"') {
|
|
1727
|
+
inString = true;
|
|
1728
|
+
continue;
|
|
1729
|
+
}
|
|
1730
|
+
if (char === "{" || char === "[") {
|
|
1731
|
+
stack.push(char === "{" ? "}" : "]");
|
|
1732
|
+
continue;
|
|
1733
|
+
}
|
|
1734
|
+
if (char !== "}" && char !== "]") {
|
|
1735
|
+
continue;
|
|
1736
|
+
}
|
|
1737
|
+
if (stack[stack.length - 1] !== char) {
|
|
1738
|
+
return void 0;
|
|
1739
|
+
}
|
|
1740
|
+
stack.pop();
|
|
1741
|
+
if (stack.length === 0) {
|
|
1742
|
+
return index;
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
return void 0;
|
|
1746
|
+
}
|
|
1747
|
+
function extractJsonCandidates(input) {
|
|
1748
|
+
const candidates = [];
|
|
1749
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
1750
|
+
const char = input[index];
|
|
1751
|
+
if (char !== "{" && char !== "[") {
|
|
1752
|
+
continue;
|
|
1753
|
+
}
|
|
1754
|
+
const end = findBalancedJsonEnd(input, index);
|
|
1755
|
+
if (end === void 0) {
|
|
1756
|
+
continue;
|
|
1757
|
+
}
|
|
1758
|
+
const candidate = input.slice(index, end + 1);
|
|
1759
|
+
try {
|
|
1760
|
+
candidates.push({
|
|
1761
|
+
parsed: JSON.parse(candidate)
|
|
1762
|
+
});
|
|
1763
|
+
index = end;
|
|
1764
|
+
} catch {
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
return candidates;
|
|
1768
|
+
}
|
|
1673
1769
|
var JsonParser = class extends BaseParserWithJson {
|
|
1674
1770
|
constructor(options = {}) {
|
|
1675
1771
|
super("json", options);
|
|
1676
1772
|
__publicField(this, "shouldValidateSchema");
|
|
1773
|
+
__publicField(this, "match");
|
|
1774
|
+
this.match = options.match ?? "exact";
|
|
1677
1775
|
this.shouldValidateSchema = !!options.schema && options.validateSchema !== false;
|
|
1678
1776
|
}
|
|
1679
1777
|
/**
|
|
1680
1778
|
* v3 parser contract:
|
|
1681
1779
|
* Category: strict
|
|
1682
|
-
* Mode:
|
|
1780
|
+
* Mode: exact
|
|
1683
1781
|
*
|
|
1684
|
-
* Parses strict JSON object/array output
|
|
1685
|
-
*
|
|
1782
|
+
* Parses strict JSON object/array output by default. Pass match: "extract"
|
|
1783
|
+
* to extract one JSON object or array from surrounding text. Invalid JSON,
|
|
1784
|
+
* empty input, JSON primitives, and non-plain runtime objects throw typed parser errors.
|
|
1686
1785
|
* Schema validation is on by default when a schema is provided unless
|
|
1687
1786
|
* validateSchema: false is explicitly set.
|
|
1688
1787
|
*
|
|
@@ -1705,19 +1804,52 @@ var JsonParser = class extends BaseParserWithJson {
|
|
|
1705
1804
|
});
|
|
1706
1805
|
}
|
|
1707
1806
|
try {
|
|
1708
|
-
parsed = JSON.parse(
|
|
1807
|
+
parsed = JSON.parse(normalizeExactResponseJsonText(text));
|
|
1709
1808
|
} catch (cause) {
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1809
|
+
if (this.match === "extract") {
|
|
1810
|
+
const candidates = extractJsonCandidates(text);
|
|
1811
|
+
if (candidates.length === 1) {
|
|
1812
|
+
parsed = candidates[0].parsed;
|
|
1813
|
+
} else if (candidates.length > 1) {
|
|
1814
|
+
throw new LlmExeError(`Multiple JSON values found in input.`, {
|
|
1815
|
+
code: "parser.parse_failed",
|
|
1816
|
+
context: {
|
|
1817
|
+
operation: "JsonParser.parse",
|
|
1818
|
+
parser: "json",
|
|
1819
|
+
reason: "ambiguous_json_match",
|
|
1820
|
+
expected: "one JSON object or array",
|
|
1821
|
+
match: this.match,
|
|
1822
|
+
inputLength,
|
|
1823
|
+
matchCount: candidates.length
|
|
1824
|
+
}
|
|
1825
|
+
});
|
|
1826
|
+
} else {
|
|
1827
|
+
throw new LlmExeError(`No JSON value found in input.`, {
|
|
1828
|
+
code: "parser.parse_failed",
|
|
1829
|
+
context: {
|
|
1830
|
+
operation: "JsonParser.parse",
|
|
1831
|
+
parser: "json",
|
|
1832
|
+
reason: "no_json_value",
|
|
1833
|
+
expected: "JSON object or array",
|
|
1834
|
+
match: this.match,
|
|
1835
|
+
inputLength
|
|
1836
|
+
},
|
|
1837
|
+
cause
|
|
1838
|
+
});
|
|
1839
|
+
}
|
|
1840
|
+
} else {
|
|
1841
|
+
throw new LlmExeError(`Invalid JSON input.`, {
|
|
1842
|
+
code: "parser.parse_failed",
|
|
1843
|
+
context: {
|
|
1844
|
+
operation: "JsonParser.parse",
|
|
1845
|
+
parser: "json",
|
|
1846
|
+
reason: "invalid_json",
|
|
1847
|
+
expected: "JSON object or array",
|
|
1848
|
+
inputLength
|
|
1849
|
+
},
|
|
1850
|
+
cause
|
|
1851
|
+
});
|
|
1852
|
+
}
|
|
1721
1853
|
}
|
|
1722
1854
|
} else if (Array.isArray(text) || isPlainObject2(text)) {
|
|
1723
1855
|
parsed = text;
|
|
@@ -2988,7 +3120,7 @@ var StringExtractParser = class extends BaseParser {
|
|
|
2988
3120
|
* Mode: configured value extraction
|
|
2989
3121
|
*
|
|
2990
3122
|
* Returns the single configured enum value found in input. Matching is
|
|
2991
|
-
* word-bounded by default; pass match: "
|
|
3123
|
+
* word-bounded by default; pass match: "exact" to require exact input or
|
|
2992
3124
|
* match: "substring" for legacy contains() behavior. Case-insensitive by
|
|
2993
3125
|
* default.
|
|
2994
3126
|
*
|
|
@@ -3070,8 +3202,8 @@ var StringExtractParser = class extends BaseParser {
|
|
|
3070
3202
|
}
|
|
3071
3203
|
findMatches(text) {
|
|
3072
3204
|
switch (this.match) {
|
|
3073
|
-
case "
|
|
3074
|
-
return this.
|
|
3205
|
+
case "exact":
|
|
3206
|
+
return this.matchExact(text);
|
|
3075
3207
|
case "substring":
|
|
3076
3208
|
return this.matchSubstring(text);
|
|
3077
3209
|
case "word":
|
|
@@ -3079,7 +3211,7 @@ var StringExtractParser = class extends BaseParser {
|
|
|
3079
3211
|
return this.matchWord(text);
|
|
3080
3212
|
}
|
|
3081
3213
|
}
|
|
3082
|
-
|
|
3214
|
+
matchExact(text) {
|
|
3083
3215
|
const candidate = this.ignoreCase ? text.trim().toLowerCase() : text.trim();
|
|
3084
3216
|
return this.enum.filter((option) => {
|
|
3085
3217
|
if (option === "") return false;
|
|
@@ -3129,36 +3261,33 @@ function createParser(...args) {
|
|
|
3129
3261
|
case "replaceStringTemplate":
|
|
3130
3262
|
return new ReplaceStringTemplateParser();
|
|
3131
3263
|
case "boolean":
|
|
3132
|
-
return new BooleanParser();
|
|
3264
|
+
return new BooleanParser(options);
|
|
3133
3265
|
case "number":
|
|
3134
3266
|
return new NumberParser(options);
|
|
3135
3267
|
case "string":
|
|
3136
3268
|
return new StringParser();
|
|
3137
3269
|
default:
|
|
3138
|
-
throw new LlmExeError(
|
|
3139
|
-
|
|
3140
|
-
{
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
],
|
|
3158
|
-
resolution: "Use a registered parser type, or define a custom parser."
|
|
3159
|
-
}
|
|
3270
|
+
throw new LlmExeError(`Invalid parser type: "${type}"`, {
|
|
3271
|
+
code: "parser.invalid_type",
|
|
3272
|
+
context: {
|
|
3273
|
+
operation: "createParser",
|
|
3274
|
+
parser: type,
|
|
3275
|
+
availableParsers: [
|
|
3276
|
+
"json",
|
|
3277
|
+
"string",
|
|
3278
|
+
"boolean",
|
|
3279
|
+
"number",
|
|
3280
|
+
"stringExtract",
|
|
3281
|
+
"listToArray",
|
|
3282
|
+
"listToJson",
|
|
3283
|
+
"listToKeyValue",
|
|
3284
|
+
"replaceStringTemplate",
|
|
3285
|
+
"markdownCodeBlock",
|
|
3286
|
+
"markdownCodeBlocks"
|
|
3287
|
+
],
|
|
3288
|
+
resolution: "Use a registered parser type, or define a custom parser."
|
|
3160
3289
|
}
|
|
3161
|
-
);
|
|
3290
|
+
});
|
|
3162
3291
|
}
|
|
3163
3292
|
}
|
|
3164
3293
|
function createCustomParser(name, parserFn) {
|
|
@@ -4223,6 +4352,20 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
|
|
|
4223
4352
|
return mergeConsecutiveSameRole(result);
|
|
4224
4353
|
}
|
|
4225
4354
|
|
|
4355
|
+
// src/llm/output/_utils/getBedrockTokenCounts.ts
|
|
4356
|
+
function getBedrockTokenCounts(headers) {
|
|
4357
|
+
if (!headers) return void 0;
|
|
4358
|
+
const input = parseInt(headers["x-amzn-bedrock-input-token-count"], 10);
|
|
4359
|
+
const output = parseInt(headers["x-amzn-bedrock-output-token-count"], 10);
|
|
4360
|
+
if (!Number.isFinite(input) && !Number.isFinite(output)) {
|
|
4361
|
+
return void 0;
|
|
4362
|
+
}
|
|
4363
|
+
return {
|
|
4364
|
+
input_tokens: Number.isFinite(input) ? input : 0,
|
|
4365
|
+
output_tokens: Number.isFinite(output) ? output : 0
|
|
4366
|
+
};
|
|
4367
|
+
}
|
|
4368
|
+
|
|
4226
4369
|
// src/llm/output/claude.ts
|
|
4227
4370
|
function formatResult2(response) {
|
|
4228
4371
|
const content = response?.content || [];
|
|
@@ -4245,15 +4388,18 @@ function formatResult2(response) {
|
|
|
4245
4388
|
}
|
|
4246
4389
|
return out;
|
|
4247
4390
|
}
|
|
4248
|
-
function OutputAnthropicClaude3Chat(result, _config) {
|
|
4391
|
+
function OutputAnthropicClaude3Chat(result, _config, headers) {
|
|
4249
4392
|
const id = result.id;
|
|
4250
4393
|
const name = result.model || _config?.options.model?.default || "anthropic.unknown";
|
|
4251
4394
|
const stopReason = result.stop_reason;
|
|
4252
4395
|
const content = formatResult2(result);
|
|
4396
|
+
const headerUsage = getBedrockTokenCounts(headers);
|
|
4397
|
+
const input_tokens = result?.usage?.input_tokens ?? headerUsage?.input_tokens ?? 0;
|
|
4398
|
+
const output_tokens = result?.usage?.output_tokens ?? headerUsage?.output_tokens ?? 0;
|
|
4253
4399
|
const usage = {
|
|
4254
|
-
input_tokens
|
|
4255
|
-
output_tokens
|
|
4256
|
-
total_tokens:
|
|
4400
|
+
input_tokens,
|
|
4401
|
+
output_tokens,
|
|
4402
|
+
total_tokens: input_tokens + output_tokens
|
|
4257
4403
|
};
|
|
4258
4404
|
return {
|
|
4259
4405
|
id,
|
|
@@ -4266,7 +4412,7 @@ function OutputAnthropicClaude3Chat(result, _config) {
|
|
|
4266
4412
|
}
|
|
4267
4413
|
|
|
4268
4414
|
// src/llm/output/llama.ts
|
|
4269
|
-
function OutputMetaLlama3Chat(result, _config) {
|
|
4415
|
+
function OutputMetaLlama3Chat(result, _config, headers) {
|
|
4270
4416
|
const id = (0, import_uuid.v4)();
|
|
4271
4417
|
const name = _config?.options?.model?.default || "meta";
|
|
4272
4418
|
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
@@ -4274,10 +4420,13 @@ function OutputMetaLlama3Chat(result, _config) {
|
|
|
4274
4420
|
const content = [
|
|
4275
4421
|
{ type: "text", text: result.generation }
|
|
4276
4422
|
];
|
|
4423
|
+
const headerUsage = getBedrockTokenCounts(headers);
|
|
4424
|
+
const output_tokens = result?.generation_token_count ?? headerUsage?.output_tokens ?? 0;
|
|
4425
|
+
const input_tokens = result?.prompt_token_count ?? headerUsage?.input_tokens ?? 0;
|
|
4277
4426
|
const usage = {
|
|
4278
|
-
output_tokens
|
|
4279
|
-
input_tokens
|
|
4280
|
-
total_tokens:
|
|
4427
|
+
output_tokens,
|
|
4428
|
+
input_tokens,
|
|
4429
|
+
total_tokens: output_tokens + input_tokens
|
|
4281
4430
|
};
|
|
4282
4431
|
return {
|
|
4283
4432
|
id,
|
|
@@ -4395,7 +4544,7 @@ var bedrock = {
|
|
|
4395
4544
|
|
|
4396
4545
|
// src/llm/config/anthropic/index.ts
|
|
4397
4546
|
var ANTHROPIC_VERSION = "2023-06-01";
|
|
4398
|
-
var MODELS_REJECTING_SAMPLING_PARAMS = ["claude-opus-4-7"];
|
|
4547
|
+
var MODELS_REJECTING_SAMPLING_PARAMS = ["claude-opus-4-7", "claude-opus-4-8"];
|
|
4399
4548
|
var isClaude4x = (model) => /^claude-(opus|sonnet|haiku)-4-/.test(model);
|
|
4400
4549
|
var dropIfModelRejectsSamplingParams = (v, body) => MODELS_REJECTING_SAMPLING_PARAMS.includes(body.model) ? void 0 : v;
|
|
4401
4550
|
var topPTransform = (v, body) => {
|
|
@@ -4480,6 +4629,11 @@ var anthropicChatV1 = {
|
|
|
4480
4629
|
};
|
|
4481
4630
|
var anthropic = {
|
|
4482
4631
|
"anthropic.chat.v1": anthropicChatV1,
|
|
4632
|
+
// Claude 4.8 models
|
|
4633
|
+
"anthropic.claude-opus-4-8": withDefaultModel(
|
|
4634
|
+
anthropicChatV1,
|
|
4635
|
+
"claude-opus-4-8"
|
|
4636
|
+
),
|
|
4483
4637
|
// Claude 4.7 models
|
|
4484
4638
|
"anthropic.claude-opus-4-7": withDefaultModel(
|
|
4485
4639
|
anthropicChatV1,
|
|
@@ -4663,7 +4817,11 @@ var ollamaChatV1 = {
|
|
|
4663
4817
|
provider: "ollama.chat",
|
|
4664
4818
|
endpoint: `${getEnvironmentVariable("OLLAMA_ENDPOINT") || `http://localhost:11434`}/api/chat`,
|
|
4665
4819
|
options: {
|
|
4666
|
-
prompt: {}
|
|
4820
|
+
prompt: {},
|
|
4821
|
+
temperature: {},
|
|
4822
|
+
topP: {},
|
|
4823
|
+
maxTokens: {},
|
|
4824
|
+
stopSequences: {}
|
|
4667
4825
|
},
|
|
4668
4826
|
method: "POST",
|
|
4669
4827
|
headers: `{"Content-Type": "application/json" }`,
|
|
@@ -4679,6 +4837,18 @@ var ollamaChatV1 = {
|
|
|
4679
4837
|
},
|
|
4680
4838
|
model: {
|
|
4681
4839
|
key: "model"
|
|
4840
|
+
},
|
|
4841
|
+
temperature: {
|
|
4842
|
+
key: "options.temperature"
|
|
4843
|
+
},
|
|
4844
|
+
topP: {
|
|
4845
|
+
key: "options.top_p"
|
|
4846
|
+
},
|
|
4847
|
+
maxTokens: {
|
|
4848
|
+
key: "options.num_predict"
|
|
4849
|
+
},
|
|
4850
|
+
stopSequences: {
|
|
4851
|
+
key: "options.stop"
|
|
4682
4852
|
}
|
|
4683
4853
|
},
|
|
4684
4854
|
transformResponse: OutputOllamaChat
|
|
@@ -4874,7 +5044,10 @@ var googleGeminiChatV1 = {
|
|
|
4874
5044
|
options: {
|
|
4875
5045
|
effort: {},
|
|
4876
5046
|
prompt: {},
|
|
4877
|
-
|
|
5047
|
+
temperature: {},
|
|
5048
|
+
topP: {},
|
|
5049
|
+
maxTokens: {},
|
|
5050
|
+
stopSequences: {},
|
|
4878
5051
|
geminiApiKey: {
|
|
4879
5052
|
default: getEnvironmentVariable("GEMINI_API_KEY")
|
|
4880
5053
|
}
|
|
@@ -4886,6 +5059,18 @@ var googleGeminiChatV1 = {
|
|
|
4886
5059
|
key: "contents",
|
|
4887
5060
|
transform: googleGeminiPromptSanitize
|
|
4888
5061
|
},
|
|
5062
|
+
temperature: {
|
|
5063
|
+
key: "generationConfig.temperature"
|
|
5064
|
+
},
|
|
5065
|
+
topP: {
|
|
5066
|
+
key: "generationConfig.topP"
|
|
5067
|
+
},
|
|
5068
|
+
maxTokens: {
|
|
5069
|
+
key: "generationConfig.maxOutputTokens"
|
|
5070
|
+
},
|
|
5071
|
+
stopSequences: {
|
|
5072
|
+
key: "generationConfig.stopSequences"
|
|
5073
|
+
},
|
|
4889
5074
|
effort: {
|
|
4890
5075
|
key: "config.thinkingConfig.thinkingBudget",
|
|
4891
5076
|
transform: (v, _s) => {
|
|
@@ -5027,6 +5212,13 @@ function isValidUrl(input) {
|
|
|
5027
5212
|
}
|
|
5028
5213
|
|
|
5029
5214
|
// src/utils/modules/request.ts
|
|
5215
|
+
function headersToRecord(headers) {
|
|
5216
|
+
const record = {};
|
|
5217
|
+
headers.forEach((value, key) => {
|
|
5218
|
+
record[key.toLowerCase()] = value;
|
|
5219
|
+
});
|
|
5220
|
+
return record;
|
|
5221
|
+
}
|
|
5030
5222
|
async function apiRequest(url, options) {
|
|
5031
5223
|
const finalOptions = {
|
|
5032
5224
|
...options
|
|
@@ -5112,13 +5304,16 @@ async function apiRequest(url, options) {
|
|
|
5112
5304
|
});
|
|
5113
5305
|
}
|
|
5114
5306
|
const contentType = response.headers.get("content-type");
|
|
5307
|
+
const headers = headersToRecord(response.headers);
|
|
5115
5308
|
if (contentType?.includes("application/json")) {
|
|
5116
|
-
const
|
|
5117
|
-
return
|
|
5118
|
-
} else {
|
|
5119
|
-
const responseData = await response.text();
|
|
5120
|
-
return responseData;
|
|
5309
|
+
const responseData2 = await response.json();
|
|
5310
|
+
return { data: responseData2, headers };
|
|
5121
5311
|
}
|
|
5312
|
+
const responseData = await response.text();
|
|
5313
|
+
return {
|
|
5314
|
+
data: responseData,
|
|
5315
|
+
headers
|
|
5316
|
+
};
|
|
5122
5317
|
}
|
|
5123
5318
|
|
|
5124
5319
|
// src/utils/modules/convertDotNotation.ts
|
|
@@ -5490,7 +5685,7 @@ async function useLlm_call(state, messages, _options) {
|
|
|
5490
5685
|
}
|
|
5491
5686
|
]
|
|
5492
5687
|
};
|
|
5493
|
-
return BaseLlmOutput(transformResponse(mockResponse, config));
|
|
5688
|
+
return BaseLlmOutput(transformResponse(mockResponse, config, {}));
|
|
5494
5689
|
}
|
|
5495
5690
|
try {
|
|
5496
5691
|
const response = await apiRequest(url, {
|
|
@@ -5498,7 +5693,9 @@ async function useLlm_call(state, messages, _options) {
|
|
|
5498
5693
|
body,
|
|
5499
5694
|
headers
|
|
5500
5695
|
});
|
|
5501
|
-
return BaseLlmOutput(
|
|
5696
|
+
return BaseLlmOutput(
|
|
5697
|
+
transformResponse(response.data, config, response.headers)
|
|
5698
|
+
);
|
|
5502
5699
|
} catch (e) {
|
|
5503
5700
|
if (!isLlmExeError(e, "request.http_error")) throw e;
|
|
5504
5701
|
const ctx = e.context ?? {};
|
|
@@ -5679,7 +5876,9 @@ var embeddingConfigs = {
|
|
|
5679
5876
|
"openai.embedding.v1": {
|
|
5680
5877
|
key: "openai.embedding.v1",
|
|
5681
5878
|
provider: "openai.embedding",
|
|
5682
|
-
|
|
5879
|
+
// Templated host: `baseUrl` defaults to OpenAI. Override to point at any
|
|
5880
|
+
// OpenAI-compatible embeddings server (Baseten, vLLM, TEI, Together, etc.).
|
|
5881
|
+
endpoint: `{{baseUrl}}/embeddings`,
|
|
5683
5882
|
method: "POST",
|
|
5684
5883
|
headers: `{"Authorization":"Bearer {{openAiApiKey}}", "Content-Type": "application/json" }`,
|
|
5685
5884
|
options: {
|
|
@@ -5690,6 +5889,9 @@ var embeddingConfigs = {
|
|
|
5690
5889
|
encodingFormat: {},
|
|
5691
5890
|
openAiApiKey: {
|
|
5692
5891
|
default: getEnvironmentVariable("OPENAI_API_KEY")
|
|
5892
|
+
},
|
|
5893
|
+
baseUrl: {
|
|
5894
|
+
default: "https://api.openai.com/v1"
|
|
5693
5895
|
}
|
|
5694
5896
|
},
|
|
5695
5897
|
mapBody: {
|
|
@@ -5876,15 +6078,34 @@ function AmazonTitanEmbedding(result, config) {
|
|
|
5876
6078
|
}
|
|
5877
6079
|
|
|
5878
6080
|
// src/embedding/output/CohereBedrockEmbedding.ts
|
|
5879
|
-
function
|
|
6081
|
+
function resolveEmbeddings(embeddings, model) {
|
|
6082
|
+
if (Array.isArray(embeddings)) {
|
|
6083
|
+
return embeddings;
|
|
6084
|
+
}
|
|
6085
|
+
if (embeddings && typeof embeddings === "object") {
|
|
6086
|
+
if (Array.isArray(embeddings.float)) {
|
|
6087
|
+
return embeddings.float;
|
|
6088
|
+
}
|
|
6089
|
+
throw new Error(
|
|
6090
|
+
`Unexpected embeddings in Cohere Bedrock response (model: "${model}"). Expected float embeddings, received object with keys: [${Object.keys(embeddings).join(", ")}]`
|
|
6091
|
+
);
|
|
6092
|
+
}
|
|
6093
|
+
throw new Error(
|
|
6094
|
+
`Unexpected embeddings shape in Cohere Bedrock response (model: "${model}"). Expected an array (Embed v3) or an object with float embeddings (Embed v4), received: ${embeddings === null ? "null" : typeof embeddings}`
|
|
6095
|
+
);
|
|
6096
|
+
}
|
|
6097
|
+
function CohereBedrockEmbedding(result, config, headers) {
|
|
6098
|
+
const headerUsage = getBedrockTokenCounts(headers);
|
|
5880
6099
|
const __result = deepClone(result);
|
|
5881
6100
|
const model = config.model || "cohere.unknown";
|
|
5882
6101
|
const created = (/* @__PURE__ */ new Date()).getTime();
|
|
5883
|
-
const embedding =
|
|
6102
|
+
const embedding = resolveEmbeddings(__result.embeddings, model);
|
|
6103
|
+
const input_tokens = headerUsage?.input_tokens ?? 0;
|
|
6104
|
+
const output_tokens = headerUsage?.output_tokens ?? 0;
|
|
5884
6105
|
const usage = {
|
|
5885
|
-
output_tokens
|
|
5886
|
-
input_tokens
|
|
5887
|
-
total_tokens:
|
|
6106
|
+
output_tokens,
|
|
6107
|
+
input_tokens,
|
|
6108
|
+
total_tokens: input_tokens + output_tokens
|
|
5888
6109
|
};
|
|
5889
6110
|
return BaseEmbeddingOutput({
|
|
5890
6111
|
id: __result.id,
|
|
@@ -5916,14 +6137,14 @@ function OpenAiEmbedding(result, config) {
|
|
|
5916
6137
|
}
|
|
5917
6138
|
|
|
5918
6139
|
// src/embedding/output/getEmbeddingOutputParser.ts
|
|
5919
|
-
function getEmbeddingOutputParser(config, response) {
|
|
6140
|
+
function getEmbeddingOutputParser(config, response, headers) {
|
|
5920
6141
|
switch (config.key) {
|
|
5921
6142
|
case "openai.embedding.v1":
|
|
5922
6143
|
return OpenAiEmbedding(response, config);
|
|
5923
6144
|
case "amazon.embedding.v1":
|
|
5924
6145
|
return AmazonTitanEmbedding(response, config);
|
|
5925
6146
|
case "amazon:cohere.embedding.v1":
|
|
5926
|
-
return CohereBedrockEmbedding(response, config);
|
|
6147
|
+
return CohereBedrockEmbedding(response, config, headers);
|
|
5927
6148
|
default:
|
|
5928
6149
|
throw new LlmExeError("Unsupported provider", {
|
|
5929
6150
|
code: "embedding.invalid_response_shape",
|
|
@@ -5960,7 +6181,7 @@ async function createEmbedding_call(state, _input, _options) {
|
|
|
5960
6181
|
body,
|
|
5961
6182
|
headers
|
|
5962
6183
|
});
|
|
5963
|
-
return getEmbeddingOutputParser(state, request);
|
|
6184
|
+
return getEmbeddingOutputParser(state, request.data, request.headers);
|
|
5964
6185
|
} catch (e) {
|
|
5965
6186
|
if (!isLlmExeError(e, "request.http_error")) throw e;
|
|
5966
6187
|
const ctx = e.context ?? {};
|