@threaded/ai 1.0.25 → 1.0.27

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.cts CHANGED
@@ -93,6 +93,9 @@ type StreamEvent = {
93
93
  type: 'approval_requested';
94
94
  call: ToolCall;
95
95
  requestId: string;
96
+ } | {
97
+ type: 'usage';
98
+ usage: TokenUsage;
96
99
  };
97
100
  interface ConversationContext {
98
101
  history: Message[];
@@ -108,6 +111,7 @@ interface ConversationContext {
108
111
  toolLimits?: Record<string, number>;
109
112
  toolConfig?: ToolExecutionConfig;
110
113
  abortSignal?: AbortSignal;
114
+ usage?: TokenUsage;
111
115
  }
112
116
  declare enum Inherit {
113
117
  Nothing = 0,
@@ -183,6 +187,11 @@ interface ImageResult {
183
187
  data: string;
184
188
  revisedPrompt?: string;
185
189
  }
190
+ interface TokenUsage {
191
+ promptTokens: number;
192
+ completionTokens: number;
193
+ totalTokens: number;
194
+ }
186
195
 
187
196
  declare const createMCPTools: (client: Client) => Promise<ToolConfig[]>;
188
197
 
@@ -191,6 +200,7 @@ declare const parseModelName: (model: string) => ParsedModel;
191
200
  declare const setKeys: (keys: ApiKeys) => void;
192
201
  declare const getKey: (provider: string) => string;
193
202
  declare const maxCalls: (toolConfig: ToolConfig, maxCalls: number) => ToolConfig;
203
+ declare const addUsage: (existing: TokenUsage | undefined, promptTokens: number, completionTokens: number, totalTokens: number) => TokenUsage;
194
204
 
195
205
  /**
196
206
  * generates embeddings for text using openai or huggingface models
@@ -337,4 +347,4 @@ declare const rateLimited: (config: RateLimitConfig) => <T extends (...args: any
337
347
 
338
348
  declare const compose: (...steps: StepFunction[]) => ComposedFunction;
339
349
 
340
- export { type ApiKeys, type ApprovalRequest, type ApprovalResponse, type ComposedFunction, type ConfigOption, type ConversationContext, IMAGE_EDIT_MODEL_SCHEMA, IMAGE_MODEL_SCHEMA, type ImageConfig, type ImageModelSchema, type ImageResult, Inherit, type JsonSchema, type Message, type ModelConfig, type ParsedModel, type ProviderConfig, type ProviderModels, type RetryOptions, type SchemaProperty, type ScopeConfig, type StandardSchema, type StepFunction, type StreamEvent, type Thread, type ThreadStore, type ToolCall, type ToolCallResult, type ToolConfig, type ToolDefinition, type ToolExecutionConfig, appendToLastRequest, compose, convertMCPSchemaToToolSchema, convertStandardSchemaToJsonSchema, convertStandardSchemaToSchemaProperties, createMCPTools, embed, everyNMessages, everyNTokens, generateApprovalToken, generateImage, getDefaultConfig, getKey, getModelConfig, getOrCreateThread, isStandardSchema, maxCalls, model, noToolsCalled, normalizeSchema, onApprovalRequested, onApprovalResolved, parseModelName, rateLimited, removeApprovalListener, requestApproval, resolveApproval, retry, scope, setKeys, tap, toolConfigToToolDefinition, toolNotUsedInNTurns, toolWasCalled, when };
350
+ export { type ApiKeys, type ApprovalRequest, type ApprovalResponse, type ComposedFunction, type ConfigOption, type ConversationContext, IMAGE_EDIT_MODEL_SCHEMA, IMAGE_MODEL_SCHEMA, type ImageConfig, type ImageModelSchema, type ImageResult, Inherit, type JsonSchema, type Message, type ModelConfig, type ParsedModel, type ProviderConfig, type ProviderModels, type RetryOptions, type SchemaProperty, type ScopeConfig, type StandardSchema, type StepFunction, type StreamEvent, type Thread, type ThreadStore, type TokenUsage, type ToolCall, type ToolCallResult, type ToolConfig, type ToolDefinition, type ToolExecutionConfig, addUsage, appendToLastRequest, compose, convertMCPSchemaToToolSchema, convertStandardSchemaToJsonSchema, convertStandardSchemaToSchemaProperties, createMCPTools, embed, everyNMessages, everyNTokens, generateApprovalToken, generateImage, getDefaultConfig, getKey, getModelConfig, getOrCreateThread, isStandardSchema, maxCalls, model, noToolsCalled, normalizeSchema, onApprovalRequested, onApprovalResolved, parseModelName, rateLimited, removeApprovalListener, requestApproval, resolveApproval, retry, scope, setKeys, tap, toolConfigToToolDefinition, toolNotUsedInNTurns, toolWasCalled, when };
package/dist/index.d.ts CHANGED
@@ -93,6 +93,9 @@ type StreamEvent = {
93
93
  type: 'approval_requested';
94
94
  call: ToolCall;
95
95
  requestId: string;
96
+ } | {
97
+ type: 'usage';
98
+ usage: TokenUsage;
96
99
  };
97
100
  interface ConversationContext {
98
101
  history: Message[];
@@ -108,6 +111,7 @@ interface ConversationContext {
108
111
  toolLimits?: Record<string, number>;
109
112
  toolConfig?: ToolExecutionConfig;
110
113
  abortSignal?: AbortSignal;
114
+ usage?: TokenUsage;
111
115
  }
112
116
  declare enum Inherit {
113
117
  Nothing = 0,
@@ -183,6 +187,11 @@ interface ImageResult {
183
187
  data: string;
184
188
  revisedPrompt?: string;
185
189
  }
190
+ interface TokenUsage {
191
+ promptTokens: number;
192
+ completionTokens: number;
193
+ totalTokens: number;
194
+ }
186
195
 
187
196
  declare const createMCPTools: (client: Client) => Promise<ToolConfig[]>;
188
197
 
@@ -191,6 +200,7 @@ declare const parseModelName: (model: string) => ParsedModel;
191
200
  declare const setKeys: (keys: ApiKeys) => void;
192
201
  declare const getKey: (provider: string) => string;
193
202
  declare const maxCalls: (toolConfig: ToolConfig, maxCalls: number) => ToolConfig;
203
+ declare const addUsage: (existing: TokenUsage | undefined, promptTokens: number, completionTokens: number, totalTokens: number) => TokenUsage;
194
204
 
195
205
  /**
196
206
  * generates embeddings for text using openai or huggingface models
@@ -337,4 +347,4 @@ declare const rateLimited: (config: RateLimitConfig) => <T extends (...args: any
337
347
 
338
348
  declare const compose: (...steps: StepFunction[]) => ComposedFunction;
339
349
 
340
- export { type ApiKeys, type ApprovalRequest, type ApprovalResponse, type ComposedFunction, type ConfigOption, type ConversationContext, IMAGE_EDIT_MODEL_SCHEMA, IMAGE_MODEL_SCHEMA, type ImageConfig, type ImageModelSchema, type ImageResult, Inherit, type JsonSchema, type Message, type ModelConfig, type ParsedModel, type ProviderConfig, type ProviderModels, type RetryOptions, type SchemaProperty, type ScopeConfig, type StandardSchema, type StepFunction, type StreamEvent, type Thread, type ThreadStore, type ToolCall, type ToolCallResult, type ToolConfig, type ToolDefinition, type ToolExecutionConfig, appendToLastRequest, compose, convertMCPSchemaToToolSchema, convertStandardSchemaToJsonSchema, convertStandardSchemaToSchemaProperties, createMCPTools, embed, everyNMessages, everyNTokens, generateApprovalToken, generateImage, getDefaultConfig, getKey, getModelConfig, getOrCreateThread, isStandardSchema, maxCalls, model, noToolsCalled, normalizeSchema, onApprovalRequested, onApprovalResolved, parseModelName, rateLimited, removeApprovalListener, requestApproval, resolveApproval, retry, scope, setKeys, tap, toolConfigToToolDefinition, toolNotUsedInNTurns, toolWasCalled, when };
350
+ export { type ApiKeys, type ApprovalRequest, type ApprovalResponse, type ComposedFunction, type ConfigOption, type ConversationContext, IMAGE_EDIT_MODEL_SCHEMA, IMAGE_MODEL_SCHEMA, type ImageConfig, type ImageModelSchema, type ImageResult, Inherit, type JsonSchema, type Message, type ModelConfig, type ParsedModel, type ProviderConfig, type ProviderModels, type RetryOptions, type SchemaProperty, type ScopeConfig, type StandardSchema, type StepFunction, type StreamEvent, type Thread, type ThreadStore, type TokenUsage, type ToolCall, type ToolCallResult, type ToolConfig, type ToolDefinition, type ToolExecutionConfig, addUsage, appendToLastRequest, compose, convertMCPSchemaToToolSchema, convertStandardSchemaToJsonSchema, convertStandardSchemaToSchemaProperties, createMCPTools, embed, everyNMessages, everyNTokens, generateApprovalToken, generateImage, getDefaultConfig, getKey, getModelConfig, getOrCreateThread, isStandardSchema, maxCalls, model, noToolsCalled, normalizeSchema, onApprovalRequested, onApprovalResolved, parseModelName, rateLimited, removeApprovalListener, requestApproval, resolveApproval, retry, scope, setKeys, tap, toolConfigToToolDefinition, toolNotUsedInNTurns, toolWasCalled, when };
package/dist/index.js CHANGED
@@ -149,6 +149,11 @@ var maxCalls = (toolConfig, maxCalls2) => ({
149
149
  ...toolConfig,
150
150
  _maxCalls: maxCalls2
151
151
  });
152
+ var addUsage = (existing, promptTokens, completionTokens, totalTokens) => ({
153
+ promptTokens: (existing?.promptTokens || 0) + promptTokens,
154
+ completionTokens: (existing?.completionTokens || 0) + completionTokens,
155
+ totalTokens: (existing?.totalTokens || 0) + totalTokens
156
+ });
152
157
 
153
158
  // src/embed.ts
154
159
  var modelCache = /* @__PURE__ */ new Map();
@@ -460,7 +465,8 @@ var callOpenAI = async (config, ctx) => {
460
465
  const body = {
461
466
  model: model2,
462
467
  messages,
463
- stream: !!ctx.stream
468
+ stream: !!ctx.stream,
469
+ ...ctx.stream && { stream_options: { include_usage: true } }
464
470
  };
465
471
  if (schema) {
466
472
  body.response_format = {
@@ -505,7 +511,8 @@ var callOpenAI = async (config, ctx) => {
505
511
  return {
506
512
  ...ctx,
507
513
  lastResponse: msg,
508
- history: [...ctx.history, msg]
514
+ history: [...ctx.history, msg],
515
+ usage: addUsage(ctx.usage, data.usage?.prompt_tokens || 0, data.usage?.completion_tokens || 0, data.usage?.total_tokens || 0)
509
516
  };
510
517
  };
511
518
  var handleOpenAIStream = async (response, ctx) => {
@@ -514,6 +521,7 @@ var handleOpenAIStream = async (response, ctx) => {
514
521
  let fullContent = "";
515
522
  let toolCalls = [];
516
523
  let buffer = "";
524
+ let streamUsage = null;
517
525
  try {
518
526
  while (true) {
519
527
  if (ctx.abortSignal?.aborted) {
@@ -531,6 +539,9 @@ var handleOpenAIStream = async (response, ctx) => {
531
539
  if (!data) continue;
532
540
  try {
533
541
  const parsed = JSON.parse(data);
542
+ if (parsed.usage) {
543
+ streamUsage = parsed.usage;
544
+ }
534
545
  const delta = parsed.choices?.[0]?.delta;
535
546
  if (delta?.content) {
536
547
  fullContent += delta.content;
@@ -556,10 +567,15 @@ var handleOpenAIStream = async (response, ctx) => {
556
567
  if (toolCalls.length > 0) {
557
568
  msg.tool_calls = toolCalls;
558
569
  }
570
+ const usage = addUsage(ctx.usage, streamUsage?.prompt_tokens || 0, streamUsage?.completion_tokens || 0, streamUsage?.total_tokens || 0);
571
+ if (ctx.stream && streamUsage) {
572
+ ctx.stream({ type: "usage", usage });
573
+ }
559
574
  return {
560
575
  ...ctx,
561
576
  lastResponse: msg,
562
- history: [...ctx.history, msg]
577
+ history: [...ctx.history, msg],
578
+ usage
563
579
  };
564
580
  };
565
581
 
@@ -695,10 +711,13 @@ Return only the JSON object, no other text or formatting.`;
695
711
  }
696
712
  ];
697
713
  }
714
+ const inputTokens = data.usage?.input_tokens || 0;
715
+ const outputTokens = data.usage?.output_tokens || 0;
698
716
  return {
699
717
  ...ctx,
700
718
  lastResponse: msg,
701
- history: [...ctx.history, msg]
719
+ history: [...ctx.history, msg],
720
+ usage: addUsage(ctx.usage, inputTokens, outputTokens, inputTokens + outputTokens)
702
721
  };
703
722
  };
704
723
  var handleAnthropicStream = async (response, ctx) => {
@@ -707,6 +726,8 @@ var handleAnthropicStream = async (response, ctx) => {
707
726
  let fullContent = "";
708
727
  const toolCalls = [];
709
728
  let buffer = "";
729
+ let inputTokens = 0;
730
+ let outputTokens = 0;
710
731
  try {
711
732
  while (true) {
712
733
  if (ctx.abortSignal?.aborted) {
@@ -723,6 +744,12 @@ var handleAnthropicStream = async (response, ctx) => {
723
744
  if (!data) continue;
724
745
  try {
725
746
  const parsed = JSON.parse(data);
747
+ if (parsed.type === "message_start" && parsed.message?.usage) {
748
+ inputTokens = parsed.message.usage.input_tokens || 0;
749
+ }
750
+ if (parsed.type === "message_delta" && parsed.usage) {
751
+ outputTokens = parsed.usage.output_tokens || 0;
752
+ }
726
753
  if (parsed.type === "content_block_delta" && parsed.delta?.text) {
727
754
  fullContent += parsed.delta.text;
728
755
  if (ctx.stream) {
@@ -762,10 +789,15 @@ var handleAnthropicStream = async (response, ctx) => {
762
789
  if (toolCalls.length > 0) {
763
790
  msg.tool_calls = toolCalls.map(({ index, ...tc }) => tc);
764
791
  }
792
+ const usage = addUsage(ctx.usage, inputTokens, outputTokens, inputTokens + outputTokens);
793
+ if (ctx.stream && (inputTokens || outputTokens)) {
794
+ ctx.stream({ type: "usage", usage });
795
+ }
765
796
  return {
766
797
  ...ctx,
767
798
  lastResponse: msg,
768
- history: [...ctx.history, msg]
799
+ history: [...ctx.history, msg],
800
+ usage
769
801
  };
770
802
  };
771
803
 
@@ -918,10 +950,12 @@ var callGoogle = async (config, ctx) => {
918
950
  if (toolCalls.length > 0) {
919
951
  msg.tool_calls = toolCalls;
920
952
  }
953
+ const um = data.usageMetadata;
921
954
  return {
922
955
  ...ctx,
923
956
  lastResponse: msg,
924
- history: [...ctx.history, msg]
957
+ history: [...ctx.history, msg],
958
+ usage: addUsage(ctx.usage, um?.promptTokenCount || 0, um?.candidatesTokenCount || 0, um?.totalTokenCount || 0)
925
959
  };
926
960
  };
927
961
  var handleGoogleStream = async (response, ctx) => {
@@ -930,6 +964,7 @@ var handleGoogleStream = async (response, ctx) => {
930
964
  let fullContent = "";
931
965
  const toolCalls = [];
932
966
  let buffer = "";
967
+ let usageMetadata = null;
933
968
  try {
934
969
  while (true) {
935
970
  if (ctx.abortSignal?.aborted) {
@@ -946,6 +981,9 @@ var handleGoogleStream = async (response, ctx) => {
946
981
  if (!data) continue;
947
982
  try {
948
983
  const parsed = JSON.parse(data);
984
+ if (parsed.usageMetadata) {
985
+ usageMetadata = parsed.usageMetadata;
986
+ }
949
987
  const candidate = parsed.candidates?.[0];
950
988
  const parts = candidate?.content?.parts || [];
951
989
  for (const part of parts) {
@@ -985,18 +1023,75 @@ var handleGoogleStream = async (response, ctx) => {
985
1023
  if (toolCalls.length > 0) {
986
1024
  msg.tool_calls = toolCalls;
987
1025
  }
1026
+ const um = usageMetadata;
1027
+ const usage = addUsage(ctx.usage, um?.promptTokenCount || 0, um?.candidatesTokenCount || 0, um?.totalTokenCount || 0);
1028
+ if (ctx.stream && um) {
1029
+ ctx.stream({ type: "usage", usage });
1030
+ }
988
1031
  return {
989
1032
  ...ctx,
990
1033
  lastResponse: msg,
991
- history: [...ctx.history, msg]
1034
+ history: [...ctx.history, msg],
1035
+ usage
992
1036
  };
993
1037
  };
994
1038
 
995
1039
  // src/providers/huggingface.ts
1040
+ var modelCache2 = /* @__PURE__ */ new Map();
1041
+ var formatMessages = (instructions, history) => {
1042
+ const messages = [];
1043
+ if (instructions) {
1044
+ messages.push({ role: "system", content: instructions });
1045
+ }
1046
+ for (const msg of history) {
1047
+ messages.push({ role: msg.role, content: msg.content });
1048
+ }
1049
+ return messages;
1050
+ };
996
1051
  var callHuggingFace = async (config, ctx) => {
997
- throw new Error(
998
- "Hugging Face provider not yet implemented. Use openai/, anthropic/, or google/ prefixes."
999
- );
1052
+ const { model: model2, instructions, schema } = config;
1053
+ const { pipeline } = await import("@huggingface/transformers");
1054
+ if (!modelCache2.has(model2)) {
1055
+ const generator2 = await pipeline("text-generation", model2, {
1056
+ dtype: "q4f16"
1057
+ });
1058
+ modelCache2.set(model2, generator2);
1059
+ }
1060
+ const generator = modelCache2.get(model2);
1061
+ const messages = formatMessages(instructions, ctx.history);
1062
+ if (schema) {
1063
+ const schemaMsg = messages.find((m) => m.role === "system");
1064
+ const schemaInstructions = [
1065
+ "you must respond with valid JSON matching this schema:",
1066
+ JSON.stringify(schema.schema, null, 2),
1067
+ "respond ONLY with the JSON object, no other text."
1068
+ ].join("\n");
1069
+ if (schemaMsg) {
1070
+ schemaMsg.content += "\n\n" + schemaInstructions;
1071
+ } else {
1072
+ messages.unshift({ role: "system", content: schemaInstructions });
1073
+ }
1074
+ }
1075
+ const output = await generator(messages, {
1076
+ max_new_tokens: 2048,
1077
+ do_sample: false
1078
+ });
1079
+ const generatedMessages = output[0].generated_text;
1080
+ const lastMessage = generatedMessages.at(-1);
1081
+ const content = lastMessage?.content || "";
1082
+ const msg = {
1083
+ role: "assistant",
1084
+ content
1085
+ };
1086
+ if (ctx.stream) {
1087
+ ctx.stream({ type: "content", content });
1088
+ }
1089
+ return {
1090
+ ...ctx,
1091
+ lastResponse: msg,
1092
+ history: [...ctx.history, msg],
1093
+ usage: addUsage(ctx.usage, 0, 0, 0)
1094
+ };
1000
1095
  };
1001
1096
 
1002
1097
  // src/providers/xai.ts
@@ -1037,7 +1132,8 @@ var callXAI = async (config, ctx) => {
1037
1132
  const body = {
1038
1133
  model: model2,
1039
1134
  messages,
1040
- stream: !!ctx.stream
1135
+ stream: !!ctx.stream,
1136
+ ...ctx.stream && { stream_options: { include_usage: true } }
1041
1137
  };
1042
1138
  if (schema) {
1043
1139
  body.response_format = {
@@ -1082,7 +1178,8 @@ var callXAI = async (config, ctx) => {
1082
1178
  return {
1083
1179
  ...ctx,
1084
1180
  lastResponse: msg,
1085
- history: [...ctx.history, msg]
1181
+ history: [...ctx.history, msg],
1182
+ usage: addUsage(ctx.usage, data.usage?.prompt_tokens || 0, data.usage?.completion_tokens || 0, data.usage?.total_tokens || 0)
1086
1183
  };
1087
1184
  };
1088
1185
  var handleXAIStream = async (response, ctx) => {
@@ -1091,6 +1188,7 @@ var handleXAIStream = async (response, ctx) => {
1091
1188
  let fullContent = "";
1092
1189
  let toolCalls = [];
1093
1190
  let buffer = "";
1191
+ let streamUsage = null;
1094
1192
  try {
1095
1193
  while (true) {
1096
1194
  if (ctx.abortSignal?.aborted) {
@@ -1108,6 +1206,9 @@ var handleXAIStream = async (response, ctx) => {
1108
1206
  if (!data) continue;
1109
1207
  try {
1110
1208
  const parsed = JSON.parse(data);
1209
+ if (parsed.usage) {
1210
+ streamUsage = parsed.usage;
1211
+ }
1111
1212
  const delta = parsed.choices?.[0]?.delta;
1112
1213
  if (delta?.content) {
1113
1214
  fullContent += delta.content;
@@ -1133,10 +1234,15 @@ var handleXAIStream = async (response, ctx) => {
1133
1234
  if (toolCalls.length > 0) {
1134
1235
  msg.tool_calls = toolCalls;
1135
1236
  }
1237
+ const usage = addUsage(ctx.usage, streamUsage?.prompt_tokens || 0, streamUsage?.completion_tokens || 0, streamUsage?.total_tokens || 0);
1238
+ if (ctx.stream && streamUsage) {
1239
+ ctx.stream({ type: "usage", usage });
1240
+ }
1136
1241
  return {
1137
1242
  ...ctx,
1138
1243
  lastResponse: msg,
1139
- history: [...ctx.history, msg]
1244
+ history: [...ctx.history, msg],
1245
+ usage
1140
1246
  };
1141
1247
  };
1142
1248
 
@@ -1169,7 +1275,8 @@ var callLocal = async (config, ctx) => {
1169
1275
  const body = {
1170
1276
  model: model2,
1171
1277
  messages,
1172
- stream: !!ctx.stream
1278
+ stream: !!ctx.stream,
1279
+ ...ctx.stream && { stream_options: { include_usage: true } }
1173
1280
  };
1174
1281
  if (schema) {
1175
1282
  body.response_format = {
@@ -1217,7 +1324,8 @@ var callLocal = async (config, ctx) => {
1217
1324
  return {
1218
1325
  ...ctx,
1219
1326
  lastResponse: msg,
1220
- history: [...ctx.history, msg]
1327
+ history: [...ctx.history, msg],
1328
+ usage: addUsage(ctx.usage, data.usage?.prompt_tokens || 0, data.usage?.completion_tokens || 0, data.usage?.total_tokens || 0)
1221
1329
  };
1222
1330
  };
1223
1331
  var handleLocalStream = async (response, ctx) => {
@@ -1226,6 +1334,7 @@ var handleLocalStream = async (response, ctx) => {
1226
1334
  let fullContent = "";
1227
1335
  let toolCalls = [];
1228
1336
  let buffer = "";
1337
+ let streamUsage = null;
1229
1338
  try {
1230
1339
  while (true) {
1231
1340
  if (ctx.abortSignal?.aborted) {
@@ -1243,6 +1352,9 @@ var handleLocalStream = async (response, ctx) => {
1243
1352
  if (!data) continue;
1244
1353
  try {
1245
1354
  const parsed = JSON.parse(data);
1355
+ if (parsed.usage) {
1356
+ streamUsage = parsed.usage;
1357
+ }
1246
1358
  const delta = parsed.choices?.[0]?.delta;
1247
1359
  if (delta?.content) {
1248
1360
  fullContent += delta.content;
@@ -1268,10 +1380,15 @@ var handleLocalStream = async (response, ctx) => {
1268
1380
  if (toolCalls.length > 0) {
1269
1381
  msg.tool_calls = toolCalls;
1270
1382
  }
1383
+ const usage = addUsage(ctx.usage, streamUsage?.prompt_tokens || 0, streamUsage?.completion_tokens || 0, streamUsage?.total_tokens || 0);
1384
+ if (ctx.stream && streamUsage) {
1385
+ ctx.stream({ type: "usage", usage });
1386
+ }
1271
1387
  return {
1272
1388
  ...ctx,
1273
1389
  lastResponse: msg,
1274
- history: [...ctx.history, msg]
1390
+ history: [...ctx.history, msg],
1391
+ usage
1275
1392
  };
1276
1393
  };
1277
1394
 
@@ -1788,6 +1905,7 @@ var scopeContext = (config, ctx) => {
1788
1905
  }
1789
1906
  scopedCtx.stream = ctx.stream;
1790
1907
  scopedCtx.abortSignal = ctx.abortSignal;
1908
+ scopedCtx.usage = ctx.usage;
1791
1909
  if (config.tools) {
1792
1910
  const toolDefinitions = config.tools.map(toolConfigToToolDefinition);
1793
1911
  const toolExecutors = config.tools.reduce(
@@ -1841,7 +1959,8 @@ var scope = (config, ...steps) => {
1841
1959
  history: config.silent ? ctx.history : scopedCtx.history,
1842
1960
  lastResponse: config.silent ? ctx.lastResponse : scopedCtx.lastResponse,
1843
1961
  lastRequest: config.silent ? ctx.lastRequest : scopedCtx.lastRequest,
1844
- stopReason: config.silent ? ctx.stopReason : scopedCtx.stopReason
1962
+ stopReason: config.silent ? ctx.stopReason : scopedCtx.stopReason,
1963
+ usage: scopedCtx.usage
1845
1964
  };
1846
1965
  };
1847
1966
  };
@@ -1902,6 +2021,7 @@ export {
1902
2021
  IMAGE_EDIT_MODEL_SCHEMA,
1903
2022
  IMAGE_MODEL_SCHEMA,
1904
2023
  Inherit,
2024
+ addUsage,
1905
2025
  appendToLastRequest,
1906
2026
  compose,
1907
2027
  convertMCPSchemaToToolSchema,