@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.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { wrapLanguageModel } from 'ai';
|
|
|
6
6
|
import AnthropicOriginal from '@anthropic-ai/sdk';
|
|
7
7
|
import { GoogleGenAI } from '@google/genai';
|
|
8
8
|
|
|
9
|
-
var version = "
|
|
9
|
+
var version = "7.0.0";
|
|
10
10
|
|
|
11
11
|
// Type guards for safer type checking
|
|
12
12
|
const isString = value => {
|
|
@@ -277,6 +277,101 @@ const truncate = input => {
|
|
|
277
277
|
}
|
|
278
278
|
return `${truncatedStr}... [truncated]`;
|
|
279
279
|
};
|
|
280
|
+
/**
|
|
281
|
+
* Calculate web search count from raw API response.
|
|
282
|
+
*
|
|
283
|
+
* Uses a two-tier detection strategy:
|
|
284
|
+
* Priority 1 (Exact Count): Count actual web search calls when available
|
|
285
|
+
* Priority 2 (Binary Detection): Return 1 if web search indicators are present, 0 otherwise
|
|
286
|
+
*
|
|
287
|
+
* @param result - Raw API response from any provider (OpenAI, Perplexity, OpenRouter, Gemini, etc.)
|
|
288
|
+
* @returns Number of web searches performed (exact count or binary 1/0)
|
|
289
|
+
*/
|
|
290
|
+
function calculateWebSearchCount(result) {
|
|
291
|
+
if (!result || typeof result !== 'object') {
|
|
292
|
+
return 0;
|
|
293
|
+
}
|
|
294
|
+
// Priority 1: Exact Count
|
|
295
|
+
// Check for OpenAI Responses API web_search_call items
|
|
296
|
+
if ('output' in result && Array.isArray(result.output)) {
|
|
297
|
+
let count = 0;
|
|
298
|
+
for (const item of result.output) {
|
|
299
|
+
if (typeof item === 'object' && item !== null && 'type' in item && item.type === 'web_search_call') {
|
|
300
|
+
count++;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (count > 0) {
|
|
304
|
+
return count;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// Priority 2: Binary Detection (1 or 0)
|
|
308
|
+
// Check for citations at root level (Perplexity)
|
|
309
|
+
if ('citations' in result && Array.isArray(result.citations) && result.citations.length > 0) {
|
|
310
|
+
return 1;
|
|
311
|
+
}
|
|
312
|
+
// Check for search_results at root level (Perplexity via OpenRouter)
|
|
313
|
+
if ('search_results' in result && Array.isArray(result.search_results) && result.search_results.length > 0) {
|
|
314
|
+
return 1;
|
|
315
|
+
}
|
|
316
|
+
// Check for usage.search_context_size (Perplexity via OpenRouter)
|
|
317
|
+
if ('usage' in result && typeof result.usage === 'object' && result.usage !== null) {
|
|
318
|
+
if ('search_context_size' in result.usage && result.usage.search_context_size) {
|
|
319
|
+
return 1;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// Check for annotations with url_citation in choices[].message or choices[].delta (OpenAI/Perplexity)
|
|
323
|
+
if ('choices' in result && Array.isArray(result.choices)) {
|
|
324
|
+
for (const choice of result.choices) {
|
|
325
|
+
if (typeof choice === 'object' && choice !== null) {
|
|
326
|
+
// Check both message (non-streaming) and delta (streaming) for annotations
|
|
327
|
+
const content = ('message' in choice ? choice.message : null) || ('delta' in choice ? choice.delta : null);
|
|
328
|
+
if (typeof content === 'object' && content !== null && 'annotations' in content) {
|
|
329
|
+
const annotations = content.annotations;
|
|
330
|
+
if (Array.isArray(annotations)) {
|
|
331
|
+
const hasUrlCitation = annotations.some(ann => {
|
|
332
|
+
return typeof ann === 'object' && ann !== null && 'type' in ann && ann.type === 'url_citation';
|
|
333
|
+
});
|
|
334
|
+
if (hasUrlCitation) {
|
|
335
|
+
return 1;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Check for annotations in output[].content[] (OpenAI Responses API)
|
|
343
|
+
if ('output' in result && Array.isArray(result.output)) {
|
|
344
|
+
for (const item of result.output) {
|
|
345
|
+
if (typeof item === 'object' && item !== null && 'content' in item) {
|
|
346
|
+
const content = item.content;
|
|
347
|
+
if (Array.isArray(content)) {
|
|
348
|
+
for (const contentItem of content) {
|
|
349
|
+
if (typeof contentItem === 'object' && contentItem !== null && 'annotations' in contentItem) {
|
|
350
|
+
const annotations = contentItem.annotations;
|
|
351
|
+
if (Array.isArray(annotations)) {
|
|
352
|
+
const hasUrlCitation = annotations.some(ann => {
|
|
353
|
+
return typeof ann === 'object' && ann !== null && 'type' in ann && ann.type === 'url_citation';
|
|
354
|
+
});
|
|
355
|
+
if (hasUrlCitation) {
|
|
356
|
+
return 1;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// Check for grounding_metadata (Gemini)
|
|
366
|
+
if ('candidates' in result && Array.isArray(result.candidates)) {
|
|
367
|
+
for (const candidate of result.candidates) {
|
|
368
|
+
if (typeof candidate === 'object' && candidate !== null && 'grounding_metadata' in candidate && candidate.grounding_metadata) {
|
|
369
|
+
return 1;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return 0;
|
|
374
|
+
}
|
|
280
375
|
/**
|
|
281
376
|
* Extract available tool calls from the request parameters.
|
|
282
377
|
* These are the tools provided to the LLM, not the tool calls in the response.
|
|
@@ -411,6 +506,9 @@ const sendEventToPosthog = async ({
|
|
|
411
506
|
} : {}),
|
|
412
507
|
...(usage.cacheCreationInputTokens ? {
|
|
413
508
|
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
509
|
+
} : {}),
|
|
510
|
+
...(usage.webSearchCount ? {
|
|
511
|
+
$ai_web_search_count: usage.webSearchCount
|
|
414
512
|
} : {})
|
|
415
513
|
};
|
|
416
514
|
const properties = {
|
|
@@ -721,12 +819,17 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
721
819
|
let accumulatedContent = '';
|
|
722
820
|
let usage = {
|
|
723
821
|
inputTokens: 0,
|
|
724
|
-
outputTokens: 0
|
|
822
|
+
outputTokens: 0,
|
|
823
|
+
webSearchCount: 0
|
|
725
824
|
};
|
|
726
825
|
// Map to track in-progress tool calls
|
|
727
826
|
const toolCallsInProgress = new Map();
|
|
728
827
|
for await (const chunk of stream1) {
|
|
729
828
|
const choice = chunk?.choices?.[0];
|
|
829
|
+
const chunkWebSearchCount = calculateWebSearchCount(chunk);
|
|
830
|
+
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
831
|
+
usage.webSearchCount = chunkWebSearchCount;
|
|
832
|
+
}
|
|
730
833
|
// Handle text content
|
|
731
834
|
const deltaContent = choice?.delta?.content;
|
|
732
835
|
if (deltaContent) {
|
|
@@ -765,6 +868,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
765
868
|
// Handle usage information
|
|
766
869
|
if (chunk.usage) {
|
|
767
870
|
usage = {
|
|
871
|
+
...usage,
|
|
768
872
|
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
769
873
|
outputTokens: chunk.usage.completion_tokens ?? 0,
|
|
770
874
|
reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
@@ -816,7 +920,13 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
816
920
|
baseURL: this.baseURL,
|
|
817
921
|
params: body,
|
|
818
922
|
httpStatus: 200,
|
|
819
|
-
usage
|
|
923
|
+
usage: {
|
|
924
|
+
inputTokens: usage.inputTokens,
|
|
925
|
+
outputTokens: usage.outputTokens,
|
|
926
|
+
reasoningTokens: usage.reasoningTokens,
|
|
927
|
+
cacheReadInputTokens: usage.cacheReadInputTokens,
|
|
928
|
+
webSearchCount: usage.webSearchCount
|
|
929
|
+
},
|
|
820
930
|
tools: availableTools
|
|
821
931
|
});
|
|
822
932
|
} catch (error) {
|
|
@@ -851,13 +961,14 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
851
961
|
if ('choices' in result) {
|
|
852
962
|
const latency = (Date.now() - startTime) / 1000;
|
|
853
963
|
const availableTools = extractAvailableToolCalls('openai', openAIParams);
|
|
964
|
+
const formattedOutput = formatResponseOpenAI(result);
|
|
854
965
|
await sendEventToPosthog({
|
|
855
966
|
client: this.phClient,
|
|
856
967
|
...posthogParams,
|
|
857
968
|
model: openAIParams.model,
|
|
858
969
|
provider: 'openai',
|
|
859
970
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
860
|
-
output:
|
|
971
|
+
output: formattedOutput,
|
|
861
972
|
latency,
|
|
862
973
|
baseURL: this.baseURL,
|
|
863
974
|
params: body,
|
|
@@ -866,7 +977,8 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
866
977
|
inputTokens: result.usage?.prompt_tokens ?? 0,
|
|
867
978
|
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
868
979
|
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
869
|
-
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
980
|
+
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0,
|
|
981
|
+
webSearchCount: calculateWebSearchCount(result)
|
|
870
982
|
},
|
|
871
983
|
tools: availableTools
|
|
872
984
|
});
|
|
@@ -921,14 +1033,22 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
921
1033
|
let finalContent = [];
|
|
922
1034
|
let usage = {
|
|
923
1035
|
inputTokens: 0,
|
|
924
|
-
outputTokens: 0
|
|
1036
|
+
outputTokens: 0,
|
|
1037
|
+
webSearchCount: 0
|
|
925
1038
|
};
|
|
926
1039
|
for await (const chunk of stream1) {
|
|
1040
|
+
if ('response' in chunk && chunk.response) {
|
|
1041
|
+
const chunkWebSearchCount = calculateWebSearchCount(chunk.response);
|
|
1042
|
+
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
1043
|
+
usage.webSearchCount = chunkWebSearchCount;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
927
1046
|
if (chunk.type === 'response.completed' && 'response' in chunk && chunk.response?.output && chunk.response.output.length > 0) {
|
|
928
1047
|
finalContent = chunk.response.output;
|
|
929
1048
|
}
|
|
930
1049
|
if ('response' in chunk && chunk.response?.usage) {
|
|
931
1050
|
usage = {
|
|
1051
|
+
...usage,
|
|
932
1052
|
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
933
1053
|
outputTokens: chunk.response.usage.output_tokens ?? 0,
|
|
934
1054
|
reasoningTokens: chunk.response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
@@ -950,7 +1070,13 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
950
1070
|
baseURL: this.baseURL,
|
|
951
1071
|
params: body,
|
|
952
1072
|
httpStatus: 200,
|
|
953
|
-
usage
|
|
1073
|
+
usage: {
|
|
1074
|
+
inputTokens: usage.inputTokens,
|
|
1075
|
+
outputTokens: usage.outputTokens,
|
|
1076
|
+
reasoningTokens: usage.reasoningTokens,
|
|
1077
|
+
cacheReadInputTokens: usage.cacheReadInputTokens,
|
|
1078
|
+
webSearchCount: usage.webSearchCount
|
|
1079
|
+
},
|
|
954
1080
|
tools: availableTools
|
|
955
1081
|
});
|
|
956
1082
|
} catch (error) {
|
|
@@ -985,6 +1111,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
985
1111
|
if ('output' in result) {
|
|
986
1112
|
const latency = (Date.now() - startTime) / 1000;
|
|
987
1113
|
const availableTools = extractAvailableToolCalls('openai', openAIParams);
|
|
1114
|
+
const formattedOutput = formatResponseOpenAI({
|
|
1115
|
+
output: result.output
|
|
1116
|
+
});
|
|
988
1117
|
await sendEventToPosthog({
|
|
989
1118
|
client: this.phClient,
|
|
990
1119
|
...posthogParams,
|
|
@@ -992,9 +1121,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
992
1121
|
model: openAIParams.model,
|
|
993
1122
|
provider: 'openai',
|
|
994
1123
|
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
995
|
-
output:
|
|
996
|
-
output: result.output
|
|
997
|
-
}),
|
|
1124
|
+
output: formattedOutput,
|
|
998
1125
|
latency,
|
|
999
1126
|
baseURL: this.baseURL,
|
|
1000
1127
|
params: body,
|
|
@@ -1003,7 +1130,8 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1003
1130
|
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1004
1131
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1005
1132
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1006
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1133
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1134
|
+
webSearchCount: calculateWebSearchCount(result)
|
|
1007
1135
|
},
|
|
1008
1136
|
tools: availableTools
|
|
1009
1137
|
});
|
|
@@ -1041,9 +1169,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1041
1169
|
} = extractPosthogParams(body);
|
|
1042
1170
|
const startTime = Date.now();
|
|
1043
1171
|
const originalCreate = super.create.bind(this);
|
|
1044
|
-
const
|
|
1045
|
-
const tempCreate =
|
|
1046
|
-
|
|
1172
|
+
const originalSelfRecord = this;
|
|
1173
|
+
const tempCreate = originalSelfRecord['create'];
|
|
1174
|
+
originalSelfRecord['create'] = originalCreate;
|
|
1047
1175
|
try {
|
|
1048
1176
|
const parentPromise = super.parse(openAIParams, options);
|
|
1049
1177
|
const wrappedPromise = parentPromise.then(async result => {
|
|
@@ -1092,7 +1220,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1092
1220
|
return wrappedPromise;
|
|
1093
1221
|
} finally {
|
|
1094
1222
|
// Restore our wrapped create method
|
|
1095
|
-
|
|
1223
|
+
originalSelfRecord['create'] = tempCreate;
|
|
1096
1224
|
}
|
|
1097
1225
|
}
|
|
1098
1226
|
};
|
|
@@ -1838,11 +1966,29 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
1838
1966
|
cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
|
|
1839
1967
|
} : {})
|
|
1840
1968
|
};
|
|
1969
|
+
// Calculate web search count based on provider
|
|
1970
|
+
let webSearchCount = 0;
|
|
1971
|
+
if (providerMetadata?.anthropic && typeof providerMetadata.anthropic === 'object' && 'server_tool_use' in providerMetadata.anthropic) {
|
|
1972
|
+
// Anthropic-specific extraction
|
|
1973
|
+
const serverToolUse = providerMetadata.anthropic.server_tool_use;
|
|
1974
|
+
if (serverToolUse && typeof serverToolUse === 'object' && 'web_search_requests' in serverToolUse && typeof serverToolUse.web_search_requests === 'number') {
|
|
1975
|
+
webSearchCount = serverToolUse.web_search_requests;
|
|
1976
|
+
}
|
|
1977
|
+
} else {
|
|
1978
|
+
// For other providers through Vercel, pass available metadata to helper
|
|
1979
|
+
// Note: Vercel abstracts provider responses, so we may not have access to
|
|
1980
|
+
// raw citations/annotations unless Vercel exposes them in usage/metadata
|
|
1981
|
+
webSearchCount = calculateWebSearchCount({
|
|
1982
|
+
usage: result.usage,
|
|
1983
|
+
providerMetadata: providerMetadata
|
|
1984
|
+
});
|
|
1985
|
+
}
|
|
1841
1986
|
const usage = {
|
|
1842
1987
|
inputTokens: result.usage.inputTokens,
|
|
1843
1988
|
outputTokens: result.usage.outputTokens,
|
|
1844
1989
|
reasoningTokens: result.usage.reasoningTokens,
|
|
1845
1990
|
cacheReadInputTokens: result.usage.cachedInputTokens,
|
|
1991
|
+
webSearchCount,
|
|
1846
1992
|
...additionalTokenValues
|
|
1847
1993
|
};
|
|
1848
1994
|
await sendEventToPosthog({
|
|
@@ -1896,6 +2042,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
1896
2042
|
let generatedText = '';
|
|
1897
2043
|
let reasoningText = '';
|
|
1898
2044
|
let usage = {};
|
|
2045
|
+
let providerMetadata = undefined;
|
|
1899
2046
|
const mergedParams = {
|
|
1900
2047
|
...options,
|
|
1901
2048
|
...mapVercelParams(params),
|
|
@@ -1953,12 +2100,10 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
1953
2100
|
});
|
|
1954
2101
|
}
|
|
1955
2102
|
if (chunk.type === 'finish') {
|
|
1956
|
-
|
|
1957
|
-
const additionalTokenValues = {
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
} : {})
|
|
1961
|
-
};
|
|
2103
|
+
providerMetadata = chunk.providerMetadata;
|
|
2104
|
+
const additionalTokenValues = providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'cacheCreationInputTokens' in providerMetadata.anthropic ? {
|
|
2105
|
+
cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
|
|
2106
|
+
} : {};
|
|
1962
2107
|
usage = {
|
|
1963
2108
|
inputTokens: chunk.usage?.inputTokens,
|
|
1964
2109
|
outputTokens: chunk.usage?.outputTokens,
|
|
@@ -2003,6 +2148,28 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
2003
2148
|
role: 'assistant',
|
|
2004
2149
|
content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
|
|
2005
2150
|
}] : [];
|
|
2151
|
+
// Calculate web search count based on provider
|
|
2152
|
+
let webSearchCount = 0;
|
|
2153
|
+
if (providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'server_tool_use' in providerMetadata.anthropic) {
|
|
2154
|
+
// Anthropic-specific extraction
|
|
2155
|
+
const serverToolUse = providerMetadata.anthropic.server_tool_use;
|
|
2156
|
+
if (serverToolUse && typeof serverToolUse === 'object' && 'web_search_requests' in serverToolUse && typeof serverToolUse.web_search_requests === 'number') {
|
|
2157
|
+
webSearchCount = serverToolUse.web_search_requests;
|
|
2158
|
+
}
|
|
2159
|
+
} else {
|
|
2160
|
+
// For other providers through Vercel, pass available metadata to helper
|
|
2161
|
+
// Note: Vercel abstracts provider responses, so we may not have access to
|
|
2162
|
+
// raw citations/annotations unless Vercel exposes them in usage/metadata
|
|
2163
|
+
webSearchCount = calculateWebSearchCount({
|
|
2164
|
+
usage: usage,
|
|
2165
|
+
providerMetadata: providerMetadata
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2168
|
+
// Update usage with web search count
|
|
2169
|
+
const finalUsage = {
|
|
2170
|
+
...usage,
|
|
2171
|
+
webSearchCount
|
|
2172
|
+
};
|
|
2006
2173
|
await sendEventToPosthog({
|
|
2007
2174
|
client: phClient,
|
|
2008
2175
|
distinctId: options.posthogDistinctId,
|
|
@@ -2015,7 +2182,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
2015
2182
|
baseURL,
|
|
2016
2183
|
params: mergedParams,
|
|
2017
2184
|
httpStatus: 200,
|
|
2018
|
-
usage,
|
|
2185
|
+
usage: finalUsage,
|
|
2019
2186
|
tools: availableTools,
|
|
2020
2187
|
captureImmediate: options.posthogCaptureImmediate
|
|
2021
2188
|
});
|
|
@@ -2101,7 +2268,8 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2101
2268
|
inputTokens: 0,
|
|
2102
2269
|
outputTokens: 0,
|
|
2103
2270
|
cacheCreationInputTokens: 0,
|
|
2104
|
-
cacheReadInputTokens: 0
|
|
2271
|
+
cacheReadInputTokens: 0,
|
|
2272
|
+
webSearchCount: 0
|
|
2105
2273
|
};
|
|
2106
2274
|
if ('tee' in value) {
|
|
2107
2275
|
const [stream1, stream2] = value.tee();
|
|
@@ -2178,9 +2346,14 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2178
2346
|
usage.inputTokens = chunk.message.usage.input_tokens ?? 0;
|
|
2179
2347
|
usage.cacheCreationInputTokens = chunk.message.usage.cache_creation_input_tokens ?? 0;
|
|
2180
2348
|
usage.cacheReadInputTokens = chunk.message.usage.cache_read_input_tokens ?? 0;
|
|
2349
|
+
usage.webSearchCount = chunk.message.usage.server_tool_use?.web_search_requests ?? 0;
|
|
2181
2350
|
}
|
|
2182
2351
|
if ('usage' in chunk) {
|
|
2183
2352
|
usage.outputTokens = chunk.usage.output_tokens ?? 0;
|
|
2353
|
+
// Update web search count if present in delta
|
|
2354
|
+
if (chunk.usage.server_tool_use?.web_search_requests !== undefined) {
|
|
2355
|
+
usage.webSearchCount = chunk.usage.server_tool_use.web_search_requests;
|
|
2356
|
+
}
|
|
2184
2357
|
}
|
|
2185
2358
|
}
|
|
2186
2359
|
const latency = (Date.now() - startTime) / 1000;
|
|
@@ -2257,7 +2430,8 @@ class WrappedMessages extends AnthropicOriginal.Messages {
|
|
|
2257
2430
|
inputTokens: result.usage.input_tokens ?? 0,
|
|
2258
2431
|
outputTokens: result.usage.output_tokens ?? 0,
|
|
2259
2432
|
cacheCreationInputTokens: result.usage.cache_creation_input_tokens ?? 0,
|
|
2260
|
-
cacheReadInputTokens: result.usage.cache_read_input_tokens ?? 0
|
|
2433
|
+
cacheReadInputTokens: result.usage.cache_read_input_tokens ?? 0,
|
|
2434
|
+
webSearchCount: result.usage.server_tool_use?.web_search_requests ?? 0
|
|
2261
2435
|
},
|
|
2262
2436
|
tools: availableTools
|
|
2263
2437
|
});
|
|
@@ -2331,7 +2505,8 @@ class WrappedModels {
|
|
|
2331
2505
|
inputTokens: metadata?.promptTokenCount ?? 0,
|
|
2332
2506
|
outputTokens: metadata?.candidatesTokenCount ?? 0,
|
|
2333
2507
|
reasoningTokens: metadata?.thoughtsTokenCount ?? 0,
|
|
2334
|
-
cacheReadInputTokens: metadata?.cachedContentTokenCount ?? 0
|
|
2508
|
+
cacheReadInputTokens: metadata?.cachedContentTokenCount ?? 0,
|
|
2509
|
+
webSearchCount: calculateGoogleWebSearchCount(response)
|
|
2335
2510
|
},
|
|
2336
2511
|
tools: availableTools
|
|
2337
2512
|
});
|
|
@@ -2368,11 +2543,16 @@ class WrappedModels {
|
|
|
2368
2543
|
const accumulatedContent = [];
|
|
2369
2544
|
let usage = {
|
|
2370
2545
|
inputTokens: 0,
|
|
2371
|
-
outputTokens: 0
|
|
2546
|
+
outputTokens: 0,
|
|
2547
|
+
webSearchCount: 0
|
|
2372
2548
|
};
|
|
2373
2549
|
try {
|
|
2374
2550
|
const stream = await this.client.models.generateContentStream(geminiParams);
|
|
2375
2551
|
for await (const chunk of stream) {
|
|
2552
|
+
const chunkWebSearchCount = calculateGoogleWebSearchCount(chunk);
|
|
2553
|
+
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2554
|
+
usage.webSearchCount = chunkWebSearchCount;
|
|
2555
|
+
}
|
|
2376
2556
|
// Handle text content
|
|
2377
2557
|
if (chunk.text) {
|
|
2378
2558
|
// Find if we already have a text item to append to
|
|
@@ -2421,7 +2601,8 @@ class WrappedModels {
|
|
|
2421
2601
|
inputTokens: metadata.promptTokenCount ?? 0,
|
|
2422
2602
|
outputTokens: metadata.candidatesTokenCount ?? 0,
|
|
2423
2603
|
reasoningTokens: metadata.thoughtsTokenCount ?? 0,
|
|
2424
|
-
cacheReadInputTokens: metadata.cachedContentTokenCount ?? 0
|
|
2604
|
+
cacheReadInputTokens: metadata.cachedContentTokenCount ?? 0,
|
|
2605
|
+
webSearchCount: usage.webSearchCount
|
|
2425
2606
|
};
|
|
2426
2607
|
}
|
|
2427
2608
|
yield chunk;
|
|
@@ -2444,7 +2625,10 @@ class WrappedModels {
|
|
|
2444
2625
|
baseURL: 'https://generativelanguage.googleapis.com',
|
|
2445
2626
|
params: params,
|
|
2446
2627
|
httpStatus: 200,
|
|
2447
|
-
usage
|
|
2628
|
+
usage: {
|
|
2629
|
+
...usage,
|
|
2630
|
+
webSearchCount: usage.webSearchCount
|
|
2631
|
+
},
|
|
2448
2632
|
tools: availableTools
|
|
2449
2633
|
});
|
|
2450
2634
|
} catch (error) {
|
|
@@ -2587,6 +2771,66 @@ class WrappedModels {
|
|
|
2587
2771
|
return messages;
|
|
2588
2772
|
}
|
|
2589
2773
|
}
|
|
2774
|
+
/**
|
|
2775
|
+
* Detect if Google Search grounding was used in the response.
|
|
2776
|
+
* Gemini bills per request that uses grounding, not per individual query.
|
|
2777
|
+
* Returns 1 if grounding was used, 0 otherwise.
|
|
2778
|
+
*/
|
|
2779
|
+
function calculateGoogleWebSearchCount(response) {
|
|
2780
|
+
if (!response || typeof response !== 'object' || !('candidates' in response)) {
|
|
2781
|
+
return 0;
|
|
2782
|
+
}
|
|
2783
|
+
const candidates = response.candidates;
|
|
2784
|
+
if (!Array.isArray(candidates)) {
|
|
2785
|
+
return 0;
|
|
2786
|
+
}
|
|
2787
|
+
const hasGrounding = candidates.some(candidate => {
|
|
2788
|
+
if (!candidate || typeof candidate !== 'object') {
|
|
2789
|
+
return false;
|
|
2790
|
+
}
|
|
2791
|
+
// Check for grounding metadata
|
|
2792
|
+
if ('groundingMetadata' in candidate && candidate.groundingMetadata) {
|
|
2793
|
+
const metadata = candidate.groundingMetadata;
|
|
2794
|
+
if (typeof metadata === 'object') {
|
|
2795
|
+
// Check if web_search_queries exists and is non-empty
|
|
2796
|
+
if ('webSearchQueries' in metadata && Array.isArray(metadata.webSearchQueries) && metadata.webSearchQueries.length > 0) {
|
|
2797
|
+
return true;
|
|
2798
|
+
}
|
|
2799
|
+
// Check if grounding_chunks exists and is non-empty
|
|
2800
|
+
if ('groundingChunks' in metadata && Array.isArray(metadata.groundingChunks) && metadata.groundingChunks.length > 0) {
|
|
2801
|
+
return true;
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
// Check for google search in function calls
|
|
2806
|
+
if ('content' in candidate && candidate.content && typeof candidate.content === 'object') {
|
|
2807
|
+
const content = candidate.content;
|
|
2808
|
+
if ('parts' in content && Array.isArray(content.parts)) {
|
|
2809
|
+
return content.parts.some(part => {
|
|
2810
|
+
if (!part || typeof part !== 'object' || !('functionCall' in part)) {
|
|
2811
|
+
return false;
|
|
2812
|
+
}
|
|
2813
|
+
const functionCall = part.functionCall;
|
|
2814
|
+
if (functionCall && typeof functionCall === 'object' && 'name' in functionCall && typeof functionCall.name === 'string') {
|
|
2815
|
+
return functionCall.name.includes('google_search') || functionCall.name.includes('grounding');
|
|
2816
|
+
}
|
|
2817
|
+
return false;
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
return false;
|
|
2822
|
+
});
|
|
2823
|
+
return hasGrounding ? 1 : 0;
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
//#region rolldown:runtime
|
|
2827
|
+
var __defProp = Object.defineProperty;
|
|
2828
|
+
var __export = (target, all) => {
|
|
2829
|
+
for (var name in all) __defProp(target, name, {
|
|
2830
|
+
get: all[name],
|
|
2831
|
+
enumerable: true
|
|
2832
|
+
});
|
|
2833
|
+
};
|
|
2590
2834
|
|
|
2591
2835
|
function getDefaultExportFromCjs (x) {
|
|
2592
2836
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -2740,370 +2984,304 @@ function requireCamelcase () {
|
|
|
2740
2984
|
|
|
2741
2985
|
requireCamelcase();
|
|
2742
2986
|
|
|
2987
|
+
//#region src/load/map_keys.ts
|
|
2743
2988
|
function keyToJson(key, map) {
|
|
2744
|
-
|
|
2989
|
+
return map?.[key] || snakeCase(key);
|
|
2745
2990
|
}
|
|
2746
2991
|
function mapKeys(fields, mapper, map) {
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
mapped[mapper(key, map)] = fields[key];
|
|
2751
|
-
}
|
|
2752
|
-
}
|
|
2753
|
-
return mapped;
|
|
2992
|
+
const mapped = {};
|
|
2993
|
+
for (const key in fields) if (Object.hasOwn(fields, key)) mapped[mapper(key, map)] = fields[key];
|
|
2994
|
+
return mapped;
|
|
2754
2995
|
}
|
|
2755
2996
|
|
|
2997
|
+
//#region src/load/serializable.ts
|
|
2998
|
+
var serializable_exports = {};
|
|
2999
|
+
__export(serializable_exports, {
|
|
3000
|
+
Serializable: () => Serializable,
|
|
3001
|
+
get_lc_unique_name: () => get_lc_unique_name
|
|
3002
|
+
});
|
|
2756
3003
|
function shallowCopy(obj) {
|
|
2757
|
-
|
|
3004
|
+
return Array.isArray(obj) ? [...obj] : { ...obj };
|
|
2758
3005
|
}
|
|
2759
3006
|
function replaceSecrets(root, secretsMap) {
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
id: [secretId],
|
|
2777
|
-
};
|
|
2778
|
-
}
|
|
2779
|
-
}
|
|
2780
|
-
return result;
|
|
3007
|
+
const result = shallowCopy(root);
|
|
3008
|
+
for (const [path, secretId] of Object.entries(secretsMap)) {
|
|
3009
|
+
const [last, ...partsReverse] = path.split(".").reverse();
|
|
3010
|
+
let current = result;
|
|
3011
|
+
for (const part of partsReverse.reverse()) {
|
|
3012
|
+
if (current[part] === void 0) break;
|
|
3013
|
+
current[part] = shallowCopy(current[part]);
|
|
3014
|
+
current = current[part];
|
|
3015
|
+
}
|
|
3016
|
+
if (current[last] !== void 0) current[last] = {
|
|
3017
|
+
lc: 1,
|
|
3018
|
+
type: "secret",
|
|
3019
|
+
id: [secretId]
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
3022
|
+
return result;
|
|
2781
3023
|
}
|
|
2782
3024
|
/**
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
function get_lc_unique_name(
|
|
2787
|
-
|
|
2788
|
-
serializableClass)
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
const parentClass = Object.getPrototypeOf(serializableClass);
|
|
2792
|
-
const lcNameIsSubclassed = typeof serializableClass.lc_name === "function" &&
|
|
2793
|
-
(typeof parentClass.lc_name !== "function" ||
|
|
2794
|
-
serializableClass.lc_name() !== parentClass.lc_name());
|
|
2795
|
-
if (lcNameIsSubclassed) {
|
|
2796
|
-
return serializableClass.lc_name();
|
|
2797
|
-
}
|
|
2798
|
-
else {
|
|
2799
|
-
return serializableClass.name;
|
|
2800
|
-
}
|
|
2801
|
-
}
|
|
2802
|
-
class Serializable {
|
|
2803
|
-
/**
|
|
2804
|
-
* The name of the serializable. Override to provide an alias or
|
|
2805
|
-
* to preserve the serialized module name in minified environments.
|
|
2806
|
-
*
|
|
2807
|
-
* Implemented as a static method to support loading logic.
|
|
2808
|
-
*/
|
|
2809
|
-
static lc_name() {
|
|
2810
|
-
return this.name;
|
|
2811
|
-
}
|
|
2812
|
-
/**
|
|
2813
|
-
* The final serialized identifier for the module.
|
|
2814
|
-
*/
|
|
2815
|
-
get lc_id() {
|
|
2816
|
-
return [
|
|
2817
|
-
...this.lc_namespace,
|
|
2818
|
-
get_lc_unique_name(this.constructor),
|
|
2819
|
-
];
|
|
2820
|
-
}
|
|
2821
|
-
/**
|
|
2822
|
-
* A map of secrets, which will be omitted from serialization.
|
|
2823
|
-
* Keys are paths to the secret in constructor args, e.g. "foo.bar.baz".
|
|
2824
|
-
* Values are the secret ids, which will be used when deserializing.
|
|
2825
|
-
*/
|
|
2826
|
-
get lc_secrets() {
|
|
2827
|
-
return undefined;
|
|
2828
|
-
}
|
|
2829
|
-
/**
|
|
2830
|
-
* A map of additional attributes to merge with constructor args.
|
|
2831
|
-
* Keys are the attribute names, e.g. "foo".
|
|
2832
|
-
* Values are the attribute values, which will be serialized.
|
|
2833
|
-
* These attributes need to be accepted by the constructor as arguments.
|
|
2834
|
-
*/
|
|
2835
|
-
get lc_attributes() {
|
|
2836
|
-
return undefined;
|
|
2837
|
-
}
|
|
2838
|
-
/**
|
|
2839
|
-
* A map of aliases for constructor args.
|
|
2840
|
-
* Keys are the attribute names, e.g. "foo".
|
|
2841
|
-
* Values are the alias that will replace the key in serialization.
|
|
2842
|
-
* This is used to eg. make argument names match Python.
|
|
2843
|
-
*/
|
|
2844
|
-
get lc_aliases() {
|
|
2845
|
-
return undefined;
|
|
2846
|
-
}
|
|
2847
|
-
/**
|
|
2848
|
-
* A manual list of keys that should be serialized.
|
|
2849
|
-
* If not overridden, all fields passed into the constructor will be serialized.
|
|
2850
|
-
*/
|
|
2851
|
-
get lc_serializable_keys() {
|
|
2852
|
-
return undefined;
|
|
2853
|
-
}
|
|
2854
|
-
constructor(kwargs, ..._args) {
|
|
2855
|
-
Object.defineProperty(this, "lc_serializable", {
|
|
2856
|
-
enumerable: true,
|
|
2857
|
-
configurable: true,
|
|
2858
|
-
writable: true,
|
|
2859
|
-
value: false
|
|
2860
|
-
});
|
|
2861
|
-
Object.defineProperty(this, "lc_kwargs", {
|
|
2862
|
-
enumerable: true,
|
|
2863
|
-
configurable: true,
|
|
2864
|
-
writable: true,
|
|
2865
|
-
value: void 0
|
|
2866
|
-
});
|
|
2867
|
-
if (this.lc_serializable_keys !== undefined) {
|
|
2868
|
-
this.lc_kwargs = Object.fromEntries(Object.entries(kwargs || {}).filter(([key]) => this.lc_serializable_keys?.includes(key)));
|
|
2869
|
-
}
|
|
2870
|
-
else {
|
|
2871
|
-
this.lc_kwargs = kwargs ?? {};
|
|
2872
|
-
}
|
|
2873
|
-
}
|
|
2874
|
-
toJSON() {
|
|
2875
|
-
if (!this.lc_serializable) {
|
|
2876
|
-
return this.toJSONNotImplemented();
|
|
2877
|
-
}
|
|
2878
|
-
if (
|
|
2879
|
-
// eslint-disable-next-line no-instanceof/no-instanceof
|
|
2880
|
-
this.lc_kwargs instanceof Serializable ||
|
|
2881
|
-
typeof this.lc_kwargs !== "object" ||
|
|
2882
|
-
Array.isArray(this.lc_kwargs)) {
|
|
2883
|
-
// We do not support serialization of classes with arg not a POJO
|
|
2884
|
-
// I'm aware the check above isn't as strict as it could be
|
|
2885
|
-
return this.toJSONNotImplemented();
|
|
2886
|
-
}
|
|
2887
|
-
const aliases = {};
|
|
2888
|
-
const secrets = {};
|
|
2889
|
-
const kwargs = Object.keys(this.lc_kwargs).reduce((acc, key) => {
|
|
2890
|
-
acc[key] = key in this ? this[key] : this.lc_kwargs[key];
|
|
2891
|
-
return acc;
|
|
2892
|
-
}, {});
|
|
2893
|
-
// get secrets, attributes and aliases from all superclasses
|
|
2894
|
-
for (
|
|
2895
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
2896
|
-
let current = Object.getPrototypeOf(this); current; current = Object.getPrototypeOf(current)) {
|
|
2897
|
-
Object.assign(aliases, Reflect.get(current, "lc_aliases", this));
|
|
2898
|
-
Object.assign(secrets, Reflect.get(current, "lc_secrets", this));
|
|
2899
|
-
Object.assign(kwargs, Reflect.get(current, "lc_attributes", this));
|
|
2900
|
-
}
|
|
2901
|
-
// include all secrets used, even if not in kwargs,
|
|
2902
|
-
// will be replaced with sentinel value in replaceSecrets
|
|
2903
|
-
Object.keys(secrets).forEach((keyPath) => {
|
|
2904
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias, @typescript-eslint/no-explicit-any
|
|
2905
|
-
let read = this;
|
|
2906
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2907
|
-
let write = kwargs;
|
|
2908
|
-
const [last, ...partsReverse] = keyPath.split(".").reverse();
|
|
2909
|
-
for (const key of partsReverse.reverse()) {
|
|
2910
|
-
if (!(key in read) || read[key] === undefined)
|
|
2911
|
-
return;
|
|
2912
|
-
if (!(key in write) || write[key] === undefined) {
|
|
2913
|
-
if (typeof read[key] === "object" && read[key] != null) {
|
|
2914
|
-
write[key] = {};
|
|
2915
|
-
}
|
|
2916
|
-
else if (Array.isArray(read[key])) {
|
|
2917
|
-
write[key] = [];
|
|
2918
|
-
}
|
|
2919
|
-
}
|
|
2920
|
-
read = read[key];
|
|
2921
|
-
write = write[key];
|
|
2922
|
-
}
|
|
2923
|
-
if (last in read && read[last] !== undefined) {
|
|
2924
|
-
write[last] = write[last] || read[last];
|
|
2925
|
-
}
|
|
2926
|
-
});
|
|
2927
|
-
return {
|
|
2928
|
-
lc: 1,
|
|
2929
|
-
type: "constructor",
|
|
2930
|
-
id: this.lc_id,
|
|
2931
|
-
kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases),
|
|
2932
|
-
};
|
|
2933
|
-
}
|
|
2934
|
-
toJSONNotImplemented() {
|
|
2935
|
-
return {
|
|
2936
|
-
lc: 1,
|
|
2937
|
-
type: "not_implemented",
|
|
2938
|
-
id: this.lc_id,
|
|
2939
|
-
};
|
|
2940
|
-
}
|
|
3025
|
+
* Get a unique name for the module, rather than parent class implementations.
|
|
3026
|
+
* Should not be subclassed, subclass lc_name above instead.
|
|
3027
|
+
*/
|
|
3028
|
+
function get_lc_unique_name(serializableClass) {
|
|
3029
|
+
const parentClass = Object.getPrototypeOf(serializableClass);
|
|
3030
|
+
const lcNameIsSubclassed = typeof serializableClass.lc_name === "function" && (typeof parentClass.lc_name !== "function" || serializableClass.lc_name() !== parentClass.lc_name());
|
|
3031
|
+
if (lcNameIsSubclassed) return serializableClass.lc_name();
|
|
3032
|
+
else return serializableClass.name;
|
|
2941
3033
|
}
|
|
3034
|
+
var Serializable = class Serializable {
|
|
3035
|
+
lc_serializable = false;
|
|
3036
|
+
lc_kwargs;
|
|
3037
|
+
/**
|
|
3038
|
+
* The name of the serializable. Override to provide an alias or
|
|
3039
|
+
* to preserve the serialized module name in minified environments.
|
|
3040
|
+
*
|
|
3041
|
+
* Implemented as a static method to support loading logic.
|
|
3042
|
+
*/
|
|
3043
|
+
static lc_name() {
|
|
3044
|
+
return this.name;
|
|
3045
|
+
}
|
|
3046
|
+
/**
|
|
3047
|
+
* The final serialized identifier for the module.
|
|
3048
|
+
*/
|
|
3049
|
+
get lc_id() {
|
|
3050
|
+
return [...this.lc_namespace, get_lc_unique_name(this.constructor)];
|
|
3051
|
+
}
|
|
3052
|
+
/**
|
|
3053
|
+
* A map of secrets, which will be omitted from serialization.
|
|
3054
|
+
* Keys are paths to the secret in constructor args, e.g. "foo.bar.baz".
|
|
3055
|
+
* Values are the secret ids, which will be used when deserializing.
|
|
3056
|
+
*/
|
|
3057
|
+
get lc_secrets() {
|
|
3058
|
+
return void 0;
|
|
3059
|
+
}
|
|
3060
|
+
/**
|
|
3061
|
+
* A map of additional attributes to merge with constructor args.
|
|
3062
|
+
* Keys are the attribute names, e.g. "foo".
|
|
3063
|
+
* Values are the attribute values, which will be serialized.
|
|
3064
|
+
* These attributes need to be accepted by the constructor as arguments.
|
|
3065
|
+
*/
|
|
3066
|
+
get lc_attributes() {
|
|
3067
|
+
return void 0;
|
|
3068
|
+
}
|
|
3069
|
+
/**
|
|
3070
|
+
* A map of aliases for constructor args.
|
|
3071
|
+
* Keys are the attribute names, e.g. "foo".
|
|
3072
|
+
* Values are the alias that will replace the key in serialization.
|
|
3073
|
+
* This is used to eg. make argument names match Python.
|
|
3074
|
+
*/
|
|
3075
|
+
get lc_aliases() {
|
|
3076
|
+
return void 0;
|
|
3077
|
+
}
|
|
3078
|
+
/**
|
|
3079
|
+
* A manual list of keys that should be serialized.
|
|
3080
|
+
* If not overridden, all fields passed into the constructor will be serialized.
|
|
3081
|
+
*/
|
|
3082
|
+
get lc_serializable_keys() {
|
|
3083
|
+
return void 0;
|
|
3084
|
+
}
|
|
3085
|
+
constructor(kwargs, ..._args) {
|
|
3086
|
+
if (this.lc_serializable_keys !== void 0) this.lc_kwargs = Object.fromEntries(Object.entries(kwargs || {}).filter(([key]) => this.lc_serializable_keys?.includes(key)));
|
|
3087
|
+
else this.lc_kwargs = kwargs ?? {};
|
|
3088
|
+
}
|
|
3089
|
+
toJSON() {
|
|
3090
|
+
if (!this.lc_serializable) return this.toJSONNotImplemented();
|
|
3091
|
+
if (this.lc_kwargs instanceof Serializable || typeof this.lc_kwargs !== "object" || Array.isArray(this.lc_kwargs)) return this.toJSONNotImplemented();
|
|
3092
|
+
const aliases = {};
|
|
3093
|
+
const secrets = {};
|
|
3094
|
+
const kwargs = Object.keys(this.lc_kwargs).reduce((acc, key) => {
|
|
3095
|
+
acc[key] = key in this ? this[key] : this.lc_kwargs[key];
|
|
3096
|
+
return acc;
|
|
3097
|
+
}, {});
|
|
3098
|
+
for (let current = Object.getPrototypeOf(this); current; current = Object.getPrototypeOf(current)) {
|
|
3099
|
+
Object.assign(aliases, Reflect.get(current, "lc_aliases", this));
|
|
3100
|
+
Object.assign(secrets, Reflect.get(current, "lc_secrets", this));
|
|
3101
|
+
Object.assign(kwargs, Reflect.get(current, "lc_attributes", this));
|
|
3102
|
+
}
|
|
3103
|
+
Object.keys(secrets).forEach((keyPath) => {
|
|
3104
|
+
let read = this;
|
|
3105
|
+
let write = kwargs;
|
|
3106
|
+
const [last, ...partsReverse] = keyPath.split(".").reverse();
|
|
3107
|
+
for (const key of partsReverse.reverse()) {
|
|
3108
|
+
if (!(key in read) || read[key] === void 0) return;
|
|
3109
|
+
if (!(key in write) || write[key] === void 0) {
|
|
3110
|
+
if (typeof read[key] === "object" && read[key] != null) write[key] = {};
|
|
3111
|
+
else if (Array.isArray(read[key])) write[key] = [];
|
|
3112
|
+
}
|
|
3113
|
+
read = read[key];
|
|
3114
|
+
write = write[key];
|
|
3115
|
+
}
|
|
3116
|
+
if (last in read && read[last] !== void 0) write[last] = write[last] || read[last];
|
|
3117
|
+
});
|
|
3118
|
+
return {
|
|
3119
|
+
lc: 1,
|
|
3120
|
+
type: "constructor",
|
|
3121
|
+
id: this.lc_id,
|
|
3122
|
+
kwargs: mapKeys(Object.keys(secrets).length ? replaceSecrets(kwargs, secrets) : kwargs, keyToJson, aliases)
|
|
3123
|
+
};
|
|
3124
|
+
}
|
|
3125
|
+
toJSONNotImplemented() {
|
|
3126
|
+
return {
|
|
3127
|
+
lc: 1,
|
|
3128
|
+
type: "not_implemented",
|
|
3129
|
+
id: this.lc_id
|
|
3130
|
+
};
|
|
3131
|
+
}
|
|
3132
|
+
};
|
|
2942
3133
|
|
|
2943
|
-
|
|
2944
|
-
|
|
3134
|
+
//#region src/utils/env.ts
|
|
3135
|
+
var env_exports = {};
|
|
3136
|
+
__export(env_exports, {
|
|
3137
|
+
getEnv: () => getEnv,
|
|
3138
|
+
getEnvironmentVariable: () => getEnvironmentVariable,
|
|
3139
|
+
getRuntimeEnvironment: () => getRuntimeEnvironment,
|
|
3140
|
+
isBrowser: () => isBrowser,
|
|
3141
|
+
isDeno: () => isDeno,
|
|
3142
|
+
isJsDom: () => isJsDom,
|
|
3143
|
+
isNode: () => isNode,
|
|
3144
|
+
isWebWorker: () => isWebWorker
|
|
3145
|
+
});
|
|
3146
|
+
const isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
3147
|
+
const isWebWorker = () => typeof globalThis === "object" && globalThis.constructor && globalThis.constructor.name === "DedicatedWorkerGlobalScope";
|
|
3148
|
+
const isJsDom = () => typeof window !== "undefined" && window.name === "nodejs" || typeof navigator !== "undefined" && navigator.userAgent.includes("jsdom");
|
|
2945
3149
|
const isDeno = () => typeof Deno !== "undefined";
|
|
3150
|
+
const isNode = () => typeof process !== "undefined" && typeof process.versions !== "undefined" && typeof process.versions.node !== "undefined" && !isDeno();
|
|
3151
|
+
const getEnv = () => {
|
|
3152
|
+
let env;
|
|
3153
|
+
if (isBrowser()) env = "browser";
|
|
3154
|
+
else if (isNode()) env = "node";
|
|
3155
|
+
else if (isWebWorker()) env = "webworker";
|
|
3156
|
+
else if (isJsDom()) env = "jsdom";
|
|
3157
|
+
else if (isDeno()) env = "deno";
|
|
3158
|
+
else env = "other";
|
|
3159
|
+
return env;
|
|
3160
|
+
};
|
|
3161
|
+
let runtimeEnvironment;
|
|
3162
|
+
function getRuntimeEnvironment() {
|
|
3163
|
+
if (runtimeEnvironment === void 0) {
|
|
3164
|
+
const env = getEnv();
|
|
3165
|
+
runtimeEnvironment = {
|
|
3166
|
+
library: "langchain-js",
|
|
3167
|
+
runtime: env
|
|
3168
|
+
};
|
|
3169
|
+
}
|
|
3170
|
+
return runtimeEnvironment;
|
|
3171
|
+
}
|
|
2946
3172
|
function getEnvironmentVariable(name) {
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
else if (isDeno()) {
|
|
2955
|
-
return Deno?.env.get(name);
|
|
2956
|
-
}
|
|
2957
|
-
else {
|
|
2958
|
-
return undefined;
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
2961
|
-
catch (e) {
|
|
2962
|
-
return undefined;
|
|
2963
|
-
}
|
|
3173
|
+
try {
|
|
3174
|
+
if (typeof process !== "undefined") return process.env?.[name];
|
|
3175
|
+
else if (isDeno()) return Deno?.env.get(name);
|
|
3176
|
+
else return void 0;
|
|
3177
|
+
} catch {
|
|
3178
|
+
return void 0;
|
|
3179
|
+
}
|
|
2964
3180
|
}
|
|
2965
3181
|
|
|
3182
|
+
//#region src/callbacks/base.ts
|
|
3183
|
+
var base_exports = {};
|
|
3184
|
+
__export(base_exports, {
|
|
3185
|
+
BaseCallbackHandler: () => BaseCallbackHandler,
|
|
3186
|
+
callbackHandlerPrefersStreaming: () => callbackHandlerPrefersStreaming,
|
|
3187
|
+
isBaseCallbackHandler: () => isBaseCallbackHandler
|
|
3188
|
+
});
|
|
2966
3189
|
/**
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
3190
|
+
* Abstract class that provides a set of optional methods that can be
|
|
3191
|
+
* overridden in derived classes to handle various events during the
|
|
3192
|
+
* execution of a LangChain application.
|
|
3193
|
+
*/
|
|
3194
|
+
var BaseCallbackHandlerMethodsClass = class {};
|
|
3195
|
+
function callbackHandlerPrefersStreaming(x) {
|
|
3196
|
+
return "lc_prefer_streaming" in x && x.lc_prefer_streaming;
|
|
2972
3197
|
}
|
|
2973
3198
|
/**
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
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
|
-
writable: true,
|
|
3061
|
-
value: false
|
|
3062
|
-
});
|
|
3063
|
-
Object.defineProperty(this, "awaitHandlers", {
|
|
3064
|
-
enumerable: true,
|
|
3065
|
-
configurable: true,
|
|
3066
|
-
writable: true,
|
|
3067
|
-
value: getEnvironmentVariable("LANGCHAIN_CALLBACKS_BACKGROUND") === "false"
|
|
3068
|
-
});
|
|
3069
|
-
this.lc_kwargs = input || {};
|
|
3070
|
-
if (input) {
|
|
3071
|
-
this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
|
|
3072
|
-
this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
|
|
3073
|
-
this.ignoreAgent = input.ignoreAgent ?? this.ignoreAgent;
|
|
3074
|
-
this.ignoreRetriever = input.ignoreRetriever ?? this.ignoreRetriever;
|
|
3075
|
-
this.ignoreCustomEvent =
|
|
3076
|
-
input.ignoreCustomEvent ?? this.ignoreCustomEvent;
|
|
3077
|
-
this.raiseError = input.raiseError ?? this.raiseError;
|
|
3078
|
-
this.awaitHandlers =
|
|
3079
|
-
this.raiseError || (input._awaitHandler ?? this.awaitHandlers);
|
|
3080
|
-
}
|
|
3081
|
-
}
|
|
3082
|
-
copy() {
|
|
3083
|
-
return new this.constructor(this);
|
|
3084
|
-
}
|
|
3085
|
-
toJSON() {
|
|
3086
|
-
return Serializable.prototype.toJSON.call(this);
|
|
3087
|
-
}
|
|
3088
|
-
toJSONNotImplemented() {
|
|
3089
|
-
return Serializable.prototype.toJSONNotImplemented.call(this);
|
|
3090
|
-
}
|
|
3091
|
-
static fromMethods(methods) {
|
|
3092
|
-
class Handler extends BaseCallbackHandler {
|
|
3093
|
-
constructor() {
|
|
3094
|
-
super();
|
|
3095
|
-
Object.defineProperty(this, "name", {
|
|
3096
|
-
enumerable: true,
|
|
3097
|
-
configurable: true,
|
|
3098
|
-
writable: true,
|
|
3099
|
-
value: uuid.v4()
|
|
3100
|
-
});
|
|
3101
|
-
Object.assign(this, methods);
|
|
3102
|
-
}
|
|
3103
|
-
}
|
|
3104
|
-
return new Handler();
|
|
3105
|
-
}
|
|
3106
|
-
}
|
|
3199
|
+
* Abstract base class for creating callback handlers in the LangChain
|
|
3200
|
+
* framework. It provides a set of optional methods that can be overridden
|
|
3201
|
+
* in derived classes to handle various events during the execution of a
|
|
3202
|
+
* LangChain application.
|
|
3203
|
+
*/
|
|
3204
|
+
var BaseCallbackHandler = class extends BaseCallbackHandlerMethodsClass {
|
|
3205
|
+
lc_serializable = false;
|
|
3206
|
+
get lc_namespace() {
|
|
3207
|
+
return [
|
|
3208
|
+
"langchain_core",
|
|
3209
|
+
"callbacks",
|
|
3210
|
+
this.name
|
|
3211
|
+
];
|
|
3212
|
+
}
|
|
3213
|
+
get lc_secrets() {
|
|
3214
|
+
return void 0;
|
|
3215
|
+
}
|
|
3216
|
+
get lc_attributes() {
|
|
3217
|
+
return void 0;
|
|
3218
|
+
}
|
|
3219
|
+
get lc_aliases() {
|
|
3220
|
+
return void 0;
|
|
3221
|
+
}
|
|
3222
|
+
get lc_serializable_keys() {
|
|
3223
|
+
return void 0;
|
|
3224
|
+
}
|
|
3225
|
+
/**
|
|
3226
|
+
* The name of the serializable. Override to provide an alias or
|
|
3227
|
+
* to preserve the serialized module name in minified environments.
|
|
3228
|
+
*
|
|
3229
|
+
* Implemented as a static method to support loading logic.
|
|
3230
|
+
*/
|
|
3231
|
+
static lc_name() {
|
|
3232
|
+
return this.name;
|
|
3233
|
+
}
|
|
3234
|
+
/**
|
|
3235
|
+
* The final serialized identifier for the module.
|
|
3236
|
+
*/
|
|
3237
|
+
get lc_id() {
|
|
3238
|
+
return [...this.lc_namespace, get_lc_unique_name(this.constructor)];
|
|
3239
|
+
}
|
|
3240
|
+
lc_kwargs;
|
|
3241
|
+
ignoreLLM = false;
|
|
3242
|
+
ignoreChain = false;
|
|
3243
|
+
ignoreAgent = false;
|
|
3244
|
+
ignoreRetriever = false;
|
|
3245
|
+
ignoreCustomEvent = false;
|
|
3246
|
+
raiseError = false;
|
|
3247
|
+
awaitHandlers = getEnvironmentVariable("LANGCHAIN_CALLBACKS_BACKGROUND") === "false";
|
|
3248
|
+
constructor(input) {
|
|
3249
|
+
super();
|
|
3250
|
+
this.lc_kwargs = input || {};
|
|
3251
|
+
if (input) {
|
|
3252
|
+
this.ignoreLLM = input.ignoreLLM ?? this.ignoreLLM;
|
|
3253
|
+
this.ignoreChain = input.ignoreChain ?? this.ignoreChain;
|
|
3254
|
+
this.ignoreAgent = input.ignoreAgent ?? this.ignoreAgent;
|
|
3255
|
+
this.ignoreRetriever = input.ignoreRetriever ?? this.ignoreRetriever;
|
|
3256
|
+
this.ignoreCustomEvent = input.ignoreCustomEvent ?? this.ignoreCustomEvent;
|
|
3257
|
+
this.raiseError = input.raiseError ?? this.raiseError;
|
|
3258
|
+
this.awaitHandlers = this.raiseError || (input._awaitHandler ?? this.awaitHandlers);
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
copy() {
|
|
3262
|
+
return new this.constructor(this);
|
|
3263
|
+
}
|
|
3264
|
+
toJSON() {
|
|
3265
|
+
return Serializable.prototype.toJSON.call(this);
|
|
3266
|
+
}
|
|
3267
|
+
toJSONNotImplemented() {
|
|
3268
|
+
return Serializable.prototype.toJSONNotImplemented.call(this);
|
|
3269
|
+
}
|
|
3270
|
+
static fromMethods(methods) {
|
|
3271
|
+
class Handler extends BaseCallbackHandler {
|
|
3272
|
+
name = uuid.v4();
|
|
3273
|
+
constructor() {
|
|
3274
|
+
super();
|
|
3275
|
+
Object.assign(this, methods);
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
return new Handler();
|
|
3279
|
+
}
|
|
3280
|
+
};
|
|
3281
|
+
const isBaseCallbackHandler = (x) => {
|
|
3282
|
+
const callbackHandler = x;
|
|
3283
|
+
return callbackHandler !== void 0 && typeof callbackHandler.copy === "function" && typeof callbackHandler.name === "string" && typeof callbackHandler.awaitHandlers === "boolean";
|
|
3284
|
+
};
|
|
3107
3285
|
|
|
3108
3286
|
class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
3109
3287
|
constructor(options) {
|
|
@@ -3407,6 +3585,9 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
|
3407
3585
|
if (additionalTokenData.reasoningTokens) {
|
|
3408
3586
|
eventProperties['$ai_reasoning_tokens'] = additionalTokenData.reasoningTokens;
|
|
3409
3587
|
}
|
|
3588
|
+
if (additionalTokenData.webSearchCount !== undefined) {
|
|
3589
|
+
eventProperties['$ai_web_search_count'] = additionalTokenData.webSearchCount;
|
|
3590
|
+
}
|
|
3410
3591
|
// Handle generations/completions
|
|
3411
3592
|
let completions;
|
|
3412
3593
|
if (output.generations && Array.isArray(output.generations)) {
|
|
@@ -3572,6 +3753,42 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
|
|
|
3572
3753
|
} else if (usage.reasoningTokens != null) {
|
|
3573
3754
|
additionalTokenData.reasoningTokens = usage.reasoningTokens;
|
|
3574
3755
|
}
|
|
3756
|
+
// Extract web search counts from various provider formats
|
|
3757
|
+
let webSearchCount;
|
|
3758
|
+
// Priority 1: Exact Count
|
|
3759
|
+
// Check Anthropic format (server_tool_use.web_search_requests)
|
|
3760
|
+
if (usage.server_tool_use?.web_search_requests !== undefined) {
|
|
3761
|
+
webSearchCount = usage.server_tool_use.web_search_requests;
|
|
3762
|
+
}
|
|
3763
|
+
// Priority 2: Binary Detection (1 or 0)
|
|
3764
|
+
// Check for citations array (Perplexity)
|
|
3765
|
+
else if (usage.citations && Array.isArray(usage.citations) && usage.citations.length > 0) {
|
|
3766
|
+
webSearchCount = 1;
|
|
3767
|
+
}
|
|
3768
|
+
// Check for search_results array (Perplexity via OpenRouter)
|
|
3769
|
+
else if (usage.search_results && Array.isArray(usage.search_results) && usage.search_results.length > 0) {
|
|
3770
|
+
webSearchCount = 1;
|
|
3771
|
+
}
|
|
3772
|
+
// Check for search_context_size (Perplexity via OpenRouter)
|
|
3773
|
+
else if (usage.search_context_size) {
|
|
3774
|
+
webSearchCount = 1;
|
|
3775
|
+
}
|
|
3776
|
+
// Check for annotations with url_citation type
|
|
3777
|
+
else if (usage.annotations && Array.isArray(usage.annotations)) {
|
|
3778
|
+
const hasUrlCitation = usage.annotations.some(ann => {
|
|
3779
|
+
return ann && typeof ann === 'object' && 'type' in ann && ann.type === 'url_citation';
|
|
3780
|
+
});
|
|
3781
|
+
if (hasUrlCitation) {
|
|
3782
|
+
webSearchCount = 1;
|
|
3783
|
+
}
|
|
3784
|
+
}
|
|
3785
|
+
// Check Gemini format (grounding metadata - binary 0 or 1)
|
|
3786
|
+
else if (usage.grounding_metadata?.grounding_support !== undefined || usage.grounding_metadata?.web_search_queries !== undefined) {
|
|
3787
|
+
webSearchCount = 1;
|
|
3788
|
+
}
|
|
3789
|
+
if (webSearchCount !== undefined) {
|
|
3790
|
+
additionalTokenData.webSearchCount = webSearchCount;
|
|
3791
|
+
}
|
|
3575
3792
|
// In LangChain, input_tokens is the sum of input and cache read tokens.
|
|
3576
3793
|
// Our cost calculation expects them to be separate, for Anthropic.
|
|
3577
3794
|
if (parsedUsage.input && additionalTokenData.cacheReadInputTokens) {
|