@posthog/ai 7.16.14 → 7.17.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.
package/dist/index.cjs CHANGED
@@ -9,28 +9,26 @@ var genai = require('@google/genai');
9
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
 
11
11
  function _interopNamespace(e) {
12
- if (e && e.__esModule) return e;
13
- var n = Object.create(null);
14
- if (e) {
15
- Object.keys(e).forEach(function (k) {
16
- if (k !== 'default') {
17
- var d = Object.getOwnPropertyDescriptor(e, k);
18
- Object.defineProperty(n, k, d.get ? d : {
19
- enumerable: true,
20
- get: function () { return e[k]; }
12
+ if (e && e.__esModule) return e;
13
+ var n = Object.create(null);
14
+ if (e) {
15
+ Object.keys(e).forEach(function (k) {
16
+ if (k !== 'default') {
17
+ var d = Object.getOwnPropertyDescriptor(e, k);
18
+ Object.defineProperty(n, k, d.get ? d : {
19
+ enumerable: true,
20
+ get: function () { return e[k]; }
21
+ });
22
+ }
21
23
  });
22
- }
23
- });
24
- }
25
- n.default = e;
26
- return Object.freeze(n);
24
+ }
25
+ n.default = e;
26
+ return Object.freeze(n);
27
27
  }
28
28
 
29
29
  var uuid__namespace = /*#__PURE__*/_interopNamespace(uuid);
30
30
  var AnthropicOriginal__default = /*#__PURE__*/_interopDefault(AnthropicOriginal);
31
31
 
32
- var version = "7.16.14";
33
-
34
32
  // Type guards for safer type checking
35
33
  const isString = value => {
36
34
  return typeof value === 'string';
@@ -679,11 +677,11 @@ const extractAvailableToolCalls = (provider, params) => {
679
677
  }
680
678
  return null;
681
679
  };
682
- var AIEvent;
680
+ exports.AIEvent = void 0;
683
681
  (function (AIEvent) {
684
682
  AIEvent["Generation"] = "$ai_generation";
685
683
  AIEvent["Embedding"] = "$ai_embedding";
686
- })(AIEvent || (AIEvent = {}));
684
+ })(exports.AIEvent || (exports.AIEvent = {}));
687
685
  function sanitizeValues(obj) {
688
686
  if (obj === undefined || obj === null) {
689
687
  return obj;
@@ -734,73 +732,107 @@ function addDefaults(params) {
734
732
  traceId: params.traceId ?? uuid.v4()
735
733
  };
736
734
  }
737
- const sendEventWithErrorToPosthog = async ({
738
- client,
739
- traceId,
740
- error,
741
- ...args
742
- }) => {
743
- const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
744
- const properties = {
745
- client,
746
- traceId,
747
- httpStatus,
748
- error: JSON.stringify(error),
749
- ...args
750
- };
751
- const enrichedError = error;
752
- if (client.options?.enableExceptionAutocapture) {
753
- // assign a uuid that can be used to link the trace and exception events
754
- const exceptionId = core.uuidv7();
755
- client.captureException(error, undefined, {
756
- $ai_trace_id: traceId
757
- }, exceptionId);
758
- enrichedError.__posthog_previously_captured_error = true;
759
- properties.exceptionId = exceptionId;
760
- }
761
- await sendEventToPosthog(properties);
762
- return enrichedError;
763
- };
764
- const sendEventToPosthog = async ({
765
- client,
766
- eventType = AIEvent.Generation,
767
- distinctId,
768
- traceId,
769
- model,
770
- provider,
771
- input,
772
- output,
773
- latency,
774
- timeToFirstToken,
775
- baseURL,
776
- params,
777
- httpStatus = 200,
778
- usage = {},
779
- error,
780
- exceptionId,
781
- stopReason,
782
- tools,
783
- captureImmediate = false
784
- }) => {
785
- if (!client.capture) {
786
- return Promise.resolve();
735
+ function formatOpenAIResponsesInput(input, instructions) {
736
+ const messages = [];
737
+ if (instructions) {
738
+ messages.push({
739
+ role: 'system',
740
+ content: instructions
741
+ });
742
+ }
743
+ if (Array.isArray(input)) {
744
+ for (const item of input) {
745
+ if (typeof item === 'string') {
746
+ messages.push({
747
+ role: 'user',
748
+ content: item
749
+ });
750
+ } else if (item && typeof item === 'object') {
751
+ const obj = item;
752
+ const role = isString(obj.role) ? obj.role : 'user';
753
+ // Handle content properly - preserve structure for objects/arrays
754
+ const content = obj.content ?? obj.text ?? item;
755
+ messages.push({
756
+ role,
757
+ content: toContentString(content)
758
+ });
759
+ } else {
760
+ messages.push({
761
+ role: 'user',
762
+ content: toContentString(item)
763
+ });
764
+ }
765
+ }
766
+ } else if (typeof input === 'string') {
767
+ messages.push({
768
+ role: 'user',
769
+ content: input
770
+ });
771
+ } else if (input) {
772
+ messages.push({
773
+ role: 'user',
774
+ content: toContentString(input)
775
+ });
787
776
  }
788
- // sanitize input and output for UTF-8 validity
789
- const safeInput = sanitizeValues(input);
790
- const safeOutput = sanitizeValues(output);
791
- const safeError = sanitizeValues(error);
777
+ return messages;
778
+ }
779
+
780
+ var version = "7.17.0";
781
+
782
+ /**
783
+ * Capture an `$ai_generation` (or `$ai_embedding`) event to PostHog.
784
+ *
785
+ * This is the canonical primitive that every `@posthog/ai` wrapper
786
+ * (`withTracing`, `OpenAI`, `Anthropic`, `GoogleGenAI`, …) funnels through, so
787
+ * external code can use it directly to instrument LLM calls made through
788
+ * arbitrary clients (Cloudflare Workers AI, custom HTTP, etc.) and get the
789
+ * same events the SDK wrappers produce.
790
+ *
791
+ * When `error` is set, the event is captured as an error. If the error is an
792
+ * object, it is mutated in place to set `__posthog_previously_captured_error`
793
+ * so callers can re-throw the original error reference safely.
794
+ */
795
+ const captureAiGeneration = async (client, options) => {
796
+ if (!client.capture) {
797
+ return;
798
+ }
799
+ const traceId = options.traceId ?? uuid.v4();
800
+ const eventType = options.eventType ?? exports.AIEvent.Generation;
801
+ const privacyMode = options.privacyMode ?? false;
802
+ const usage = options.usage ?? {};
803
+ const safeInput = sanitizeValues(options.input);
804
+ const safeOutput = sanitizeValues(options.output);
805
+ let httpStatus = options.httpStatus;
792
806
  let errorData = {};
793
- if (error) {
807
+ if (options.error) {
808
+ if (httpStatus === undefined) {
809
+ if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
810
+ httpStatus = options.error.status;
811
+ } else {
812
+ httpStatus = 500;
813
+ }
814
+ }
815
+ let exceptionId;
816
+ if (client.options?.enableExceptionAutocapture) {
817
+ exceptionId = core.uuidv7();
818
+ client.captureException(options.error, undefined, {
819
+ $ai_trace_id: traceId
820
+ }, exceptionId);
821
+ if (typeof options.error === 'object') {
822
+ options.error.__posthog_previously_captured_error = true;
823
+ }
824
+ }
794
825
  errorData = {
795
826
  $ai_is_error: true,
796
- $ai_error: safeError,
827
+ $ai_error: sanitizeValues(JSON.stringify(options.error)),
797
828
  $exception_event_id: exceptionId
798
829
  };
799
830
  }
831
+ httpStatus = httpStatus ?? 200;
800
832
  let costOverrideData = {};
801
- if (params.posthogCostOverride) {
802
- const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
803
- const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
833
+ if (options.costOverride) {
834
+ const inputCostUSD = (options.costOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
835
+ const outputCostUSD = (options.costOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
804
836
  costOverrideData = {
805
837
  $ai_input_cost_usd: inputCostUSD,
806
838
  $ai_output_cost_usd: outputCostUSD,
@@ -827,95 +859,49 @@ const sendEventToPosthog = async ({
827
859
  const properties = {
828
860
  $ai_lib: 'posthog-ai',
829
861
  $ai_lib_version: version,
830
- $ai_provider: params.posthogProviderOverride ?? provider,
831
- $ai_model: params.posthogModelOverride ?? model,
832
- $ai_model_parameters: getModelParams(params),
833
- $ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),
834
- $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),
862
+ $ai_provider: options.providerOverride ?? options.provider,
863
+ $ai_model: options.modelOverride ?? options.model,
864
+ $ai_model_parameters: options.modelParameters ?? {},
865
+ $ai_input: withPrivacyMode(client, privacyMode, safeInput),
866
+ $ai_output_choices: withPrivacyMode(client, privacyMode, safeOutput),
835
867
  $ai_http_status: httpStatus,
836
868
  $ai_input_tokens: usage.inputTokens ?? 0,
837
869
  ...(usage.outputTokens !== undefined ? {
838
870
  $ai_output_tokens: usage.outputTokens
839
871
  } : {}),
840
872
  ...additionalTokenValues,
841
- $ai_latency: latency,
842
- ...(timeToFirstToken !== undefined ? {
843
- $ai_time_to_first_token: timeToFirstToken
873
+ $ai_latency: options.latency ?? 0,
874
+ ...(options.timeToFirstToken !== undefined ? {
875
+ $ai_time_to_first_token: options.timeToFirstToken
844
876
  } : {}),
845
877
  $ai_trace_id: traceId,
846
- $ai_base_url: baseURL,
847
- ...params.posthogProperties,
848
- $ai_tokens_source: getTokensSource(params.posthogProperties),
849
- ...(distinctId ? {} : {
878
+ $ai_base_url: options.baseURL ?? '',
879
+ ...options.properties,
880
+ $ai_tokens_source: getTokensSource(options.properties),
881
+ ...(options.distinctId ? {} : {
850
882
  $process_person_profile: false
851
883
  }),
852
- ...(stopReason ? {
853
- $ai_stop_reason: stopReason
884
+ ...(options.stopReason ? {
885
+ $ai_stop_reason: options.stopReason
854
886
  } : {}),
855
- ...(tools ? {
856
- $ai_tools: tools
887
+ ...(options.tools ? {
888
+ $ai_tools: options.tools
857
889
  } : {}),
858
890
  ...errorData,
859
891
  ...costOverrideData
860
892
  };
861
893
  const event = {
862
- distinctId: distinctId ?? traceId,
894
+ distinctId: options.distinctId ?? traceId,
863
895
  event: eventType,
864
896
  properties,
865
- groups: params.posthogGroups
897
+ groups: options.groups
866
898
  };
867
- if (captureImmediate) {
868
- // await capture promise to send single event in serverless environments
899
+ if (options.captureImmediate) {
869
900
  await client.captureImmediate(event);
870
901
  } else {
871
902
  client.capture(event);
872
903
  }
873
- return Promise.resolve();
874
904
  };
875
- function formatOpenAIResponsesInput(input, instructions) {
876
- const messages = [];
877
- if (instructions) {
878
- messages.push({
879
- role: 'system',
880
- content: instructions
881
- });
882
- }
883
- if (Array.isArray(input)) {
884
- for (const item of input) {
885
- if (typeof item === 'string') {
886
- messages.push({
887
- role: 'user',
888
- content: item
889
- });
890
- } else if (item && typeof item === 'object') {
891
- const obj = item;
892
- const role = isString(obj.role) ? obj.role : 'user';
893
- // Handle content properly - preserve structure for objects/arrays
894
- const content = obj.content ?? obj.text ?? item;
895
- messages.push({
896
- role,
897
- content: toContentString(content)
898
- });
899
- } else {
900
- messages.push({
901
- role: 'user',
902
- content: toContentString(item)
903
- });
904
- }
905
- }
906
- } else if (typeof input === 'string') {
907
- messages.push({
908
- role: 'user',
909
- content: input
910
- });
911
- } else if (input) {
912
- messages.push({
913
- role: 'user',
914
- content: toContentString(input)
915
- });
916
- }
917
- return messages;
918
- }
919
905
 
920
906
  /**
921
907
  * Checks if a ResponseStreamEvent chunk represents the first token/content from the model.
@@ -1084,8 +1070,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1084
1070
  const latency = (Date.now() - startTime) / 1000;
1085
1071
  const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
1086
1072
  const availableTools = extractAvailableToolCalls('openai', openAIParams);
1087
- await sendEventToPosthog({
1088
- client: this.phClient,
1073
+ await captureAiGeneration(this.phClient, {
1089
1074
  ...posthogParams,
1090
1075
  model: openAIParams.model ?? modelFromResponse,
1091
1076
  provider: 'openai',
@@ -1094,7 +1079,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1094
1079
  latency,
1095
1080
  timeToFirstToken,
1096
1081
  baseURL: this.baseURL,
1097
- params: body,
1082
+ modelParameters: getModelParams(body),
1098
1083
  httpStatus: 200,
1099
1084
  usage: {
1100
1085
  inputTokens: usage.inputTokens,
@@ -1108,8 +1093,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1108
1093
  tools: availableTools
1109
1094
  });
1110
1095
  } catch (error) {
1111
- const enrichedError = await sendEventWithErrorToPosthog({
1112
- client: this.phClient,
1096
+ await captureAiGeneration(this.phClient, {
1113
1097
  ...posthogParams,
1114
1098
  model: openAIParams.model,
1115
1099
  provider: 'openai',
@@ -1117,14 +1101,14 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1117
1101
  output: [],
1118
1102
  latency: 0,
1119
1103
  baseURL: this.baseURL,
1120
- params: body,
1104
+ modelParameters: getModelParams(body),
1121
1105
  usage: {
1122
1106
  inputTokens: 0,
1123
1107
  outputTokens: 0
1124
1108
  },
1125
1109
  error
1126
1110
  });
1127
- throw enrichedError;
1111
+ throw error;
1128
1112
  }
1129
1113
  })();
1130
1114
  // Return the other stream to the user
@@ -1138,8 +1122,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1138
1122
  const latency = (Date.now() - startTime) / 1000;
1139
1123
  const availableTools = extractAvailableToolCalls('openai', openAIParams);
1140
1124
  const formattedOutput = formatResponseOpenAI(result);
1141
- await sendEventToPosthog({
1142
- client: this.phClient,
1125
+ await captureAiGeneration(this.phClient, {
1143
1126
  ...posthogParams,
1144
1127
  model: openAIParams.model ?? result.model,
1145
1128
  provider: 'openai',
@@ -1147,7 +1130,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1147
1130
  output: formattedOutput,
1148
1131
  latency,
1149
1132
  baseURL: this.baseURL,
1150
- params: body,
1133
+ modelParameters: getModelParams(body),
1151
1134
  httpStatus: 200,
1152
1135
  usage: {
1153
1136
  inputTokens: result.usage?.prompt_tokens ?? 0,
@@ -1164,8 +1147,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1164
1147
  return result;
1165
1148
  }, async error => {
1166
1149
  const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1167
- await sendEventToPosthog({
1168
- client: this.phClient,
1150
+ await captureAiGeneration(this.phClient, {
1169
1151
  ...posthogParams,
1170
1152
  model: openAIParams.model,
1171
1153
  provider: 'openai',
@@ -1173,13 +1155,13 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
1173
1155
  output: [],
1174
1156
  latency: 0,
1175
1157
  baseURL: this.baseURL,
1176
- params: body,
1158
+ modelParameters: getModelParams(body),
1177
1159
  httpStatus,
1178
1160
  usage: {
1179
1161
  inputTokens: 0,
1180
1162
  outputTokens: 0
1181
1163
  },
1182
- error: JSON.stringify(error)
1164
+ error
1183
1165
  });
1184
1166
  throw error;
1185
1167
  });
@@ -1252,8 +1234,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1252
1234
  const latency = (Date.now() - startTime) / 1000;
1253
1235
  const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
1254
1236
  const availableTools = extractAvailableToolCalls('openai', openAIParams);
1255
- await sendEventToPosthog({
1256
- client: this.phClient,
1237
+ await captureAiGeneration(this.phClient, {
1257
1238
  ...posthogParams,
1258
1239
  model: openAIParams.model ?? modelFromResponse,
1259
1240
  provider: 'openai',
@@ -1262,7 +1243,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1262
1243
  latency,
1263
1244
  timeToFirstToken,
1264
1245
  baseURL: this.baseURL,
1265
- params: body,
1246
+ modelParameters: getModelParams(body),
1266
1247
  httpStatus: 200,
1267
1248
  usage: {
1268
1249
  inputTokens: usage.inputTokens,
@@ -1276,8 +1257,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1276
1257
  tools: availableTools
1277
1258
  });
1278
1259
  } catch (error) {
1279
- const enrichedError = await sendEventWithErrorToPosthog({
1280
- client: this.phClient,
1260
+ await captureAiGeneration(this.phClient, {
1281
1261
  ...posthogParams,
1282
1262
  model: openAIParams.model,
1283
1263
  provider: 'openai',
@@ -1285,14 +1265,14 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1285
1265
  output: [],
1286
1266
  latency: 0,
1287
1267
  baseURL: this.baseURL,
1288
- params: body,
1268
+ modelParameters: getModelParams(body),
1289
1269
  usage: {
1290
1270
  inputTokens: 0,
1291
1271
  outputTokens: 0
1292
1272
  },
1293
- error: error
1273
+ error
1294
1274
  });
1295
- throw enrichedError;
1275
+ throw error;
1296
1276
  }
1297
1277
  })();
1298
1278
  return stream2;
@@ -1307,8 +1287,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1307
1287
  const formattedOutput = formatResponseOpenAI({
1308
1288
  output: result.output
1309
1289
  });
1310
- await sendEventToPosthog({
1311
- client: this.phClient,
1290
+ await captureAiGeneration(this.phClient, {
1312
1291
  ...posthogParams,
1313
1292
  model: openAIParams.model ?? result.model,
1314
1293
  provider: 'openai',
@@ -1316,7 +1295,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1316
1295
  output: formattedOutput,
1317
1296
  latency,
1318
1297
  baseURL: this.baseURL,
1319
- params: body,
1298
+ modelParameters: getModelParams(body),
1320
1299
  httpStatus: 200,
1321
1300
  usage: {
1322
1301
  inputTokens: result.usage?.input_tokens ?? 0,
@@ -1333,8 +1312,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1333
1312
  return result;
1334
1313
  }, async error => {
1335
1314
  const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1336
- await sendEventToPosthog({
1337
- client: this.phClient,
1315
+ await captureAiGeneration(this.phClient, {
1338
1316
  ...posthogParams,
1339
1317
  model: openAIParams.model,
1340
1318
  provider: 'openai',
@@ -1342,13 +1320,13 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1342
1320
  output: [],
1343
1321
  latency: 0,
1344
1322
  baseURL: this.baseURL,
1345
- params: body,
1323
+ modelParameters: getModelParams(body),
1346
1324
  httpStatus,
1347
1325
  usage: {
1348
1326
  inputTokens: 0,
1349
1327
  outputTokens: 0
1350
1328
  },
1351
- error: JSON.stringify(error)
1329
+ error
1352
1330
  });
1353
1331
  throw error;
1354
1332
  });
@@ -1369,8 +1347,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1369
1347
  const parentPromise = super.parse(openAIParams, options);
1370
1348
  const wrappedPromise = parentPromise.then(async result => {
1371
1349
  const latency = (Date.now() - startTime) / 1000;
1372
- await sendEventToPosthog({
1373
- client: this.phClient,
1350
+ await captureAiGeneration(this.phClient, {
1374
1351
  ...posthogParams,
1375
1352
  model: openAIParams.model ?? result.model,
1376
1353
  provider: 'openai',
@@ -1378,7 +1355,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1378
1355
  output: result.output,
1379
1356
  latency,
1380
1357
  baseURL: this.baseURL,
1381
- params: body,
1358
+ modelParameters: getModelParams(body),
1382
1359
  httpStatus: 200,
1383
1360
  usage: {
1384
1361
  inputTokens: result.usage?.input_tokens ?? 0,
@@ -1391,8 +1368,7 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1391
1368
  });
1392
1369
  return result;
1393
1370
  }, async error => {
1394
- const enrichedError = await sendEventWithErrorToPosthog({
1395
- client: this.phClient,
1371
+ await captureAiGeneration(this.phClient, {
1396
1372
  ...posthogParams,
1397
1373
  model: openAIParams.model,
1398
1374
  provider: 'openai',
@@ -1400,14 +1376,14 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
1400
1376
  output: [],
1401
1377
  latency: 0,
1402
1378
  baseURL: this.baseURL,
1403
- params: body,
1379
+ modelParameters: getModelParams(body),
1404
1380
  usage: {
1405
1381
  inputTokens: 0,
1406
1382
  outputTokens: 0
1407
1383
  },
1408
- error: JSON.stringify(error)
1384
+ error
1409
1385
  });
1410
- throw enrichedError;
1386
+ throw error;
1411
1387
  });
1412
1388
  return wrappedPromise;
1413
1389
  } finally {
@@ -1431,10 +1407,9 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends Embeddings {
1431
1407
  const parentPromise = super.create(openAIParams, options);
1432
1408
  const wrappedPromise = parentPromise.then(async result => {
1433
1409
  const latency = (Date.now() - startTime) / 1000;
1434
- await sendEventToPosthog({
1435
- client: this.phClient,
1410
+ await captureAiGeneration(this.phClient, {
1436
1411
  ...posthogParams,
1437
- eventType: AIEvent.Embedding,
1412
+ eventType: exports.AIEvent.Embedding,
1438
1413
  model: openAIParams.model,
1439
1414
  provider: 'openai',
1440
1415
  input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
@@ -1442,7 +1417,7 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends Embeddings {
1442
1417
  // Embeddings don't have output content
1443
1418
  latency,
1444
1419
  baseURL: this.baseURL,
1445
- params: body,
1420
+ modelParameters: getModelParams(body),
1446
1421
  httpStatus: 200,
1447
1422
  usage: {
1448
1423
  inputTokens: result.usage?.prompt_tokens ?? 0,
@@ -1452,9 +1427,8 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends Embeddings {
1452
1427
  return result;
1453
1428
  }, async error => {
1454
1429
  const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1455
- await sendEventToPosthog({
1456
- client: this.phClient,
1457
- eventType: AIEvent.Embedding,
1430
+ await captureAiGeneration(this.phClient, {
1431
+ eventType: exports.AIEvent.Embedding,
1458
1432
  ...posthogParams,
1459
1433
  model: openAIParams.model,
1460
1434
  provider: 'openai',
@@ -1463,12 +1437,12 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends Embeddings {
1463
1437
  // Embeddings don't have output content
1464
1438
  latency: 0,
1465
1439
  baseURL: this.baseURL,
1466
- params: body,
1440
+ modelParameters: getModelParams(body),
1467
1441
  httpStatus,
1468
1442
  usage: {
1469
1443
  inputTokens: 0
1470
1444
  },
1471
- error: JSON.stringify(error)
1445
+ error
1472
1446
  });
1473
1447
  throw error;
1474
1448
  });
@@ -1527,8 +1501,7 @@ class WrappedTranscriptions extends Transcriptions {
1527
1501
  const latency = (Date.now() - startTime) / 1000;
1528
1502
  const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
1529
1503
  const availableTools = extractAvailableToolCalls('openai', openAIParams);
1530
- await sendEventToPosthog({
1531
- client: this.phClient,
1504
+ await captureAiGeneration(this.phClient, {
1532
1505
  ...posthogParams,
1533
1506
  model: openAIParams.model,
1534
1507
  provider: 'openai',
@@ -1537,14 +1510,13 @@ class WrappedTranscriptions extends Transcriptions {
1537
1510
  latency,
1538
1511
  timeToFirstToken,
1539
1512
  baseURL: this.baseURL,
1540
- params: body,
1513
+ modelParameters: getModelParams(body),
1541
1514
  httpStatus: 200,
1542
1515
  usage,
1543
1516
  tools: availableTools
1544
1517
  });
1545
1518
  } catch (error) {
1546
- const enrichedError = await sendEventWithErrorToPosthog({
1547
- client: this.phClient,
1519
+ await captureAiGeneration(this.phClient, {
1548
1520
  ...posthogParams,
1549
1521
  model: openAIParams.model,
1550
1522
  provider: 'openai',
@@ -1552,14 +1524,14 @@ class WrappedTranscriptions extends Transcriptions {
1552
1524
  output: [],
1553
1525
  latency: 0,
1554
1526
  baseURL: this.baseURL,
1555
- params: body,
1527
+ modelParameters: getModelParams(body),
1556
1528
  usage: {
1557
1529
  inputTokens: 0,
1558
1530
  outputTokens: 0
1559
1531
  },
1560
- error: error
1532
+ error
1561
1533
  });
1562
- throw enrichedError;
1534
+ throw error;
1563
1535
  }
1564
1536
  })();
1565
1537
  return stream2;
@@ -1570,8 +1542,7 @@ class WrappedTranscriptions extends Transcriptions {
1570
1542
  const wrappedPromise = parentPromise.then(async result => {
1571
1543
  if ('text' in result) {
1572
1544
  const latency = (Date.now() - startTime) / 1000;
1573
- await sendEventToPosthog({
1574
- client: this.phClient,
1545
+ await captureAiGeneration(this.phClient, {
1575
1546
  ...posthogParams,
1576
1547
  model: openAIParams.model,
1577
1548
  provider: 'openai',
@@ -1579,7 +1550,7 @@ class WrappedTranscriptions extends Transcriptions {
1579
1550
  output: result.text,
1580
1551
  latency,
1581
1552
  baseURL: this.baseURL,
1582
- params: body,
1553
+ modelParameters: getModelParams(body),
1583
1554
  httpStatus: 200,
1584
1555
  usage: {
1585
1556
  inputTokens: result.usage?.type === 'tokens' ? result.usage.input_tokens ?? 0 : 0,
@@ -1590,8 +1561,7 @@ class WrappedTranscriptions extends Transcriptions {
1590
1561
  return result;
1591
1562
  }
1592
1563
  }, async error => {
1593
- const enrichedError = await sendEventWithErrorToPosthog({
1594
- client: this.phClient,
1564
+ await captureAiGeneration(this.phClient, {
1595
1565
  ...posthogParams,
1596
1566
  model: openAIParams.model,
1597
1567
  provider: 'openai',
@@ -1599,14 +1569,14 @@ class WrappedTranscriptions extends Transcriptions {
1599
1569
  output: [],
1600
1570
  latency: 0,
1601
1571
  baseURL: this.baseURL,
1602
- params: body,
1572
+ modelParameters: getModelParams(body),
1603
1573
  usage: {
1604
1574
  inputTokens: 0,
1605
1575
  outputTokens: 0
1606
1576
  },
1607
- error: error
1577
+ error
1608
1578
  });
1609
- throw enrichedError;
1579
+ throw error;
1610
1580
  });
1611
1581
  return wrappedPromise;
1612
1582
  }
@@ -1751,8 +1721,7 @@ class WrappedCompletions extends openai.AzureOpenAI.Chat.Completions {
1751
1721
  }];
1752
1722
  const latency = (Date.now() - startTime) / 1000;
1753
1723
  const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
1754
- await sendEventToPosthog({
1755
- client: this.phClient,
1724
+ await captureAiGeneration(this.phClient, {
1756
1725
  ...posthogParams,
1757
1726
  model: openAIParams.model ?? modelFromResponse,
1758
1727
  provider: 'azure',
@@ -1761,13 +1730,12 @@ class WrappedCompletions extends openai.AzureOpenAI.Chat.Completions {
1761
1730
  latency,
1762
1731
  timeToFirstToken,
1763
1732
  baseURL: this.baseURL,
1764
- params: body,
1733
+ modelParameters: getModelParams(body),
1765
1734
  httpStatus: 200,
1766
1735
  usage
1767
1736
  });
1768
1737
  } catch (error) {
1769
- const enrichedError = await sendEventWithErrorToPosthog({
1770
- client: this.phClient,
1738
+ await captureAiGeneration(this.phClient, {
1771
1739
  ...posthogParams,
1772
1740
  model: openAIParams.model,
1773
1741
  provider: 'azure',
@@ -1775,14 +1743,14 @@ class WrappedCompletions extends openai.AzureOpenAI.Chat.Completions {
1775
1743
  output: [],
1776
1744
  latency: 0,
1777
1745
  baseURL: this.baseURL,
1778
- params: body,
1746
+ modelParameters: getModelParams(body),
1779
1747
  usage: {
1780
1748
  inputTokens: 0,
1781
1749
  outputTokens: 0
1782
1750
  },
1783
1751
  error: error
1784
1752
  });
1785
- throw enrichedError;
1753
+ throw error;
1786
1754
  }
1787
1755
  })();
1788
1756
  // Return the other stream to the user
@@ -1794,8 +1762,7 @@ class WrappedCompletions extends openai.AzureOpenAI.Chat.Completions {
1794
1762
  const wrappedPromise = parentPromise.then(async result => {
1795
1763
  if ('choices' in result) {
1796
1764
  const latency = (Date.now() - startTime) / 1000;
1797
- await sendEventToPosthog({
1798
- client: this.phClient,
1765
+ await captureAiGeneration(this.phClient, {
1799
1766
  ...posthogParams,
1800
1767
  model: openAIParams.model ?? result.model,
1801
1768
  provider: 'azure',
@@ -1803,7 +1770,7 @@ class WrappedCompletions extends openai.AzureOpenAI.Chat.Completions {
1803
1770
  output: formatResponseOpenAI(result),
1804
1771
  latency,
1805
1772
  baseURL: this.baseURL,
1806
- params: body,
1773
+ modelParameters: getModelParams(body),
1807
1774
  httpStatus: 200,
1808
1775
  usage: {
1809
1776
  inputTokens: result.usage?.prompt_tokens ?? 0,
@@ -1816,8 +1783,7 @@ class WrappedCompletions extends openai.AzureOpenAI.Chat.Completions {
1816
1783
  return result;
1817
1784
  }, async error => {
1818
1785
  const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1819
- await sendEventToPosthog({
1820
- client: this.phClient,
1786
+ await captureAiGeneration(this.phClient, {
1821
1787
  ...posthogParams,
1822
1788
  model: openAIParams.model,
1823
1789
  provider: 'azure',
@@ -1825,13 +1791,13 @@ class WrappedCompletions extends openai.AzureOpenAI.Chat.Completions {
1825
1791
  output: [],
1826
1792
  latency: 0,
1827
1793
  baseURL: this.baseURL,
1828
- params: body,
1794
+ modelParameters: getModelParams(body),
1829
1795
  httpStatus,
1830
1796
  usage: {
1831
1797
  inputTokens: 0,
1832
1798
  outputTokens: 0
1833
1799
  },
1834
- error: JSON.stringify(error)
1800
+ error
1835
1801
  });
1836
1802
  throw error;
1837
1803
  });
@@ -1891,8 +1857,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1891
1857
  }
1892
1858
  const latency = (Date.now() - startTime) / 1000;
1893
1859
  const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
1894
- await sendEventToPosthog({
1895
- client: this.phClient,
1860
+ await captureAiGeneration(this.phClient, {
1896
1861
  ...posthogParams,
1897
1862
  model: openAIParams.model ?? modelFromResponse,
1898
1863
  provider: 'azure',
@@ -1901,13 +1866,12 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1901
1866
  latency,
1902
1867
  timeToFirstToken,
1903
1868
  baseURL: this.baseURL,
1904
- params: body,
1869
+ modelParameters: getModelParams(body),
1905
1870
  httpStatus: 200,
1906
1871
  usage
1907
1872
  });
1908
1873
  } catch (error) {
1909
- const enrichedError = await sendEventWithErrorToPosthog({
1910
- client: this.phClient,
1874
+ await captureAiGeneration(this.phClient, {
1911
1875
  ...posthogParams,
1912
1876
  model: openAIParams.model,
1913
1877
  provider: 'azure',
@@ -1915,14 +1879,14 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1915
1879
  output: [],
1916
1880
  latency: 0,
1917
1881
  baseURL: this.baseURL,
1918
- params: body,
1882
+ modelParameters: getModelParams(body),
1919
1883
  usage: {
1920
1884
  inputTokens: 0,
1921
1885
  outputTokens: 0
1922
1886
  },
1923
1887
  error: error
1924
1888
  });
1925
- throw enrichedError;
1889
+ throw error;
1926
1890
  }
1927
1891
  })();
1928
1892
  return stream2;
@@ -1933,8 +1897,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1933
1897
  const wrappedPromise = parentPromise.then(async result => {
1934
1898
  if ('output' in result) {
1935
1899
  const latency = (Date.now() - startTime) / 1000;
1936
- await sendEventToPosthog({
1937
- client: this.phClient,
1900
+ await captureAiGeneration(this.phClient, {
1938
1901
  ...posthogParams,
1939
1902
  model: openAIParams.model ?? result.model,
1940
1903
  provider: 'azure',
@@ -1942,7 +1905,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1942
1905
  output: result.output,
1943
1906
  latency,
1944
1907
  baseURL: this.baseURL,
1945
- params: body,
1908
+ modelParameters: getModelParams(body),
1946
1909
  httpStatus: 200,
1947
1910
  usage: {
1948
1911
  inputTokens: result.usage?.input_tokens ?? 0,
@@ -1955,8 +1918,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1955
1918
  return result;
1956
1919
  }, async error => {
1957
1920
  const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
1958
- await sendEventToPosthog({
1959
- client: this.phClient,
1921
+ await captureAiGeneration(this.phClient, {
1960
1922
  ...posthogParams,
1961
1923
  model: openAIParams.model,
1962
1924
  provider: 'azure',
@@ -1964,13 +1926,13 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1964
1926
  output: [],
1965
1927
  latency: 0,
1966
1928
  baseURL: this.baseURL,
1967
- params: body,
1929
+ modelParameters: getModelParams(body),
1968
1930
  httpStatus,
1969
1931
  usage: {
1970
1932
  inputTokens: 0,
1971
1933
  outputTokens: 0
1972
1934
  },
1973
- error: JSON.stringify(error)
1935
+ error
1974
1936
  });
1975
1937
  throw error;
1976
1938
  });
@@ -1986,8 +1948,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1986
1948
  const parentPromise = super.parse(openAIParams, options);
1987
1949
  const wrappedPromise = parentPromise.then(async result => {
1988
1950
  const latency = (Date.now() - startTime) / 1000;
1989
- await sendEventToPosthog({
1990
- client: this.phClient,
1951
+ await captureAiGeneration(this.phClient, {
1991
1952
  ...posthogParams,
1992
1953
  model: openAIParams.model ?? result.model,
1993
1954
  provider: 'azure',
@@ -1995,7 +1956,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
1995
1956
  output: result.output,
1996
1957
  latency,
1997
1958
  baseURL: this.baseURL,
1998
- params: body,
1959
+ modelParameters: getModelParams(body),
1999
1960
  httpStatus: 200,
2000
1961
  usage: {
2001
1962
  inputTokens: result.usage?.input_tokens ?? 0,
@@ -2006,8 +1967,7 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
2006
1967
  });
2007
1968
  return result;
2008
1969
  }, async error => {
2009
- await sendEventToPosthog({
2010
- client: this.phClient,
1970
+ await captureAiGeneration(this.phClient, {
2011
1971
  ...posthogParams,
2012
1972
  model: openAIParams.model,
2013
1973
  provider: 'azure',
@@ -2015,13 +1975,13 @@ class WrappedResponses extends openai.AzureOpenAI.Responses {
2015
1975
  output: [],
2016
1976
  latency: 0,
2017
1977
  baseURL: this.baseURL,
2018
- params: body,
1978
+ modelParameters: getModelParams(body),
2019
1979
  httpStatus: error?.status ? error.status : 500,
2020
1980
  usage: {
2021
1981
  inputTokens: 0,
2022
1982
  outputTokens: 0
2023
1983
  },
2024
- error: JSON.stringify(error)
1984
+ error
2025
1985
  });
2026
1986
  throw error;
2027
1987
  });
@@ -2043,9 +2003,8 @@ class WrappedEmbeddings extends openai.AzureOpenAI.Embeddings {
2043
2003
  const parentPromise = super.create(openAIParams, options);
2044
2004
  const wrappedPromise = parentPromise.then(async result => {
2045
2005
  const latency = (Date.now() - startTime) / 1000;
2046
- await sendEventToPosthog({
2047
- client: this.phClient,
2048
- eventType: AIEvent.Embedding,
2006
+ await captureAiGeneration(this.phClient, {
2007
+ eventType: exports.AIEvent.Embedding,
2049
2008
  ...posthogParams,
2050
2009
  model: openAIParams.model,
2051
2010
  provider: 'azure',
@@ -2054,7 +2013,7 @@ class WrappedEmbeddings extends openai.AzureOpenAI.Embeddings {
2054
2013
  // Embeddings don't have output content
2055
2014
  latency,
2056
2015
  baseURL: this.baseURL,
2057
- params: body,
2016
+ modelParameters: getModelParams(body),
2058
2017
  httpStatus: 200,
2059
2018
  usage: {
2060
2019
  inputTokens: result.usage?.prompt_tokens ?? 0
@@ -2063,9 +2022,8 @@ class WrappedEmbeddings extends openai.AzureOpenAI.Embeddings {
2063
2022
  return result;
2064
2023
  }, async error => {
2065
2024
  const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
2066
- await sendEventToPosthog({
2067
- client: this.phClient,
2068
- eventType: AIEvent.Embedding,
2025
+ await captureAiGeneration(this.phClient, {
2026
+ eventType: exports.AIEvent.Embedding,
2069
2027
  ...posthogParams,
2070
2028
  model: openAIParams.model,
2071
2029
  provider: 'azure',
@@ -2073,12 +2031,12 @@ class WrappedEmbeddings extends openai.AzureOpenAI.Embeddings {
2073
2031
  output: null,
2074
2032
  latency: 0,
2075
2033
  baseURL: this.baseURL,
2076
- params: body,
2034
+ modelParameters: getModelParams(body),
2077
2035
  httpStatus,
2078
2036
  usage: {
2079
2037
  inputTokens: 0
2080
2038
  },
2081
- error: JSON.stringify(error)
2039
+ error
2082
2040
  });
2083
2041
  throw error;
2084
2042
  });
@@ -2407,6 +2365,18 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2407
2365
  $ai_framework_version: model.specificationVersion === 'v3' ? '6' : '5'
2408
2366
  }
2409
2367
  };
2368
+ // Shared `captureAiGeneration` options for every call site in this wrapper.
2369
+ const baseOptions = {
2370
+ distinctId: mergedOptions.posthogDistinctId,
2371
+ traceId,
2372
+ properties: mergedOptions.posthogProperties,
2373
+ groups: mergedOptions.posthogGroups,
2374
+ privacyMode: mergedOptions.posthogPrivacyMode,
2375
+ modelOverride: mergedOptions.posthogModelOverride,
2376
+ providerOverride: mergedOptions.posthogProviderOverride,
2377
+ costOverride: mergedOptions.posthogCostOverride,
2378
+ captureImmediate: mergedOptions.posthogCaptureImmediate
2379
+ };
2410
2380
  // Create wrapped model using Object.create to preserve the prototype chain
2411
2381
  // This automatically inherits all properties (including getters) from the model
2412
2382
  const wrappedModel = Object.create(model, {
@@ -2459,46 +2429,40 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2459
2429
  // Extract finish reason - V2 returns a string, V3 returns an object with .unified
2460
2430
  const rawFinishReason = result.finishReason;
2461
2431
  const finishReasonStr = typeof rawFinishReason === 'string' ? rawFinishReason : rawFinishReason && typeof rawFinishReason === 'object' && 'unified' in rawFinishReason ? String(rawFinishReason.unified) : undefined;
2462
- await sendEventToPosthog({
2463
- client: phClient,
2464
- distinctId: mergedOptions.posthogDistinctId,
2465
- traceId: mergedOptions.posthogTraceId ?? uuid.v4(),
2432
+ await captureAiGeneration(phClient, {
2433
+ ...baseOptions,
2466
2434
  model: modelId,
2467
2435
  provider: provider,
2468
2436
  input: mergedOptions.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
2469
2437
  output: content,
2470
2438
  latency,
2471
2439
  baseURL,
2472
- params: mergedParams,
2440
+ modelParameters: getModelParams(mergedParams),
2473
2441
  httpStatus: 200,
2474
2442
  usage,
2475
2443
  stopReason: finishReasonStr,
2476
- tools: availableTools,
2477
- captureImmediate: mergedOptions.posthogCaptureImmediate
2444
+ tools: availableTools
2478
2445
  });
2479
2446
  return result;
2480
2447
  } catch (error) {
2481
2448
  const modelId = model.modelId;
2482
- const enrichedError = await sendEventWithErrorToPosthog({
2483
- client: phClient,
2484
- distinctId: mergedOptions.posthogDistinctId,
2485
- traceId: mergedOptions.posthogTraceId ?? uuid.v4(),
2449
+ await captureAiGeneration(phClient, {
2450
+ ...baseOptions,
2486
2451
  model: modelId,
2487
2452
  provider: model.provider,
2488
2453
  input: mergedOptions.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
2489
2454
  output: [],
2490
2455
  latency: 0,
2491
2456
  baseURL: '',
2492
- params: mergedParams,
2457
+ modelParameters: getModelParams(mergedParams),
2493
2458
  usage: {
2494
2459
  inputTokens: 0,
2495
2460
  outputTokens: 0
2496
2461
  },
2497
2462
  error: error,
2498
- tools: availableTools,
2499
- captureImmediate: mergedOptions.posthogCaptureImmediate
2463
+ tools: availableTools
2500
2464
  });
2501
- throw enrichedError;
2465
+ throw error;
2502
2466
  }
2503
2467
  },
2504
2468
  writable: true,
@@ -2644,10 +2608,8 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2644
2608
  }
2645
2609
  };
2646
2610
  adjustAnthropicV3CacheTokens(model, modelId, provider, finalUsage);
2647
- await sendEventToPosthog({
2648
- client: phClient,
2649
- distinctId: mergedOptions.posthogDistinctId,
2650
- traceId: mergedOptions.posthogTraceId ?? uuid.v4(),
2611
+ await captureAiGeneration(phClient, {
2612
+ ...baseOptions,
2651
2613
  model: modelId,
2652
2614
  provider: provider,
2653
2615
  input: mergedOptions.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
@@ -2655,12 +2617,11 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2655
2617
  latency,
2656
2618
  timeToFirstToken,
2657
2619
  baseURL,
2658
- params: mergedParams,
2620
+ modelParameters: getModelParams(mergedParams),
2659
2621
  httpStatus: 200,
2660
2622
  usage: finalUsage,
2661
2623
  stopReason,
2662
- tools: availableTools,
2663
- captureImmediate: mergedOptions.posthogCaptureImmediate
2624
+ tools: availableTools
2664
2625
  });
2665
2626
  }
2666
2627
  });
@@ -2669,26 +2630,23 @@ const wrapVercelLanguageModel = (model, phClient, options) => {
2669
2630
  ...rest
2670
2631
  };
2671
2632
  } catch (error) {
2672
- const enrichedError = await sendEventWithErrorToPosthog({
2673
- client: phClient,
2674
- distinctId: mergedOptions.posthogDistinctId,
2675
- traceId: mergedOptions.posthogTraceId ?? uuid.v4(),
2633
+ await captureAiGeneration(phClient, {
2634
+ ...baseOptions,
2676
2635
  model: modelId,
2677
2636
  provider: provider,
2678
2637
  input: mergedOptions.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
2679
2638
  output: [],
2680
2639
  latency: 0,
2681
2640
  baseURL: '',
2682
- params: mergedParams,
2641
+ modelParameters: getModelParams(mergedParams),
2683
2642
  usage: {
2684
2643
  inputTokens: 0,
2685
2644
  outputTokens: 0
2686
2645
  },
2687
2646
  error: error,
2688
- tools: availableTools,
2689
- captureImmediate: mergedOptions.posthogCaptureImmediate
2647
+ tools: availableTools
2690
2648
  });
2691
- throw enrichedError;
2649
+ throw error;
2692
2650
  }
2693
2651
  },
2694
2652
  writable: true,
@@ -2853,8 +2811,7 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
2853
2811
  text: accumulatedContent
2854
2812
  }]
2855
2813
  }];
2856
- await sendEventToPosthog({
2857
- client: this.phClient,
2814
+ await captureAiGeneration(this.phClient, {
2858
2815
  ...posthogParams,
2859
2816
  model: anthropicParams.model,
2860
2817
  provider: 'anthropic',
@@ -2863,15 +2820,14 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
2863
2820
  latency,
2864
2821
  timeToFirstToken,
2865
2822
  baseURL: this.baseURL,
2866
- params: body,
2823
+ modelParameters: getModelParams(body),
2867
2824
  httpStatus: 200,
2868
2825
  usage,
2869
2826
  stopReason,
2870
2827
  tools: availableTools
2871
2828
  });
2872
2829
  } catch (error) {
2873
- const enrichedError = await sendEventWithErrorToPosthog({
2874
- client: this.phClient,
2830
+ await captureAiGeneration(this.phClient, {
2875
2831
  ...posthogParams,
2876
2832
  model: anthropicParams.model,
2877
2833
  provider: 'anthropic',
@@ -2879,14 +2835,14 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
2879
2835
  output: [],
2880
2836
  latency: 0,
2881
2837
  baseURL: this.baseURL,
2882
- params: body,
2838
+ modelParameters: getModelParams(body),
2883
2839
  usage: {
2884
2840
  inputTokens: 0,
2885
2841
  outputTokens: 0
2886
2842
  },
2887
2843
  error: error
2888
2844
  });
2889
- throw enrichedError;
2845
+ throw error;
2890
2846
  }
2891
2847
  })();
2892
2848
  // Return the other stream to the user
@@ -2899,8 +2855,7 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
2899
2855
  if ('content' in result) {
2900
2856
  const latency = (Date.now() - startTime) / 1000;
2901
2857
  const availableTools = extractAvailableToolCalls('anthropic', anthropicParams);
2902
- await sendEventToPosthog({
2903
- client: this.phClient,
2858
+ await captureAiGeneration(this.phClient, {
2904
2859
  ...posthogParams,
2905
2860
  model: anthropicParams.model,
2906
2861
  provider: 'anthropic',
@@ -2908,7 +2863,7 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
2908
2863
  output: formatResponseAnthropic(result),
2909
2864
  latency,
2910
2865
  baseURL: this.baseURL,
2911
- params: body,
2866
+ modelParameters: getModelParams(body),
2912
2867
  httpStatus: 200,
2913
2868
  usage: {
2914
2869
  inputTokens: result.usage.input_tokens ?? 0,
@@ -2924,8 +2879,7 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
2924
2879
  }
2925
2880
  return result;
2926
2881
  }, async error => {
2927
- await sendEventToPosthog({
2928
- client: this.phClient,
2882
+ await captureAiGeneration(this.phClient, {
2929
2883
  ...posthogParams,
2930
2884
  model: anthropicParams.model,
2931
2885
  provider: 'anthropic',
@@ -2933,13 +2887,13 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
2933
2887
  output: [],
2934
2888
  latency: 0,
2935
2889
  baseURL: this.baseURL,
2936
- params: body,
2890
+ modelParameters: getModelParams(body),
2937
2891
  httpStatus: error?.status ? error.status : 500,
2938
2892
  usage: {
2939
2893
  inputTokens: 0,
2940
2894
  outputTokens: 0
2941
2895
  },
2942
- error: JSON.stringify(error)
2896
+ error: error
2943
2897
  });
2944
2898
  throw error;
2945
2899
  });
@@ -2976,8 +2930,7 @@ class WrappedModels {
2976
2930
  const availableTools = extractAvailableToolCalls('gemini', geminiParams);
2977
2931
  const metadata = response.usageMetadata;
2978
2932
  const finishReason = response.candidates?.[0]?.finishReason;
2979
- await sendEventToPosthog({
2980
- client: this.phClient,
2933
+ await captureAiGeneration(this.phClient, {
2981
2934
  ...posthogParams,
2982
2935
  model: geminiParams.model,
2983
2936
  provider: 'gemini',
@@ -2985,7 +2938,7 @@ class WrappedModels {
2985
2938
  output: formatResponseGemini(response),
2986
2939
  latency,
2987
2940
  baseURL: 'https://generativelanguage.googleapis.com',
2988
- params: params,
2941
+ modelParameters: getModelParams(params),
2989
2942
  httpStatus: 200,
2990
2943
  usage: {
2991
2944
  inputTokens: metadata?.promptTokenCount ?? 0,
@@ -3001,8 +2954,7 @@ class WrappedModels {
3001
2954
  return response;
3002
2955
  } catch (error) {
3003
2956
  const latency = (Date.now() - startTime) / 1000;
3004
- const enrichedError = await sendEventWithErrorToPosthog({
3005
- client: this.phClient,
2957
+ await captureAiGeneration(this.phClient, {
3006
2958
  ...posthogParams,
3007
2959
  model: geminiParams.model,
3008
2960
  provider: 'gemini',
@@ -3010,14 +2962,14 @@ class WrappedModels {
3010
2962
  output: [],
3011
2963
  latency,
3012
2964
  baseURL: 'https://generativelanguage.googleapis.com',
3013
- params: params,
2965
+ modelParameters: getModelParams(params),
3014
2966
  usage: {
3015
2967
  inputTokens: 0,
3016
2968
  outputTokens: 0
3017
2969
  },
3018
- error: error
2970
+ error
3019
2971
  });
3020
- throw enrichedError;
2972
+ throw error;
3021
2973
  }
3022
2974
  }
3023
2975
  async *generateContentStream(params) {
@@ -3116,8 +3068,7 @@ class WrappedModels {
3116
3068
  role: 'assistant',
3117
3069
  content: accumulatedContent
3118
3070
  }] : [];
3119
- await sendEventToPosthog({
3120
- client: this.phClient,
3071
+ await captureAiGeneration(this.phClient, {
3121
3072
  ...posthogParams,
3122
3073
  model: geminiParams.model,
3123
3074
  provider: 'gemini',
@@ -3126,7 +3077,7 @@ class WrappedModels {
3126
3077
  latency,
3127
3078
  timeToFirstToken,
3128
3079
  baseURL: 'https://generativelanguage.googleapis.com',
3129
- params: params,
3080
+ modelParameters: getModelParams(params),
3130
3081
  httpStatus: 200,
3131
3082
  usage: {
3132
3083
  ...usage,
@@ -3138,8 +3089,7 @@ class WrappedModels {
3138
3089
  });
3139
3090
  } catch (error) {
3140
3091
  const latency = (Date.now() - startTime) / 1000;
3141
- const enrichedError = await sendEventWithErrorToPosthog({
3142
- client: this.phClient,
3092
+ await captureAiGeneration(this.phClient, {
3143
3093
  ...posthogParams,
3144
3094
  model: geminiParams.model,
3145
3095
  provider: 'gemini',
@@ -3147,14 +3097,14 @@ class WrappedModels {
3147
3097
  output: [],
3148
3098
  latency,
3149
3099
  baseURL: 'https://generativelanguage.googleapis.com',
3150
- params: params,
3100
+ modelParameters: getModelParams(params),
3151
3101
  usage: {
3152
3102
  inputTokens: 0,
3153
3103
  outputTokens: 0
3154
3104
  },
3155
- error: error
3105
+ error
3156
3106
  });
3157
- throw enrichedError;
3107
+ throw error;
3158
3108
  }
3159
3109
  }
3160
3110
  async embedContent(params) {
@@ -3167,17 +3117,16 @@ class WrappedModels {
3167
3117
  const response = await this.client.models.embedContent(geminiParams);
3168
3118
  const latency = (Date.now() - startTime) / 1000;
3169
3119
  const inputTokens = extractEmbeddingTokenCount(response);
3170
- await sendEventToPosthog({
3171
- client: this.phClient,
3120
+ await captureAiGeneration(this.phClient, {
3172
3121
  ...posthogParams,
3173
- eventType: AIEvent.Embedding,
3122
+ eventType: exports.AIEvent.Embedding,
3174
3123
  model: geminiParams.model,
3175
3124
  provider: 'gemini',
3176
3125
  input: withPrivacyMode(this.phClient, posthogParams.privacyMode ?? false, geminiParams.contents),
3177
3126
  output: null,
3178
3127
  latency,
3179
3128
  baseURL: 'https://generativelanguage.googleapis.com',
3180
- params: params,
3129
+ modelParameters: getModelParams(params),
3181
3130
  httpStatus: 200,
3182
3131
  usage: {
3183
3132
  inputTokens
@@ -3186,23 +3135,22 @@ class WrappedModels {
3186
3135
  return response;
3187
3136
  } catch (error) {
3188
3137
  const latency = (Date.now() - startTime) / 1000;
3189
- const enrichedError = await sendEventWithErrorToPosthog({
3190
- client: this.phClient,
3138
+ await captureAiGeneration(this.phClient, {
3191
3139
  ...posthogParams,
3192
- eventType: AIEvent.Embedding,
3140
+ eventType: exports.AIEvent.Embedding,
3193
3141
  model: geminiParams.model,
3194
3142
  provider: 'gemini',
3195
3143
  input: withPrivacyMode(this.phClient, posthogParams.privacyMode ?? false, geminiParams.contents),
3196
3144
  output: null,
3197
3145
  latency,
3198
3146
  baseURL: 'https://generativelanguage.googleapis.com',
3199
- params: params,
3147
+ modelParameters: getModelParams(params),
3200
3148
  usage: {
3201
3149
  inputTokens: 0
3202
3150
  },
3203
- error: error
3151
+ error
3204
3152
  });
3205
- throw enrichedError;
3153
+ throw error;
3206
3154
  }
3207
3155
  }
3208
3156
  formatPartsAsContentBlocks(parts) {
@@ -4744,5 +4692,6 @@ exports.GoogleGenAI = PostHogGoogleGenAI;
4744
4692
  exports.LangChainCallbackHandler = LangChainCallbackHandler;
4745
4693
  exports.OpenAI = PostHogOpenAI;
4746
4694
  exports.Prompts = Prompts;
4695
+ exports.captureAiGeneration = captureAiGeneration;
4747
4696
  exports.withTracing = wrapVercelLanguageModel;
4748
4697
  //# sourceMappingURL=index.cjs.map