@stackfactor/agent-utils 1.2.7 → 1.2.8

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.
@@ -15,8 +15,9 @@ declare const _default: {
15
15
  createAgent: (name: string, modelName: string, systemPrompt: string, tools: any[], responseFormat: any, config: any) => any;
16
16
  runAgent: (agent: any, prompt: string, config: any, onProgress?: Function | null, usageTracker?: UsageTracker | null) => Promise<any>;
17
17
  runPromptWithModel: (modelName: string, config: any, prompt: any, onProgressReport: any, minPercent?: number, maxPercent?: number, expectsJsonResponse?: boolean, schema?: any, agentName?: string, tools?: any[], usageTracker?: UsageTracker | null) => Promise<any>;
18
- runPromptWithModelForImageGeneration: (modelName: string, config: any, prompt: string, options?: any) => Promise<any>;
18
+ runPromptWithModelForImageGeneration: (modelName: string, config: any, prompt: string, options?: any, usageTracker?: UsageTracker | null) => Promise<any>;
19
19
  throwErrorIfNotSuccessful: (response: any) => string;
20
+ updateUsageTrackerForCharacters: (tracker: UsageTracker | null | undefined, modelName: string, characterCount: number, config: any) => void;
20
21
  validateModel: (selectedModel: string, supportedModels: string[]) => string;
21
22
  };
22
23
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AA2BA;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACxC,CAAC;;0CAE2C,GAAG,KAAG,IAAI;wBAkd/C,MAAM,aACD,MAAM,gBACH,MAAM,SACb,GAAG,EAAE,kBACI,GAAG,UACX,GAAG,KACV,GAAG;sBA0BG,GAAG,UACF,MAAM,UACN,GAAG,eACC,QAAQ,GAAG,IAAI,iBACb,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;oCA4XF,MAAM,UACT,GAAG,UACH,GAAG,oBACO,GAAG,eACT,MAAM,eACN,MAAM,wBACG,OAAO,WACpB,GAAG,cACA,MAAM,UACV,GAAG,EAAE,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;sDAmsBF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,KACX,OAAO,CAAC,GAAG,CAAC;0CAt+B8B,GAAG,KAAG,MAAM;mCAoBxC,MAAM,mBACJ,MAAM,EAAE,KACxB,MAAM;;AA2gCT,wBAQE"}
1
+ {"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AA2BA;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACxC,CAAC;;0CAE2C,GAAG,KAAG,IAAI;wBA+jB/C,MAAM,aACD,MAAM,gBACH,MAAM,SACb,GAAG,EAAE,kBACI,GAAG,UACX,GAAG,KACV,GAAG;sBA0BG,GAAG,UACF,MAAM,UACN,GAAG,eACC,QAAQ,GAAG,IAAI,iBACb,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;oCA4XF,MAAM,UACT,GAAG,UACH,GAAG,oBACO,GAAG,eACT,MAAM,eACN,MAAM,wBACG,OAAO,WACpB,GAAG,cACA,MAAM,UACV,GAAG,EAAE,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;sDAusBF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;0CA3+B8B,GAAG,KAAG,MAAM;+CApjB9C,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,kBACD,MAAM,UACd,GAAG,KACV,IAAI;mCAokBU,MAAM,mBACJ,MAAM,EAAE,KACxB,MAAM;;AAkhCT,wBASE"}
@@ -68,6 +68,101 @@ const updateUsageTracker = (tracker, modelName, usage, config) => {
68
68
  tracker.tokens[inputKey] = (tracker.tokens[inputKey] || 0) + inputTokens;
69
69
  tracker.tokens[outputKey] = (tracker.tokens[outputKey] || 0) + outputTokens;
70
70
  };
71
+ /**
72
+ * Adds a single image-generation call's usage to the caller-supplied tracker.
73
+ * Extracts token counts from provider-specific response shapes: OpenAI returns
74
+ * `response.usage` with `input_tokens_details.{text_tokens,image_tokens}` and
75
+ * `output_tokens`; Google returns `response.usageMetadata` with
76
+ * `promptTokensDetails` (modality-keyed) and `candidatesTokenCount` for the
77
+ * generated image. Reads rates from `<model>-input-token-costs`,
78
+ * `<model>-image-input-token-costs`, and `<model>-image-output-token-costs`.
79
+ * No-ops when the tracker or response usage info is absent.
80
+ */
81
+ const updateImageUsageTracker = (tracker, modelName, response, config, provider) => {
82
+ if (!tracker || !modelName || !response)
83
+ return;
84
+ if (typeof tracker.cost !== "number")
85
+ tracker.cost = 0;
86
+ if (!tracker.tokens || typeof tracker.tokens !== "object")
87
+ tracker.tokens = {};
88
+ let textInputTokens = 0;
89
+ let imageInputTokens = 0;
90
+ let imageOutputTokens = 0;
91
+ if (provider === "openai") {
92
+ const usage = response.usage;
93
+ if (!usage)
94
+ return;
95
+ const details = usage.input_tokens_details || {};
96
+ textInputTokens = details.text_tokens || 0;
97
+ imageInputTokens = details.image_tokens || 0;
98
+ // Older shapes report a single input_tokens without modality breakdown.
99
+ if (!textInputTokens && !imageInputTokens && usage.input_tokens) {
100
+ textInputTokens = usage.input_tokens;
101
+ }
102
+ imageOutputTokens = usage.output_tokens || 0;
103
+ }
104
+ else {
105
+ const um = response.usageMetadata;
106
+ if (!um)
107
+ return;
108
+ const promptDetails = Array.isArray(um.promptTokensDetails)
109
+ ? um.promptTokensDetails
110
+ : [];
111
+ for (const d of promptDetails) {
112
+ const modality = String(d?.modality || "").toUpperCase();
113
+ const count = Number(d?.tokenCount) || 0;
114
+ if (modality === "IMAGE")
115
+ imageInputTokens += count;
116
+ else
117
+ textInputTokens += count;
118
+ }
119
+ if (!textInputTokens && !imageInputTokens) {
120
+ textInputTokens = Number(um.promptTokenCount) || 0;
121
+ }
122
+ imageOutputTokens = Number(um.candidatesTokenCount) || 0;
123
+ }
124
+ const textInputRate = getModelRate(modelName, config, "input-token");
125
+ const imageInputRate = getModelRate(modelName, config, "image-input-token");
126
+ const imageOutputRate = getModelRate(modelName, config, "image-output-token");
127
+ const addedCost = (textInputTokens / 1_000_000) * textInputRate +
128
+ (imageInputTokens / 1_000_000) * imageInputRate +
129
+ (imageOutputTokens / 1_000_000) * imageOutputRate;
130
+ if (Number.isFinite(addedCost) && addedCost > 0)
131
+ tracker.cost += addedCost;
132
+ if (textInputTokens > 0) {
133
+ const key = `${modelName}_inputTokens`;
134
+ tracker.tokens[key] = (tracker.tokens[key] || 0) + textInputTokens;
135
+ }
136
+ if (imageInputTokens > 0) {
137
+ const key = `${modelName}_imageInputTokens`;
138
+ tracker.tokens[key] = (tracker.tokens[key] || 0) + imageInputTokens;
139
+ }
140
+ if (imageOutputTokens > 0) {
141
+ const key = `${modelName}_imageOutputTokens`;
142
+ tracker.tokens[key] = (tracker.tokens[key] || 0) + imageOutputTokens;
143
+ }
144
+ };
145
+ /**
146
+ * Adds character-billed usage (e.g. ElevenLabs TTS) to the caller-supplied
147
+ * tracker. There is no provider response to parse — billing is deterministic
148
+ * from the input character count. Reads the rate from
149
+ * `<model>-character-costs` (USD per million characters) and accumulates
150
+ * under `<model>_characters`. No-ops on missing tracker / model / count.
151
+ */
152
+ const updateUsageTrackerForCharacters = (tracker, modelName, characterCount, config) => {
153
+ if (!tracker || !modelName || !characterCount)
154
+ return;
155
+ if (typeof tracker.cost !== "number")
156
+ tracker.cost = 0;
157
+ if (!tracker.tokens || typeof tracker.tokens !== "object")
158
+ tracker.tokens = {};
159
+ const rate = getModelRate(modelName, config, "character");
160
+ const addedCost = (characterCount / 1_000_000) * rate;
161
+ if (Number.isFinite(addedCost) && addedCost > 0)
162
+ tracker.cost += addedCost;
163
+ const key = `${modelName}_characters`;
164
+ tracker.tokens[key] = (tracker.tokens[key] || 0) + characterCount;
165
+ };
71
166
  /**
72
167
  * Extracts a normalized token-usage object from a single LangChain `invoke()`
73
168
  * response. Reads from `usage_metadata` first (standardized in LangChain v1),
@@ -1170,7 +1265,7 @@ const getImageModelProvider = (modelName) => {
1170
1265
  * @returns An object with `url`, `b64_json`, and `revisedPrompt` for a single image,
1171
1266
  * or `{ images: [...] }` for multiple images
1172
1267
  */
1173
- const generateImageWithOpenAI = async (modelName, config, prompt, options) => {
1268
+ const generateImageWithOpenAI = async (modelName, config, prompt, options, usageTracker = null) => {
1174
1269
  const { size = "1024x1024", style = "vivid", responseFormat = "url", n = 1, } = options;
1175
1270
  if (!config.openAIAPIKey) {
1176
1271
  throw errorHandling_js_1.default.create(const_js_1.default.HTTP_CODES.BAD_REQUEST, "OpenAI API key is required for OpenAI image generation");
@@ -1218,6 +1313,7 @@ const generateImageWithOpenAI = async (modelName, config, prompt, options) => {
1218
1313
  }
1219
1314
  }
1220
1315
  const response = await openai.images.generate(requestParams);
1316
+ updateImageUsageTracker(usageTracker, modelName, response, config, "openai");
1221
1317
  // Format response based on number of images
1222
1318
  if (n === 1) {
1223
1319
  const imageData = response.data[0];
@@ -1255,7 +1351,7 @@ const generateImageWithOpenAI = async (modelName, config, prompt, options) => {
1255
1351
  * @returns A single image descriptor `{ b64_json, mimeType }` when one image is
1256
1352
  * requested, or `{ images: [...] }` for multiple images
1257
1353
  */
1258
- const generateImageWithGoogle = async (modelName, config, prompt, options) => {
1354
+ const generateImageWithGoogle = async (modelName, config, prompt, options, usageTracker = null) => {
1259
1355
  const { aspectRatio = "1:1", numberOfImages = 1, negativePrompt = "", } = options;
1260
1356
  if (!config.googleAPIKey) {
1261
1357
  throw errorHandling_js_1.default.create(const_js_1.default.HTTP_CODES.BAD_REQUEST, "Google API key is required for Google image generation");
@@ -1316,6 +1412,7 @@ const generateImageWithGoogle = async (modelName, config, prompt, options) => {
1316
1412
  },
1317
1413
  };
1318
1414
  const response = await ai.models.generateContent(req);
1415
+ updateImageUsageTracker(usageTracker, modelName, response, config, "google");
1319
1416
  // Extract images from response
1320
1417
  const images = [];
1321
1418
  const candidates = response.candidates || [];
@@ -1358,7 +1455,7 @@ const generateImageWithGoogle = async (modelName, config, prompt, options) => {
1358
1455
  * and `generateImageWithGoogle` for full option sets); defaults to `{}`
1359
1456
  * @returns The generated image data object returned by the provider-specific function
1360
1457
  */
1361
- const runPromptWithModelForImageGeneration = async (modelName, config, prompt, options = {}) => {
1458
+ const runPromptWithModelForImageGeneration = async (modelName, config, prompt, options = {}, usageTracker = null) => {
1362
1459
  const provider = getImageModelProvider(modelName);
1363
1460
  if (!provider) {
1364
1461
  throw errorHandling_js_1.default.create(const_js_1.default.HTTP_CODES.BAD_REQUEST, `Unable to determine provider for model: ${modelName}. Model name should start with 'gpt-image-', 'gemini-', or 'imagen-'.`);
@@ -1367,10 +1464,10 @@ const runPromptWithModelForImageGeneration = async (modelName, config, prompt, o
1367
1464
  try {
1368
1465
  let result;
1369
1466
  if (provider === "openai") {
1370
- result = await generateImageWithOpenAI(modelName, config, prompt, options);
1467
+ result = await generateImageWithOpenAI(modelName, config, prompt, options, usageTracker);
1371
1468
  }
1372
1469
  else if (provider === "google") {
1373
- result = await generateImageWithGoogle(modelName, config, prompt, options);
1470
+ result = await generateImageWithGoogle(modelName, config, prompt, options, usageTracker);
1374
1471
  }
1375
1472
  const endTime = Date.now();
1376
1473
  const duration = endTime - startTime;
@@ -1398,5 +1495,6 @@ exports.default = {
1398
1495
  runPromptWithModel,
1399
1496
  runPromptWithModelForImageGeneration,
1400
1497
  throwErrorIfNotSuccessful,
1498
+ updateUsageTrackerForCharacters,
1401
1499
  validateModel,
1402
1500
  };
@@ -15,8 +15,9 @@ declare const _default: {
15
15
  createAgent: (name: string, modelName: string, systemPrompt: string, tools: any[], responseFormat: any, config: any) => any;
16
16
  runAgent: (agent: any, prompt: string, config: any, onProgress?: Function | null, usageTracker?: UsageTracker | null) => Promise<any>;
17
17
  runPromptWithModel: (modelName: string, config: any, prompt: any, onProgressReport: any, minPercent?: number, maxPercent?: number, expectsJsonResponse?: boolean, schema?: any, agentName?: string, tools?: any[], usageTracker?: UsageTracker | null) => Promise<any>;
18
- runPromptWithModelForImageGeneration: (modelName: string, config: any, prompt: string, options?: any) => Promise<any>;
18
+ runPromptWithModelForImageGeneration: (modelName: string, config: any, prompt: string, options?: any, usageTracker?: UsageTracker | null) => Promise<any>;
19
19
  throwErrorIfNotSuccessful: (response: any) => string;
20
+ updateUsageTrackerForCharacters: (tracker: UsageTracker | null | undefined, modelName: string, characterCount: number, config: any) => void;
20
21
  validateModel: (selectedModel: string, supportedModels: string[]) => string;
21
22
  };
22
23
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AA2BA;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACxC,CAAC;;0CAE2C,GAAG,KAAG,IAAI;wBAkd/C,MAAM,aACD,MAAM,gBACH,MAAM,SACb,GAAG,EAAE,kBACI,GAAG,UACX,GAAG,KACV,GAAG;sBA0BG,GAAG,UACF,MAAM,UACN,GAAG,eACC,QAAQ,GAAG,IAAI,iBACb,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;oCA4XF,MAAM,UACT,GAAG,UACH,GAAG,oBACO,GAAG,eACT,MAAM,eACN,MAAM,wBACG,OAAO,WACpB,GAAG,cACA,MAAM,UACV,GAAG,EAAE,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;sDAmsBF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,KACX,OAAO,CAAC,GAAG,CAAC;0CAt+B8B,GAAG,KAAG,MAAM;mCAoBxC,MAAM,mBACJ,MAAM,EAAE,KACxB,MAAM;;AA2gCT,wBAQE"}
1
+ {"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AA2BA;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CACxC,CAAC;;0CAE2C,GAAG,KAAG,IAAI;wBA+jB/C,MAAM,aACD,MAAM,gBACH,MAAM,SACb,GAAG,EAAE,kBACI,GAAG,UACX,GAAG,KACV,GAAG;sBA0BG,GAAG,UACF,MAAM,UACN,GAAG,eACC,QAAQ,GAAG,IAAI,iBACb,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;oCA4XF,MAAM,UACT,GAAG,UACH,GAAG,oBACO,GAAG,eACT,MAAM,eACN,MAAM,wBACG,OAAO,WACpB,GAAG,cACA,MAAM,UACV,GAAG,EAAE,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;sDAusBF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;0CA3+B8B,GAAG,KAAG,MAAM;+CApjB9C,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,kBACD,MAAM,UACd,GAAG,KACV,IAAI;mCAokBU,MAAM,mBACJ,MAAM,EAAE,KACxB,MAAM;;AAkhCT,wBASE"}
@@ -63,6 +63,101 @@ const updateUsageTracker = (tracker, modelName, usage, config) => {
63
63
  tracker.tokens[inputKey] = (tracker.tokens[inputKey] || 0) + inputTokens;
64
64
  tracker.tokens[outputKey] = (tracker.tokens[outputKey] || 0) + outputTokens;
65
65
  };
66
+ /**
67
+ * Adds a single image-generation call's usage to the caller-supplied tracker.
68
+ * Extracts token counts from provider-specific response shapes: OpenAI returns
69
+ * `response.usage` with `input_tokens_details.{text_tokens,image_tokens}` and
70
+ * `output_tokens`; Google returns `response.usageMetadata` with
71
+ * `promptTokensDetails` (modality-keyed) and `candidatesTokenCount` for the
72
+ * generated image. Reads rates from `<model>-input-token-costs`,
73
+ * `<model>-image-input-token-costs`, and `<model>-image-output-token-costs`.
74
+ * No-ops when the tracker or response usage info is absent.
75
+ */
76
+ const updateImageUsageTracker = (tracker, modelName, response, config, provider) => {
77
+ if (!tracker || !modelName || !response)
78
+ return;
79
+ if (typeof tracker.cost !== "number")
80
+ tracker.cost = 0;
81
+ if (!tracker.tokens || typeof tracker.tokens !== "object")
82
+ tracker.tokens = {};
83
+ let textInputTokens = 0;
84
+ let imageInputTokens = 0;
85
+ let imageOutputTokens = 0;
86
+ if (provider === "openai") {
87
+ const usage = response.usage;
88
+ if (!usage)
89
+ return;
90
+ const details = usage.input_tokens_details || {};
91
+ textInputTokens = details.text_tokens || 0;
92
+ imageInputTokens = details.image_tokens || 0;
93
+ // Older shapes report a single input_tokens without modality breakdown.
94
+ if (!textInputTokens && !imageInputTokens && usage.input_tokens) {
95
+ textInputTokens = usage.input_tokens;
96
+ }
97
+ imageOutputTokens = usage.output_tokens || 0;
98
+ }
99
+ else {
100
+ const um = response.usageMetadata;
101
+ if (!um)
102
+ return;
103
+ const promptDetails = Array.isArray(um.promptTokensDetails)
104
+ ? um.promptTokensDetails
105
+ : [];
106
+ for (const d of promptDetails) {
107
+ const modality = String(d?.modality || "").toUpperCase();
108
+ const count = Number(d?.tokenCount) || 0;
109
+ if (modality === "IMAGE")
110
+ imageInputTokens += count;
111
+ else
112
+ textInputTokens += count;
113
+ }
114
+ if (!textInputTokens && !imageInputTokens) {
115
+ textInputTokens = Number(um.promptTokenCount) || 0;
116
+ }
117
+ imageOutputTokens = Number(um.candidatesTokenCount) || 0;
118
+ }
119
+ const textInputRate = getModelRate(modelName, config, "input-token");
120
+ const imageInputRate = getModelRate(modelName, config, "image-input-token");
121
+ const imageOutputRate = getModelRate(modelName, config, "image-output-token");
122
+ const addedCost = (textInputTokens / 1_000_000) * textInputRate +
123
+ (imageInputTokens / 1_000_000) * imageInputRate +
124
+ (imageOutputTokens / 1_000_000) * imageOutputRate;
125
+ if (Number.isFinite(addedCost) && addedCost > 0)
126
+ tracker.cost += addedCost;
127
+ if (textInputTokens > 0) {
128
+ const key = `${modelName}_inputTokens`;
129
+ tracker.tokens[key] = (tracker.tokens[key] || 0) + textInputTokens;
130
+ }
131
+ if (imageInputTokens > 0) {
132
+ const key = `${modelName}_imageInputTokens`;
133
+ tracker.tokens[key] = (tracker.tokens[key] || 0) + imageInputTokens;
134
+ }
135
+ if (imageOutputTokens > 0) {
136
+ const key = `${modelName}_imageOutputTokens`;
137
+ tracker.tokens[key] = (tracker.tokens[key] || 0) + imageOutputTokens;
138
+ }
139
+ };
140
+ /**
141
+ * Adds character-billed usage (e.g. ElevenLabs TTS) to the caller-supplied
142
+ * tracker. There is no provider response to parse — billing is deterministic
143
+ * from the input character count. Reads the rate from
144
+ * `<model>-character-costs` (USD per million characters) and accumulates
145
+ * under `<model>_characters`. No-ops on missing tracker / model / count.
146
+ */
147
+ const updateUsageTrackerForCharacters = (tracker, modelName, characterCount, config) => {
148
+ if (!tracker || !modelName || !characterCount)
149
+ return;
150
+ if (typeof tracker.cost !== "number")
151
+ tracker.cost = 0;
152
+ if (!tracker.tokens || typeof tracker.tokens !== "object")
153
+ tracker.tokens = {};
154
+ const rate = getModelRate(modelName, config, "character");
155
+ const addedCost = (characterCount / 1_000_000) * rate;
156
+ if (Number.isFinite(addedCost) && addedCost > 0)
157
+ tracker.cost += addedCost;
158
+ const key = `${modelName}_characters`;
159
+ tracker.tokens[key] = (tracker.tokens[key] || 0) + characterCount;
160
+ };
66
161
  /**
67
162
  * Extracts a normalized token-usage object from a single LangChain `invoke()`
68
163
  * response. Reads from `usage_metadata` first (standardized in LangChain v1),
@@ -1165,7 +1260,7 @@ const getImageModelProvider = (modelName) => {
1165
1260
  * @returns An object with `url`, `b64_json`, and `revisedPrompt` for a single image,
1166
1261
  * or `{ images: [...] }` for multiple images
1167
1262
  */
1168
- const generateImageWithOpenAI = async (modelName, config, prompt, options) => {
1263
+ const generateImageWithOpenAI = async (modelName, config, prompt, options, usageTracker = null) => {
1169
1264
  const { size = "1024x1024", style = "vivid", responseFormat = "url", n = 1, } = options;
1170
1265
  if (!config.openAIAPIKey) {
1171
1266
  throw errorHandlingHelper.create(constants.HTTP_CODES.BAD_REQUEST, "OpenAI API key is required for OpenAI image generation");
@@ -1213,6 +1308,7 @@ const generateImageWithOpenAI = async (modelName, config, prompt, options) => {
1213
1308
  }
1214
1309
  }
1215
1310
  const response = await openai.images.generate(requestParams);
1311
+ updateImageUsageTracker(usageTracker, modelName, response, config, "openai");
1216
1312
  // Format response based on number of images
1217
1313
  if (n === 1) {
1218
1314
  const imageData = response.data[0];
@@ -1250,7 +1346,7 @@ const generateImageWithOpenAI = async (modelName, config, prompt, options) => {
1250
1346
  * @returns A single image descriptor `{ b64_json, mimeType }` when one image is
1251
1347
  * requested, or `{ images: [...] }` for multiple images
1252
1348
  */
1253
- const generateImageWithGoogle = async (modelName, config, prompt, options) => {
1349
+ const generateImageWithGoogle = async (modelName, config, prompt, options, usageTracker = null) => {
1254
1350
  const { aspectRatio = "1:1", numberOfImages = 1, negativePrompt = "", } = options;
1255
1351
  if (!config.googleAPIKey) {
1256
1352
  throw errorHandlingHelper.create(constants.HTTP_CODES.BAD_REQUEST, "Google API key is required for Google image generation");
@@ -1311,6 +1407,7 @@ const generateImageWithGoogle = async (modelName, config, prompt, options) => {
1311
1407
  },
1312
1408
  };
1313
1409
  const response = await ai.models.generateContent(req);
1410
+ updateImageUsageTracker(usageTracker, modelName, response, config, "google");
1314
1411
  // Extract images from response
1315
1412
  const images = [];
1316
1413
  const candidates = response.candidates || [];
@@ -1353,7 +1450,7 @@ const generateImageWithGoogle = async (modelName, config, prompt, options) => {
1353
1450
  * and `generateImageWithGoogle` for full option sets); defaults to `{}`
1354
1451
  * @returns The generated image data object returned by the provider-specific function
1355
1452
  */
1356
- const runPromptWithModelForImageGeneration = async (modelName, config, prompt, options = {}) => {
1453
+ const runPromptWithModelForImageGeneration = async (modelName, config, prompt, options = {}, usageTracker = null) => {
1357
1454
  const provider = getImageModelProvider(modelName);
1358
1455
  if (!provider) {
1359
1456
  throw errorHandlingHelper.create(constants.HTTP_CODES.BAD_REQUEST, `Unable to determine provider for model: ${modelName}. Model name should start with 'gpt-image-', 'gemini-', or 'imagen-'.`);
@@ -1362,10 +1459,10 @@ const runPromptWithModelForImageGeneration = async (modelName, config, prompt, o
1362
1459
  try {
1363
1460
  let result;
1364
1461
  if (provider === "openai") {
1365
- result = await generateImageWithOpenAI(modelName, config, prompt, options);
1462
+ result = await generateImageWithOpenAI(modelName, config, prompt, options, usageTracker);
1366
1463
  }
1367
1464
  else if (provider === "google") {
1368
- result = await generateImageWithGoogle(modelName, config, prompt, options);
1465
+ result = await generateImageWithGoogle(modelName, config, prompt, options, usageTracker);
1369
1466
  }
1370
1467
  const endTime = Date.now();
1371
1468
  const duration = endTime - startTime;
@@ -1393,5 +1490,6 @@ export default {
1393
1490
  runPromptWithModel,
1394
1491
  runPromptWithModelForImageGeneration,
1395
1492
  throwErrorIfNotSuccessful,
1493
+ updateUsageTrackerForCharacters,
1396
1494
  validateModel,
1397
1495
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.2.7",
6
+ "version": "1.2.8",
7
7
  "description": "",
8
8
  "main": "dist/cjs/index.js",
9
9
  "module": "dist/esm/index.js",