@jambonz/llm 0.6.8 → 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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as ServiceAccountJson, A as AuthSpec, a as AuthKindSchema, P as PromptRequest, b as AdapterFactory, c as AdapterManifest, C as CreateLlmArgs, L as LlmAdapter } from './types-4l2etrW-.cjs';
2
- export { d as ApiKeyAuth, e as AuthKind, f as AzureOpenAIApiKeyAuth, B as BedrockApiKeyAuth, g as BedrockIamAuth, h as ClientOptions, i as ContentBlock, F as FinishReason, j as FormField, k as FormFieldType, G as GoogleApiKeyAuth, l as GoogleServiceAccountAuth, J as JsonSchema, m as LlmEvent, M as Message, n as ModelCapabilities, o as ModelInfo, R as Role, T as Tool, p as ToolCallEvent, U as Usage, V as VertexServiceAccountAuth } from './types-4l2etrW-.cjs';
1
+ import { S as ServiceAccountJson, A as AuthSpec, a as AuthKindSchema, P as PromptRequest, b as AdapterFactory, c as AdapterManifest, C as CreateLlmArgs, L as LlmAdapter } from './types-C3Cdt-km.cjs';
2
+ export { d as ApiKeyAuth, e as AuthKind, f as AzureOpenAIApiKeyAuth, B as BedrockApiKeyAuth, g as BedrockIamAuth, h as ClientOptions, i as ContentBlock, F as FinishReason, j as FormField, k as FormFieldType, G as GoogleApiKeyAuth, l as GoogleServiceAccountAuth, J as JsonSchema, m as LlmEvent, M as Message, n as ModelCapabilities, o as ModelInfo, R as Role, T as Tool, p as ToolCallEvent, U as Usage, V as VendorCategory, q as VertexServiceAccountAuth } from './types-C3Cdt-km.cjs';
3
3
 
4
4
  /**
5
5
  * The loose "DB-shape" input accepted by `normalizeAuth`.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as ServiceAccountJson, A as AuthSpec, a as AuthKindSchema, P as PromptRequest, b as AdapterFactory, c as AdapterManifest, C as CreateLlmArgs, L as LlmAdapter } from './types-4l2etrW-.js';
2
- export { d as ApiKeyAuth, e as AuthKind, f as AzureOpenAIApiKeyAuth, B as BedrockApiKeyAuth, g as BedrockIamAuth, h as ClientOptions, i as ContentBlock, F as FinishReason, j as FormField, k as FormFieldType, G as GoogleApiKeyAuth, l as GoogleServiceAccountAuth, J as JsonSchema, m as LlmEvent, M as Message, n as ModelCapabilities, o as ModelInfo, R as Role, T as Tool, p as ToolCallEvent, U as Usage, V as VertexServiceAccountAuth } from './types-4l2etrW-.js';
1
+ import { S as ServiceAccountJson, A as AuthSpec, a as AuthKindSchema, P as PromptRequest, b as AdapterFactory, c as AdapterManifest, C as CreateLlmArgs, L as LlmAdapter } from './types-C3Cdt-km.js';
2
+ export { d as ApiKeyAuth, e as AuthKind, f as AzureOpenAIApiKeyAuth, B as BedrockApiKeyAuth, g as BedrockIamAuth, h as ClientOptions, i as ContentBlock, F as FinishReason, j as FormField, k as FormFieldType, G as GoogleApiKeyAuth, l as GoogleServiceAccountAuth, J as JsonSchema, m as LlmEvent, M as Message, n as ModelCapabilities, o as ModelInfo, R as Role, T as Tool, p as ToolCallEvent, U as Usage, V as VendorCategory, q as VertexServiceAccountAuth } from './types-C3Cdt-km.js';
3
3
 
4
4
  /**
5
5
  * The loose "DB-shape" input accepted by `normalizeAuth`.
package/dist/index.js CHANGED
@@ -59,7 +59,7 @@ function getManifest() {
59
59
  const vendors = [
60
60
  ...Array.from(registry.values()).map((f) => f.manifest),
61
61
  ...credentialVendors.values()
62
- ].sort((a, b) => a.vendor.localeCompare(b.vendor));
62
+ ].map((m) => ({ ...m, category: m.category ?? "llm" })).sort((a, b) => a.vendor.localeCompare(b.vendor));
63
63
  return { vendors };
64
64
  }
65
65
 
@@ -1269,6 +1269,21 @@ var ANTHROPIC_KNOWN_MODELS = [
1269
1269
  maxContextTokens: 2e5
1270
1270
  }
1271
1271
  },
1272
+ {
1273
+ // Thinks by default (effort `medium`), and the thinking counts toward
1274
+ // max_tokens. For voice, send `providerParams: {output_config: {effort:
1275
+ // 'low'}}`. Rejects non-default sampling parameters, so the adapter
1276
+ // leaves `temperature` out of its requests.
1277
+ id: "claude-haiku-5-5",
1278
+ displayName: "Claude Haiku 5.5",
1279
+ capabilities: {
1280
+ streaming: true,
1281
+ tools: true,
1282
+ vision: true,
1283
+ systemPrompt: true,
1284
+ maxContextTokens: 1e6
1285
+ }
1286
+ },
1272
1287
  {
1273
1288
  id: "claude-haiku-4-5-20251001",
1274
1289
  displayName: "Claude Haiku 4.5",
@@ -1352,6 +1367,7 @@ var ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([
1352
1367
  { header: "anthropic-ratelimit-input-tokens-remaining", key: "input_tokens_remaining", numeric: true },
1353
1368
  { header: "anthropic-ratelimit-output-tokens-remaining", key: "output_tokens_remaining", numeric: true }
1354
1369
  ]);
1370
+ var REJECTS_SAMPLING_PARAMS = /^claude-(opus-4-[7-9]|opus-5|sonnet-5|haiku-5|fable|mythos)/;
1355
1371
  var AnthropicAdapter = class {
1356
1372
  vendor = anthropicManifest.vendor;
1357
1373
  acceptedAuth = ["apiKey"];
@@ -1384,7 +1400,14 @@ var AnthropicAdapter = class {
1384
1400
  };
1385
1401
  if (req.system) body.system = req.system;
1386
1402
  if (tools) body.tools = tools;
1387
- if (req.temperature !== void 0) body.temperature = req.temperature;
1403
+ if (req.temperature !== void 0 && !REJECTS_SAMPLING_PARAMS.test(req.model)) {
1404
+ body.temperature = req.temperature;
1405
+ }
1406
+ if (req.providerParams) {
1407
+ for (const [key, value] of Object.entries(req.providerParams)) {
1408
+ if (!(key in body)) body[key] = value;
1409
+ }
1410
+ }
1388
1411
  if (req.cacheKey) {
1389
1412
  if (req.system) {
1390
1413
  body.system = [{ type: "text", text: req.system, cache_control: { type: "ephemeral" } }];
@@ -1395,21 +1418,31 @@ var AnthropicAdapter = class {
1395
1418
  }
1396
1419
  markLastMessageForCaching(messages);
1397
1420
  }
1398
- let stream;
1399
- let responseHeaders;
1400
- try {
1421
+ const open = async (b) => {
1401
1422
  const apiPromise = client.messages.create(
1402
- body,
1423
+ b,
1403
1424
  { signal: req.signal }
1404
1425
  );
1405
1426
  const maybeWithResponse = apiPromise.withResponse;
1406
1427
  if (typeof maybeWithResponse === "function") {
1407
1428
  const result = await maybeWithResponse.call(apiPromise);
1408
- stream = result.data;
1409
- responseHeaders = result.response?.headers;
1410
- } else {
1411
- stream = await apiPromise;
1429
+ return { stream: result.data, headers: result.response?.headers };
1412
1430
  }
1431
+ return { stream: await apiPromise, headers: void 0 };
1432
+ };
1433
+ let stream;
1434
+ let responseHeaders;
1435
+ try {
1436
+ let opened;
1437
+ try {
1438
+ opened = await open(body);
1439
+ } catch (err) {
1440
+ const stripped = isThinkingBlockRejection(err) ? withoutThinking(messages) : void 0;
1441
+ if (!stripped) throw err;
1442
+ opened = await open({ ...body, messages: stripped });
1443
+ }
1444
+ stream = opened.stream;
1445
+ responseHeaders = opened.headers;
1413
1446
  } catch (err) {
1414
1447
  if (isAbortError2(err)) {
1415
1448
  yield { type: "end", finishReason: "aborted" };
@@ -1418,7 +1451,10 @@ var AnthropicAdapter = class {
1418
1451
  throw err;
1419
1452
  }
1420
1453
  let currentToolUse = null;
1454
+ let currentThinking = null;
1455
+ let currentText = null;
1421
1456
  const completedToolCalls = [];
1457
+ const turnContent = [];
1422
1458
  let stopReason;
1423
1459
  let inputTokens;
1424
1460
  let outputTokens;
@@ -1451,19 +1487,42 @@ var AnthropicAdapter = class {
1451
1487
  name: currentToolUse.name
1452
1488
  };
1453
1489
  }
1490
+ } else if (block?.type === "text") {
1491
+ currentText = block.text ?? "";
1492
+ } else if (block?.type === "thinking") {
1493
+ currentThinking = {
1494
+ type: "thinking",
1495
+ thinking: block.thinking ?? "",
1496
+ signature: block.signature ?? ""
1497
+ };
1498
+ } else if (block?.type === "redacted_thinking" && block.data) {
1499
+ turnContent.push({ type: "redacted_thinking", data: block.data });
1454
1500
  }
1455
1501
  break;
1456
1502
  }
1457
1503
  case "content_block_delta": {
1458
1504
  const delta = event.delta;
1459
1505
  if (delta?.type === "text_delta" && delta.text) {
1506
+ if (currentText !== null) currentText += delta.text;
1460
1507
  yield { type: "token", text: delta.text };
1461
1508
  } else if (delta?.type === "input_json_delta" && currentToolUse && delta.partial_json) {
1462
1509
  currentToolUse.argumentsText += delta.partial_json;
1510
+ } else if (delta?.type === "thinking_delta" && currentThinking && delta.thinking) {
1511
+ currentThinking.thinking += delta.thinking;
1512
+ } else if (delta?.type === "signature_delta" && currentThinking && delta.signature) {
1513
+ currentThinking.signature += delta.signature;
1463
1514
  }
1464
1515
  break;
1465
1516
  }
1466
1517
  case "content_block_stop":
1518
+ if (currentThinking) {
1519
+ if (currentThinking.signature) turnContent.push(currentThinking);
1520
+ currentThinking = null;
1521
+ }
1522
+ if (currentText !== null) {
1523
+ if (currentText) turnContent.push({ type: "text", text: currentText });
1524
+ currentText = null;
1525
+ }
1467
1526
  if (currentToolUse && currentToolUse.id && currentToolUse.name) {
1468
1527
  let parsed = {};
1469
1528
  try {
@@ -1476,6 +1535,12 @@ var AnthropicAdapter = class {
1476
1535
  name: currentToolUse.name,
1477
1536
  arguments: parsed
1478
1537
  });
1538
+ turnContent.push({
1539
+ type: "tool_use",
1540
+ id: currentToolUse.id,
1541
+ name: currentToolUse.name,
1542
+ input: parsed
1543
+ });
1479
1544
  }
1480
1545
  currentToolUse = null;
1481
1546
  break;
@@ -1504,12 +1569,14 @@ var AnthropicAdapter = class {
1504
1569
  yield { type: "end", finishReason: "aborted" };
1505
1570
  return;
1506
1571
  }
1572
+ const toolCallRaw = { content: turnContent };
1507
1573
  for (const tc of completedToolCalls) {
1508
1574
  yield {
1509
1575
  type: "toolCall",
1510
1576
  id: tc.id,
1511
1577
  name: tc.name,
1512
- arguments: tc.arguments
1578
+ arguments: tc.arguments,
1579
+ vendorRaw: toolCallRaw
1513
1580
  };
1514
1581
  }
1515
1582
  const finishReason = mapStopReason(stopReason, completedToolCalls.length > 0);
@@ -1540,15 +1607,7 @@ var AnthropicAdapter = class {
1540
1607
  const text = assistantText?.trim() ? assistantText : null;
1541
1608
  const wireMessage = {
1542
1609
  role: "assistant",
1543
- content: [
1544
- ...text ? [{ type: "text", text }] : [],
1545
- ...toolCalls.map((tc) => ({
1546
- type: "tool_use",
1547
- id: tc.id,
1548
- name: tc.name,
1549
- input: tc.arguments ?? {}
1550
- }))
1551
- ]
1610
+ content: assistantTurnContent(toolCalls, text)
1552
1611
  };
1553
1612
  return [
1554
1613
  ...history,
@@ -1640,6 +1699,62 @@ function markLastMessageForCaching(messages) {
1640
1699
  };
1641
1700
  }
1642
1701
  }
1702
+ function isThinkingBlockRejection(err) {
1703
+ const e = err;
1704
+ return e?.status === 400 && /`thinking` block/.test(String(e.message ?? ""));
1705
+ }
1706
+ function withoutThinking(messages) {
1707
+ let removed = false;
1708
+ const out = messages.map((m) => {
1709
+ const content = m.content;
1710
+ if (!Array.isArray(content)) return m;
1711
+ const kept = content.filter((b) => {
1712
+ const thinking = b?.type === "thinking" || b?.type === "redacted_thinking";
1713
+ if (thinking) removed = true;
1714
+ return !thinking;
1715
+ });
1716
+ return kept.length === content.length ? m : { ...m, content: kept };
1717
+ });
1718
+ return removed ? out : void 0;
1719
+ }
1720
+ function assistantTurnContent(toolCalls, text) {
1721
+ const recorded = recordedTurnOf(toolCalls);
1722
+ if (!recorded) {
1723
+ return [
1724
+ ...text ? [{ type: "text", text }] : [],
1725
+ ...toolCalls.map((tc) => ({
1726
+ type: "tool_use",
1727
+ id: tc.id,
1728
+ name: tc.name,
1729
+ input: tc.arguments ?? {}
1730
+ }))
1731
+ ];
1732
+ }
1733
+ const ids = new Set(toolCalls.map((tc) => tc.id));
1734
+ const content = recorded.filter(
1735
+ (b) => b.type !== "tool_use" || ids.has(b.id)
1736
+ );
1737
+ if (text && !content.some((b) => b.type === "text")) {
1738
+ const at = content.findIndex((b) => b.type === "tool_use");
1739
+ content.splice(at === -1 ? content.length : at, 0, { type: "text", text });
1740
+ }
1741
+ const known = new Set(
1742
+ content.flatMap((b) => b.type === "tool_use" ? [b.id] : [])
1743
+ );
1744
+ for (const tc of toolCalls) {
1745
+ if (!known.has(tc.id)) {
1746
+ content.push({ type: "tool_use", id: tc.id, name: tc.name, input: tc.arguments ?? {} });
1747
+ }
1748
+ }
1749
+ return content;
1750
+ }
1751
+ function recordedTurnOf(toolCalls) {
1752
+ for (const tc of toolCalls) {
1753
+ const raw = tc.vendorRaw;
1754
+ if (raw && Array.isArray(raw.content)) return raw.content;
1755
+ }
1756
+ return void 0;
1757
+ }
1643
1758
  function formatTools2(tools) {
1644
1759
  return tools.map((t) => ({
1645
1760
  name: t.name,
@@ -1657,6 +1772,8 @@ function mapStopReason(r, hadToolCalls) {
1657
1772
  return "tool";
1658
1773
  case "max_tokens":
1659
1774
  return "length";
1775
+ case "refusal":
1776
+ return "filtered";
1660
1777
  default:
1661
1778
  return "stop";
1662
1779
  }
@@ -3781,7 +3898,60 @@ var harnessManifest = {
3781
3898
  ],
3782
3899
  knownModels: [],
3783
3900
  supportsModelListing: false,
3784
- credentialOnly: true
3901
+ credentialOnly: true,
3902
+ category: "llm"
3903
+ };
3904
+
3905
+ // src/vendors/dialogflow-ces.ts
3906
+ var dialogflowCesManifest = {
3907
+ vendor: "dialogflow_ces",
3908
+ displayName: "Dialogflow CES",
3909
+ authKinds: [
3910
+ {
3911
+ kind: "googleServiceAccount",
3912
+ displayName: "Service Account JSON",
3913
+ fields: [
3914
+ {
3915
+ name: "credentials",
3916
+ label: "Service Account Key (JSON)",
3917
+ type: "json-file",
3918
+ required: true,
3919
+ help: "The key of a service account allowed to run your CES agents (Customer Engagement Suite)."
3920
+ }
3921
+ ]
3922
+ }
3923
+ ],
3924
+ knownModels: [],
3925
+ supportsModelListing: false,
3926
+ docsUrl: "https://cloud.google.com/customer-engagement-ai/conversational-agents/ps",
3927
+ credentialOnly: true,
3928
+ category: "hosted"
3929
+ };
3930
+
3931
+ // src/vendors/openai-s2s.ts
3932
+ var openaiS2sManifest = {
3933
+ vendor: "openai_s2s",
3934
+ displayName: "OpenAI Realtime",
3935
+ authKinds: [
3936
+ {
3937
+ kind: "apiKey",
3938
+ displayName: "API Key",
3939
+ fields: [
3940
+ {
3941
+ name: "apiKey",
3942
+ label: "API Key",
3943
+ type: "password",
3944
+ required: true,
3945
+ help: "An OpenAI API key with access to the Realtime API."
3946
+ }
3947
+ ]
3948
+ }
3949
+ ],
3950
+ knownModels: [],
3951
+ supportsModelListing: false,
3952
+ docsUrl: "https://platform.openai.com/docs/guides/realtime",
3953
+ credentialOnly: true,
3954
+ category: "s2s"
3785
3955
  };
3786
3956
 
3787
3957
  // src/adapters/index.ts
@@ -3802,6 +3972,8 @@ registerAdapter(groqFactory);
3802
3972
  registerAdapter(huggingfaceFactory);
3803
3973
  registerAdapter(openRouterFactory);
3804
3974
  registerCredentialVendor(harnessManifest);
3975
+ registerCredentialVendor(openaiS2sManifest);
3976
+ registerCredentialVendor(dialogflowCesManifest);
3805
3977
 
3806
3978
  // src/normalize-auth.ts
3807
3979
  function normalizeAuth(vendor, raw) {