@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.mjs
CHANGED
|
@@ -6,6 +6,9 @@ import { Stream } from "openai/streaming";
|
|
|
6
6
|
const isString = (value) => {
|
|
7
7
|
return typeof value === "string";
|
|
8
8
|
};
|
|
9
|
+
const isObject = (value) => {
|
|
10
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
11
|
+
};
|
|
9
12
|
//#endregion
|
|
10
13
|
//#region src/captureAiEvent.ts
|
|
11
14
|
/** @internal */
|
|
@@ -172,17 +175,26 @@ var BinaryContentRedactor = class {
|
|
|
172
175
|
this.visited = /* @__PURE__ */ new WeakSet();
|
|
173
176
|
return this.walk(value, mediaType ? new MediaTypeContext(void 0, void 0, mediaType) : MediaTypeContext.EMPTY);
|
|
174
177
|
}
|
|
178
|
+
/** Redact one leaf while a caller owns bounded, type-preserving traversal. @internal */
|
|
179
|
+
redactLeaf(value, context) {
|
|
180
|
+
return typeof value === "string" ? this.redactString(value, context) : this.placeholderFor(context.inferMediaType());
|
|
181
|
+
}
|
|
175
182
|
walk(value, ctx) {
|
|
176
183
|
if (value === null || value === void 0) return value;
|
|
177
|
-
if (typeof value === "string") return this.
|
|
184
|
+
if (typeof value === "string") return this.redactLeaf(value, ctx);
|
|
178
185
|
if (typeof value !== "object") return value;
|
|
179
|
-
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return this.
|
|
186
|
+
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return this.redactLeaf(value, ctx);
|
|
180
187
|
if (this.visited.has(value)) return null;
|
|
181
188
|
this.visited.add(value);
|
|
182
189
|
if (Array.isArray(value)) return value.map((item) => this.walk(item, ctx));
|
|
183
190
|
const obj = value;
|
|
184
191
|
const out = {};
|
|
185
|
-
for (const k of Object.keys(obj))
|
|
192
|
+
for (const k of Object.keys(obj)) Object.defineProperty(out, k, {
|
|
193
|
+
value: this.walk(obj[k], new MediaTypeContext(obj, k)),
|
|
194
|
+
enumerable: true,
|
|
195
|
+
writable: true,
|
|
196
|
+
configurable: true
|
|
197
|
+
});
|
|
186
198
|
return out;
|
|
187
199
|
}
|
|
188
200
|
redactString(value, ctx) {
|
|
@@ -204,8 +216,8 @@ var BinaryContentRedactor = class {
|
|
|
204
216
|
};
|
|
205
217
|
//#endregion
|
|
206
218
|
//#region src/sanitization.ts
|
|
207
|
-
const redactor = new BinaryContentRedactor();
|
|
208
|
-
const sanitize = (data, client) => isFullAiCaptureEnabled(client) ? data : redactor.redact(data);
|
|
219
|
+
const redactor$1 = new BinaryContentRedactor();
|
|
220
|
+
const sanitize = (data, client) => isFullAiCaptureEnabled(client) ? data : redactor$1.redact(data);
|
|
209
221
|
const sanitizeOpenAI = (data, client) => sanitize(data, client);
|
|
210
222
|
const sanitizeOpenAIResponse = (data, client) => sanitize(data, client);
|
|
211
223
|
//#endregion
|
|
@@ -228,9 +240,10 @@ function hasTokenOverrides(posthogProperties) {
|
|
|
228
240
|
function getTokensSource(posthogProperties) {
|
|
229
241
|
return hasTokenOverrides(posthogProperties) ? "passthrough" : "sdk";
|
|
230
242
|
}
|
|
243
|
+
const MAX_OUTPUT_SIZE = 2e5;
|
|
231
244
|
const STRING_FORMAT = "utf8";
|
|
232
|
-
new TextEncoder();
|
|
233
|
-
new TextDecoder(STRING_FORMAT, { fatal: false });
|
|
245
|
+
const sharedTextEncoder = new TextEncoder();
|
|
246
|
+
const sharedTextDecoder = new TextDecoder(STRING_FORMAT, { fatal: false });
|
|
234
247
|
/**
|
|
235
248
|
* Safely converts content to a string, preserving structure for objects/arrays.
|
|
236
249
|
* - If content is already a string, returns it as-is
|
|
@@ -287,14 +300,18 @@ const formatResponseOpenAI = (response) => {
|
|
|
287
300
|
type: "text",
|
|
288
301
|
text: choice.message.content
|
|
289
302
|
});
|
|
290
|
-
if (choice.message.tool_calls) for (const toolCall of choice.message.tool_calls)
|
|
291
|
-
type:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
303
|
+
if (choice.message.tool_calls) for (const toolCall of choice.message.tool_calls) {
|
|
304
|
+
const call = toolCall.type === "custom" ? toolCall.custom : toolCall.function;
|
|
305
|
+
if (!call) continue;
|
|
306
|
+
content.push({
|
|
307
|
+
type: "function",
|
|
308
|
+
id: toolCall.id,
|
|
309
|
+
function: {
|
|
310
|
+
name: call.name,
|
|
311
|
+
arguments: toolCall.type === "custom" ? call.input : call.arguments
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
}
|
|
298
315
|
if (choice.message.audio) content.push({
|
|
299
316
|
type: "audio",
|
|
300
317
|
...choice.message.audio
|
|
@@ -346,8 +363,30 @@ const formatResponseOpenAI = (response) => {
|
|
|
346
363
|
}
|
|
347
364
|
return output;
|
|
348
365
|
};
|
|
366
|
+
const isPrivacyModeEnabled = (client, privacyMode) => Boolean(client.privacy_mode || privacyMode);
|
|
349
367
|
const withPrivacyMode = (client, privacyMode, input) => {
|
|
350
|
-
return client
|
|
368
|
+
return isPrivacyModeEnabled(client, privacyMode) ? null : input;
|
|
369
|
+
};
|
|
370
|
+
function toSafeString(input) {
|
|
371
|
+
if (input === void 0 || input === null) return "";
|
|
372
|
+
if (typeof input === "string") return input;
|
|
373
|
+
try {
|
|
374
|
+
return JSON.stringify(input);
|
|
375
|
+
} catch {
|
|
376
|
+
console.warn("Failed to stringify input", input);
|
|
377
|
+
return "";
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
const truncate = (input, client, maxBytes = MAX_OUTPUT_SIZE) => {
|
|
381
|
+
const str = toSafeString(input);
|
|
382
|
+
if (str === "") return "";
|
|
383
|
+
if (isFullAiCaptureEnabled(client)) return str;
|
|
384
|
+
const buffer = sharedTextEncoder.encode(str);
|
|
385
|
+
if (buffer.length <= maxBytes) return sharedTextDecoder.decode(buffer);
|
|
386
|
+
const truncatedBuffer = buffer.slice(0, maxBytes);
|
|
387
|
+
let truncatedStr = sharedTextDecoder.decode(truncatedBuffer);
|
|
388
|
+
if (truncatedStr.endsWith("�")) truncatedStr = truncatedStr.slice(0, -1);
|
|
389
|
+
return `${truncatedStr}... [truncated]`;
|
|
351
390
|
};
|
|
352
391
|
/**
|
|
353
392
|
* Calculate web search count from raw API response.
|
|
@@ -495,7 +534,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
495
534
|
}
|
|
496
535
|
//#endregion
|
|
497
536
|
//#region package.json
|
|
498
|
-
var version = "8.14.
|
|
537
|
+
var version = "8.14.3";
|
|
499
538
|
//#endregion
|
|
500
539
|
//#region src/serializeError.ts
|
|
501
540
|
const DEFAULT_MAX_DEPTH = 3;
|
|
@@ -582,7 +621,7 @@ const captureAiGeneration$1 = async (client, options) => {
|
|
|
582
621
|
const eventType = options.eventType ?? "$ai_generation";
|
|
583
622
|
const privacyMode = options.privacyMode ?? false;
|
|
584
623
|
const usage = options.usage ?? {};
|
|
585
|
-
const shouldRedact =
|
|
624
|
+
const shouldRedact = isPrivacyModeEnabled(client, privacyMode);
|
|
586
625
|
const safeInput = shouldRedact ? null : toJsonSafeValue(options.input);
|
|
587
626
|
const safeOutput = shouldRedact ? null : toJsonSafeValue(options.output);
|
|
588
627
|
let httpStatus = options.httpStatus;
|
|
@@ -1213,7 +1252,114 @@ var OpenAIResponsesStreamAccumulator = class {
|
|
|
1213
1252
|
}
|
|
1214
1253
|
};
|
|
1215
1254
|
//#endregion
|
|
1255
|
+
//#region src/toolResult.ts
|
|
1256
|
+
const MAX_DEPTH = 20;
|
|
1257
|
+
const MAX_ITEMS = 1e3;
|
|
1258
|
+
const MAX_NODES = 1e4;
|
|
1259
|
+
const TRUNCATED = "[Truncated]";
|
|
1260
|
+
const UNSERIALIZABLE = "[Unserializable]";
|
|
1261
|
+
const redactor = new BinaryContentRedactor();
|
|
1262
|
+
const propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
|
|
1263
|
+
/** @internal Preserve tool-result structure while bounding each string value. */
|
|
1264
|
+
function formatToolResult(content, client, maxBytes = 5e3) {
|
|
1265
|
+
try {
|
|
1266
|
+
if (isFullAiCaptureEnabled(client)) return toJsonSafeValue(content);
|
|
1267
|
+
const ancestors = /* @__PURE__ */ new WeakSet();
|
|
1268
|
+
let remainingNodes = MAX_NODES;
|
|
1269
|
+
const convert = (value, depth, context) => {
|
|
1270
|
+
if (remainingNodes <= 0) return TRUNCATED;
|
|
1271
|
+
remainingNodes--;
|
|
1272
|
+
try {
|
|
1273
|
+
if (value === null || typeof value !== "object") {
|
|
1274
|
+
const safe = toJsonSafeValue(value);
|
|
1275
|
+
return typeof safe === "string" ? truncate(redactor.redactLeaf(safe, context), void 0, maxBytes) : safe;
|
|
1276
|
+
}
|
|
1277
|
+
if (depth >= MAX_DEPTH) return TRUNCATED;
|
|
1278
|
+
if (typeof Uint8Array !== "undefined" && value instanceof Uint8Array) return redactor.redactLeaf(value, context);
|
|
1279
|
+
if (ancestors.has(value)) return "[Circular]";
|
|
1280
|
+
ancestors.add(value);
|
|
1281
|
+
try {
|
|
1282
|
+
if (value instanceof Date) {
|
|
1283
|
+
const safe = toJsonSafeValue(value);
|
|
1284
|
+
return typeof safe === "string" ? truncate(redactor.redactLeaf(safe, context), void 0, maxBytes) : safe;
|
|
1285
|
+
}
|
|
1286
|
+
let hasToJSONResult = false;
|
|
1287
|
+
let toJSONResult;
|
|
1288
|
+
try {
|
|
1289
|
+
const toJSON = value.toJSON;
|
|
1290
|
+
if (typeof toJSON === "function") {
|
|
1291
|
+
toJSONResult = toJSON.call(value);
|
|
1292
|
+
hasToJSONResult = true;
|
|
1293
|
+
}
|
|
1294
|
+
} catch {}
|
|
1295
|
+
if (hasToJSONResult) return convert(toJSONResult, depth + 1, context);
|
|
1296
|
+
if (Array.isArray(value)) {
|
|
1297
|
+
const output = [];
|
|
1298
|
+
const count = Math.min(value.length, MAX_ITEMS);
|
|
1299
|
+
let index = 0;
|
|
1300
|
+
for (; index < count && remainingNodes > 0; index++) output.push(convert(value[index], depth + 1, context));
|
|
1301
|
+
if (value.length > index) output.push(TRUNCATED);
|
|
1302
|
+
return output;
|
|
1303
|
+
}
|
|
1304
|
+
const input = value;
|
|
1305
|
+
const output = {};
|
|
1306
|
+
let count = 0;
|
|
1307
|
+
let truncated = false;
|
|
1308
|
+
for (const key in input) {
|
|
1309
|
+
if (!propertyIsEnumerable.call(input, key)) break;
|
|
1310
|
+
if (count >= MAX_ITEMS || remainingNodes <= 0) {
|
|
1311
|
+
truncated = true;
|
|
1312
|
+
break;
|
|
1313
|
+
}
|
|
1314
|
+
const converted = convert(input[key], depth + 1, new MediaTypeContext(input, key));
|
|
1315
|
+
Object.defineProperty(output, key, {
|
|
1316
|
+
value: converted,
|
|
1317
|
+
enumerable: true,
|
|
1318
|
+
writable: true,
|
|
1319
|
+
configurable: true
|
|
1320
|
+
});
|
|
1321
|
+
count++;
|
|
1322
|
+
}
|
|
1323
|
+
if (truncated) output[TRUNCATED] = "Additional properties omitted";
|
|
1324
|
+
return output;
|
|
1325
|
+
} finally {
|
|
1326
|
+
ancestors.delete(value);
|
|
1327
|
+
}
|
|
1328
|
+
} catch {
|
|
1329
|
+
return UNSERIALIZABLE;
|
|
1330
|
+
}
|
|
1331
|
+
};
|
|
1332
|
+
return convert(content, 0, MediaTypeContext.EMPTY);
|
|
1333
|
+
} catch {
|
|
1334
|
+
return UNSERIALIZABLE;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
//#endregion
|
|
1216
1338
|
//#region src/openai/telemetry.ts
|
|
1339
|
+
const RESPONSE_TOOL_RESULT_TYPES = /* @__PURE__ */ new Set([
|
|
1340
|
+
"function_call_output",
|
|
1341
|
+
"custom_tool_call_output",
|
|
1342
|
+
"computer_call_output",
|
|
1343
|
+
"local_shell_call_output",
|
|
1344
|
+
"shell_call_output",
|
|
1345
|
+
"apply_patch_call_output",
|
|
1346
|
+
"mcp_call"
|
|
1347
|
+
]);
|
|
1348
|
+
function buildSanitizedChatInput(context) {
|
|
1349
|
+
try {
|
|
1350
|
+
if (isPrivacyModeEnabled(context.client, context.monitoring.privacyMode)) return null;
|
|
1351
|
+
const messages = context.params.messages.map((message) => {
|
|
1352
|
+
if ((message.role === "tool" || message.role === "function") && Object.hasOwn(message, "content")) return {
|
|
1353
|
+
...message,
|
|
1354
|
+
content: formatToolResult(message.content, context.client, Infinity)
|
|
1355
|
+
};
|
|
1356
|
+
return message;
|
|
1357
|
+
});
|
|
1358
|
+
return sanitizeOpenAI(messages, context.client);
|
|
1359
|
+
} catch {
|
|
1360
|
+
return "[Unserializable]";
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1217
1363
|
function captureAiGenerationInBackground(...args) {
|
|
1218
1364
|
captureAiGeneration(...args).catch(() => void 0);
|
|
1219
1365
|
}
|
|
@@ -1249,7 +1395,7 @@ function buildChatSuccessOptions(context, result) {
|
|
|
1249
1395
|
...context.monitoring,
|
|
1250
1396
|
model: context.params.model ?? result.model,
|
|
1251
1397
|
provider: context.provider,
|
|
1252
|
-
input:
|
|
1398
|
+
input: buildSanitizedChatInput(context),
|
|
1253
1399
|
output: sanitizeOpenAIResponse(result.output, context.client),
|
|
1254
1400
|
latency: result.latency,
|
|
1255
1401
|
timeToFirstToken: result.timeToFirstToken,
|
|
@@ -1272,7 +1418,7 @@ function buildChatErrorOptions(context, error, metadata) {
|
|
|
1272
1418
|
...context.monitoring,
|
|
1273
1419
|
model: context.params.model,
|
|
1274
1420
|
provider: context.provider,
|
|
1275
|
-
input:
|
|
1421
|
+
input: buildSanitizedChatInput(context),
|
|
1276
1422
|
output: [],
|
|
1277
1423
|
latency: metadata.latency,
|
|
1278
1424
|
baseURL: context.baseURL,
|
|
@@ -1284,7 +1430,21 @@ function buildChatErrorOptions(context, error, metadata) {
|
|
|
1284
1430
|
};
|
|
1285
1431
|
}
|
|
1286
1432
|
function buildSanitizedResponsesInput(context) {
|
|
1287
|
-
|
|
1433
|
+
try {
|
|
1434
|
+
if (isPrivacyModeEnabled(context.client, context.monitoring.privacyMode)) return null;
|
|
1435
|
+
const input = Array.isArray(context.params.input) ? context.params.input.map((item) => {
|
|
1436
|
+
if (!isObject(item) || typeof item.type !== "string") return item;
|
|
1437
|
+
const key = RESPONSE_TOOL_RESULT_TYPES.has(item.type) ? "output" : item.type === "code_interpreter_call" ? "outputs" : item.type === "file_search_call" ? "results" : void 0;
|
|
1438
|
+
if (!key || !Object.hasOwn(item, key)) return item;
|
|
1439
|
+
return {
|
|
1440
|
+
...item,
|
|
1441
|
+
[key]: formatToolResult(item[key], context.client, Infinity)
|
|
1442
|
+
};
|
|
1443
|
+
}) : context.params.input;
|
|
1444
|
+
return formatOpenAIResponsesInput(sanitizeOpenAIResponse(input, context.client), sanitizeOpenAIResponse(context.params.instructions, context.client));
|
|
1445
|
+
} catch {
|
|
1446
|
+
return "[Unserializable]";
|
|
1447
|
+
}
|
|
1288
1448
|
}
|
|
1289
1449
|
function buildResponsesSuccessOptions(context, result) {
|
|
1290
1450
|
const response = result.response;
|