190proof 1.0.104 → 1.0.105

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
@@ -289,6 +289,10 @@ interface ParsedResponseMessage {
289
289
  function_call: FunctionCall | null;
290
290
  function_calls: FunctionCall[];
291
291
  files: File[]; // For models that return files (e.g., image generation)
292
+ // Who actually served the response: OpenRouter's upstream provider from the
293
+ // response body (e.g. "Baidu"), or the SDK provider name ("anthropic", ...)
294
+ // for direct providers. On fallback, reflects the model that answered.
295
+ provider?: string;
292
296
  usage: {
293
297
  prompt_tokens: number;
294
298
  completion_tokens: number;
package/dist/index.d.mts CHANGED
@@ -175,6 +175,15 @@ interface ParsedResponseMessage {
175
175
  * validate. Undefined when the model/provider returns none.
176
176
  */
177
177
  reasoningDetails?: any;
178
+ /**
179
+ * Who actually served the response. For OpenRouter this is the upstream
180
+ * provider from the response body (e.g. "Baidu", "Morph") — the routing
181
+ * decision OpenRouter made, not the requested model slug. For direct
182
+ * providers it's the SDK provider name ("anthropic", "openai", "google",
183
+ * "groq"). On model fallback it reflects the model that answered, so a
184
+ * mismatch with the requested model's provider reveals the fallback.
185
+ */
186
+ provider?: string;
178
187
  usage: {
179
188
  prompt_tokens: number;
180
189
  completion_tokens: number;
package/dist/index.d.ts CHANGED
@@ -175,6 +175,15 @@ interface ParsedResponseMessage {
175
175
  * validate. Undefined when the model/provider returns none.
176
176
  */
177
177
  reasoningDetails?: any;
178
+ /**
179
+ * Who actually served the response. For OpenRouter this is the upstream
180
+ * provider from the response body (e.g. "Baidu", "Morph") — the routing
181
+ * decision OpenRouter made, not the requested model slug. For direct
182
+ * providers it's the SDK provider name ("anthropic", "openai", "google",
183
+ * "groq"). On model fallback it reflects the model that answered, so a
184
+ * mismatch with the requested model's provider reveals the fallback.
185
+ */
186
+ provider?: string;
178
187
  usage: {
179
188
  prompt_tokens: number;
180
189
  completion_tokens: number;
package/dist/index.js CHANGED
@@ -684,7 +684,11 @@ async function prepareAnthropicPayload(_identifier, payload) {
684
684
  model: payload.model,
685
685
  messages: [],
686
686
  functions: payload.functions,
687
- temperature: payload.temperature
687
+ temperature: payload.temperature,
688
+ // Map the generic function_call to Anthropic tool_choice ("none" forces a
689
+ // text-only turn). Only meaningful alongside tools — callAnthropic sends
690
+ // it only when tools are present (tool_choice without tools 400s).
691
+ tool_choice: payload.function_call ? typeof payload.function_call === "string" ? { type: payload.function_call } : { type: "tool", name: payload.function_call.name } : void 0
688
692
  };
689
693
  for (const message of payload.messages) {
690
694
  if (message.role === "system") {
@@ -798,6 +802,8 @@ async function callAnthropic(id, payload, config, requestTimeoutMs = 12e4, signa
798
802
  model: payload.model,
799
803
  messages: anthropicMessages,
800
804
  tools: cachedTools,
805
+ // tool_choice requires tools in the request; drop it otherwise.
806
+ tool_choice: (cachedTools == null ? void 0 : cachedTools.length) ? payload.tool_choice : void 0,
801
807
  temperature: payload.temperature,
802
808
  system: payload.system,
803
809
  max_tokens: 4096
@@ -929,6 +935,13 @@ async function prepareGoogleAIPayload(_identifier, payload) {
929
935
  ...fn.parameters
930
936
  }
931
937
  }))
938
+ } : void 0,
939
+ // Map the generic function_call to Gemini's functionCallingConfig ("none"
940
+ // → mode NONE forces a text-only turn). Only meaningful alongside tools.
941
+ toolConfig: payload.functions && payload.function_call ? {
942
+ functionCallingConfig: {
943
+ mode: typeof payload.function_call === "string" ? payload.function_call === "none" ? "NONE" : "AUTO" : "ANY"
944
+ }
932
945
  } : void 0
933
946
  };
934
947
  const toolNameById = /* @__PURE__ */ new Map();
@@ -1014,6 +1027,9 @@ async function callGoogleAI(id, payload, requestTimeoutMs = 12e4, signal) {
1014
1027
  };
1015
1028
  if (payload.tools)
1016
1029
  requestBody.tools = [payload.tools];
1030
+ if (payload.tools && payload.toolConfig) {
1031
+ requestBody.toolConfig = payload.toolConfig;
1032
+ }
1017
1033
  if (payload.systemInstruction) {
1018
1034
  requestBody.systemInstruction = {
1019
1035
  parts: [{ text: payload.systemInstruction }]
@@ -1390,7 +1406,7 @@ function parseDsmlToolCalls(content) {
1390
1406
  return { calls, remainingContent: remaining.length ? remaining : null };
1391
1407
  }
1392
1408
  async function callOpenRouter(id, payload, requestTimeoutMs = 12e4, signal) {
1393
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1409
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1394
1410
  const response = await import_axios.default.post(
1395
1411
  "https://openrouter.ai/api/v1/chat/completions",
1396
1412
  payload,
@@ -1450,11 +1466,14 @@ async function callOpenRouter(id, payload, requestTimeoutMs = 12e4, signal) {
1450
1466
  files: [],
1451
1467
  reasoning: (_f = answer.reasoning) != null ? _f : void 0,
1452
1468
  reasoningDetails: (_g = answer.reasoning_details) != null ? _g : void 0,
1469
+ // The upstream provider OpenRouter routed to (e.g. "Baidu") — finer-grained
1470
+ // than the "openrouter" stamp callWithRetries would apply.
1471
+ provider: (_h = response.data.provider) != null ? _h : void 0,
1453
1472
  usage: response.data.usage ? {
1454
1473
  prompt_tokens: response.data.usage.prompt_tokens,
1455
1474
  completion_tokens: response.data.usage.completion_tokens,
1456
1475
  total_tokens: response.data.usage.total_tokens,
1457
- cached_tokens: (_i = (_h = response.data.usage.prompt_tokens_details) == null ? void 0 : _h.cached_tokens) != null ? _i : 0
1476
+ cached_tokens: (_j = (_i = response.data.usage.prompt_tokens_details) == null ? void 0 : _i.cached_tokens) != null ? _j : 0
1458
1477
  } : null
1459
1478
  };
1460
1479
  }
@@ -1504,15 +1523,16 @@ function parseModelString(model) {
1504
1523
  );
1505
1524
  }
1506
1525
  async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeoutMs = 15e3) {
1507
- var _a, _b;
1526
+ var _a, _b, _c;
1508
1527
  try {
1509
1528
  const { provider, modelId } = parseModelString(aiPayload.model);
1510
1529
  const routingPayload = { ...aiPayload, model: modelId };
1511
1530
  const requestTimeoutMs = (_a = aiPayload.requestTimeoutMs) != null ? _a : 12e4;
1512
1531
  const signal = aiPayload.signal;
1532
+ let result;
1513
1533
  switch (provider) {
1514
1534
  case "anthropic":
1515
- return await callAnthropicWithRetries(
1535
+ result = await callAnthropicWithRetries(
1516
1536
  id,
1517
1537
  await prepareAnthropicPayload(id, routingPayload),
1518
1538
  aiConfig,
@@ -1520,8 +1540,9 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
1520
1540
  requestTimeoutMs,
1521
1541
  signal
1522
1542
  );
1543
+ break;
1523
1544
  case "openai":
1524
- return await callOpenAiWithRetries(
1545
+ result = await callOpenAiWithRetries(
1525
1546
  id,
1526
1547
  await prepareOpenAIPayload(id, routingPayload),
1527
1548
  aiConfig,
@@ -1530,33 +1551,39 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
1530
1551
  requestTimeoutMs,
1531
1552
  signal
1532
1553
  );
1554
+ break;
1533
1555
  case "groq":
1534
- return await callGroqWithRetries(
1556
+ result = await callGroqWithRetries(
1535
1557
  id,
1536
1558
  prepareGroqPayload(routingPayload),
1537
1559
  retries,
1538
1560
  requestTimeoutMs,
1539
1561
  signal
1540
1562
  );
1563
+ break;
1541
1564
  case "google":
1542
- return await callGoogleAIWithRetries(
1565
+ result = await callGoogleAIWithRetries(
1543
1566
  id,
1544
1567
  await prepareGoogleAIPayload(id, routingPayload),
1545
1568
  retries,
1546
1569
  requestTimeoutMs,
1547
1570
  signal
1548
1571
  );
1572
+ break;
1549
1573
  case "openrouter":
1550
- return await callOpenRouterWithRetries(
1574
+ result = await callOpenRouterWithRetries(
1551
1575
  id,
1552
1576
  prepareOpenRouterPayload(routingPayload),
1553
1577
  retries,
1554
1578
  requestTimeoutMs,
1555
1579
  signal
1556
1580
  );
1581
+ break;
1557
1582
  }
1583
+ (_b = result.provider) != null ? _b : result.provider = provider;
1584
+ return result;
1558
1585
  } catch (error2) {
1559
- if ((_b = aiPayload.signal) == null ? void 0 : _b.aborted)
1586
+ if ((_c = aiPayload.signal) == null ? void 0 : _c.aborted)
1560
1587
  throw error2;
1561
1588
  if (aiPayload.fallbackModel) {
1562
1589
  logger_default.error(