@posthog/ai 8.6.3 → 8.6.5
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 +98 -9
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.d.ts +2 -3
- package/dist/anthropic/index.mjs +98 -9
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +21 -9
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +21 -9
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +37 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +37 -31
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +16 -6
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +16 -6
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +255 -132
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.d.ts +2 -2
- package/dist/openai/index.mjs +255 -132
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +10 -2
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.mjs +10 -2
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/otel/index.cjs +15 -5
- package/dist/otel/index.cjs.map +1 -1
- package/dist/otel/index.mjs +15 -5
- package/dist/otel/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +37 -31
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +37 -31
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/vercel/index.mjs
CHANGED
|
@@ -42,14 +42,16 @@ const FILE_FAMILY_TYPES = new Set(['file', 'input_file', 'document', 'media', 'f
|
|
|
42
42
|
const KNOWN_AUDIO_FORMATS = new Set(['wav', 'mp3', 'ogg', 'flac', 'm4a', 'aac', 'webm']);
|
|
43
43
|
class MediaTypeContext {
|
|
44
44
|
static EMPTY = new MediaTypeContext(undefined, undefined);
|
|
45
|
-
constructor(parent, key) {
|
|
45
|
+
constructor(parent, key, explicitMediaType) {
|
|
46
46
|
this.parent = parent;
|
|
47
47
|
this.key = key;
|
|
48
|
+
this.explicitMediaType = explicitMediaType;
|
|
48
49
|
}
|
|
49
50
|
inferMediaType() {
|
|
50
51
|
return this.inferFromSiblingMime() ?? this.inferFromSiblingFormat() ?? this.inferFromParentType() ?? this.inferFromKey();
|
|
51
52
|
}
|
|
52
53
|
inferFromSiblingMime() {
|
|
54
|
+
if (this.explicitMediaType) return this.explicitMediaType;
|
|
53
55
|
if (!this.parent) return undefined;
|
|
54
56
|
for (const hint of MIME_HINT_KEYS) {
|
|
55
57
|
const v = this.parent[hint];
|
|
@@ -84,7 +86,13 @@ class MediaTypeContext {
|
|
|
84
86
|
if (key.includes('file') || key.includes('document')) return 'application/octet-stream';
|
|
85
87
|
return undefined;
|
|
86
88
|
}
|
|
89
|
+
hasExplicitBinaryMediaType() {
|
|
90
|
+
if (!this.explicitMediaType && (!this.parent || !this.key || !STRONG_CONTEXT_KEYS.has(this.key))) return false;
|
|
91
|
+
const mediaType = this.inferFromSiblingMime();
|
|
92
|
+
return mediaType !== undefined && !mediaType.toLowerCase().startsWith('text/');
|
|
93
|
+
}
|
|
87
94
|
signalsBinary() {
|
|
95
|
+
if (this.explicitMediaType) return true;
|
|
88
96
|
if (this.parent) {
|
|
89
97
|
for (const hint of MIME_HINT_KEYS) {
|
|
90
98
|
if (typeof this.parent[hint] === 'string') return true;
|
|
@@ -106,10 +114,10 @@ class BinaryContentRedactor {
|
|
|
106
114
|
constructor(recognizer = new Base64Recognizer()) {
|
|
107
115
|
this.recognizer = recognizer;
|
|
108
116
|
}
|
|
109
|
-
redact(value) {
|
|
117
|
+
redact(value, mediaType) {
|
|
110
118
|
if (this.isMultimodalEnabled()) return value;
|
|
111
119
|
this.visited = new WeakSet();
|
|
112
|
-
return this.walk(value, MediaTypeContext.EMPTY);
|
|
120
|
+
return this.walk(value, mediaType ? new MediaTypeContext(undefined, undefined, mediaType) : MediaTypeContext.EMPTY);
|
|
113
121
|
}
|
|
114
122
|
walk(value, ctx) {
|
|
115
123
|
if (value === null || value === undefined) return value;
|
|
@@ -133,8 +141,10 @@ class BinaryContentRedactor {
|
|
|
133
141
|
return out;
|
|
134
142
|
}
|
|
135
143
|
redactString(value, ctx) {
|
|
136
|
-
const
|
|
137
|
-
const
|
|
144
|
+
const hasExplicitBinaryMediaType = ctx.hasExplicitBinaryMediaType();
|
|
145
|
+
const recognitionValue = hasExplicitBinaryMediaType ? value.replace(/[\r\n]/g, '') : value;
|
|
146
|
+
const minLength = hasExplicitBinaryMediaType ? Math.min(recognitionValue.length, STRONG_CONTEXT_MIN_LENGTH) : ctx.signalsBinary() ? STRONG_CONTEXT_MIN_LENGTH : WEAK_CONTEXT_MIN_LENGTH;
|
|
147
|
+
const recognition = this.recognizer.recognize(recognitionValue, minLength);
|
|
138
148
|
switch (recognition.kind) {
|
|
139
149
|
case 'data-url':
|
|
140
150
|
return this.placeholderFor(recognition.mediaType);
|
|
@@ -156,9 +166,10 @@ class BinaryContentRedactor {
|
|
|
156
166
|
}
|
|
157
167
|
|
|
158
168
|
const redactor = new BinaryContentRedactor();
|
|
159
|
-
function redactBase64DataUrl(str) {
|
|
160
|
-
return redactor.redact(str);
|
|
169
|
+
function redactBase64DataUrl(str, mediaType) {
|
|
170
|
+
return redactor.redact(str, mediaType);
|
|
161
171
|
}
|
|
172
|
+
const sanitizeVercel = data => redactor.redact(data);
|
|
162
173
|
|
|
163
174
|
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']);
|
|
164
175
|
function getTokensSource(posthogProperties) {
|
|
@@ -395,7 +406,7 @@ function sanitizeValues(obj) {
|
|
|
395
406
|
return jsonSafe;
|
|
396
407
|
}
|
|
397
408
|
|
|
398
|
-
var version = "8.6.
|
|
409
|
+
var version = "8.6.5";
|
|
399
410
|
|
|
400
411
|
const DEFAULT_MAX_DEPTH = 3;
|
|
401
412
|
const MAX_STACK_LINES = 20;
|
|
@@ -528,6 +539,8 @@ const captureAiGeneration = async (client, options) => {
|
|
|
528
539
|
if (httpStatus === undefined) {
|
|
529
540
|
if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
|
|
530
541
|
httpStatus = options.error.status;
|
|
542
|
+
} else if (typeof options.error === 'object' && 'statusCode' in options.error && typeof options.error.statusCode === 'number') {
|
|
543
|
+
httpStatus = options.error.statusCode;
|
|
531
544
|
} else {
|
|
532
545
|
httpStatus = 500;
|
|
533
546
|
}
|
|
@@ -643,6 +656,15 @@ function isV3Model(model) {
|
|
|
643
656
|
|
|
644
657
|
// Content types for the output array
|
|
645
658
|
|
|
659
|
+
const redactFileData = (data, mediaType) => {
|
|
660
|
+
if (data instanceof URL) {
|
|
661
|
+
return redactBase64DataUrl(data.toString(), data.protocol === 'data:' ? mediaType : undefined);
|
|
662
|
+
}
|
|
663
|
+
if (isString(data)) {
|
|
664
|
+
return redactBase64DataUrl(data, mediaType);
|
|
665
|
+
}
|
|
666
|
+
return undefined;
|
|
667
|
+
};
|
|
646
668
|
const mapVercelParams = params => {
|
|
647
669
|
return {
|
|
648
670
|
temperature: params.temperature,
|
|
@@ -675,17 +697,8 @@ const mapVercelPrompt = messages => {
|
|
|
675
697
|
text: truncate(c.text)
|
|
676
698
|
};
|
|
677
699
|
} else if (c.type === 'file') {
|
|
678
|
-
//
|
|
679
|
-
|
|
680
|
-
const contentData = c.data;
|
|
681
|
-
if (contentData instanceof URL) {
|
|
682
|
-
fileData = contentData.toString();
|
|
683
|
-
} else if (isString(contentData)) {
|
|
684
|
-
// Redact base64 data URLs and raw base64 to prevent oversized events
|
|
685
|
-
fileData = redactBase64DataUrl(contentData);
|
|
686
|
-
} else {
|
|
687
|
-
fileData = 'raw files not supported';
|
|
688
|
-
}
|
|
700
|
+
// Redact base64 data URLs and raw base64 to prevent oversized events
|
|
701
|
+
const fileData = redactFileData(c.data, c.mediaType) ?? 'raw files not supported';
|
|
689
702
|
return {
|
|
690
703
|
type: 'file',
|
|
691
704
|
file: fileData,
|
|
@@ -708,7 +721,7 @@ const mapVercelPrompt = messages => {
|
|
|
708
721
|
type: 'tool-result',
|
|
709
722
|
toolCallId: c.toolCallId,
|
|
710
723
|
toolName: c.toolName,
|
|
711
|
-
output: c.output,
|
|
724
|
+
output: sanitizeVercel(c.output),
|
|
712
725
|
isError: c.isError
|
|
713
726
|
};
|
|
714
727
|
}
|
|
@@ -794,18 +807,11 @@ const mapVercelOutput = result => {
|
|
|
794
807
|
}
|
|
795
808
|
if (item.type === 'file') {
|
|
796
809
|
// Handle files similar to input mapping - avoid large base64 data
|
|
797
|
-
let fileData
|
|
798
|
-
if (item.data instanceof URL) {
|
|
799
|
-
fileData = item.data.toString();
|
|
800
|
-
} else if (typeof item.data === 'string') {
|
|
801
|
-
fileData = redactBase64DataUrl(item.data);
|
|
810
|
+
let fileData = redactFileData(item.data, item.mediaType) ?? `[binary ${item.mediaType} file]`;
|
|
802
811
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
}
|
|
807
|
-
} else {
|
|
808
|
-
fileData = `[binary ${item.mediaType} file]`;
|
|
812
|
+
// If not redacted and still large, replace with size indicator
|
|
813
|
+
if (typeof item.data === 'string' && fileData === item.data && item.data.length > 1000) {
|
|
814
|
+
fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
|
|
809
815
|
}
|
|
810
816
|
return {
|
|
811
817
|
type: 'file',
|