@posthog/ai 8.14.1 → 8.14.3
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/README.md +35 -1
- package/dist/adk/index.cjs +16 -6
- package/dist/adk/index.cjs.map +1 -1
- package/dist/adk/index.mjs +16 -6
- package/dist/adk/index.mjs.map +1 -1
- package/dist/anthropic/index.cjs +156 -15
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.d.ts +1 -0
- package/dist/anthropic/index.mjs +156 -15
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/claude-agent-sdk/index.cjs +111 -37
- package/dist/claude-agent-sdk/index.cjs.map +1 -1
- package/dist/claude-agent-sdk/index.mjs +111 -37
- package/dist/claude-agent-sdk/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +175 -39
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.d.ts +1 -1
- package/dist/gemini/index.mjs +175 -39
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +15 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +15 -8
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +15 -5
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +15 -5
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/langchain/middleware/index.cjs +15 -5
- package/dist/langchain/middleware/index.cjs.map +1 -1
- package/dist/langchain/middleware/index.mjs +15 -5
- package/dist/langchain/middleware/index.mjs.map +1 -1
- package/dist/openai/index.cjs +181 -21
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +181 -21
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +15 -5
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.mjs +15 -5
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/otel/index.cjs +12 -3
- package/dist/otel/index.cjs.map +1 -1
- package/dist/otel/index.mjs +12 -3
- package/dist/otel/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +15 -8
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +15 -8
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/gemini/index.mjs
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { GoogleGenAI } from "@google/genai";
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
3
|
import { toJsonSafeValue, uuidv7 } from "@posthog/core";
|
|
4
|
-
//#region src/typeGuards.ts
|
|
5
|
-
const isString = (value) => {
|
|
6
|
-
return typeof value === "string";
|
|
7
|
-
};
|
|
8
|
-
//#endregion
|
|
9
4
|
//#region src/captureAiEvent.ts
|
|
10
5
|
/** @internal */
|
|
11
6
|
function isFullAiCaptureEnabled(client) {
|
|
@@ -28,6 +23,14 @@ async function captureAiEventImmediate(client, event) {
|
|
|
28
23
|
await client.captureImmediate(event);
|
|
29
24
|
}
|
|
30
25
|
//#endregion
|
|
26
|
+
//#region src/typeGuards.ts
|
|
27
|
+
const isString = (value) => {
|
|
28
|
+
return typeof value === "string";
|
|
29
|
+
};
|
|
30
|
+
const isObject = (value) => {
|
|
31
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
31
34
|
//#region src/sanitization/base64_recognizer.ts
|
|
32
35
|
const DATA_URL_PREFIX_RE = /^data:([^;,\s]+)(?:;[^;,\s]+)*;base64,/i;
|
|
33
36
|
const BASE64_ALPHABET_RE = /^[A-Za-z0-9+/_=-]+$/;
|
|
@@ -171,17 +174,26 @@ var BinaryContentRedactor = class {
|
|
|
171
174
|
this.visited = /* @__PURE__ */ new WeakSet();
|
|
172
175
|
return this.walk(value, mediaType ? new MediaTypeContext(void 0, void 0, mediaType) : MediaTypeContext.EMPTY);
|
|
173
176
|
}
|
|
177
|
+
/** Redact one leaf while a caller owns bounded, type-preserving traversal. @internal */
|
|
178
|
+
redactLeaf(value, context) {
|
|
179
|
+
return typeof value === "string" ? this.redactString(value, context) : this.placeholderFor(context.inferMediaType());
|
|
180
|
+
}
|
|
174
181
|
walk(value, ctx) {
|
|
175
182
|
if (value === null || value === void 0) return value;
|
|
176
|
-
if (typeof value === "string") return this.
|
|
183
|
+
if (typeof value === "string") return this.redactLeaf(value, ctx);
|
|
177
184
|
if (typeof value !== "object") return value;
|
|
178
|
-
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return this.
|
|
185
|
+
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return this.redactLeaf(value, ctx);
|
|
179
186
|
if (this.visited.has(value)) return null;
|
|
180
187
|
this.visited.add(value);
|
|
181
188
|
if (Array.isArray(value)) return value.map((item) => this.walk(item, ctx));
|
|
182
189
|
const obj = value;
|
|
183
190
|
const out = {};
|
|
184
|
-
for (const k of Object.keys(obj))
|
|
191
|
+
for (const k of Object.keys(obj)) Object.defineProperty(out, k, {
|
|
192
|
+
value: this.walk(obj[k], new MediaTypeContext(obj, k)),
|
|
193
|
+
enumerable: true,
|
|
194
|
+
writable: true,
|
|
195
|
+
configurable: true
|
|
196
|
+
});
|
|
185
197
|
return out;
|
|
186
198
|
}
|
|
187
199
|
redactString(value, ctx) {
|
|
@@ -203,11 +215,11 @@ var BinaryContentRedactor = class {
|
|
|
203
215
|
};
|
|
204
216
|
//#endregion
|
|
205
217
|
//#region src/sanitization.ts
|
|
206
|
-
const redactor = new BinaryContentRedactor();
|
|
218
|
+
const redactor$1 = new BinaryContentRedactor();
|
|
207
219
|
function redactBase64DataUrl(str, mediaType) {
|
|
208
|
-
return redactor.redact(str, mediaType);
|
|
220
|
+
return redactor$1.redact(str, mediaType);
|
|
209
221
|
}
|
|
210
|
-
const sanitize = (data, client) => isFullAiCaptureEnabled(client) ? data : redactor.redact(data);
|
|
222
|
+
const sanitize = (data, client) => isFullAiCaptureEnabled(client) ? data : redactor$1.redact(data);
|
|
211
223
|
const sanitizeGemini = (data, client) => sanitize(data, client);
|
|
212
224
|
//#endregion
|
|
213
225
|
//#region src/utils.ts
|
|
@@ -352,8 +364,9 @@ const formatResponseGemini = (response, client) => {
|
|
|
352
364
|
});
|
|
353
365
|
return output;
|
|
354
366
|
};
|
|
367
|
+
const isPrivacyModeEnabled = (client, privacyMode) => Boolean(client.privacy_mode || privacyMode);
|
|
355
368
|
const withPrivacyMode = (client, privacyMode, input) => {
|
|
356
|
-
return client
|
|
369
|
+
return isPrivacyModeEnabled(client, privacyMode) ? null : input;
|
|
357
370
|
};
|
|
358
371
|
function toSafeString(input) {
|
|
359
372
|
if (input === void 0 || input === null) return "";
|
|
@@ -435,7 +448,7 @@ function addDefaults(params) {
|
|
|
435
448
|
}
|
|
436
449
|
//#endregion
|
|
437
450
|
//#region package.json
|
|
438
|
-
var version = "8.14.
|
|
451
|
+
var version = "8.14.3";
|
|
439
452
|
//#endregion
|
|
440
453
|
//#region src/serializeError.ts
|
|
441
454
|
const DEFAULT_MAX_DEPTH = 3;
|
|
@@ -522,7 +535,7 @@ const captureAiGeneration = async (client, options) => {
|
|
|
522
535
|
const eventType = options.eventType ?? "$ai_generation";
|
|
523
536
|
const privacyMode = options.privacyMode ?? false;
|
|
524
537
|
const usage = options.usage ?? {};
|
|
525
|
-
const shouldRedact =
|
|
538
|
+
const shouldRedact = isPrivacyModeEnabled(client, privacyMode);
|
|
526
539
|
const safeInput = shouldRedact ? null : toJsonSafeValue(options.input);
|
|
527
540
|
const safeOutput = shouldRedact ? null : toJsonSafeValue(options.output);
|
|
528
541
|
let httpStatus = options.httpStatus;
|
|
@@ -604,6 +617,89 @@ const captureAiGeneration = async (client, options) => {
|
|
|
604
617
|
}
|
|
605
618
|
};
|
|
606
619
|
//#endregion
|
|
620
|
+
//#region src/toolResult.ts
|
|
621
|
+
const MAX_DEPTH = 20;
|
|
622
|
+
const MAX_ITEMS = 1e3;
|
|
623
|
+
const MAX_NODES = 1e4;
|
|
624
|
+
const TRUNCATED = "[Truncated]";
|
|
625
|
+
const UNSERIALIZABLE = "[Unserializable]";
|
|
626
|
+
const redactor = new BinaryContentRedactor();
|
|
627
|
+
const propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
|
|
628
|
+
/** @internal Preserve tool-result structure while bounding each string value. */
|
|
629
|
+
function formatToolResult(content, client, maxBytes = 5e3) {
|
|
630
|
+
try {
|
|
631
|
+
if (isFullAiCaptureEnabled(client)) return toJsonSafeValue(content);
|
|
632
|
+
const ancestors = /* @__PURE__ */ new WeakSet();
|
|
633
|
+
let remainingNodes = MAX_NODES;
|
|
634
|
+
const convert = (value, depth, context) => {
|
|
635
|
+
if (remainingNodes <= 0) return TRUNCATED;
|
|
636
|
+
remainingNodes--;
|
|
637
|
+
try {
|
|
638
|
+
if (value === null || typeof value !== "object") {
|
|
639
|
+
const safe = toJsonSafeValue(value);
|
|
640
|
+
return typeof safe === "string" ? truncate(redactor.redactLeaf(safe, context), void 0, maxBytes) : safe;
|
|
641
|
+
}
|
|
642
|
+
if (depth >= MAX_DEPTH) return TRUNCATED;
|
|
643
|
+
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return redactor.redactLeaf(value, context);
|
|
644
|
+
if (ancestors.has(value)) return "[Circular]";
|
|
645
|
+
ancestors.add(value);
|
|
646
|
+
try {
|
|
647
|
+
if (value instanceof Date) {
|
|
648
|
+
const safe = toJsonSafeValue(value);
|
|
649
|
+
return typeof safe === "string" ? truncate(redactor.redactLeaf(safe, context), void 0, maxBytes) : safe;
|
|
650
|
+
}
|
|
651
|
+
let hasToJSONResult = false;
|
|
652
|
+
let toJSONResult;
|
|
653
|
+
try {
|
|
654
|
+
const toJSON = value.toJSON;
|
|
655
|
+
if (typeof toJSON === "function") {
|
|
656
|
+
toJSONResult = toJSON.call(value);
|
|
657
|
+
hasToJSONResult = true;
|
|
658
|
+
}
|
|
659
|
+
} catch {}
|
|
660
|
+
if (hasToJSONResult) return convert(toJSONResult, depth + 1, context);
|
|
661
|
+
if (Array.isArray(value)) {
|
|
662
|
+
const output = [];
|
|
663
|
+
const count = Math.min(value.length, MAX_ITEMS);
|
|
664
|
+
let index = 0;
|
|
665
|
+
for (; index < count && remainingNodes > 0; index++) output.push(convert(value[index], depth + 1, context));
|
|
666
|
+
if (value.length > index) output.push(TRUNCATED);
|
|
667
|
+
return output;
|
|
668
|
+
}
|
|
669
|
+
const input = value;
|
|
670
|
+
const output = {};
|
|
671
|
+
let count = 0;
|
|
672
|
+
let truncated = false;
|
|
673
|
+
for (const key in input) {
|
|
674
|
+
if (!propertyIsEnumerable.call(input, key)) break;
|
|
675
|
+
if (count >= MAX_ITEMS || remainingNodes <= 0) {
|
|
676
|
+
truncated = true;
|
|
677
|
+
break;
|
|
678
|
+
}
|
|
679
|
+
const converted = convert(input[key], depth + 1, new MediaTypeContext(input, key));
|
|
680
|
+
Object.defineProperty(output, key, {
|
|
681
|
+
value: converted,
|
|
682
|
+
enumerable: true,
|
|
683
|
+
writable: true,
|
|
684
|
+
configurable: true
|
|
685
|
+
});
|
|
686
|
+
count++;
|
|
687
|
+
}
|
|
688
|
+
if (truncated) output[TRUNCATED] = "Additional properties omitted";
|
|
689
|
+
return output;
|
|
690
|
+
} finally {
|
|
691
|
+
ancestors.delete(value);
|
|
692
|
+
}
|
|
693
|
+
} catch {
|
|
694
|
+
return UNSERIALIZABLE;
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
return convert(content, 0, MediaTypeContext.EMPTY);
|
|
698
|
+
} catch {
|
|
699
|
+
return UNSERIALIZABLE;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
//#endregion
|
|
607
703
|
//#region src/gemini/usage.ts
|
|
608
704
|
/** Map Gemini usage metadata to PostHog's provider-agnostic token fields. */
|
|
609
705
|
function mapGeminiUsage(metadata, additionalUsage = {}) {
|
|
@@ -620,6 +716,12 @@ function mapGeminiUsage(metadata, additionalUsage = {}) {
|
|
|
620
716
|
//#endregion
|
|
621
717
|
//#region src/gemini/index.ts
|
|
622
718
|
const TOOL_RESULT_MAX_BYTES = 5e3;
|
|
719
|
+
function geminiFunctionResponseContent(response) {
|
|
720
|
+
return response.parts !== void 0 ? {
|
|
721
|
+
...response.response !== void 0 && { response: response.response },
|
|
722
|
+
parts: response.parts
|
|
723
|
+
} : response.response ?? {};
|
|
724
|
+
}
|
|
623
725
|
var PostHogGoogleGenAI = class {
|
|
624
726
|
constructor(config) {
|
|
625
727
|
const { posthog, ...geminiConfig } = config;
|
|
@@ -646,7 +748,7 @@ var WrappedModels = class {
|
|
|
646
748
|
...posthogParams,
|
|
647
749
|
model: geminiParams.model,
|
|
648
750
|
provider: "gemini",
|
|
649
|
-
input: this.formatInputForPostHog(geminiParams),
|
|
751
|
+
input: this.formatInputForPostHog(geminiParams, posthogParams.privacyMode),
|
|
650
752
|
output: formatResponseGemini(response, this.phClient),
|
|
651
753
|
latency,
|
|
652
754
|
baseURL: "https://generativelanguage.googleapis.com",
|
|
@@ -663,7 +765,7 @@ var WrappedModels = class {
|
|
|
663
765
|
...posthogParams,
|
|
664
766
|
model: geminiParams.model,
|
|
665
767
|
provider: "gemini",
|
|
666
|
-
input: this.formatInputForPostHog(geminiParams),
|
|
768
|
+
input: this.formatInputForPostHog(geminiParams, posthogParams.privacyMode),
|
|
667
769
|
output: [],
|
|
668
770
|
latency,
|
|
669
771
|
baseURL: "https://generativelanguage.googleapis.com",
|
|
@@ -730,7 +832,7 @@ var WrappedModels = class {
|
|
|
730
832
|
...posthogParams,
|
|
731
833
|
model: geminiParams.model,
|
|
732
834
|
provider: "gemini",
|
|
733
|
-
input: this.formatInputForPostHog(geminiParams),
|
|
835
|
+
input: this.formatInputForPostHog(geminiParams, posthogParams.privacyMode),
|
|
734
836
|
output: [],
|
|
735
837
|
latency,
|
|
736
838
|
baseURL: "https://generativelanguage.googleapis.com",
|
|
@@ -752,7 +854,7 @@ var WrappedModels = class {
|
|
|
752
854
|
...posthogParams,
|
|
753
855
|
model: geminiParams.model,
|
|
754
856
|
provider: "gemini",
|
|
755
|
-
input: this.formatInputForPostHog(geminiParams),
|
|
857
|
+
input: this.formatInputForPostHog(geminiParams, posthogParams.privacyMode),
|
|
756
858
|
output,
|
|
757
859
|
latency,
|
|
758
860
|
timeToFirstToken,
|
|
@@ -836,28 +938,16 @@ var WrappedModels = class {
|
|
|
836
938
|
} else if (part && typeof part === "object" && "functionResponse" in part) {
|
|
837
939
|
const functionResponse = part.functionResponse;
|
|
838
940
|
if (functionResponse?.name) {
|
|
839
|
-
const content = functionResponse
|
|
840
|
-
...functionResponse.response !== void 0 && { response: functionResponse.response },
|
|
841
|
-
parts: functionResponse.parts
|
|
842
|
-
} : functionResponse.response ?? {};
|
|
941
|
+
const content = geminiFunctionResponseContent(functionResponse);
|
|
843
942
|
blocks.push({
|
|
844
943
|
type: "tool_result",
|
|
845
944
|
...functionResponse.id != null && { tool_use_id: functionResponse.id },
|
|
846
|
-
content
|
|
945
|
+
content
|
|
847
946
|
});
|
|
848
947
|
}
|
|
849
948
|
}
|
|
850
949
|
return blocks;
|
|
851
950
|
}
|
|
852
|
-
boundToolResult(content) {
|
|
853
|
-
if (isFullAiCaptureEnabled(this.phClient)) return content;
|
|
854
|
-
try {
|
|
855
|
-
const serialized = JSON.stringify(content);
|
|
856
|
-
return utf8ByteLength(serialized) > TOOL_RESULT_MAX_BYTES ? truncate(serialized, void 0, TOOL_RESULT_MAX_BYTES) : content;
|
|
857
|
-
} catch {
|
|
858
|
-
return "[Unserializable tool result]";
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
951
|
formatInput(contents) {
|
|
862
952
|
if (typeof contents === "string") return [{
|
|
863
953
|
role: "user",
|
|
@@ -932,17 +1022,63 @@ var WrappedModels = class {
|
|
|
932
1022
|
}
|
|
933
1023
|
return null;
|
|
934
1024
|
}
|
|
935
|
-
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
1025
|
+
boundToolResult(content) {
|
|
1026
|
+
const normalized = formatToolResult(content, this.phClient, Infinity);
|
|
1027
|
+
if (isFullAiCaptureEnabled(this.phClient)) return normalized;
|
|
1028
|
+
const serialized = JSON.stringify(normalized);
|
|
1029
|
+
return serialized !== void 0 && utf8ByteLength(serialized) > TOOL_RESULT_MAX_BYTES ? truncate(serialized, void 0, TOOL_RESULT_MAX_BYTES) : normalized;
|
|
1030
|
+
}
|
|
1031
|
+
formatInputForPostHog(params, privacyMode) {
|
|
1032
|
+
try {
|
|
1033
|
+
if (isPrivacyModeEnabled(this.phClient, privacyMode)) return null;
|
|
1034
|
+
const preparePart = (part) => {
|
|
1035
|
+
if (!isObject(part) || !Object.hasOwn(part, "functionResponse") || !isObject(part.functionResponse)) return part;
|
|
1036
|
+
const response = part.functionResponse;
|
|
1037
|
+
const hasParts = response.parts !== void 0;
|
|
1038
|
+
const hasResponse = Object.hasOwn(response, "response");
|
|
1039
|
+
if (!hasParts && !hasResponse) return part;
|
|
1040
|
+
const formatted = this.boundToolResult(geminiFunctionResponseContent(response));
|
|
1041
|
+
const prepared = { ...response };
|
|
1042
|
+
if (hasParts && isObject(formatted)) {
|
|
1043
|
+
if (hasResponse) prepared.response = formatted.response;
|
|
1044
|
+
prepared.parts = formatted.parts;
|
|
1045
|
+
} else {
|
|
1046
|
+
prepared.response = formatted;
|
|
1047
|
+
if (hasParts) delete prepared.parts;
|
|
1048
|
+
}
|
|
1049
|
+
return {
|
|
1050
|
+
...part,
|
|
1051
|
+
functionResponse: prepared
|
|
1052
|
+
};
|
|
1053
|
+
};
|
|
1054
|
+
const prepareContent = (content) => {
|
|
1055
|
+
const part = preparePart(content);
|
|
1056
|
+
if (!isObject(part)) return part;
|
|
1057
|
+
const originalParts = Object.hasOwn(part, "parts") ? part.parts : void 0;
|
|
1058
|
+
const originalContent = Object.hasOwn(part, "content") ? part.content : void 0;
|
|
1059
|
+
const parts = Array.isArray(originalParts) ? originalParts.map(preparePart) : void 0;
|
|
1060
|
+
const blocks = Array.isArray(originalContent) ? originalContent.map(preparePart) : void 0;
|
|
1061
|
+
const partsChanged = parts?.some((value, index) => value !== originalParts[index]);
|
|
1062
|
+
const contentChanged = blocks?.some((value, index) => value !== originalContent[index]);
|
|
1063
|
+
if (!partsChanged && !contentChanged) return part;
|
|
1064
|
+
return {
|
|
1065
|
+
...part,
|
|
1066
|
+
...partsChanged && { parts },
|
|
1067
|
+
...contentChanged && { content: blocks }
|
|
1068
|
+
};
|
|
1069
|
+
};
|
|
1070
|
+
const contents = Array.isArray(params.contents) ? params.contents.map(prepareContent) : prepareContent(params.contents);
|
|
1071
|
+
const sanitized = sanitizeGemini(contents, this.phClient);
|
|
1072
|
+
const messages = this.formatInput(sanitized);
|
|
1073
|
+
const systemInstruction = this.extractSystemInstruction(params);
|
|
1074
|
+
if (systemInstruction && !messages.some((message) => message.role === "system")) return [{
|
|
941
1075
|
role: "system",
|
|
942
1076
|
content: systemInstruction
|
|
943
1077
|
}, ...messages];
|
|
1078
|
+
return messages;
|
|
1079
|
+
} catch {
|
|
1080
|
+
return "[Unserializable]";
|
|
944
1081
|
}
|
|
945
|
-
return messages;
|
|
946
1082
|
}
|
|
947
1083
|
};
|
|
948
1084
|
/**
|