@visibe.ai/node 0.1.22 → 0.1.24
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/cjs/client.js +13 -4
- package/dist/cjs/index.js +104 -3
- package/dist/cjs/integrations/openai.js +6 -4
- package/dist/esm/client.js +13 -4
- package/dist/esm/index.js +104 -3
- package/dist/esm/integrations/openai.js +6 -4
- package/package.json +1 -1
package/dist/cjs/client.js
CHANGED
|
@@ -224,19 +224,28 @@ function applyIntegration(client, name, visibe) {
|
|
|
224
224
|
// Integrations are loaded lazily to avoid import errors when the peer
|
|
225
225
|
// dependency is not installed. Each integration module exports a
|
|
226
226
|
// `patchClient(client, name, visibe)` that returns a restore function.
|
|
227
|
-
|
|
227
|
+
// Walk the prototype chain to collect all ancestor class names.
|
|
228
|
+
// This handles subclasses (including our own PatchedOpenAI wrapper) without
|
|
229
|
+
// requiring the direct constructor to have a specific name.
|
|
230
|
+
const ancestorNames = new Set();
|
|
231
|
+
let ctor = client?.constructor;
|
|
232
|
+
while (ctor && ctor.name) {
|
|
233
|
+
ancestorNames.add(ctor.name);
|
|
234
|
+
ctor = Object.getPrototypeOf(ctor);
|
|
235
|
+
}
|
|
236
|
+
const has = (name) => ancestorNames.has(name);
|
|
228
237
|
try {
|
|
229
|
-
if (
|
|
238
|
+
if (has('OpenAI')) {
|
|
230
239
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
231
240
|
const { patchOpenAIClient } = require('./integrations/openai');
|
|
232
241
|
return patchOpenAIClient(client, name, visibe);
|
|
233
242
|
}
|
|
234
|
-
if (
|
|
243
|
+
if (has('Anthropic')) {
|
|
235
244
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
236
245
|
const { patchAnthropicClient } = require('./integrations/anthropic');
|
|
237
246
|
return patchAnthropicClient(client, name, visibe);
|
|
238
247
|
}
|
|
239
|
-
if (
|
|
248
|
+
if (has('BedrockRuntimeClient')) {
|
|
240
249
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
241
250
|
const { patchBedrockClient } = require('./integrations/bedrock');
|
|
242
251
|
return patchBedrockClient(client, name, visibe);
|
package/dist/cjs/index.js
CHANGED
|
@@ -100,6 +100,8 @@ async function patchFramework(framework, client) {
|
|
|
100
100
|
try {
|
|
101
101
|
switch (framework) {
|
|
102
102
|
case 'openai': {
|
|
103
|
+
if (_originalOpenAI)
|
|
104
|
+
break; // already patched by _syncPatch()
|
|
103
105
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
104
106
|
const openaiModule = await Promise.resolve().then(() => __importStar(require('openai')));
|
|
105
107
|
_originalOpenAI = openaiModule.OpenAI ?? openaiModule.default;
|
|
@@ -128,6 +130,8 @@ async function patchFramework(framework, client) {
|
|
|
128
130
|
break;
|
|
129
131
|
}
|
|
130
132
|
case 'anthropic': {
|
|
133
|
+
if (_originalAnthropic)
|
|
134
|
+
break; // already patched by _syncPatch()
|
|
131
135
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
136
|
const anthropicModule = await Promise.resolve().then(() => __importStar(require('@anthropic-ai/sdk')));
|
|
133
137
|
_originalAnthropic = anthropicModule.Anthropic ?? anthropicModule.default;
|
|
@@ -154,6 +158,8 @@ async function patchFramework(framework, client) {
|
|
|
154
158
|
break;
|
|
155
159
|
}
|
|
156
160
|
case 'bedrock': {
|
|
161
|
+
if (_originalBedrockClient)
|
|
162
|
+
break; // already patched by _syncPatch()
|
|
157
163
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
158
164
|
const bedrockModule = await Promise.resolve().then(() => __importStar(require('@aws-sdk/client-bedrock-runtime')));
|
|
159
165
|
_originalBedrockClient = bedrockModule.BedrockRuntimeClient;
|
|
@@ -238,6 +244,98 @@ async function _autoPatch(client, frameworks) {
|
|
|
238
244
|
}
|
|
239
245
|
}
|
|
240
246
|
// ---------------------------------------------------------------------------
|
|
247
|
+
// _syncPatch() — synchronous CJS patching.
|
|
248
|
+
//
|
|
249
|
+
// In CJS builds, require() is synchronous so we can patch framework modules
|
|
250
|
+
// inline inside init() BEFORE it returns. This means instances created right
|
|
251
|
+
// after init() (e.g. `const client = new OpenAI()`) are already using the
|
|
252
|
+
// patched class — no async race condition.
|
|
253
|
+
//
|
|
254
|
+
// In ESM builds, require is undefined — the entire function silently no-ops
|
|
255
|
+
// and _autoPatch() handles instrumentation via dynamic import() instead.
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
258
|
+
function _makePatchedClass(Orig, client) {
|
|
259
|
+
return class Patched extends Orig {
|
|
260
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
261
|
+
constructor(...args) {
|
|
262
|
+
super(...args);
|
|
263
|
+
try {
|
|
264
|
+
client.instrument(this);
|
|
265
|
+
}
|
|
266
|
+
catch { /* never crash constructor */ }
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function _syncPatch(client, frameworksToTry) {
|
|
271
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
272
|
+
if (typeof require === 'undefined')
|
|
273
|
+
return;
|
|
274
|
+
for (const fw of frameworksToTry) {
|
|
275
|
+
try {
|
|
276
|
+
switch (fw) {
|
|
277
|
+
case 'openai': {
|
|
278
|
+
if (_originalOpenAI)
|
|
279
|
+
break;
|
|
280
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
281
|
+
const m = require('openai');
|
|
282
|
+
const Orig = m.OpenAI ?? m.default;
|
|
283
|
+
if (!Orig)
|
|
284
|
+
break;
|
|
285
|
+
_originalOpenAI = Orig;
|
|
286
|
+
const Patched = _makePatchedClass(Orig, client);
|
|
287
|
+
try {
|
|
288
|
+
_setProp(m, 'OpenAI', Patched);
|
|
289
|
+
_setProp(m, 'default', Patched);
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
_originalOpenAI = null;
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
case 'anthropic': {
|
|
297
|
+
if (_originalAnthropic)
|
|
298
|
+
break;
|
|
299
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
300
|
+
const m = require('@anthropic-ai/sdk');
|
|
301
|
+
const Orig = m.Anthropic ?? m.default;
|
|
302
|
+
if (!Orig)
|
|
303
|
+
break;
|
|
304
|
+
_originalAnthropic = Orig;
|
|
305
|
+
const Patched = _makePatchedClass(Orig, client);
|
|
306
|
+
try {
|
|
307
|
+
_setProp(m, 'Anthropic', Patched);
|
|
308
|
+
_setProp(m, 'default', Patched);
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
_originalAnthropic = null;
|
|
312
|
+
}
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
case 'bedrock': {
|
|
316
|
+
if (_originalBedrockClient)
|
|
317
|
+
break;
|
|
318
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
319
|
+
const m = require('@aws-sdk/client-bedrock-runtime');
|
|
320
|
+
const Orig = m.BedrockRuntimeClient;
|
|
321
|
+
if (!Orig)
|
|
322
|
+
break;
|
|
323
|
+
_originalBedrockClient = Orig;
|
|
324
|
+
const Patched = _makePatchedClass(Orig, client);
|
|
325
|
+
try {
|
|
326
|
+
m.BedrockRuntimeClient = Patched;
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
_originalBedrockClient = null;
|
|
330
|
+
}
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
catch { /* package not installed — skip */ }
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
241
339
|
// init()
|
|
242
340
|
// ---------------------------------------------------------------------------
|
|
243
341
|
function init(options) {
|
|
@@ -246,10 +344,13 @@ function init(options) {
|
|
|
246
344
|
return _globalClient;
|
|
247
345
|
}
|
|
248
346
|
_globalClient = new client_1.Visibe(options ?? {});
|
|
249
|
-
// Fire async patching — works in both CJS and ESM via dynamic import().
|
|
250
|
-
// Patching typically completes within microseconds (cached modules) so there
|
|
251
|
-
// is no practical race condition for normal usage patterns.
|
|
252
347
|
const frameworksToTry = options?.frameworks ?? ALL_FRAMEWORKS;
|
|
348
|
+
// Synchronous CJS path — patches module exports inline so instances created
|
|
349
|
+
// right after init() (e.g. `const client = new OpenAI()`) are instrumented.
|
|
350
|
+
// In ESM, require is undefined and this silently no-ops.
|
|
351
|
+
_syncPatch(_globalClient, frameworksToTry);
|
|
352
|
+
// Async path — handles ESM and framework detection for LangChain/LangGraph
|
|
353
|
+
// (prototype patches don't need to be synchronous).
|
|
253
354
|
_autoPatch(_globalClient, frameworksToTry).catch(() => { });
|
|
254
355
|
if (!_shutdownRegistered) {
|
|
255
356
|
const graceful = async () => { await shutdown(); process.exit(0); };
|
|
@@ -152,8 +152,9 @@ class OpenAIIntegration extends base_1.BaseIntegration {
|
|
|
152
152
|
throw err;
|
|
153
153
|
}
|
|
154
154
|
const model = response.model ?? params.model ?? 'unknown';
|
|
155
|
-
|
|
156
|
-
const
|
|
155
|
+
// Support both openai v4 (prompt_tokens/completion_tokens) and v5/v6 (input_tokens/output_tokens)
|
|
156
|
+
const inputTokens = response.usage?.prompt_tokens ?? response.usage?.input_tokens ?? 0;
|
|
157
|
+
const outputTokens = response.usage?.completion_tokens ?? response.usage?.output_tokens ?? 0;
|
|
157
158
|
const cost = (0, utils_1.calculateCost)(model, inputTokens, outputTokens);
|
|
158
159
|
const choice = response.choices?.[0];
|
|
159
160
|
const rawContent = choice?.message?.content;
|
|
@@ -244,9 +245,10 @@ class OpenAIIntegration extends base_1.BaseIntegration {
|
|
|
244
245
|
if (delta)
|
|
245
246
|
outputText += delta;
|
|
246
247
|
// Last chunk carries usage when stream_options.include_usage is set
|
|
248
|
+
// Support both openai v4 (prompt_tokens/completion_tokens) and v5/v6 (input_tokens/output_tokens)
|
|
247
249
|
if (chunk.usage) {
|
|
248
|
-
inputTokens = chunk.usage.prompt_tokens ?? 0;
|
|
249
|
-
outputTokens = chunk.usage.completion_tokens ?? 0;
|
|
250
|
+
inputTokens = chunk.usage.prompt_tokens ?? chunk.usage.input_tokens ?? 0;
|
|
251
|
+
outputTokens = chunk.usage.completion_tokens ?? chunk.usage.output_tokens ?? 0;
|
|
250
252
|
}
|
|
251
253
|
}
|
|
252
254
|
return result;
|
package/dist/esm/client.js
CHANGED
|
@@ -220,19 +220,28 @@ function applyIntegration(client, name, visibe) {
|
|
|
220
220
|
// Integrations are loaded lazily to avoid import errors when the peer
|
|
221
221
|
// dependency is not installed. Each integration module exports a
|
|
222
222
|
// `patchClient(client, name, visibe)` that returns a restore function.
|
|
223
|
-
|
|
223
|
+
// Walk the prototype chain to collect all ancestor class names.
|
|
224
|
+
// This handles subclasses (including our own PatchedOpenAI wrapper) without
|
|
225
|
+
// requiring the direct constructor to have a specific name.
|
|
226
|
+
const ancestorNames = new Set();
|
|
227
|
+
let ctor = client?.constructor;
|
|
228
|
+
while (ctor && ctor.name) {
|
|
229
|
+
ancestorNames.add(ctor.name);
|
|
230
|
+
ctor = Object.getPrototypeOf(ctor);
|
|
231
|
+
}
|
|
232
|
+
const has = (name) => ancestorNames.has(name);
|
|
224
233
|
try {
|
|
225
|
-
if (
|
|
234
|
+
if (has('OpenAI')) {
|
|
226
235
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
227
236
|
const { patchOpenAIClient } = require('./integrations/openai');
|
|
228
237
|
return patchOpenAIClient(client, name, visibe);
|
|
229
238
|
}
|
|
230
|
-
if (
|
|
239
|
+
if (has('Anthropic')) {
|
|
231
240
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
232
241
|
const { patchAnthropicClient } = require('./integrations/anthropic');
|
|
233
242
|
return patchAnthropicClient(client, name, visibe);
|
|
234
243
|
}
|
|
235
|
-
if (
|
|
244
|
+
if (has('BedrockRuntimeClient')) {
|
|
236
245
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
237
246
|
const { patchBedrockClient } = require('./integrations/bedrock');
|
|
238
247
|
return patchBedrockClient(client, name, visibe);
|
package/dist/esm/index.js
CHANGED
|
@@ -61,6 +61,8 @@ async function patchFramework(framework, client) {
|
|
|
61
61
|
try {
|
|
62
62
|
switch (framework) {
|
|
63
63
|
case 'openai': {
|
|
64
|
+
if (_originalOpenAI)
|
|
65
|
+
break; // already patched by _syncPatch()
|
|
64
66
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
65
67
|
const openaiModule = await import('openai');
|
|
66
68
|
_originalOpenAI = openaiModule.OpenAI ?? openaiModule.default;
|
|
@@ -89,6 +91,8 @@ async function patchFramework(framework, client) {
|
|
|
89
91
|
break;
|
|
90
92
|
}
|
|
91
93
|
case 'anthropic': {
|
|
94
|
+
if (_originalAnthropic)
|
|
95
|
+
break; // already patched by _syncPatch()
|
|
92
96
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
93
97
|
const anthropicModule = await import('@anthropic-ai/sdk');
|
|
94
98
|
_originalAnthropic = anthropicModule.Anthropic ?? anthropicModule.default;
|
|
@@ -115,6 +119,8 @@ async function patchFramework(framework, client) {
|
|
|
115
119
|
break;
|
|
116
120
|
}
|
|
117
121
|
case 'bedrock': {
|
|
122
|
+
if (_originalBedrockClient)
|
|
123
|
+
break; // already patched by _syncPatch()
|
|
118
124
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
125
|
const bedrockModule = await import('@aws-sdk/client-bedrock-runtime');
|
|
120
126
|
_originalBedrockClient = bedrockModule.BedrockRuntimeClient;
|
|
@@ -199,6 +205,98 @@ async function _autoPatch(client, frameworks) {
|
|
|
199
205
|
}
|
|
200
206
|
}
|
|
201
207
|
// ---------------------------------------------------------------------------
|
|
208
|
+
// _syncPatch() — synchronous CJS patching.
|
|
209
|
+
//
|
|
210
|
+
// In CJS builds, require() is synchronous so we can patch framework modules
|
|
211
|
+
// inline inside init() BEFORE it returns. This means instances created right
|
|
212
|
+
// after init() (e.g. `const client = new OpenAI()`) are already using the
|
|
213
|
+
// patched class — no async race condition.
|
|
214
|
+
//
|
|
215
|
+
// In ESM builds, require is undefined — the entire function silently no-ops
|
|
216
|
+
// and _autoPatch() handles instrumentation via dynamic import() instead.
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
219
|
+
function _makePatchedClass(Orig, client) {
|
|
220
|
+
return class Patched extends Orig {
|
|
221
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
222
|
+
constructor(...args) {
|
|
223
|
+
super(...args);
|
|
224
|
+
try {
|
|
225
|
+
client.instrument(this);
|
|
226
|
+
}
|
|
227
|
+
catch { /* never crash constructor */ }
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function _syncPatch(client, frameworksToTry) {
|
|
232
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
233
|
+
if (typeof require === 'undefined')
|
|
234
|
+
return;
|
|
235
|
+
for (const fw of frameworksToTry) {
|
|
236
|
+
try {
|
|
237
|
+
switch (fw) {
|
|
238
|
+
case 'openai': {
|
|
239
|
+
if (_originalOpenAI)
|
|
240
|
+
break;
|
|
241
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
242
|
+
const m = require('openai');
|
|
243
|
+
const Orig = m.OpenAI ?? m.default;
|
|
244
|
+
if (!Orig)
|
|
245
|
+
break;
|
|
246
|
+
_originalOpenAI = Orig;
|
|
247
|
+
const Patched = _makePatchedClass(Orig, client);
|
|
248
|
+
try {
|
|
249
|
+
_setProp(m, 'OpenAI', Patched);
|
|
250
|
+
_setProp(m, 'default', Patched);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
_originalOpenAI = null;
|
|
254
|
+
}
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
case 'anthropic': {
|
|
258
|
+
if (_originalAnthropic)
|
|
259
|
+
break;
|
|
260
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
261
|
+
const m = require('@anthropic-ai/sdk');
|
|
262
|
+
const Orig = m.Anthropic ?? m.default;
|
|
263
|
+
if (!Orig)
|
|
264
|
+
break;
|
|
265
|
+
_originalAnthropic = Orig;
|
|
266
|
+
const Patched = _makePatchedClass(Orig, client);
|
|
267
|
+
try {
|
|
268
|
+
_setProp(m, 'Anthropic', Patched);
|
|
269
|
+
_setProp(m, 'default', Patched);
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
_originalAnthropic = null;
|
|
273
|
+
}
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case 'bedrock': {
|
|
277
|
+
if (_originalBedrockClient)
|
|
278
|
+
break;
|
|
279
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any
|
|
280
|
+
const m = require('@aws-sdk/client-bedrock-runtime');
|
|
281
|
+
const Orig = m.BedrockRuntimeClient;
|
|
282
|
+
if (!Orig)
|
|
283
|
+
break;
|
|
284
|
+
_originalBedrockClient = Orig;
|
|
285
|
+
const Patched = _makePatchedClass(Orig, client);
|
|
286
|
+
try {
|
|
287
|
+
m.BedrockRuntimeClient = Patched;
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
_originalBedrockClient = null;
|
|
291
|
+
}
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
catch { /* package not installed — skip */ }
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
202
300
|
// init()
|
|
203
301
|
// ---------------------------------------------------------------------------
|
|
204
302
|
export function init(options) {
|
|
@@ -207,10 +305,13 @@ export function init(options) {
|
|
|
207
305
|
return _globalClient;
|
|
208
306
|
}
|
|
209
307
|
_globalClient = new Visibe(options ?? {});
|
|
210
|
-
// Fire async patching — works in both CJS and ESM via dynamic import().
|
|
211
|
-
// Patching typically completes within microseconds (cached modules) so there
|
|
212
|
-
// is no practical race condition for normal usage patterns.
|
|
213
308
|
const frameworksToTry = options?.frameworks ?? ALL_FRAMEWORKS;
|
|
309
|
+
// Synchronous CJS path — patches module exports inline so instances created
|
|
310
|
+
// right after init() (e.g. `const client = new OpenAI()`) are instrumented.
|
|
311
|
+
// In ESM, require is undefined and this silently no-ops.
|
|
312
|
+
_syncPatch(_globalClient, frameworksToTry);
|
|
313
|
+
// Async path — handles ESM and framework detection for LangChain/LangGraph
|
|
314
|
+
// (prototype patches don't need to be synchronous).
|
|
214
315
|
_autoPatch(_globalClient, frameworksToTry).catch(() => { });
|
|
215
316
|
if (!_shutdownRegistered) {
|
|
216
317
|
const graceful = async () => { await shutdown(); process.exit(0); };
|
|
@@ -148,8 +148,9 @@ export class OpenAIIntegration extends BaseIntegration {
|
|
|
148
148
|
throw err;
|
|
149
149
|
}
|
|
150
150
|
const model = response.model ?? params.model ?? 'unknown';
|
|
151
|
-
|
|
152
|
-
const
|
|
151
|
+
// Support both openai v4 (prompt_tokens/completion_tokens) and v5/v6 (input_tokens/output_tokens)
|
|
152
|
+
const inputTokens = response.usage?.prompt_tokens ?? response.usage?.input_tokens ?? 0;
|
|
153
|
+
const outputTokens = response.usage?.completion_tokens ?? response.usage?.output_tokens ?? 0;
|
|
153
154
|
const cost = calculateCost(model, inputTokens, outputTokens);
|
|
154
155
|
const choice = response.choices?.[0];
|
|
155
156
|
const rawContent = choice?.message?.content;
|
|
@@ -240,9 +241,10 @@ export class OpenAIIntegration extends BaseIntegration {
|
|
|
240
241
|
if (delta)
|
|
241
242
|
outputText += delta;
|
|
242
243
|
// Last chunk carries usage when stream_options.include_usage is set
|
|
244
|
+
// Support both openai v4 (prompt_tokens/completion_tokens) and v5/v6 (input_tokens/output_tokens)
|
|
243
245
|
if (chunk.usage) {
|
|
244
|
-
inputTokens = chunk.usage.prompt_tokens ?? 0;
|
|
245
|
-
outputTokens = chunk.usage.completion_tokens ?? 0;
|
|
246
|
+
inputTokens = chunk.usage.prompt_tokens ?? chunk.usage.input_tokens ?? 0;
|
|
247
|
+
outputTokens = chunk.usage.completion_tokens ?? chunk.usage.output_tokens ?? 0;
|
|
246
248
|
}
|
|
247
249
|
}
|
|
248
250
|
return result;
|
package/package.json
CHANGED