@jambonz/llm 0.5.7 → 0.6.0
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 +156 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +156 -7
- package/dist/index.js.map +1 -1
- package/dist/test-kit/index.cjs +156 -7
- package/dist/test-kit/index.cjs.map +1 -1
- package/dist/test-kit/index.d.cts +1 -1
- package/dist/test-kit/index.d.ts +1 -1
- package/dist/test-kit/index.js +156 -7
- package/dist/test-kit/index.js.map +1 -1
- package/dist/{types-rZZBXYhB.d.cts → types-Y0o6rN3B.d.cts} +35 -0
- package/dist/{types-rZZBXYhB.d.ts → types-Y0o6rN3B.d.ts} +35 -0
- package/package.json +1 -1
package/dist/test-kit/index.cjs
CHANGED
|
@@ -88,6 +88,9 @@ function assertValidRequest(req) {
|
|
|
88
88
|
"PromptRequest.messages must not contain role: 'system'. Pass the system prompt via PromptRequest.system instead."
|
|
89
89
|
);
|
|
90
90
|
}
|
|
91
|
+
if (req.cacheKey !== void 0 && (typeof req.cacheKey !== "string" || req.cacheKey.length === 0)) {
|
|
92
|
+
throw new Error("PromptRequest.cacheKey must be a non-empty string");
|
|
93
|
+
}
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
// src/adapters/openai/_streaming.ts
|
|
@@ -112,6 +115,9 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
112
115
|
body.tool_choice = "auto";
|
|
113
116
|
}
|
|
114
117
|
if (req.temperature !== void 0) body.temperature = req.temperature;
|
|
118
|
+
if (req.cacheKey && options.includeCacheKey !== false) {
|
|
119
|
+
body.prompt_cache_key = req.cacheKey;
|
|
120
|
+
}
|
|
115
121
|
const effectiveMaxTokens = req.maxTokens ?? options.defaultMaxTokens;
|
|
116
122
|
if (effectiveMaxTokens !== void 0) {
|
|
117
123
|
const param = options.tokensParam ?? (needsMaxCompletionTokens(req.model) ? "max_completion_tokens" : "max_tokens");
|
|
@@ -165,10 +171,12 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
165
171
|
throw new Error(`OpenAI-compatible stream returned an error: ${message}`);
|
|
166
172
|
}
|
|
167
173
|
if (chunk.usage) {
|
|
174
|
+
const cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens;
|
|
168
175
|
usage = {
|
|
169
|
-
...chunk.usage.prompt_tokens !== void 0 ? { inputTokens: chunk.usage.prompt_tokens } : {},
|
|
176
|
+
...chunk.usage.prompt_tokens !== void 0 ? { inputTokens: chunk.usage.prompt_tokens - (cachedTokens ?? 0) } : {},
|
|
170
177
|
...chunk.usage.completion_tokens !== void 0 ? { outputTokens: chunk.usage.completion_tokens } : {},
|
|
171
|
-
...chunk.usage.total_tokens !== void 0 ? { totalTokens: chunk.usage.total_tokens } : {}
|
|
178
|
+
...chunk.usage.total_tokens !== void 0 ? { totalTokens: chunk.usage.total_tokens } : {},
|
|
179
|
+
...cachedTokens !== void 0 ? { cacheReadTokens: cachedTokens } : {}
|
|
172
180
|
};
|
|
173
181
|
}
|
|
174
182
|
const choice = chunk.choices?.[0];
|
|
@@ -1221,6 +1229,16 @@ var AnthropicAdapter = class {
|
|
|
1221
1229
|
if (req.system) body.system = req.system;
|
|
1222
1230
|
if (tools) body.tools = tools;
|
|
1223
1231
|
if (req.temperature !== void 0) body.temperature = req.temperature;
|
|
1232
|
+
if (req.cacheKey) {
|
|
1233
|
+
if (req.system) {
|
|
1234
|
+
body.system = [{ type: "text", text: req.system, cache_control: { type: "ephemeral" } }];
|
|
1235
|
+
}
|
|
1236
|
+
if (tools) {
|
|
1237
|
+
const lastTool = tools[tools.length - 1];
|
|
1238
|
+
lastTool.cache_control = { type: "ephemeral" };
|
|
1239
|
+
}
|
|
1240
|
+
markLastMessageForCaching(messages);
|
|
1241
|
+
}
|
|
1224
1242
|
let stream;
|
|
1225
1243
|
let responseHeaders;
|
|
1226
1244
|
try {
|
|
@@ -1248,6 +1266,8 @@ var AnthropicAdapter = class {
|
|
|
1248
1266
|
let stopReason;
|
|
1249
1267
|
let inputTokens;
|
|
1250
1268
|
let outputTokens;
|
|
1269
|
+
let cacheReadTokens;
|
|
1270
|
+
let cacheWriteTokens;
|
|
1251
1271
|
try {
|
|
1252
1272
|
for await (const event of stream) {
|
|
1253
1273
|
if (req.signal?.aborted) {
|
|
@@ -1257,6 +1277,8 @@ var AnthropicAdapter = class {
|
|
|
1257
1277
|
switch (event.type) {
|
|
1258
1278
|
case "message_start":
|
|
1259
1279
|
inputTokens = event.message?.usage?.input_tokens;
|
|
1280
|
+
cacheReadTokens = event.message?.usage?.cache_read_input_tokens;
|
|
1281
|
+
cacheWriteTokens = event.message?.usage?.cache_creation_input_tokens;
|
|
1260
1282
|
break;
|
|
1261
1283
|
case "content_block_start": {
|
|
1262
1284
|
const block = event.content_block;
|
|
@@ -1338,7 +1360,11 @@ var AnthropicAdapter = class {
|
|
|
1338
1360
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 ? {
|
|
1339
1361
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
1340
1362
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
1341
|
-
...inputTokens !== void 0 && outputTokens !== void 0 ? {
|
|
1363
|
+
...inputTokens !== void 0 && outputTokens !== void 0 ? {
|
|
1364
|
+
totalTokens: inputTokens + outputTokens + (cacheReadTokens ?? 0) + (cacheWriteTokens ?? 0)
|
|
1365
|
+
} : {},
|
|
1366
|
+
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {},
|
|
1367
|
+
...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {}
|
|
1342
1368
|
} : void 0;
|
|
1343
1369
|
const endEvent = {
|
|
1344
1370
|
type: "end",
|
|
@@ -1437,6 +1463,23 @@ function buildWireMessages2(req) {
|
|
|
1437
1463
|
}
|
|
1438
1464
|
return out;
|
|
1439
1465
|
}
|
|
1466
|
+
function markLastMessageForCaching(messages) {
|
|
1467
|
+
if (messages.length === 0) return;
|
|
1468
|
+
const last = messages[messages.length - 1];
|
|
1469
|
+
const cacheControl = { cache_control: { type: "ephemeral" } };
|
|
1470
|
+
if (typeof last.content === "string" && last.content.length > 0) {
|
|
1471
|
+
messages[messages.length - 1] = {
|
|
1472
|
+
...last,
|
|
1473
|
+
content: [{ type: "text", text: last.content, ...cacheControl }]
|
|
1474
|
+
};
|
|
1475
|
+
} else if (Array.isArray(last.content) && last.content.length > 0) {
|
|
1476
|
+
const blocks = last.content;
|
|
1477
|
+
messages[messages.length - 1] = {
|
|
1478
|
+
...last,
|
|
1479
|
+
content: [...blocks.slice(0, -1), { ...blocks[blocks.length - 1], ...cacheControl }]
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1440
1483
|
function formatTools2(tools) {
|
|
1441
1484
|
return tools.map((t) => ({
|
|
1442
1485
|
name: t.name,
|
|
@@ -1499,6 +1542,11 @@ async function* streamFromGemini(client, req) {
|
|
|
1499
1542
|
if (req.temperature !== void 0) config.temperature = req.temperature;
|
|
1500
1543
|
if (req.maxTokens !== void 0) config.maxOutputTokens = req.maxTokens;
|
|
1501
1544
|
if (req.signal) config.abortSignal = req.signal;
|
|
1545
|
+
if (req.providerParams) {
|
|
1546
|
+
for (const [key, value] of Object.entries(req.providerParams)) {
|
|
1547
|
+
if (!(key in config)) config[key] = value;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1502
1550
|
let stream;
|
|
1503
1551
|
try {
|
|
1504
1552
|
stream = await client.models.generateContentStream({
|
|
@@ -1519,6 +1567,7 @@ async function* streamFromGemini(client, req) {
|
|
|
1519
1567
|
let inputTokens;
|
|
1520
1568
|
let outputTokens;
|
|
1521
1569
|
let totalTokens;
|
|
1570
|
+
let cacheReadTokens;
|
|
1522
1571
|
try {
|
|
1523
1572
|
for await (const chunk of stream) {
|
|
1524
1573
|
if (req.signal?.aborted) {
|
|
@@ -1527,7 +1576,12 @@ async function* streamFromGemini(client, req) {
|
|
|
1527
1576
|
}
|
|
1528
1577
|
const usage2 = chunk.usageMetadata;
|
|
1529
1578
|
if (usage2) {
|
|
1530
|
-
if (usage2.
|
|
1579
|
+
if (usage2.cachedContentTokenCount !== void 0) {
|
|
1580
|
+
cacheReadTokens = usage2.cachedContentTokenCount;
|
|
1581
|
+
}
|
|
1582
|
+
if (usage2.promptTokenCount !== void 0) {
|
|
1583
|
+
inputTokens = usage2.promptTokenCount - (usage2.cachedContentTokenCount ?? 0);
|
|
1584
|
+
}
|
|
1531
1585
|
if (usage2.candidatesTokenCount !== void 0) outputTokens = usage2.candidatesTokenCount;
|
|
1532
1586
|
if (usage2.totalTokenCount !== void 0) totalTokens = usage2.totalTokenCount;
|
|
1533
1587
|
}
|
|
@@ -1581,7 +1635,8 @@ async function* streamFromGemini(client, req) {
|
|
|
1581
1635
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 || totalTokens !== void 0 ? {
|
|
1582
1636
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
1583
1637
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
1584
|
-
...totalTokens !== void 0 ? { totalTokens } : {}
|
|
1638
|
+
...totalTokens !== void 0 ? { totalTokens } : {},
|
|
1639
|
+
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {}
|
|
1585
1640
|
} : void 0;
|
|
1586
1641
|
const endEvent = {
|
|
1587
1642
|
type: "end",
|
|
@@ -1723,6 +1778,39 @@ function isAbortError3(err) {
|
|
|
1723
1778
|
|
|
1724
1779
|
// src/adapters/google/manifest.ts
|
|
1725
1780
|
var GOOGLE_KNOWN_MODELS = [
|
|
1781
|
+
{
|
|
1782
|
+
id: "gemini-3.6-flash",
|
|
1783
|
+
displayName: "Gemini 3.6 Flash",
|
|
1784
|
+
capabilities: {
|
|
1785
|
+
streaming: true,
|
|
1786
|
+
tools: true,
|
|
1787
|
+
vision: true,
|
|
1788
|
+
systemPrompt: true,
|
|
1789
|
+
maxContextTokens: 1e6
|
|
1790
|
+
}
|
|
1791
|
+
},
|
|
1792
|
+
{
|
|
1793
|
+
id: "gemini-3.5-flash",
|
|
1794
|
+
displayName: "Gemini 3.5 Flash",
|
|
1795
|
+
capabilities: {
|
|
1796
|
+
streaming: true,
|
|
1797
|
+
tools: true,
|
|
1798
|
+
vision: true,
|
|
1799
|
+
systemPrompt: true,
|
|
1800
|
+
maxContextTokens: 1e6
|
|
1801
|
+
}
|
|
1802
|
+
},
|
|
1803
|
+
{
|
|
1804
|
+
id: "gemini-3.5-flash-lite",
|
|
1805
|
+
displayName: "Gemini 3.5 Flash-Lite",
|
|
1806
|
+
capabilities: {
|
|
1807
|
+
streaming: true,
|
|
1808
|
+
tools: true,
|
|
1809
|
+
vision: true,
|
|
1810
|
+
systemPrompt: true,
|
|
1811
|
+
maxContextTokens: 1e6
|
|
1812
|
+
}
|
|
1813
|
+
},
|
|
1726
1814
|
{
|
|
1727
1815
|
id: "gemini-2.5-pro",
|
|
1728
1816
|
displayName: "Gemini 2.5 Pro",
|
|
@@ -1866,6 +1954,39 @@ var import_genai2 = require("@google/genai");
|
|
|
1866
1954
|
|
|
1867
1955
|
// src/adapters/vertex-gemini/manifest.ts
|
|
1868
1956
|
var VERTEX_GEMINI_KNOWN_MODELS = [
|
|
1957
|
+
{
|
|
1958
|
+
id: "gemini-3.6-flash",
|
|
1959
|
+
displayName: "Gemini 3.6 Flash",
|
|
1960
|
+
capabilities: {
|
|
1961
|
+
streaming: true,
|
|
1962
|
+
tools: true,
|
|
1963
|
+
vision: true,
|
|
1964
|
+
systemPrompt: true,
|
|
1965
|
+
maxContextTokens: 1e6
|
|
1966
|
+
}
|
|
1967
|
+
},
|
|
1968
|
+
{
|
|
1969
|
+
id: "gemini-3.5-flash",
|
|
1970
|
+
displayName: "Gemini 3.5 Flash",
|
|
1971
|
+
capabilities: {
|
|
1972
|
+
streaming: true,
|
|
1973
|
+
tools: true,
|
|
1974
|
+
vision: true,
|
|
1975
|
+
systemPrompt: true,
|
|
1976
|
+
maxContextTokens: 1e6
|
|
1977
|
+
}
|
|
1978
|
+
},
|
|
1979
|
+
{
|
|
1980
|
+
id: "gemini-3.5-flash-lite",
|
|
1981
|
+
displayName: "Gemini 3.5 Flash-Lite",
|
|
1982
|
+
capabilities: {
|
|
1983
|
+
streaming: true,
|
|
1984
|
+
tools: true,
|
|
1985
|
+
vision: true,
|
|
1986
|
+
systemPrompt: true,
|
|
1987
|
+
maxContextTokens: 1e6
|
|
1988
|
+
}
|
|
1989
|
+
},
|
|
1869
1990
|
{
|
|
1870
1991
|
id: "gemini-2.5-pro",
|
|
1871
1992
|
displayName: "Gemini 2.5 Pro",
|
|
@@ -2549,6 +2670,15 @@ var BedrockAdapter = class {
|
|
|
2549
2670
|
if (Object.keys(inferenceConfig).length > 0) {
|
|
2550
2671
|
commandInput.inferenceConfig = inferenceConfig;
|
|
2551
2672
|
}
|
|
2673
|
+
if (req.cacheKey) {
|
|
2674
|
+
if (commandInput.system) {
|
|
2675
|
+
commandInput.system.push({ cachePoint: { type: "default" } });
|
|
2676
|
+
}
|
|
2677
|
+
if (tools) {
|
|
2678
|
+
tools.tools.push({ cachePoint: { type: "default" } });
|
|
2679
|
+
}
|
|
2680
|
+
markLastMessageForCaching2(messages);
|
|
2681
|
+
}
|
|
2552
2682
|
const command = new import_client_bedrock_runtime.ConverseStreamCommand(
|
|
2553
2683
|
commandInput
|
|
2554
2684
|
);
|
|
@@ -2572,6 +2702,8 @@ var BedrockAdapter = class {
|
|
|
2572
2702
|
let inputTokens;
|
|
2573
2703
|
let outputTokens;
|
|
2574
2704
|
let totalTokens;
|
|
2705
|
+
let cacheReadTokens;
|
|
2706
|
+
let cacheWriteTokens;
|
|
2575
2707
|
try {
|
|
2576
2708
|
for await (const event of response.stream) {
|
|
2577
2709
|
if (req.signal?.aborted) {
|
|
@@ -2624,6 +2756,8 @@ var BedrockAdapter = class {
|
|
|
2624
2756
|
inputTokens = event.metadata.usage.inputTokens;
|
|
2625
2757
|
outputTokens = event.metadata.usage.outputTokens;
|
|
2626
2758
|
totalTokens = event.metadata.usage.totalTokens;
|
|
2759
|
+
cacheReadTokens = event.metadata.usage.cacheReadInputTokens;
|
|
2760
|
+
cacheWriteTokens = event.metadata.usage.cacheWriteInputTokens;
|
|
2627
2761
|
}
|
|
2628
2762
|
}
|
|
2629
2763
|
}
|
|
@@ -2650,7 +2784,9 @@ var BedrockAdapter = class {
|
|
|
2650
2784
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 || totalTokens !== void 0 ? {
|
|
2651
2785
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
2652
2786
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
2653
|
-
...totalTokens !== void 0 ? { totalTokens } : {}
|
|
2787
|
+
...totalTokens !== void 0 ? { totalTokens } : {},
|
|
2788
|
+
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {},
|
|
2789
|
+
...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {}
|
|
2654
2790
|
} : void 0;
|
|
2655
2791
|
const endEvent = {
|
|
2656
2792
|
type: "end",
|
|
@@ -2758,6 +2894,16 @@ function buildWireMessages3(req) {
|
|
|
2758
2894
|
}
|
|
2759
2895
|
return out;
|
|
2760
2896
|
}
|
|
2897
|
+
function markLastMessageForCaching2(messages) {
|
|
2898
|
+
if (messages.length === 0) return;
|
|
2899
|
+
const last = messages[messages.length - 1];
|
|
2900
|
+
if (Array.isArray(last.content) && last.content.length > 0) {
|
|
2901
|
+
messages[messages.length - 1] = {
|
|
2902
|
+
...last,
|
|
2903
|
+
content: [...last.content, { cachePoint: { type: "default" } }]
|
|
2904
|
+
};
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2761
2907
|
function formatTools4(tools) {
|
|
2762
2908
|
return tools.map((t) => ({
|
|
2763
2909
|
toolSpec: {
|
|
@@ -3113,7 +3259,10 @@ var GroqAdapter = class extends OpenAIAdapter {
|
|
|
3113
3259
|
stream(req) {
|
|
3114
3260
|
return streamFromOpenAI(this.ensureClient(), req, {
|
|
3115
3261
|
knownModels: groqManifest.knownModels,
|
|
3116
|
-
vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR
|
|
3262
|
+
vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR,
|
|
3263
|
+
// Groq caches automatically server-side and rejects/ignores undocumented
|
|
3264
|
+
// OpenAI params — do not forward prompt_cache_key.
|
|
3265
|
+
includeCacheKey: false
|
|
3117
3266
|
});
|
|
3118
3267
|
}
|
|
3119
3268
|
};
|