@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/openai/index.cjs
CHANGED
|
@@ -10,6 +10,9 @@ let openai_streaming = require("openai/streaming");
|
|
|
10
10
|
const isString = (value) => {
|
|
11
11
|
return typeof value === "string";
|
|
12
12
|
};
|
|
13
|
+
const isObject = (value) => {
|
|
14
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
15
|
+
};
|
|
13
16
|
//#endregion
|
|
14
17
|
//#region src/captureAiEvent.ts
|
|
15
18
|
/** @internal */
|
|
@@ -176,17 +179,26 @@ var BinaryContentRedactor = class {
|
|
|
176
179
|
this.visited = /* @__PURE__ */ new WeakSet();
|
|
177
180
|
return this.walk(value, mediaType ? new MediaTypeContext(void 0, void 0, mediaType) : MediaTypeContext.EMPTY);
|
|
178
181
|
}
|
|
182
|
+
/** Redact one leaf while a caller owns bounded, type-preserving traversal. @internal */
|
|
183
|
+
redactLeaf(value, context) {
|
|
184
|
+
return typeof value === "string" ? this.redactString(value, context) : this.placeholderFor(context.inferMediaType());
|
|
185
|
+
}
|
|
179
186
|
walk(value, ctx) {
|
|
180
187
|
if (value === null || value === void 0) return value;
|
|
181
|
-
if (typeof value === "string") return this.
|
|
188
|
+
if (typeof value === "string") return this.redactLeaf(value, ctx);
|
|
182
189
|
if (typeof value !== "object") return value;
|
|
183
|
-
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return this.
|
|
190
|
+
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return this.redactLeaf(value, ctx);
|
|
184
191
|
if (this.visited.has(value)) return null;
|
|
185
192
|
this.visited.add(value);
|
|
186
193
|
if (Array.isArray(value)) return value.map((item) => this.walk(item, ctx));
|
|
187
194
|
const obj = value;
|
|
188
195
|
const out = {};
|
|
189
|
-
for (const k of Object.keys(obj))
|
|
196
|
+
for (const k of Object.keys(obj)) Object.defineProperty(out, k, {
|
|
197
|
+
value: this.walk(obj[k], new MediaTypeContext(obj, k)),
|
|
198
|
+
enumerable: true,
|
|
199
|
+
writable: true,
|
|
200
|
+
configurable: true
|
|
201
|
+
});
|
|
190
202
|
return out;
|
|
191
203
|
}
|
|
192
204
|
redactString(value, ctx) {
|
|
@@ -208,8 +220,8 @@ var BinaryContentRedactor = class {
|
|
|
208
220
|
};
|
|
209
221
|
//#endregion
|
|
210
222
|
//#region src/sanitization.ts
|
|
211
|
-
const redactor = new BinaryContentRedactor();
|
|
212
|
-
const sanitize = (data, client) => isFullAiCaptureEnabled(client) ? data : redactor.redact(data);
|
|
223
|
+
const redactor$1 = new BinaryContentRedactor();
|
|
224
|
+
const sanitize = (data, client) => isFullAiCaptureEnabled(client) ? data : redactor$1.redact(data);
|
|
213
225
|
const sanitizeOpenAI = (data, client) => sanitize(data, client);
|
|
214
226
|
const sanitizeOpenAIResponse = (data, client) => sanitize(data, client);
|
|
215
227
|
//#endregion
|
|
@@ -232,9 +244,10 @@ function hasTokenOverrides(posthogProperties) {
|
|
|
232
244
|
function getTokensSource(posthogProperties) {
|
|
233
245
|
return hasTokenOverrides(posthogProperties) ? "passthrough" : "sdk";
|
|
234
246
|
}
|
|
247
|
+
const MAX_OUTPUT_SIZE = 2e5;
|
|
235
248
|
const STRING_FORMAT = "utf8";
|
|
236
|
-
new TextEncoder();
|
|
237
|
-
new TextDecoder(STRING_FORMAT, { fatal: false });
|
|
249
|
+
const sharedTextEncoder = new TextEncoder();
|
|
250
|
+
const sharedTextDecoder = new TextDecoder(STRING_FORMAT, { fatal: false });
|
|
238
251
|
/**
|
|
239
252
|
* Safely converts content to a string, preserving structure for objects/arrays.
|
|
240
253
|
* - If content is already a string, returns it as-is
|
|
@@ -291,14 +304,18 @@ const formatResponseOpenAI = (response) => {
|
|
|
291
304
|
type: "text",
|
|
292
305
|
text: choice.message.content
|
|
293
306
|
});
|
|
294
|
-
if (choice.message.tool_calls) for (const toolCall of choice.message.tool_calls)
|
|
295
|
-
type:
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
307
|
+
if (choice.message.tool_calls) for (const toolCall of choice.message.tool_calls) {
|
|
308
|
+
const call = toolCall.type === "custom" ? toolCall.custom : toolCall.function;
|
|
309
|
+
if (!call) continue;
|
|
310
|
+
content.push({
|
|
311
|
+
type: "function",
|
|
312
|
+
id: toolCall.id,
|
|
313
|
+
function: {
|
|
314
|
+
name: call.name,
|
|
315
|
+
arguments: toolCall.type === "custom" ? call.input : call.arguments
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
302
319
|
if (choice.message.audio) content.push({
|
|
303
320
|
type: "audio",
|
|
304
321
|
...choice.message.audio
|
|
@@ -350,8 +367,30 @@ const formatResponseOpenAI = (response) => {
|
|
|
350
367
|
}
|
|
351
368
|
return output;
|
|
352
369
|
};
|
|
370
|
+
const isPrivacyModeEnabled = (client, privacyMode) => Boolean(client.privacy_mode || privacyMode);
|
|
353
371
|
const withPrivacyMode = (client, privacyMode, input) => {
|
|
354
|
-
return client
|
|
372
|
+
return isPrivacyModeEnabled(client, privacyMode) ? null : input;
|
|
373
|
+
};
|
|
374
|
+
function toSafeString(input) {
|
|
375
|
+
if (input === void 0 || input === null) return "";
|
|
376
|
+
if (typeof input === "string") return input;
|
|
377
|
+
try {
|
|
378
|
+
return JSON.stringify(input);
|
|
379
|
+
} catch {
|
|
380
|
+
console.warn("Failed to stringify input", input);
|
|
381
|
+
return "";
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
const truncate = (input, client, maxBytes = MAX_OUTPUT_SIZE) => {
|
|
385
|
+
const str = toSafeString(input);
|
|
386
|
+
if (str === "") return "";
|
|
387
|
+
if (isFullAiCaptureEnabled(client)) return str;
|
|
388
|
+
const buffer = sharedTextEncoder.encode(str);
|
|
389
|
+
if (buffer.length <= maxBytes) return sharedTextDecoder.decode(buffer);
|
|
390
|
+
const truncatedBuffer = buffer.slice(0, maxBytes);
|
|
391
|
+
let truncatedStr = sharedTextDecoder.decode(truncatedBuffer);
|
|
392
|
+
if (truncatedStr.endsWith("�")) truncatedStr = truncatedStr.slice(0, -1);
|
|
393
|
+
return `${truncatedStr}... [truncated]`;
|
|
355
394
|
};
|
|
356
395
|
/**
|
|
357
396
|
* Calculate web search count from raw API response.
|
|
@@ -499,7 +538,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
499
538
|
}
|
|
500
539
|
//#endregion
|
|
501
540
|
//#region package.json
|
|
502
|
-
var version = "8.14.
|
|
541
|
+
var version = "8.14.3";
|
|
503
542
|
//#endregion
|
|
504
543
|
//#region src/serializeError.ts
|
|
505
544
|
const DEFAULT_MAX_DEPTH = 3;
|
|
@@ -586,7 +625,7 @@ const captureAiGeneration$1 = async (client, options) => {
|
|
|
586
625
|
const eventType = options.eventType ?? "$ai_generation";
|
|
587
626
|
const privacyMode = options.privacyMode ?? false;
|
|
588
627
|
const usage = options.usage ?? {};
|
|
589
|
-
const shouldRedact =
|
|
628
|
+
const shouldRedact = isPrivacyModeEnabled(client, privacyMode);
|
|
590
629
|
const safeInput = shouldRedact ? null : (0, _posthog_core.toJsonSafeValue)(options.input);
|
|
591
630
|
const safeOutput = shouldRedact ? null : (0, _posthog_core.toJsonSafeValue)(options.output);
|
|
592
631
|
let httpStatus = options.httpStatus;
|
|
@@ -1217,7 +1256,114 @@ var OpenAIResponsesStreamAccumulator = class {
|
|
|
1217
1256
|
}
|
|
1218
1257
|
};
|
|
1219
1258
|
//#endregion
|
|
1259
|
+
//#region src/toolResult.ts
|
|
1260
|
+
const MAX_DEPTH = 20;
|
|
1261
|
+
const MAX_ITEMS = 1e3;
|
|
1262
|
+
const MAX_NODES = 1e4;
|
|
1263
|
+
const TRUNCATED = "[Truncated]";
|
|
1264
|
+
const UNSERIALIZABLE = "[Unserializable]";
|
|
1265
|
+
const redactor = new BinaryContentRedactor();
|
|
1266
|
+
const propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
|
|
1267
|
+
/** @internal Preserve tool-result structure while bounding each string value. */
|
|
1268
|
+
function formatToolResult(content, client, maxBytes = 5e3) {
|
|
1269
|
+
try {
|
|
1270
|
+
if (isFullAiCaptureEnabled(client)) return (0, _posthog_core.toJsonSafeValue)(content);
|
|
1271
|
+
const ancestors = /* @__PURE__ */ new WeakSet();
|
|
1272
|
+
let remainingNodes = MAX_NODES;
|
|
1273
|
+
const convert = (value, depth, context) => {
|
|
1274
|
+
if (remainingNodes <= 0) return TRUNCATED;
|
|
1275
|
+
remainingNodes--;
|
|
1276
|
+
try {
|
|
1277
|
+
if (value === null || typeof value !== "object") {
|
|
1278
|
+
const safe = (0, _posthog_core.toJsonSafeValue)(value);
|
|
1279
|
+
return typeof safe === "string" ? truncate(redactor.redactLeaf(safe, context), void 0, maxBytes) : safe;
|
|
1280
|
+
}
|
|
1281
|
+
if (depth >= MAX_DEPTH) return TRUNCATED;
|
|
1282
|
+
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return redactor.redactLeaf(value, context);
|
|
1283
|
+
if (ancestors.has(value)) return "[Circular]";
|
|
1284
|
+
ancestors.add(value);
|
|
1285
|
+
try {
|
|
1286
|
+
if (value instanceof Date) {
|
|
1287
|
+
const safe = (0, _posthog_core.toJsonSafeValue)(value);
|
|
1288
|
+
return typeof safe === "string" ? truncate(redactor.redactLeaf(safe, context), void 0, maxBytes) : safe;
|
|
1289
|
+
}
|
|
1290
|
+
let hasToJSONResult = false;
|
|
1291
|
+
let toJSONResult;
|
|
1292
|
+
try {
|
|
1293
|
+
const toJSON = value.toJSON;
|
|
1294
|
+
if (typeof toJSON === "function") {
|
|
1295
|
+
toJSONResult = toJSON.call(value);
|
|
1296
|
+
hasToJSONResult = true;
|
|
1297
|
+
}
|
|
1298
|
+
} catch {}
|
|
1299
|
+
if (hasToJSONResult) return convert(toJSONResult, depth + 1, context);
|
|
1300
|
+
if (Array.isArray(value)) {
|
|
1301
|
+
const output = [];
|
|
1302
|
+
const count = Math.min(value.length, MAX_ITEMS);
|
|
1303
|
+
let index = 0;
|
|
1304
|
+
for (; index < count && remainingNodes > 0; index++) output.push(convert(value[index], depth + 1, context));
|
|
1305
|
+
if (value.length > index) output.push(TRUNCATED);
|
|
1306
|
+
return output;
|
|
1307
|
+
}
|
|
1308
|
+
const input = value;
|
|
1309
|
+
const output = {};
|
|
1310
|
+
let count = 0;
|
|
1311
|
+
let truncated = false;
|
|
1312
|
+
for (const key in input) {
|
|
1313
|
+
if (!propertyIsEnumerable.call(input, key)) break;
|
|
1314
|
+
if (count >= MAX_ITEMS || remainingNodes <= 0) {
|
|
1315
|
+
truncated = true;
|
|
1316
|
+
break;
|
|
1317
|
+
}
|
|
1318
|
+
const converted = convert(input[key], depth + 1, new MediaTypeContext(input, key));
|
|
1319
|
+
Object.defineProperty(output, key, {
|
|
1320
|
+
value: converted,
|
|
1321
|
+
enumerable: true,
|
|
1322
|
+
writable: true,
|
|
1323
|
+
configurable: true
|
|
1324
|
+
});
|
|
1325
|
+
count++;
|
|
1326
|
+
}
|
|
1327
|
+
if (truncated) output[TRUNCATED] = "Additional properties omitted";
|
|
1328
|
+
return output;
|
|
1329
|
+
} finally {
|
|
1330
|
+
ancestors.delete(value);
|
|
1331
|
+
}
|
|
1332
|
+
} catch {
|
|
1333
|
+
return UNSERIALIZABLE;
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
return convert(content, 0, MediaTypeContext.EMPTY);
|
|
1337
|
+
} catch {
|
|
1338
|
+
return UNSERIALIZABLE;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
//#endregion
|
|
1220
1342
|
//#region src/openai/telemetry.ts
|
|
1343
|
+
const RESPONSE_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
|
|
1344
|
+
"function_call_output",
|
|
1345
|
+
"custom_tool_call_output",
|
|
1346
|
+
"computer_call_output",
|
|
1347
|
+
"local_shell_call_output",
|
|
1348
|
+
"shell_call_output",
|
|
1349
|
+
"apply_patch_call_output",
|
|
1350
|
+
"mcp_call"
|
|
1351
|
+
]);
|
|
1352
|
+
function buildSanitizedChatInput(context) {
|
|
1353
|
+
try {
|
|
1354
|
+
if (isPrivacyModeEnabled(context.client, context.monitoring.privacyMode)) return null;
|
|
1355
|
+
const messages = context.params.messages.map((message) => {
|
|
1356
|
+
if ((message.role === "tool" || message.role === "function") && Object.hasOwn(message, "content")) return {
|
|
1357
|
+
...message,
|
|
1358
|
+
content: formatToolResult(message.content, context.client, Infinity)
|
|
1359
|
+
};
|
|
1360
|
+
return message;
|
|
1361
|
+
});
|
|
1362
|
+
return sanitizeOpenAI(messages, context.client);
|
|
1363
|
+
} catch {
|
|
1364
|
+
return "[Unserializable]";
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1221
1367
|
function captureAiGenerationInBackground(...args) {
|
|
1222
1368
|
captureAiGeneration(...args).catch(() => void 0);
|
|
1223
1369
|
}
|
|
@@ -1253,7 +1399,7 @@ function buildChatSuccessOptions(context, result) {
|
|
|
1253
1399
|
...context.monitoring,
|
|
1254
1400
|
model: context.params.model ?? result.model,
|
|
1255
1401
|
provider: context.provider,
|
|
1256
|
-
input:
|
|
1402
|
+
input: buildSanitizedChatInput(context),
|
|
1257
1403
|
output: sanitizeOpenAIResponse(result.output, context.client),
|
|
1258
1404
|
latency: result.latency,
|
|
1259
1405
|
timeToFirstToken: result.timeToFirstToken,
|
|
@@ -1276,7 +1422,7 @@ function buildChatErrorOptions(context, error, metadata) {
|
|
|
1276
1422
|
...context.monitoring,
|
|
1277
1423
|
model: context.params.model,
|
|
1278
1424
|
provider: context.provider,
|
|
1279
|
-
input:
|
|
1425
|
+
input: buildSanitizedChatInput(context),
|
|
1280
1426
|
output: [],
|
|
1281
1427
|
latency: metadata.latency,
|
|
1282
1428
|
baseURL: context.baseURL,
|
|
@@ -1288,7 +1434,21 @@ function buildChatErrorOptions(context, error, metadata) {
|
|
|
1288
1434
|
};
|
|
1289
1435
|
}
|
|
1290
1436
|
function buildSanitizedResponsesInput(context) {
|
|
1291
|
-
|
|
1437
|
+
try {
|
|
1438
|
+
if (isPrivacyModeEnabled(context.client, context.monitoring.privacyMode)) return null;
|
|
1439
|
+
const input = Array.isArray(context.params.input) ? context.params.input.map((item) => {
|
|
1440
|
+
if (!isObject(item) || typeof item.type !== "string") return item;
|
|
1441
|
+
const key = RESPONSE_TOOL_RESULT_TYPES.has(item.type) ? "output" : item.type === "code_interpreter_call" ? "outputs" : item.type === "file_search_call" ? "results" : void 0;
|
|
1442
|
+
if (!key || !Object.hasOwn(item, key)) return item;
|
|
1443
|
+
return {
|
|
1444
|
+
...item,
|
|
1445
|
+
[key]: formatToolResult(item[key], context.client, Infinity)
|
|
1446
|
+
};
|
|
1447
|
+
}) : context.params.input;
|
|
1448
|
+
return formatOpenAIResponsesInput(sanitizeOpenAIResponse(input, context.client), sanitizeOpenAIResponse(context.params.instructions, context.client));
|
|
1449
|
+
} catch {
|
|
1450
|
+
return "[Unserializable]";
|
|
1451
|
+
}
|
|
1292
1452
|
}
|
|
1293
1453
|
function buildResponsesSuccessOptions(context, result) {
|
|
1294
1454
|
const response = result.response;
|