@gammatech/aijsx 0.15.3-dev.2024-10-21 → 0.16.0-dev.2024-10-28
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.d.mts +20 -15
- package/dist/index.d.ts +20 -15
- package/dist/index.js +268 -154
- package/dist/index.mjs +264 -148
- package/dist/{jsx-dev-runtime-lYsmphqH.d.mts → jsx-dev-runtime-yLtSq2UV.d.mts} +13 -6
- package/dist/{jsx-dev-runtime-lYsmphqH.d.ts → jsx-dev-runtime-yLtSq2UV.d.ts} +13 -6
- package/dist/jsx-dev-runtime.d.mts +1 -1
- package/dist/jsx-dev-runtime.d.ts +1 -1
- package/dist/jsx-runtime.d.mts +1 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/package.json +4 -6
package/dist/index.mjs
CHANGED
|
@@ -175,7 +175,7 @@ var UserChatMessageBuilder = class {
|
|
|
175
175
|
this.content.push(props);
|
|
176
176
|
return this;
|
|
177
177
|
}
|
|
178
|
-
async build() {
|
|
178
|
+
async build(opts) {
|
|
179
179
|
const promises = this.content.map(
|
|
180
180
|
async (part) => {
|
|
181
181
|
if (typeof part === "string") {
|
|
@@ -196,7 +196,8 @@ var UserChatMessageBuilder = class {
|
|
|
196
196
|
);
|
|
197
197
|
return {
|
|
198
198
|
role: "user",
|
|
199
|
-
content: await Promise.all(promises)
|
|
199
|
+
content: await Promise.all(promises),
|
|
200
|
+
cachePrompt: opts.cachePrompt
|
|
200
201
|
};
|
|
201
202
|
}
|
|
202
203
|
};
|
|
@@ -214,21 +215,16 @@ var UserMessage = (props) => {
|
|
|
214
215
|
var AssistantMessage = (props) => {
|
|
215
216
|
return props.children;
|
|
216
217
|
};
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return {
|
|
228
|
-
prompt,
|
|
229
|
-
completion,
|
|
230
|
-
total: prompt + completion
|
|
231
|
-
};
|
|
218
|
+
var ChatMessageXmlAttributes = {
|
|
219
|
+
AssistantMessage: {
|
|
220
|
+
cachePrompt: true
|
|
221
|
+
},
|
|
222
|
+
UserMessage: {
|
|
223
|
+
cachePrompt: true
|
|
224
|
+
},
|
|
225
|
+
SystemMessage: {
|
|
226
|
+
cachePrompt: true
|
|
227
|
+
}
|
|
232
228
|
};
|
|
233
229
|
|
|
234
230
|
// src/EventEmitter.ts
|
|
@@ -1941,56 +1937,14 @@ var errorToChatCompletionError = (error, requestData) => {
|
|
|
1941
1937
|
);
|
|
1942
1938
|
};
|
|
1943
1939
|
|
|
1944
|
-
// src/lib/openai/tokenizer.ts
|
|
1945
|
-
import { getEncoding } from "js-tiktoken";
|
|
1946
|
-
var cl100kTokenizer = getEncoding("cl100k_base");
|
|
1947
|
-
var tokenizer = {
|
|
1948
|
-
encode: (text) => cl100kTokenizer.encode(text),
|
|
1949
|
-
decode: (tokens) => cl100kTokenizer.decode(tokens)
|
|
1950
|
-
};
|
|
1951
|
-
var TOKENS_PER_MESSAGE = 3;
|
|
1952
|
-
var textCost = (content) => {
|
|
1953
|
-
return TOKENS_PER_MESSAGE + tokenizer.encode(content).length;
|
|
1954
|
-
};
|
|
1955
|
-
var COST_PER_LOW = 85;
|
|
1956
|
-
var COST_PER_512x512 = 170;
|
|
1957
|
-
var imageCost = (w, h) => {
|
|
1958
|
-
const area = w * h;
|
|
1959
|
-
return Math.ceil(area / (512 * 512)) * COST_PER_512x512 + COST_PER_LOW;
|
|
1960
|
-
};
|
|
1961
|
-
var openaiTokenizer = (message) => {
|
|
1962
|
-
switch (message.role) {
|
|
1963
|
-
case "assistant":
|
|
1964
|
-
case "system":
|
|
1965
|
-
return textCost(message.content || "");
|
|
1966
|
-
case "user":
|
|
1967
|
-
if (typeof message.content === "string") {
|
|
1968
|
-
return textCost(message.content);
|
|
1969
|
-
}
|
|
1970
|
-
return message.content.reduce((acc, part) => {
|
|
1971
|
-
if (part.type === "text") {
|
|
1972
|
-
return acc + textCost(part.text);
|
|
1973
|
-
} else {
|
|
1974
|
-
if (part.image.detail === "low") {
|
|
1975
|
-
return acc + 85;
|
|
1976
|
-
}
|
|
1977
|
-
if (part.image.dimensions) {
|
|
1978
|
-
return acc + imageCost(
|
|
1979
|
-
part.image.dimensions.width,
|
|
1980
|
-
part.image.dimensions.height
|
|
1981
|
-
);
|
|
1982
|
-
}
|
|
1983
|
-
return acc + imageCost(1024, 1024);
|
|
1984
|
-
}
|
|
1985
|
-
}, 0);
|
|
1986
|
-
}
|
|
1987
|
-
};
|
|
1988
|
-
|
|
1989
1940
|
// src/chat/buildMessages.ts
|
|
1990
1941
|
async function toXml(ctx, children) {
|
|
1991
1942
|
const childrenXml = await ctx.render(children, {
|
|
1992
1943
|
preserveTags: true,
|
|
1993
|
-
renderedProps:
|
|
1944
|
+
renderedProps: {
|
|
1945
|
+
...IMAGE_RENDERED_PROPS,
|
|
1946
|
+
...ChatMessageXmlAttributes
|
|
1947
|
+
}
|
|
1994
1948
|
});
|
|
1995
1949
|
const topLevelTags = ["UserMessage", "AssistantMessage", "SystemMessage"];
|
|
1996
1950
|
const chatMessageTags = [...topLevelTags, "ImagePart"];
|
|
@@ -2030,25 +1984,35 @@ async function buildChatMessages(ctx, children, opts) {
|
|
|
2030
1984
|
throw new Error("Invalid User ChildNode, expecting Text or ImagePart");
|
|
2031
1985
|
}
|
|
2032
1986
|
}
|
|
2033
|
-
return builder.build(
|
|
1987
|
+
return builder.build({
|
|
1988
|
+
cachePrompt: node.attributes.cachePrompt === true
|
|
1989
|
+
});
|
|
2034
1990
|
};
|
|
2035
1991
|
return iterateChatMessageXml(nodes, async (node) => {
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
1992
|
+
const cachePrompt = node.attributes.cachePrompt === true;
|
|
1993
|
+
const getMessageWithoutCachePrompt = () => {
|
|
1994
|
+
switch (node.nodeName) {
|
|
1995
|
+
case "UserMessage":
|
|
1996
|
+
return handleUserMessage(node);
|
|
1997
|
+
case "SystemMessage":
|
|
1998
|
+
return {
|
|
1999
|
+
role: "system",
|
|
2000
|
+
content: node.textContent
|
|
2001
|
+
};
|
|
2002
|
+
case "AssistantMessage":
|
|
2003
|
+
return {
|
|
2004
|
+
role: "assistant",
|
|
2005
|
+
content: node.textContent
|
|
2006
|
+
};
|
|
2007
|
+
default:
|
|
2008
|
+
throw new Error("Invalid top level chat message tags");
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
const message = await getMessageWithoutCachePrompt();
|
|
2012
|
+
return cachePrompt ? {
|
|
2013
|
+
...message,
|
|
2014
|
+
cachePrompt: true
|
|
2015
|
+
} : message;
|
|
2052
2016
|
});
|
|
2053
2017
|
}
|
|
2054
2018
|
|
|
@@ -2148,6 +2112,9 @@ async function* OpenAIChatCompletionInner(props, ctx) {
|
|
|
2148
2112
|
const chatCompletionRequest = {
|
|
2149
2113
|
model: props.model,
|
|
2150
2114
|
max_tokens: props.maxTokens,
|
|
2115
|
+
stream_options: {
|
|
2116
|
+
include_usage: true
|
|
2117
|
+
},
|
|
2151
2118
|
temperature: props.temperature,
|
|
2152
2119
|
stop: props.stop,
|
|
2153
2120
|
messages: openAIMessages,
|
|
@@ -2185,8 +2152,24 @@ async function* OpenAIChatCompletionInner(props, ctx) {
|
|
|
2185
2152
|
}
|
|
2186
2153
|
let finishReason = void 0;
|
|
2187
2154
|
let content = "";
|
|
2155
|
+
let tokensUsed = {
|
|
2156
|
+
prompt: 0,
|
|
2157
|
+
completion: 0,
|
|
2158
|
+
total: 0,
|
|
2159
|
+
cachedPromptTokensCreated: 0,
|
|
2160
|
+
cachedPromptTokensRead: 0
|
|
2161
|
+
};
|
|
2188
2162
|
try {
|
|
2189
2163
|
for await (const message of chatResponse) {
|
|
2164
|
+
if (message.usage) {
|
|
2165
|
+
tokensUsed = {
|
|
2166
|
+
prompt: message.usage.prompt_tokens,
|
|
2167
|
+
completion: message.usage.completion_tokens,
|
|
2168
|
+
total: message.usage.total_tokens,
|
|
2169
|
+
cachedPromptTokensCreated: 0,
|
|
2170
|
+
cachedPromptTokensRead: message.usage.prompt_tokens_details?.cached_tokens || 0
|
|
2171
|
+
};
|
|
2172
|
+
}
|
|
2190
2173
|
if (!message.choices || !message.choices[0]) {
|
|
2191
2174
|
continue;
|
|
2192
2175
|
}
|
|
@@ -2212,10 +2195,6 @@ async function* OpenAIChatCompletionInner(props, ctx) {
|
|
|
2212
2195
|
role: "assistant",
|
|
2213
2196
|
content
|
|
2214
2197
|
};
|
|
2215
|
-
const tokensUsed = computeUsage(
|
|
2216
|
-
[...chatMessages, outputMessage],
|
|
2217
|
-
openaiTokenizer
|
|
2218
|
-
);
|
|
2219
2198
|
const cost = costFn?.(props.model, tokensUsed) ?? void 0;
|
|
2220
2199
|
const responseData = {
|
|
2221
2200
|
...logRequestData,
|
|
@@ -2273,32 +2252,6 @@ import { OpenAI as OpenAIClient3 } from "openai";
|
|
|
2273
2252
|
|
|
2274
2253
|
// src/lib/anthropic/Anthropic.tsx
|
|
2275
2254
|
import AnthropicClient from "@anthropic-ai/sdk";
|
|
2276
|
-
|
|
2277
|
-
// src/lib/anthropic/tokenizer.ts
|
|
2278
|
-
import { countTokens } from "@anthropic-ai/tokenizer";
|
|
2279
|
-
var DEFAULT_IMAGE_TOKEN_COST = 1334;
|
|
2280
|
-
var imageTokens = (w, h) => {
|
|
2281
|
-
return Math.ceil(w * h / 750);
|
|
2282
|
-
};
|
|
2283
|
-
var anthropicTokenizer = (message) => {
|
|
2284
|
-
if (message.role === "system") {
|
|
2285
|
-
return countTokens(message.content);
|
|
2286
|
-
}
|
|
2287
|
-
if (message.role === "assistant") {
|
|
2288
|
-
return countTokens(message.content);
|
|
2289
|
-
}
|
|
2290
|
-
return message.content.reduce((carry, item) => {
|
|
2291
|
-
let tokens = 0;
|
|
2292
|
-
if (item.type === "text") {
|
|
2293
|
-
tokens = countTokens(item.text);
|
|
2294
|
-
} else {
|
|
2295
|
-
tokens = item.image.dimensions ? imageTokens(item.image.dimensions.width, item.image.dimensions.height) : DEFAULT_IMAGE_TOKEN_COST;
|
|
2296
|
-
}
|
|
2297
|
-
return carry + tokens;
|
|
2298
|
-
}, 0);
|
|
2299
|
-
};
|
|
2300
|
-
|
|
2301
|
-
// src/lib/anthropic/Anthropic.tsx
|
|
2302
2255
|
var defaultClient2 = null;
|
|
2303
2256
|
var AnthropicClientContext = createContext(async () => {
|
|
2304
2257
|
if (defaultClient2) {
|
|
@@ -2314,21 +2267,73 @@ var AnthropicClientContext = createContext(async () => {
|
|
|
2314
2267
|
return defaultClient2;
|
|
2315
2268
|
});
|
|
2316
2269
|
var defaultMaxTokens = 4096;
|
|
2270
|
+
var populateCacheControl = (message, cachePrompt) => {
|
|
2271
|
+
if (!cachePrompt) {
|
|
2272
|
+
return message;
|
|
2273
|
+
}
|
|
2274
|
+
const content = message.content;
|
|
2275
|
+
if (typeof content === "string") {
|
|
2276
|
+
return {
|
|
2277
|
+
role: message.role,
|
|
2278
|
+
content: [
|
|
2279
|
+
{
|
|
2280
|
+
type: "text",
|
|
2281
|
+
text: content,
|
|
2282
|
+
// @ts-ignore - AnthropicSDK isn't up to date with this
|
|
2283
|
+
cache_control: {
|
|
2284
|
+
type: "ephemeral"
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
]
|
|
2288
|
+
};
|
|
2289
|
+
}
|
|
2290
|
+
if (content.length === 0) {
|
|
2291
|
+
return message;
|
|
2292
|
+
}
|
|
2293
|
+
const lastcontent = {
|
|
2294
|
+
...content[content.length - 1],
|
|
2295
|
+
cache_control: {
|
|
2296
|
+
type: "ephemeral"
|
|
2297
|
+
}
|
|
2298
|
+
};
|
|
2299
|
+
return {
|
|
2300
|
+
role: message.role,
|
|
2301
|
+
content: [...content.slice(0, -1), lastcontent]
|
|
2302
|
+
};
|
|
2303
|
+
};
|
|
2317
2304
|
var buildAnthropicMessages = (chatMesssages) => {
|
|
2318
2305
|
let system = "";
|
|
2319
2306
|
const messages = [];
|
|
2320
|
-
chatMesssages.forEach(({ role, content }) => {
|
|
2307
|
+
chatMesssages.forEach(({ role, content, cachePrompt }) => {
|
|
2321
2308
|
if (role === "system") {
|
|
2322
|
-
|
|
2309
|
+
if (cachePrompt) {
|
|
2310
|
+
system = [
|
|
2311
|
+
{
|
|
2312
|
+
type: "text",
|
|
2313
|
+
text: content,
|
|
2314
|
+
// @ts-ignore - AnthropicSDK isn't up to date with this
|
|
2315
|
+
cache_control: {
|
|
2316
|
+
type: "ephemeral"
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
];
|
|
2320
|
+
} else {
|
|
2321
|
+
system = content;
|
|
2322
|
+
}
|
|
2323
2323
|
return;
|
|
2324
2324
|
}
|
|
2325
2325
|
if (role === "user") {
|
|
2326
2326
|
const userContent = content;
|
|
2327
2327
|
if (userContent.length === 1 && userContent[0].type === "text") {
|
|
2328
|
-
messages.push(
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2328
|
+
messages.push(
|
|
2329
|
+
populateCacheControl(
|
|
2330
|
+
{
|
|
2331
|
+
role,
|
|
2332
|
+
content: userContent[0].text
|
|
2333
|
+
},
|
|
2334
|
+
cachePrompt
|
|
2335
|
+
)
|
|
2336
|
+
);
|
|
2332
2337
|
return;
|
|
2333
2338
|
}
|
|
2334
2339
|
const c = userContent.map((part) => {
|
|
@@ -2353,17 +2358,27 @@ var buildAnthropicMessages = (chatMesssages) => {
|
|
|
2353
2358
|
a.type === "image" || a.type === "text" && a.text.trim().length > 0
|
|
2354
2359
|
)
|
|
2355
2360
|
);
|
|
2356
|
-
messages.push(
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2361
|
+
messages.push(
|
|
2362
|
+
populateCacheControl(
|
|
2363
|
+
{
|
|
2364
|
+
role,
|
|
2365
|
+
content: c
|
|
2366
|
+
},
|
|
2367
|
+
cachePrompt
|
|
2368
|
+
)
|
|
2369
|
+
);
|
|
2360
2370
|
return;
|
|
2361
2371
|
}
|
|
2362
2372
|
if (role === "assistant") {
|
|
2363
|
-
messages.push(
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2373
|
+
messages.push(
|
|
2374
|
+
populateCacheControl(
|
|
2375
|
+
{
|
|
2376
|
+
role,
|
|
2377
|
+
content
|
|
2378
|
+
},
|
|
2379
|
+
cachePrompt
|
|
2380
|
+
)
|
|
2381
|
+
);
|
|
2367
2382
|
return;
|
|
2368
2383
|
}
|
|
2369
2384
|
throw new Error(`Invalid role: ${role}`);
|
|
@@ -2416,6 +2431,9 @@ function AnthropicChatCompletion(props, ctx) {
|
|
|
2416
2431
|
}
|
|
2417
2432
|
);
|
|
2418
2433
|
}
|
|
2434
|
+
var ANTHROPIC_DEFAULT_HEADERS = {
|
|
2435
|
+
"anthropic-beta": "prompt-caching-2024-07-31"
|
|
2436
|
+
};
|
|
2419
2437
|
async function* AnthropicChatCompletionInner(props, ctx) {
|
|
2420
2438
|
const startTime = performance.now();
|
|
2421
2439
|
const { logger, tracer, getContext } = ctx;
|
|
@@ -2453,9 +2471,12 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2453
2471
|
stop_sequences: stopSequences,
|
|
2454
2472
|
model: props.model
|
|
2455
2473
|
};
|
|
2456
|
-
const requestOptions =
|
|
2457
|
-
headers:
|
|
2458
|
-
|
|
2474
|
+
const requestOptions = {
|
|
2475
|
+
headers: {
|
|
2476
|
+
...ANTHROPIC_DEFAULT_HEADERS,
|
|
2477
|
+
...props.extraHeaders
|
|
2478
|
+
}
|
|
2479
|
+
};
|
|
2459
2480
|
const chatCompletionRequestToLog = cleanChatCompletionRequest2(
|
|
2460
2481
|
anthropicCompletionRequest
|
|
2461
2482
|
);
|
|
@@ -2501,13 +2522,27 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2501
2522
|
throw err;
|
|
2502
2523
|
}
|
|
2503
2524
|
let content = "";
|
|
2504
|
-
let outputUsage;
|
|
2505
|
-
let inputUsage;
|
|
2506
2525
|
let finishReason = null;
|
|
2526
|
+
const tokensUsed = {
|
|
2527
|
+
prompt: 0,
|
|
2528
|
+
completion: 0,
|
|
2529
|
+
total: 0,
|
|
2530
|
+
cachedPromptTokensCreated: 0,
|
|
2531
|
+
cachedPromptTokensRead: 0
|
|
2532
|
+
};
|
|
2507
2533
|
try {
|
|
2508
2534
|
for await (const event of response) {
|
|
2509
2535
|
if (event.type === "message_start") {
|
|
2510
|
-
inputUsage = event.message.usage
|
|
2536
|
+
const inputUsage = event.message.usage;
|
|
2537
|
+
if (inputUsage) {
|
|
2538
|
+
const cacheCreated = inputUsage.cache_creation_input_tokens || 0;
|
|
2539
|
+
const cacheRead = inputUsage.cache_read_input_tokens || 0;
|
|
2540
|
+
const promptTokens = inputUsage.input_tokens + cacheCreated + cacheRead;
|
|
2541
|
+
logger.info(`inputUsage: ${JSON.stringify(inputUsage, null, 2)}`);
|
|
2542
|
+
tokensUsed.prompt = promptTokens;
|
|
2543
|
+
tokensUsed.cachedPromptTokensCreated = cacheCreated;
|
|
2544
|
+
tokensUsed.cachedPromptTokensRead = cacheRead;
|
|
2545
|
+
}
|
|
2511
2546
|
}
|
|
2512
2547
|
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
|
|
2513
2548
|
const chunk = event.delta.text;
|
|
@@ -2516,7 +2551,8 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2516
2551
|
}
|
|
2517
2552
|
if (event.type === "message_delta") {
|
|
2518
2553
|
finishReason = event.delta.stop_reason;
|
|
2519
|
-
|
|
2554
|
+
tokensUsed.completion = event.usage?.output_tokens || 0;
|
|
2555
|
+
tokensUsed.total = tokensUsed.prompt + tokensUsed.completion;
|
|
2520
2556
|
span.setAttributes({
|
|
2521
2557
|
finishReason
|
|
2522
2558
|
});
|
|
@@ -2534,11 +2570,6 @@ async function* AnthropicChatCompletionInner(props, ctx) {
|
|
|
2534
2570
|
role: "assistant",
|
|
2535
2571
|
content
|
|
2536
2572
|
};
|
|
2537
|
-
const tokensUsed = inputUsage !== void 0 && outputUsage !== void 0 ? {
|
|
2538
|
-
prompt: inputUsage,
|
|
2539
|
-
completion: outputUsage,
|
|
2540
|
-
total: inputUsage + outputUsage
|
|
2541
|
-
} : computeUsage([...chatMessages, outputMessage], anthropicTokenizer);
|
|
2542
2573
|
const cost = costFn?.(props.model, tokensUsed) ?? void 0;
|
|
2543
2574
|
const responseData = {
|
|
2544
2575
|
...logRequestData,
|
|
@@ -2596,6 +2627,92 @@ function cleanChatCompletionRequest2(chatCompletionRequest) {
|
|
|
2596
2627
|
// src/lib/anthropic/index.ts
|
|
2597
2628
|
import AnthropicClient2 from "@anthropic-ai/sdk";
|
|
2598
2629
|
|
|
2630
|
+
// src/lib/anthropic/AnthropicPromptCacheDebugger.tsx
|
|
2631
|
+
import crypto from "crypto";
|
|
2632
|
+
var renderAttrs = (attrs) => {
|
|
2633
|
+
if (!attrs || Object.keys(attrs).length === 0)
|
|
2634
|
+
return "";
|
|
2635
|
+
return Object.entries(attrs).map(([key, value]) => ` ${key}="${value}"`).join("");
|
|
2636
|
+
};
|
|
2637
|
+
var indentOver = (str, indent) => {
|
|
2638
|
+
const lines = str.split("\n");
|
|
2639
|
+
return lines.map((l) => " ".repeat(indent) + l).join("\n");
|
|
2640
|
+
};
|
|
2641
|
+
var renderTag = (tag2, indent, slice = null) => {
|
|
2642
|
+
if (Array.isArray(tag2)) {
|
|
2643
|
+
return tag2.map((t) => renderTag(t, indent, slice)).join("\n");
|
|
2644
|
+
}
|
|
2645
|
+
if (typeof tag2.children === "string") {
|
|
2646
|
+
const sliced = slice == null ? tag2.children : tag2.children.slice(0, slice);
|
|
2647
|
+
return indentOver(sliced, indent);
|
|
2648
|
+
}
|
|
2649
|
+
if (Array.isArray(tag2.children)) {
|
|
2650
|
+
const children = tag2.children.map((c) => {
|
|
2651
|
+
return renderTag(c, indent + 1, slice);
|
|
2652
|
+
}).join("\n");
|
|
2653
|
+
const res = `<${tag2.type}${renderAttrs(tag2.attrs)}>
|
|
2654
|
+
${children}
|
|
2655
|
+
</${tag2.type}>`;
|
|
2656
|
+
return indentOver(res, indent);
|
|
2657
|
+
}
|
|
2658
|
+
};
|
|
2659
|
+
var tag = (type, attrs, children) => {
|
|
2660
|
+
let c;
|
|
2661
|
+
if (typeof children === "string") {
|
|
2662
|
+
c = children;
|
|
2663
|
+
} else if (!Array.isArray(children)) {
|
|
2664
|
+
c = [children];
|
|
2665
|
+
} else {
|
|
2666
|
+
c = children;
|
|
2667
|
+
}
|
|
2668
|
+
return {
|
|
2669
|
+
type,
|
|
2670
|
+
attrs,
|
|
2671
|
+
children: c
|
|
2672
|
+
};
|
|
2673
|
+
};
|
|
2674
|
+
var AnthropicPromptCacheDebugger = async (props, ctx) => {
|
|
2675
|
+
const chatMessages = await buildChatMessages(ctx, props.children, {
|
|
2676
|
+
useBase64Images: true
|
|
2677
|
+
});
|
|
2678
|
+
const breakpointIndices = chatMessages.map((m, i) => {
|
|
2679
|
+
if (m.cachePrompt) {
|
|
2680
|
+
return i;
|
|
2681
|
+
}
|
|
2682
|
+
return void 0;
|
|
2683
|
+
}).filter((a) => a !== void 0);
|
|
2684
|
+
const messagesToTags = (messages) => {
|
|
2685
|
+
return messages.map((m) => {
|
|
2686
|
+
const role = m.role;
|
|
2687
|
+
const co = m.content;
|
|
2688
|
+
let inner = "";
|
|
2689
|
+
if (typeof co === "string") {
|
|
2690
|
+
inner = co;
|
|
2691
|
+
} else if (Array.isArray(co)) {
|
|
2692
|
+
inner = co.map((c) => {
|
|
2693
|
+
if (c.type === "text") {
|
|
2694
|
+
return tag(c.type, {}, c.text);
|
|
2695
|
+
} else if (c.type === "image") {
|
|
2696
|
+
return tag(c.type, {}, c.image.data?.slice(0, 22) || "image data");
|
|
2697
|
+
}
|
|
2698
|
+
throw new Error("Invalid content");
|
|
2699
|
+
});
|
|
2700
|
+
}
|
|
2701
|
+
return tag(role, {}, inner);
|
|
2702
|
+
});
|
|
2703
|
+
};
|
|
2704
|
+
const final = breakpointIndices.map((acc, i) => {
|
|
2705
|
+
const lastIndex = breakpointIndices[i - 1];
|
|
2706
|
+
const thisIndex = breakpointIndices[i];
|
|
2707
|
+
const toHash = messagesToTags(chatMessages.slice(0, thisIndex + 1));
|
|
2708
|
+
const content = chatMessages.slice(lastIndex + 1, thisIndex + 1);
|
|
2709
|
+
const hash = crypto.createHash("sha256").update(renderTag(toHash, 0)).digest("hex").slice(0, 8);
|
|
2710
|
+
return tag("breakpoint", { index: i, hash }, messagesToTags(content));
|
|
2711
|
+
});
|
|
2712
|
+
const res = final.map((t) => renderTag(t, 0)).join("\n");
|
|
2713
|
+
return res;
|
|
2714
|
+
};
|
|
2715
|
+
|
|
2599
2716
|
// src/lib/google/Google.tsx
|
|
2600
2717
|
import {
|
|
2601
2718
|
HarmBlockThreshold,
|
|
@@ -2800,8 +2917,13 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2800
2917
|
throw errorToChatCompletionError2(err, logRequestData);
|
|
2801
2918
|
}
|
|
2802
2919
|
let content = "";
|
|
2803
|
-
|
|
2804
|
-
|
|
2920
|
+
const tokensUsed = {
|
|
2921
|
+
prompt: 0,
|
|
2922
|
+
completion: 0,
|
|
2923
|
+
total: 0,
|
|
2924
|
+
cachedPromptTokensCreated: 0,
|
|
2925
|
+
cachedPromptTokensRead: 0
|
|
2926
|
+
};
|
|
2805
2927
|
let finishReason = null;
|
|
2806
2928
|
try {
|
|
2807
2929
|
for await (const event of response.stream) {
|
|
@@ -2814,10 +2936,10 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2814
2936
|
}
|
|
2815
2937
|
if (event.usageMetadata) {
|
|
2816
2938
|
if (event.usageMetadata.promptTokenCount) {
|
|
2817
|
-
|
|
2939
|
+
tokensUsed.prompt = event.usageMetadata.promptTokenCount;
|
|
2818
2940
|
}
|
|
2819
2941
|
if (event.usageMetadata.candidatesTokenCount) {
|
|
2820
|
-
|
|
2942
|
+
tokensUsed.completion = event.usageMetadata.candidatesTokenCount;
|
|
2821
2943
|
}
|
|
2822
2944
|
}
|
|
2823
2945
|
const chunk = event.candidates[0].content;
|
|
@@ -2855,11 +2977,7 @@ async function* GoogleChatCompletionInner(props, ctx) {
|
|
|
2855
2977
|
role: "assistant",
|
|
2856
2978
|
content
|
|
2857
2979
|
};
|
|
2858
|
-
|
|
2859
|
-
prompt: inputUsage,
|
|
2860
|
-
completion: outputUsage,
|
|
2861
|
-
total: inputUsage + outputUsage
|
|
2862
|
-
};
|
|
2980
|
+
tokensUsed.total = tokensUsed.prompt + tokensUsed.completion;
|
|
2863
2981
|
const cost = costFn?.(props.model, tokensUsed) ?? void 0;
|
|
2864
2982
|
const responseData = {
|
|
2865
2983
|
...logRequestData,
|
|
@@ -2944,16 +3062,14 @@ export {
|
|
|
2944
3062
|
Trace,
|
|
2945
3063
|
UserMessage,
|
|
2946
3064
|
VertexAI2 as VertexAI,
|
|
2947
|
-
anthropicTokenizer,
|
|
2948
3065
|
attachedContextSymbol,
|
|
2949
|
-
computeUsage,
|
|
2950
3066
|
createAIElement,
|
|
2951
3067
|
createContext,
|
|
2952
3068
|
createPrompt,
|
|
2953
3069
|
createRenderContext,
|
|
2954
3070
|
evaluatePrompt,
|
|
3071
|
+
AnthropicPromptCacheDebugger as experimental__AnthropicPromptCacheDebugger,
|
|
2955
3072
|
isPromptParsed2 as isPromptParsed,
|
|
2956
|
-
openaiTokenizer,
|
|
2957
3073
|
toDebugMessage,
|
|
2958
3074
|
tracing
|
|
2959
3075
|
};
|
|
@@ -44,13 +44,16 @@ type UserTextPart = {
|
|
|
44
44
|
type UserChatMessage = {
|
|
45
45
|
role: 'user';
|
|
46
46
|
content: (UserTextPart | UserImagePart)[];
|
|
47
|
+
cachePrompt?: boolean;
|
|
47
48
|
};
|
|
48
49
|
type ChatMessage = {
|
|
49
50
|
role: 'system';
|
|
50
51
|
content: string;
|
|
52
|
+
cachePrompt?: boolean;
|
|
51
53
|
} | {
|
|
52
54
|
role: 'assistant';
|
|
53
55
|
content: string;
|
|
56
|
+
cachePrompt?: boolean;
|
|
54
57
|
} | UserChatMessage;
|
|
55
58
|
type DebugMessage = {
|
|
56
59
|
role: ChatRole;
|
|
@@ -58,6 +61,14 @@ type DebugMessage = {
|
|
|
58
61
|
};
|
|
59
62
|
declare const toDebugMessage: (message: ChatMessage) => DebugMessage;
|
|
60
63
|
|
|
64
|
+
type ChatCompletionUsage = {
|
|
65
|
+
prompt: number;
|
|
66
|
+
completion: number;
|
|
67
|
+
total: number;
|
|
68
|
+
cachedPromptTokensCreated: number;
|
|
69
|
+
cachedPromptTokensRead: number;
|
|
70
|
+
};
|
|
71
|
+
|
|
61
72
|
type Literal = string | number | null | undefined | boolean;
|
|
62
73
|
interface RenderResult extends AsyncGenerator<string, void> {
|
|
63
74
|
then(onFulfilled: (value: string) => string | PromiseLike<string>, onRejected?: (reason: any) => string | PromiseLike<string>): PromiseLike<string>;
|
|
@@ -260,11 +271,7 @@ interface LogChatCompletionResponse<R extends Record<string, any> = ChatCompleti
|
|
|
260
271
|
latency: number;
|
|
261
272
|
outputMessage: ChatMessage;
|
|
262
273
|
finishReason: string | null;
|
|
263
|
-
tokensUsed:
|
|
264
|
-
prompt: number;
|
|
265
|
-
completion: number;
|
|
266
|
-
total: number;
|
|
267
|
-
};
|
|
274
|
+
tokensUsed: ChatCompletionUsage;
|
|
268
275
|
}
|
|
269
276
|
type LogLevel = 'error' | 'warn' | 'info' | 'debug';
|
|
270
277
|
type Loggable = string | number | boolean | undefined | null | object;
|
|
@@ -355,4 +362,4 @@ declare const jsxs: typeof jsx;
|
|
|
355
362
|
/** @hidden */
|
|
356
363
|
declare const Fragment: typeof AIFragment;
|
|
357
364
|
|
|
358
|
-
export { type AINode as A, BoundLogger as B, type
|
|
365
|
+
export { type AINode as A, BoundLogger as B, type ContextValues as C, type DebugMessage as D, type EvaluatorResult as E, type Renderable as F, type PropsOfAIComponent as G, type SpanContext as H, ImagePart as I, JSX as J, type SpanStatus as K, type LogChatCompletionRequest as L, type Span as M, NoopLogImplementation as N, type SpanEvent as O, type Prompt as P, type TracingContextKey as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, type TracingContext as U, type TracingContextManager as V, type OutputParser as W, jsx as X, jsxDEV as Y, jsxs as Z, Fragment as _, LogImplementation as a, type Context as b, type ReadableSpan as c, type SpanAttributes as d, type SpanExporter as e, type AIComponent as f, type ChatCompletionRequestPayloads as g, type EvaluatorFn as h, type PromptParsed as i, createAIElement as j, AIFragment as k, createContext as l, type ChatMessage as m, type ChatRole as n, type ImagePartProps as o, type ChatCompletionUsage as p, type LogChatCompletionResponse as q, type LogLevel as r, type Logger as s, toDebugMessage as t, ConsoleLogger as u, CombinedLogger as v, type Literal as w, type RenderResult as x, attachedContextSymbol as y, type AIElement as z };
|
|
@@ -44,13 +44,16 @@ type UserTextPart = {
|
|
|
44
44
|
type UserChatMessage = {
|
|
45
45
|
role: 'user';
|
|
46
46
|
content: (UserTextPart | UserImagePart)[];
|
|
47
|
+
cachePrompt?: boolean;
|
|
47
48
|
};
|
|
48
49
|
type ChatMessage = {
|
|
49
50
|
role: 'system';
|
|
50
51
|
content: string;
|
|
52
|
+
cachePrompt?: boolean;
|
|
51
53
|
} | {
|
|
52
54
|
role: 'assistant';
|
|
53
55
|
content: string;
|
|
56
|
+
cachePrompt?: boolean;
|
|
54
57
|
} | UserChatMessage;
|
|
55
58
|
type DebugMessage = {
|
|
56
59
|
role: ChatRole;
|
|
@@ -58,6 +61,14 @@ type DebugMessage = {
|
|
|
58
61
|
};
|
|
59
62
|
declare const toDebugMessage: (message: ChatMessage) => DebugMessage;
|
|
60
63
|
|
|
64
|
+
type ChatCompletionUsage = {
|
|
65
|
+
prompt: number;
|
|
66
|
+
completion: number;
|
|
67
|
+
total: number;
|
|
68
|
+
cachedPromptTokensCreated: number;
|
|
69
|
+
cachedPromptTokensRead: number;
|
|
70
|
+
};
|
|
71
|
+
|
|
61
72
|
type Literal = string | number | null | undefined | boolean;
|
|
62
73
|
interface RenderResult extends AsyncGenerator<string, void> {
|
|
63
74
|
then(onFulfilled: (value: string) => string | PromiseLike<string>, onRejected?: (reason: any) => string | PromiseLike<string>): PromiseLike<string>;
|
|
@@ -260,11 +271,7 @@ interface LogChatCompletionResponse<R extends Record<string, any> = ChatCompleti
|
|
|
260
271
|
latency: number;
|
|
261
272
|
outputMessage: ChatMessage;
|
|
262
273
|
finishReason: string | null;
|
|
263
|
-
tokensUsed:
|
|
264
|
-
prompt: number;
|
|
265
|
-
completion: number;
|
|
266
|
-
total: number;
|
|
267
|
-
};
|
|
274
|
+
tokensUsed: ChatCompletionUsage;
|
|
268
275
|
}
|
|
269
276
|
type LogLevel = 'error' | 'warn' | 'info' | 'debug';
|
|
270
277
|
type Loggable = string | number | boolean | undefined | null | object;
|
|
@@ -355,4 +362,4 @@ declare const jsxs: typeof jsx;
|
|
|
355
362
|
/** @hidden */
|
|
356
363
|
declare const Fragment: typeof AIFragment;
|
|
357
364
|
|
|
358
|
-
export { type AINode as A, BoundLogger as B, type
|
|
365
|
+
export { type AINode as A, BoundLogger as B, type ContextValues as C, type DebugMessage as D, type EvaluatorResult as E, type Renderable as F, type PropsOfAIComponent as G, type SpanContext as H, ImagePart as I, JSX as J, type SpanStatus as K, type LogChatCompletionRequest as L, type Span as M, NoopLogImplementation as N, type SpanEvent as O, type Prompt as P, type TracingContextKey as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, type TracingContext as U, type TracingContextManager as V, type OutputParser as W, jsx as X, jsxDEV as Y, jsxs as Z, Fragment as _, LogImplementation as a, type Context as b, type ReadableSpan as c, type SpanAttributes as d, type SpanExporter as e, type AIComponent as f, type ChatCompletionRequestPayloads as g, type EvaluatorFn as h, type PromptParsed as i, createAIElement as j, AIFragment as k, createContext as l, type ChatMessage as m, type ChatRole as n, type ImagePartProps as o, type ChatCompletionUsage as p, type LogChatCompletionResponse as q, type LogLevel as r, type Logger as s, toDebugMessage as t, ConsoleLogger as u, CombinedLogger as v, type Literal as w, type RenderResult as x, attachedContextSymbol as y, type AIElement as z };
|