@jaypie/llm 1.2.24 → 1.2.26
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/cjs/index.cjs +126 -13
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/operate/adapters/AnthropicAdapter.d.ts +4 -0
- package/dist/cjs/providers/gemini/types.d.ts +1 -0
- package/dist/cjs/util/index.d.ts +1 -0
- package/dist/cjs/util/jsonSchemaToOpenApi3.d.ts +10 -0
- package/dist/esm/index.js +126 -13
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/operate/adapters/AnthropicAdapter.d.ts +4 -0
- package/dist/esm/providers/gemini/types.d.ts +1 -0
- package/dist/esm/util/index.d.ts +1 -0
- package/dist/esm/util/jsonSchemaToOpenApi3.d.ts +10 -0
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -554,6 +554,50 @@ function formatOperateInput(input, options) {
|
|
|
554
554
|
return [input];
|
|
555
555
|
}
|
|
556
556
|
|
|
557
|
+
/**
|
|
558
|
+
* Converts a JSON Schema (Draft 2020-12) object to the OpenAPI 3.0 schema subset
|
|
559
|
+
* that Gemini's `responseSchema` accepts. This constrains generation (not just validation)
|
|
560
|
+
* and avoids the `items`-keyword leakage bug in `responseJsonSchema`.
|
|
561
|
+
*
|
|
562
|
+
* Strips: $schema, additionalProperties, $defs, $ref (inlines where possible), const
|
|
563
|
+
* Preserves: type, properties, required, items, enum, description, nullable
|
|
564
|
+
*/
|
|
565
|
+
function jsonSchemaToOpenApi3(schema) {
|
|
566
|
+
if (typeof schema !== "object" || schema === null || Array.isArray(schema)) {
|
|
567
|
+
return schema;
|
|
568
|
+
}
|
|
569
|
+
const result = {};
|
|
570
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
571
|
+
// Strip JSON Schema keywords not in OpenAPI 3.0 subset
|
|
572
|
+
if (key === "$schema" ||
|
|
573
|
+
key === "$defs" ||
|
|
574
|
+
key === "additionalProperties" ||
|
|
575
|
+
key === "const" ||
|
|
576
|
+
key === "$ref") {
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
if (key === "properties" &&
|
|
580
|
+
typeof value === "object" &&
|
|
581
|
+
value !== null &&
|
|
582
|
+
!Array.isArray(value)) {
|
|
583
|
+
const convertedProps = {};
|
|
584
|
+
for (const [propKey, propValue] of Object.entries(value)) {
|
|
585
|
+
convertedProps[propKey] = jsonSchemaToOpenApi3(propValue);
|
|
586
|
+
}
|
|
587
|
+
result[key] = convertedProps;
|
|
588
|
+
}
|
|
589
|
+
else if (key === "items" &&
|
|
590
|
+
typeof value === "object" &&
|
|
591
|
+
value !== null) {
|
|
592
|
+
result[key] = jsonSchemaToOpenApi3(value);
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
result[key] = value;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return result;
|
|
599
|
+
}
|
|
600
|
+
|
|
557
601
|
const getLogger$5 = () => log$1.log.lib({ lib: kit.JAYPIE.LIB.LLM });
|
|
558
602
|
|
|
559
603
|
// Turn policy constants
|
|
@@ -1021,6 +1065,24 @@ const NOT_RETRYABLE_ERROR_NAMES = [
|
|
|
1021
1065
|
"NotFoundError",
|
|
1022
1066
|
"PermissionDeniedError",
|
|
1023
1067
|
];
|
|
1068
|
+
// Models known not to accept `temperature`.
|
|
1069
|
+
// Patterns (not exact names) so dated variants and future releases are covered
|
|
1070
|
+
// without code changes — Anthropic is trending toward removing temperature on
|
|
1071
|
+
// newer Claude models.
|
|
1072
|
+
const MODELS_WITHOUT_TEMPERATURE = [
|
|
1073
|
+
/^claude-opus-4-[789]/,
|
|
1074
|
+
/^claude-opus-[5-9]/,
|
|
1075
|
+
];
|
|
1076
|
+
function isTemperatureDeprecationError(error) {
|
|
1077
|
+
if (!error || typeof error !== "object")
|
|
1078
|
+
return false;
|
|
1079
|
+
const err = error;
|
|
1080
|
+
const name = error?.constructor?.name;
|
|
1081
|
+
if (name !== "BadRequestError" && err.status !== 400)
|
|
1082
|
+
return false;
|
|
1083
|
+
const messages = [err.message, err.error?.message].filter((m) => typeof m === "string");
|
|
1084
|
+
return messages.some((m) => m.toLowerCase().includes("temperature"));
|
|
1085
|
+
}
|
|
1024
1086
|
//
|
|
1025
1087
|
//
|
|
1026
1088
|
// Main
|
|
@@ -1035,6 +1097,20 @@ class AnthropicAdapter extends BaseProviderAdapter {
|
|
|
1035
1097
|
super(...arguments);
|
|
1036
1098
|
this.name = PROVIDER.ANTHROPIC.NAME;
|
|
1037
1099
|
this.defaultModel = PROVIDER.ANTHROPIC.MODEL.DEFAULT;
|
|
1100
|
+
// Session-level cache of models observed to reject `temperature` at runtime.
|
|
1101
|
+
// Populated by executeRequest on 400 errors so repeat calls skip the param.
|
|
1102
|
+
this.runtimeNoTemperatureModels = new Set();
|
|
1103
|
+
}
|
|
1104
|
+
rememberModelRejectsTemperature(model) {
|
|
1105
|
+
this.runtimeNoTemperatureModels.add(model);
|
|
1106
|
+
}
|
|
1107
|
+
clearRuntimeNoTemperatureModels() {
|
|
1108
|
+
this.runtimeNoTemperatureModels.clear();
|
|
1109
|
+
}
|
|
1110
|
+
supportsTemperature(model) {
|
|
1111
|
+
if (this.runtimeNoTemperatureModels.has(model))
|
|
1112
|
+
return false;
|
|
1113
|
+
return !MODELS_WITHOUT_TEMPERATURE.some((pattern) => pattern.test(model));
|
|
1038
1114
|
}
|
|
1039
1115
|
//
|
|
1040
1116
|
// Request Building
|
|
@@ -1126,6 +1202,11 @@ class AnthropicAdapter extends BaseProviderAdapter {
|
|
|
1126
1202
|
if (request.temperature !== undefined) {
|
|
1127
1203
|
anthropicRequest.temperature = request.temperature;
|
|
1128
1204
|
}
|
|
1205
|
+
// Strip temperature for models that don't support it (denylist + runtime cache)
|
|
1206
|
+
if (anthropicRequest.temperature !== undefined &&
|
|
1207
|
+
!this.supportsTemperature(anthropicRequest.model)) {
|
|
1208
|
+
delete anthropicRequest.temperature;
|
|
1209
|
+
}
|
|
1129
1210
|
return anthropicRequest;
|
|
1130
1211
|
}
|
|
1131
1212
|
formatTools(toolkit, outputSchema) {
|
|
@@ -1176,22 +1257,48 @@ class AnthropicAdapter extends BaseProviderAdapter {
|
|
|
1176
1257
|
//
|
|
1177
1258
|
async executeRequest(client, request, signal) {
|
|
1178
1259
|
const anthropic = client;
|
|
1260
|
+
const anthropicRequest = request;
|
|
1179
1261
|
try {
|
|
1180
|
-
return (await anthropic.messages.create(
|
|
1262
|
+
return (await anthropic.messages.create(anthropicRequest, signal ? { signal } : undefined));
|
|
1181
1263
|
}
|
|
1182
1264
|
catch (error) {
|
|
1183
1265
|
if (signal?.aborted)
|
|
1184
1266
|
return undefined;
|
|
1267
|
+
// If the model rejected `temperature`, cache it and retry without the param
|
|
1268
|
+
if (anthropicRequest.temperature !== undefined &&
|
|
1269
|
+
isTemperatureDeprecationError(error)) {
|
|
1270
|
+
this.rememberModelRejectsTemperature(anthropicRequest.model);
|
|
1271
|
+
const retryRequest = { ...anthropicRequest };
|
|
1272
|
+
delete retryRequest.temperature;
|
|
1273
|
+
return (await anthropic.messages.create(retryRequest, signal ? { signal } : undefined));
|
|
1274
|
+
}
|
|
1185
1275
|
throw error;
|
|
1186
1276
|
}
|
|
1187
1277
|
}
|
|
1188
1278
|
async *executeStreamRequest(client, request, signal) {
|
|
1189
1279
|
const anthropic = client;
|
|
1190
|
-
|
|
1280
|
+
let streamRequest = {
|
|
1191
1281
|
...request,
|
|
1192
1282
|
stream: true,
|
|
1193
1283
|
};
|
|
1194
|
-
|
|
1284
|
+
let stream;
|
|
1285
|
+
try {
|
|
1286
|
+
stream = await anthropic.messages.create(streamRequest, signal ? { signal } : undefined);
|
|
1287
|
+
}
|
|
1288
|
+
catch (error) {
|
|
1289
|
+
if (streamRequest.temperature !== undefined &&
|
|
1290
|
+
isTemperatureDeprecationError(error)) {
|
|
1291
|
+
this.rememberModelRejectsTemperature(streamRequest.model);
|
|
1292
|
+
streamRequest = {
|
|
1293
|
+
...streamRequest,
|
|
1294
|
+
};
|
|
1295
|
+
delete streamRequest.temperature;
|
|
1296
|
+
stream = await anthropic.messages.create(streamRequest, signal ? { signal } : undefined);
|
|
1297
|
+
}
|
|
1298
|
+
else {
|
|
1299
|
+
throw error;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1195
1302
|
// Track current tool call being built
|
|
1196
1303
|
let currentToolCall = null;
|
|
1197
1304
|
// Track usage for final chunk
|
|
@@ -1540,11 +1647,21 @@ class GeminiAdapter extends BaseProviderAdapter {
|
|
|
1540
1647
|
// Gemini doesn't support combining function calling with responseMimeType: 'application/json'
|
|
1541
1648
|
// When tools are present, structured output is handled via the structured_output tool
|
|
1542
1649
|
if (request.format && !(request.tools && request.tools.length > 0)) {
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1650
|
+
const useJsonSchema = request.providerOptions?.useJsonSchema === true;
|
|
1651
|
+
if (useJsonSchema) {
|
|
1652
|
+
geminiRequest.config = {
|
|
1653
|
+
...geminiRequest.config,
|
|
1654
|
+
responseMimeType: "application/json",
|
|
1655
|
+
responseJsonSchema: request.format,
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
else {
|
|
1659
|
+
geminiRequest.config = {
|
|
1660
|
+
...geminiRequest.config,
|
|
1661
|
+
responseMimeType: "application/json",
|
|
1662
|
+
responseSchema: jsonSchemaToOpenApi3(request.format),
|
|
1663
|
+
};
|
|
1664
|
+
}
|
|
1548
1665
|
}
|
|
1549
1666
|
// When format is specified with tools, add instruction to use structured_output tool
|
|
1550
1667
|
if (request.format && request.tools && request.tools.length > 0) {
|
|
@@ -1612,11 +1729,7 @@ class GeminiAdapter extends BaseProviderAdapter {
|
|
|
1612
1729
|
: naturalZodSchema(schema);
|
|
1613
1730
|
jsonSchema = v4.z.toJSONSchema(zodSchema);
|
|
1614
1731
|
}
|
|
1615
|
-
|
|
1616
|
-
if (jsonSchema.$schema) {
|
|
1617
|
-
delete jsonSchema.$schema;
|
|
1618
|
-
}
|
|
1619
|
-
return jsonSchema;
|
|
1732
|
+
return jsonSchemaToOpenApi3(jsonSchema);
|
|
1620
1733
|
}
|
|
1621
1734
|
//
|
|
1622
1735
|
// API Execution
|