@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/index.cjs
CHANGED
|
@@ -101,6 +101,9 @@ function assertValidRequest(req) {
|
|
|
101
101
|
"PromptRequest.messages must not contain role: 'system'. Pass the system prompt via PromptRequest.system instead."
|
|
102
102
|
);
|
|
103
103
|
}
|
|
104
|
+
if (req.cacheKey !== void 0 && (typeof req.cacheKey !== "string" || req.cacheKey.length === 0)) {
|
|
105
|
+
throw new Error("PromptRequest.cacheKey must be a non-empty string");
|
|
106
|
+
}
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
// src/adapters/openai/_streaming.ts
|
|
@@ -125,6 +128,9 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
125
128
|
body.tool_choice = "auto";
|
|
126
129
|
}
|
|
127
130
|
if (req.temperature !== void 0) body.temperature = req.temperature;
|
|
131
|
+
if (req.cacheKey && options.includeCacheKey !== false) {
|
|
132
|
+
body.prompt_cache_key = req.cacheKey;
|
|
133
|
+
}
|
|
128
134
|
const effectiveMaxTokens = req.maxTokens ?? options.defaultMaxTokens;
|
|
129
135
|
if (effectiveMaxTokens !== void 0) {
|
|
130
136
|
const param = options.tokensParam ?? (needsMaxCompletionTokens(req.model) ? "max_completion_tokens" : "max_tokens");
|
|
@@ -178,10 +184,12 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
178
184
|
throw new Error(`OpenAI-compatible stream returned an error: ${message}`);
|
|
179
185
|
}
|
|
180
186
|
if (chunk.usage) {
|
|
187
|
+
const cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens;
|
|
181
188
|
usage = {
|
|
182
|
-
...chunk.usage.prompt_tokens !== void 0 ? { inputTokens: chunk.usage.prompt_tokens } : {},
|
|
189
|
+
...chunk.usage.prompt_tokens !== void 0 ? { inputTokens: chunk.usage.prompt_tokens - (cachedTokens ?? 0) } : {},
|
|
183
190
|
...chunk.usage.completion_tokens !== void 0 ? { outputTokens: chunk.usage.completion_tokens } : {},
|
|
184
|
-
...chunk.usage.total_tokens !== void 0 ? { totalTokens: chunk.usage.total_tokens } : {}
|
|
191
|
+
...chunk.usage.total_tokens !== void 0 ? { totalTokens: chunk.usage.total_tokens } : {},
|
|
192
|
+
...cachedTokens !== void 0 ? { cacheReadTokens: cachedTokens } : {}
|
|
185
193
|
};
|
|
186
194
|
}
|
|
187
195
|
const choice = chunk.choices?.[0];
|
|
@@ -1234,6 +1242,16 @@ var AnthropicAdapter = class {
|
|
|
1234
1242
|
if (req.system) body.system = req.system;
|
|
1235
1243
|
if (tools) body.tools = tools;
|
|
1236
1244
|
if (req.temperature !== void 0) body.temperature = req.temperature;
|
|
1245
|
+
if (req.cacheKey) {
|
|
1246
|
+
if (req.system) {
|
|
1247
|
+
body.system = [{ type: "text", text: req.system, cache_control: { type: "ephemeral" } }];
|
|
1248
|
+
}
|
|
1249
|
+
if (tools) {
|
|
1250
|
+
const lastTool = tools[tools.length - 1];
|
|
1251
|
+
lastTool.cache_control = { type: "ephemeral" };
|
|
1252
|
+
}
|
|
1253
|
+
markLastMessageForCaching(messages);
|
|
1254
|
+
}
|
|
1237
1255
|
let stream;
|
|
1238
1256
|
let responseHeaders;
|
|
1239
1257
|
try {
|
|
@@ -1261,6 +1279,8 @@ var AnthropicAdapter = class {
|
|
|
1261
1279
|
let stopReason;
|
|
1262
1280
|
let inputTokens;
|
|
1263
1281
|
let outputTokens;
|
|
1282
|
+
let cacheReadTokens;
|
|
1283
|
+
let cacheWriteTokens;
|
|
1264
1284
|
try {
|
|
1265
1285
|
for await (const event of stream) {
|
|
1266
1286
|
if (req.signal?.aborted) {
|
|
@@ -1270,6 +1290,8 @@ var AnthropicAdapter = class {
|
|
|
1270
1290
|
switch (event.type) {
|
|
1271
1291
|
case "message_start":
|
|
1272
1292
|
inputTokens = event.message?.usage?.input_tokens;
|
|
1293
|
+
cacheReadTokens = event.message?.usage?.cache_read_input_tokens;
|
|
1294
|
+
cacheWriteTokens = event.message?.usage?.cache_creation_input_tokens;
|
|
1273
1295
|
break;
|
|
1274
1296
|
case "content_block_start": {
|
|
1275
1297
|
const block = event.content_block;
|
|
@@ -1351,7 +1373,11 @@ var AnthropicAdapter = class {
|
|
|
1351
1373
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 ? {
|
|
1352
1374
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
1353
1375
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
1354
|
-
...inputTokens !== void 0 && outputTokens !== void 0 ? {
|
|
1376
|
+
...inputTokens !== void 0 && outputTokens !== void 0 ? {
|
|
1377
|
+
totalTokens: inputTokens + outputTokens + (cacheReadTokens ?? 0) + (cacheWriteTokens ?? 0)
|
|
1378
|
+
} : {},
|
|
1379
|
+
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {},
|
|
1380
|
+
...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {}
|
|
1355
1381
|
} : void 0;
|
|
1356
1382
|
const endEvent = {
|
|
1357
1383
|
type: "end",
|
|
@@ -1450,6 +1476,23 @@ function buildWireMessages2(req) {
|
|
|
1450
1476
|
}
|
|
1451
1477
|
return out;
|
|
1452
1478
|
}
|
|
1479
|
+
function markLastMessageForCaching(messages) {
|
|
1480
|
+
if (messages.length === 0) return;
|
|
1481
|
+
const last = messages[messages.length - 1];
|
|
1482
|
+
const cacheControl = { cache_control: { type: "ephemeral" } };
|
|
1483
|
+
if (typeof last.content === "string" && last.content.length > 0) {
|
|
1484
|
+
messages[messages.length - 1] = {
|
|
1485
|
+
...last,
|
|
1486
|
+
content: [{ type: "text", text: last.content, ...cacheControl }]
|
|
1487
|
+
};
|
|
1488
|
+
} else if (Array.isArray(last.content) && last.content.length > 0) {
|
|
1489
|
+
const blocks = last.content;
|
|
1490
|
+
messages[messages.length - 1] = {
|
|
1491
|
+
...last,
|
|
1492
|
+
content: [...blocks.slice(0, -1), { ...blocks[blocks.length - 1], ...cacheControl }]
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1453
1496
|
function formatTools2(tools) {
|
|
1454
1497
|
return tools.map((t) => ({
|
|
1455
1498
|
name: t.name,
|
|
@@ -1512,6 +1555,11 @@ async function* streamFromGemini(client, req) {
|
|
|
1512
1555
|
if (req.temperature !== void 0) config.temperature = req.temperature;
|
|
1513
1556
|
if (req.maxTokens !== void 0) config.maxOutputTokens = req.maxTokens;
|
|
1514
1557
|
if (req.signal) config.abortSignal = req.signal;
|
|
1558
|
+
if (req.providerParams) {
|
|
1559
|
+
for (const [key, value] of Object.entries(req.providerParams)) {
|
|
1560
|
+
if (!(key in config)) config[key] = value;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1515
1563
|
let stream;
|
|
1516
1564
|
try {
|
|
1517
1565
|
stream = await client.models.generateContentStream({
|
|
@@ -1532,6 +1580,7 @@ async function* streamFromGemini(client, req) {
|
|
|
1532
1580
|
let inputTokens;
|
|
1533
1581
|
let outputTokens;
|
|
1534
1582
|
let totalTokens;
|
|
1583
|
+
let cacheReadTokens;
|
|
1535
1584
|
try {
|
|
1536
1585
|
for await (const chunk of stream) {
|
|
1537
1586
|
if (req.signal?.aborted) {
|
|
@@ -1540,7 +1589,12 @@ async function* streamFromGemini(client, req) {
|
|
|
1540
1589
|
}
|
|
1541
1590
|
const usage2 = chunk.usageMetadata;
|
|
1542
1591
|
if (usage2) {
|
|
1543
|
-
if (usage2.
|
|
1592
|
+
if (usage2.cachedContentTokenCount !== void 0) {
|
|
1593
|
+
cacheReadTokens = usage2.cachedContentTokenCount;
|
|
1594
|
+
}
|
|
1595
|
+
if (usage2.promptTokenCount !== void 0) {
|
|
1596
|
+
inputTokens = usage2.promptTokenCount - (usage2.cachedContentTokenCount ?? 0);
|
|
1597
|
+
}
|
|
1544
1598
|
if (usage2.candidatesTokenCount !== void 0) outputTokens = usage2.candidatesTokenCount;
|
|
1545
1599
|
if (usage2.totalTokenCount !== void 0) totalTokens = usage2.totalTokenCount;
|
|
1546
1600
|
}
|
|
@@ -1594,7 +1648,8 @@ async function* streamFromGemini(client, req) {
|
|
|
1594
1648
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 || totalTokens !== void 0 ? {
|
|
1595
1649
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
1596
1650
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
1597
|
-
...totalTokens !== void 0 ? { totalTokens } : {}
|
|
1651
|
+
...totalTokens !== void 0 ? { totalTokens } : {},
|
|
1652
|
+
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {}
|
|
1598
1653
|
} : void 0;
|
|
1599
1654
|
const endEvent = {
|
|
1600
1655
|
type: "end",
|
|
@@ -1736,6 +1791,39 @@ function isAbortError3(err) {
|
|
|
1736
1791
|
|
|
1737
1792
|
// src/adapters/google/manifest.ts
|
|
1738
1793
|
var GOOGLE_KNOWN_MODELS = [
|
|
1794
|
+
{
|
|
1795
|
+
id: "gemini-3.6-flash",
|
|
1796
|
+
displayName: "Gemini 3.6 Flash",
|
|
1797
|
+
capabilities: {
|
|
1798
|
+
streaming: true,
|
|
1799
|
+
tools: true,
|
|
1800
|
+
vision: true,
|
|
1801
|
+
systemPrompt: true,
|
|
1802
|
+
maxContextTokens: 1e6
|
|
1803
|
+
}
|
|
1804
|
+
},
|
|
1805
|
+
{
|
|
1806
|
+
id: "gemini-3.5-flash",
|
|
1807
|
+
displayName: "Gemini 3.5 Flash",
|
|
1808
|
+
capabilities: {
|
|
1809
|
+
streaming: true,
|
|
1810
|
+
tools: true,
|
|
1811
|
+
vision: true,
|
|
1812
|
+
systemPrompt: true,
|
|
1813
|
+
maxContextTokens: 1e6
|
|
1814
|
+
}
|
|
1815
|
+
},
|
|
1816
|
+
{
|
|
1817
|
+
id: "gemini-3.5-flash-lite",
|
|
1818
|
+
displayName: "Gemini 3.5 Flash-Lite",
|
|
1819
|
+
capabilities: {
|
|
1820
|
+
streaming: true,
|
|
1821
|
+
tools: true,
|
|
1822
|
+
vision: true,
|
|
1823
|
+
systemPrompt: true,
|
|
1824
|
+
maxContextTokens: 1e6
|
|
1825
|
+
}
|
|
1826
|
+
},
|
|
1739
1827
|
{
|
|
1740
1828
|
id: "gemini-2.5-pro",
|
|
1741
1829
|
displayName: "Gemini 2.5 Pro",
|
|
@@ -1879,6 +1967,39 @@ var import_genai2 = require("@google/genai");
|
|
|
1879
1967
|
|
|
1880
1968
|
// src/adapters/vertex-gemini/manifest.ts
|
|
1881
1969
|
var VERTEX_GEMINI_KNOWN_MODELS = [
|
|
1970
|
+
{
|
|
1971
|
+
id: "gemini-3.6-flash",
|
|
1972
|
+
displayName: "Gemini 3.6 Flash",
|
|
1973
|
+
capabilities: {
|
|
1974
|
+
streaming: true,
|
|
1975
|
+
tools: true,
|
|
1976
|
+
vision: true,
|
|
1977
|
+
systemPrompt: true,
|
|
1978
|
+
maxContextTokens: 1e6
|
|
1979
|
+
}
|
|
1980
|
+
},
|
|
1981
|
+
{
|
|
1982
|
+
id: "gemini-3.5-flash",
|
|
1983
|
+
displayName: "Gemini 3.5 Flash",
|
|
1984
|
+
capabilities: {
|
|
1985
|
+
streaming: true,
|
|
1986
|
+
tools: true,
|
|
1987
|
+
vision: true,
|
|
1988
|
+
systemPrompt: true,
|
|
1989
|
+
maxContextTokens: 1e6
|
|
1990
|
+
}
|
|
1991
|
+
},
|
|
1992
|
+
{
|
|
1993
|
+
id: "gemini-3.5-flash-lite",
|
|
1994
|
+
displayName: "Gemini 3.5 Flash-Lite",
|
|
1995
|
+
capabilities: {
|
|
1996
|
+
streaming: true,
|
|
1997
|
+
tools: true,
|
|
1998
|
+
vision: true,
|
|
1999
|
+
systemPrompt: true,
|
|
2000
|
+
maxContextTokens: 1e6
|
|
2001
|
+
}
|
|
2002
|
+
},
|
|
1882
2003
|
{
|
|
1883
2004
|
id: "gemini-2.5-pro",
|
|
1884
2005
|
displayName: "Gemini 2.5 Pro",
|
|
@@ -2562,6 +2683,15 @@ var BedrockAdapter = class {
|
|
|
2562
2683
|
if (Object.keys(inferenceConfig).length > 0) {
|
|
2563
2684
|
commandInput.inferenceConfig = inferenceConfig;
|
|
2564
2685
|
}
|
|
2686
|
+
if (req.cacheKey) {
|
|
2687
|
+
if (commandInput.system) {
|
|
2688
|
+
commandInput.system.push({ cachePoint: { type: "default" } });
|
|
2689
|
+
}
|
|
2690
|
+
if (tools) {
|
|
2691
|
+
tools.tools.push({ cachePoint: { type: "default" } });
|
|
2692
|
+
}
|
|
2693
|
+
markLastMessageForCaching2(messages);
|
|
2694
|
+
}
|
|
2565
2695
|
const command = new import_client_bedrock_runtime.ConverseStreamCommand(
|
|
2566
2696
|
commandInput
|
|
2567
2697
|
);
|
|
@@ -2585,6 +2715,8 @@ var BedrockAdapter = class {
|
|
|
2585
2715
|
let inputTokens;
|
|
2586
2716
|
let outputTokens;
|
|
2587
2717
|
let totalTokens;
|
|
2718
|
+
let cacheReadTokens;
|
|
2719
|
+
let cacheWriteTokens;
|
|
2588
2720
|
try {
|
|
2589
2721
|
for await (const event of response.stream) {
|
|
2590
2722
|
if (req.signal?.aborted) {
|
|
@@ -2637,6 +2769,8 @@ var BedrockAdapter = class {
|
|
|
2637
2769
|
inputTokens = event.metadata.usage.inputTokens;
|
|
2638
2770
|
outputTokens = event.metadata.usage.outputTokens;
|
|
2639
2771
|
totalTokens = event.metadata.usage.totalTokens;
|
|
2772
|
+
cacheReadTokens = event.metadata.usage.cacheReadInputTokens;
|
|
2773
|
+
cacheWriteTokens = event.metadata.usage.cacheWriteInputTokens;
|
|
2640
2774
|
}
|
|
2641
2775
|
}
|
|
2642
2776
|
}
|
|
@@ -2663,7 +2797,9 @@ var BedrockAdapter = class {
|
|
|
2663
2797
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 || totalTokens !== void 0 ? {
|
|
2664
2798
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
2665
2799
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
2666
|
-
...totalTokens !== void 0 ? { totalTokens } : {}
|
|
2800
|
+
...totalTokens !== void 0 ? { totalTokens } : {},
|
|
2801
|
+
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {},
|
|
2802
|
+
...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {}
|
|
2667
2803
|
} : void 0;
|
|
2668
2804
|
const endEvent = {
|
|
2669
2805
|
type: "end",
|
|
@@ -2771,6 +2907,16 @@ function buildWireMessages3(req) {
|
|
|
2771
2907
|
}
|
|
2772
2908
|
return out;
|
|
2773
2909
|
}
|
|
2910
|
+
function markLastMessageForCaching2(messages) {
|
|
2911
|
+
if (messages.length === 0) return;
|
|
2912
|
+
const last = messages[messages.length - 1];
|
|
2913
|
+
if (Array.isArray(last.content) && last.content.length > 0) {
|
|
2914
|
+
messages[messages.length - 1] = {
|
|
2915
|
+
...last,
|
|
2916
|
+
content: [...last.content, { cachePoint: { type: "default" } }]
|
|
2917
|
+
};
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2774
2920
|
function formatTools4(tools) {
|
|
2775
2921
|
return tools.map((t) => ({
|
|
2776
2922
|
toolSpec: {
|
|
@@ -3126,7 +3272,10 @@ var GroqAdapter = class extends OpenAIAdapter {
|
|
|
3126
3272
|
stream(req) {
|
|
3127
3273
|
return streamFromOpenAI(this.ensureClient(), req, {
|
|
3128
3274
|
knownModels: groqManifest.knownModels,
|
|
3129
|
-
vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR
|
|
3275
|
+
vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR,
|
|
3276
|
+
// Groq caches automatically server-side and rejects/ignores undocumented
|
|
3277
|
+
// OpenAI params — do not forward prompt_cache_key.
|
|
3278
|
+
includeCacheKey: false
|
|
3130
3279
|
});
|
|
3131
3280
|
}
|
|
3132
3281
|
};
|