@posthog/ai 7.17.0 → 7.17.2

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/index.mjs CHANGED
@@ -242,6 +242,13 @@ function getTokensSource(posthogProperties) {
242
242
  // limit large outputs by truncating to 200kb (approx 200k bytes)
243
243
  const MAX_OUTPUT_SIZE = 200000;
244
244
  const STRING_FORMAT = 'utf8';
245
+ // Reused across calls to avoid per-invocation allocation; truncate() runs
246
+ // hundreds of times for prompts with many parts.
247
+ const sharedTextEncoder = new TextEncoder();
248
+ const sharedTextDecoder = new TextDecoder(STRING_FORMAT, {
249
+ fatal: false
250
+ });
251
+ const utf8ByteLength = str => sharedTextEncoder.encode(str).byteLength;
245
252
  /**
246
253
  * Safely converts content to a string, preserving structure for objects/arrays.
247
254
  * - If content is already a string, returns it as-is
@@ -512,19 +519,15 @@ const truncate = input => {
512
519
  return '';
513
520
  }
514
521
  // Check if we need to truncate and ensure STRING_FORMAT is respected
515
- const encoder = new TextEncoder();
516
- const buffer = encoder.encode(str);
522
+ const buffer = sharedTextEncoder.encode(str);
517
523
  if (buffer.length <= MAX_OUTPUT_SIZE) {
518
524
  // Ensure STRING_FORMAT is respected
519
- return new TextDecoder(STRING_FORMAT).decode(buffer);
525
+ return sharedTextDecoder.decode(buffer);
520
526
  }
521
- // Truncate the buffer and ensure a valid string is returned
527
+ // Truncate the buffer and ensure a valid string is returned.
528
+ // fatal: false means we get U+FFFD at the end if truncation broke the encoding.
522
529
  const truncatedBuffer = buffer.slice(0, MAX_OUTPUT_SIZE);
523
- // fatal: false means we get U+FFFD at the end if truncation broke the encoding
524
- const decoder = new TextDecoder(STRING_FORMAT, {
525
- fatal: false
526
- });
527
- let truncatedStr = decoder.decode(truncatedBuffer);
530
+ let truncatedStr = sharedTextDecoder.decode(truncatedBuffer);
528
531
  if (truncatedStr.endsWith('\uFFFD')) {
529
532
  truncatedStr = truncatedStr.slice(0, -1);
530
533
  }
@@ -753,7 +756,7 @@ function formatOpenAIResponsesInput(input, instructions) {
753
756
  return messages;
754
757
  }
755
758
 
756
- var version = "7.17.0";
759
+ var version = "7.17.2";
757
760
 
758
761
  /**
759
762
  * Capture an `$ai_generation` (or `$ai_embedding`) event to PostHog.
@@ -2111,18 +2114,26 @@ const mapVercelPrompt = messages => {
2111
2114
  };
2112
2115
  });
2113
2116
  try {
2114
- // Trim the inputs array until its JSON size fits within MAX_OUTPUT_SIZE
2115
- const encoder = new TextEncoder();
2116
- let serialized = JSON.stringify(inputs);
2117
+ // Trim the inputs array until its serialized JSON size fits within MAX_OUTPUT_SIZE.
2118
+ // Pre-compute each message's byte size once so we can shift by accumulated budget
2119
+ // in a single linear pass, instead of re-stringifying the whole array per iteration.
2120
+ const messageSizes = inputs.map(m => utf8ByteLength(JSON.stringify(m)));
2121
+ // Account for the surrounding `[` `]` plus a comma between each pair of elements.
2122
+ let totalBytes = 2 + Math.max(0, messageSizes.length - 1);
2123
+ for (const size of messageSizes) {
2124
+ totalBytes += size;
2125
+ }
2117
2126
  let removedCount = 0;
2118
- // We need to keep track of the initial size of the inputs array because we're going to be mutating it
2119
- const initialSize = inputs.length;
2120
- for (let i = 0; i < initialSize && encoder.encode(serialized).byteLength > MAX_OUTPUT_SIZE; i++) {
2121
- inputs.shift();
2127
+ while (totalBytes > MAX_OUTPUT_SIZE && removedCount < messageSizes.length) {
2128
+ totalBytes -= messageSizes[removedCount];
2129
+ // Each removed message past the first also drops the comma that joined it.
2130
+ if (removedCount < messageSizes.length - 1) {
2131
+ totalBytes -= 1;
2132
+ }
2122
2133
  removedCount++;
2123
- serialized = JSON.stringify(inputs);
2124
2134
  }
2125
2135
  if (removedCount > 0) {
2136
+ inputs.splice(0, removedCount);
2126
2137
  // Add one placeholder to indicate how many were removed
2127
2138
  inputs.unshift({
2128
2139
  role: 'posthog',