@posthog/ai 7.21.0 → 8.0.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/README.md +21 -4
- package/dist/anthropic/index.cjs +1 -1
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +1 -1
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +2 -1
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.d.ts +1 -1
- package/dist/gemini/index.mjs +2 -2
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +72 -3500
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -276
- package/dist/index.mjs +72 -3473
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +4 -486
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +3 -465
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +529 -1
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.d.ts +40 -2
- package/dist/openai/index.mjs +530 -3
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +1 -1
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.mjs +1 -1
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/otel/index.cjs +14 -14
- package/dist/otel/index.cjs.map +1 -1
- package/dist/otel/index.d.ts +11 -16
- package/dist/otel/index.mjs +14 -14
- package/dist/otel/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +1 -1
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +1 -1
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +24 -9
package/dist/openai/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import OpenAIOrignal, { AzureOpenAI, APIPromise, OpenAI, ClientOptions } from 'openai';
|
|
2
2
|
import { PostHog } from 'posthog-node';
|
|
3
3
|
import { Stream } from 'openai/streaming';
|
|
4
4
|
import { ParsedResponse } from 'openai/resources/responses/responses';
|
|
@@ -24,6 +24,44 @@ interface CostOverride {
|
|
|
24
24
|
outputCost: number;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
type ChatCompletion$1 = OpenAIOrignal.ChatCompletion;
|
|
28
|
+
type ChatCompletionChunk$1 = OpenAIOrignal.ChatCompletionChunk;
|
|
29
|
+
type ChatCompletionCreateParamsBase$1 = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams;
|
|
30
|
+
type ChatCompletionCreateParamsNonStreaming$1 = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParamsNonStreaming;
|
|
31
|
+
type ChatCompletionCreateParamsStreaming$1 = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParamsStreaming;
|
|
32
|
+
type CreateEmbeddingResponse$1 = OpenAIOrignal.CreateEmbeddingResponse;
|
|
33
|
+
type EmbeddingCreateParams$1 = OpenAIOrignal.EmbeddingCreateParams;
|
|
34
|
+
interface MonitoringOpenAIConfig$1 {
|
|
35
|
+
apiKey: string;
|
|
36
|
+
posthog: PostHog;
|
|
37
|
+
baseURL?: string;
|
|
38
|
+
}
|
|
39
|
+
type RequestOptions$1 = Record<string, any>;
|
|
40
|
+
declare class PostHogAzureOpenAI extends AzureOpenAI {
|
|
41
|
+
private readonly phClient;
|
|
42
|
+
chat: WrappedChat$1;
|
|
43
|
+
embeddings: WrappedEmbeddings$1;
|
|
44
|
+
constructor(config: MonitoringOpenAIConfig$1);
|
|
45
|
+
}
|
|
46
|
+
declare class WrappedChat$1 extends AzureOpenAI.Chat {
|
|
47
|
+
constructor(parentClient: PostHogAzureOpenAI, phClient: PostHog);
|
|
48
|
+
completions: WrappedCompletions$1;
|
|
49
|
+
}
|
|
50
|
+
declare class WrappedCompletions$1 extends AzureOpenAI.Chat.Completions {
|
|
51
|
+
private readonly phClient;
|
|
52
|
+
private readonly baseURL;
|
|
53
|
+
constructor(client: AzureOpenAI, phClient: PostHog);
|
|
54
|
+
create(body: ChatCompletionCreateParamsNonStreaming$1 & MonitoringParams, options?: RequestOptions$1): APIPromise<ChatCompletion$1>;
|
|
55
|
+
create(body: ChatCompletionCreateParamsStreaming$1 & MonitoringParams, options?: RequestOptions$1): APIPromise<Stream<ChatCompletionChunk$1>>;
|
|
56
|
+
create(body: ChatCompletionCreateParamsBase$1 & MonitoringParams, options?: RequestOptions$1): APIPromise<ChatCompletion$1 | Stream<ChatCompletionChunk$1>>;
|
|
57
|
+
}
|
|
58
|
+
declare class WrappedEmbeddings$1 extends AzureOpenAI.Embeddings {
|
|
59
|
+
private readonly phClient;
|
|
60
|
+
private readonly baseURL;
|
|
61
|
+
constructor(client: AzureOpenAI, phClient: PostHog);
|
|
62
|
+
create(body: EmbeddingCreateParams$1 & MonitoringParams, options?: RequestOptions$1): APIPromise<CreateEmbeddingResponse$1>;
|
|
63
|
+
}
|
|
64
|
+
|
|
27
65
|
declare const Chat: typeof OpenAI.Chat;
|
|
28
66
|
declare const Completions: typeof OpenAI.Chat.Completions;
|
|
29
67
|
declare const Responses: typeof OpenAI.Responses;
|
|
@@ -98,4 +136,4 @@ declare class WrappedTranscriptions extends Transcriptions {
|
|
|
98
136
|
create(body: OpenAI.Audio.Transcriptions.TranscriptionCreateParams & MonitoringParams, options?: RequestOptions): APIPromise<OpenAI.Audio.Transcriptions.TranscriptionCreateResponse | string | Stream<OpenAI.Audio.Transcriptions.TranscriptionStreamEvent>>;
|
|
99
137
|
}
|
|
100
138
|
|
|
101
|
-
export { PostHogOpenAI as OpenAI, PostHogOpenAI, WrappedAudio, WrappedChat, WrappedCompletions, WrappedEmbeddings, WrappedResponses, WrappedTranscriptions, PostHogOpenAI as default };
|
|
139
|
+
export { PostHogAzureOpenAI as AzureOpenAI, PostHogOpenAI as OpenAI, PostHogOpenAI, WrappedAudio, WrappedChat, WrappedCompletions, WrappedEmbeddings, WrappedResponses, WrappedTranscriptions, PostHogOpenAI as default };
|
package/dist/openai/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OpenAI } from 'openai';
|
|
1
|
+
import { AzureOpenAI, OpenAI } from 'openai';
|
|
2
2
|
import { v4 } from 'uuid';
|
|
3
3
|
import { uuidv7 } from '@posthog/core';
|
|
4
4
|
|
|
@@ -530,7 +530,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
530
530
|
return messages;
|
|
531
531
|
}
|
|
532
532
|
|
|
533
|
-
var version = "
|
|
533
|
+
var version = "8.0.0";
|
|
534
534
|
|
|
535
535
|
const DEFAULT_MAX_DEPTH = 3;
|
|
536
536
|
const MAX_STACK_LINES = 20;
|
|
@@ -755,6 +755,533 @@ function buildProviderMetadata(fields) {
|
|
|
755
755
|
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
756
756
|
}
|
|
757
757
|
|
|
758
|
+
class PostHogAzureOpenAI extends AzureOpenAI {
|
|
759
|
+
constructor(config) {
|
|
760
|
+
const {
|
|
761
|
+
posthog,
|
|
762
|
+
...openAIConfig
|
|
763
|
+
} = config;
|
|
764
|
+
super(openAIConfig);
|
|
765
|
+
this.phClient = posthog;
|
|
766
|
+
this.chat = new WrappedChat$1(this, this.phClient);
|
|
767
|
+
this.embeddings = new WrappedEmbeddings$1(this, this.phClient);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
let WrappedChat$1 = class WrappedChat extends AzureOpenAI.Chat {
|
|
771
|
+
constructor(parentClient, phClient) {
|
|
772
|
+
super(parentClient);
|
|
773
|
+
this.completions = new WrappedCompletions$1(parentClient, phClient);
|
|
774
|
+
}
|
|
775
|
+
};
|
|
776
|
+
let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Completions {
|
|
777
|
+
constructor(client, phClient) {
|
|
778
|
+
super(client);
|
|
779
|
+
this.phClient = phClient;
|
|
780
|
+
this.baseURL = client.baseURL;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// --- Overload #1: Non-streaming
|
|
784
|
+
|
|
785
|
+
// --- Overload #2: Streaming
|
|
786
|
+
|
|
787
|
+
// --- Overload #3: Generic base
|
|
788
|
+
|
|
789
|
+
// --- Implementation Signature
|
|
790
|
+
create(body, options) {
|
|
791
|
+
const {
|
|
792
|
+
providerParams: openAIParams,
|
|
793
|
+
posthogParams
|
|
794
|
+
} = extractPosthogParams(body);
|
|
795
|
+
const startTime = Date.now();
|
|
796
|
+
const parentPromise = super.create(openAIParams, options);
|
|
797
|
+
if (openAIParams.stream) {
|
|
798
|
+
return parentPromise.then(value => {
|
|
799
|
+
if ('tee' in value) {
|
|
800
|
+
const [stream1, stream2] = value.tee();
|
|
801
|
+
(async () => {
|
|
802
|
+
// Hoisted so the catch block can surface whatever was accumulated
|
|
803
|
+
// from the streamed chunks before the failure.
|
|
804
|
+
let completionIdFromResponse;
|
|
805
|
+
let systemFingerprintFromResponse;
|
|
806
|
+
try {
|
|
807
|
+
const contentBlocks = [];
|
|
808
|
+
let accumulatedContent = '';
|
|
809
|
+
let modelFromResponse;
|
|
810
|
+
let firstTokenTime;
|
|
811
|
+
let usage = {
|
|
812
|
+
inputTokens: 0,
|
|
813
|
+
outputTokens: 0
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
// Map to track in-progress tool calls
|
|
817
|
+
const toolCallsInProgress = new Map();
|
|
818
|
+
for await (const chunk of stream1) {
|
|
819
|
+
// Extract model and completion metadata from chunk (Chat Completions chunks carry these fields)
|
|
820
|
+
if (!modelFromResponse && chunk.model) {
|
|
821
|
+
modelFromResponse = chunk.model;
|
|
822
|
+
}
|
|
823
|
+
if (!completionIdFromResponse && chunk.id) {
|
|
824
|
+
completionIdFromResponse = chunk.id;
|
|
825
|
+
}
|
|
826
|
+
if (!systemFingerprintFromResponse && chunk.system_fingerprint) {
|
|
827
|
+
systemFingerprintFromResponse = chunk.system_fingerprint;
|
|
828
|
+
}
|
|
829
|
+
const choice = chunk?.choices?.[0];
|
|
830
|
+
|
|
831
|
+
// Handle text content
|
|
832
|
+
const deltaContent = choice?.delta?.content;
|
|
833
|
+
if (deltaContent) {
|
|
834
|
+
if (firstTokenTime === undefined) {
|
|
835
|
+
firstTokenTime = Date.now();
|
|
836
|
+
}
|
|
837
|
+
accumulatedContent += deltaContent;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// Handle tool calls
|
|
841
|
+
const deltaToolCalls = choice?.delta?.tool_calls;
|
|
842
|
+
if (deltaToolCalls && Array.isArray(deltaToolCalls)) {
|
|
843
|
+
if (firstTokenTime === undefined) {
|
|
844
|
+
firstTokenTime = Date.now();
|
|
845
|
+
}
|
|
846
|
+
for (const toolCall of deltaToolCalls) {
|
|
847
|
+
const index = toolCall.index;
|
|
848
|
+
if (index !== undefined) {
|
|
849
|
+
if (!toolCallsInProgress.has(index)) {
|
|
850
|
+
// New tool call
|
|
851
|
+
toolCallsInProgress.set(index, {
|
|
852
|
+
id: toolCall.id || '',
|
|
853
|
+
name: toolCall.function?.name || '',
|
|
854
|
+
arguments: ''
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
const inProgressCall = toolCallsInProgress.get(index);
|
|
858
|
+
if (inProgressCall) {
|
|
859
|
+
// Update tool call data
|
|
860
|
+
if (toolCall.id) {
|
|
861
|
+
inProgressCall.id = toolCall.id;
|
|
862
|
+
}
|
|
863
|
+
if (toolCall.function?.name) {
|
|
864
|
+
inProgressCall.name = toolCall.function.name;
|
|
865
|
+
}
|
|
866
|
+
if (toolCall.function?.arguments) {
|
|
867
|
+
inProgressCall.arguments += toolCall.function.arguments;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// Handle usage information
|
|
875
|
+
if (chunk.usage) {
|
|
876
|
+
usage = {
|
|
877
|
+
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
878
|
+
outputTokens: chunk.usage.completion_tokens ?? 0,
|
|
879
|
+
reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
880
|
+
cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
// Build final content blocks
|
|
886
|
+
if (accumulatedContent) {
|
|
887
|
+
contentBlocks.push({
|
|
888
|
+
type: 'text',
|
|
889
|
+
text: accumulatedContent
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// Add completed tool calls to content blocks
|
|
894
|
+
for (const toolCall of toolCallsInProgress.values()) {
|
|
895
|
+
if (toolCall.name) {
|
|
896
|
+
contentBlocks.push({
|
|
897
|
+
type: 'function',
|
|
898
|
+
id: toolCall.id,
|
|
899
|
+
function: {
|
|
900
|
+
name: toolCall.name,
|
|
901
|
+
arguments: toolCall.arguments
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// Format output to match non-streaming version
|
|
908
|
+
const formattedOutput = contentBlocks.length > 0 ? [{
|
|
909
|
+
role: 'assistant',
|
|
910
|
+
content: contentBlocks
|
|
911
|
+
}] : [{
|
|
912
|
+
role: 'assistant',
|
|
913
|
+
content: [{
|
|
914
|
+
type: 'text',
|
|
915
|
+
text: ''
|
|
916
|
+
}]
|
|
917
|
+
}];
|
|
918
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
919
|
+
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
920
|
+
await captureAiGeneration(this.phClient, {
|
|
921
|
+
...posthogParams,
|
|
922
|
+
model: openAIParams.model ?? modelFromResponse,
|
|
923
|
+
provider: 'azure',
|
|
924
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
925
|
+
output: formattedOutput,
|
|
926
|
+
latency,
|
|
927
|
+
timeToFirstToken,
|
|
928
|
+
baseURL: this.baseURL,
|
|
929
|
+
modelParameters: getModelParams(body),
|
|
930
|
+
httpStatus: 200,
|
|
931
|
+
usage,
|
|
932
|
+
completionId: completionIdFromResponse,
|
|
933
|
+
providerMetadata: buildProviderMetadata({
|
|
934
|
+
systemFingerprint: systemFingerprintFromResponse
|
|
935
|
+
})
|
|
936
|
+
});
|
|
937
|
+
} catch (error) {
|
|
938
|
+
await captureAiGeneration(this.phClient, {
|
|
939
|
+
...posthogParams,
|
|
940
|
+
model: openAIParams.model,
|
|
941
|
+
provider: 'azure',
|
|
942
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
943
|
+
output: [],
|
|
944
|
+
latency: 0,
|
|
945
|
+
baseURL: this.baseURL,
|
|
946
|
+
modelParameters: getModelParams(body),
|
|
947
|
+
usage: {
|
|
948
|
+
inputTokens: 0,
|
|
949
|
+
outputTokens: 0
|
|
950
|
+
},
|
|
951
|
+
// If the stream fails mid-flight, surface whatever completion
|
|
952
|
+
// metadata the consumed chunks already provided so the error
|
|
953
|
+
// event can still be correlated to OpenAI's Logs dashboard.
|
|
954
|
+
completionId: completionIdFromResponse,
|
|
955
|
+
providerMetadata: buildProviderMetadata({
|
|
956
|
+
systemFingerprint: systemFingerprintFromResponse
|
|
957
|
+
}),
|
|
958
|
+
error: error
|
|
959
|
+
});
|
|
960
|
+
throw error;
|
|
961
|
+
}
|
|
962
|
+
})();
|
|
963
|
+
|
|
964
|
+
// Return the other stream to the user
|
|
965
|
+
return stream2;
|
|
966
|
+
}
|
|
967
|
+
return value;
|
|
968
|
+
});
|
|
969
|
+
} else {
|
|
970
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
971
|
+
if ('choices' in result) {
|
|
972
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
973
|
+
await captureAiGeneration(this.phClient, {
|
|
974
|
+
...posthogParams,
|
|
975
|
+
model: openAIParams.model ?? result.model,
|
|
976
|
+
provider: 'azure',
|
|
977
|
+
input: openAIParams.messages,
|
|
978
|
+
output: formatResponseOpenAI(result),
|
|
979
|
+
latency,
|
|
980
|
+
baseURL: this.baseURL,
|
|
981
|
+
modelParameters: getModelParams(body),
|
|
982
|
+
httpStatus: 200,
|
|
983
|
+
usage: {
|
|
984
|
+
inputTokens: result.usage?.prompt_tokens ?? 0,
|
|
985
|
+
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
986
|
+
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
987
|
+
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
988
|
+
},
|
|
989
|
+
completionId: result.id,
|
|
990
|
+
providerMetadata: buildProviderMetadata({
|
|
991
|
+
systemFingerprint: result.system_fingerprint,
|
|
992
|
+
requestId: extractRequestId(result)
|
|
993
|
+
})
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
return result;
|
|
997
|
+
}, async error => {
|
|
998
|
+
const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
|
|
999
|
+
await captureAiGeneration(this.phClient, {
|
|
1000
|
+
...posthogParams,
|
|
1001
|
+
model: openAIParams.model,
|
|
1002
|
+
provider: 'azure',
|
|
1003
|
+
input: openAIParams.messages,
|
|
1004
|
+
output: [],
|
|
1005
|
+
latency: 0,
|
|
1006
|
+
baseURL: this.baseURL,
|
|
1007
|
+
modelParameters: getModelParams(body),
|
|
1008
|
+
httpStatus,
|
|
1009
|
+
usage: {
|
|
1010
|
+
inputTokens: 0,
|
|
1011
|
+
outputTokens: 0
|
|
1012
|
+
},
|
|
1013
|
+
error
|
|
1014
|
+
});
|
|
1015
|
+
throw error;
|
|
1016
|
+
});
|
|
1017
|
+
return wrappedPromise;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
};
|
|
1021
|
+
let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
1022
|
+
constructor(client, phClient) {
|
|
1023
|
+
super(client);
|
|
1024
|
+
this.phClient = phClient;
|
|
1025
|
+
this.baseURL = client.baseURL;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
// --- Overload #1: Non-streaming
|
|
1029
|
+
|
|
1030
|
+
// --- Overload #2: Streaming
|
|
1031
|
+
|
|
1032
|
+
// --- Overload #3: Generic base
|
|
1033
|
+
|
|
1034
|
+
// --- Implementation Signature
|
|
1035
|
+
create(body, options) {
|
|
1036
|
+
const {
|
|
1037
|
+
providerParams: openAIParams,
|
|
1038
|
+
posthogParams
|
|
1039
|
+
} = extractPosthogParams(body);
|
|
1040
|
+
const startTime = Date.now();
|
|
1041
|
+
const parentPromise = super.create(openAIParams, options);
|
|
1042
|
+
if (openAIParams.stream) {
|
|
1043
|
+
return parentPromise.then(value => {
|
|
1044
|
+
if ('tee' in value && typeof value.tee === 'function') {
|
|
1045
|
+
const [stream1, stream2] = value.tee();
|
|
1046
|
+
(async () => {
|
|
1047
|
+
// Hoisted so the catch block can surface the completion ID that
|
|
1048
|
+
// was accumulated from the streamed chunks before the failure.
|
|
1049
|
+
let completionIdFromResponse;
|
|
1050
|
+
try {
|
|
1051
|
+
let finalContent = [];
|
|
1052
|
+
let modelFromResponse;
|
|
1053
|
+
let firstTokenTime;
|
|
1054
|
+
let usage = {
|
|
1055
|
+
inputTokens: 0,
|
|
1056
|
+
outputTokens: 0
|
|
1057
|
+
};
|
|
1058
|
+
for await (const chunk of stream1) {
|
|
1059
|
+
// Track first token time on content delta events
|
|
1060
|
+
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
1061
|
+
firstTokenTime = Date.now();
|
|
1062
|
+
}
|
|
1063
|
+
if ('response' in chunk && chunk.response) {
|
|
1064
|
+
// Extract model and completion ID from the response object in the chunk (for stored prompts)
|
|
1065
|
+
if (!modelFromResponse && chunk.response.model) {
|
|
1066
|
+
modelFromResponse = chunk.response.model;
|
|
1067
|
+
}
|
|
1068
|
+
if (!completionIdFromResponse && chunk.response.id) {
|
|
1069
|
+
completionIdFromResponse = chunk.response.id;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
if (chunk.type === 'response.completed' && 'response' in chunk && chunk.response?.output && chunk.response.output.length > 0) {
|
|
1073
|
+
finalContent = chunk.response.output;
|
|
1074
|
+
}
|
|
1075
|
+
if ('usage' in chunk && chunk.usage) {
|
|
1076
|
+
usage = {
|
|
1077
|
+
inputTokens: chunk.usage.input_tokens ?? 0,
|
|
1078
|
+
outputTokens: chunk.usage.output_tokens ?? 0,
|
|
1079
|
+
reasoningTokens: chunk.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1080
|
+
cacheReadInputTokens: chunk.usage.input_tokens_details?.cached_tokens ?? 0
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
1085
|
+
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
1086
|
+
await captureAiGeneration(this.phClient, {
|
|
1087
|
+
...posthogParams,
|
|
1088
|
+
model: openAIParams.model ?? modelFromResponse,
|
|
1089
|
+
provider: 'azure',
|
|
1090
|
+
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1091
|
+
output: finalContent,
|
|
1092
|
+
latency,
|
|
1093
|
+
timeToFirstToken,
|
|
1094
|
+
baseURL: this.baseURL,
|
|
1095
|
+
modelParameters: getModelParams(body),
|
|
1096
|
+
httpStatus: 200,
|
|
1097
|
+
usage,
|
|
1098
|
+
completionId: completionIdFromResponse
|
|
1099
|
+
});
|
|
1100
|
+
} catch (error) {
|
|
1101
|
+
await captureAiGeneration(this.phClient, {
|
|
1102
|
+
...posthogParams,
|
|
1103
|
+
model: openAIParams.model,
|
|
1104
|
+
provider: 'azure',
|
|
1105
|
+
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1106
|
+
output: [],
|
|
1107
|
+
latency: 0,
|
|
1108
|
+
baseURL: this.baseURL,
|
|
1109
|
+
modelParameters: getModelParams(body),
|
|
1110
|
+
usage: {
|
|
1111
|
+
inputTokens: 0,
|
|
1112
|
+
outputTokens: 0
|
|
1113
|
+
},
|
|
1114
|
+
// Surface the completion ID from any chunks consumed before
|
|
1115
|
+
// the stream failed so the error event remains correlatable.
|
|
1116
|
+
completionId: completionIdFromResponse,
|
|
1117
|
+
error: error
|
|
1118
|
+
});
|
|
1119
|
+
throw error;
|
|
1120
|
+
}
|
|
1121
|
+
})();
|
|
1122
|
+
return stream2;
|
|
1123
|
+
}
|
|
1124
|
+
return value;
|
|
1125
|
+
});
|
|
1126
|
+
} else {
|
|
1127
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
1128
|
+
if ('output' in result) {
|
|
1129
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
1130
|
+
await captureAiGeneration(this.phClient, {
|
|
1131
|
+
...posthogParams,
|
|
1132
|
+
model: openAIParams.model ?? result.model,
|
|
1133
|
+
provider: 'azure',
|
|
1134
|
+
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1135
|
+
output: result.output,
|
|
1136
|
+
latency,
|
|
1137
|
+
baseURL: this.baseURL,
|
|
1138
|
+
modelParameters: getModelParams(body),
|
|
1139
|
+
httpStatus: 200,
|
|
1140
|
+
usage: {
|
|
1141
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1142
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1143
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1144
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1145
|
+
},
|
|
1146
|
+
completionId: result.id,
|
|
1147
|
+
providerMetadata: buildProviderMetadata({
|
|
1148
|
+
requestId: extractRequestId(result)
|
|
1149
|
+
})
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
return result;
|
|
1153
|
+
}, async error => {
|
|
1154
|
+
const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
|
|
1155
|
+
await captureAiGeneration(this.phClient, {
|
|
1156
|
+
...posthogParams,
|
|
1157
|
+
model: openAIParams.model,
|
|
1158
|
+
provider: 'azure',
|
|
1159
|
+
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1160
|
+
output: [],
|
|
1161
|
+
latency: 0,
|
|
1162
|
+
baseURL: this.baseURL,
|
|
1163
|
+
modelParameters: getModelParams(body),
|
|
1164
|
+
httpStatus,
|
|
1165
|
+
usage: {
|
|
1166
|
+
inputTokens: 0,
|
|
1167
|
+
outputTokens: 0
|
|
1168
|
+
},
|
|
1169
|
+
error
|
|
1170
|
+
});
|
|
1171
|
+
throw error;
|
|
1172
|
+
});
|
|
1173
|
+
return wrappedPromise;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
parse(body, options) {
|
|
1177
|
+
const {
|
|
1178
|
+
providerParams: openAIParams,
|
|
1179
|
+
posthogParams
|
|
1180
|
+
} = extractPosthogParams(body);
|
|
1181
|
+
const startTime = Date.now();
|
|
1182
|
+
const parentPromise = super.parse(openAIParams, options);
|
|
1183
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
1184
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
1185
|
+
await captureAiGeneration(this.phClient, {
|
|
1186
|
+
...posthogParams,
|
|
1187
|
+
model: openAIParams.model ?? result.model,
|
|
1188
|
+
provider: 'azure',
|
|
1189
|
+
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1190
|
+
output: result.output,
|
|
1191
|
+
latency,
|
|
1192
|
+
baseURL: this.baseURL,
|
|
1193
|
+
modelParameters: getModelParams(body),
|
|
1194
|
+
httpStatus: 200,
|
|
1195
|
+
usage: {
|
|
1196
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1197
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1198
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1199
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1200
|
+
},
|
|
1201
|
+
completionId: result.id,
|
|
1202
|
+
providerMetadata: buildProviderMetadata({
|
|
1203
|
+
requestId: extractRequestId(result)
|
|
1204
|
+
})
|
|
1205
|
+
});
|
|
1206
|
+
return result;
|
|
1207
|
+
}, async error => {
|
|
1208
|
+
await captureAiGeneration(this.phClient, {
|
|
1209
|
+
...posthogParams,
|
|
1210
|
+
model: openAIParams.model,
|
|
1211
|
+
provider: 'azure',
|
|
1212
|
+
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1213
|
+
output: [],
|
|
1214
|
+
latency: 0,
|
|
1215
|
+
baseURL: this.baseURL,
|
|
1216
|
+
modelParameters: getModelParams(body),
|
|
1217
|
+
httpStatus: error?.status ? error.status : 500,
|
|
1218
|
+
usage: {
|
|
1219
|
+
inputTokens: 0,
|
|
1220
|
+
outputTokens: 0
|
|
1221
|
+
},
|
|
1222
|
+
error
|
|
1223
|
+
});
|
|
1224
|
+
throw error;
|
|
1225
|
+
});
|
|
1226
|
+
return wrappedPromise;
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
let WrappedEmbeddings$1 = class WrappedEmbeddings extends AzureOpenAI.Embeddings {
|
|
1230
|
+
constructor(client, phClient) {
|
|
1231
|
+
super(client);
|
|
1232
|
+
this.phClient = phClient;
|
|
1233
|
+
this.baseURL = client.baseURL;
|
|
1234
|
+
}
|
|
1235
|
+
create(body, options) {
|
|
1236
|
+
const {
|
|
1237
|
+
providerParams: openAIParams,
|
|
1238
|
+
posthogParams
|
|
1239
|
+
} = extractPosthogParams(body);
|
|
1240
|
+
const startTime = Date.now();
|
|
1241
|
+
const parentPromise = super.create(openAIParams, options);
|
|
1242
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
1243
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
1244
|
+
await captureAiGeneration(this.phClient, {
|
|
1245
|
+
eventType: AIEvent.Embedding,
|
|
1246
|
+
...posthogParams,
|
|
1247
|
+
model: openAIParams.model,
|
|
1248
|
+
provider: 'azure',
|
|
1249
|
+
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
1250
|
+
output: null,
|
|
1251
|
+
// Embeddings don't have output content
|
|
1252
|
+
latency,
|
|
1253
|
+
baseURL: this.baseURL,
|
|
1254
|
+
modelParameters: getModelParams(body),
|
|
1255
|
+
httpStatus: 200,
|
|
1256
|
+
usage: {
|
|
1257
|
+
inputTokens: result.usage?.prompt_tokens ?? 0
|
|
1258
|
+
}
|
|
1259
|
+
});
|
|
1260
|
+
return result;
|
|
1261
|
+
}, async error => {
|
|
1262
|
+
const httpStatus = error && typeof error === 'object' && 'status' in error ? error.status ?? 500 : 500;
|
|
1263
|
+
await captureAiGeneration(this.phClient, {
|
|
1264
|
+
eventType: AIEvent.Embedding,
|
|
1265
|
+
...posthogParams,
|
|
1266
|
+
model: openAIParams.model,
|
|
1267
|
+
provider: 'azure',
|
|
1268
|
+
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
1269
|
+
output: null,
|
|
1270
|
+
latency: 0,
|
|
1271
|
+
baseURL: this.baseURL,
|
|
1272
|
+
modelParameters: getModelParams(body),
|
|
1273
|
+
httpStatus,
|
|
1274
|
+
usage: {
|
|
1275
|
+
inputTokens: 0
|
|
1276
|
+
},
|
|
1277
|
+
error
|
|
1278
|
+
});
|
|
1279
|
+
throw error;
|
|
1280
|
+
});
|
|
1281
|
+
return wrappedPromise;
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
|
|
758
1285
|
const Chat = OpenAI.Chat;
|
|
759
1286
|
const Completions = Chat.Completions;
|
|
760
1287
|
const Responses = OpenAI.Responses;
|
|
@@ -1538,5 +2065,5 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
1538
2065
|
}
|
|
1539
2066
|
}
|
|
1540
2067
|
|
|
1541
|
-
export { PostHogOpenAI as OpenAI, PostHogOpenAI, WrappedAudio, WrappedChat, WrappedCompletions, WrappedEmbeddings, WrappedResponses, WrappedTranscriptions, PostHogOpenAI as default };
|
|
2068
|
+
export { PostHogAzureOpenAI as AzureOpenAI, PostHogOpenAI as OpenAI, PostHogOpenAI, WrappedAudio, WrappedChat, WrappedCompletions, WrappedEmbeddings, WrappedResponses, WrappedTranscriptions, PostHogOpenAI as default };
|
|
1542
2069
|
//# sourceMappingURL=index.mjs.map
|