190proof 1.0.102 → 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 +4 -0
- package/dist/index.d.mts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +58 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
@@ -123,6 +123,11 @@ interface GenericMessage {
|
|
|
123
123
|
* `redacted_thinking` blocks captured in
|
|
124
124
|
* `ParsedResponseMessage.reasoningDetails`). Preserves the signatures /
|
|
125
125
|
* encrypted payloads that providers validate on round-trip.
|
|
126
|
+
*
|
|
127
|
+
* Safe to echo regardless of which provider serves the next call: each
|
|
128
|
+
* serializer keeps only its own provider's block shapes (Anthropic keeps
|
|
129
|
+
* `thinking`/`redacted_thinking`; OpenAI-compat keeps `reasoning.*`), so a
|
|
130
|
+
* cross-provider fallback drops foreign blocks instead of 400ing.
|
|
126
131
|
*/
|
|
127
132
|
reasoningDetails?: any;
|
|
128
133
|
}
|
|
@@ -170,6 +175,15 @@ interface ParsedResponseMessage {
|
|
|
170
175
|
* validate. Undefined when the model/provider returns none.
|
|
171
176
|
*/
|
|
172
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;
|
|
173
187
|
usage: {
|
|
174
188
|
prompt_tokens: number;
|
|
175
189
|
completion_tokens: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -123,6 +123,11 @@ interface GenericMessage {
|
|
|
123
123
|
* `redacted_thinking` blocks captured in
|
|
124
124
|
* `ParsedResponseMessage.reasoningDetails`). Preserves the signatures /
|
|
125
125
|
* encrypted payloads that providers validate on round-trip.
|
|
126
|
+
*
|
|
127
|
+
* Safe to echo regardless of which provider serves the next call: each
|
|
128
|
+
* serializer keeps only its own provider's block shapes (Anthropic keeps
|
|
129
|
+
* `thinking`/`redacted_thinking`; OpenAI-compat keeps `reasoning.*`), so a
|
|
130
|
+
* cross-provider fallback drops foreign blocks instead of 400ing.
|
|
126
131
|
*/
|
|
127
132
|
reasoningDetails?: any;
|
|
128
133
|
}
|
|
@@ -170,6 +175,15 @@ interface ParsedResponseMessage {
|
|
|
170
175
|
* validate. Undefined when the model/provider returns none.
|
|
171
176
|
*/
|
|
172
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;
|
|
173
187
|
usage: {
|
|
174
188
|
prompt_tokens: number;
|
|
175
189
|
completion_tokens: number;
|
package/dist/index.js
CHANGED
|
@@ -320,6 +320,14 @@ function buildOpenAIRequestConfig(identifier, model, config) {
|
|
|
320
320
|
}
|
|
321
321
|
};
|
|
322
322
|
}
|
|
323
|
+
function filterOpenAICompatReasoningDetails(details) {
|
|
324
|
+
if (!Array.isArray(details))
|
|
325
|
+
return details || void 0;
|
|
326
|
+
const blocks = details.filter(
|
|
327
|
+
(block) => typeof (block == null ? void 0 : block.type) === "string" && block.type.startsWith("reasoning.")
|
|
328
|
+
);
|
|
329
|
+
return blocks.length ? blocks : void 0;
|
|
330
|
+
}
|
|
323
331
|
async function prepareOpenAIPayload(identifier, payload) {
|
|
324
332
|
var _a, _b;
|
|
325
333
|
const preparedPayload = {
|
|
@@ -387,8 +395,11 @@ async function prepareOpenAIPayload(identifier, payload) {
|
|
|
387
395
|
}
|
|
388
396
|
if (message.reasoning)
|
|
389
397
|
outMessage.reasoning = message.reasoning;
|
|
390
|
-
|
|
391
|
-
|
|
398
|
+
const reasoningDetails = filterOpenAICompatReasoningDetails(
|
|
399
|
+
message.reasoningDetails
|
|
400
|
+
);
|
|
401
|
+
if (reasoningDetails)
|
|
402
|
+
outMessage.reasoning_details = reasoningDetails;
|
|
392
403
|
preparedPayload.messages.push(outMessage);
|
|
393
404
|
}
|
|
394
405
|
return preparedPayload;
|
|
@@ -673,7 +684,11 @@ async function prepareAnthropicPayload(_identifier, payload) {
|
|
|
673
684
|
model: payload.model,
|
|
674
685
|
messages: [],
|
|
675
686
|
functions: payload.functions,
|
|
676
|
-
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
|
|
677
692
|
};
|
|
678
693
|
for (const message of payload.messages) {
|
|
679
694
|
if (message.role === "system") {
|
|
@@ -728,7 +743,9 @@ async function prepareAnthropicPayload(_identifier, payload) {
|
|
|
728
743
|
});
|
|
729
744
|
}
|
|
730
745
|
}
|
|
731
|
-
const leadingBlocks = message.role === "assistant" && Array.isArray(message.reasoningDetails) ? message.reasoningDetails
|
|
746
|
+
const leadingBlocks = message.role === "assistant" && Array.isArray(message.reasoningDetails) ? message.reasoningDetails.filter(
|
|
747
|
+
(block) => (block == null ? void 0 : block.type) === "thinking" || (block == null ? void 0 : block.type) === "redacted_thinking"
|
|
748
|
+
) : [];
|
|
732
749
|
const toolUseBlocks = (message.functionCalls || []).map((fc, i) => {
|
|
733
750
|
var _a;
|
|
734
751
|
return {
|
|
@@ -785,6 +802,8 @@ async function callAnthropic(id, payload, config, requestTimeoutMs = 12e4, signa
|
|
|
785
802
|
model: payload.model,
|
|
786
803
|
messages: anthropicMessages,
|
|
787
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,
|
|
788
807
|
temperature: payload.temperature,
|
|
789
808
|
system: payload.system,
|
|
790
809
|
max_tokens: 4096
|
|
@@ -916,6 +935,13 @@ async function prepareGoogleAIPayload(_identifier, payload) {
|
|
|
916
935
|
...fn.parameters
|
|
917
936
|
}
|
|
918
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
|
+
}
|
|
919
945
|
} : void 0
|
|
920
946
|
};
|
|
921
947
|
const toolNameById = /* @__PURE__ */ new Map();
|
|
@@ -1001,6 +1027,9 @@ async function callGoogleAI(id, payload, requestTimeoutMs = 12e4, signal) {
|
|
|
1001
1027
|
};
|
|
1002
1028
|
if (payload.tools)
|
|
1003
1029
|
requestBody.tools = [payload.tools];
|
|
1030
|
+
if (payload.tools && payload.toolConfig) {
|
|
1031
|
+
requestBody.toolConfig = payload.toolConfig;
|
|
1032
|
+
}
|
|
1004
1033
|
if (payload.systemInstruction) {
|
|
1005
1034
|
requestBody.systemInstruction = {
|
|
1006
1035
|
parts: [{ text: payload.systemInstruction }]
|
|
@@ -1227,8 +1256,11 @@ function prepareOpenAICompatMessages(messages) {
|
|
|
1227
1256
|
}
|
|
1228
1257
|
if (message.reasoning)
|
|
1229
1258
|
outMessage.reasoning = message.reasoning;
|
|
1230
|
-
|
|
1231
|
-
|
|
1259
|
+
const reasoningDetails = filterOpenAICompatReasoningDetails(
|
|
1260
|
+
message.reasoningDetails
|
|
1261
|
+
);
|
|
1262
|
+
if (reasoningDetails)
|
|
1263
|
+
outMessage.reasoning_details = reasoningDetails;
|
|
1232
1264
|
out.push(outMessage);
|
|
1233
1265
|
}
|
|
1234
1266
|
return out;
|
|
@@ -1374,7 +1406,7 @@ function parseDsmlToolCalls(content) {
|
|
|
1374
1406
|
return { calls, remainingContent: remaining.length ? remaining : null };
|
|
1375
1407
|
}
|
|
1376
1408
|
async function callOpenRouter(id, payload, requestTimeoutMs = 12e4, signal) {
|
|
1377
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1409
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1378
1410
|
const response = await import_axios.default.post(
|
|
1379
1411
|
"https://openrouter.ai/api/v1/chat/completions",
|
|
1380
1412
|
payload,
|
|
@@ -1434,11 +1466,14 @@ async function callOpenRouter(id, payload, requestTimeoutMs = 12e4, signal) {
|
|
|
1434
1466
|
files: [],
|
|
1435
1467
|
reasoning: (_f = answer.reasoning) != null ? _f : void 0,
|
|
1436
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,
|
|
1437
1472
|
usage: response.data.usage ? {
|
|
1438
1473
|
prompt_tokens: response.data.usage.prompt_tokens,
|
|
1439
1474
|
completion_tokens: response.data.usage.completion_tokens,
|
|
1440
1475
|
total_tokens: response.data.usage.total_tokens,
|
|
1441
|
-
cached_tokens: (
|
|
1476
|
+
cached_tokens: (_j = (_i = response.data.usage.prompt_tokens_details) == null ? void 0 : _i.cached_tokens) != null ? _j : 0
|
|
1442
1477
|
} : null
|
|
1443
1478
|
};
|
|
1444
1479
|
}
|
|
@@ -1488,15 +1523,16 @@ function parseModelString(model) {
|
|
|
1488
1523
|
);
|
|
1489
1524
|
}
|
|
1490
1525
|
async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeoutMs = 15e3) {
|
|
1491
|
-
var _a, _b;
|
|
1526
|
+
var _a, _b, _c;
|
|
1492
1527
|
try {
|
|
1493
1528
|
const { provider, modelId } = parseModelString(aiPayload.model);
|
|
1494
1529
|
const routingPayload = { ...aiPayload, model: modelId };
|
|
1495
1530
|
const requestTimeoutMs = (_a = aiPayload.requestTimeoutMs) != null ? _a : 12e4;
|
|
1496
1531
|
const signal = aiPayload.signal;
|
|
1532
|
+
let result;
|
|
1497
1533
|
switch (provider) {
|
|
1498
1534
|
case "anthropic":
|
|
1499
|
-
|
|
1535
|
+
result = await callAnthropicWithRetries(
|
|
1500
1536
|
id,
|
|
1501
1537
|
await prepareAnthropicPayload(id, routingPayload),
|
|
1502
1538
|
aiConfig,
|
|
@@ -1504,8 +1540,9 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
|
|
|
1504
1540
|
requestTimeoutMs,
|
|
1505
1541
|
signal
|
|
1506
1542
|
);
|
|
1543
|
+
break;
|
|
1507
1544
|
case "openai":
|
|
1508
|
-
|
|
1545
|
+
result = await callOpenAiWithRetries(
|
|
1509
1546
|
id,
|
|
1510
1547
|
await prepareOpenAIPayload(id, routingPayload),
|
|
1511
1548
|
aiConfig,
|
|
@@ -1514,33 +1551,39 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
|
|
|
1514
1551
|
requestTimeoutMs,
|
|
1515
1552
|
signal
|
|
1516
1553
|
);
|
|
1554
|
+
break;
|
|
1517
1555
|
case "groq":
|
|
1518
|
-
|
|
1556
|
+
result = await callGroqWithRetries(
|
|
1519
1557
|
id,
|
|
1520
1558
|
prepareGroqPayload(routingPayload),
|
|
1521
1559
|
retries,
|
|
1522
1560
|
requestTimeoutMs,
|
|
1523
1561
|
signal
|
|
1524
1562
|
);
|
|
1563
|
+
break;
|
|
1525
1564
|
case "google":
|
|
1526
|
-
|
|
1565
|
+
result = await callGoogleAIWithRetries(
|
|
1527
1566
|
id,
|
|
1528
1567
|
await prepareGoogleAIPayload(id, routingPayload),
|
|
1529
1568
|
retries,
|
|
1530
1569
|
requestTimeoutMs,
|
|
1531
1570
|
signal
|
|
1532
1571
|
);
|
|
1572
|
+
break;
|
|
1533
1573
|
case "openrouter":
|
|
1534
|
-
|
|
1574
|
+
result = await callOpenRouterWithRetries(
|
|
1535
1575
|
id,
|
|
1536
1576
|
prepareOpenRouterPayload(routingPayload),
|
|
1537
1577
|
retries,
|
|
1538
1578
|
requestTimeoutMs,
|
|
1539
1579
|
signal
|
|
1540
1580
|
);
|
|
1581
|
+
break;
|
|
1541
1582
|
}
|
|
1583
|
+
(_b = result.provider) != null ? _b : result.provider = provider;
|
|
1584
|
+
return result;
|
|
1542
1585
|
} catch (error2) {
|
|
1543
|
-
if ((
|
|
1586
|
+
if ((_c = aiPayload.signal) == null ? void 0 : _c.aborted)
|
|
1544
1587
|
throw error2;
|
|
1545
1588
|
if (aiPayload.fallbackModel) {
|
|
1546
1589
|
logger_default.error(
|