@jambonz/llm 0.6.9 → 0.6.10
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 +136 -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 +136 -19
- package/dist/index.js.map +1 -1
- package/dist/test-kit/index.cjs +136 -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 +136 -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/test-kit/index.cjs
CHANGED
|
@@ -1291,6 +1291,21 @@ var ANTHROPIC_KNOWN_MODELS = [
|
|
|
1291
1291
|
maxContextTokens: 2e5
|
|
1292
1292
|
}
|
|
1293
1293
|
},
|
|
1294
|
+
{
|
|
1295
|
+
// Thinks by default (effort `medium`), and the thinking counts toward
|
|
1296
|
+
// max_tokens. For voice, send `providerParams: {output_config: {effort:
|
|
1297
|
+
// 'low'}}`. Rejects non-default sampling parameters, so the adapter
|
|
1298
|
+
// leaves `temperature` out of its requests.
|
|
1299
|
+
id: "claude-haiku-5-5",
|
|
1300
|
+
displayName: "Claude Haiku 5.5",
|
|
1301
|
+
capabilities: {
|
|
1302
|
+
streaming: true,
|
|
1303
|
+
tools: true,
|
|
1304
|
+
vision: true,
|
|
1305
|
+
systemPrompt: true,
|
|
1306
|
+
maxContextTokens: 1e6
|
|
1307
|
+
}
|
|
1308
|
+
},
|
|
1294
1309
|
{
|
|
1295
1310
|
id: "claude-haiku-4-5-20251001",
|
|
1296
1311
|
displayName: "Claude Haiku 4.5",
|
|
@@ -1374,6 +1389,7 @@ var ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
|
1374
1389
|
{ header: "anthropic-ratelimit-input-tokens-remaining", key: "input_tokens_remaining", numeric: true },
|
|
1375
1390
|
{ header: "anthropic-ratelimit-output-tokens-remaining", key: "output_tokens_remaining", numeric: true }
|
|
1376
1391
|
]);
|
|
1392
|
+
var REJECTS_SAMPLING_PARAMS = /^claude-(opus-4-[7-9]|opus-5|sonnet-5|haiku-5|fable|mythos)/;
|
|
1377
1393
|
var AnthropicAdapter = class {
|
|
1378
1394
|
vendor = anthropicManifest.vendor;
|
|
1379
1395
|
acceptedAuth = ["apiKey"];
|
|
@@ -1406,7 +1422,14 @@ var AnthropicAdapter = class {
|
|
|
1406
1422
|
};
|
|
1407
1423
|
if (req.system) body.system = req.system;
|
|
1408
1424
|
if (tools) body.tools = tools;
|
|
1409
|
-
if (req.temperature !== void 0
|
|
1425
|
+
if (req.temperature !== void 0 && !REJECTS_SAMPLING_PARAMS.test(req.model)) {
|
|
1426
|
+
body.temperature = req.temperature;
|
|
1427
|
+
}
|
|
1428
|
+
if (req.providerParams) {
|
|
1429
|
+
for (const [key, value] of Object.entries(req.providerParams)) {
|
|
1430
|
+
if (!(key in body)) body[key] = value;
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1410
1433
|
if (req.cacheKey) {
|
|
1411
1434
|
if (req.system) {
|
|
1412
1435
|
body.system = [{ type: "text", text: req.system, cache_control: { type: "ephemeral" } }];
|
|
@@ -1417,21 +1440,31 @@ var AnthropicAdapter = class {
|
|
|
1417
1440
|
}
|
|
1418
1441
|
markLastMessageForCaching(messages);
|
|
1419
1442
|
}
|
|
1420
|
-
|
|
1421
|
-
let responseHeaders;
|
|
1422
|
-
try {
|
|
1443
|
+
const open = async (b) => {
|
|
1423
1444
|
const apiPromise = client.messages.create(
|
|
1424
|
-
|
|
1445
|
+
b,
|
|
1425
1446
|
{ signal: req.signal }
|
|
1426
1447
|
);
|
|
1427
1448
|
const maybeWithResponse = apiPromise.withResponse;
|
|
1428
1449
|
if (typeof maybeWithResponse === "function") {
|
|
1429
1450
|
const result = await maybeWithResponse.call(apiPromise);
|
|
1430
|
-
stream
|
|
1431
|
-
responseHeaders = result.response?.headers;
|
|
1432
|
-
} else {
|
|
1433
|
-
stream = await apiPromise;
|
|
1451
|
+
return { stream: result.data, headers: result.response?.headers };
|
|
1434
1452
|
}
|
|
1453
|
+
return { stream: await apiPromise, headers: void 0 };
|
|
1454
|
+
};
|
|
1455
|
+
let stream;
|
|
1456
|
+
let responseHeaders;
|
|
1457
|
+
try {
|
|
1458
|
+
let opened;
|
|
1459
|
+
try {
|
|
1460
|
+
opened = await open(body);
|
|
1461
|
+
} catch (err) {
|
|
1462
|
+
const stripped = isThinkingBlockRejection(err) ? withoutThinking(messages) : void 0;
|
|
1463
|
+
if (!stripped) throw err;
|
|
1464
|
+
opened = await open({ ...body, messages: stripped });
|
|
1465
|
+
}
|
|
1466
|
+
stream = opened.stream;
|
|
1467
|
+
responseHeaders = opened.headers;
|
|
1435
1468
|
} catch (err) {
|
|
1436
1469
|
if (isAbortError2(err)) {
|
|
1437
1470
|
yield { type: "end", finishReason: "aborted" };
|
|
@@ -1440,7 +1473,10 @@ var AnthropicAdapter = class {
|
|
|
1440
1473
|
throw err;
|
|
1441
1474
|
}
|
|
1442
1475
|
let currentToolUse = null;
|
|
1476
|
+
let currentThinking = null;
|
|
1477
|
+
let currentText = null;
|
|
1443
1478
|
const completedToolCalls = [];
|
|
1479
|
+
const turnContent = [];
|
|
1444
1480
|
let stopReason;
|
|
1445
1481
|
let inputTokens;
|
|
1446
1482
|
let outputTokens;
|
|
@@ -1473,19 +1509,42 @@ var AnthropicAdapter = class {
|
|
|
1473
1509
|
name: currentToolUse.name
|
|
1474
1510
|
};
|
|
1475
1511
|
}
|
|
1512
|
+
} else if (block?.type === "text") {
|
|
1513
|
+
currentText = block.text ?? "";
|
|
1514
|
+
} else if (block?.type === "thinking") {
|
|
1515
|
+
currentThinking = {
|
|
1516
|
+
type: "thinking",
|
|
1517
|
+
thinking: block.thinking ?? "",
|
|
1518
|
+
signature: block.signature ?? ""
|
|
1519
|
+
};
|
|
1520
|
+
} else if (block?.type === "redacted_thinking" && block.data) {
|
|
1521
|
+
turnContent.push({ type: "redacted_thinking", data: block.data });
|
|
1476
1522
|
}
|
|
1477
1523
|
break;
|
|
1478
1524
|
}
|
|
1479
1525
|
case "content_block_delta": {
|
|
1480
1526
|
const delta = event.delta;
|
|
1481
1527
|
if (delta?.type === "text_delta" && delta.text) {
|
|
1528
|
+
if (currentText !== null) currentText += delta.text;
|
|
1482
1529
|
yield { type: "token", text: delta.text };
|
|
1483
1530
|
} else if (delta?.type === "input_json_delta" && currentToolUse && delta.partial_json) {
|
|
1484
1531
|
currentToolUse.argumentsText += delta.partial_json;
|
|
1532
|
+
} else if (delta?.type === "thinking_delta" && currentThinking && delta.thinking) {
|
|
1533
|
+
currentThinking.thinking += delta.thinking;
|
|
1534
|
+
} else if (delta?.type === "signature_delta" && currentThinking && delta.signature) {
|
|
1535
|
+
currentThinking.signature += delta.signature;
|
|
1485
1536
|
}
|
|
1486
1537
|
break;
|
|
1487
1538
|
}
|
|
1488
1539
|
case "content_block_stop":
|
|
1540
|
+
if (currentThinking) {
|
|
1541
|
+
if (currentThinking.signature) turnContent.push(currentThinking);
|
|
1542
|
+
currentThinking = null;
|
|
1543
|
+
}
|
|
1544
|
+
if (currentText !== null) {
|
|
1545
|
+
if (currentText) turnContent.push({ type: "text", text: currentText });
|
|
1546
|
+
currentText = null;
|
|
1547
|
+
}
|
|
1489
1548
|
if (currentToolUse && currentToolUse.id && currentToolUse.name) {
|
|
1490
1549
|
let parsed = {};
|
|
1491
1550
|
try {
|
|
@@ -1498,6 +1557,12 @@ var AnthropicAdapter = class {
|
|
|
1498
1557
|
name: currentToolUse.name,
|
|
1499
1558
|
arguments: parsed
|
|
1500
1559
|
});
|
|
1560
|
+
turnContent.push({
|
|
1561
|
+
type: "tool_use",
|
|
1562
|
+
id: currentToolUse.id,
|
|
1563
|
+
name: currentToolUse.name,
|
|
1564
|
+
input: parsed
|
|
1565
|
+
});
|
|
1501
1566
|
}
|
|
1502
1567
|
currentToolUse = null;
|
|
1503
1568
|
break;
|
|
@@ -1526,12 +1591,14 @@ var AnthropicAdapter = class {
|
|
|
1526
1591
|
yield { type: "end", finishReason: "aborted" };
|
|
1527
1592
|
return;
|
|
1528
1593
|
}
|
|
1594
|
+
const toolCallRaw = { content: turnContent };
|
|
1529
1595
|
for (const tc of completedToolCalls) {
|
|
1530
1596
|
yield {
|
|
1531
1597
|
type: "toolCall",
|
|
1532
1598
|
id: tc.id,
|
|
1533
1599
|
name: tc.name,
|
|
1534
|
-
arguments: tc.arguments
|
|
1600
|
+
arguments: tc.arguments,
|
|
1601
|
+
vendorRaw: toolCallRaw
|
|
1535
1602
|
};
|
|
1536
1603
|
}
|
|
1537
1604
|
const finishReason = mapStopReason(stopReason, completedToolCalls.length > 0);
|
|
@@ -1562,15 +1629,7 @@ var AnthropicAdapter = class {
|
|
|
1562
1629
|
const text = assistantText?.trim() ? assistantText : null;
|
|
1563
1630
|
const wireMessage = {
|
|
1564
1631
|
role: "assistant",
|
|
1565
|
-
content:
|
|
1566
|
-
...text ? [{ type: "text", text }] : [],
|
|
1567
|
-
...toolCalls.map((tc) => ({
|
|
1568
|
-
type: "tool_use",
|
|
1569
|
-
id: tc.id,
|
|
1570
|
-
name: tc.name,
|
|
1571
|
-
input: tc.arguments ?? {}
|
|
1572
|
-
}))
|
|
1573
|
-
]
|
|
1632
|
+
content: assistantTurnContent(toolCalls, text)
|
|
1574
1633
|
};
|
|
1575
1634
|
return [
|
|
1576
1635
|
...history,
|
|
@@ -1662,6 +1721,62 @@ function markLastMessageForCaching(messages) {
|
|
|
1662
1721
|
};
|
|
1663
1722
|
}
|
|
1664
1723
|
}
|
|
1724
|
+
function isThinkingBlockRejection(err) {
|
|
1725
|
+
const e = err;
|
|
1726
|
+
return e?.status === 400 && /`thinking` block/.test(String(e.message ?? ""));
|
|
1727
|
+
}
|
|
1728
|
+
function withoutThinking(messages) {
|
|
1729
|
+
let removed = false;
|
|
1730
|
+
const out = messages.map((m) => {
|
|
1731
|
+
const content = m.content;
|
|
1732
|
+
if (!Array.isArray(content)) return m;
|
|
1733
|
+
const kept = content.filter((b) => {
|
|
1734
|
+
const thinking = b?.type === "thinking" || b?.type === "redacted_thinking";
|
|
1735
|
+
if (thinking) removed = true;
|
|
1736
|
+
return !thinking;
|
|
1737
|
+
});
|
|
1738
|
+
return kept.length === content.length ? m : { ...m, content: kept };
|
|
1739
|
+
});
|
|
1740
|
+
return removed ? out : void 0;
|
|
1741
|
+
}
|
|
1742
|
+
function assistantTurnContent(toolCalls, text) {
|
|
1743
|
+
const recorded = recordedTurnOf(toolCalls);
|
|
1744
|
+
if (!recorded) {
|
|
1745
|
+
return [
|
|
1746
|
+
...text ? [{ type: "text", text }] : [],
|
|
1747
|
+
...toolCalls.map((tc) => ({
|
|
1748
|
+
type: "tool_use",
|
|
1749
|
+
id: tc.id,
|
|
1750
|
+
name: tc.name,
|
|
1751
|
+
input: tc.arguments ?? {}
|
|
1752
|
+
}))
|
|
1753
|
+
];
|
|
1754
|
+
}
|
|
1755
|
+
const ids = new Set(toolCalls.map((tc) => tc.id));
|
|
1756
|
+
const content = recorded.filter(
|
|
1757
|
+
(b) => b.type !== "tool_use" || ids.has(b.id)
|
|
1758
|
+
);
|
|
1759
|
+
if (text && !content.some((b) => b.type === "text")) {
|
|
1760
|
+
const at = content.findIndex((b) => b.type === "tool_use");
|
|
1761
|
+
content.splice(at === -1 ? content.length : at, 0, { type: "text", text });
|
|
1762
|
+
}
|
|
1763
|
+
const known = new Set(
|
|
1764
|
+
content.flatMap((b) => b.type === "tool_use" ? [b.id] : [])
|
|
1765
|
+
);
|
|
1766
|
+
for (const tc of toolCalls) {
|
|
1767
|
+
if (!known.has(tc.id)) {
|
|
1768
|
+
content.push({ type: "tool_use", id: tc.id, name: tc.name, input: tc.arguments ?? {} });
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
return content;
|
|
1772
|
+
}
|
|
1773
|
+
function recordedTurnOf(toolCalls) {
|
|
1774
|
+
for (const tc of toolCalls) {
|
|
1775
|
+
const raw = tc.vendorRaw;
|
|
1776
|
+
if (raw && Array.isArray(raw.content)) return raw.content;
|
|
1777
|
+
}
|
|
1778
|
+
return void 0;
|
|
1779
|
+
}
|
|
1665
1780
|
function formatTools2(tools) {
|
|
1666
1781
|
return tools.map((t) => ({
|
|
1667
1782
|
name: t.name,
|
|
@@ -1679,6 +1794,8 @@ function mapStopReason(r, hadToolCalls) {
|
|
|
1679
1794
|
return "tool";
|
|
1680
1795
|
case "max_tokens":
|
|
1681
1796
|
return "length";
|
|
1797
|
+
case "refusal":
|
|
1798
|
+
return "filtered";
|
|
1682
1799
|
default:
|
|
1683
1800
|
return "stop";
|
|
1684
1801
|
}
|