190proof 1.0.112 → 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 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 proof_exports = {};
32
- __export(proof_exports, {
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(proof_exports);
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: { responseModalities: ["TEXT"] }
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
- errorDetails.safetyRatings = error2.safetyRatings;
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
- errorDetails.httpStatus = error2.status;
1194
- if (error2.code)
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}`,
@@ -1261,9 +1246,13 @@ function prepareOpenAICompatMessages(messages) {
1261
1246
  }
1262
1247
  continue;
1263
1248
  }
1249
+ const fileRefs = (message.files || []).filter((file) => file.url).map(
1250
+ (file) => ALLOWED_IMAGE_MIME_TYPES.includes(file.mimeType) ? `Image (${file.url})` : `File (${file.url})`
1251
+ );
1252
+ const content = [normalizeMessageContent(message.content), ...fileRefs].filter(Boolean).join("\n");
1264
1253
  const outMessage = {
1265
1254
  role: message.role,
1266
- content: normalizeMessageContent(message.content)
1255
+ content
1267
1256
  };
1268
1257
  if ((_a = message.functionCalls) == null ? void 0 : _a.length) {
1269
1258
  outMessage.tool_calls = message.functionCalls.map((fc, i) => {
@@ -1277,16 +1266,13 @@ function prepareOpenAICompatMessages(messages) {
1277
1266
  }
1278
1267
  };
1279
1268
  });
1280
- if (!message.content)
1281
- outMessage.content = null;
1269
+ if (!content) outMessage.content = null;
1282
1270
  }
1283
- if (message.reasoning)
1284
- outMessage.reasoning = message.reasoning;
1271
+ if (message.reasoning) outMessage.reasoning = message.reasoning;
1285
1272
  const reasoningDetails = filterOpenAICompatReasoningDetails(
1286
1273
  message.reasoningDetails
1287
1274
  );
1288
- if (reasoningDetails)
1289
- outMessage.reasoning_details = reasoningDetails;
1275
+ if (reasoningDetails) outMessage.reasoning_details = reasoningDetails;
1290
1276
  out.push(outMessage);
1291
1277
  }
1292
1278
  return out;
@@ -1429,8 +1415,7 @@ function parseDsmlToolCalls(content) {
1429
1415
  let last = -1;
1430
1416
  let tag;
1431
1417
  while ((tag = DSML_ANY_TAG_RE.exec(content)) !== null) {
1432
- if (first === -1)
1433
- first = tag.index;
1418
+ if (first === -1) first = tag.index;
1434
1419
  last = tag.index + tag[0].length;
1435
1420
  }
1436
1421
  const remaining = first === -1 ? content : (content.slice(0, first) + content.slice(last)).trim();
@@ -1446,8 +1431,7 @@ function finalizeOpenRouterMessage(id, raw) {
1446
1431
  const functionCalls = [];
1447
1432
  for (let i = 0; i < raw.toolCalls.length; i++) {
1448
1433
  const tc = raw.toolCalls[i];
1449
- if (!tc.name)
1450
- continue;
1434
+ if (!tc.name) continue;
1451
1435
  functionCalls.push({
1452
1436
  id: (_a = tc.id) != null ? _a : `call_${i}`,
1453
1437
  name: tc.name,
@@ -1500,8 +1484,7 @@ async function callOpenRouterStream(id, payload, streamTimeoutMs = OPENROUTER_ST
1500
1484
  controller.abort();
1501
1485
  };
1502
1486
  const unref = (t) => {
1503
- if (typeof t === "object" && "unref" in t)
1504
- t.unref();
1487
+ if (typeof t === "object" && "unref" in t) t.unref();
1505
1488
  return t;
1506
1489
  };
1507
1490
  const totalTimer = unref(
@@ -1569,98 +1552,88 @@ async function callOpenRouterStream(id, payload, streamTimeoutMs = OPENROUTER_ST
1569
1552
  const reader = response.body.getReader();
1570
1553
  const decoder = new TextDecoder();
1571
1554
  let lineBuffer = "";
1572
- outer:
1573
- while (true) {
1574
- const { done, value } = await reader.read();
1575
- if (done)
1576
- break;
1577
- lineBuffer += decoder.decode(value, { stream: true });
1578
- let newlineIdx;
1579
- while ((newlineIdx = lineBuffer.indexOf("\n")) !== -1) {
1580
- let line = lineBuffer.slice(0, newlineIdx);
1581
- lineBuffer = lineBuffer.slice(newlineIdx + 1);
1582
- if (line.endsWith("\r"))
1583
- line = line.slice(0, -1);
1584
- if (!line)
1585
- continue;
1586
- if (line.startsWith(":"))
1587
- continue;
1588
- if (!line.startsWith("data:"))
1589
- continue;
1590
- const dataStr = line.slice(5).trimStart();
1591
- if (dataStr === "[DONE]") {
1592
- sawDone = true;
1593
- break outer;
1594
- }
1595
- let json;
1596
- try {
1597
- json = JSON.parse(dataStr);
1598
- } catch (e) {
1599
- logger_default.error(
1600
- id,
1601
- "OpenRouter stream: unparseable data line:",
1602
- dataStr.slice(0, 200)
1603
- );
1604
- continue;
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;
1605
1604
  }
1606
- dataChunks++;
1607
- if (json.error) {
1608
- logger_default.error(id, "OpenRouter stream error event:", json.error);
1609
- const error2 = new Error(
1610
- `OpenRouter error: ${json.error.message}`
1611
- );
1612
- error2.data = json.error;
1613
- throw error2;
1605
+ if (delta.reasoning) {
1606
+ reasoning += delta.reasoning;
1607
+ useful = true;
1614
1608
  }
1615
- if (json.provider)
1616
- provider = json.provider;
1617
- let useful = false;
1618
- if (json.usage) {
1619
- usage = json.usage;
1609
+ if (Array.isArray(delta.reasoning_details) && delta.reasoning_details.length) {
1610
+ reasoningDetails.push(...delta.reasoning_details);
1620
1611
  useful = true;
1621
1612
  }
1622
- const choice = (_c = json.choices) == null ? void 0 : _c[0];
1623
- if (choice) {
1624
- const delta = (_d = choice.delta) != null ? _d : {};
1625
- if (delta.content) {
1626
- paragraph += delta.content;
1627
- useful = true;
1628
- }
1629
- if (delta.reasoning) {
1630
- reasoning += delta.reasoning;
1631
- useful = true;
1632
- }
1633
- if (Array.isArray(delta.reasoning_details) && delta.reasoning_details.length) {
1634
- reasoningDetails.push(...delta.reasoning_details);
1635
- useful = true;
1636
- }
1637
- if (Array.isArray(delta.tool_calls)) {
1638
- for (const toolCall of delta.tool_calls) {
1639
- const idx = (_e = toolCall.index) != null ? _e : 0;
1640
- while (toolCalls.length <= idx) {
1641
- toolCalls.push({ name: "", argumentsJson: "" });
1642
- }
1643
- if (toolCall.id)
1644
- toolCalls[idx].id = toolCall.id;
1645
- if ((_f = toolCall.function) == null ? void 0 : _f.name)
1646
- toolCalls[idx].name += toolCall.function.name;
1647
- if ((_g = toolCall.function) == null ? void 0 : _g.arguments)
1648
- toolCalls[idx].argumentsJson += toolCall.function.arguments;
1649
- 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: "" });
1650
1618
  }
1651
- }
1652
- if (choice.finish_reason) {
1653
- finishReason = choice.finish_reason;
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;
1654
1624
  useful = true;
1655
1625
  }
1656
1626
  }
1657
- if (useful)
1658
- armStallTimer();
1627
+ if (choice.finish_reason) {
1628
+ finishReason = choice.finish_reason;
1629
+ useful = true;
1630
+ }
1659
1631
  }
1632
+ if (useful) armStallTimer();
1660
1633
  }
1661
- if (sawDone)
1662
- reader.cancel().catch(() => {
1663
- });
1634
+ }
1635
+ if (sawDone) reader.cancel().catch(() => {
1636
+ });
1664
1637
  if (!sawDone && !finishReason) {
1665
1638
  logger_default.error(
1666
1639
  id,
@@ -1767,15 +1740,12 @@ var MODERATION_RE = /moderat|inappropriate content|content polic|content managem
1767
1740
  function moderationEvictionSlug(error2, payload) {
1768
1741
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1769
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;
1770
- if (!body)
1771
- return null;
1743
+ if (!body) return null;
1772
1744
  const message = String((_d = body.message) != null ? _d : "");
1773
1745
  const isModeration = body.code === 403 || Array.isArray((_e = body.metadata) == null ? void 0 : _e.reasons) || MODERATION_RE.test(message);
1774
- if (!isModeration)
1775
- return null;
1746
+ if (!isModeration) return null;
1776
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];
1777
- if (!display)
1778
- return null;
1748
+ if (!display) return null;
1779
1749
  const key = normalizeProviderKey(display);
1780
1750
  const fromOrder = (_j = (_i = payload.provider) == null ? void 0 : _i.order) == null ? void 0 : _j.find(
1781
1751
  (entry) => normalizeProviderKey(entry) === key
@@ -1785,11 +1755,9 @@ function moderationEvictionSlug(error2, payload) {
1785
1755
  var MIN_STREAM_ATTEMPT_MS = 1e4;
1786
1756
  var estimateTokens = (text) => Math.round(text.length / 4);
1787
1757
  function streamAttemptBudgetMs(options) {
1788
- if (options.streamDeadlineAt === void 0)
1789
- return options.streamTimeoutMs;
1758
+ if (options.streamDeadlineAt === void 0) return options.streamTimeoutMs;
1790
1759
  const remaining = options.streamDeadlineAt - Date.now();
1791
- if (remaining < MIN_STREAM_ATTEMPT_MS)
1792
- return null;
1760
+ if (remaining < MIN_STREAM_ATTEMPT_MS) return null;
1793
1761
  return Math.min(options.streamTimeoutMs, remaining);
1794
1762
  }
1795
1763
  async function callOpenRouterWithRetries(id, payload, retries = 5, options, signal) {
@@ -1945,8 +1913,7 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
1945
1913
  (_e = result.provider) != null ? _e : result.provider = provider;
1946
1914
  return result;
1947
1915
  } catch (error2) {
1948
- if ((_f = aiPayload.signal) == null ? void 0 : _f.aborted)
1949
- throw error2;
1916
+ if ((_f = aiPayload.signal) == null ? void 0 : _f.aborted) throw error2;
1950
1917
  if (aiPayload.fallbackModel) {
1951
1918
  logger_default.error(
1952
1919
  id,