190proof 1.0.113 → 1.0.114
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/README.md +4 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +114 -151
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +112 -150
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -279,6 +279,7 @@ Optional per-request knobs live on `payload` (`GenericPayload`):
|
|
|
279
279
|
- `payload.streaming`: `boolean` - OpenRouter-only (default: true). Streams the completion over SSE. A streaming attempt is bounded by two independent timers instead of `requestTimeoutMs`: `streamTimeoutMs` (total wall clock, default 600000) and the per-useful-chunk stall timeout (`chunkTimeoutMs` argument, default 15000). A chunk is "useful" only if it advances content, reasoning, tool-call fragments, finish_reason, or usage — SSE comment keep-alives (`: OPENROUTER PROCESSING`) and role-only deltas don't reset the stall timer, so a hung provider dies within one stall window while a healthy long generation can run to the total budget. Set `streaming: false` for the old single-JSON-body transport.
|
|
280
280
|
- `payload.streamTimeoutMs`: `number` - OpenRouter-only: total wall-clock budget per streaming attempt (default: 600000).
|
|
281
281
|
- `payload.streamDeadlineAt`: `number` - OpenRouter-only: absolute deadline (epoch ms) for the whole call **including retries** — the caller's turn budget. Each attempt gets `min(streamTimeoutMs, deadline - now)`, and once under 10s remain the call fails fast instead of starting a generation that cannot be delivered. Use it whenever the caller has its own timeout: a per-attempt budget alone is re-granted on every retry and can outlive that timeout.
|
|
282
|
+
- `payload.thinkingConfig`: `Record<string, unknown>` - Google-only: forwarded verbatim as `generationConfig.thinkingConfig` on the Gemini request — e.g. `{ thinkingBudget: 0 }` to disable thinking, `{ thinkingLevel: "HIGH" }` on models that take a level. Ignored by all other adapters; shapes are model-specific and validated by Google, not the SDK.
|
|
282
283
|
|
|
283
284
|
When a streaming attempt is cut at its **total deadline** and prose has already arrived, the partial answer is returned with `truncated: true` on the response rather than discarded — those tokens were generated and billed, so throwing them away costs money and gives the user nothing. Surface such a reply as incomplete. Salvage never applies to tool-call turns (half-streamed arguments are unparseable JSON), to stalls (the provider died mid-thought), or to caller aborts. When nothing is salvageable, the discard is logged with an approximate token count — aborted attempts never receive OpenRouter's `usage` chunk, so that log line is the only record of the wasted spend.
|
|
284
285
|
|
|
@@ -304,6 +305,9 @@ interface ParsedResponseMessage {
|
|
|
304
305
|
prompt_tokens: number;
|
|
305
306
|
completion_tokens: number;
|
|
306
307
|
total_tokens: number;
|
|
308
|
+
// Reasoning/thinking tokens spent before the visible answer; currently
|
|
309
|
+
// populated from Google's usageMetadata.thoughtsTokenCount.
|
|
310
|
+
thoughts_tokens?: number;
|
|
307
311
|
} | null; // null when streaming
|
|
308
312
|
}
|
|
309
313
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -199,6 +199,13 @@ interface ParsedResponseMessage {
|
|
|
199
199
|
total_tokens: number;
|
|
200
200
|
/** Prompt tokens served from the provider's cache (subset of prompt_tokens). */
|
|
201
201
|
cached_tokens?: number;
|
|
202
|
+
/**
|
|
203
|
+
* Reasoning/thinking tokens spent before the visible answer (subset of
|
|
204
|
+
* completion_tokens on some providers, separate on others). Currently
|
|
205
|
+
* populated from Google's `usageMetadata.thoughtsTokenCount`; undefined
|
|
206
|
+
* when the provider reports none.
|
|
207
|
+
*/
|
|
208
|
+
thoughts_tokens?: number;
|
|
202
209
|
} | null;
|
|
203
210
|
}
|
|
204
211
|
interface FunctionCall {
|
|
@@ -275,6 +282,14 @@ interface GenericPayload {
|
|
|
275
282
|
};
|
|
276
283
|
temperature?: number;
|
|
277
284
|
fallbackModel?: AnyModel;
|
|
285
|
+
/**
|
|
286
|
+
* Google-only: forwarded verbatim as `generationConfig.thinkingConfig` on
|
|
287
|
+
* the Gemini request — e.g. `{ thinkingBudget: 0 }` to disable thinking or
|
|
288
|
+
* `{ thinkingLevel: "HIGH" }` on models that take a level. Ignored by all
|
|
289
|
+
* other adapters. Shapes are model-specific and validated by Google, not
|
|
290
|
+
* the SDK.
|
|
291
|
+
*/
|
|
292
|
+
thinkingConfig?: Record<string, unknown>;
|
|
278
293
|
/**
|
|
279
294
|
* OpenRouter-only: provider-routing preferences. Ignored by non-OpenRouter
|
|
280
295
|
* adapters. Forwarded as the request body's `provider` field.
|
package/dist/index.d.ts
CHANGED
|
@@ -199,6 +199,13 @@ interface ParsedResponseMessage {
|
|
|
199
199
|
total_tokens: number;
|
|
200
200
|
/** Prompt tokens served from the provider's cache (subset of prompt_tokens). */
|
|
201
201
|
cached_tokens?: number;
|
|
202
|
+
/**
|
|
203
|
+
* Reasoning/thinking tokens spent before the visible answer (subset of
|
|
204
|
+
* completion_tokens on some providers, separate on others). Currently
|
|
205
|
+
* populated from Google's `usageMetadata.thoughtsTokenCount`; undefined
|
|
206
|
+
* when the provider reports none.
|
|
207
|
+
*/
|
|
208
|
+
thoughts_tokens?: number;
|
|
202
209
|
} | null;
|
|
203
210
|
}
|
|
204
211
|
interface FunctionCall {
|
|
@@ -275,6 +282,14 @@ interface GenericPayload {
|
|
|
275
282
|
};
|
|
276
283
|
temperature?: number;
|
|
277
284
|
fallbackModel?: AnyModel;
|
|
285
|
+
/**
|
|
286
|
+
* Google-only: forwarded verbatim as `generationConfig.thinkingConfig` on
|
|
287
|
+
* the Gemini request — e.g. `{ thinkingBudget: 0 }` to disable thinking or
|
|
288
|
+
* `{ thinkingLevel: "HIGH" }` on models that take a level. Ignored by all
|
|
289
|
+
* other adapters. Shapes are model-specific and validated by Google, not
|
|
290
|
+
* the SDK.
|
|
291
|
+
*/
|
|
292
|
+
thinkingConfig?: Record<string, unknown>;
|
|
278
293
|
/**
|
|
279
294
|
* OpenRouter-only: provider-routing preferences. Ignored by non-OpenRouter
|
|
280
295
|
* adapters. Forwarded as the request body's `provider` field.
|
package/dist/index.js
CHANGED
|
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
30
|
// index.ts
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
33
|
ClaudeModel: () => ClaudeModel,
|
|
34
34
|
GPTModel: () => GPTModel,
|
|
35
35
|
GeminiModel: () => GeminiModel,
|
|
@@ -41,7 +41,7 @@ __export(proof_exports, {
|
|
|
41
41
|
callWithRetries: () => callWithRetries,
|
|
42
42
|
parseModelString: () => parseModelString
|
|
43
43
|
});
|
|
44
|
-
module.exports = __toCommonJS(
|
|
44
|
+
module.exports = __toCommonJS(index_exports);
|
|
45
45
|
|
|
46
46
|
// interfaces.ts
|
|
47
47
|
var ClaudeModel = /* @__PURE__ */ ((ClaudeModel2) => {
|
|
@@ -172,8 +172,7 @@ async function withRetries(identifier, apiName, fn, options = {}) {
|
|
|
172
172
|
return await fn();
|
|
173
173
|
} catch (error3) {
|
|
174
174
|
lastError = error3;
|
|
175
|
-
if ((_a = options.signal) == null ? void 0 : _a.aborted)
|
|
176
|
-
throw error3;
|
|
175
|
+
if ((_a = options.signal) == null ? void 0 : _a.aborted) throw error3;
|
|
177
176
|
if (onError) {
|
|
178
177
|
onError(error3, attempt);
|
|
179
178
|
} else {
|
|
@@ -197,8 +196,7 @@ function parseStreamedResponse(identifier, paragraph, toolCallAccumulators, allo
|
|
|
197
196
|
const functionCalls = [];
|
|
198
197
|
for (let i = 0; i < toolCallAccumulators.length; i++) {
|
|
199
198
|
const acc = toolCallAccumulators[i];
|
|
200
|
-
if (!acc.name || !acc.arguments)
|
|
201
|
-
continue;
|
|
199
|
+
if (!acc.name || !acc.arguments) continue;
|
|
202
200
|
if (allowedFunctionNames && !allowedFunctionNames.has(acc.name)) {
|
|
203
201
|
throw new Error(
|
|
204
202
|
`Stream error: received function call with unknown name: ${acc.name}`
|
|
@@ -337,8 +335,7 @@ function buildOpenAIRequestConfig(identifier, model, config) {
|
|
|
337
335
|
};
|
|
338
336
|
}
|
|
339
337
|
function filterOpenAICompatReasoningDetails(details) {
|
|
340
|
-
if (!Array.isArray(details))
|
|
341
|
-
return details || void 0;
|
|
338
|
+
if (!Array.isArray(details)) return details || void 0;
|
|
342
339
|
const blocks = details.filter(
|
|
343
340
|
(block) => typeof (block == null ? void 0 : block.type) === "string" && block.type.startsWith("reasoning.")
|
|
344
341
|
);
|
|
@@ -409,13 +406,11 @@ async function prepareOpenAIPayload(identifier, payload) {
|
|
|
409
406
|
};
|
|
410
407
|
});
|
|
411
408
|
}
|
|
412
|
-
if (message.reasoning)
|
|
413
|
-
outMessage.reasoning = message.reasoning;
|
|
409
|
+
if (message.reasoning) outMessage.reasoning = message.reasoning;
|
|
414
410
|
const reasoningDetails = filterOpenAICompatReasoningDetails(
|
|
415
411
|
message.reasoningDetails
|
|
416
412
|
);
|
|
417
|
-
if (reasoningDetails)
|
|
418
|
-
outMessage.reasoning_details = reasoningDetails;
|
|
413
|
+
if (reasoningDetails) outMessage.reasoning_details = reasoningDetails;
|
|
419
414
|
preparedPayload.messages.push(outMessage);
|
|
420
415
|
}
|
|
421
416
|
return preparedPayload;
|
|
@@ -477,8 +472,7 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs,
|
|
|
477
472
|
}
|
|
478
473
|
const jsonStrings = chunk.split(/^data: /gm);
|
|
479
474
|
for (const jsonString of jsonStrings) {
|
|
480
|
-
if (!jsonString)
|
|
481
|
-
continue;
|
|
475
|
+
if (!jsonString) continue;
|
|
482
476
|
if (jsonString.includes("[DONE]")) {
|
|
483
477
|
clearTimeout(overallTimeout);
|
|
484
478
|
return parseStreamedResponse(
|
|
@@ -516,8 +510,7 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs,
|
|
|
516
510
|
while (toolCallAccumulators.length <= idx) {
|
|
517
511
|
toolCallAccumulators.push({ name: "", arguments: "" });
|
|
518
512
|
}
|
|
519
|
-
if (toolCall.id)
|
|
520
|
-
toolCallAccumulators[idx].id = toolCall.id;
|
|
513
|
+
if (toolCall.id) toolCallAccumulators[idx].id = toolCall.id;
|
|
521
514
|
if ((_e = toolCall.function) == null ? void 0 : _e.name)
|
|
522
515
|
toolCallAccumulators[idx].name += toolCall.function.name;
|
|
523
516
|
if ((_f = toolCall.function) == null ? void 0 : _f.arguments)
|
|
@@ -525,11 +518,9 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs,
|
|
|
525
518
|
}
|
|
526
519
|
}
|
|
527
520
|
const text = (_h = (_g = json.choices[0]) == null ? void 0 : _g.delta) == null ? void 0 : _h.content;
|
|
528
|
-
if (text)
|
|
529
|
-
paragraph += text;
|
|
521
|
+
if (text) paragraph += text;
|
|
530
522
|
const reasoningDelta = (_j = (_i = json.choices[0]) == null ? void 0 : _i.delta) == null ? void 0 : _j.reasoning;
|
|
531
|
-
if (reasoningDelta)
|
|
532
|
-
reasoning += reasoningDelta;
|
|
523
|
+
if (reasoningDelta) reasoning += reasoningDelta;
|
|
533
524
|
}
|
|
534
525
|
}
|
|
535
526
|
}
|
|
@@ -674,8 +665,7 @@ function jigAnthropicMessages(messages) {
|
|
|
674
665
|
];
|
|
675
666
|
}
|
|
676
667
|
jiggedMessages = jiggedMessages.reduce((acc, message) => {
|
|
677
|
-
if (acc.length === 0)
|
|
678
|
-
return [message];
|
|
668
|
+
if (acc.length === 0) return [message];
|
|
679
669
|
const lastMessage = acc[acc.length - 1];
|
|
680
670
|
if (lastMessage.role === message.role) {
|
|
681
671
|
const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
|
|
@@ -929,8 +919,7 @@ function jigGoogleMessages(messages) {
|
|
|
929
919
|
];
|
|
930
920
|
}
|
|
931
921
|
jiggedMessages = jiggedMessages.reduce((acc, message) => {
|
|
932
|
-
if (acc.length === 0)
|
|
933
|
-
return [message];
|
|
922
|
+
if (acc.length === 0) return [message];
|
|
934
923
|
const lastMessage = acc[acc.length - 1];
|
|
935
924
|
if (lastMessage.role === message.role) {
|
|
936
925
|
lastMessage.parts = [...lastMessage.parts, ...message.parts];
|
|
@@ -948,6 +937,7 @@ async function prepareGoogleAIPayload(_identifier, payload) {
|
|
|
948
937
|
const preparedPayload = {
|
|
949
938
|
model: payload.model,
|
|
950
939
|
messages: [],
|
|
940
|
+
thinkingConfig: payload.thinkingConfig,
|
|
951
941
|
tools: payload.functions ? {
|
|
952
942
|
functionDeclarations: payload.functions.map((fn) => ({
|
|
953
943
|
name: fn.name,
|
|
@@ -968,8 +958,7 @@ async function prepareGoogleAIPayload(_identifier, payload) {
|
|
|
968
958
|
const toolNameById = /* @__PURE__ */ new Map();
|
|
969
959
|
for (const m of payload.messages) {
|
|
970
960
|
for (const fc of m.functionCalls || []) {
|
|
971
|
-
if (fc.id)
|
|
972
|
-
toolNameById.set(fc.id, fc.name);
|
|
961
|
+
if (fc.id) toolNameById.set(fc.id, fc.name);
|
|
973
962
|
}
|
|
974
963
|
}
|
|
975
964
|
for (const message of payload.messages) {
|
|
@@ -1044,10 +1033,12 @@ async function callGoogleAI(id, payload, requestTimeoutMs = 12e4, signal) {
|
|
|
1044
1033
|
const contents = jigGoogleMessages(payload.messages);
|
|
1045
1034
|
const requestBody = {
|
|
1046
1035
|
contents,
|
|
1047
|
-
generationConfig: {
|
|
1036
|
+
generationConfig: {
|
|
1037
|
+
responseModalities: ["TEXT"],
|
|
1038
|
+
...payload.thinkingConfig ? { thinkingConfig: payload.thinkingConfig } : {}
|
|
1039
|
+
}
|
|
1048
1040
|
};
|
|
1049
|
-
if (payload.tools)
|
|
1050
|
-
requestBody.tools = [payload.tools];
|
|
1041
|
+
if (payload.tools) requestBody.tools = [payload.tools];
|
|
1051
1042
|
if (payload.tools && payload.toolConfig) {
|
|
1052
1043
|
requestBody.toolConfig = payload.toolConfig;
|
|
1053
1044
|
}
|
|
@@ -1105,8 +1096,7 @@ async function callGoogleAI(id, payload, requestTimeoutMs = 12e4, signal) {
|
|
|
1105
1096
|
});
|
|
1106
1097
|
continue;
|
|
1107
1098
|
}
|
|
1108
|
-
if (part.text)
|
|
1109
|
-
text += part.text;
|
|
1099
|
+
if (part.text) text += part.text;
|
|
1110
1100
|
if ((_m = part.inlineData) == null ? void 0 : _m.data) {
|
|
1111
1101
|
files.push({ mimeType: "image/png", data: part.inlineData.data });
|
|
1112
1102
|
}
|
|
@@ -1150,7 +1140,8 @@ async function callGoogleAI(id, payload, requestTimeoutMs = 12e4, signal) {
|
|
|
1150
1140
|
prompt_tokens: (_o = response.usageMetadata.promptTokenCount) != null ? _o : 0,
|
|
1151
1141
|
completion_tokens: (_p = response.usageMetadata.candidatesTokenCount) != null ? _p : 0,
|
|
1152
1142
|
total_tokens: (_q = response.usageMetadata.totalTokenCount) != null ? _q : 0,
|
|
1153
|
-
cached_tokens: (_r = response.usageMetadata.cachedContentTokenCount) != null ? _r : 0
|
|
1143
|
+
cached_tokens: (_r = response.usageMetadata.cachedContentTokenCount) != null ? _r : 0,
|
|
1144
|
+
thoughts_tokens: response.usageMetadata.thoughtsTokenCount
|
|
1154
1145
|
} : null
|
|
1155
1146
|
};
|
|
1156
1147
|
}
|
|
@@ -1183,21 +1174,15 @@ async function callGoogleAIWithRetries(id, payload, retries = 5, requestTimeoutM
|
|
|
1183
1174
|
finishReason: error2.finishReason,
|
|
1184
1175
|
modelVersion: error2.modelVersion
|
|
1185
1176
|
};
|
|
1186
|
-
if (error2.safetyRatings)
|
|
1187
|
-
|
|
1188
|
-
if (error2.usageMetadata)
|
|
1189
|
-
errorDetails.usageMetadata = error2.usageMetadata;
|
|
1177
|
+
if (error2.safetyRatings) errorDetails.safetyRatings = error2.safetyRatings;
|
|
1178
|
+
if (error2.usageMetadata) errorDetails.usageMetadata = error2.usageMetadata;
|
|
1190
1179
|
if (error2.promptFeedback)
|
|
1191
1180
|
errorDetails.promptFeedback = error2.promptFeedback;
|
|
1192
|
-
if (error2.status)
|
|
1193
|
-
|
|
1194
|
-
if (error2.
|
|
1195
|
-
errorDetails.errorCode = error2.code;
|
|
1196
|
-
if (error2.details)
|
|
1197
|
-
errorDetails.errorDetails = error2.details;
|
|
1181
|
+
if (error2.status) errorDetails.httpStatus = error2.status;
|
|
1182
|
+
if (error2.code) errorDetails.errorCode = error2.code;
|
|
1183
|
+
if (error2.details) errorDetails.errorDetails = error2.details;
|
|
1198
1184
|
const fileUris = payload.messages.flatMap((m) => m.parts).filter((p) => "fileData" in p).map((p) => p.fileData.fileUri);
|
|
1199
|
-
if (fileUris.length)
|
|
1200
|
-
errorDetails.fileUris = fileUris;
|
|
1185
|
+
if (fileUris.length) errorDetails.fileUris = fileUris;
|
|
1201
1186
|
logger_default.error(
|
|
1202
1187
|
id,
|
|
1203
1188
|
`Retry #${attempt} error: ${error2.message}`,
|
|
@@ -1281,16 +1266,13 @@ function prepareOpenAICompatMessages(messages) {
|
|
|
1281
1266
|
}
|
|
1282
1267
|
};
|
|
1283
1268
|
});
|
|
1284
|
-
if (!content)
|
|
1285
|
-
outMessage.content = null;
|
|
1269
|
+
if (!content) outMessage.content = null;
|
|
1286
1270
|
}
|
|
1287
|
-
if (message.reasoning)
|
|
1288
|
-
outMessage.reasoning = message.reasoning;
|
|
1271
|
+
if (message.reasoning) outMessage.reasoning = message.reasoning;
|
|
1289
1272
|
const reasoningDetails = filterOpenAICompatReasoningDetails(
|
|
1290
1273
|
message.reasoningDetails
|
|
1291
1274
|
);
|
|
1292
|
-
if (reasoningDetails)
|
|
1293
|
-
outMessage.reasoning_details = reasoningDetails;
|
|
1275
|
+
if (reasoningDetails) outMessage.reasoning_details = reasoningDetails;
|
|
1294
1276
|
out.push(outMessage);
|
|
1295
1277
|
}
|
|
1296
1278
|
return out;
|
|
@@ -1433,8 +1415,7 @@ function parseDsmlToolCalls(content) {
|
|
|
1433
1415
|
let last = -1;
|
|
1434
1416
|
let tag;
|
|
1435
1417
|
while ((tag = DSML_ANY_TAG_RE.exec(content)) !== null) {
|
|
1436
|
-
if (first === -1)
|
|
1437
|
-
first = tag.index;
|
|
1418
|
+
if (first === -1) first = tag.index;
|
|
1438
1419
|
last = tag.index + tag[0].length;
|
|
1439
1420
|
}
|
|
1440
1421
|
const remaining = first === -1 ? content : (content.slice(0, first) + content.slice(last)).trim();
|
|
@@ -1450,8 +1431,7 @@ function finalizeOpenRouterMessage(id, raw) {
|
|
|
1450
1431
|
const functionCalls = [];
|
|
1451
1432
|
for (let i = 0; i < raw.toolCalls.length; i++) {
|
|
1452
1433
|
const tc = raw.toolCalls[i];
|
|
1453
|
-
if (!tc.name)
|
|
1454
|
-
continue;
|
|
1434
|
+
if (!tc.name) continue;
|
|
1455
1435
|
functionCalls.push({
|
|
1456
1436
|
id: (_a = tc.id) != null ? _a : `call_${i}`,
|
|
1457
1437
|
name: tc.name,
|
|
@@ -1504,8 +1484,7 @@ async function callOpenRouterStream(id, payload, streamTimeoutMs = OPENROUTER_ST
|
|
|
1504
1484
|
controller.abort();
|
|
1505
1485
|
};
|
|
1506
1486
|
const unref = (t) => {
|
|
1507
|
-
if (typeof t === "object" && "unref" in t)
|
|
1508
|
-
t.unref();
|
|
1487
|
+
if (typeof t === "object" && "unref" in t) t.unref();
|
|
1509
1488
|
return t;
|
|
1510
1489
|
};
|
|
1511
1490
|
const totalTimer = unref(
|
|
@@ -1573,98 +1552,88 @@ async function callOpenRouterStream(id, payload, streamTimeoutMs = OPENROUTER_ST
|
|
|
1573
1552
|
const reader = response.body.getReader();
|
|
1574
1553
|
const decoder = new TextDecoder();
|
|
1575
1554
|
let lineBuffer = "";
|
|
1576
|
-
outer:
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
let newlineIdx;
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1555
|
+
outer: while (true) {
|
|
1556
|
+
const { done, value } = await reader.read();
|
|
1557
|
+
if (done) break;
|
|
1558
|
+
lineBuffer += decoder.decode(value, { stream: true });
|
|
1559
|
+
let newlineIdx;
|
|
1560
|
+
while ((newlineIdx = lineBuffer.indexOf("\n")) !== -1) {
|
|
1561
|
+
let line = lineBuffer.slice(0, newlineIdx);
|
|
1562
|
+
lineBuffer = lineBuffer.slice(newlineIdx + 1);
|
|
1563
|
+
if (line.endsWith("\r")) line = line.slice(0, -1);
|
|
1564
|
+
if (!line) continue;
|
|
1565
|
+
if (line.startsWith(":")) continue;
|
|
1566
|
+
if (!line.startsWith("data:")) continue;
|
|
1567
|
+
const dataStr = line.slice(5).trimStart();
|
|
1568
|
+
if (dataStr === "[DONE]") {
|
|
1569
|
+
sawDone = true;
|
|
1570
|
+
break outer;
|
|
1571
|
+
}
|
|
1572
|
+
let json;
|
|
1573
|
+
try {
|
|
1574
|
+
json = JSON.parse(dataStr);
|
|
1575
|
+
} catch (e) {
|
|
1576
|
+
logger_default.error(
|
|
1577
|
+
id,
|
|
1578
|
+
"OpenRouter stream: unparseable data line:",
|
|
1579
|
+
dataStr.slice(0, 200)
|
|
1580
|
+
);
|
|
1581
|
+
continue;
|
|
1582
|
+
}
|
|
1583
|
+
dataChunks++;
|
|
1584
|
+
if (json.error) {
|
|
1585
|
+
logger_default.error(id, "OpenRouter stream error event:", json.error);
|
|
1586
|
+
const error2 = new Error(
|
|
1587
|
+
`OpenRouter error: ${json.error.message}`
|
|
1588
|
+
);
|
|
1589
|
+
error2.data = json.error;
|
|
1590
|
+
throw error2;
|
|
1591
|
+
}
|
|
1592
|
+
if (json.provider) provider = json.provider;
|
|
1593
|
+
let useful = false;
|
|
1594
|
+
if (json.usage) {
|
|
1595
|
+
usage = json.usage;
|
|
1596
|
+
useful = true;
|
|
1597
|
+
}
|
|
1598
|
+
const choice = (_c = json.choices) == null ? void 0 : _c[0];
|
|
1599
|
+
if (choice) {
|
|
1600
|
+
const delta = (_d = choice.delta) != null ? _d : {};
|
|
1601
|
+
if (delta.content) {
|
|
1602
|
+
paragraph += delta.content;
|
|
1603
|
+
useful = true;
|
|
1609
1604
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
const error2 = new Error(
|
|
1614
|
-
`OpenRouter error: ${json.error.message}`
|
|
1615
|
-
);
|
|
1616
|
-
error2.data = json.error;
|
|
1617
|
-
throw error2;
|
|
1605
|
+
if (delta.reasoning) {
|
|
1606
|
+
reasoning += delta.reasoning;
|
|
1607
|
+
useful = true;
|
|
1618
1608
|
}
|
|
1619
|
-
if (
|
|
1620
|
-
|
|
1621
|
-
let useful = false;
|
|
1622
|
-
if (json.usage) {
|
|
1623
|
-
usage = json.usage;
|
|
1609
|
+
if (Array.isArray(delta.reasoning_details) && delta.reasoning_details.length) {
|
|
1610
|
+
reasoningDetails.push(...delta.reasoning_details);
|
|
1624
1611
|
useful = true;
|
|
1625
1612
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
useful = true;
|
|
1632
|
-
}
|
|
1633
|
-
if (delta.reasoning) {
|
|
1634
|
-
reasoning += delta.reasoning;
|
|
1635
|
-
useful = true;
|
|
1636
|
-
}
|
|
1637
|
-
if (Array.isArray(delta.reasoning_details) && delta.reasoning_details.length) {
|
|
1638
|
-
reasoningDetails.push(...delta.reasoning_details);
|
|
1639
|
-
useful = true;
|
|
1640
|
-
}
|
|
1641
|
-
if (Array.isArray(delta.tool_calls)) {
|
|
1642
|
-
for (const toolCall of delta.tool_calls) {
|
|
1643
|
-
const idx = (_e = toolCall.index) != null ? _e : 0;
|
|
1644
|
-
while (toolCalls.length <= idx) {
|
|
1645
|
-
toolCalls.push({ name: "", argumentsJson: "" });
|
|
1646
|
-
}
|
|
1647
|
-
if (toolCall.id)
|
|
1648
|
-
toolCalls[idx].id = toolCall.id;
|
|
1649
|
-
if ((_f = toolCall.function) == null ? void 0 : _f.name)
|
|
1650
|
-
toolCalls[idx].name += toolCall.function.name;
|
|
1651
|
-
if ((_g = toolCall.function) == null ? void 0 : _g.arguments)
|
|
1652
|
-
toolCalls[idx].argumentsJson += toolCall.function.arguments;
|
|
1653
|
-
useful = true;
|
|
1613
|
+
if (Array.isArray(delta.tool_calls)) {
|
|
1614
|
+
for (const toolCall of delta.tool_calls) {
|
|
1615
|
+
const idx = (_e = toolCall.index) != null ? _e : 0;
|
|
1616
|
+
while (toolCalls.length <= idx) {
|
|
1617
|
+
toolCalls.push({ name: "", argumentsJson: "" });
|
|
1654
1618
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1619
|
+
if (toolCall.id) toolCalls[idx].id = toolCall.id;
|
|
1620
|
+
if ((_f = toolCall.function) == null ? void 0 : _f.name)
|
|
1621
|
+
toolCalls[idx].name += toolCall.function.name;
|
|
1622
|
+
if ((_g = toolCall.function) == null ? void 0 : _g.arguments)
|
|
1623
|
+
toolCalls[idx].argumentsJson += toolCall.function.arguments;
|
|
1658
1624
|
useful = true;
|
|
1659
1625
|
}
|
|
1660
1626
|
}
|
|
1661
|
-
if (
|
|
1662
|
-
|
|
1627
|
+
if (choice.finish_reason) {
|
|
1628
|
+
finishReason = choice.finish_reason;
|
|
1629
|
+
useful = true;
|
|
1630
|
+
}
|
|
1663
1631
|
}
|
|
1632
|
+
if (useful) armStallTimer();
|
|
1664
1633
|
}
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1634
|
+
}
|
|
1635
|
+
if (sawDone) reader.cancel().catch(() => {
|
|
1636
|
+
});
|
|
1668
1637
|
if (!sawDone && !finishReason) {
|
|
1669
1638
|
logger_default.error(
|
|
1670
1639
|
id,
|
|
@@ -1771,15 +1740,12 @@ var MODERATION_RE = /moderat|inappropriate content|content polic|content managem
|
|
|
1771
1740
|
function moderationEvictionSlug(error2, payload) {
|
|
1772
1741
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1773
1742
|
const body = (_c = error2 == null ? void 0 : error2.data) != null ? _c : (_b = (_a = error2 == null ? void 0 : error2.response) == null ? void 0 : _a.data) == null ? void 0 : _b.error;
|
|
1774
|
-
if (!body)
|
|
1775
|
-
return null;
|
|
1743
|
+
if (!body) return null;
|
|
1776
1744
|
const message = String((_d = body.message) != null ? _d : "");
|
|
1777
1745
|
const isModeration = body.code === 403 || Array.isArray((_e = body.metadata) == null ? void 0 : _e.reasons) || MODERATION_RE.test(message);
|
|
1778
|
-
if (!isModeration)
|
|
1779
|
-
return null;
|
|
1746
|
+
if (!isModeration) return null;
|
|
1780
1747
|
const display = (_h = (_f = body.metadata) == null ? void 0 : _f.provider_name) != null ? _h : (_g = /Upstream error from ([^:]+):/.exec(message)) == null ? void 0 : _g[1];
|
|
1781
|
-
if (!display)
|
|
1782
|
-
return null;
|
|
1748
|
+
if (!display) return null;
|
|
1783
1749
|
const key = normalizeProviderKey(display);
|
|
1784
1750
|
const fromOrder = (_j = (_i = payload.provider) == null ? void 0 : _i.order) == null ? void 0 : _j.find(
|
|
1785
1751
|
(entry) => normalizeProviderKey(entry) === key
|
|
@@ -1789,11 +1755,9 @@ function moderationEvictionSlug(error2, payload) {
|
|
|
1789
1755
|
var MIN_STREAM_ATTEMPT_MS = 1e4;
|
|
1790
1756
|
var estimateTokens = (text) => Math.round(text.length / 4);
|
|
1791
1757
|
function streamAttemptBudgetMs(options) {
|
|
1792
|
-
if (options.streamDeadlineAt === void 0)
|
|
1793
|
-
return options.streamTimeoutMs;
|
|
1758
|
+
if (options.streamDeadlineAt === void 0) return options.streamTimeoutMs;
|
|
1794
1759
|
const remaining = options.streamDeadlineAt - Date.now();
|
|
1795
|
-
if (remaining < MIN_STREAM_ATTEMPT_MS)
|
|
1796
|
-
return null;
|
|
1760
|
+
if (remaining < MIN_STREAM_ATTEMPT_MS) return null;
|
|
1797
1761
|
return Math.min(options.streamTimeoutMs, remaining);
|
|
1798
1762
|
}
|
|
1799
1763
|
async function callOpenRouterWithRetries(id, payload, retries = 5, options, signal) {
|
|
@@ -1949,8 +1913,7 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
|
|
|
1949
1913
|
(_e = result.provider) != null ? _e : result.provider = provider;
|
|
1950
1914
|
return result;
|
|
1951
1915
|
} catch (error2) {
|
|
1952
|
-
if ((_f = aiPayload.signal) == null ? void 0 : _f.aborted)
|
|
1953
|
-
throw error2;
|
|
1916
|
+
if ((_f = aiPayload.signal) == null ? void 0 : _f.aborted) throw error2;
|
|
1954
1917
|
if (aiPayload.fallbackModel) {
|
|
1955
1918
|
logger_default.error(
|
|
1956
1919
|
id,
|