@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.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
- // src/chat/tokenizer.ts
219
- var computeUsage = (messages, tokenizer2) => {
220
- const promptMessages = [...messages];
221
- let assistantMessage;
222
- if (promptMessages[promptMessages.length - 1].role === "assistant") {
223
- assistantMessage = promptMessages.pop();
224
- }
225
- const prompt = promptMessages.reduce((acc, m) => acc + tokenizer2(m), 0);
226
- const completion = assistantMessage ? tokenizer2(assistantMessage) : 0;
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: IMAGE_RENDERED_PROPS
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
- switch (node.nodeName) {
2037
- case "UserMessage":
2038
- return handleUserMessage(node);
2039
- case "SystemMessage":
2040
- return {
2041
- role: "system",
2042
- content: node.textContent
2043
- };
2044
- case "AssistantMessage":
2045
- return {
2046
- role: "assistant",
2047
- content: node.textContent
2048
- };
2049
- default:
2050
- throw new Error("Invalid top level chat message tags");
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
- system = content;
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
- role,
2330
- content: userContent[0].text
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
- role,
2358
- content: c
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
- role,
2365
- content
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 = props.extraHeaders ? {
2457
- headers: props.extraHeaders
2458
- } : void 0;
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?.input_tokens || 0;
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
- outputUsage = event.usage?.output_tokens;
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
- let outputUsage = 0;
2804
- let inputUsage = 0;
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
- inputUsage = event.usageMetadata.promptTokenCount;
2939
+ tokensUsed.prompt = event.usageMetadata.promptTokenCount;
2818
2940
  }
2819
2941
  if (event.usageMetadata.candidatesTokenCount) {
2820
- outputUsage = event.usageMetadata.candidatesTokenCount;
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
- const tokensUsed = {
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 ChatMessage as C, type DebugMessage as D, type EvaluatorResult as E, type PropsOfAIComponent as F, type SpanContext as G, type SpanStatus as H, ImagePart as I, JSX as J, type Span as K, type LogChatCompletionRequest as L, type SpanEvent as M, NoopLogImplementation as N, type TracingContextKey as O, type Prompt as P, type TracingContext as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, type TracingContextManager as U, type OutputParser as V, jsx as W, jsxDEV as X, jsxs as Y, Fragment as Z, LogImplementation as a, type ContextValues as b, type Context as c, type ReadableSpan as d, type SpanAttributes as e, type SpanExporter as f, type AIComponent as g, type ChatCompletionRequestPayloads as h, type EvaluatorFn as i, type PromptParsed as j, createAIElement as k, AIFragment as l, createContext as m, type ChatRole as n, type ImagePartProps as o, type LogChatCompletionResponse as p, type LogLevel as q, type Logger as r, ConsoleLogger as s, toDebugMessage as t, CombinedLogger as u, type Literal as v, type RenderResult as w, attachedContextSymbol as x, type AIElement as y, type Renderable as z };
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 ChatMessage as C, type DebugMessage as D, type EvaluatorResult as E, type PropsOfAIComponent as F, type SpanContext as G, type SpanStatus as H, ImagePart as I, JSX as J, type Span as K, type LogChatCompletionRequest as L, type SpanEvent as M, NoopLogImplementation as N, type TracingContextKey as O, type Prompt as P, type TracingContext as Q, type RenderContext as R, type SpanProcessor as S, type Tracer as T, type TracingContextManager as U, type OutputParser as V, jsx as W, jsxDEV as X, jsxs as Y, Fragment as Z, LogImplementation as a, type ContextValues as b, type Context as c, type ReadableSpan as d, type SpanAttributes as e, type SpanExporter as f, type AIComponent as g, type ChatCompletionRequestPayloads as h, type EvaluatorFn as i, type PromptParsed as j, createAIElement as k, AIFragment as l, createContext as m, type ChatRole as n, type ImagePartProps as o, type LogChatCompletionResponse as p, type LogLevel as q, type Logger as r, ConsoleLogger as s, toDebugMessage as t, CombinedLogger as u, type Literal as v, type RenderResult as w, attachedContextSymbol as x, type AIElement as y, type Renderable as z };
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 };