@posthog/ai 8.7.0 → 8.8.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 +61 -17
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +61 -17
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +73 -17
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +73 -17
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +83 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +83 -39
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +27 -13
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +27 -13
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +91 -47
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +91 -47
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +25 -4
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.mjs +25 -4
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/otel/index.cjs +1 -5
- package/dist/otel/index.cjs.map +1 -1
- package/dist/otel/index.mjs +1 -5
- package/dist/otel/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +92 -39
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +92 -39
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/anthropic/index.cjs
CHANGED
|
@@ -11,6 +11,33 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
11
11
|
|
|
12
12
|
var AnthropicOriginal__default = /*#__PURE__*/_interopDefault(AnthropicOriginal);
|
|
13
13
|
|
|
14
|
+
/** @internal */
|
|
15
|
+
|
|
16
|
+
/** @internal */
|
|
17
|
+
|
|
18
|
+
/** @internal */
|
|
19
|
+
function isFullAiCaptureEnabled(client) {
|
|
20
|
+
return client?.enableFullAiCapture === true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** @internal */
|
|
24
|
+
function captureAiEvent(client, event) {
|
|
25
|
+
if (isFullAiCaptureEnabled(client) && typeof client.captureAi === 'function') {
|
|
26
|
+
client.captureAi(event);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
client.capture(event);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** @internal */
|
|
33
|
+
async function captureAiEventImmediate(client, event) {
|
|
34
|
+
if (isFullAiCaptureEnabled(client) && typeof client.captureAiImmediate === 'function') {
|
|
35
|
+
await client.captureAiImmediate(event);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
await client.captureImmediate(event);
|
|
39
|
+
}
|
|
40
|
+
|
|
14
41
|
const DATA_URL_PREFIX_RE = /^data:([^;,\s]+)(?:;[^;,\s]+)*;base64,/i;
|
|
15
42
|
const BASE64_ALPHABET_RE = /^[A-Za-z0-9+/_=-]+$/;
|
|
16
43
|
class Base64Recognizer {
|
|
@@ -116,7 +143,6 @@ class BinaryContentRedactor {
|
|
|
116
143
|
this.recognizer = recognizer;
|
|
117
144
|
}
|
|
118
145
|
redact(value, mediaType) {
|
|
119
|
-
if (this.isMultimodalEnabled()) return value;
|
|
120
146
|
this.visited = new WeakSet();
|
|
121
147
|
return this.walk(value, mediaType ? new MediaTypeContext(undefined, undefined, mediaType) : MediaTypeContext.EMPTY);
|
|
122
148
|
}
|
|
@@ -160,21 +186,23 @@ class BinaryContentRedactor {
|
|
|
160
186
|
if (mediaType === 'application/octet-stream') return '[base64 file redacted]';
|
|
161
187
|
return `[base64 ${mediaType} redacted]`;
|
|
162
188
|
}
|
|
163
|
-
isMultimodalEnabled() {
|
|
164
|
-
const val = process.env._INTERNAL_LLMA_MULTIMODAL || '';
|
|
165
|
-
return val.toLowerCase() === 'true' || val === '1' || val.toLowerCase() === 'yes';
|
|
166
|
-
}
|
|
167
189
|
}
|
|
168
190
|
|
|
169
191
|
const redactor = new BinaryContentRedactor();
|
|
170
|
-
const
|
|
192
|
+
const sanitize = (data, client) => isFullAiCaptureEnabled(client) ? data : redactor.redact(data);
|
|
193
|
+
const sanitizeAnthropic = (data, client) => sanitize(data, client);
|
|
171
194
|
|
|
172
195
|
const TOKEN_PROPERTY_KEYS = new Set(['$ai_input_tokens', '$ai_output_tokens', '$ai_cache_read_input_tokens', '$ai_cache_creation_input_tokens', '$ai_total_tokens', '$ai_reasoning_tokens']);
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Whether the caller supplied their own token counts, which override the ones the SDK
|
|
199
|
+
* derived from the provider response.
|
|
200
|
+
*/
|
|
201
|
+
function hasTokenOverrides(posthogProperties) {
|
|
202
|
+
return !!posthogProperties && Object.keys(posthogProperties).some(key => TOKEN_PROPERTY_KEYS.has(key));
|
|
203
|
+
}
|
|
173
204
|
function getTokensSource(posthogProperties) {
|
|
174
|
-
|
|
175
|
-
return 'passthrough';
|
|
176
|
-
}
|
|
177
|
-
return 'sdk';
|
|
205
|
+
return hasTokenOverrides(posthogProperties) ? 'passthrough' : 'sdk';
|
|
178
206
|
}
|
|
179
207
|
const STRING_FORMAT = 'utf8';
|
|
180
208
|
|
|
@@ -310,7 +338,7 @@ function addDefaults(params) {
|
|
|
310
338
|
};
|
|
311
339
|
}
|
|
312
340
|
|
|
313
|
-
var version = "8.
|
|
341
|
+
var version = "8.8.0";
|
|
314
342
|
|
|
315
343
|
const DEFAULT_MAX_DEPTH = 3;
|
|
316
344
|
const MAX_STACK_LINES = 20;
|
|
@@ -477,6 +505,10 @@ const captureAiGeneration = async (client, options) => {
|
|
|
477
505
|
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
478
506
|
};
|
|
479
507
|
}
|
|
508
|
+
|
|
509
|
+
// The caller's own token counts override the SDK-derived ones further down, via the
|
|
510
|
+
// `options.properties` spread.
|
|
511
|
+
const tokensOverridden = hasTokenOverrides(options.properties);
|
|
480
512
|
const additionalTokenValues = {
|
|
481
513
|
...(usage.reasoningTokens ? {
|
|
482
514
|
$ai_reasoning_tokens: usage.reasoningTokens
|
|
@@ -487,6 +519,18 @@ const captureAiGeneration = async (client, options) => {
|
|
|
487
519
|
...(usage.cacheCreationInputTokens ? {
|
|
488
520
|
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
489
521
|
} : {}),
|
|
522
|
+
// Checked against undefined rather than truthiness, because false is the meaningful
|
|
523
|
+
// value here and a truthiness guard would drop it.
|
|
524
|
+
//
|
|
525
|
+
// Dropped entirely when the caller overrides the token counts: the flag describes how
|
|
526
|
+
// the SDK-derived counts relate to each other, so against passthrough counts it can be
|
|
527
|
+
// wrong in the expensive direction. Declaring inclusive over counts that are actually
|
|
528
|
+
// exclusive makes ingestion subtract the cache pool that was never in the input. A
|
|
529
|
+
// caller who knows their own accounting model can still pass
|
|
530
|
+
// `$ai_cache_reporting_exclusive` themselves, and that value wins.
|
|
531
|
+
...(usage.cacheReportingExclusive !== undefined && !tokensOverridden ? {
|
|
532
|
+
$ai_cache_reporting_exclusive: usage.cacheReportingExclusive
|
|
533
|
+
} : {}),
|
|
490
534
|
...(usage.webSearchCount ? {
|
|
491
535
|
$ai_web_search_count: usage.webSearchCount
|
|
492
536
|
} : {}),
|
|
@@ -543,9 +587,9 @@ const captureAiGeneration = async (client, options) => {
|
|
|
543
587
|
groups: options.groups
|
|
544
588
|
};
|
|
545
589
|
if (options.captureImmediate) {
|
|
546
|
-
await client
|
|
590
|
+
await captureAiEventImmediate(client, event);
|
|
547
591
|
} else {
|
|
548
|
-
client
|
|
592
|
+
captureAiEvent(client, event);
|
|
549
593
|
}
|
|
550
594
|
} catch (error) {
|
|
551
595
|
// Telemetry failures must never affect the instrumented provider call.
|
|
@@ -1006,7 +1050,7 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
1006
1050
|
...posthogParams,
|
|
1007
1051
|
model: anthropicParams.model,
|
|
1008
1052
|
provider: 'anthropic',
|
|
1009
|
-
input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams, 'anthropic')),
|
|
1053
|
+
input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams, 'anthropic'), this.phClient),
|
|
1010
1054
|
output: formattedOutput,
|
|
1011
1055
|
latency,
|
|
1012
1056
|
timeToFirstToken,
|
|
@@ -1022,7 +1066,7 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
1022
1066
|
...posthogParams,
|
|
1023
1067
|
model: anthropicParams.model,
|
|
1024
1068
|
provider: 'anthropic',
|
|
1025
|
-
input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams)),
|
|
1069
|
+
input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams), this.phClient),
|
|
1026
1070
|
output: [],
|
|
1027
1071
|
latency: 0,
|
|
1028
1072
|
baseURL: this.baseURL,
|
|
@@ -1058,7 +1102,7 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
1058
1102
|
...posthogParams,
|
|
1059
1103
|
model: anthropicParams.model,
|
|
1060
1104
|
provider: 'anthropic',
|
|
1061
|
-
input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams)),
|
|
1105
|
+
input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams), this.phClient),
|
|
1062
1106
|
output: formatResponseAnthropic(result),
|
|
1063
1107
|
latency,
|
|
1064
1108
|
baseURL: this.baseURL,
|
|
@@ -1082,7 +1126,7 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
1082
1126
|
...posthogParams,
|
|
1083
1127
|
model: anthropicParams.model,
|
|
1084
1128
|
provider: 'anthropic',
|
|
1085
|
-
input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams)),
|
|
1129
|
+
input: sanitizeAnthropic(mergeSystemPrompt(anthropicParams), this.phClient),
|
|
1086
1130
|
output: [],
|
|
1087
1131
|
latency: 0,
|
|
1088
1132
|
baseURL: this.baseURL,
|