@jambonz/llm 0.6.1 → 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.
- package/dist/index.cjs +163 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +163 -38
- package/dist/index.js.map +1 -1
- package/dist/test-kit/index.cjs +215 -40
- package/dist/test-kit/index.cjs.map +1 -1
- package/dist/test-kit/index.d.cts +2 -2
- package/dist/test-kit/index.d.ts +2 -2
- package/dist/test-kit/index.js +215 -40
- package/dist/test-kit/index.js.map +1 -1
- package/dist/{types-Y0o6rN3B.d.cts → types-dbgrfviJ.d.cts} +7 -1
- package/dist/{types-Y0o6rN3B.d.ts → types-dbgrfviJ.d.ts} +7 -1
- package/package.json +1 -1
package/dist/test-kit/index.cjs
CHANGED
|
@@ -271,10 +271,11 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
271
271
|
}
|
|
272
272
|
yield endEvent;
|
|
273
273
|
}
|
|
274
|
-
function appendOpenAIAssistantToolCall(history, toolCalls) {
|
|
274
|
+
function appendOpenAIAssistantToolCall(history, toolCalls, assistantText) {
|
|
275
|
+
const text = assistantText?.trim() ? assistantText : null;
|
|
275
276
|
const wireMessage = {
|
|
276
277
|
role: "assistant",
|
|
277
|
-
content:
|
|
278
|
+
content: text,
|
|
278
279
|
tool_calls: toolCalls.map((tc) => ({
|
|
279
280
|
id: tc.id,
|
|
280
281
|
type: "function",
|
|
@@ -288,7 +289,7 @@ function appendOpenAIAssistantToolCall(history, toolCalls) {
|
|
|
288
289
|
...history,
|
|
289
290
|
{
|
|
290
291
|
role: "assistant",
|
|
291
|
-
content: "",
|
|
292
|
+
content: text ?? "",
|
|
292
293
|
vendorRaw: wireMessage
|
|
293
294
|
}
|
|
294
295
|
];
|
|
@@ -559,8 +560,8 @@ var OpenAIAdapter = class {
|
|
|
559
560
|
includeCacheKey: this.forwardCacheKey()
|
|
560
561
|
});
|
|
561
562
|
}
|
|
562
|
-
appendAssistantToolCall(history, toolCalls) {
|
|
563
|
-
return appendOpenAIAssistantToolCall(history, toolCalls);
|
|
563
|
+
appendAssistantToolCall(history, toolCalls, assistantText) {
|
|
564
|
+
return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);
|
|
564
565
|
}
|
|
565
566
|
appendToolResult(history, toolCallId, result) {
|
|
566
567
|
return appendOpenAIToolResult(history, toolCallId, result);
|
|
@@ -1121,6 +1122,116 @@ var xaiFactory = {
|
|
|
1121
1122
|
manifest: xaiManifest,
|
|
1122
1123
|
create: () => new XaiAdapter()
|
|
1123
1124
|
};
|
|
1125
|
+
var BEDROCK_MANTLE_DEFAULT_BASE_URL = "https://bedrock-mantle.us-east-1.api.aws/v1";
|
|
1126
|
+
var bedrockMantleManifest = {
|
|
1127
|
+
vendor: "bedrock-mantle",
|
|
1128
|
+
displayName: "AWS Bedrock (OpenAI-compatible)",
|
|
1129
|
+
authKinds: [
|
|
1130
|
+
{
|
|
1131
|
+
kind: "apiKey",
|
|
1132
|
+
displayName: "API Key",
|
|
1133
|
+
fields: [
|
|
1134
|
+
{
|
|
1135
|
+
name: "apiKey",
|
|
1136
|
+
label: "Bedrock API Key",
|
|
1137
|
+
type: "password",
|
|
1138
|
+
required: true,
|
|
1139
|
+
help: "Generate a long-term Bedrock API key in the AWS console (Amazon Bedrock \u2192 API keys)."
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
name: "baseURL",
|
|
1143
|
+
label: "Base URL",
|
|
1144
|
+
type: "url",
|
|
1145
|
+
required: false,
|
|
1146
|
+
default: BEDROCK_MANTLE_DEFAULT_BASE_URL,
|
|
1147
|
+
help: "Change the region to match your key. xAI models are served only on the /openai/v1 path."
|
|
1148
|
+
}
|
|
1149
|
+
]
|
|
1150
|
+
}
|
|
1151
|
+
],
|
|
1152
|
+
/* A convenience seed, NOT the source of truth: the live `/v1/models`
|
|
1153
|
+
* endpoint is authoritative and grows continuously, which is why
|
|
1154
|
+
* `supportsModelListing` is true. Any model the endpoint lists can be used
|
|
1155
|
+
* by id without appearing here.
|
|
1156
|
+
*
|
|
1157
|
+
* AWS publishes no context-window metadata (neither `/v1/models` nor
|
|
1158
|
+
* `GetFoundationModel` returns it), so these limits are carried over from
|
|
1159
|
+
* the native-vendor manifests above for the same underlying models. Vision
|
|
1160
|
+
* follows Bedrock's `inputModalities`. */
|
|
1161
|
+
knownModels: [
|
|
1162
|
+
{
|
|
1163
|
+
id: "zai.glm-5",
|
|
1164
|
+
displayName: "GLM 5",
|
|
1165
|
+
capabilities: {
|
|
1166
|
+
streaming: true,
|
|
1167
|
+
tools: true,
|
|
1168
|
+
vision: false,
|
|
1169
|
+
systemPrompt: true,
|
|
1170
|
+
maxContextTokens: 202800
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
id: "zai.glm-4.7",
|
|
1175
|
+
displayName: "GLM 4.7",
|
|
1176
|
+
capabilities: {
|
|
1177
|
+
streaming: true,
|
|
1178
|
+
tools: true,
|
|
1179
|
+
vision: false,
|
|
1180
|
+
systemPrompt: true,
|
|
1181
|
+
maxContextTokens: 2e5
|
|
1182
|
+
}
|
|
1183
|
+
},
|
|
1184
|
+
{
|
|
1185
|
+
id: "moonshotai.kimi-k2.5",
|
|
1186
|
+
displayName: "Kimi K2.5",
|
|
1187
|
+
capabilities: {
|
|
1188
|
+
streaming: true,
|
|
1189
|
+
tools: true,
|
|
1190
|
+
vision: true,
|
|
1191
|
+
systemPrompt: true,
|
|
1192
|
+
maxContextTokens: 262144
|
|
1193
|
+
}
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
id: "xai.grok-4.3",
|
|
1197
|
+
displayName: "Grok 4.3",
|
|
1198
|
+
capabilities: {
|
|
1199
|
+
streaming: true,
|
|
1200
|
+
tools: true,
|
|
1201
|
+
vision: true,
|
|
1202
|
+
systemPrompt: true,
|
|
1203
|
+
maxContextTokens: 1e6
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
],
|
|
1207
|
+
supportsModelListing: true,
|
|
1208
|
+
docsUrl: "https://docs.aws.amazon.com/bedrock/latest/userguide/inference-chat-completions.html"
|
|
1209
|
+
};
|
|
1210
|
+
var BedrockMantleAdapter = class extends OpenAIAdapter {
|
|
1211
|
+
vendor = bedrockMantleManifest.vendor;
|
|
1212
|
+
init(auth, client) {
|
|
1213
|
+
super.init(
|
|
1214
|
+
{
|
|
1215
|
+
...auth,
|
|
1216
|
+
baseURL: auth.baseURL ?? BEDROCK_MANTLE_DEFAULT_BASE_URL
|
|
1217
|
+
},
|
|
1218
|
+
client
|
|
1219
|
+
);
|
|
1220
|
+
}
|
|
1221
|
+
knownModels() {
|
|
1222
|
+
return bedrockMantleManifest.knownModels;
|
|
1223
|
+
}
|
|
1224
|
+
// Mantle fronts many third-party runtimes with differing param strictness,
|
|
1225
|
+
// and prompt_cache_key is unverified against all of them — do not forward.
|
|
1226
|
+
forwardCacheKey() {
|
|
1227
|
+
return false;
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
var bedrockMantleFactory = {
|
|
1231
|
+
vendor: bedrockMantleManifest.vendor,
|
|
1232
|
+
manifest: bedrockMantleManifest,
|
|
1233
|
+
create: () => new BedrockMantleAdapter()
|
|
1234
|
+
};
|
|
1124
1235
|
|
|
1125
1236
|
// src/adapters/anthropic/adapter.ts
|
|
1126
1237
|
var import_sdk = __toESM(require("@anthropic-ai/sdk"), 1);
|
|
@@ -1416,21 +1527,25 @@ var AnthropicAdapter = class {
|
|
|
1416
1527
|
}
|
|
1417
1528
|
yield endEvent;
|
|
1418
1529
|
}
|
|
1419
|
-
appendAssistantToolCall(history, toolCalls) {
|
|
1530
|
+
appendAssistantToolCall(history, toolCalls, assistantText) {
|
|
1531
|
+
const text = assistantText?.trim() ? assistantText : null;
|
|
1420
1532
|
const wireMessage = {
|
|
1421
1533
|
role: "assistant",
|
|
1422
|
-
content:
|
|
1423
|
-
type: "
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1534
|
+
content: [
|
|
1535
|
+
...text ? [{ type: "text", text }] : [],
|
|
1536
|
+
...toolCalls.map((tc) => ({
|
|
1537
|
+
type: "tool_use",
|
|
1538
|
+
id: tc.id,
|
|
1539
|
+
name: tc.name,
|
|
1540
|
+
input: tc.arguments ?? {}
|
|
1541
|
+
}))
|
|
1542
|
+
]
|
|
1428
1543
|
};
|
|
1429
1544
|
return [
|
|
1430
1545
|
...history,
|
|
1431
1546
|
{
|
|
1432
1547
|
role: "assistant",
|
|
1433
|
-
content: "",
|
|
1548
|
+
content: text ?? "",
|
|
1434
1549
|
vendorRaw: wireMessage
|
|
1435
1550
|
}
|
|
1436
1551
|
];
|
|
@@ -1682,21 +1797,25 @@ async function* streamFromGemini(client, req) {
|
|
|
1682
1797
|
};
|
|
1683
1798
|
yield endEvent;
|
|
1684
1799
|
}
|
|
1685
|
-
function appendGeminiAssistantToolCall(history, toolCalls) {
|
|
1800
|
+
function appendGeminiAssistantToolCall(history, toolCalls, assistantText) {
|
|
1801
|
+
const text = assistantText?.trim() ? assistantText : null;
|
|
1686
1802
|
const wireMessage = {
|
|
1687
1803
|
role: "model",
|
|
1688
|
-
parts:
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1804
|
+
parts: [
|
|
1805
|
+
...text ? [{ text }] : [],
|
|
1806
|
+
...toolCalls.map((tc) => ({
|
|
1807
|
+
functionCall: {
|
|
1808
|
+
name: parseToolName(tc.id),
|
|
1809
|
+
args: tc.arguments ?? {}
|
|
1810
|
+
}
|
|
1811
|
+
}))
|
|
1812
|
+
]
|
|
1694
1813
|
};
|
|
1695
1814
|
return [
|
|
1696
1815
|
...history,
|
|
1697
1816
|
{
|
|
1698
1817
|
role: "assistant",
|
|
1699
|
-
content: "",
|
|
1818
|
+
content: text ?? "",
|
|
1700
1819
|
vendorRaw: wireMessage
|
|
1701
1820
|
}
|
|
1702
1821
|
];
|
|
@@ -1956,8 +2075,8 @@ var GoogleAdapter = class {
|
|
|
1956
2075
|
stream(req) {
|
|
1957
2076
|
return streamFromGemini(this.ensureClient(), req);
|
|
1958
2077
|
}
|
|
1959
|
-
appendAssistantToolCall(history, toolCalls) {
|
|
1960
|
-
return appendGeminiAssistantToolCall(history, toolCalls);
|
|
2078
|
+
appendAssistantToolCall(history, toolCalls, assistantText) {
|
|
2079
|
+
return appendGeminiAssistantToolCall(history, toolCalls, assistantText);
|
|
1961
2080
|
}
|
|
1962
2081
|
appendToolResult(history, toolCallId, result) {
|
|
1963
2082
|
return appendGeminiToolResult(history, toolCallId, result);
|
|
@@ -2162,8 +2281,8 @@ var VertexGeminiAdapter = class {
|
|
|
2162
2281
|
stream(req) {
|
|
2163
2282
|
return streamFromGemini(this.ensureClient(), req);
|
|
2164
2283
|
}
|
|
2165
|
-
appendAssistantToolCall(history, toolCalls) {
|
|
2166
|
-
return appendGeminiAssistantToolCall(history, toolCalls);
|
|
2284
|
+
appendAssistantToolCall(history, toolCalls, assistantText) {
|
|
2285
|
+
return appendGeminiAssistantToolCall(history, toolCalls, assistantText);
|
|
2167
2286
|
}
|
|
2168
2287
|
appendToolResult(history, toolCallId, result) {
|
|
2169
2288
|
return appendGeminiToolResult(history, toolCallId, result);
|
|
@@ -2360,8 +2479,8 @@ var VertexOpenAIAdapter = class {
|
|
|
2360
2479
|
vendorMetadataExtractor: VERTEX_OPENAI_METADATA_EXTRACTOR
|
|
2361
2480
|
});
|
|
2362
2481
|
}
|
|
2363
|
-
appendAssistantToolCall(history, toolCalls) {
|
|
2364
|
-
return appendOpenAIAssistantToolCall(history, toolCalls);
|
|
2482
|
+
appendAssistantToolCall(history, toolCalls, assistantText) {
|
|
2483
|
+
return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);
|
|
2365
2484
|
}
|
|
2366
2485
|
appendToolResult(history, toolCallId, result) {
|
|
2367
2486
|
return appendOpenAIToolResult(history, toolCallId, result);
|
|
@@ -2847,22 +2966,26 @@ var BedrockAdapter = class {
|
|
|
2847
2966
|
}
|
|
2848
2967
|
yield endEvent;
|
|
2849
2968
|
}
|
|
2850
|
-
appendAssistantToolCall(history, toolCalls) {
|
|
2969
|
+
appendAssistantToolCall(history, toolCalls, assistantText) {
|
|
2970
|
+
const text = assistantText?.trim() ? assistantText : null;
|
|
2851
2971
|
const wireMessage = {
|
|
2852
2972
|
role: "assistant",
|
|
2853
|
-
content:
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2973
|
+
content: [
|
|
2974
|
+
...text ? [{ text }] : [],
|
|
2975
|
+
...toolCalls.map((tc) => ({
|
|
2976
|
+
toolUse: {
|
|
2977
|
+
toolUseId: tc.id,
|
|
2978
|
+
name: tc.name,
|
|
2979
|
+
input: tc.arguments ?? {}
|
|
2980
|
+
}
|
|
2981
|
+
}))
|
|
2982
|
+
]
|
|
2860
2983
|
};
|
|
2861
2984
|
return [
|
|
2862
2985
|
...history,
|
|
2863
2986
|
{
|
|
2864
2987
|
role: "assistant",
|
|
2865
|
-
content: "",
|
|
2988
|
+
content: text ?? "",
|
|
2866
2989
|
vendorRaw: wireMessage
|
|
2867
2990
|
}
|
|
2868
2991
|
];
|
|
@@ -3152,8 +3275,8 @@ var AzureOpenAIAdapter = class {
|
|
|
3152
3275
|
vendorMetadataExtractor: AZURE_OPENAI_METADATA_EXTRACTOR
|
|
3153
3276
|
});
|
|
3154
3277
|
}
|
|
3155
|
-
appendAssistantToolCall(history, toolCalls) {
|
|
3156
|
-
return appendOpenAIAssistantToolCall(history, toolCalls);
|
|
3278
|
+
appendAssistantToolCall(history, toolCalls, assistantText) {
|
|
3279
|
+
return appendOpenAIAssistantToolCall(history, toolCalls, assistantText);
|
|
3157
3280
|
}
|
|
3158
3281
|
appendToolResult(history, toolCallId, result) {
|
|
3159
3282
|
return appendOpenAIToolResult(history, toolCallId, result);
|
|
@@ -3441,6 +3564,7 @@ registerAdapter(basetenFactory);
|
|
|
3441
3564
|
registerAdapter(moonshotFactory);
|
|
3442
3565
|
registerAdapter(zaiFactory);
|
|
3443
3566
|
registerAdapter(xaiFactory);
|
|
3567
|
+
registerAdapter(bedrockMantleFactory);
|
|
3444
3568
|
registerAdapter(anthropicFactory);
|
|
3445
3569
|
registerAdapter(googleFactory);
|
|
3446
3570
|
registerAdapter(vertexGeminiFactory);
|
|
@@ -3807,6 +3931,55 @@ function runContractTests(harness) {
|
|
|
3807
3931
|
(0, import_vitest.expect)(appended.role).toBe("assistant");
|
|
3808
3932
|
(0, import_vitest.expect)(appended.vendorRaw).toBeDefined();
|
|
3809
3933
|
});
|
|
3934
|
+
(0, import_vitest.it)("[22] appendAssistantToolCall carries pre-tool assistant text onto the wire", async () => {
|
|
3935
|
+
await harness.mockScenario("tool-call");
|
|
3936
|
+
const adapter = await init(harness);
|
|
3937
|
+
const first = await drainStream(adapter, {
|
|
3938
|
+
model: harness.toolCapableModel,
|
|
3939
|
+
messages: [{ role: "user", content: "go" }],
|
|
3940
|
+
tools: [
|
|
3941
|
+
{ name: "test_tool", description: "x", parameters: { type: "object" } }
|
|
3942
|
+
]
|
|
3943
|
+
});
|
|
3944
|
+
const tc = first.find(
|
|
3945
|
+
(e) => e.type === "toolCall"
|
|
3946
|
+
);
|
|
3947
|
+
(0, import_vitest.expect)(tc).toBeDefined();
|
|
3948
|
+
const preToolText = "Checking that now.";
|
|
3949
|
+
const history = adapter.appendAssistantToolCall(
|
|
3950
|
+
[{ role: "user", content: "go" }],
|
|
3951
|
+
[tc],
|
|
3952
|
+
preToolText
|
|
3953
|
+
);
|
|
3954
|
+
const appended = history[history.length - 1];
|
|
3955
|
+
(0, import_vitest.expect)(appended.content).toBe(preToolText);
|
|
3956
|
+
(0, import_vitest.expect)(JSON.stringify(appended.vendorRaw)).toContain(preToolText);
|
|
3957
|
+
});
|
|
3958
|
+
(0, import_vitest.it)("[23] appendAssistantToolCall omits empty pre-tool text from the wire", async () => {
|
|
3959
|
+
await harness.mockScenario("tool-call");
|
|
3960
|
+
const adapter = await init(harness);
|
|
3961
|
+
const first = await drainStream(adapter, {
|
|
3962
|
+
model: harness.toolCapableModel,
|
|
3963
|
+
messages: [{ role: "user", content: "go" }],
|
|
3964
|
+
tools: [
|
|
3965
|
+
{ name: "test_tool", description: "x", parameters: { type: "object" } }
|
|
3966
|
+
]
|
|
3967
|
+
});
|
|
3968
|
+
const tc = first.find(
|
|
3969
|
+
(e) => e.type === "toolCall"
|
|
3970
|
+
);
|
|
3971
|
+
(0, import_vitest.expect)(tc).toBeDefined();
|
|
3972
|
+
for (const blank of [void 0, "", " "]) {
|
|
3973
|
+
const history = adapter.appendAssistantToolCall(
|
|
3974
|
+
[{ role: "user", content: "go" }],
|
|
3975
|
+
[tc],
|
|
3976
|
+
blank
|
|
3977
|
+
);
|
|
3978
|
+
const appended = history[history.length - 1];
|
|
3979
|
+
(0, import_vitest.expect)(appended.content).toBe("");
|
|
3980
|
+
(0, import_vitest.expect)(JSON.stringify(appended.vendorRaw)).not.toContain('"text":""');
|
|
3981
|
+
}
|
|
3982
|
+
});
|
|
3810
3983
|
});
|
|
3811
3984
|
}
|
|
3812
3985
|
async function init(harness) {
|
|
@@ -3871,13 +4044,15 @@ var FakeAdapter = class {
|
|
|
3871
4044
|
throw new Error(`FakeAdapter: unknown scenario '${scenario}'`);
|
|
3872
4045
|
}
|
|
3873
4046
|
}
|
|
3874
|
-
appendAssistantToolCall(history, toolCalls) {
|
|
4047
|
+
appendAssistantToolCall(history, toolCalls, assistantText) {
|
|
4048
|
+
const text = assistantText?.trim() ? assistantText : null;
|
|
3875
4049
|
return [
|
|
3876
4050
|
...history,
|
|
3877
4051
|
{
|
|
3878
4052
|
role: "assistant",
|
|
3879
|
-
content: "",
|
|
4053
|
+
content: text ?? "",
|
|
3880
4054
|
vendorRaw: {
|
|
4055
|
+
...text ? { text } : {},
|
|
3881
4056
|
role: "assistant",
|
|
3882
4057
|
toolCalls: toolCalls.map((tc) => ({
|
|
3883
4058
|
id: tc.id,
|