@jambonz/llm 0.6.9 → 0.6.11
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/index.cjs +163 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +163 -19
- package/dist/index.js.map +1 -1
- package/dist/test-kit/index.cjs +163 -19
- package/dist/test-kit/index.cjs.map +1 -1
- package/dist/test-kit/index.d.cts +1 -1
- package/dist/test-kit/index.d.ts +1 -1
- package/dist/test-kit/index.js +163 -19
- package/dist/test-kit/index.js.map +1 -1
- package/dist/{types-C_yrWq_0.d.cts → types-C3Cdt-km.d.cts} +20 -6
- package/dist/{types-C_yrWq_0.d.ts → types-C3Cdt-km.d.ts} +20 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1315,6 +1315,21 @@ var ANTHROPIC_KNOWN_MODELS = [
|
|
|
1315
1315
|
maxContextTokens: 2e5
|
|
1316
1316
|
}
|
|
1317
1317
|
},
|
|
1318
|
+
{
|
|
1319
|
+
// Thinks by default (effort `medium`), and the thinking counts toward
|
|
1320
|
+
// max_tokens. For voice, send `providerParams: {output_config: {effort:
|
|
1321
|
+
// 'low'}}`. Rejects non-default sampling parameters, so the adapter
|
|
1322
|
+
// leaves `temperature` out of its requests.
|
|
1323
|
+
id: "claude-haiku-5-5",
|
|
1324
|
+
displayName: "Claude Haiku 5.5",
|
|
1325
|
+
capabilities: {
|
|
1326
|
+
streaming: true,
|
|
1327
|
+
tools: true,
|
|
1328
|
+
vision: true,
|
|
1329
|
+
systemPrompt: true,
|
|
1330
|
+
maxContextTokens: 1e6
|
|
1331
|
+
}
|
|
1332
|
+
},
|
|
1318
1333
|
{
|
|
1319
1334
|
id: "claude-haiku-4-5-20251001",
|
|
1320
1335
|
displayName: "Claude Haiku 4.5",
|
|
@@ -1398,6 +1413,7 @@ var ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
|
1398
1413
|
{ header: "anthropic-ratelimit-input-tokens-remaining", key: "input_tokens_remaining", numeric: true },
|
|
1399
1414
|
{ header: "anthropic-ratelimit-output-tokens-remaining", key: "output_tokens_remaining", numeric: true }
|
|
1400
1415
|
]);
|
|
1416
|
+
var REJECTS_SAMPLING_PARAMS = /^claude-(opus-4-[7-9]|opus-5|sonnet-5|haiku-5|fable|mythos)/;
|
|
1401
1417
|
var AnthropicAdapter = class {
|
|
1402
1418
|
vendor = anthropicManifest.vendor;
|
|
1403
1419
|
acceptedAuth = ["apiKey"];
|
|
@@ -1430,7 +1446,14 @@ var AnthropicAdapter = class {
|
|
|
1430
1446
|
};
|
|
1431
1447
|
if (req.system) body.system = req.system;
|
|
1432
1448
|
if (tools) body.tools = tools;
|
|
1433
|
-
if (req.temperature !== void 0
|
|
1449
|
+
if (req.temperature !== void 0 && !REJECTS_SAMPLING_PARAMS.test(req.model)) {
|
|
1450
|
+
body.temperature = req.temperature;
|
|
1451
|
+
}
|
|
1452
|
+
if (req.providerParams) {
|
|
1453
|
+
for (const [key, value] of Object.entries(req.providerParams)) {
|
|
1454
|
+
if (!(key in body)) body[key] = value;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1434
1457
|
if (req.cacheKey) {
|
|
1435
1458
|
if (req.system) {
|
|
1436
1459
|
body.system = [{ type: "text", text: req.system, cache_control: { type: "ephemeral" } }];
|
|
@@ -1441,21 +1464,31 @@ var AnthropicAdapter = class {
|
|
|
1441
1464
|
}
|
|
1442
1465
|
markLastMessageForCaching(messages);
|
|
1443
1466
|
}
|
|
1444
|
-
|
|
1445
|
-
let responseHeaders;
|
|
1446
|
-
try {
|
|
1467
|
+
const open = async (b) => {
|
|
1447
1468
|
const apiPromise = client.messages.create(
|
|
1448
|
-
|
|
1469
|
+
b,
|
|
1449
1470
|
{ signal: req.signal }
|
|
1450
1471
|
);
|
|
1451
1472
|
const maybeWithResponse = apiPromise.withResponse;
|
|
1452
1473
|
if (typeof maybeWithResponse === "function") {
|
|
1453
1474
|
const result = await maybeWithResponse.call(apiPromise);
|
|
1454
|
-
stream
|
|
1455
|
-
responseHeaders = result.response?.headers;
|
|
1456
|
-
} else {
|
|
1457
|
-
stream = await apiPromise;
|
|
1475
|
+
return { stream: result.data, headers: result.response?.headers };
|
|
1458
1476
|
}
|
|
1477
|
+
return { stream: await apiPromise, headers: void 0 };
|
|
1478
|
+
};
|
|
1479
|
+
let stream;
|
|
1480
|
+
let responseHeaders;
|
|
1481
|
+
try {
|
|
1482
|
+
let opened;
|
|
1483
|
+
try {
|
|
1484
|
+
opened = await open(body);
|
|
1485
|
+
} catch (err) {
|
|
1486
|
+
const stripped = isThinkingBlockRejection(err) ? withoutThinking(messages) : void 0;
|
|
1487
|
+
if (!stripped) throw err;
|
|
1488
|
+
opened = await open({ ...body, messages: stripped });
|
|
1489
|
+
}
|
|
1490
|
+
stream = opened.stream;
|
|
1491
|
+
responseHeaders = opened.headers;
|
|
1459
1492
|
} catch (err) {
|
|
1460
1493
|
if (isAbortError2(err)) {
|
|
1461
1494
|
yield { type: "end", finishReason: "aborted" };
|
|
@@ -1464,7 +1497,10 @@ var AnthropicAdapter = class {
|
|
|
1464
1497
|
throw err;
|
|
1465
1498
|
}
|
|
1466
1499
|
let currentToolUse = null;
|
|
1500
|
+
let currentThinking = null;
|
|
1501
|
+
let currentText = null;
|
|
1467
1502
|
const completedToolCalls = [];
|
|
1503
|
+
const turnContent = [];
|
|
1468
1504
|
let stopReason;
|
|
1469
1505
|
let inputTokens;
|
|
1470
1506
|
let outputTokens;
|
|
@@ -1497,19 +1533,42 @@ var AnthropicAdapter = class {
|
|
|
1497
1533
|
name: currentToolUse.name
|
|
1498
1534
|
};
|
|
1499
1535
|
}
|
|
1536
|
+
} else if (block?.type === "text") {
|
|
1537
|
+
currentText = block.text ?? "";
|
|
1538
|
+
} else if (block?.type === "thinking") {
|
|
1539
|
+
currentThinking = {
|
|
1540
|
+
type: "thinking",
|
|
1541
|
+
thinking: block.thinking ?? "",
|
|
1542
|
+
signature: block.signature ?? ""
|
|
1543
|
+
};
|
|
1544
|
+
} else if (block?.type === "redacted_thinking" && block.data) {
|
|
1545
|
+
turnContent.push({ type: "redacted_thinking", data: block.data });
|
|
1500
1546
|
}
|
|
1501
1547
|
break;
|
|
1502
1548
|
}
|
|
1503
1549
|
case "content_block_delta": {
|
|
1504
1550
|
const delta = event.delta;
|
|
1505
1551
|
if (delta?.type === "text_delta" && delta.text) {
|
|
1552
|
+
if (currentText !== null) currentText += delta.text;
|
|
1506
1553
|
yield { type: "token", text: delta.text };
|
|
1507
1554
|
} else if (delta?.type === "input_json_delta" && currentToolUse && delta.partial_json) {
|
|
1508
1555
|
currentToolUse.argumentsText += delta.partial_json;
|
|
1556
|
+
} else if (delta?.type === "thinking_delta" && currentThinking && delta.thinking) {
|
|
1557
|
+
currentThinking.thinking += delta.thinking;
|
|
1558
|
+
} else if (delta?.type === "signature_delta" && currentThinking && delta.signature) {
|
|
1559
|
+
currentThinking.signature += delta.signature;
|
|
1509
1560
|
}
|
|
1510
1561
|
break;
|
|
1511
1562
|
}
|
|
1512
1563
|
case "content_block_stop":
|
|
1564
|
+
if (currentThinking) {
|
|
1565
|
+
if (currentThinking.signature) turnContent.push(currentThinking);
|
|
1566
|
+
currentThinking = null;
|
|
1567
|
+
}
|
|
1568
|
+
if (currentText !== null) {
|
|
1569
|
+
if (currentText) turnContent.push({ type: "text", text: currentText });
|
|
1570
|
+
currentText = null;
|
|
1571
|
+
}
|
|
1513
1572
|
if (currentToolUse && currentToolUse.id && currentToolUse.name) {
|
|
1514
1573
|
let parsed = {};
|
|
1515
1574
|
try {
|
|
@@ -1522,6 +1581,12 @@ var AnthropicAdapter = class {
|
|
|
1522
1581
|
name: currentToolUse.name,
|
|
1523
1582
|
arguments: parsed
|
|
1524
1583
|
});
|
|
1584
|
+
turnContent.push({
|
|
1585
|
+
type: "tool_use",
|
|
1586
|
+
id: currentToolUse.id,
|
|
1587
|
+
name: currentToolUse.name,
|
|
1588
|
+
input: parsed
|
|
1589
|
+
});
|
|
1525
1590
|
}
|
|
1526
1591
|
currentToolUse = null;
|
|
1527
1592
|
break;
|
|
@@ -1550,12 +1615,14 @@ var AnthropicAdapter = class {
|
|
|
1550
1615
|
yield { type: "end", finishReason: "aborted" };
|
|
1551
1616
|
return;
|
|
1552
1617
|
}
|
|
1618
|
+
const toolCallRaw = { content: turnContent };
|
|
1553
1619
|
for (const tc of completedToolCalls) {
|
|
1554
1620
|
yield {
|
|
1555
1621
|
type: "toolCall",
|
|
1556
1622
|
id: tc.id,
|
|
1557
1623
|
name: tc.name,
|
|
1558
|
-
arguments: tc.arguments
|
|
1624
|
+
arguments: tc.arguments,
|
|
1625
|
+
vendorRaw: toolCallRaw
|
|
1559
1626
|
};
|
|
1560
1627
|
}
|
|
1561
1628
|
const finishReason = mapStopReason(stopReason, completedToolCalls.length > 0);
|
|
@@ -1586,15 +1653,7 @@ var AnthropicAdapter = class {
|
|
|
1586
1653
|
const text = assistantText?.trim() ? assistantText : null;
|
|
1587
1654
|
const wireMessage = {
|
|
1588
1655
|
role: "assistant",
|
|
1589
|
-
content:
|
|
1590
|
-
...text ? [{ type: "text", text }] : [],
|
|
1591
|
-
...toolCalls.map((tc) => ({
|
|
1592
|
-
type: "tool_use",
|
|
1593
|
-
id: tc.id,
|
|
1594
|
-
name: tc.name,
|
|
1595
|
-
input: tc.arguments ?? {}
|
|
1596
|
-
}))
|
|
1597
|
-
]
|
|
1656
|
+
content: assistantTurnContent(toolCalls, text)
|
|
1598
1657
|
};
|
|
1599
1658
|
return [
|
|
1600
1659
|
...history,
|
|
@@ -1686,6 +1745,62 @@ function markLastMessageForCaching(messages) {
|
|
|
1686
1745
|
};
|
|
1687
1746
|
}
|
|
1688
1747
|
}
|
|
1748
|
+
function isThinkingBlockRejection(err) {
|
|
1749
|
+
const e = err;
|
|
1750
|
+
return e?.status === 400 && /`thinking` block/.test(String(e.message ?? ""));
|
|
1751
|
+
}
|
|
1752
|
+
function withoutThinking(messages) {
|
|
1753
|
+
let removed = false;
|
|
1754
|
+
const out = messages.map((m) => {
|
|
1755
|
+
const content = m.content;
|
|
1756
|
+
if (!Array.isArray(content)) return m;
|
|
1757
|
+
const kept = content.filter((b) => {
|
|
1758
|
+
const thinking = b?.type === "thinking" || b?.type === "redacted_thinking";
|
|
1759
|
+
if (thinking) removed = true;
|
|
1760
|
+
return !thinking;
|
|
1761
|
+
});
|
|
1762
|
+
return kept.length === content.length ? m : { ...m, content: kept };
|
|
1763
|
+
});
|
|
1764
|
+
return removed ? out : void 0;
|
|
1765
|
+
}
|
|
1766
|
+
function assistantTurnContent(toolCalls, text) {
|
|
1767
|
+
const recorded = recordedTurnOf(toolCalls);
|
|
1768
|
+
if (!recorded) {
|
|
1769
|
+
return [
|
|
1770
|
+
...text ? [{ type: "text", text }] : [],
|
|
1771
|
+
...toolCalls.map((tc) => ({
|
|
1772
|
+
type: "tool_use",
|
|
1773
|
+
id: tc.id,
|
|
1774
|
+
name: tc.name,
|
|
1775
|
+
input: tc.arguments ?? {}
|
|
1776
|
+
}))
|
|
1777
|
+
];
|
|
1778
|
+
}
|
|
1779
|
+
const ids = new Set(toolCalls.map((tc) => tc.id));
|
|
1780
|
+
const content = recorded.filter(
|
|
1781
|
+
(b) => b.type !== "tool_use" || ids.has(b.id)
|
|
1782
|
+
);
|
|
1783
|
+
if (text && !content.some((b) => b.type === "text")) {
|
|
1784
|
+
const at = content.findIndex((b) => b.type === "tool_use");
|
|
1785
|
+
content.splice(at === -1 ? content.length : at, 0, { type: "text", text });
|
|
1786
|
+
}
|
|
1787
|
+
const known = new Set(
|
|
1788
|
+
content.flatMap((b) => b.type === "tool_use" ? [b.id] : [])
|
|
1789
|
+
);
|
|
1790
|
+
for (const tc of toolCalls) {
|
|
1791
|
+
if (!known.has(tc.id)) {
|
|
1792
|
+
content.push({ type: "tool_use", id: tc.id, name: tc.name, input: tc.arguments ?? {} });
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
return content;
|
|
1796
|
+
}
|
|
1797
|
+
function recordedTurnOf(toolCalls) {
|
|
1798
|
+
for (const tc of toolCalls) {
|
|
1799
|
+
const raw = tc.vendorRaw;
|
|
1800
|
+
if (raw && Array.isArray(raw.content)) return raw.content;
|
|
1801
|
+
}
|
|
1802
|
+
return void 0;
|
|
1803
|
+
}
|
|
1689
1804
|
function formatTools2(tools) {
|
|
1690
1805
|
return tools.map((t) => ({
|
|
1691
1806
|
name: t.name,
|
|
@@ -1703,6 +1818,8 @@ function mapStopReason(r, hadToolCalls) {
|
|
|
1703
1818
|
return "tool";
|
|
1704
1819
|
case "max_tokens":
|
|
1705
1820
|
return "length";
|
|
1821
|
+
case "refusal":
|
|
1822
|
+
return "filtered";
|
|
1706
1823
|
default:
|
|
1707
1824
|
return "stop";
|
|
1708
1825
|
}
|
|
@@ -3877,6 +3994,32 @@ var openaiS2sManifest = {
|
|
|
3877
3994
|
category: "s2s"
|
|
3878
3995
|
};
|
|
3879
3996
|
|
|
3997
|
+
// src/vendors/rime-s2s.ts
|
|
3998
|
+
var rimeS2sManifest = {
|
|
3999
|
+
vendor: "rime_s2s",
|
|
4000
|
+
displayName: "Rime Prism",
|
|
4001
|
+
authKinds: [
|
|
4002
|
+
{
|
|
4003
|
+
kind: "apiKey",
|
|
4004
|
+
displayName: "API Key",
|
|
4005
|
+
fields: [
|
|
4006
|
+
{
|
|
4007
|
+
name: "apiKey",
|
|
4008
|
+
label: "API Key",
|
|
4009
|
+
type: "password",
|
|
4010
|
+
required: true,
|
|
4011
|
+
help: "A Rime API key. Prism uses the same keys as Rime text-to-speech."
|
|
4012
|
+
}
|
|
4013
|
+
]
|
|
4014
|
+
}
|
|
4015
|
+
],
|
|
4016
|
+
knownModels: [],
|
|
4017
|
+
supportsModelListing: false,
|
|
4018
|
+
docsUrl: "https://docs.rime.ai/docs/prism/overview",
|
|
4019
|
+
credentialOnly: true,
|
|
4020
|
+
category: "s2s"
|
|
4021
|
+
};
|
|
4022
|
+
|
|
3880
4023
|
// src/adapters/index.ts
|
|
3881
4024
|
registerAdapter(openAIFactory);
|
|
3882
4025
|
registerAdapter(deepseekFactory);
|
|
@@ -3896,6 +4039,7 @@ registerAdapter(huggingfaceFactory);
|
|
|
3896
4039
|
registerAdapter(openRouterFactory);
|
|
3897
4040
|
registerCredentialVendor(harnessManifest);
|
|
3898
4041
|
registerCredentialVendor(openaiS2sManifest);
|
|
4042
|
+
registerCredentialVendor(rimeS2sManifest);
|
|
3899
4043
|
registerCredentialVendor(dialogflowCesManifest);
|
|
3900
4044
|
|
|
3901
4045
|
// src/normalize-auth.ts
|