@jambonz/llm 0.5.6 → 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 +162 -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 +162 -7
- package/dist/index.js.map +1 -1
- package/dist/test-kit/index.cjs +162 -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 +162 -7
- package/dist/test-kit/index.js.map +1 -1
- package/dist/{types-BEgQaQIb.d.cts → types-Y0o6rN3B.d.cts} +45 -0
- package/dist/{types-BEgQaQIb.d.ts → types-Y0o6rN3B.d.ts} +45 -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,11 +128,20 @@ 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");
|
|
131
137
|
body[param] = effectiveMaxTokens;
|
|
132
138
|
}
|
|
139
|
+
if (req.providerParams) {
|
|
140
|
+
const bodyRecord = body;
|
|
141
|
+
for (const [key, value] of Object.entries(req.providerParams)) {
|
|
142
|
+
if (!(key in bodyRecord)) bodyRecord[key] = value;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
133
145
|
const t0 = process.hrtime.bigint();
|
|
134
146
|
let t1;
|
|
135
147
|
let t2;
|
|
@@ -172,10 +184,12 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
172
184
|
throw new Error(`OpenAI-compatible stream returned an error: ${message}`);
|
|
173
185
|
}
|
|
174
186
|
if (chunk.usage) {
|
|
187
|
+
const cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens;
|
|
175
188
|
usage = {
|
|
176
|
-
...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) } : {},
|
|
177
190
|
...chunk.usage.completion_tokens !== void 0 ? { outputTokens: chunk.usage.completion_tokens } : {},
|
|
178
|
-
...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 } : {}
|
|
179
193
|
};
|
|
180
194
|
}
|
|
181
195
|
const choice = chunk.choices?.[0];
|
|
@@ -1228,6 +1242,16 @@ var AnthropicAdapter = class {
|
|
|
1228
1242
|
if (req.system) body.system = req.system;
|
|
1229
1243
|
if (tools) body.tools = tools;
|
|
1230
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
|
+
}
|
|
1231
1255
|
let stream;
|
|
1232
1256
|
let responseHeaders;
|
|
1233
1257
|
try {
|
|
@@ -1255,6 +1279,8 @@ var AnthropicAdapter = class {
|
|
|
1255
1279
|
let stopReason;
|
|
1256
1280
|
let inputTokens;
|
|
1257
1281
|
let outputTokens;
|
|
1282
|
+
let cacheReadTokens;
|
|
1283
|
+
let cacheWriteTokens;
|
|
1258
1284
|
try {
|
|
1259
1285
|
for await (const event of stream) {
|
|
1260
1286
|
if (req.signal?.aborted) {
|
|
@@ -1264,6 +1290,8 @@ var AnthropicAdapter = class {
|
|
|
1264
1290
|
switch (event.type) {
|
|
1265
1291
|
case "message_start":
|
|
1266
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;
|
|
1267
1295
|
break;
|
|
1268
1296
|
case "content_block_start": {
|
|
1269
1297
|
const block = event.content_block;
|
|
@@ -1345,7 +1373,11 @@ var AnthropicAdapter = class {
|
|
|
1345
1373
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 ? {
|
|
1346
1374
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
1347
1375
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
1348
|
-
...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 } : {}
|
|
1349
1381
|
} : void 0;
|
|
1350
1382
|
const endEvent = {
|
|
1351
1383
|
type: "end",
|
|
@@ -1444,6 +1476,23 @@ function buildWireMessages2(req) {
|
|
|
1444
1476
|
}
|
|
1445
1477
|
return out;
|
|
1446
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
|
+
}
|
|
1447
1496
|
function formatTools2(tools) {
|
|
1448
1497
|
return tools.map((t) => ({
|
|
1449
1498
|
name: t.name,
|
|
@@ -1506,6 +1555,11 @@ async function* streamFromGemini(client, req) {
|
|
|
1506
1555
|
if (req.temperature !== void 0) config.temperature = req.temperature;
|
|
1507
1556
|
if (req.maxTokens !== void 0) config.maxOutputTokens = req.maxTokens;
|
|
1508
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
|
+
}
|
|
1509
1563
|
let stream;
|
|
1510
1564
|
try {
|
|
1511
1565
|
stream = await client.models.generateContentStream({
|
|
@@ -1526,6 +1580,7 @@ async function* streamFromGemini(client, req) {
|
|
|
1526
1580
|
let inputTokens;
|
|
1527
1581
|
let outputTokens;
|
|
1528
1582
|
let totalTokens;
|
|
1583
|
+
let cacheReadTokens;
|
|
1529
1584
|
try {
|
|
1530
1585
|
for await (const chunk of stream) {
|
|
1531
1586
|
if (req.signal?.aborted) {
|
|
@@ -1534,7 +1589,12 @@ async function* streamFromGemini(client, req) {
|
|
|
1534
1589
|
}
|
|
1535
1590
|
const usage2 = chunk.usageMetadata;
|
|
1536
1591
|
if (usage2) {
|
|
1537
|
-
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
|
+
}
|
|
1538
1598
|
if (usage2.candidatesTokenCount !== void 0) outputTokens = usage2.candidatesTokenCount;
|
|
1539
1599
|
if (usage2.totalTokenCount !== void 0) totalTokens = usage2.totalTokenCount;
|
|
1540
1600
|
}
|
|
@@ -1588,7 +1648,8 @@ async function* streamFromGemini(client, req) {
|
|
|
1588
1648
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 || totalTokens !== void 0 ? {
|
|
1589
1649
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
1590
1650
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
1591
|
-
...totalTokens !== void 0 ? { totalTokens } : {}
|
|
1651
|
+
...totalTokens !== void 0 ? { totalTokens } : {},
|
|
1652
|
+
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {}
|
|
1592
1653
|
} : void 0;
|
|
1593
1654
|
const endEvent = {
|
|
1594
1655
|
type: "end",
|
|
@@ -1730,6 +1791,39 @@ function isAbortError3(err) {
|
|
|
1730
1791
|
|
|
1731
1792
|
// src/adapters/google/manifest.ts
|
|
1732
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
|
+
},
|
|
1733
1827
|
{
|
|
1734
1828
|
id: "gemini-2.5-pro",
|
|
1735
1829
|
displayName: "Gemini 2.5 Pro",
|
|
@@ -1873,6 +1967,39 @@ var import_genai2 = require("@google/genai");
|
|
|
1873
1967
|
|
|
1874
1968
|
// src/adapters/vertex-gemini/manifest.ts
|
|
1875
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
|
+
},
|
|
1876
2003
|
{
|
|
1877
2004
|
id: "gemini-2.5-pro",
|
|
1878
2005
|
displayName: "Gemini 2.5 Pro",
|
|
@@ -2556,6 +2683,15 @@ var BedrockAdapter = class {
|
|
|
2556
2683
|
if (Object.keys(inferenceConfig).length > 0) {
|
|
2557
2684
|
commandInput.inferenceConfig = inferenceConfig;
|
|
2558
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
|
+
}
|
|
2559
2695
|
const command = new import_client_bedrock_runtime.ConverseStreamCommand(
|
|
2560
2696
|
commandInput
|
|
2561
2697
|
);
|
|
@@ -2579,6 +2715,8 @@ var BedrockAdapter = class {
|
|
|
2579
2715
|
let inputTokens;
|
|
2580
2716
|
let outputTokens;
|
|
2581
2717
|
let totalTokens;
|
|
2718
|
+
let cacheReadTokens;
|
|
2719
|
+
let cacheWriteTokens;
|
|
2582
2720
|
try {
|
|
2583
2721
|
for await (const event of response.stream) {
|
|
2584
2722
|
if (req.signal?.aborted) {
|
|
@@ -2631,6 +2769,8 @@ var BedrockAdapter = class {
|
|
|
2631
2769
|
inputTokens = event.metadata.usage.inputTokens;
|
|
2632
2770
|
outputTokens = event.metadata.usage.outputTokens;
|
|
2633
2771
|
totalTokens = event.metadata.usage.totalTokens;
|
|
2772
|
+
cacheReadTokens = event.metadata.usage.cacheReadInputTokens;
|
|
2773
|
+
cacheWriteTokens = event.metadata.usage.cacheWriteInputTokens;
|
|
2634
2774
|
}
|
|
2635
2775
|
}
|
|
2636
2776
|
}
|
|
@@ -2657,7 +2797,9 @@ var BedrockAdapter = class {
|
|
|
2657
2797
|
const usage = inputTokens !== void 0 || outputTokens !== void 0 || totalTokens !== void 0 ? {
|
|
2658
2798
|
...inputTokens !== void 0 ? { inputTokens } : {},
|
|
2659
2799
|
...outputTokens !== void 0 ? { outputTokens } : {},
|
|
2660
|
-
...totalTokens !== void 0 ? { totalTokens } : {}
|
|
2800
|
+
...totalTokens !== void 0 ? { totalTokens } : {},
|
|
2801
|
+
...cacheReadTokens !== void 0 ? { cacheReadTokens } : {},
|
|
2802
|
+
...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {}
|
|
2661
2803
|
} : void 0;
|
|
2662
2804
|
const endEvent = {
|
|
2663
2805
|
type: "end",
|
|
@@ -2765,6 +2907,16 @@ function buildWireMessages3(req) {
|
|
|
2765
2907
|
}
|
|
2766
2908
|
return out;
|
|
2767
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
|
+
}
|
|
2768
2920
|
function formatTools4(tools) {
|
|
2769
2921
|
return tools.map((t) => ({
|
|
2770
2922
|
toolSpec: {
|
|
@@ -3120,7 +3272,10 @@ var GroqAdapter = class extends OpenAIAdapter {
|
|
|
3120
3272
|
stream(req) {
|
|
3121
3273
|
return streamFromOpenAI(this.ensureClient(), req, {
|
|
3122
3274
|
knownModels: groqManifest.knownModels,
|
|
3123
|
-
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
|
|
3124
3279
|
});
|
|
3125
3280
|
}
|
|
3126
3281
|
};
|