@stackfactor/agent-utils 1.2.10 → 1.2.11
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AAgCA;;;;;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;wBA6lB/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;sDAstBF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;0CA1/B8B,GAAG,KAAG,MAAM;+CA/jB9C,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,kBACD,MAAM,UACd,GAAG,KACV,IAAI;mCA+kBU,MAAM,mBACJ,MAAM,EAAE,KACxB,MAAM;;AAiiCT,wBASE"}
|
package/dist/cjs/langChain.js
CHANGED
|
@@ -56,7 +56,19 @@ const updateUsageTracker = (tracker, modelName, usage, config) => {
|
|
|
56
56
|
if (!tracker.tokens || typeof tracker.tokens !== "object")
|
|
57
57
|
tracker.tokens = {};
|
|
58
58
|
const inputTokens = usage.input_tokens || 0;
|
|
59
|
-
const
|
|
59
|
+
const visibleOutputTokens = usage.output_tokens || 0;
|
|
60
|
+
const totalTokens = usage.total_tokens || 0;
|
|
61
|
+
// Recover reasoning/"thinking" tokens the provider leaves out of
|
|
62
|
+
// `output_tokens`. Gemini reports its thoughts only in `totalTokenCount`, so
|
|
63
|
+
// `total - input - visibleOutput` is the thinking output the caller was still
|
|
64
|
+
// billed for. Providers that already fold reasoning into `output_tokens`
|
|
65
|
+
// (Anthropic, OpenAI) report `total == input + output`, so this adds 0.
|
|
66
|
+
// Reasoning is charged at the output rate, so we treat it as output for both
|
|
67
|
+
// the token counters and the cost.
|
|
68
|
+
const reasoningTokens = totalTokens > 0
|
|
69
|
+
? Math.max(0, totalTokens - inputTokens - visibleOutputTokens)
|
|
70
|
+
: 0;
|
|
71
|
+
const outputTokens = visibleOutputTokens + reasoningTokens;
|
|
60
72
|
const inputRate = getModelRate(modelName, config, "input-token");
|
|
61
73
|
const outputRate = getModelRate(modelName, config, "output-token");
|
|
62
74
|
const addedCost = (inputTokens / 1_000_000) * inputRate +
|
|
@@ -122,7 +134,12 @@ const updateImageUsageTracker = (tracker, modelName, response, config, provider)
|
|
|
122
134
|
imageOutputTokens = Number(um.candidatesTokenCount) || 0;
|
|
123
135
|
}
|
|
124
136
|
const textInputRate = getModelRate(modelName, config, "input-token");
|
|
125
|
-
|
|
137
|
+
// Reference-image input tokens are billed at the model's input rate. Configs
|
|
138
|
+
// that don't define a dedicated `<model>-image-input-token-costs` (the common
|
|
139
|
+
// case — image models charge all input at one rate and only differ on output)
|
|
140
|
+
// fall back to the text input rate rather than silently billing image input
|
|
141
|
+
// at $0.
|
|
142
|
+
const imageInputRate = getModelRate(modelName, config, "image-input-token") || textInputRate;
|
|
126
143
|
const imageOutputRate = getModelRate(modelName, config, "image-output-token");
|
|
127
144
|
const addedCost = (textInputTokens / 1_000_000) * textInputRate +
|
|
128
145
|
(imageInputTokens / 1_000_000) * imageInputRate +
|
|
@@ -176,6 +193,7 @@ const extractUsageFromInvoke = (response) => {
|
|
|
176
193
|
return {
|
|
177
194
|
input_tokens: um.input_tokens || 0,
|
|
178
195
|
output_tokens: um.output_tokens || 0,
|
|
196
|
+
total_tokens: um.total_tokens || 0,
|
|
179
197
|
};
|
|
180
198
|
}
|
|
181
199
|
const rm = response.response_metadata;
|
|
@@ -183,12 +201,14 @@ const extractUsageFromInvoke = (response) => {
|
|
|
183
201
|
return {
|
|
184
202
|
input_tokens: rm.usage.input_tokens || rm.usage.prompt_tokens || 0,
|
|
185
203
|
output_tokens: rm.usage.output_tokens || rm.usage.completion_tokens || 0,
|
|
204
|
+
total_tokens: rm.usage.total_tokens || rm.usage.total_token_count || 0,
|
|
186
205
|
};
|
|
187
206
|
}
|
|
188
207
|
if (rm?.tokenUsage) {
|
|
189
208
|
return {
|
|
190
209
|
input_tokens: rm.tokenUsage.promptTokens || 0,
|
|
191
210
|
output_tokens: rm.tokenUsage.completionTokens || 0,
|
|
211
|
+
total_tokens: rm.tokenUsage.totalTokens || 0,
|
|
192
212
|
};
|
|
193
213
|
}
|
|
194
214
|
return null;
|
|
@@ -205,6 +225,7 @@ const accumulateChunkUsage = (acc, chunk) => {
|
|
|
205
225
|
if (um) {
|
|
206
226
|
acc.input_tokens += um.input_tokens || 0;
|
|
207
227
|
acc.output_tokens += um.output_tokens || 0;
|
|
228
|
+
acc.total_tokens += um.total_tokens || 0;
|
|
208
229
|
return acc;
|
|
209
230
|
}
|
|
210
231
|
const rm = chunk.response_metadata;
|
|
@@ -212,6 +233,8 @@ const accumulateChunkUsage = (acc, chunk) => {
|
|
|
212
233
|
acc.input_tokens += rm.usage.input_tokens || rm.usage.prompt_tokens || 0;
|
|
213
234
|
acc.output_tokens +=
|
|
214
235
|
rm.usage.output_tokens || rm.usage.completion_tokens || 0;
|
|
236
|
+
acc.total_tokens +=
|
|
237
|
+
rm.usage.total_tokens || rm.usage.total_token_count || 0;
|
|
215
238
|
}
|
|
216
239
|
return acc;
|
|
217
240
|
};
|
|
@@ -224,13 +247,18 @@ const sumAgentResponseUsage = (response) => {
|
|
|
224
247
|
const messages = response?.messages;
|
|
225
248
|
if (!Array.isArray(messages) || messages.length === 0)
|
|
226
249
|
return null;
|
|
227
|
-
const total = {
|
|
250
|
+
const total = {
|
|
251
|
+
input_tokens: 0,
|
|
252
|
+
output_tokens: 0,
|
|
253
|
+
total_tokens: 0,
|
|
254
|
+
};
|
|
228
255
|
let found = false;
|
|
229
256
|
for (const msg of messages) {
|
|
230
257
|
const um = msg?.usage_metadata;
|
|
231
258
|
if (um) {
|
|
232
259
|
total.input_tokens += um.input_tokens || 0;
|
|
233
260
|
total.output_tokens += um.output_tokens || 0;
|
|
261
|
+
total.total_tokens += um.total_tokens || 0;
|
|
234
262
|
found = true;
|
|
235
263
|
}
|
|
236
264
|
}
|
|
@@ -1054,7 +1082,11 @@ const runPromptWithModel = async (modelName, config, prompt, onProgressReport, m
|
|
|
1054
1082
|
while (true) {
|
|
1055
1083
|
let rawContent = "";
|
|
1056
1084
|
let chunkCount = 0;
|
|
1057
|
-
let streamUsage = {
|
|
1085
|
+
let streamUsage = {
|
|
1086
|
+
input_tokens: 0,
|
|
1087
|
+
output_tokens: 0,
|
|
1088
|
+
total_tokens: 0,
|
|
1089
|
+
};
|
|
1058
1090
|
// Inner loop: wait + retry on 429 around stream setup and consumption.
|
|
1059
1091
|
// Usage is only recorded on a successful stream — partial streams that
|
|
1060
1092
|
// error out with a rate limit are not counted. A 429 fired mid-stream
|
|
@@ -1063,7 +1095,7 @@ const runPromptWithModel = async (modelName, config, prompt, onProgressReport, m
|
|
|
1063
1095
|
while (true) {
|
|
1064
1096
|
rawContent = "";
|
|
1065
1097
|
chunkCount = 0;
|
|
1066
|
-
streamUsage = { input_tokens: 0, output_tokens: 0 };
|
|
1098
|
+
streamUsage = { input_tokens: 0, output_tokens: 0, total_tokens: 0 };
|
|
1067
1099
|
try {
|
|
1068
1100
|
// Honour caller cancellation: passing the signal tears down the
|
|
1069
1101
|
// upstream HTTP request so a cancelled call stops billing tokens.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AAgCA;;;;;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;wBA6lB/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;sDAstBF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;0CA1/B8B,GAAG,KAAG,MAAM;+CA/jB9C,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,kBACD,MAAM,UACd,GAAG,KACV,IAAI;mCA+kBU,MAAM,mBACJ,MAAM,EAAE,KACxB,MAAM;;AAiiCT,wBASE"}
|
package/dist/esm/langChain.js
CHANGED
|
@@ -51,7 +51,19 @@ const updateUsageTracker = (tracker, modelName, usage, config) => {
|
|
|
51
51
|
if (!tracker.tokens || typeof tracker.tokens !== "object")
|
|
52
52
|
tracker.tokens = {};
|
|
53
53
|
const inputTokens = usage.input_tokens || 0;
|
|
54
|
-
const
|
|
54
|
+
const visibleOutputTokens = usage.output_tokens || 0;
|
|
55
|
+
const totalTokens = usage.total_tokens || 0;
|
|
56
|
+
// Recover reasoning/"thinking" tokens the provider leaves out of
|
|
57
|
+
// `output_tokens`. Gemini reports its thoughts only in `totalTokenCount`, so
|
|
58
|
+
// `total - input - visibleOutput` is the thinking output the caller was still
|
|
59
|
+
// billed for. Providers that already fold reasoning into `output_tokens`
|
|
60
|
+
// (Anthropic, OpenAI) report `total == input + output`, so this adds 0.
|
|
61
|
+
// Reasoning is charged at the output rate, so we treat it as output for both
|
|
62
|
+
// the token counters and the cost.
|
|
63
|
+
const reasoningTokens = totalTokens > 0
|
|
64
|
+
? Math.max(0, totalTokens - inputTokens - visibleOutputTokens)
|
|
65
|
+
: 0;
|
|
66
|
+
const outputTokens = visibleOutputTokens + reasoningTokens;
|
|
55
67
|
const inputRate = getModelRate(modelName, config, "input-token");
|
|
56
68
|
const outputRate = getModelRate(modelName, config, "output-token");
|
|
57
69
|
const addedCost = (inputTokens / 1_000_000) * inputRate +
|
|
@@ -117,7 +129,12 @@ const updateImageUsageTracker = (tracker, modelName, response, config, provider)
|
|
|
117
129
|
imageOutputTokens = Number(um.candidatesTokenCount) || 0;
|
|
118
130
|
}
|
|
119
131
|
const textInputRate = getModelRate(modelName, config, "input-token");
|
|
120
|
-
|
|
132
|
+
// Reference-image input tokens are billed at the model's input rate. Configs
|
|
133
|
+
// that don't define a dedicated `<model>-image-input-token-costs` (the common
|
|
134
|
+
// case — image models charge all input at one rate and only differ on output)
|
|
135
|
+
// fall back to the text input rate rather than silently billing image input
|
|
136
|
+
// at $0.
|
|
137
|
+
const imageInputRate = getModelRate(modelName, config, "image-input-token") || textInputRate;
|
|
121
138
|
const imageOutputRate = getModelRate(modelName, config, "image-output-token");
|
|
122
139
|
const addedCost = (textInputTokens / 1_000_000) * textInputRate +
|
|
123
140
|
(imageInputTokens / 1_000_000) * imageInputRate +
|
|
@@ -171,6 +188,7 @@ const extractUsageFromInvoke = (response) => {
|
|
|
171
188
|
return {
|
|
172
189
|
input_tokens: um.input_tokens || 0,
|
|
173
190
|
output_tokens: um.output_tokens || 0,
|
|
191
|
+
total_tokens: um.total_tokens || 0,
|
|
174
192
|
};
|
|
175
193
|
}
|
|
176
194
|
const rm = response.response_metadata;
|
|
@@ -178,12 +196,14 @@ const extractUsageFromInvoke = (response) => {
|
|
|
178
196
|
return {
|
|
179
197
|
input_tokens: rm.usage.input_tokens || rm.usage.prompt_tokens || 0,
|
|
180
198
|
output_tokens: rm.usage.output_tokens || rm.usage.completion_tokens || 0,
|
|
199
|
+
total_tokens: rm.usage.total_tokens || rm.usage.total_token_count || 0,
|
|
181
200
|
};
|
|
182
201
|
}
|
|
183
202
|
if (rm?.tokenUsage) {
|
|
184
203
|
return {
|
|
185
204
|
input_tokens: rm.tokenUsage.promptTokens || 0,
|
|
186
205
|
output_tokens: rm.tokenUsage.completionTokens || 0,
|
|
206
|
+
total_tokens: rm.tokenUsage.totalTokens || 0,
|
|
187
207
|
};
|
|
188
208
|
}
|
|
189
209
|
return null;
|
|
@@ -200,6 +220,7 @@ const accumulateChunkUsage = (acc, chunk) => {
|
|
|
200
220
|
if (um) {
|
|
201
221
|
acc.input_tokens += um.input_tokens || 0;
|
|
202
222
|
acc.output_tokens += um.output_tokens || 0;
|
|
223
|
+
acc.total_tokens += um.total_tokens || 0;
|
|
203
224
|
return acc;
|
|
204
225
|
}
|
|
205
226
|
const rm = chunk.response_metadata;
|
|
@@ -207,6 +228,8 @@ const accumulateChunkUsage = (acc, chunk) => {
|
|
|
207
228
|
acc.input_tokens += rm.usage.input_tokens || rm.usage.prompt_tokens || 0;
|
|
208
229
|
acc.output_tokens +=
|
|
209
230
|
rm.usage.output_tokens || rm.usage.completion_tokens || 0;
|
|
231
|
+
acc.total_tokens +=
|
|
232
|
+
rm.usage.total_tokens || rm.usage.total_token_count || 0;
|
|
210
233
|
}
|
|
211
234
|
return acc;
|
|
212
235
|
};
|
|
@@ -219,13 +242,18 @@ const sumAgentResponseUsage = (response) => {
|
|
|
219
242
|
const messages = response?.messages;
|
|
220
243
|
if (!Array.isArray(messages) || messages.length === 0)
|
|
221
244
|
return null;
|
|
222
|
-
const total = {
|
|
245
|
+
const total = {
|
|
246
|
+
input_tokens: 0,
|
|
247
|
+
output_tokens: 0,
|
|
248
|
+
total_tokens: 0,
|
|
249
|
+
};
|
|
223
250
|
let found = false;
|
|
224
251
|
for (const msg of messages) {
|
|
225
252
|
const um = msg?.usage_metadata;
|
|
226
253
|
if (um) {
|
|
227
254
|
total.input_tokens += um.input_tokens || 0;
|
|
228
255
|
total.output_tokens += um.output_tokens || 0;
|
|
256
|
+
total.total_tokens += um.total_tokens || 0;
|
|
229
257
|
found = true;
|
|
230
258
|
}
|
|
231
259
|
}
|
|
@@ -1049,7 +1077,11 @@ const runPromptWithModel = async (modelName, config, prompt, onProgressReport, m
|
|
|
1049
1077
|
while (true) {
|
|
1050
1078
|
let rawContent = "";
|
|
1051
1079
|
let chunkCount = 0;
|
|
1052
|
-
let streamUsage = {
|
|
1080
|
+
let streamUsage = {
|
|
1081
|
+
input_tokens: 0,
|
|
1082
|
+
output_tokens: 0,
|
|
1083
|
+
total_tokens: 0,
|
|
1084
|
+
};
|
|
1053
1085
|
// Inner loop: wait + retry on 429 around stream setup and consumption.
|
|
1054
1086
|
// Usage is only recorded on a successful stream — partial streams that
|
|
1055
1087
|
// error out with a rate limit are not counted. A 429 fired mid-stream
|
|
@@ -1058,7 +1090,7 @@ const runPromptWithModel = async (modelName, config, prompt, onProgressReport, m
|
|
|
1058
1090
|
while (true) {
|
|
1059
1091
|
rawContent = "";
|
|
1060
1092
|
chunkCount = 0;
|
|
1061
|
-
streamUsage = { input_tokens: 0, output_tokens: 0 };
|
|
1093
|
+
streamUsage = { input_tokens: 0, output_tokens: 0, total_tokens: 0 };
|
|
1062
1094
|
try {
|
|
1063
1095
|
// Honour caller cancellation: passing the signal tears down the
|
|
1064
1096
|
// upstream HTTP request so a cancelled call stops billing tokens.
|