@posthog/ai 6.2.0 → 6.3.1

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.
@@ -22,6 +22,7 @@ interface CostOverride {
22
22
  declare const Chat: typeof OpenAI.Chat;
23
23
  declare const Completions: typeof OpenAI.Chat.Completions;
24
24
  declare const Responses: typeof OpenAI.Responses;
25
+ declare const Embeddings: typeof OpenAI.Embeddings;
25
26
  type ChatCompletion = OpenAI.ChatCompletion;
26
27
  type ChatCompletionChunk = OpenAI.ChatCompletionChunk;
27
28
  type ChatCompletionCreateParamsBase = OpenAI.Chat.Completions.ChatCompletionCreateParams;
@@ -30,6 +31,8 @@ type ChatCompletionCreateParamsStreaming = OpenAI.Chat.Completions.ChatCompletio
30
31
  type ResponsesCreateParamsBase = OpenAI.Responses.ResponseCreateParams;
31
32
  type ResponsesCreateParamsNonStreaming = OpenAI.Responses.ResponseCreateParamsNonStreaming;
32
33
  type ResponsesCreateParamsStreaming = OpenAI.Responses.ResponseCreateParamsStreaming;
34
+ type CreateEmbeddingResponse = OpenAI.CreateEmbeddingResponse;
35
+ type EmbeddingCreateParams = OpenAI.EmbeddingCreateParams;
33
36
  interface MonitoringOpenAIConfig extends ClientOptions {
34
37
  apiKey: string;
35
38
  posthog: PostHog;
@@ -40,6 +43,7 @@ declare class PostHogOpenAI extends OpenAI {
40
43
  private readonly phClient;
41
44
  chat: WrappedChat;
42
45
  responses: WrappedResponses;
46
+ embeddings: WrappedEmbeddings;
43
47
  constructor(config: MonitoringOpenAIConfig);
44
48
  }
45
49
  declare class WrappedChat extends Chat {
@@ -48,6 +52,7 @@ declare class WrappedChat extends Chat {
48
52
  }
49
53
  declare class WrappedCompletions extends Completions {
50
54
  private readonly phClient;
55
+ private readonly baseURL;
51
56
  constructor(client: OpenAI, phClient: PostHog);
52
57
  create(body: ChatCompletionCreateParamsNonStreaming & MonitoringParams, options?: RequestOptions): APIPromise<ChatCompletion>;
53
58
  create(body: ChatCompletionCreateParamsStreaming & MonitoringParams, options?: RequestOptions): APIPromise<Stream<ChatCompletionChunk>>;
@@ -55,11 +60,18 @@ declare class WrappedCompletions extends Completions {
55
60
  }
56
61
  declare class WrappedResponses extends Responses {
57
62
  private readonly phClient;
63
+ private readonly baseURL;
58
64
  constructor(client: OpenAI, phClient: PostHog);
59
65
  create(body: ResponsesCreateParamsNonStreaming & MonitoringParams, options?: RequestOptions): APIPromise<OpenAI.Responses.Response>;
60
66
  create(body: ResponsesCreateParamsStreaming & MonitoringParams, options?: RequestOptions): APIPromise<Stream<OpenAI.Responses.ResponseStreamEvent>>;
61
67
  create(body: ResponsesCreateParamsBase & MonitoringParams, options?: RequestOptions): APIPromise<OpenAI.Responses.Response | Stream<OpenAI.Responses.ResponseStreamEvent>>;
62
68
  parse<Params extends ResponsesCreateParamsBase, ParsedT = any>(body: Params & MonitoringParams, options?: RequestOptions): APIPromise<ParsedResponse<ParsedT>>;
63
69
  }
70
+ declare class WrappedEmbeddings extends Embeddings {
71
+ private readonly phClient;
72
+ private readonly baseURL;
73
+ constructor(client: OpenAI, phClient: PostHog);
74
+ create(body: EmbeddingCreateParams & MonitoringParams, options?: RequestOptions): APIPromise<CreateEmbeddingResponse>;
75
+ }
64
76
 
65
- export { PostHogOpenAI as OpenAI, PostHogOpenAI, WrappedChat, WrappedCompletions, WrappedResponses, PostHogOpenAI as default };
77
+ export { PostHogOpenAI as OpenAI, PostHogOpenAI, WrappedChat, WrappedCompletions, WrappedEmbeddings, WrappedResponses, PostHogOpenAI as default };
@@ -2,7 +2,7 @@ import { OpenAI } from 'openai';
2
2
  import { v4 } from 'uuid';
3
3
  import { Buffer } from 'buffer';
4
4
 
5
- var version = "6.2.0";
5
+ var version = "6.3.1";
6
6
 
7
7
  const STRING_FORMAT = 'utf8';
8
8
  const getModelParams = params => {
@@ -124,6 +124,11 @@ const extractAvailableToolCalls = (provider, params) => {
124
124
  return null;
125
125
  }
126
126
  };
127
+ let AIEvent = /*#__PURE__*/function (AIEvent) {
128
+ AIEvent["Generation"] = "$ai_generation";
129
+ AIEvent["Embedding"] = "$ai_embedding";
130
+ return AIEvent;
131
+ }({});
127
132
  function sanitizeValues(obj) {
128
133
  if (obj === undefined || obj === null) {
129
134
  return obj;
@@ -140,6 +145,7 @@ function sanitizeValues(obj) {
140
145
  }
141
146
  const sendEventToPosthog = async ({
142
147
  client,
148
+ eventType = AIEvent.Generation,
143
149
  distinctId,
144
150
  traceId,
145
151
  model,
@@ -201,7 +207,9 @@ const sendEventToPosthog = async ({
201
207
  $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),
202
208
  $ai_http_status: httpStatus,
203
209
  $ai_input_tokens: usage.inputTokens ?? 0,
204
- $ai_output_tokens: usage.outputTokens ?? 0,
210
+ ...(usage.outputTokens !== undefined ? {
211
+ $ai_output_tokens: usage.outputTokens
212
+ } : {}),
205
213
  ...additionalTokenValues,
206
214
  $ai_latency: latency,
207
215
  $ai_trace_id: traceId,
@@ -218,7 +226,7 @@ const sendEventToPosthog = async ({
218
226
  };
219
227
  const event = {
220
228
  distinctId: distinctId ?? traceId,
221
- event: '$ai_generation',
229
+ event: eventType,
222
230
  properties,
223
231
  groups: params.posthogGroups
224
232
  };
@@ -356,6 +364,7 @@ const sanitizeOpenAIResponse = data => {
356
364
  const Chat = OpenAI.Chat;
357
365
  const Completions = Chat.Completions;
358
366
  const Responses = OpenAI.Responses;
367
+ const Embeddings = OpenAI.Embeddings;
359
368
  class PostHogOpenAI extends OpenAI {
360
369
  constructor(config) {
361
370
  const {
@@ -366,6 +375,7 @@ class PostHogOpenAI extends OpenAI {
366
375
  this.phClient = posthog;
367
376
  this.chat = new WrappedChat(this, this.phClient);
368
377
  this.responses = new WrappedResponses(this, this.phClient);
378
+ this.embeddings = new WrappedEmbeddings(this, this.phClient);
369
379
  }
370
380
  }
371
381
  class WrappedChat extends Chat {
@@ -378,6 +388,7 @@ class WrappedCompletions extends Completions {
378
388
  constructor(client, phClient) {
379
389
  super(client);
380
390
  this.phClient = phClient;
391
+ this.baseURL = client.baseURL;
381
392
  }
382
393
 
383
394
  // --- Overload #1: Non-streaming
@@ -391,10 +402,6 @@ class WrappedCompletions extends Completions {
391
402
  const {
392
403
  posthogDistinctId,
393
404
  posthogTraceId,
394
- posthogProperties,
395
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
396
- posthogPrivacyMode = false,
397
- posthogGroups,
398
405
  posthogCaptureImmediate,
399
406
  ...openAIParams
400
407
  } = body;
@@ -511,7 +518,7 @@ class WrappedCompletions extends Completions {
511
518
  input: sanitizeOpenAI(openAIParams.messages),
512
519
  output: formattedOutput,
513
520
  latency,
514
- baseURL: this.baseURL ?? '',
521
+ baseURL: this.baseURL,
515
522
  params: body,
516
523
  httpStatus: 200,
517
524
  usage,
@@ -529,7 +536,7 @@ class WrappedCompletions extends Completions {
529
536
  input: sanitizeOpenAI(openAIParams.messages),
530
537
  output: [],
531
538
  latency: 0,
532
- baseURL: this.baseURL ?? '',
539
+ baseURL: this.baseURL,
533
540
  params: body,
534
541
  httpStatus,
535
542
  usage: {
@@ -562,7 +569,7 @@ class WrappedCompletions extends Completions {
562
569
  input: sanitizeOpenAI(openAIParams.messages),
563
570
  output: formatResponseOpenAI(result),
564
571
  latency,
565
- baseURL: this.baseURL ?? '',
572
+ baseURL: this.baseURL,
566
573
  params: body,
567
574
  httpStatus: 200,
568
575
  usage: {
@@ -587,7 +594,7 @@ class WrappedCompletions extends Completions {
587
594
  input: sanitizeOpenAI(openAIParams.messages),
588
595
  output: [],
589
596
  latency: 0,
590
- baseURL: this.baseURL ?? '',
597
+ baseURL: this.baseURL,
591
598
  params: body,
592
599
  httpStatus,
593
600
  usage: {
@@ -608,6 +615,7 @@ class WrappedResponses extends Responses {
608
615
  constructor(client, phClient) {
609
616
  super(client);
610
617
  this.phClient = phClient;
618
+ this.baseURL = client.baseURL;
611
619
  }
612
620
 
613
621
  // --- Overload #1: Non-streaming
@@ -621,10 +629,6 @@ class WrappedResponses extends Responses {
621
629
  const {
622
630
  posthogDistinctId,
623
631
  posthogTraceId,
624
- posthogProperties,
625
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
626
- posthogPrivacyMode = false,
627
- posthogGroups,
628
632
  posthogCaptureImmediate,
629
633
  ...openAIParams
630
634
  } = body;
@@ -667,7 +671,7 @@ class WrappedResponses extends Responses {
667
671
  input: sanitizeOpenAIResponse(openAIParams.input),
668
672
  output: finalContent,
669
673
  latency,
670
- baseURL: this.baseURL ?? '',
674
+ baseURL: this.baseURL,
671
675
  params: body,
672
676
  httpStatus: 200,
673
677
  usage,
@@ -686,7 +690,7 @@ class WrappedResponses extends Responses {
686
690
  input: sanitizeOpenAIResponse(openAIParams.input),
687
691
  output: [],
688
692
  latency: 0,
689
- baseURL: this.baseURL ?? '',
693
+ baseURL: this.baseURL,
690
694
  params: body,
691
695
  httpStatus,
692
696
  usage: {
@@ -720,7 +724,7 @@ class WrappedResponses extends Responses {
720
724
  output: result.output
721
725
  }),
722
726
  latency,
723
- baseURL: this.baseURL ?? '',
727
+ baseURL: this.baseURL,
724
728
  params: body,
725
729
  httpStatus: 200,
726
730
  usage: {
@@ -746,7 +750,7 @@ class WrappedResponses extends Responses {
746
750
  input: sanitizeOpenAIResponse(openAIParams.input),
747
751
  output: [],
748
752
  latency: 0,
749
- baseURL: this.baseURL ?? '',
753
+ baseURL: this.baseURL,
750
754
  params: body,
751
755
  httpStatus,
752
756
  usage: {
@@ -766,10 +770,6 @@ class WrappedResponses extends Responses {
766
770
  const {
767
771
  posthogDistinctId,
768
772
  posthogTraceId,
769
- posthogProperties,
770
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
771
- posthogPrivacyMode = false,
772
- posthogGroups,
773
773
  posthogCaptureImmediate,
774
774
  ...openAIParams
775
775
  } = body;
@@ -795,7 +795,7 @@ class WrappedResponses extends Responses {
795
795
  input: sanitizeOpenAIResponse(openAIParams.input),
796
796
  output: result.output,
797
797
  latency,
798
- baseURL: this.baseURL ?? '',
798
+ baseURL: this.baseURL,
799
799
  params: body,
800
800
  httpStatus: 200,
801
801
  usage: {
@@ -819,7 +819,7 @@ class WrappedResponses extends Responses {
819
819
  input: sanitizeOpenAIResponse(openAIParams.input),
820
820
  output: [],
821
821
  latency: 0,
822
- baseURL: this.baseURL ?? '',
822
+ baseURL: this.baseURL,
823
823
  params: body,
824
824
  httpStatus,
825
825
  usage: {
@@ -839,6 +839,73 @@ class WrappedResponses extends Responses {
839
839
  }
840
840
  }
841
841
  }
842
+ class WrappedEmbeddings extends Embeddings {
843
+ constructor(client, phClient) {
844
+ super(client);
845
+ this.phClient = phClient;
846
+ this.baseURL = client.baseURL;
847
+ }
848
+ create(body, options) {
849
+ const {
850
+ posthogDistinctId,
851
+ posthogTraceId,
852
+ posthogPrivacyMode = false,
853
+ posthogCaptureImmediate,
854
+ ...openAIParams
855
+ } = body;
856
+ const traceId = posthogTraceId ?? v4();
857
+ const startTime = Date.now();
858
+ const parentPromise = super.create(openAIParams, options);
859
+ const wrappedPromise = parentPromise.then(async result => {
860
+ const latency = (Date.now() - startTime) / 1000;
861
+ await sendEventToPosthog({
862
+ client: this.phClient,
863
+ eventType: AIEvent.Embedding,
864
+ distinctId: posthogDistinctId,
865
+ traceId,
866
+ model: openAIParams.model,
867
+ provider: 'openai',
868
+ input: withPrivacyMode(this.phClient, posthogPrivacyMode, openAIParams.input),
869
+ output: null,
870
+ // Embeddings don't have output content
871
+ latency,
872
+ baseURL: this.baseURL,
873
+ params: body,
874
+ httpStatus: 200,
875
+ usage: {
876
+ inputTokens: result.usage?.prompt_tokens ?? 0
877
+ },
878
+ captureImmediate: posthogCaptureImmediate
879
+ });
880
+ return result;
881
+ }, async error => {
882
+ const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
883
+ await sendEventToPosthog({
884
+ client: this.phClient,
885
+ eventType: AIEvent.Embedding,
886
+ distinctId: posthogDistinctId,
887
+ traceId,
888
+ model: openAIParams.model,
889
+ provider: 'openai',
890
+ input: withPrivacyMode(this.phClient, posthogPrivacyMode, openAIParams.input),
891
+ output: null,
892
+ // Embeddings don't have output content
893
+ latency: 0,
894
+ baseURL: this.baseURL,
895
+ params: body,
896
+ httpStatus,
897
+ usage: {
898
+ inputTokens: 0
899
+ },
900
+ isError: true,
901
+ error: JSON.stringify(error),
902
+ captureImmediate: posthogCaptureImmediate
903
+ });
904
+ throw error;
905
+ });
906
+ return wrappedPromise;
907
+ }
908
+ }
842
909
 
843
- export { PostHogOpenAI as OpenAI, PostHogOpenAI, WrappedChat, WrappedCompletions, WrappedResponses, PostHogOpenAI as default };
910
+ export { PostHogOpenAI as OpenAI, PostHogOpenAI, WrappedChat, WrappedCompletions, WrappedEmbeddings, WrappedResponses, PostHogOpenAI as default };
844
911
  //# sourceMappingURL=index.mjs.map