@posthog/ai 7.13.2 → 7.14.0
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/anthropic/index.cjs +14 -1
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +14 -1
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +79 -1
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.d.ts +2 -1
- package/dist/gemini/index.mjs +79 -1
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +145 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +145 -2
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +38 -1
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.d.ts +1 -0
- package/dist/langchain/index.mjs +38 -1
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +19 -2
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +19 -2
- package/dist/openai/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +20 -1
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +20 -1
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { ResponseCreateParamsWithTools, ExtractParsedContentFromParams } from 'o
|
|
|
6
6
|
import { LanguageModelV2, LanguageModelV3 } from '@ai-sdk/provider';
|
|
7
7
|
import AnthropicOriginal, { APIPromise as APIPromise$1 } from '@anthropic-ai/sdk';
|
|
8
8
|
import { Stream as Stream$1 } from '@anthropic-ai/sdk/streaming';
|
|
9
|
-
import { GoogleGenAI, GenerateContentParameters, GenerateContentResponse, GoogleGenAIOptions } from '@google/genai';
|
|
9
|
+
import { GoogleGenAI, GenerateContentParameters, GenerateContentResponse, EmbedContentParameters, EmbedContentResponse, GoogleGenAIOptions } from '@google/genai';
|
|
10
10
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
11
11
|
import { Serialized } from '@langchain/core/load/serializable';
|
|
12
12
|
import { ChainValues } from '@langchain/core/utils/types';
|
|
@@ -228,6 +228,7 @@ declare class WrappedModels {
|
|
|
228
228
|
constructor(client: GoogleGenAI, phClient: PostHog);
|
|
229
229
|
generateContent(params: GenerateContentParameters & MonitoringParams): Promise<GenerateContentResponse>;
|
|
230
230
|
generateContentStream(params: GenerateContentParameters & MonitoringParams): AsyncGenerator<GenerateContentResponse, void, unknown>;
|
|
231
|
+
embedContent(params: EmbedContentParameters & MonitoringParams): Promise<EmbedContentResponse>;
|
|
231
232
|
private formatPartsAsContentBlocks;
|
|
232
233
|
private formatInput;
|
|
233
234
|
private extractSystemInstruction;
|
|
@@ -290,6 +291,7 @@ declare class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
|
290
291
|
private _convertLcToolCallsToOai;
|
|
291
292
|
private _extractRawResponse;
|
|
292
293
|
private _convertMessageToDict;
|
|
294
|
+
private _extractStopReason;
|
|
293
295
|
private _parseUsageModel;
|
|
294
296
|
private parseUsage;
|
|
295
297
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { uuidv7 } from '@posthog/core';
|
|
|
5
5
|
import AnthropicOriginal from '@anthropic-ai/sdk';
|
|
6
6
|
import { GoogleGenAI } from '@google/genai';
|
|
7
7
|
|
|
8
|
-
var version = "7.
|
|
8
|
+
var version = "7.14.0";
|
|
9
9
|
|
|
10
10
|
// Type guards for safer type checking
|
|
11
11
|
const isString = value => {
|
|
@@ -754,6 +754,7 @@ const sendEventToPosthog = async ({
|
|
|
754
754
|
usage = {},
|
|
755
755
|
error,
|
|
756
756
|
exceptionId,
|
|
757
|
+
stopReason,
|
|
757
758
|
tools,
|
|
758
759
|
captureImmediate = false
|
|
759
760
|
}) => {
|
|
@@ -824,6 +825,9 @@ const sendEventToPosthog = async ({
|
|
|
824
825
|
...(distinctId ? {} : {
|
|
825
826
|
$process_person_profile: false
|
|
826
827
|
}),
|
|
828
|
+
...(stopReason ? {
|
|
829
|
+
$ai_stop_reason: stopReason
|
|
830
|
+
} : {}),
|
|
827
831
|
...(tools ? {
|
|
828
832
|
$ai_tools: tools
|
|
829
833
|
} : {}),
|
|
@@ -947,6 +951,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
947
951
|
let accumulatedContent = '';
|
|
948
952
|
let modelFromResponse;
|
|
949
953
|
let firstTokenTime;
|
|
954
|
+
let stopReason;
|
|
950
955
|
let usage = {
|
|
951
956
|
inputTokens: 0,
|
|
952
957
|
outputTokens: 0,
|
|
@@ -961,6 +966,9 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
961
966
|
modelFromResponse = chunk.model;
|
|
962
967
|
}
|
|
963
968
|
const choice = chunk?.choices?.[0];
|
|
969
|
+
if (choice?.finish_reason) {
|
|
970
|
+
stopReason = choice.finish_reason;
|
|
971
|
+
}
|
|
964
972
|
const chunkWebSearchCount = calculateWebSearchCount(chunk);
|
|
965
973
|
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
966
974
|
usage.webSearchCount = chunkWebSearchCount;
|
|
@@ -1072,6 +1080,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
1072
1080
|
webSearchCount: usage.webSearchCount,
|
|
1073
1081
|
rawUsage: rawUsageData
|
|
1074
1082
|
},
|
|
1083
|
+
stopReason,
|
|
1075
1084
|
tools: availableTools
|
|
1076
1085
|
});
|
|
1077
1086
|
} catch (error) {
|
|
@@ -1124,6 +1133,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
1124
1133
|
webSearchCount: calculateWebSearchCount(result),
|
|
1125
1134
|
rawUsage: result.usage
|
|
1126
1135
|
},
|
|
1136
|
+
stopReason: result.choices[0]?.finish_reason ?? undefined,
|
|
1127
1137
|
tools: availableTools
|
|
1128
1138
|
});
|
|
1129
1139
|
}
|
|
@@ -1176,6 +1186,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1176
1186
|
let finalContent = [];
|
|
1177
1187
|
let modelFromResponse;
|
|
1178
1188
|
let firstTokenTime;
|
|
1189
|
+
let stopReason;
|
|
1179
1190
|
let usage = {
|
|
1180
1191
|
inputTokens: 0,
|
|
1181
1192
|
outputTokens: 0,
|
|
@@ -1199,6 +1210,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1199
1210
|
}
|
|
1200
1211
|
if (chunk.type === 'response.completed' && 'response' in chunk && chunk.response?.output && chunk.response.output.length > 0) {
|
|
1201
1212
|
finalContent = chunk.response.output;
|
|
1213
|
+
if (chunk.response.status) {
|
|
1214
|
+
stopReason = chunk.response.status;
|
|
1215
|
+
}
|
|
1202
1216
|
}
|
|
1203
1217
|
if ('response' in chunk && chunk.response?.usage) {
|
|
1204
1218
|
rawUsageData = chunk.response.usage;
|
|
@@ -1234,6 +1248,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1234
1248
|
webSearchCount: usage.webSearchCount,
|
|
1235
1249
|
rawUsage: rawUsageData
|
|
1236
1250
|
},
|
|
1251
|
+
stopReason,
|
|
1237
1252
|
tools: availableTools
|
|
1238
1253
|
});
|
|
1239
1254
|
} catch (error) {
|
|
@@ -1287,6 +1302,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1287
1302
|
webSearchCount: calculateWebSearchCount(result),
|
|
1288
1303
|
rawUsage: result.usage
|
|
1289
1304
|
},
|
|
1305
|
+
stopReason: result.status ?? undefined,
|
|
1290
1306
|
tools: availableTools
|
|
1291
1307
|
});
|
|
1292
1308
|
}
|
|
@@ -1346,7 +1362,8 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1346
1362
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1347
1363
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1348
1364
|
rawUsage: result.usage
|
|
1349
|
-
}
|
|
1365
|
+
},
|
|
1366
|
+
stopReason: result.status ?? undefined
|
|
1350
1367
|
});
|
|
1351
1368
|
return result;
|
|
1352
1369
|
}, async error => {
|
|
@@ -2382,6 +2399,9 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
|
2382
2399
|
rawUsage: rawUsageData
|
|
2383
2400
|
};
|
|
2384
2401
|
adjustAnthropicV3CacheTokens(model, provider, usage);
|
|
2402
|
+
// Extract finish reason - V2 returns a string, V3 returns an object with .unified
|
|
2403
|
+
const rawFinishReason = result.finishReason;
|
|
2404
|
+
const finishReasonStr = typeof rawFinishReason === 'string' ? rawFinishReason : rawFinishReason && typeof rawFinishReason === 'object' && 'unified' in rawFinishReason ? String(rawFinishReason.unified) : undefined;
|
|
2385
2405
|
await sendEventToPosthog({
|
|
2386
2406
|
client: phClient,
|
|
2387
2407
|
distinctId: mergedOptions.posthogDistinctId,
|
|
@@ -2395,6 +2415,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
|
2395
2415
|
params: mergedParams,
|
|
2396
2416
|
httpStatus: 200,
|
|
2397
2417
|
usage,
|
|
2418
|
+
stopReason: finishReasonStr,
|
|
2398
2419
|
tools: availableTools,
|
|
2399
2420
|
captureImmediate: mergedOptions.posthogCaptureImmediate
|
|
2400
2421
|
});
|
|
@@ -2433,6 +2454,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
|
2433
2454
|
let firstTokenTime;
|
|
2434
2455
|
let generatedText = '';
|
|
2435
2456
|
let reasoningText = '';
|
|
2457
|
+
let stopReason;
|
|
2436
2458
|
let usage = {};
|
|
2437
2459
|
let providerMetadata = undefined;
|
|
2438
2460
|
const mergedParams = {
|
|
@@ -2509,6 +2531,13 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
|
2509
2531
|
cacheReadInputTokens: extractCacheReadTokens(chunkUsage),
|
|
2510
2532
|
...additionalTokenValues
|
|
2511
2533
|
};
|
|
2534
|
+
// Extract finish reason - V2 returns a string, V3 returns an object with .unified
|
|
2535
|
+
const rawFinishReason = chunk.finishReason;
|
|
2536
|
+
if (typeof rawFinishReason === 'string') {
|
|
2537
|
+
stopReason = rawFinishReason;
|
|
2538
|
+
} else if (rawFinishReason && typeof rawFinishReason === 'object' && 'unified' in rawFinishReason) {
|
|
2539
|
+
stopReason = String(rawFinishReason.unified);
|
|
2540
|
+
}
|
|
2512
2541
|
}
|
|
2513
2542
|
controller.enqueue(chunk);
|
|
2514
2543
|
},
|
|
@@ -2572,6 +2601,7 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
|
2572
2601
|
params: mergedParams,
|
|
2573
2602
|
httpStatus: 200,
|
|
2574
2603
|
usage: finalUsage,
|
|
2604
|
+
stopReason,
|
|
2575
2605
|
tools: availableTools,
|
|
2576
2606
|
captureImmediate: mergedOptions.posthogCaptureImmediate
|
|
2577
2607
|
});
|
|
@@ -2643,6 +2673,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2643
2673
|
const toolsInProgress = new Map();
|
|
2644
2674
|
let currentTextBlock = null;
|
|
2645
2675
|
let firstTokenTime;
|
|
2676
|
+
let stopReason;
|
|
2646
2677
|
const usage = {
|
|
2647
2678
|
inputTokens: 0,
|
|
2648
2679
|
outputTokens: 0,
|
|
@@ -2743,6 +2774,12 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2743
2774
|
usage.webSearchCount = chunk.usage.server_tool_use.web_search_requests;
|
|
2744
2775
|
}
|
|
2745
2776
|
}
|
|
2777
|
+
if (chunk.type === 'message_delta' && 'delta' in chunk) {
|
|
2778
|
+
const delta = chunk.delta;
|
|
2779
|
+
if ('stop_reason' in delta && typeof delta.stop_reason === 'string' && delta.stop_reason) {
|
|
2780
|
+
stopReason = delta.stop_reason;
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2746
2783
|
}
|
|
2747
2784
|
usage.rawUsage = lastRawUsage;
|
|
2748
2785
|
const latency = (Date.now() - startTime) / 1000;
|
|
@@ -2772,6 +2809,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2772
2809
|
params: body,
|
|
2773
2810
|
httpStatus: 200,
|
|
2774
2811
|
usage,
|
|
2812
|
+
stopReason,
|
|
2775
2813
|
tools: availableTools
|
|
2776
2814
|
});
|
|
2777
2815
|
} catch (error) {
|
|
@@ -2823,6 +2861,7 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2823
2861
|
webSearchCount: result.usage.server_tool_use?.web_search_requests ?? 0,
|
|
2824
2862
|
rawUsage: result.usage
|
|
2825
2863
|
},
|
|
2864
|
+
stopReason: result.stop_reason ?? undefined,
|
|
2826
2865
|
tools: availableTools
|
|
2827
2866
|
});
|
|
2828
2867
|
}
|
|
@@ -2879,6 +2918,7 @@ class WrappedModels {
|
|
|
2879
2918
|
const latency = (Date.now() - startTime) / 1000;
|
|
2880
2919
|
const availableTools = extractAvailableToolCalls('gemini', geminiParams);
|
|
2881
2920
|
const metadata = response.usageMetadata;
|
|
2921
|
+
const finishReason = response.candidates?.[0]?.finishReason;
|
|
2882
2922
|
await sendEventToPosthog({
|
|
2883
2923
|
client: this.phClient,
|
|
2884
2924
|
...posthogParams,
|
|
@@ -2898,6 +2938,7 @@ class WrappedModels {
|
|
|
2898
2938
|
webSearchCount: calculateGoogleWebSearchCount(response),
|
|
2899
2939
|
rawUsage: metadata
|
|
2900
2940
|
},
|
|
2941
|
+
stopReason: finishReason ?? undefined,
|
|
2901
2942
|
tools: availableTools
|
|
2902
2943
|
});
|
|
2903
2944
|
return response;
|
|
@@ -2930,6 +2971,7 @@ class WrappedModels {
|
|
|
2930
2971
|
const startTime = Date.now();
|
|
2931
2972
|
const accumulatedContent = [];
|
|
2932
2973
|
let firstTokenTime;
|
|
2974
|
+
let stopReason;
|
|
2933
2975
|
let usage = {
|
|
2934
2976
|
inputTokens: 0,
|
|
2935
2977
|
outputTokens: 0,
|
|
@@ -2966,6 +3008,10 @@ class WrappedModels {
|
|
|
2966
3008
|
});
|
|
2967
3009
|
}
|
|
2968
3010
|
}
|
|
3011
|
+
// Track finish reason from candidates
|
|
3012
|
+
if (chunk.candidates?.[0]?.finishReason) {
|
|
3013
|
+
stopReason = chunk.candidates[0].finishReason;
|
|
3014
|
+
}
|
|
2969
3015
|
// Handle function calls from candidates
|
|
2970
3016
|
if (chunk.candidates && Array.isArray(chunk.candidates)) {
|
|
2971
3017
|
for (const candidate of chunk.candidates) {
|
|
@@ -3030,6 +3076,7 @@ class WrappedModels {
|
|
|
3030
3076
|
webSearchCount: usage.webSearchCount,
|
|
3031
3077
|
rawUsage: usage.rawUsage
|
|
3032
3078
|
},
|
|
3079
|
+
stopReason,
|
|
3033
3080
|
tools: availableTools
|
|
3034
3081
|
});
|
|
3035
3082
|
} catch (error) {
|
|
@@ -3053,6 +3100,54 @@ class WrappedModels {
|
|
|
3053
3100
|
throw enrichedError;
|
|
3054
3101
|
}
|
|
3055
3102
|
}
|
|
3103
|
+
async embedContent(params) {
|
|
3104
|
+
const {
|
|
3105
|
+
providerParams: geminiParams,
|
|
3106
|
+
posthogParams
|
|
3107
|
+
} = extractPosthogParams(params);
|
|
3108
|
+
const startTime = Date.now();
|
|
3109
|
+
try {
|
|
3110
|
+
const response = await this.client.models.embedContent(geminiParams);
|
|
3111
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
3112
|
+
const inputTokens = extractEmbeddingTokenCount(response);
|
|
3113
|
+
await sendEventToPosthog({
|
|
3114
|
+
client: this.phClient,
|
|
3115
|
+
...posthogParams,
|
|
3116
|
+
eventType: AIEvent.Embedding,
|
|
3117
|
+
model: geminiParams.model,
|
|
3118
|
+
provider: 'gemini',
|
|
3119
|
+
input: withPrivacyMode(this.phClient, posthogParams.privacyMode ?? false, geminiParams.contents),
|
|
3120
|
+
output: null,
|
|
3121
|
+
latency,
|
|
3122
|
+
baseURL: 'https://generativelanguage.googleapis.com',
|
|
3123
|
+
params: params,
|
|
3124
|
+
httpStatus: 200,
|
|
3125
|
+
usage: {
|
|
3126
|
+
inputTokens
|
|
3127
|
+
}
|
|
3128
|
+
});
|
|
3129
|
+
return response;
|
|
3130
|
+
} catch (error) {
|
|
3131
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
3132
|
+
const enrichedError = await sendEventWithErrorToPosthog({
|
|
3133
|
+
client: this.phClient,
|
|
3134
|
+
...posthogParams,
|
|
3135
|
+
eventType: AIEvent.Embedding,
|
|
3136
|
+
model: geminiParams.model,
|
|
3137
|
+
provider: 'gemini',
|
|
3138
|
+
input: withPrivacyMode(this.phClient, posthogParams.privacyMode ?? false, geminiParams.contents),
|
|
3139
|
+
output: null,
|
|
3140
|
+
latency,
|
|
3141
|
+
baseURL: 'https://generativelanguage.googleapis.com',
|
|
3142
|
+
params: params,
|
|
3143
|
+
usage: {
|
|
3144
|
+
inputTokens: 0
|
|
3145
|
+
},
|
|
3146
|
+
error: error
|
|
3147
|
+
});
|
|
3148
|
+
throw enrichedError;
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3056
3151
|
formatPartsAsContentBlocks(parts) {
|
|
3057
3152
|
const blocks = [];
|
|
3058
3153
|
for (const part of parts) {
|
|
@@ -3207,6 +3302,22 @@ class WrappedModels {
|
|
|
3207
3302
|
return messages;
|
|
3208
3303
|
}
|
|
3209
3304
|
}
|
|
3305
|
+
/**
|
|
3306
|
+
* Extract total token count from a Gemini embed_content response.
|
|
3307
|
+
* Token counts are only available per-embedding via Vertex AI's statistics.tokenCount.
|
|
3308
|
+
* Returns 0 if no token counts are available.
|
|
3309
|
+
*/
|
|
3310
|
+
function extractEmbeddingTokenCount(response) {
|
|
3311
|
+
let total = 0;
|
|
3312
|
+
if (response.embeddings) {
|
|
3313
|
+
for (const embedding of response.embeddings) {
|
|
3314
|
+
if (embedding.statistics?.tokenCount != null) {
|
|
3315
|
+
total += embedding.statistics.tokenCount;
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
return total;
|
|
3320
|
+
}
|
|
3210
3321
|
/**
|
|
3211
3322
|
* Detect if Google Search grounding was used in the response.
|
|
3212
3323
|
* Gemini bills per request that uses grounding, not per individual query.
|
|
@@ -4030,6 +4141,11 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
|
4030
4141
|
if (additionalTokenData.webSearchCount !== undefined) {
|
|
4031
4142
|
eventProperties['$ai_web_search_count'] = additionalTokenData.webSearchCount;
|
|
4032
4143
|
}
|
|
4144
|
+
// Extract stop reason from generation info
|
|
4145
|
+
const stopReason = this._extractStopReason(output);
|
|
4146
|
+
if (stopReason) {
|
|
4147
|
+
eventProperties['$ai_stop_reason'] = stopReason;
|
|
4148
|
+
}
|
|
4033
4149
|
// Handle generations/completions
|
|
4034
4150
|
let completions;
|
|
4035
4151
|
if (output.generations && Array.isArray(output.generations)) {
|
|
@@ -4164,6 +4280,33 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
|
4164
4280
|
// Sanitize the message content to redact base64 images
|
|
4165
4281
|
return sanitizeLangChain(messageDict);
|
|
4166
4282
|
}
|
|
4283
|
+
_extractStopReason(output) {
|
|
4284
|
+
if (!output.generations || !Array.isArray(output.generations)) {
|
|
4285
|
+
return undefined;
|
|
4286
|
+
}
|
|
4287
|
+
const lastGeneration = output.generations[output.generations.length - 1];
|
|
4288
|
+
if (!Array.isArray(lastGeneration) || lastGeneration.length === 0) {
|
|
4289
|
+
return undefined;
|
|
4290
|
+
}
|
|
4291
|
+
const gen = lastGeneration[0];
|
|
4292
|
+
// Check generationInfo for finish_reason (OpenAI format)
|
|
4293
|
+
if (gen.generationInfo?.finish_reason) {
|
|
4294
|
+
return String(gen.generationInfo.finish_reason);
|
|
4295
|
+
}
|
|
4296
|
+
// Check generationInfo for response_metadata.stop_reason (Anthropic format)
|
|
4297
|
+
if (gen.generationInfo?.response_metadata?.stop_reason) {
|
|
4298
|
+
return String(gen.generationInfo.response_metadata.stop_reason);
|
|
4299
|
+
}
|
|
4300
|
+
// Check message response_metadata for finish_reason (common LangChain format)
|
|
4301
|
+
if (gen.generationInfo?.response_metadata?.finish_reason) {
|
|
4302
|
+
return String(gen.generationInfo.response_metadata.finish_reason);
|
|
4303
|
+
}
|
|
4304
|
+
// Check for stop_reason directly in generationInfo
|
|
4305
|
+
if (gen.generationInfo?.stop_reason) {
|
|
4306
|
+
return String(gen.generationInfo.stop_reason);
|
|
4307
|
+
}
|
|
4308
|
+
return undefined;
|
|
4309
|
+
}
|
|
4167
4310
|
_parseUsageModel(usage, provider, model) {
|
|
4168
4311
|
const conversionList = [['promptTokens', 'input'], ['completionTokens', 'output'], ['input_tokens', 'input'], ['output_tokens', 'output'], ['prompt_token_count', 'input'], ['candidates_token_count', 'output'], ['inputTokenCount', 'input'], ['outputTokenCount', 'output'], ['input_token_count', 'input'], ['generated_token_count', 'output']];
|
|
4169
4312
|
const parsedUsage = conversionList.reduce((acc, [modelKey, typeKey]) => {
|