@jambonz/llm 0.6.2 → 0.6.3

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);
@@ -2924,22 +2933,26 @@ var BedrockAdapter = class {
2924
2933
  }
2925
2934
  yield endEvent;
2926
2935
  }
2927
- appendAssistantToolCall(history, toolCalls) {
2936
+ appendAssistantToolCall(history, toolCalls, assistantText) {
2937
+ const text = assistantText?.trim() ? assistantText : null;
2928
2938
  const wireMessage = {
2929
2939
  role: "assistant",
2930
- content: toolCalls.map((tc) => ({
2931
- toolUse: {
2932
- toolUseId: tc.id,
2933
- name: tc.name,
2934
- input: tc.arguments ?? {}
2935
- }
2936
- }))
2940
+ content: [
2941
+ ...text ? [{ text }] : [],
2942
+ ...toolCalls.map((tc) => ({
2943
+ toolUse: {
2944
+ toolUseId: tc.id,
2945
+ name: tc.name,
2946
+ input: tc.arguments ?? {}
2947
+ }
2948
+ }))
2949
+ ]
2937
2950
  };
2938
2951
  return [
2939
2952
  ...history,
2940
2953
  {
2941
2954
  role: "assistant",
2942
- content: "",
2955
+ content: text ?? "",
2943
2956
  vendorRaw: wireMessage
2944
2957
  }
2945
2958
  ];
@@ -3229,8 +3242,8 @@ var AzureOpenAIAdapter = class {
3229
3242
  vendorMetadataExtractor: AZURE_OPENAI_METADATA_EXTRACTOR
3230
3243
  });
3231
3244
  }
3232
- appendAssistantToolCall(history, toolCalls) {
3233
- return appendOpenAIAssistantToolCall(history, toolCalls);
3245
+ appendAssistantToolCall(history, toolCalls, assistantText) {
3246
+ return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);
3234
3247
  }
3235
3248
  appendToolResult(history, toolCallId, result) {
3236
3249
  return appendOpenAIToolResult(history, toolCallId, result);
@@ -3885,6 +3898,55 @@ function runContractTests(harness) {
3885
3898
  expect(appended.role).toBe("assistant");
3886
3899
  expect(appended.vendorRaw).toBeDefined();
3887
3900
  });
3901
+ it("[22] appendAssistantToolCall carries pre-tool assistant text onto the wire", async () => {
3902
+ await harness.mockScenario("tool-call");
3903
+ const adapter = await init(harness);
3904
+ const first = await drainStream(adapter, {
3905
+ model: harness.toolCapableModel,
3906
+ messages: [{ role: "user", content: "go" }],
3907
+ tools: [
3908
+ { name: "test_tool", description: "x", parameters: { type: "object" } }
3909
+ ]
3910
+ });
3911
+ const tc = first.find(
3912
+ (e) => e.type === "toolCall"
3913
+ );
3914
+ expect(tc).toBeDefined();
3915
+ const preToolText = "Checking that now.";
3916
+ const history = adapter.appendAssistantToolCall(
3917
+ [{ role: "user", content: "go" }],
3918
+ [tc],
3919
+ preToolText
3920
+ );
3921
+ const appended = history[history.length - 1];
3922
+ expect(appended.content).toBe(preToolText);
3923
+ expect(JSON.stringify(appended.vendorRaw)).toContain(preToolText);
3924
+ });
3925
+ it("[23] appendAssistantToolCall omits empty pre-tool text from the wire", async () => {
3926
+ await harness.mockScenario("tool-call");
3927
+ const adapter = await init(harness);
3928
+ const first = await drainStream(adapter, {
3929
+ model: harness.toolCapableModel,
3930
+ messages: [{ role: "user", content: "go" }],
3931
+ tools: [
3932
+ { name: "test_tool", description: "x", parameters: { type: "object" } }
3933
+ ]
3934
+ });
3935
+ const tc = first.find(
3936
+ (e) => e.type === "toolCall"
3937
+ );
3938
+ expect(tc).toBeDefined();
3939
+ for (const blank of [void 0, "", " "]) {
3940
+ const history = adapter.appendAssistantToolCall(
3941
+ [{ role: "user", content: "go" }],
3942
+ [tc],
3943
+ blank
3944
+ );
3945
+ const appended = history[history.length - 1];
3946
+ expect(appended.content).toBe("");
3947
+ expect(JSON.stringify(appended.vendorRaw)).not.toContain('"text":""');
3948
+ }
3949
+ });
3888
3950
  });
3889
3951
  }
3890
3952
  async function init(harness) {
@@ -3949,13 +4011,15 @@ var FakeAdapter = class {
3949
4011
  throw new Error(`FakeAdapter: unknown scenario '${scenario}'`);
3950
4012
  }
3951
4013
  }
3952
- appendAssistantToolCall(history, toolCalls) {
4014
+ appendAssistantToolCall(history, toolCalls, assistantText) {
4015
+ const text = assistantText?.trim() ? assistantText : null;
3953
4016
  return [
3954
4017
  ...history,
3955
4018
  {
3956
4019
  role: "assistant",
3957
- content: "",
4020
+ content: text ?? "",
3958
4021
  vendorRaw: {
4022
+ ...text ? { text } : {},
3959
4023
  role: "assistant",
3960
4024
  toolCalls: toolCalls.map((tc) => ({
3961
4025
  id: tc.id,