@jambonz/llm 0.6.2 → 0.6.4

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-Y0o6rN3B.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-dbgrfviJ.cjs';
2
2
 
3
3
  /**
4
4
  * Named scenarios the harness must be able to stage. Each scenario configures
@@ -129,7 +129,7 @@ declare class FakeAdapter implements LlmAdapter<ApiKeyAuth> {
129
129
  constructor(state: FakeState);
130
130
  init(auth: ApiKeyAuth, _client?: ClientOptions): void;
131
131
  stream(req: PromptRequest): AsyncIterable<LlmEvent>;
132
- appendAssistantToolCall(history: Message[], toolCalls: ReadonlyArray<ToolCallEvent>): Message[];
132
+ appendAssistantToolCall(history: Message[], toolCalls: ReadonlyArray<ToolCallEvent>, assistantText?: string): Message[];
133
133
  appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[];
134
134
  listAvailableModels(): Promise<ModelInfo[]>;
135
135
  testCredential(): Promise<void>;
@@ -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-Y0o6rN3B.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-dbgrfviJ.js';
2
2
 
3
3
  /**
4
4
  * Named scenarios the harness must be able to stage. Each scenario configures
@@ -129,7 +129,7 @@ declare class FakeAdapter implements LlmAdapter<ApiKeyAuth> {
129
129
  constructor(state: FakeState);
130
130
  init(auth: ApiKeyAuth, _client?: ClientOptions): void;
131
131
  stream(req: PromptRequest): AsyncIterable<LlmEvent>;
132
- appendAssistantToolCall(history: Message[], toolCalls: ReadonlyArray<ToolCallEvent>): Message[];
132
+ appendAssistantToolCall(history: Message[], toolCalls: ReadonlyArray<ToolCallEvent>, assistantText?: string): Message[];
133
133
  appendToolResult(history: Message[], toolCallId: string, result: unknown): Message[];
134
134
  listAvailableModels(): Promise<ModelInfo[]>;
135
135
  testCredential(): Promise<void>;
@@ -232,10 +232,11 @@ async function* streamFromOpenAI(client, req, options) {
232
232
  }
233
233
  yield endEvent;
234
234
  }
235
- function appendOpenAIAssistantToolCall(history, toolCalls) {
235
+ function appendOpenAIAssistantToolCall(history, toolCalls, assistantText) {
236
+ const text = assistantText?.trim() ? assistantText : null;
236
237
  const wireMessage = {
237
238
  role: "assistant",
238
- content: null,
239
+ content: text,
239
240
  tool_calls: toolCalls.map((tc) => ({
240
241
  id: tc.id,
241
242
  type: "function",
@@ -249,7 +250,7 @@ function appendOpenAIAssistantToolCall(history, toolCalls) {
249
250
  ...history,
250
251
  {
251
252
  role: "assistant",
252
- content: "",
253
+ content: text ?? "",
253
254
  vendorRaw: wireMessage
254
255
  }
255
256
  ];
@@ -520,8 +521,8 @@ var OpenAIAdapter = class {
520
521
  includeCacheKey: this.forwardCacheKey()
521
522
  });
522
523
  }
523
- appendAssistantToolCall(history, toolCalls) {
524
- return appendOpenAIAssistantToolCall(history, toolCalls);
524
+ appendAssistantToolCall(history, toolCalls, assistantText) {
525
+ return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);
525
526
  }
526
527
  appendToolResult(history, toolCallId, result) {
527
528
  return appendOpenAIToolResult(history, toolCallId, result);
@@ -1487,21 +1488,25 @@ var AnthropicAdapter = class {
1487
1488
  }
1488
1489
  yield endEvent;
1489
1490
  }
1490
- appendAssistantToolCall(history, toolCalls) {
1491
+ appendAssistantToolCall(history, toolCalls, assistantText) {
1492
+ const text = assistantText?.trim() ? assistantText : null;
1491
1493
  const wireMessage = {
1492
1494
  role: "assistant",
1493
- content: toolCalls.map((tc) => ({
1494
- type: "tool_use",
1495
- id: tc.id,
1496
- name: tc.name,
1497
- input: tc.arguments ?? {}
1498
- }))
1495
+ content: [
1496
+ ...text ? [{ type: "text", text }] : [],
1497
+ ...toolCalls.map((tc) => ({
1498
+ type: "tool_use",
1499
+ id: tc.id,
1500
+ name: tc.name,
1501
+ input: tc.arguments ?? {}
1502
+ }))
1503
+ ]
1499
1504
  };
1500
1505
  return [
1501
1506
  ...history,
1502
1507
  {
1503
1508
  role: "assistant",
1504
- content: "",
1509
+ content: text ?? "",
1505
1510
  vendorRaw: wireMessage
1506
1511
  }
1507
1512
  ];
@@ -1753,21 +1758,25 @@ async function* streamFromGemini(client, req) {
1753
1758
  };
1754
1759
  yield endEvent;
1755
1760
  }
1756
- function appendGeminiAssistantToolCall(history, toolCalls) {
1761
+ function appendGeminiAssistantToolCall(history, toolCalls, assistantText) {
1762
+ const text = assistantText?.trim() ? assistantText : null;
1757
1763
  const wireMessage = {
1758
1764
  role: "model",
1759
- parts: toolCalls.map((tc) => ({
1760
- functionCall: {
1761
- name: parseToolName(tc.id),
1762
- args: tc.arguments ?? {}
1763
- }
1764
- }))
1765
+ parts: [
1766
+ ...text ? [{ text }] : [],
1767
+ ...toolCalls.map((tc) => ({
1768
+ functionCall: {
1769
+ name: parseToolName(tc.id),
1770
+ args: tc.arguments ?? {}
1771
+ }
1772
+ }))
1773
+ ]
1765
1774
  };
1766
1775
  return [
1767
1776
  ...history,
1768
1777
  {
1769
1778
  role: "assistant",
1770
- content: "",
1779
+ content: text ?? "",
1771
1780
  vendorRaw: wireMessage
1772
1781
  }
1773
1782
  ];
@@ -2027,8 +2036,8 @@ var GoogleAdapter = class {
2027
2036
  stream(req) {
2028
2037
  return streamFromGemini(this.ensureClient(), req);
2029
2038
  }
2030
- appendAssistantToolCall(history, toolCalls) {
2031
- return appendGeminiAssistantToolCall(history, toolCalls);
2039
+ appendAssistantToolCall(history, toolCalls, assistantText) {
2040
+ return appendGeminiAssistantToolCall(history, toolCalls, assistantText);
2032
2041
  }
2033
2042
  appendToolResult(history, toolCallId, result) {
2034
2043
  return appendGeminiToolResult(history, toolCallId, result);
@@ -2233,8 +2242,8 @@ var VertexGeminiAdapter = class {
2233
2242
  stream(req) {
2234
2243
  return streamFromGemini(this.ensureClient(), req);
2235
2244
  }
2236
- appendAssistantToolCall(history, toolCalls) {
2237
- return appendGeminiAssistantToolCall(history, toolCalls);
2245
+ appendAssistantToolCall(history, toolCalls, assistantText) {
2246
+ return appendGeminiAssistantToolCall(history, toolCalls, assistantText);
2238
2247
  }
2239
2248
  appendToolResult(history, toolCallId, result) {
2240
2249
  return appendGeminiToolResult(history, toolCallId, result);
@@ -2431,8 +2440,8 @@ var VertexOpenAIAdapter = class {
2431
2440
  vendorMetadataExtractor: VERTEX_OPENAI_METADATA_EXTRACTOR
2432
2441
  });
2433
2442
  }
2434
- appendAssistantToolCall(history, toolCalls) {
2435
- return appendOpenAIAssistantToolCall(history, toolCalls);
2443
+ appendAssistantToolCall(history, toolCalls, assistantText) {
2444
+ return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);
2436
2445
  }
2437
2446
  appendToolResult(history, toolCallId, result) {
2438
2447
  return appendOpenAIToolResult(history, toolCallId, result);
@@ -2783,11 +2792,12 @@ var BedrockAdapter = class {
2783
2792
  if (Object.keys(inferenceConfig).length > 0) {
2784
2793
  commandInput.inferenceConfig = inferenceConfig;
2785
2794
  }
2786
- if (req.cacheKey) {
2795
+ const caching = req.cacheKey ? cachePointSupport(req.model) : void 0;
2796
+ if (caching) {
2787
2797
  if (commandInput.system) {
2788
2798
  commandInput.system.push({ cachePoint: { type: "default" } });
2789
2799
  }
2790
- if (tools) {
2800
+ if (tools && caching.tools) {
2791
2801
  tools.tools.push({ cachePoint: { type: "default" } });
2792
2802
  }
2793
2803
  markLastMessageForCaching2(messages);
@@ -2924,22 +2934,26 @@ var BedrockAdapter = class {
2924
2934
  }
2925
2935
  yield endEvent;
2926
2936
  }
2927
- appendAssistantToolCall(history, toolCalls) {
2937
+ appendAssistantToolCall(history, toolCalls, assistantText) {
2938
+ const text = assistantText?.trim() ? assistantText : null;
2928
2939
  const wireMessage = {
2929
2940
  role: "assistant",
2930
- content: toolCalls.map((tc) => ({
2931
- toolUse: {
2932
- toolUseId: tc.id,
2933
- name: tc.name,
2934
- input: tc.arguments ?? {}
2935
- }
2936
- }))
2941
+ content: [
2942
+ ...text ? [{ text }] : [],
2943
+ ...toolCalls.map((tc) => ({
2944
+ toolUse: {
2945
+ toolUseId: tc.id,
2946
+ name: tc.name,
2947
+ input: tc.arguments ?? {}
2948
+ }
2949
+ }))
2950
+ ]
2937
2951
  };
2938
2952
  return [
2939
2953
  ...history,
2940
2954
  {
2941
2955
  role: "assistant",
2942
- content: "",
2956
+ content: text ?? "",
2943
2957
  vendorRaw: wireMessage
2944
2958
  }
2945
2959
  ];
@@ -3007,6 +3021,11 @@ function buildWireMessages3(req) {
3007
3021
  }
3008
3022
  return out;
3009
3023
  }
3024
+ function cachePointSupport(model) {
3025
+ if (model.includes("anthropic.claude")) return { tools: true };
3026
+ if (model.includes("amazon.nova")) return { tools: false };
3027
+ return void 0;
3028
+ }
3010
3029
  function markLastMessageForCaching2(messages) {
3011
3030
  if (messages.length === 0) return;
3012
3031
  const last = messages[messages.length - 1];
@@ -3229,8 +3248,8 @@ var AzureOpenAIAdapter = class {
3229
3248
  vendorMetadataExtractor: AZURE_OPENAI_METADATA_EXTRACTOR
3230
3249
  });
3231
3250
  }
3232
- appendAssistantToolCall(history, toolCalls) {
3233
- return appendOpenAIAssistantToolCall(history, toolCalls);
3251
+ appendAssistantToolCall(history, toolCalls, assistantText) {
3252
+ return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);
3234
3253
  }
3235
3254
  appendToolResult(history, toolCallId, result) {
3236
3255
  return appendOpenAIToolResult(history, toolCallId, result);
@@ -3885,6 +3904,55 @@ function runContractTests(harness) {
3885
3904
  expect(appended.role).toBe("assistant");
3886
3905
  expect(appended.vendorRaw).toBeDefined();
3887
3906
  });
3907
+ it("[22] appendAssistantToolCall carries pre-tool assistant text onto the wire", async () => {
3908
+ await harness.mockScenario("tool-call");
3909
+ const adapter = await init(harness);
3910
+ const first = await drainStream(adapter, {
3911
+ model: harness.toolCapableModel,
3912
+ messages: [{ role: "user", content: "go" }],
3913
+ tools: [
3914
+ { name: "test_tool", description: "x", parameters: { type: "object" } }
3915
+ ]
3916
+ });
3917
+ const tc = first.find(
3918
+ (e) => e.type === "toolCall"
3919
+ );
3920
+ expect(tc).toBeDefined();
3921
+ const preToolText = "Checking that now.";
3922
+ const history = adapter.appendAssistantToolCall(
3923
+ [{ role: "user", content: "go" }],
3924
+ [tc],
3925
+ preToolText
3926
+ );
3927
+ const appended = history[history.length - 1];
3928
+ expect(appended.content).toBe(preToolText);
3929
+ expect(JSON.stringify(appended.vendorRaw)).toContain(preToolText);
3930
+ });
3931
+ it("[23] appendAssistantToolCall omits empty pre-tool text from the wire", async () => {
3932
+ await harness.mockScenario("tool-call");
3933
+ const adapter = await init(harness);
3934
+ const first = await drainStream(adapter, {
3935
+ model: harness.toolCapableModel,
3936
+ messages: [{ role: "user", content: "go" }],
3937
+ tools: [
3938
+ { name: "test_tool", description: "x", parameters: { type: "object" } }
3939
+ ]
3940
+ });
3941
+ const tc = first.find(
3942
+ (e) => e.type === "toolCall"
3943
+ );
3944
+ expect(tc).toBeDefined();
3945
+ for (const blank of [void 0, "", " "]) {
3946
+ const history = adapter.appendAssistantToolCall(
3947
+ [{ role: "user", content: "go" }],
3948
+ [tc],
3949
+ blank
3950
+ );
3951
+ const appended = history[history.length - 1];
3952
+ expect(appended.content).toBe("");
3953
+ expect(JSON.stringify(appended.vendorRaw)).not.toContain('"text":""');
3954
+ }
3955
+ });
3888
3956
  });
3889
3957
  }
3890
3958
  async function init(harness) {
@@ -3949,13 +4017,15 @@ var FakeAdapter = class {
3949
4017
  throw new Error(`FakeAdapter: unknown scenario '${scenario}'`);
3950
4018
  }
3951
4019
  }
3952
- appendAssistantToolCall(history, toolCalls) {
4020
+ appendAssistantToolCall(history, toolCalls, assistantText) {
4021
+ const text = assistantText?.trim() ? assistantText : null;
3953
4022
  return [
3954
4023
  ...history,
3955
4024
  {
3956
4025
  role: "assistant",
3957
- content: "",
4026
+ content: text ?? "",
3958
4027
  vendorRaw: {
4028
+ ...text ? { text } : {},
3959
4029
  role: "assistant",
3960
4030
  toolCalls: toolCalls.map((tc) => ({
3961
4031
  id: tc.id,