@posthog/ai 6.5.1 → 7.0.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 +13 -3
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +13 -3
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +74 -5
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +74 -5
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +590 -373
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +590 -373
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +330 -346
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +330 -346
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +152 -15
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/openai/index.mjs +152 -15
- package/dist/openai/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +157 -8
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +157 -8
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +10 -10
package/dist/index.cjs
CHANGED
|
@@ -26,7 +26,7 @@ function _interopNamespaceDefault(e) {
|
|
|
26
26
|
|
|
27
27
|
var uuid__namespace = /*#__PURE__*/_interopNamespaceDefault(uuid);
|
|
28
28
|
|
|
29
|
-
var version = "
|
|
29
|
+
var version = "7.0.0";
|
|
30
30
|
|
|
31
31
|
// Type guards for safer type checking
|
|
32
32
|
const isString = value => {
|
|
@@ -297,6 +297,101 @@ const truncate = input => {
|
|
|
297
297
|
}
|
|
298
298
|
return `${truncatedStr}... [truncated]`;
|
|
299
299
|
};
|
|
300
|
+
/**
|
|
301
|
+
* Calculate web search count from raw API response.
|
|
302
|
+
*
|
|
303
|
+
* Uses a two-tier detection strategy:
|
|
304
|
+
* Priority 1 (Exact Count): Count actual web search calls when available
|
|
305
|
+
* Priority 2 (Binary Detection): Return 1 if web search indicators are present, 0 otherwise
|
|
306
|
+
*
|
|
307
|
+
* @param result - Raw API response from any provider (OpenAI, Perplexity, OpenRouter, Gemini, etc.)
|
|
308
|
+
* @returns Number of web searches performed (exact count or binary 1/0)
|
|
309
|
+
*/
|
|
310
|
+
function calculateWebSearchCount(result) {
|
|
311
|
+
if (!result || typeof result !== 'object') {
|
|
312
|
+
return 0;
|
|
313
|
+
}
|
|
314
|
+
// Priority 1: Exact Count
|
|
315
|
+
// Check for OpenAI Responses API web_search_call items
|
|
316
|
+
if ('output' in result && Array.isArray(result.output)) {
|
|
317
|
+
let count = 0;
|
|
318
|
+
for (const item of result.output) {
|
|
319
|
+
if (typeof item === 'object' && item !== null && 'type' in item && item.type === 'web_search_call') {
|
|
320
|
+
count++;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (count > 0) {
|
|
324
|
+
return count;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// Priority 2: Binary Detection (1 or 0)
|
|
328
|
+
// Check for citations at root level (Perplexity)
|
|
329
|
+
if ('citations' in result && Array.isArray(result.citations) && result.citations.length > 0) {
|
|
330
|
+
return 1;
|
|
331
|
+
}
|
|
332
|
+
// Check for search_results at root level (Perplexity via OpenRouter)
|
|
333
|
+
if ('search_results' in result && Array.isArray(result.search_results) && result.search_results.length > 0) {
|
|
334
|
+
return 1;
|
|
335
|
+
}
|
|
336
|
+
// Check for usage.search_context_size (Perplexity via OpenRouter)
|
|
337
|
+
if ('usage' in result && typeof result.usage === 'object' && result.usage !== null) {
|
|
338
|
+
if ('search_context_size' in result.usage && result.usage.search_context_size) {
|
|
339
|
+
return 1;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Check for annotations with url_citation in choices[].message or choices[].delta (OpenAI/Perplexity)
|
|
343
|
+
if ('choices' in result && Array.isArray(result.choices)) {
|
|
344
|
+
for (const choice of result.choices) {
|
|
345
|
+
if (typeof choice === 'object' && choice !== null) {
|
|
346
|
+
// Check both message (non-streaming) and delta (streaming) for annotations
|
|
347
|
+
const content = ('message' in choice ? choice.message : null) || ('delta' in choice ? choice.delta : null);
|
|
348
|
+
if (typeof content === 'object' && content !== null && 'annotations' in content) {
|
|
349
|
+
const annotations = content.annotations;
|
|
350
|
+
if (Array.isArray(annotations)) {
|
|
351
|
+
const hasUrlCitation = annotations.some(ann => {
|
|
352
|
+
return typeof ann === 'object' && ann !== null && 'type' in ann && ann.type === 'url_citation';
|
|
353
|
+
});
|
|
354
|
+
if (hasUrlCitation) {
|
|
355
|
+
return 1;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Check for annotations in output[].content[] (OpenAI Responses API)
|
|
363
|
+
if ('output' in result && Array.isArray(result.output)) {
|
|
364
|
+
for (const item of result.output) {
|
|
365
|
+
if (typeof item === 'object' && item !== null && 'content' in item) {
|
|
366
|
+
const content = item.content;
|
|
367
|
+
if (Array.isArray(content)) {
|
|
368
|
+
for (const contentItem of content) {
|
|
369
|
+
if (typeof contentItem === 'object' && contentItem !== null && 'annotations' in contentItem) {
|
|
370
|
+
const annotations = contentItem.annotations;
|
|
371
|
+
if (Array.isArray(annotations)) {
|
|
372
|
+
const hasUrlCitation = annotations.some(ann => {
|
|
373
|
+
return typeof ann === 'object' && ann !== null && 'type' in ann && ann.type === 'url_citation';
|
|
374
|
+
});
|
|
375
|
+
if (hasUrlCitation) {
|
|
376
|
+
return 1;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Check for grounding_metadata (Gemini)
|
|
386
|
+
if ('candidates' in result && Array.isArray(result.candidates)) {
|
|
387
|
+
for (const candidate of result.candidates) {
|
|
388
|
+
if (typeof candidate === 'object' && candidate !== null && 'grounding_metadata' in candidate && candidate.grounding_metadata) {
|
|
389
|
+
return 1;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return 0;
|
|
394
|
+
}
|
|
300
395
|
/**
|
|
301
396
|
* Extract available tool calls from the request parameters.
|
|
302
397
|
* These are the tools provided to the LLM, not the tool calls in the response.
|
|
@@ -431,6 +526,9 @@ const sendEventToPosthog = async ({
|
|
|
431
526
|
} : {}),
|
|
432
527
|
...(usage.cacheCreationInputTokens ? {
|
|
433
528
|
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
529
|
+
} : {}),
|
|
530
|
+
...(usage.webSearchCount ? {
|
|
531
|
+
$ai_web_search_count: usage.webSearchCount
|
|
434
532
|
} : {})
|
|
435
533
|
};
|
|
436
534
|
const properties = {
|
|
@@ -741,12 +839,17 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
741
839
|
let accumulatedContent = '';
|
|
742
840
|
let usage = {
|
|
743
841
|
inputTokens: 0,
|
|
744
|
-
outputTokens: 0
|
|
842
|
+
outputTokens: 0,
|
|
843
|
+
webSearchCount: 0
|
|
745
844
|
};
|
|
746
845
|
// Map to track in-progress tool calls
|
|
747
846
|
const toolCallsInProgress = new Map();
|
|
748
847
|
for await (const chunk of stream1) {
|
|
749
848
|
const choice = chunk?.choices?.[0];
|
|
849
|
+
const chunkWebSearchCount = calculateWebSearchCount(chunk);
|
|
850
|
+
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
851
|
+
usage.webSearchCount = chunkWebSearchCount;
|
|
852
|
+
}
|
|
750
853
|
// Handle text content
|
|
751
854
|
const deltaContent = choice?.delta?.content;
|
|
752
855
|
if (deltaContent) {
|
|
@@ -785,6 +888,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
785
888
|
// Handle usage information
|
|
786
889
|
if (chunk.usage) {
|
|
787
890
|
usage = {
|
|
891
|
+
...usage,
|
|
788
892
|
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
789
893
|
outputTokens: chunk.usage.completion_tokens ?? 0,
|
|
790
894
|
reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
@@ -836,7 +940,13 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
836
940
|
baseURL: this.baseURL,
|
|
837
941
|
params: body,
|
|
838
942
|
httpStatus: 200,
|
|
839
|
-
usage
|
|
943
|
+
usage: {
|
|
944
|
+
inputTokens: usage.inputTokens,
|
|
945
|
+
outputTokens: usage.outputTokens,
|
|
946
|
+
reasoningTokens: usage.reasoningTokens,
|
|
947
|
+
cacheReadInputTokens: usage.cacheReadInputTokens,
|
|
948
|
+
webSearchCount: usage.webSearchCount
|
|
949
|
+
},
|
|
840
950
|
tools: availableTools
|
|
841
951
|
});
|
|
842
952
|
} catch (error) {
|
|
@@ -871,13 +981,14 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
871
981
|
if ('choices' in result) {
|
|
872
982
|
const latency = (Date.now() - startTime) / 1000;
|
|
873
983
|
const availableTools = extractAvailableToolCalls('openai', openAIParams);
|
|
984
|
+
const formattedOutput = formatResponseOpenAI(result);
|
|
874
985
|
await sendEventToPosthog({
|
|
875
986
|
client: this.phClient,
|
|
876
987
|
...posthogParams,
|
|
877
988
|
model: openAIParams.model,
|
|
878
989
|
provider: 'openai',
|
|
879
990
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
880
|
-
output:
|
|
991
|
+
output: formattedOutput,
|
|
881
992
|
latency,
|
|
882
993
|
baseURL: this.baseURL,
|
|
883
994
|
params: body,
|
|
@@ -886,7 +997,8 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
886
997
|
inputTokens: result.usage?.prompt_tokens ?? 0,
|
|
887
998
|
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
888
999
|
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
889
|
-
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
1000
|
+
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0,
|
|
1001
|
+
webSearchCount: calculateWebSearchCount(result)
|
|
890
1002
|
},
|
|
891
1003
|
tools: availableTools
|
|
892
1004
|
});
|
|
@@ -941,14 +1053,22 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
941
1053
|
let finalContent = [];
|
|
942
1054
|
let usage = {
|
|
943
1055
|
inputTokens: 0,
|
|
944
|
-
outputTokens: 0
|
|
1056
|
+
outputTokens: 0,
|
|
1057
|
+
webSearchCount: 0
|
|
945
1058
|
};
|
|
946
1059
|
for await (const chunk of stream1) {
|
|
1060
|
+
if ('response' in chunk && chunk.response) {
|
|
1061
|
+
const chunkWebSearchCount = calculateWebSearchCount(chunk.response);
|
|
1062
|
+
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
1063
|
+
usage.webSearchCount = chunkWebSearchCount;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
947
1066
|
if (chunk.type === 'response.completed' && 'response' in chunk && chunk.response?.output && chunk.response.output.length > 0) {
|
|
948
1067
|
finalContent = chunk.response.output;
|
|
949
1068
|
}
|
|
950
1069
|
if ('response' in chunk && chunk.response?.usage) {
|
|
951
1070
|
usage = {
|
|
1071
|
+
...usage,
|
|
952
1072
|
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
953
1073
|
outputTokens: chunk.response.usage.output_tokens ?? 0,
|
|
954
1074
|
reasoningTokens: chunk.response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
@@ -970,7 +1090,13 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
970
1090
|
baseURL: this.baseURL,
|
|
971
1091
|
params: body,
|
|
972
1092
|
httpStatus: 200,
|
|
973
|
-
usage
|
|
1093
|
+
usage: {
|
|
1094
|
+
inputTokens: usage.inputTokens,
|
|
1095
|
+
outputTokens: usage.outputTokens,
|
|
1096
|
+
reasoningTokens: usage.reasoningTokens,
|
|
1097
|
+
cacheReadInputTokens: usage.cacheReadInputTokens,
|
|
1098
|
+
webSearchCount: usage.webSearchCount
|
|
1099
|
+
},
|
|
974
1100
|
tools: availableTools
|
|
975
1101
|
});
|
|
976
1102
|
} catch (error) {
|
|
@@ -1005,6 +1131,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1005
1131
|
if ('output' in result) {
|
|
1006
1132
|
const latency = (Date.now() - startTime) / 1000;
|
|
1007
1133
|
const availableTools = extractAvailableToolCalls('openai', openAIParams);
|
|
1134
|
+
const formattedOutput = formatResponseOpenAI({
|
|
1135
|
+
output: result.output
|
|
1136
|
+
});
|
|
1008
1137
|
await sendEventToPosthog({
|
|
1009
1138
|
client: this.phClient,
|
|
1010
1139
|
...posthogParams,
|
|
@@ -1012,9 +1141,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1012
1141
|
model: openAIParams.model,
|
|
1013
1142
|
provider: 'openai',
|
|
1014
1143
|
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1015
|
-
output:
|
|
1016
|
-
output: result.output
|
|
1017
|
-
}),
|
|
1144
|
+
output: formattedOutput,
|
|
1018
1145
|
latency,
|
|
1019
1146
|
baseURL: this.baseURL,
|
|
1020
1147
|
params: body,
|
|
@@ -1023,7 +1150,8 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1023
1150
|
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1024
1151
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1025
1152
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1026
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1153
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1154
|
+
webSearchCount: calculateWebSearchCount(result)
|
|
1027
1155
|
},
|
|
1028
1156
|
tools: availableTools
|
|
1029
1157
|
});
|
|
@@ -1061,9 +1189,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1061
1189
|
} = extractPosthogParams(body);
|
|
1062
1190
|
const startTime = Date.now();
|
|
1063
1191
|
const originalCreate = super.create.bind(this);
|
|
1064
|
-
const
|
|
1065
|
-
const tempCreate =
|
|
1066
|
-
|
|
1192
|
+
const originalSelfRecord = this;
|
|
1193
|
+
const tempCreate = originalSelfRecord['create'];
|
|
1194
|
+
originalSelfRecord['create'] = originalCreate;
|
|
1067
1195
|
try {
|
|
1068
1196
|
const parentPromise = super.parse(openAIParams, options);
|
|
1069
1197
|
const wrappedPromise = parentPromise.then(async result => {
|
|
@@ -1112,7 +1240,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1112
1240
|
return wrappedPromise;
|
|
1113
1241
|
} finally {
|
|
1114
1242
|
// Restore our wrapped create method
|
|
1115
|
-
|
|
1243
|
+
originalSelfRecord['create'] = tempCreate;
|
|
1116
1244
|
}
|
|
1117
1245
|
}
|
|
1118
1246
|
};
|
|
@@ -1858,11 +1986,29 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
1858
1986
|
cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
|
|
1859
1987
|
} : {})
|
|
1860
1988
|
};
|
|
1989
|
+
// Calculate web search count based on provider
|
|
1990
|
+
let webSearchCount = 0;
|
|
1991
|
+
if (providerMetadata?.anthropic && typeof providerMetadata.anthropic === 'object' && 'server_tool_use' in providerMetadata.anthropic) {
|
|
1992
|
+
// Anthropic-specific extraction
|
|
1993
|
+
const serverToolUse = providerMetadata.anthropic.server_tool_use;
|
|
1994
|
+
if (serverToolUse && typeof serverToolUse === 'object' && 'web_search_requests' in serverToolUse && typeof serverToolUse.web_search_requests === 'number') {
|
|
1995
|
+
webSearchCount = serverToolUse.web_search_requests;
|
|
1996
|
+
}
|
|
1997
|
+
} else {
|
|
1998
|
+
// For other providers through Vercel, pass available metadata to helper
|
|
1999
|
+
// Note: Vercel abstracts provider responses, so we may not have access to
|
|
2000
|
+
// raw citations/annotations unless Vercel exposes them in usage/metadata
|
|
2001
|
+
webSearchCount = calculateWebSearchCount({
|
|
2002
|
+
usage: result.usage,
|
|
2003
|
+
providerMetadata: providerMetadata
|
|
2004
|
+
});
|
|
2005
|
+
}
|
|
1861
2006
|
const usage = {
|
|
1862
2007
|
inputTokens: result.usage.inputTokens,
|
|
1863
2008
|
outputTokens: result.usage.outputTokens,
|
|
1864
2009
|
reasoningTokens: result.usage.reasoningTokens,
|
|
1865
2010
|
cacheReadInputTokens: result.usage.cachedInputTokens,
|
|
2011
|
+
webSearchCount,
|
|
1866
2012
|
...additionalTokenValues
|
|
1867
2013
|
};
|
|
1868
2014
|
await sendEventToPosthog({
|
|
@@ -1916,6 +2062,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
1916
2062
|
let generatedText = '';
|
|
1917
2063
|
let reasoningText = '';
|
|
1918
2064
|
let usage = {};
|
|
2065
|
+
let providerMetadata = undefined;
|
|
1919
2066
|
const mergedParams = {
|
|
1920
2067
|
...options,
|
|
1921
2068
|
...mapVercelParams(params),
|
|
@@ -1973,12 +2120,10 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
1973
2120
|
});
|
|
1974
2121
|
}
|
|
1975
2122
|
if (chunk.type === 'finish') {
|
|
1976
|
-
|
|
1977
|
-
const additionalTokenValues = {
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
} : {})
|
|
1981
|
-
};
|
|
2123
|
+
providerMetadata = chunk.providerMetadata;
|
|
2124
|
+
const additionalTokenValues = providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'cacheCreationInputTokens' in providerMetadata.anthropic ? {
|
|
2125
|
+
cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
|
|
2126
|
+
} : {};
|
|
1982
2127
|
usage = {
|
|
1983
2128
|
inputTokens: chunk.usage?.inputTokens,
|
|
1984
2129
|
outputTokens: chunk.usage?.outputTokens,
|
|
@@ -2023,6 +2168,28 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
2023
2168
|
role: 'assistant',
|
|
2024
2169
|
content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
|
|
2025
2170
|
}] : [];
|
|
2171
|
+
// Calculate web search count based on provider
|
|
2172
|
+
let webSearchCount = 0;
|
|
2173
|
+
if (providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'server_tool_use' in providerMetadata.anthropic) {
|
|
2174
|
+
// Anthropic-specific extraction
|
|
2175
|
+
const serverToolUse = providerMetadata.anthropic.server_tool_use;
|
|
2176
|
+
if (serverToolUse && typeof serverToolUse === 'object' && 'web_search_requests' in serverToolUse && typeof serverToolUse.web_search_requests === 'number') {
|
|
2177
|
+
webSearchCount = serverToolUse.web_search_requests;
|
|
2178
|
+
}
|
|
2179
|
+
} else {
|
|
2180
|
+
// For other providers through Vercel, pass available metadata to helper
|
|
2181
|
+
// Note: Vercel abstracts provider responses, so we may not have access to
|
|
2182
|
+
// raw citations/annotations unless Vercel exposes them in usage/metadata
|
|
2183
|
+
webSearchCount = calculateWebSearchCount({
|
|
2184
|
+
usage: usage,
|
|
2185
|
+
providerMetadata: providerMetadata
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
// Update usage with web search count
|
|
2189
|
+
const finalUsage = {
|
|
2190
|
+
...usage,
|
|
2191
|
+
webSearchCount
|
|
2192
|
+
};
|
|
2026
2193
|
await sendEventToPosthog({
|
|
2027
2194
|
client: phClient,
|
|
2028
2195
|
distinctId: options.posthogDistinctId,
|
|
@@ -2035,7 +2202,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
2035
2202
|
baseURL,
|
|
2036
2203
|
params: mergedParams,
|
|
2037
2204
|
httpStatus: 200,
|
|
2038
|
-
usage,
|
|
2205
|
+
usage: finalUsage,
|
|
2039
2206
|
tools: availableTools,
|
|
2040
2207
|
captureImmediate: options.posthogCaptureImmediate
|
|
2041
2208
|
});
|
|
@@ -2121,7 +2288,8 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2121
2288
|
inputTokens: 0,
|
|
2122
2289
|
outputTokens: 0,
|
|
2123
2290
|
cacheCreationInputTokens: 0,
|
|
2124
|
-
cacheReadInputTokens: 0
|
|
2291
|
+
cacheReadInputTokens: 0,
|
|
2292
|
+
webSearchCount: 0
|
|
2125
2293
|
};
|
|
2126
2294
|
if ('tee' in value) {
|
|
2127
2295
|
const [stream1, stream2] = value.tee();
|
|
@@ -2198,9 +2366,14 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2198
2366
|
usage.inputTokens = chunk.message.usage.input_tokens ?? 0;
|
|
2199
2367
|
usage.cacheCreationInputTokens = chunk.message.usage.cache_creation_input_tokens ?? 0;
|
|
2200
2368
|
usage.cacheReadInputTokens = chunk.message.usage.cache_read_input_tokens ?? 0;
|
|
2369
|
+
usage.webSearchCount = chunk.message.usage.server_tool_use?.web_search_requests ?? 0;
|
|
2201
2370
|
}
|
|
2202
2371
|
if ('usage' in chunk) {
|
|
2203
2372
|
usage.outputTokens = chunk.usage.output_tokens ?? 0;
|
|
2373
|
+
// Update web search count if present in delta
|
|
2374
|
+
if (chunk.usage.server_tool_use?.web_search_requests !== undefined) {
|
|
2375
|
+
usage.webSearchCount = chunk.usage.server_tool_use.web_search_requests;
|
|
2376
|
+
}
|
|
2204
2377
|
}
|
|
2205
2378
|
}
|
|
2206
2379
|
const latency = (Date.now() - startTime) / 1000;
|
|
@@ -2277,7 +2450,8 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2277
2450
|
inputTokens: result.usage.input_tokens ?? 0,
|
|
2278
2451
|
outputTokens: result.usage.output_tokens ?? 0,
|
|
2279
2452
|
cacheCreationInputTokens: result.usage.cache_creation_input_tokens ?? 0,
|
|
2280
|
-
cacheReadInputTokens: result.usage.cache_read_input_tokens ?? 0
|
|
2453
|
+
cacheReadInputTokens: result.usage.cache_read_input_tokens ?? 0,
|
|
2454
|
+
webSearchCount: result.usage.server_tool_use?.web_search_requests ?? 0
|
|
2281
2455
|
},
|
|
2282
2456
|
tools: availableTools
|
|
2283
2457
|
});
|
|
@@ -2351,7 +2525,8 @@ class WrappedModels {
|
|
|
2351
2525
|
inputTokens: metadata?.promptTokenCount ?? 0,
|
|
2352
2526
|
outputTokens: metadata?.candidatesTokenCount ?? 0,
|
|
2353
2527
|
reasoningTokens: metadata?.thoughtsTokenCount ?? 0,
|
|
2354
|
-
cacheReadInputTokens: metadata?.cachedContentTokenCount ?? 0
|
|
2528
|
+
cacheReadInputTokens: metadata?.cachedContentTokenCount ?? 0,
|
|
2529
|
+
webSearchCount: calculateGoogleWebSearchCount(response)
|
|
2355
2530
|
},
|
|
2356
2531
|
tools: availableTools
|
|
2357
2532
|
});
|
|
@@ -2388,11 +2563,16 @@ class WrappedModels {
|
|
|
2388
2563
|
const accumulatedContent = [];
|
|
2389
2564
|
let usage = {
|
|
2390
2565
|
inputTokens: 0,
|
|
2391
|
-
outputTokens: 0
|
|
2566
|
+
outputTokens: 0,
|
|
2567
|
+
webSearchCount: 0
|
|
2392
2568
|
};
|
|
2393
2569
|
try {
|
|
2394
2570
|
const stream = await this.client.models.generateContentStream(geminiParams);
|
|
2395
2571
|
for await (const chunk of stream) {
|
|
2572
|
+
const chunkWebSearchCount = calculateGoogleWebSearchCount(chunk);
|
|
2573
|
+
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2574
|
+
usage.webSearchCount = chunkWebSearchCount;
|
|
2575
|
+
}
|
|
2396
2576
|
// Handle text content
|
|
2397
2577
|
if (chunk.text) {
|
|
2398
2578
|
// Find if we already have a text item to append to
|
|
@@ -2441,7 +2621,8 @@ class WrappedModels {
|
|
|
2441
2621
|
inputTokens: metadata.promptTokenCount ?? 0,
|
|
2442
2622
|
outputTokens: metadata.candidatesTokenCount ?? 0,
|
|
2443
2623
|
reasoningTokens: metadata.thoughtsTokenCount ?? 0,
|
|
2444
|
-
cacheReadInputTokens: metadata.cachedContentTokenCount ?? 0
|
|
2624
|
+
cacheReadInputTokens: metadata.cachedContentTokenCount ?? 0,
|
|
2625
|
+
webSearchCount: usage.webSearchCount
|
|
2445
2626
|
};
|
|
2446
2627
|
}
|
|
2447
2628
|
yield chunk;
|
|
@@ -2464,7 +2645,10 @@ class WrappedModels {
|
|
|
2464
2645
|
baseURL: 'https://generativelanguage.googleapis.com',
|
|
2465
2646
|
params: params,
|
|
2466
2647
|
httpStatus: 200,
|
|
2467
|
-
usage
|
|
2648
|
+
usage: {
|
|
2649
|
+
...usage,
|
|
2650
|
+
webSearchCount: usage.webSearchCount
|
|
2651
|
+
},
|
|
2468
2652
|
tools: availableTools
|
|
2469
2653
|
});
|
|
2470
2654
|
} catch (error) {
|
|
@@ -2607,6 +2791,66 @@ class WrappedModels {
|
|
|
2607
2791
|
return messages;
|
|
2608
2792
|
}
|
|
2609
2793
|
}
|
|
2794
|
+
/**
|
|
2795
|
+
* Detect if Google Search grounding was used in the response.
|
|
2796
|
+
* Gemini bills per request that uses grounding, not per individual query.
|
|
2797
|
+
* Returns 1 if grounding was used, 0 otherwise.
|
|
2798
|
+
*/
|
|
2799
|
+
function calculateGoogleWebSearchCount(response) {
|
|
2800
|
+
if (!response || typeof response !== 'object' || !('candidates' in response)) {
|
|
2801
|
+
return 0;
|
|
2802
|
+
}
|
|
2803
|
+
const candidates = response.candidates;
|
|
2804
|
+
if (!Array.isArray(candidates)) {
|
|
2805
|
+
return 0;
|
|
2806
|
+
}
|
|
2807
|
+
const hasGrounding = candidates.some(candidate => {
|
|
2808
|
+
if (!candidate || typeof candidate !== 'object') {
|
|
2809
|
+
return false;
|
|
2810
|
+
}
|
|
2811
|
+
// Check for grounding metadata
|
|
2812
|
+
if ('groundingMetadata' in candidate && candidate.groundingMetadata) {
|
|
2813
|
+
const metadata = candidate.groundingMetadata;
|
|
2814
|
+
if (typeof metadata === 'object') {
|
|
2815
|
+
// Check if web_search_queries exists and is non-empty
|
|
2816
|
+
if ('webSearchQueries' in metadata && Array.isArray(metadata.webSearchQueries) && metadata.webSearchQueries.length > 0) {
|
|
2817
|
+
return true;
|
|
2818
|
+
}
|
|
2819
|
+
// Check if grounding_chunks exists and is non-empty
|
|
2820
|
+
if ('groundingChunks' in metadata && Array.isArray(metadata.groundingChunks) && metadata.groundingChunks.length > 0) {
|
|
2821
|
+
return true;
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
// Check for google search in function calls
|
|
2826
|
+
if ('content' in candidate && candidate.content && typeof candidate.content === 'object') {
|
|
2827
|
+
const content = candidate.content;
|
|
2828
|
+
if ('parts' in content && Array.isArray(content.parts)) {
|
|
2829
|
+
return content.parts.some(part => {
|
|
2830
|
+
if (!part || typeof part !== 'object' || !('functionCall' in part)) {
|
|
2831
|
+
return false;
|
|
2832
|
+
}
|
|
2833
|
+
const functionCall = part.functionCall;
|
|
2834
|
+
if (functionCall && typeof functionCall === 'object' && 'name' in functionCall && typeof functionCall.name === 'string') {
|
|
2835
|
+
return functionCall.name.includes('google_search') || functionCall.name.includes('grounding');
|
|
2836
|
+
}
|
|
2837
|
+
return false;
|
|
2838
|
+
});
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
return false;
|
|
2842
|
+
});
|
|
2843
|
+
return hasGrounding ? 1 : 0;
|
|
2844
|
+
}
|
|
2845
|
+
|
|
2846
|
+
//#region rolldown:runtime
|
|
2847
|
+
var __defProp = Object.defineProperty;
|
|
2848
|
+
var __export = (target, all) => {
|
|
2849
|
+
for (var name in all) __defProp(target, name, {
|
|
2850
|
+
get: all[name],
|
|
2851
|
+
enumerable: true
|
|
2852
|
+
});
|
|
2853
|
+
};
|
|
2610
2854
|
|
|
2611
2855
|
function getDefaultExportFromCjs (x) {
|
|
2612
2856
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -2760,370 +3004,304 @@ function requireCamelcase () {
|
|
|
2760
3004
|
|
|
2761
3005
|
requireCamelcase();
|
|
2762
3006
|
|
|
3007
|
+
//#region src/load/map_keys.ts
|
|
2763
3008
|
function keyToJson(key, map) {
|
|
2764
|
-
|
|
3009
|
+
return map?.[key] || snakeCase(key);
|
|
2765
3010
|
}
|
|
2766
3011
|
function mapKeys(fields, mapper, map) {
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
mapped[mapper(key, map)] = fields[key];
|
|
2771
|
-
}
|
|
2772
|
-
}
|
|
2773
|
-
return mapped;
|
|
3012
|
+
const mapped = {};
|
|
3013
|
+
for (const key in fields) if (Object.hasOwn(fields, key)) mapped[mapper(key, map)] = fields[key];
|
|
3014
|
+
return mapped;
|
|
2774
3015
|
}
|
|
2775
3016
|
|
|
3017
|
+
//#region src/load/serializable.ts
|
|
3018
|
+
var serializable_exports = {};
|
|
3019
|
+
__export(serializable_exports, {
|
|
3020
|
+
Serializable: () => Serializable,
|
|
3021
|
+
get_lc_unique_name: () => get_lc_unique_name
|
|
3022
|
+
});
|
|
2776
3023
|
function shallowCopy(obj) {
|
|
2777
|
-
|
|
3024
|
+
return Array.isArray(obj) ? [...obj] : { ...obj };
|
|
2778
3025
|
}
|
|
2779
3026
|
function replaceSecrets(root, secretsMap) {
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
id: [secretId],
|
|
2797
|
-
};
|
|
2798
|
-
}
|
|
2799
|
-
}
|
|
2800
|
-
return result;
|
|
3027
|
+
const result = shallowCopy(root);
|
|
3028
|
+
for (const [path, secretId] of Object.entries(secretsMap)) {
|
|
3029
|
+
const [last, ...partsReverse] = path.split(".").reverse();
|
|
3030
|
+
let current = result;
|
|
3031
|
+
for (const part of partsReverse.reverse()) {
|
|
3032
|
+
if (current[part] === void 0) break;
|
|
3033
|
+
current[part] = shallowCopy(current[part]);
|
|
3034
|
+
current = current[part];
|
|
3035
|
+
}
|
|
3036
|
+
if (current[last] !== void 0) current[last] = {
|
|
3037
|
+
lc: 1,
|
|
3038
|
+
type: "secret",
|
|
3039
|
+
id: [secretId]
|
|
3040
|
+
};
|
|
3041
|
+
}
|
|
3042
|
+
return result;
|
|
2801
3043
|
}
|
|
2802
3044
|
/**
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
function get_lc_unique_name(
|
|
2807
|
-
|
|
2808
|
-
serializableClass)
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
const parentClass = Object.getPrototypeOf(serializableClass);
|
|
2812
|
-
const lcNameIsSubclassed = typeof serializableClass.lc_name === "function" &&
|
|
2813
|
-
(typeof parentClass.lc_name !== "function" ||
|
|
2814
|
-
serializableClass.lc_name() !== parentClass.lc_name());
|
|
2815
|
-
if (lcNameIsSubclassed) {
|
|
2816
|
-
return serializableClass.lc_name();
|
|
2817
|
-
}
|
|
2818
|
-
else {
|
|
2819
|
-
return serializableClass.name;
|
|
2820
|
-
}
|
|
2821
|
-
}
|
|
2822
|
-
class Serializable {
|
|
2823
|
-
/**
|
|
2824
|
-
* The name of the serializable. Override to provide an alias or
|
|
2825
|
-
* to preserve the serialized module name in minified environments.
|
|
2826
|
-
*
|
|
2827
|
-
* Implemented as a static method to support loading logic.
|
|
2828
|
-
*/
|
|
2829
|
-
static lc_name() {
|
|
2830
|
-
return this.name;
|
|
2831
|
-
}
|
|
2832
|
-
/**
|
|
2833
|
-
* The final serialized identifier for the module.
|
|
2834
|
-
*/
|
|
2835
|
-
get lc_id() {
|
|
2836
|
-
return [
|
|
2837
|
-
...this.lc_namespace,
|
|
2838
|
-
get_lc_unique_name(this.constructor),
|
|
2839
|
-
];
|
|
2840
|
-
}
|
|
2841
|
-
/**
|
|
2842
|
-
* A map of secrets, which will be omitted from serialization.
|
|
2843
|
-
* Keys are paths to the secret in constructor args, e.g. "foo.bar.baz".
|
|
2844
|
-
* Values are the secret ids, which will be used when deserializing.
|
|
2845
|
-
*/
|
|
2846
|
-
get lc_secrets() {
|
|
2847
|
-
return undefined;
|
|
2848
|
-
}
|
|
2849
|
-
/**
|
|
2850
|
-
* A map of additional attributes to merge with constructor args.
|
|
2851
|
-
* Keys are the attribute names, e.g. "foo".
|
|
2852
|
-
* Values are the attribute values, which will be serialized.
|
|
2853
|
-
* These attributes need to be accepted by the constructor as arguments.
|
|
2854
|
-
*/
|
|
2855
|
-
get lc_attributes() {
|
|
2856
|
-
return undefined;
|
|
2857
|
-
}
|
|
2858
|
-
/**
|
|
2859
|
-
* A map of aliases for constructor args.
|
|
2860
|
-
* Keys are the attribute names, e.g. "foo".
|
|
2861
|
-
* Values are the alias that will replace the key in serialization.
|
|
2862
|
-
* This is used to eg. make argument names match Python.
|
|
2863
|
-
*/
|
|
2864
|
-
get lc_aliases() {
|
|
2865
|
-
return undefined;
|
|
2866
|
-
}
|
|
2867
|
-
/**
|
|
2868
|
-
* A manual list of keys that should be serialized.
|
|
2869
|
-
* If not overridden, all fields passed into the constructor will be serialized.
|
|
2870
|
-
*/
|
|
2871
|
-
get lc_serializable_keys() {
|
|
2872
|
-
return undefined;
|
|
2873
|
-
}
|
|
2874
|
-
constructor(kwargs, ..._args) {
|
|
2875
|
-
Object.defineProperty(this, "lc_serializable", {
|
|
2876
|
-
enumerable: true,
|
|
2877
|
-
configurable: true,
|
|
2878
|
-
writable: true,
|
|
2879
|
-
value: false
|
|
2880
|
-
});
|
|
2881
|
-
Object.defineProperty(this, "lc_kwargs", {
|
|
2882
|
-
enumerable: true,
|
|
2883
|
-
configurable: true,
|
|
2884
|
-
writable: true,
|
|
2885
|
-
value: void 0
|
|
2886
|
-
});
|
|
2887
|
-
if (this.lc_serializable_keys !== undefined) {
|
|
2888
|
-
this.lc_kwargs = Object.fromEntries(Object.entries(kwargs || {}).filter(([key]) => this.lc_serializable_keys?.includes(key)));
|
|
2889
|
-
}
|
|
2890
|
-
else {
|
|
2891
|
-
this.lc_kwargs = kwargs ?? {};
|
|
2892
|
-
}
|
|
2893
|
-
}
|
|
2894
|
-
toJSON() {
|
|
2895
|
-
if (!this.lc_serializable) {
|
|
2896
|
-
return this.toJSONNotImplemented();
|
|
2897
|
-
}
|
|
2898
|
-
if (
|
|
2899
|
-
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
2900
|
-
this.lc_kwargs instanceof Serializable ||
|
|
2901
|
-
typeof this.lc_kwargs !== "object" ||
|
|
2902
|
-
Array.isArray(this.lc_kwargs)) {
|
|
2903
|
-
// We do not support serialization of classes with arg not a POJO
|
|
2904
|
-
// I'm aware the check above isn't as strict as it could be
|
|
2905
|
-
return this.toJSONNotImplemented();
|
|
2906
|
-
}
|
|
2907
|
-
const aliases = {};
|
|
2908
|
-
const secrets = {};
|
|
2909
|
-
const kwargs = Object.keys(this.lc_kwargs).reduce((acc, key) => {
|
|
2910
|
-
acc[key] = key in this ? this[key] : this.lc_kwargs[key];
|
|
2911
|
-
return acc;
|
|
2912
|
-
}, {});
|
|
2913
|
-
// get secrets, attributes and aliases from all superclasses
|
|
2914
|
-
for (
|
|
2915
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
2916
|
-
let current = Object.getPrototypeOf(this); current; current = Object.getPrototypeOf(current)) {
|
|
2917
|
-
Object.assign(aliases, Reflect.get(current, "lc_aliases", this));
|
|
2918
|
-
Object.assign(secrets, Reflect.get(current, "lc_secrets", this));
|
|
2919
|
-
Object.assign(kwargs, Reflect.get(current, "lc_attributes", this));
|
|
2920
|
-
}
|
|
2921
|
-
// include all secrets used, even if not in kwargs,
|
|
2922
|
-
// will be replaced with sentinel value in replaceSecrets
|
|
2923
|
-
Object.keys(secrets).forEach((keyPath) => {
|
|
2924
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-explicit-any
|
|
2925
|
-
let read = this;
|
|
2926
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2927
|
-
let write = kwargs;
|
|
2928
|
-
const [last, ...partsReverse] = keyPath.split(".").reverse();
|
|
2929
|
-
for (const key of partsReverse.reverse()) {
|
|
2930
|
-
if (!(key in read) || read[key] === undefined)
|
|
2931
|
-
return;
|
|
2932
|
-
if (!(key in write) || write[key] === undefined) {
|
|
2933
|
-
if (typeof read[key] === "object" && read[key] != null) {
|
|
2934
|
-
write[key] = {};
|
|
2935
|
-
}
|
|
2936
|
-
else if (Array.isArray(read[key])) {
|
|
2937
|
-
write[key] = [];
|
|
2938
|
-
}
|
|
2939
|
-
}
|
|
2940
|
-
read = read[key];
|
|
2941
|
-
write = write[key];
|
|
2942
|
-
}
|
|
2943
|
-
if (last in read && read[last] !== undefined) {
|
|
2944
|
-
write[last] = write[last] || read[last];
|
|
2945
|
-
}
|
|
2946
|
-
});
|
|
2947
|
-
return {
|
|
2948
|
-
lc: 1,
|
|
2949
|
-
type: "constructor",
|
|
2950
|
-
id: this.lc_id,
|
|
2951
|
-
kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases),
|
|
2952
|
-
};
|
|
2953
|
-
}
|
|
2954
|
-
toJSONNotImplemented() {
|
|
2955
|
-
return {
|
|
2956
|
-
lc: 1,
|
|
2957
|
-
type: "not_implemented",
|
|
2958
|
-
id: this.lc_id,
|
|
2959
|
-
};
|
|
2960
|
-
}
|
|
3045
|
+
* Get a unique name for the module, rather than parent class implementations.
|
|
3046
|
+
* Should not be subclassed, subclass lc_name above instead.
|
|
3047
|
+
*/
|
|
3048
|
+
function get_lc_unique_name(serializableClass) {
|
|
3049
|
+
const parentClass = Object.getPrototypeOf(serializableClass);
|
|
3050
|
+
const lcNameIsSubclassed = typeof serializableClass.lc_name === "function" && (typeof parentClass.lc_name !== "function" || serializableClass.lc_name() !== parentClass.lc_name());
|
|
3051
|
+
if (lcNameIsSubclassed) return serializableClass.lc_name();
|
|
3052
|
+
else return serializableClass.name;
|
|
2961
3053
|
}
|
|
3054
|
+
var Serializable = class Serializable {
|
|
3055
|
+
lc_serializable = false;
|
|
3056
|
+
lc_kwargs;
|
|
3057
|
+
/**
|
|
3058
|
+
* The name of the serializable. Override to provide an alias or
|
|
3059
|
+
* to preserve the serialized module name in minified environments.
|
|
3060
|
+
*
|
|
3061
|
+
* Implemented as a static method to support loading logic.
|
|
3062
|
+
*/
|
|
3063
|
+
static lc_name() {
|
|
3064
|
+
return this.name;
|
|
3065
|
+
}
|
|
3066
|
+
/**
|
|
3067
|
+
* The final serialized identifier for the module.
|
|
3068
|
+
*/
|
|
3069
|
+
get lc_id() {
|
|
3070
|
+
return [...this.lc_namespace, get_lc_unique_name(this.constructor)];
|
|
3071
|
+
}
|
|
3072
|
+
/**
|
|
3073
|
+
* A map of secrets, which will be omitted from serialization.
|
|
3074
|
+
* Keys are paths to the secret in constructor args, e.g. "foo.bar.baz".
|
|
3075
|
+
* Values are the secret ids, which will be used when deserializing.
|
|
3076
|
+
*/
|
|
3077
|
+
get lc_secrets() {
|
|
3078
|
+
return void 0;
|
|
3079
|
+
}
|
|
3080
|
+
/**
|
|
3081
|
+
* A map of additional attributes to merge with constructor args.
|
|
3082
|
+
* Keys are the attribute names, e.g. "foo".
|
|
3083
|
+
* Values are the attribute values, which will be serialized.
|
|
3084
|
+
* These attributes need to be accepted by the constructor as arguments.
|
|
3085
|
+
*/
|
|
3086
|
+
get lc_attributes() {
|
|
3087
|
+
return void 0;
|
|
3088
|
+
}
|
|
3089
|
+
/**
|
|
3090
|
+
* A map of aliases for constructor args.
|
|
3091
|
+
* Keys are the attribute names, e.g. "foo".
|
|
3092
|
+
* Values are the alias that will replace the key in serialization.
|
|
3093
|
+
* This is used to eg. make argument names match Python.
|
|
3094
|
+
*/
|
|
3095
|
+
get lc_aliases() {
|
|
3096
|
+
return void 0;
|
|
3097
|
+
}
|
|
3098
|
+
/**
|
|
3099
|
+
* A manual list of keys that should be serialized.
|
|
3100
|
+
* If not overridden, all fields passed into the constructor will be serialized.
|
|
3101
|
+
*/
|
|
3102
|
+
get lc_serializable_keys() {
|
|
3103
|
+
return void 0;
|
|
3104
|
+
}
|
|
3105
|
+
constructor(kwargs, ..._args) {
|
|
3106
|
+
if (this.lc_serializable_keys !== void 0) this.lc_kwargs = Object.fromEntries(Object.entries(kwargs || {}).filter(([key]) => this.lc_serializable_keys?.includes(key)));
|
|
3107
|
+
else this.lc_kwargs = kwargs ?? {};
|
|
3108
|
+
}
|
|
3109
|
+
toJSON() {
|
|
3110
|
+
if (!this.lc_serializable) return this.toJSONNotImplemented();
|
|
3111
|
+
if (this.lc_kwargs instanceof Serializable || typeof this.lc_kwargs !== "object" || Array.isArray(this.lc_kwargs)) return this.toJSONNotImplemented();
|
|
3112
|
+
const aliases = {};
|
|
3113
|
+
const secrets = {};
|
|
3114
|
+
const kwargs = Object.keys(this.lc_kwargs).reduce((acc, key) => {
|
|
3115
|
+
acc[key] = key in this ? this[key] : this.lc_kwargs[key];
|
|
3116
|
+
return acc;
|
|
3117
|
+
}, {});
|
|
3118
|
+
for (let current = Object.getPrototypeOf(this); current; current = Object.getPrototypeOf(current)) {
|
|
3119
|
+
Object.assign(aliases, Reflect.get(current, "lc_aliases", this));
|
|
3120
|
+
Object.assign(secrets, Reflect.get(current, "lc_secrets", this));
|
|
3121
|
+
Object.assign(kwargs, Reflect.get(current, "lc_attributes", this));
|
|
3122
|
+
}
|
|
3123
|
+
Object.keys(secrets).forEach((keyPath) => {
|
|
3124
|
+
let read = this;
|
|
3125
|
+
let write = kwargs;
|
|
3126
|
+
const [last, ...partsReverse] = keyPath.split(".").reverse();
|
|
3127
|
+
for (const key of partsReverse.reverse()) {
|
|
3128
|
+
if (!(key in read) || read[key] === void 0) return;
|
|
3129
|
+
if (!(key in write) || write[key] === void 0) {
|
|
3130
|
+
if (typeof read[key] === "object" && read[key] != null) write[key] = {};
|
|
3131
|
+
else if (Array.isArray(read[key])) write[key] = [];
|
|
3132
|
+
}
|
|
3133
|
+
read = read[key];
|
|
3134
|
+
write = write[key];
|
|
3135
|
+
}
|
|
3136
|
+
if (last in read && read[last] !== void 0) write[last] = write[last] || read[last];
|
|
3137
|
+
});
|
|
3138
|
+
return {
|
|
3139
|
+
lc: 1,
|
|
3140
|
+
type: "constructor",
|
|
3141
|
+
id: this.lc_id,
|
|
3142
|
+
kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases)
|
|
3143
|
+
};
|
|
3144
|
+
}
|
|
3145
|
+
toJSONNotImplemented() {
|
|
3146
|
+
return {
|
|
3147
|
+
lc: 1,
|
|
3148
|
+
type: "not_implemented",
|
|
3149
|
+
id: this.lc_id
|
|
3150
|
+
};
|
|
3151
|
+
}
|
|
3152
|
+
};
|
|
2962
3153
|
|
|
2963
|
-
|
|
2964
|
-
|
|
3154
|
+
//#region src/utils/env.ts
|
|
3155
|
+
var env_exports = {};
|
|
3156
|
+
__export(env_exports, {
|
|
3157
|
+
getEnv: () => getEnv,
|
|
3158
|
+
getEnvironmentVariable: () => getEnvironmentVariable,
|
|
3159
|
+
getRuntimeEnvironment: () => getRuntimeEnvironment,
|
|
3160
|
+
isBrowser: () => isBrowser,
|
|
3161
|
+
isDeno: () => isDeno,
|
|
3162
|
+
isJsDom: () => isJsDom,
|
|
3163
|
+
isNode: () => isNode,
|
|
3164
|
+
isWebWorker: () => isWebWorker
|
|
3165
|
+
});
|
|
3166
|
+
const isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
3167
|
+
const isWebWorker = () => typeof globalThis === "object" && globalThis.constructor && globalThis.constructor.name === "DedicatedWorkerGlobalScope";
|
|
3168
|
+
const isJsDom = () => typeof window !== "undefined" && window.name === "nodejs" || typeof navigator !== "undefined" && navigator.userAgent.includes("jsdom");
|
|
2965
3169
|
const isDeno = () => typeof Deno !== "undefined";
|
|
3170
|
+
const isNode = () => typeof process !== "undefined" && typeof process.versions !== "undefined" && typeof process.versions.node !== "undefined" && !isDeno();
|
|
3171
|
+
const getEnv = () => {
|
|
3172
|
+
let env;
|
|
3173
|
+
if (isBrowser()) env = "browser";
|
|
3174
|
+
else if (isNode()) env = "node";
|
|
3175
|
+
else if (isWebWorker()) env = "webworker";
|
|
3176
|
+
else if (isJsDom()) env = "jsdom";
|
|
3177
|
+
else if (isDeno()) env = "deno";
|
|
3178
|
+
else env = "other";
|
|
3179
|
+
return env;
|
|
3180
|
+
};
|
|
3181
|
+
let runtimeEnvironment;
|
|
3182
|
+
function getRuntimeEnvironment() {
|
|
3183
|
+
if (runtimeEnvironment === void 0) {
|
|
3184
|
+
const env = getEnv();
|
|
3185
|
+
runtimeEnvironment = {
|
|
3186
|
+
library: "langchain-js",
|
|
3187
|
+
runtime: env
|
|
3188
|
+
};
|
|
3189
|
+
}
|
|
3190
|
+
return runtimeEnvironment;
|
|
3191
|
+
}
|
|
2966
3192
|
function getEnvironmentVariable(name) {
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
else if (isDeno()) {
|
|
2975
|
-
return Deno?.env.get(name);
|
|
2976
|
-
}
|
|
2977
|
-
else {
|
|
2978
|
-
return undefined;
|
|
2979
|
-
}
|
|
2980
|
-
}
|
|
2981
|
-
catch (e) {
|
|
2982
|
-
return undefined;
|
|
2983
|
-
}
|
|
3193
|
+
try {
|
|
3194
|
+
if (typeof process !== "undefined") return process.env?.[name];
|
|
3195
|
+
else if (isDeno()) return Deno?.env.get(name);
|
|
3196
|
+
else return void 0;
|
|
3197
|
+
} catch {
|
|
3198
|
+
return void 0;
|
|
3199
|
+
}
|
|
2984
3200
|
}
|
|
2985
3201
|
|
|
3202
|
+
//#region src/callbacks/base.ts
|
|
3203
|
+
var base_exports = {};
|
|
3204
|
+
__export(base_exports, {
|
|
3205
|
+
BaseCallbackHandler: () => BaseCallbackHandler,
|
|
3206
|
+
callbackHandlerPrefersStreaming: () => callbackHandlerPrefersStreaming,
|
|
3207
|
+
isBaseCallbackHandler: () => isBaseCallbackHandler
|
|
3208
|
+
});
|
|
2986
3209
|
/**
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
3210
|
+
* Abstract class that provides a set of optional methods that can be
|
|
3211
|
+
* overridden in derived classes to handle various events during the
|
|
3212
|
+
* execution of a LangChain application.
|
|
3213
|
+
*/
|
|
3214
|
+
var BaseCallbackHandlerMethodsClass = class {};
|
|
3215
|
+
function callbackHandlerPrefersStreaming(x) {
|
|
3216
|
+
return "lc_prefer_streaming" in x && x.lc_prefer_streaming;
|
|
2992
3217
|
}
|
|
2993
3218
|
/**
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
writable: true,
|
|
3081
|
-
value: false
|
|
3082
|
-
});
|
|
3083
|
-
Object.defineProperty(this, "awaitHandlers", {
|
|
3084
|
-
enumerable: true,
|
|
3085
|
-
configurable: true,
|
|
3086
|
-
writable: true,
|
|
3087
|
-
value: getEnvironmentVariable("LANGCHAIN_CALLBACKS_BACKGROUND") === "false"
|
|
3088
|
-
});
|
|
3089
|
-
this.lc_kwargs = input || {};
|
|
3090
|
-
if (input) {
|
|
3091
|
-
this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
|
|
3092
|
-
this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
|
|
3093
|
-
this.ignoreAgent = input.ignoreAgent ?? this.ignoreAgent;
|
|
3094
|
-
this.ignoreRetriever = input.ignoreRetriever ?? this.ignoreRetriever;
|
|
3095
|
-
this.ignoreCustomEvent =
|
|
3096
|
-
input.ignoreCustomEvent ?? this.ignoreCustomEvent;
|
|
3097
|
-
this.raiseError = input.raiseError ?? this.raiseError;
|
|
3098
|
-
this.awaitHandlers =
|
|
3099
|
-
this.raiseError || (input._awaitHandler ?? this.awaitHandlers);
|
|
3100
|
-
}
|
|
3101
|
-
}
|
|
3102
|
-
copy() {
|
|
3103
|
-
return new this.constructor(this);
|
|
3104
|
-
}
|
|
3105
|
-
toJSON() {
|
|
3106
|
-
return Serializable.prototype.toJSON.call(this);
|
|
3107
|
-
}
|
|
3108
|
-
toJSONNotImplemented() {
|
|
3109
|
-
return Serializable.prototype.toJSONNotImplemented.call(this);
|
|
3110
|
-
}
|
|
3111
|
-
static fromMethods(methods) {
|
|
3112
|
-
class Handler extends BaseCallbackHandler {
|
|
3113
|
-
constructor() {
|
|
3114
|
-
super();
|
|
3115
|
-
Object.defineProperty(this, "name", {
|
|
3116
|
-
enumerable: true,
|
|
3117
|
-
configurable: true,
|
|
3118
|
-
writable: true,
|
|
3119
|
-
value: uuid__namespace.v4()
|
|
3120
|
-
});
|
|
3121
|
-
Object.assign(this, methods);
|
|
3122
|
-
}
|
|
3123
|
-
}
|
|
3124
|
-
return new Handler();
|
|
3125
|
-
}
|
|
3126
|
-
}
|
|
3219
|
+
* Abstract base class for creating callback handlers in the LangChain
|
|
3220
|
+
* framework. It provides a set of optional methods that can be overridden
|
|
3221
|
+
* in derived classes to handle various events during the execution of a
|
|
3222
|
+
* LangChain application.
|
|
3223
|
+
*/
|
|
3224
|
+
var BaseCallbackHandler = class extends BaseCallbackHandlerMethodsClass {
|
|
3225
|
+
lc_serializable = false;
|
|
3226
|
+
get lc_namespace() {
|
|
3227
|
+
return [
|
|
3228
|
+
"langchain_core",
|
|
3229
|
+
"callbacks",
|
|
3230
|
+
this.name
|
|
3231
|
+
];
|
|
3232
|
+
}
|
|
3233
|
+
get lc_secrets() {
|
|
3234
|
+
return void 0;
|
|
3235
|
+
}
|
|
3236
|
+
get lc_attributes() {
|
|
3237
|
+
return void 0;
|
|
3238
|
+
}
|
|
3239
|
+
get lc_aliases() {
|
|
3240
|
+
return void 0;
|
|
3241
|
+
}
|
|
3242
|
+
get lc_serializable_keys() {
|
|
3243
|
+
return void 0;
|
|
3244
|
+
}
|
|
3245
|
+
/**
|
|
3246
|
+
* The name of the serializable. Override to provide an alias or
|
|
3247
|
+
* to preserve the serialized module name in minified environments.
|
|
3248
|
+
*
|
|
3249
|
+
* Implemented as a static method to support loading logic.
|
|
3250
|
+
*/
|
|
3251
|
+
static lc_name() {
|
|
3252
|
+
return this.name;
|
|
3253
|
+
}
|
|
3254
|
+
/**
|
|
3255
|
+
* The final serialized identifier for the module.
|
|
3256
|
+
*/
|
|
3257
|
+
get lc_id() {
|
|
3258
|
+
return [...this.lc_namespace, get_lc_unique_name(this.constructor)];
|
|
3259
|
+
}
|
|
3260
|
+
lc_kwargs;
|
|
3261
|
+
ignoreLLM = false;
|
|
3262
|
+
ignoreChain = false;
|
|
3263
|
+
ignoreAgent = false;
|
|
3264
|
+
ignoreRetriever = false;
|
|
3265
|
+
ignoreCustomEvent = false;
|
|
3266
|
+
raiseError = false;
|
|
3267
|
+
awaitHandlers = getEnvironmentVariable("LANGCHAIN_CALLBACKS_BACKGROUND") === "false";
|
|
3268
|
+
constructor(input) {
|
|
3269
|
+
super();
|
|
3270
|
+
this.lc_kwargs = input || {};
|
|
3271
|
+
if (input) {
|
|
3272
|
+
this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
|
|
3273
|
+
this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
|
|
3274
|
+
this.ignoreAgent = input.ignoreAgent ?? this.ignoreAgent;
|
|
3275
|
+
this.ignoreRetriever = input.ignoreRetriever ?? this.ignoreRetriever;
|
|
3276
|
+
this.ignoreCustomEvent = input.ignoreCustomEvent ?? this.ignoreCustomEvent;
|
|
3277
|
+
this.raiseError = input.raiseError ?? this.raiseError;
|
|
3278
|
+
this.awaitHandlers = this.raiseError || (input._awaitHandler ?? this.awaitHandlers);
|
|
3279
|
+
}
|
|
3280
|
+
}
|
|
3281
|
+
copy() {
|
|
3282
|
+
return new this.constructor(this);
|
|
3283
|
+
}
|
|
3284
|
+
toJSON() {
|
|
3285
|
+
return Serializable.prototype.toJSON.call(this);
|
|
3286
|
+
}
|
|
3287
|
+
toJSONNotImplemented() {
|
|
3288
|
+
return Serializable.prototype.toJSONNotImplemented.call(this);
|
|
3289
|
+
}
|
|
3290
|
+
static fromMethods(methods) {
|
|
3291
|
+
class Handler extends BaseCallbackHandler {
|
|
3292
|
+
name = uuid__namespace.v4();
|
|
3293
|
+
constructor() {
|
|
3294
|
+
super();
|
|
3295
|
+
Object.assign(this, methods);
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
return new Handler();
|
|
3299
|
+
}
|
|
3300
|
+
};
|
|
3301
|
+
const isBaseCallbackHandler = (x) => {
|
|
3302
|
+
const callbackHandler = x;
|
|
3303
|
+
return callbackHandler !== void 0 && typeof callbackHandler.copy === "function" && typeof callbackHandler.name === "string" && typeof callbackHandler.awaitHandlers === "boolean";
|
|
3304
|
+
};
|
|
3127
3305
|
|
|
3128
3306
|
class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
3129
3307
|
constructor(options) {
|
|
@@ -3427,6 +3605,9 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
|
3427
3605
|
if (additionalTokenData.reasoningTokens) {
|
|
3428
3606
|
eventProperties['$ai_reasoning_tokens'] = additionalTokenData.reasoningTokens;
|
|
3429
3607
|
}
|
|
3608
|
+
if (additionalTokenData.webSearchCount !== undefined) {
|
|
3609
|
+
eventProperties['$ai_web_search_count'] = additionalTokenData.webSearchCount;
|
|
3610
|
+
}
|
|
3430
3611
|
// Handle generations/completions
|
|
3431
3612
|
let completions;
|
|
3432
3613
|
if (output.generations && Array.isArray(output.generations)) {
|
|
@@ -3592,6 +3773,42 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
|
3592
3773
|
} else if (usage.reasoningTokens != null) {
|
|
3593
3774
|
additionalTokenData.reasoningTokens = usage.reasoningTokens;
|
|
3594
3775
|
}
|
|
3776
|
+
// Extract web search counts from various provider formats
|
|
3777
|
+
let webSearchCount;
|
|
3778
|
+
// Priority 1: Exact Count
|
|
3779
|
+
// Check Anthropic format (server_tool_use.web_search_requests)
|
|
3780
|
+
if (usage.server_tool_use?.web_search_requests !== undefined) {
|
|
3781
|
+
webSearchCount = usage.server_tool_use.web_search_requests;
|
|
3782
|
+
}
|
|
3783
|
+
// Priority 2: Binary Detection (1 or 0)
|
|
3784
|
+
// Check for citations array (Perplexity)
|
|
3785
|
+
else if (usage.citations && Array.isArray(usage.citations) && usage.citations.length > 0) {
|
|
3786
|
+
webSearchCount = 1;
|
|
3787
|
+
}
|
|
3788
|
+
// Check for search_results array (Perplexity via OpenRouter)
|
|
3789
|
+
else if (usage.search_results && Array.isArray(usage.search_results) && usage.search_results.length > 0) {
|
|
3790
|
+
webSearchCount = 1;
|
|
3791
|
+
}
|
|
3792
|
+
// Check for search_context_size (Perplexity via OpenRouter)
|
|
3793
|
+
else if (usage.search_context_size) {
|
|
3794
|
+
webSearchCount = 1;
|
|
3795
|
+
}
|
|
3796
|
+
// Check for annotations with url_citation type
|
|
3797
|
+
else if (usage.annotations && Array.isArray(usage.annotations)) {
|
|
3798
|
+
const hasUrlCitation = usage.annotations.some(ann => {
|
|
3799
|
+
return ann && typeof ann === 'object' && 'type' in ann && ann.type === 'url_citation';
|
|
3800
|
+
});
|
|
3801
|
+
if (hasUrlCitation) {
|
|
3802
|
+
webSearchCount = 1;
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
// Check Gemini format (grounding metadata - binary 0 or 1)
|
|
3806
|
+
else if (usage.grounding_metadata?.grounding_support !== undefined || usage.grounding_metadata?.web_search_queries !== undefined) {
|
|
3807
|
+
webSearchCount = 1;
|
|
3808
|
+
}
|
|
3809
|
+
if (webSearchCount !== undefined) {
|
|
3810
|
+
additionalTokenData.webSearchCount = webSearchCount;
|
|
3811
|
+
}
|
|
3595
3812
|
// In LangChain, input_tokens is the sum of input and cache read tokens.
|
|
3596
3813
|
// Our cost calculation expects them to be separate, for Anthropic.
|
|
3597
3814
|
if (parsedUsage.input && additionalTokenData.cacheReadInputTokens) {
|