@posthog/ai 8.2.3 → 8.3.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.
@@ -299,7 +299,7 @@ function addDefaults(params) {
299
299
  };
300
300
  }
301
301
 
302
- var version = "8.2.3";
302
+ var version = "8.3.0";
303
303
 
304
304
  const DEFAULT_MAX_DEPTH = 3;
305
305
  const MAX_STACK_LINES = 20;
@@ -291,7 +291,7 @@ function addDefaults(params) {
291
291
  };
292
292
  }
293
293
 
294
- var version = "8.2.3";
294
+ var version = "8.3.0";
295
295
 
296
296
  const DEFAULT_MAX_DEPTH = 3;
297
297
  const MAX_STACK_LINES = 20;
@@ -384,7 +384,7 @@ function addDefaults(params) {
384
384
  };
385
385
  }
386
386
 
387
- var version = "8.2.3";
387
+ var version = "8.3.0";
388
388
 
389
389
  const DEFAULT_MAX_DEPTH = 3;
390
390
  const MAX_STACK_LINES = 20;
@@ -380,7 +380,7 @@ function addDefaults(params) {
380
380
  };
381
381
  }
382
382
 
383
- var version = "8.2.3";
383
+ var version = "8.3.0";
384
384
 
385
385
  const DEFAULT_MAX_DEPTH = 3;
386
386
  const MAX_STACK_LINES = 20;
package/dist/index.cjs CHANGED
@@ -380,7 +380,7 @@ function sanitizeValues(obj) {
380
380
  return jsonSafe;
381
381
  }
382
382
 
383
- var version = "8.2.3";
383
+ var version = "8.3.0";
384
384
 
385
385
  const DEFAULT_MAX_DEPTH = 3;
386
386
  const MAX_STACK_LINES = 20;
package/dist/index.mjs CHANGED
@@ -378,7 +378,7 @@ function sanitizeValues(obj) {
378
378
  return jsonSafe;
379
379
  }
380
380
 
381
- var version = "8.2.3";
381
+ var version = "8.3.0";
382
382
 
383
383
  const DEFAULT_MAX_DEPTH = 3;
384
384
  const MAX_STACK_LINES = 20;
@@ -217,7 +217,7 @@ function sanitizeValues(obj) {
217
217
  return jsonSafe;
218
218
  }
219
219
 
220
- var version = "8.2.3";
220
+ var version = "8.3.0";
221
221
 
222
222
  const DEFAULT_MAX_DEPTH = 3;
223
223
  const MAX_STACK_LINES = 20;
@@ -215,7 +215,7 @@ function sanitizeValues(obj) {
215
215
  return jsonSafe;
216
216
  }
217
217
 
218
- var version = "8.2.3";
218
+ var version = "8.3.0";
219
219
 
220
220
  const DEFAULT_MAX_DEPTH = 3;
221
221
  const MAX_STACK_LINES = 20;
@@ -534,7 +534,7 @@ function formatOpenAIResponsesInput(input, instructions) {
534
534
  return messages;
535
535
  }
536
536
 
537
- var version = "8.2.3";
537
+ var version = "8.3.0";
538
538
 
539
539
  const DEFAULT_MAX_DEPTH = 3;
540
540
  const MAX_STACK_LINES = 20;
@@ -530,7 +530,7 @@ function formatOpenAIResponsesInput(input, instructions) {
530
530
  return messages;
531
531
  }
532
532
 
533
- var version = "8.2.3";
533
+ var version = "8.3.0";
534
534
 
535
535
  const DEFAULT_MAX_DEPTH = 3;
536
536
  const MAX_STACK_LINES = 20;
@@ -76,6 +76,33 @@ const sharedTextEncoder = new TextEncoder();
76
76
  const sharedTextDecoder = new TextDecoder(STRING_FORMAT, {
77
77
  fatal: false
78
78
  });
79
+ const utf8ByteLength = str => sharedTextEncoder.encode(str).byteLength;
80
+
81
+ /**
82
+ * Safely converts content to a string, preserving structure for objects/arrays.
83
+ * - If content is already a string, returns it as-is
84
+ * - If content is an object or array, stringifies it with JSON.stringify to preserve structure
85
+ * - Otherwise, converts to string with String()
86
+ *
87
+ * This prevents the "[object Object]" bug when objects are naively converted to strings.
88
+ *
89
+ * @param content - The content to convert to a string
90
+ * @returns A string representation that preserves structure for complex types
91
+ */
92
+ function toContentString(content) {
93
+ if (typeof content === 'string') {
94
+ return content;
95
+ }
96
+ if (content !== undefined && content !== null && typeof content === 'object') {
97
+ try {
98
+ return JSON.stringify(content);
99
+ } catch {
100
+ // Fallback for circular refs, BigInt, or objects with throwing toJSON
101
+ return String(content);
102
+ }
103
+ }
104
+ return String(content);
105
+ }
79
106
  const withPrivacyMode = (client, privacyMode, input) => {
80
107
  return client.privacy_mode || privacyMode ? null : input;
81
108
  };
@@ -116,7 +143,7 @@ const truncate = input => {
116
143
  return `${truncatedStr}... [truncated]`;
117
144
  };
118
145
 
119
- var version = "8.2.3";
146
+ var version = "8.3.0";
120
147
 
121
148
  // Warn when a wrapper's base_url points at the PostHog AI Gateway: the gateway
122
149
  // emits its own $ai_generation, so each call would be captured (and, for billable
@@ -183,38 +210,46 @@ function normalizeInputRoles(input) {
183
210
  return item;
184
211
  });
185
212
  }
213
+ function safeContentString(value) {
214
+ try {
215
+ return toContentString(value);
216
+ } catch {
217
+ return Object.prototype.toString.call(value);
218
+ }
219
+ }
186
220
  function ensureSerializable(obj) {
187
221
  if (obj === null || obj === undefined) {
188
222
  return obj;
189
223
  }
190
224
  try {
191
- JSON.stringify(obj);
192
- return obj;
225
+ const serializedValue = JSON.stringify(obj);
226
+ return serializedValue === undefined ? safeContentString(obj) : obj;
193
227
  } catch {
194
- return String(obj);
228
+ return safeContentString(obj);
195
229
  }
196
230
  }
197
- function exceedsMaxOutputSize(value) {
231
+ function stringifyForSizeCheck(value) {
198
232
  if (value === null || value === undefined) {
199
- return false;
233
+ return null;
234
+ }
235
+ if (typeof value === 'string') {
236
+ return value;
200
237
  }
201
238
  try {
202
- const serializedValue = typeof value === 'string' ? value : JSON.stringify(value);
203
- return new TextEncoder().encode(serializedValue).length > MAX_OUTPUT_SIZE;
239
+ return JSON.stringify(value) ?? safeContentString(value);
204
240
  } catch {
205
- return false;
241
+ return safeContentString(value);
206
242
  }
207
243
  }
244
+ function exceedsMaxOutputSize(serializedValue) {
245
+ return serializedValue === null ? false : utf8ByteLength(serializedValue) > MAX_OUTPUT_SIZE;
246
+ }
208
247
  function parseIsoTimestamp(isoStr) {
209
- if (!isoStr) {
210
- return null;
211
- }
212
- try {
213
- const ts = new Date(isoStr).getTime();
214
- return isNaN(ts) ? null : ts / 1000;
215
- } catch {
248
+ if (typeof isoStr !== 'string' || isoStr.trim() === '') {
216
249
  return null;
217
250
  }
251
+ const ts = new Date(isoStr).getTime();
252
+ return Number.isFinite(ts) ? ts / 1000 : null;
218
253
  }
219
254
  /**
220
255
  * A tracing processor that sends OpenAI Agents SDK traces to PostHog.
@@ -244,6 +279,7 @@ class PostHogTracingProcessor {
244
279
  this._privacyMode = options.privacyMode ?? false;
245
280
  this._groups = options.groups ?? {};
246
281
  this._properties = options.properties ?? {};
282
+ this._onError = options.onError;
247
283
  }
248
284
  _getDistinctId(trace) {
249
285
  if (typeof this._distinctId === 'function') {
@@ -264,7 +300,8 @@ class PostHogTracingProcessor {
264
300
  }
265
301
  _prepareCapturedValue(value) {
266
302
  const serializableValue = ensureSerializable(value);
267
- const boundedValue = exceedsMaxOutputSize(serializableValue) ? truncate(serializableValue) : serializableValue;
303
+ const serializedValue = stringifyForSizeCheck(serializableValue);
304
+ const boundedValue = exceedsMaxOutputSize(serializedValue) ? truncate(serializedValue) : serializableValue;
268
305
  return this._withPrivacyMode(boundedValue);
269
306
  }
270
307
  _evictStaleEntries() {
@@ -283,6 +320,12 @@ class PostHogTracingProcessor {
283
320
  }
284
321
  }
285
322
  }
323
+ _handleError(error, context) {
324
+ try {
325
+ this._onError?.(error, context);
326
+ } catch (handlerError) {
327
+ }
328
+ }
286
329
  _captureEvent(event, properties, distinctId) {
287
330
  try {
288
331
  if (!this._client?.capture) {
@@ -299,8 +342,8 @@ class PostHogTracingProcessor {
299
342
  groups: Object.keys(this._groups).length > 0 ? this._groups : undefined
300
343
  };
301
344
  this._client.capture(eventMessage);
302
- } catch {
303
- // Silently ignore capture errors
345
+ } catch (error) {
346
+ this._handleError(error, 'capture');
304
347
  }
305
348
  }
306
349
  _baseProperties(traceId, spanId, parentId, latency, groupId, errorProperties) {
@@ -361,8 +404,8 @@ class PostHogTracingProcessor {
361
404
  distinctId,
362
405
  startTime: Date.now() / 1000
363
406
  });
364
- } catch {
365
- // Silently ignore errors
407
+ } catch (error) {
408
+ this._handleError(error, 'onTraceStart');
366
409
  }
367
410
  }
368
411
  async onTraceEnd(trace) {
@@ -397,16 +440,16 @@ class PostHogTracingProcessor {
397
440
  properties.$process_person_profile = false;
398
441
  }
399
442
  this._captureEvent('$ai_trace', properties, distinctId ?? traceId);
400
- } catch {
401
- // Silently ignore errors
443
+ } catch (error) {
444
+ this._handleError(error, 'onTraceEnd');
402
445
  }
403
446
  }
404
447
  async onSpanStart(span) {
405
448
  try {
406
449
  this._evictStaleEntries();
407
450
  this._spanStartTimes.set(span.spanId, Date.now() / 1000);
408
- } catch {
409
- // Silently ignore errors
451
+ } catch (error) {
452
+ this._handleError(error, 'onSpanStart');
410
453
  }
411
454
  }
412
455
  async onSpanEnd(span) {
@@ -479,8 +522,8 @@ class PostHogTracingProcessor {
479
522
  this._handleGenericSpan(spanData, traceId, spanId, parentId, latency, distinctId, groupId, errorProperties);
480
523
  break;
481
524
  }
482
- } catch {
483
- // Silently ignore errors
525
+ } catch (error) {
526
+ this._handleError(error, 'onSpanEnd');
484
527
  }
485
528
  }
486
529
  async shutdown() {
@@ -490,8 +533,8 @@ class PostHogTracingProcessor {
490
533
  if (typeof this._client?.flush === 'function') {
491
534
  await this._client.flush();
492
535
  }
493
- } catch {
494
- // Silently ignore errors
536
+ } catch (error) {
537
+ this._handleError(error, 'shutdown');
495
538
  }
496
539
  }
497
540
  async forceFlush() {
@@ -499,8 +542,8 @@ class PostHogTracingProcessor {
499
542
  if (typeof this._client?.flush === 'function') {
500
543
  await this._client.flush();
501
544
  }
502
- } catch {
503
- // Silently ignore errors
545
+ } catch (error) {
546
+ this._handleError(error, 'forceFlush');
504
547
  }
505
548
  }
506
549