@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.
@@ -1,4 +1,4 @@
1
- import { b as AdapterFactory, e as AuthKind, A as AuthSpec, L as LlmAdapter, d as ApiKeyAuth, h as ClientOptions, P as PromptRequest, m as LlmEvent, M as Message, p as ToolCallEvent, o as ModelInfo, c as AdapterManifest } from '../types-C_yrWq_0.cjs';
1
+ import { b as AdapterFactory, e as AuthKind, A as AuthSpec, L as LlmAdapter, d as ApiKeyAuth, h as ClientOptions, P as PromptRequest, m as LlmEvent, M as Message, p as ToolCallEvent, o as ModelInfo, c as AdapterManifest } from '../types-C3Cdt-km.cjs';
2
2
 
3
3
  /**
4
4
  * Named scenarios the harness must be able to stage. Each scenario configures
@@ -1,4 +1,4 @@
1
- import { b as AdapterFactory, e as AuthKind, A as AuthSpec, L as LlmAdapter, d as ApiKeyAuth, h as ClientOptions, P as PromptRequest, m as LlmEvent, M as Message, p as ToolCallEvent, o as ModelInfo, c as AdapterManifest } from '../types-C_yrWq_0.js';
1
+ import { b as AdapterFactory, e as AuthKind, A as AuthSpec, L as LlmAdapter, d as ApiKeyAuth, h as ClientOptions, P as PromptRequest, m as LlmEvent, M as Message, p as ToolCallEvent, o as ModelInfo, c as AdapterManifest } from '../types-C3Cdt-km.js';
2
2
 
3
3
  /**
4
4
  * Named scenarios the harness must be able to stage. Each scenario configures
@@ -1252,6 +1252,21 @@ var ANTHROPIC_KNOWN_MODELS = [
1252
1252
  maxContextTokens: 2e5
1253
1253
  }
1254
1254
  },
1255
+ {
1256
+ // Thinks by default (effort `medium`), and the thinking counts toward
1257
+ // max_tokens. For voice, send `providerParams: {output_config: {effort:
1258
+ // 'low'}}`. Rejects non-default sampling parameters, so the adapter
1259
+ // leaves `temperature` out of its requests.
1260
+ id: "claude-haiku-5-5",
1261
+ displayName: "Claude Haiku 5.5",
1262
+ capabilities: {
1263
+ streaming: true,
1264
+ tools: true,
1265
+ vision: true,
1266
+ systemPrompt: true,
1267
+ maxContextTokens: 1e6
1268
+ }
1269
+ },
1255
1270
  {
1256
1271
  id: "claude-haiku-4-5-20251001",
1257
1272
  displayName: "Claude Haiku 4.5",
@@ -1335,6 +1350,7 @@ var ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([
1335
1350
  { header: "anthropic-ratelimit-input-tokens-remaining", key: "input_tokens_remaining", numeric: true },
1336
1351
  { header: "anthropic-ratelimit-output-tokens-remaining", key: "output_tokens_remaining", numeric: true }
1337
1352
  ]);
1353
+ var REJECTS_SAMPLING_PARAMS = /^claude-(opus-4-[7-9]|opus-5|sonnet-5|haiku-5|fable|mythos)/;
1338
1354
  var AnthropicAdapter = class {
1339
1355
  vendor = anthropicManifest.vendor;
1340
1356
  acceptedAuth = ["apiKey"];
@@ -1367,7 +1383,14 @@ var AnthropicAdapter = class {
1367
1383
  };
1368
1384
  if (req.system) body.system = req.system;
1369
1385
  if (tools) body.tools = tools;
1370
- if (req.temperature !== void 0) body.temperature = req.temperature;
1386
+ if (req.temperature !== void 0 && !REJECTS_SAMPLING_PARAMS.test(req.model)) {
1387
+ body.temperature = req.temperature;
1388
+ }
1389
+ if (req.providerParams) {
1390
+ for (const [key, value] of Object.entries(req.providerParams)) {
1391
+ if (!(key in body)) body[key] = value;
1392
+ }
1393
+ }
1371
1394
  if (req.cacheKey) {
1372
1395
  if (req.system) {
1373
1396
  body.system = [{ type: "text", text: req.system, cache_control: { type: "ephemeral" } }];
@@ -1378,21 +1401,31 @@ var AnthropicAdapter = class {
1378
1401
  }
1379
1402
  markLastMessageForCaching(messages);
1380
1403
  }
1381
- let stream;
1382
- let responseHeaders;
1383
- try {
1404
+ const open = async (b) => {
1384
1405
  const apiPromise = client.messages.create(
1385
- body,
1406
+ b,
1386
1407
  { signal: req.signal }
1387
1408
  );
1388
1409
  const maybeWithResponse = apiPromise.withResponse;
1389
1410
  if (typeof maybeWithResponse === "function") {
1390
1411
  const result = await maybeWithResponse.call(apiPromise);
1391
- stream = result.data;
1392
- responseHeaders = result.response?.headers;
1393
- } else {
1394
- stream = await apiPromise;
1412
+ return { stream: result.data, headers: result.response?.headers };
1395
1413
  }
1414
+ return { stream: await apiPromise, headers: void 0 };
1415
+ };
1416
+ let stream;
1417
+ let responseHeaders;
1418
+ try {
1419
+ let opened;
1420
+ try {
1421
+ opened = await open(body);
1422
+ } catch (err) {
1423
+ const stripped = isThinkingBlockRejection(err) ? withoutThinking(messages) : void 0;
1424
+ if (!stripped) throw err;
1425
+ opened = await open({ ...body, messages: stripped });
1426
+ }
1427
+ stream = opened.stream;
1428
+ responseHeaders = opened.headers;
1396
1429
  } catch (err) {
1397
1430
  if (isAbortError2(err)) {
1398
1431
  yield { type: "end", finishReason: "aborted" };
@@ -1401,7 +1434,10 @@ var AnthropicAdapter = class {
1401
1434
  throw err;
1402
1435
  }
1403
1436
  let currentToolUse = null;
1437
+ let currentThinking = null;
1438
+ let currentText = null;
1404
1439
  const completedToolCalls = [];
1440
+ const turnContent = [];
1405
1441
  let stopReason;
1406
1442
  let inputTokens;
1407
1443
  let outputTokens;
@@ -1434,19 +1470,42 @@ var AnthropicAdapter = class {
1434
1470
  name: currentToolUse.name
1435
1471
  };
1436
1472
  }
1473
+ } else if (block?.type === "text") {
1474
+ currentText = block.text ?? "";
1475
+ } else if (block?.type === "thinking") {
1476
+ currentThinking = {
1477
+ type: "thinking",
1478
+ thinking: block.thinking ?? "",
1479
+ signature: block.signature ?? ""
1480
+ };
1481
+ } else if (block?.type === "redacted_thinking" && block.data) {
1482
+ turnContent.push({ type: "redacted_thinking", data: block.data });
1437
1483
  }
1438
1484
  break;
1439
1485
  }
1440
1486
  case "content_block_delta": {
1441
1487
  const delta = event.delta;
1442
1488
  if (delta?.type === "text_delta" && delta.text) {
1489
+ if (currentText !== null) currentText += delta.text;
1443
1490
  yield { type: "token", text: delta.text };
1444
1491
  } else if (delta?.type === "input_json_delta" && currentToolUse && delta.partial_json) {
1445
1492
  currentToolUse.argumentsText += delta.partial_json;
1493
+ } else if (delta?.type === "thinking_delta" && currentThinking && delta.thinking) {
1494
+ currentThinking.thinking += delta.thinking;
1495
+ } else if (delta?.type === "signature_delta" && currentThinking && delta.signature) {
1496
+ currentThinking.signature += delta.signature;
1446
1497
  }
1447
1498
  break;
1448
1499
  }
1449
1500
  case "content_block_stop":
1501
+ if (currentThinking) {
1502
+ if (currentThinking.signature) turnContent.push(currentThinking);
1503
+ currentThinking = null;
1504
+ }
1505
+ if (currentText !== null) {
1506
+ if (currentText) turnContent.push({ type: "text", text: currentText });
1507
+ currentText = null;
1508
+ }
1450
1509
  if (currentToolUse && currentToolUse.id && currentToolUse.name) {
1451
1510
  let parsed = {};
1452
1511
  try {
@@ -1459,6 +1518,12 @@ var AnthropicAdapter = class {
1459
1518
  name: currentToolUse.name,
1460
1519
  arguments: parsed
1461
1520
  });
1521
+ turnContent.push({
1522
+ type: "tool_use",
1523
+ id: currentToolUse.id,
1524
+ name: currentToolUse.name,
1525
+ input: parsed
1526
+ });
1462
1527
  }
1463
1528
  currentToolUse = null;
1464
1529
  break;
@@ -1487,12 +1552,14 @@ var AnthropicAdapter = class {
1487
1552
  yield { type: "end", finishReason: "aborted" };
1488
1553
  return;
1489
1554
  }
1555
+ const toolCallRaw = { content: turnContent };
1490
1556
  for (const tc of completedToolCalls) {
1491
1557
  yield {
1492
1558
  type: "toolCall",
1493
1559
  id: tc.id,
1494
1560
  name: tc.name,
1495
- arguments: tc.arguments
1561
+ arguments: tc.arguments,
1562
+ vendorRaw: toolCallRaw
1496
1563
  };
1497
1564
  }
1498
1565
  const finishReason = mapStopReason(stopReason, completedToolCalls.length > 0);
@@ -1523,15 +1590,7 @@ var AnthropicAdapter = class {
1523
1590
  const text = assistantText?.trim() ? assistantText : null;
1524
1591
  const wireMessage = {
1525
1592
  role: "assistant",
1526
- content: [
1527
- ...text ? [{ type: "text", text }] : [],
1528
- ...toolCalls.map((tc) => ({
1529
- type: "tool_use",
1530
- id: tc.id,
1531
- name: tc.name,
1532
- input: tc.arguments ?? {}
1533
- }))
1534
- ]
1593
+ content: assistantTurnContent(toolCalls, text)
1535
1594
  };
1536
1595
  return [
1537
1596
  ...history,
@@ -1623,6 +1682,62 @@ function markLastMessageForCaching(messages) {
1623
1682
  };
1624
1683
  }
1625
1684
  }
1685
+ function isThinkingBlockRejection(err) {
1686
+ const e = err;
1687
+ return e?.status === 400 && /`thinking` block/.test(String(e.message ?? ""));
1688
+ }
1689
+ function withoutThinking(messages) {
1690
+ let removed = false;
1691
+ const out = messages.map((m) => {
1692
+ const content = m.content;
1693
+ if (!Array.isArray(content)) return m;
1694
+ const kept = content.filter((b) => {
1695
+ const thinking = b?.type === "thinking" || b?.type === "redacted_thinking";
1696
+ if (thinking) removed = true;
1697
+ return !thinking;
1698
+ });
1699
+ return kept.length === content.length ? m : { ...m, content: kept };
1700
+ });
1701
+ return removed ? out : void 0;
1702
+ }
1703
+ function assistantTurnContent(toolCalls, text) {
1704
+ const recorded = recordedTurnOf(toolCalls);
1705
+ if (!recorded) {
1706
+ return [
1707
+ ...text ? [{ type: "text", text }] : [],
1708
+ ...toolCalls.map((tc) => ({
1709
+ type: "tool_use",
1710
+ id: tc.id,
1711
+ name: tc.name,
1712
+ input: tc.arguments ?? {}
1713
+ }))
1714
+ ];
1715
+ }
1716
+ const ids = new Set(toolCalls.map((tc) => tc.id));
1717
+ const content = recorded.filter(
1718
+ (b) => b.type !== "tool_use" || ids.has(b.id)
1719
+ );
1720
+ if (text && !content.some((b) => b.type === "text")) {
1721
+ const at = content.findIndex((b) => b.type === "tool_use");
1722
+ content.splice(at === -1 ? content.length : at, 0, { type: "text", text });
1723
+ }
1724
+ const known = new Set(
1725
+ content.flatMap((b) => b.type === "tool_use" ? [b.id] : [])
1726
+ );
1727
+ for (const tc of toolCalls) {
1728
+ if (!known.has(tc.id)) {
1729
+ content.push({ type: "tool_use", id: tc.id, name: tc.name, input: tc.arguments ?? {} });
1730
+ }
1731
+ }
1732
+ return content;
1733
+ }
1734
+ function recordedTurnOf(toolCalls) {
1735
+ for (const tc of toolCalls) {
1736
+ const raw = tc.vendorRaw;
1737
+ if (raw && Array.isArray(raw.content)) return raw.content;
1738
+ }
1739
+ return void 0;
1740
+ }
1626
1741
  function formatTools2(tools) {
1627
1742
  return tools.map((t) => ({
1628
1743
  name: t.name,
@@ -1640,6 +1755,8 @@ function mapStopReason(r, hadToolCalls) {
1640
1755
  return "tool";
1641
1756
  case "max_tokens":
1642
1757
  return "length";
1758
+ case "refusal":
1759
+ return "filtered";
1643
1760
  default:
1644
1761
  return "stop";
1645
1762
  }