@posthog/ai 8.6.1 → 8.6.3
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/anthropic/index.cjs +334 -108
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +335 -109
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +121 -110
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +122 -111
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +237 -183
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +238 -184
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +19 -32
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.d.ts +1 -0
- package/dist/langchain/index.mjs +19 -32
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +351 -125
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +352 -126
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +24 -4
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.d.ts +1 -1
- package/dist/openai-agents/index.mjs +24 -4
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/otel/index.cjs +5 -3
- package/dist/otel/index.cjs.map +1 -1
- package/dist/otel/index.mjs +5 -3
- package/dist/otel/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +238 -186
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +239 -187
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/openai/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AzureOpenAI, OpenAI } from 'openai';
|
|
2
2
|
import { v4 } from 'uuid';
|
|
3
|
-
import { uuidv7 } from '@posthog/core';
|
|
3
|
+
import { toJsonSafeValue, uuidv7 } from '@posthog/core';
|
|
4
|
+
import { Stream } from 'openai/streaming';
|
|
4
5
|
|
|
5
6
|
// Type guards for safer type checking
|
|
6
7
|
|
|
@@ -533,7 +534,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
533
534
|
return messages;
|
|
534
535
|
}
|
|
535
536
|
|
|
536
|
-
var version = "8.6.
|
|
537
|
+
var version = "8.6.3";
|
|
537
538
|
|
|
538
539
|
const DEFAULT_MAX_DEPTH = 3;
|
|
539
540
|
const MAX_STACK_LINES = 20;
|
|
@@ -644,120 +645,131 @@ const warnIfPostHogAiGateway = baseURL => {
|
|
|
644
645
|
* so callers can re-throw the original error reference safely.
|
|
645
646
|
*/
|
|
646
647
|
const captureAiGeneration$1 = async (client, options) => {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
warnIfPostHogAiGateway(options.baseURL);
|
|
651
|
-
const traceId = options.traceId ?? v4();
|
|
652
|
-
const eventType = options.eventType ?? AIEvent.Generation;
|
|
653
|
-
const privacyMode = options.privacyMode ?? false;
|
|
654
|
-
const usage = options.usage ?? {};
|
|
655
|
-
const safeInput = sanitizeValues(options.input);
|
|
656
|
-
const safeOutput = sanitizeValues(options.output);
|
|
657
|
-
let httpStatus = options.httpStatus;
|
|
658
|
-
let errorData = {};
|
|
659
|
-
if (options.error) {
|
|
660
|
-
if (httpStatus === undefined) {
|
|
661
|
-
if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
|
|
662
|
-
httpStatus = options.error.status;
|
|
663
|
-
} else {
|
|
664
|
-
httpStatus = 500;
|
|
665
|
-
}
|
|
648
|
+
try {
|
|
649
|
+
if (!client.capture) {
|
|
650
|
+
return;
|
|
666
651
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
652
|
+
warnIfPostHogAiGateway(options.baseURL);
|
|
653
|
+
const traceId = options.traceId ?? v4();
|
|
654
|
+
const eventType = options.eventType ?? AIEvent.Generation;
|
|
655
|
+
const privacyMode = options.privacyMode ?? false;
|
|
656
|
+
const usage = options.usage ?? {};
|
|
657
|
+
|
|
658
|
+
// Check privacy before reading or traversing input/output. Besides avoiding
|
|
659
|
+
// needless work, this ensures hostile getters/proxies cannot observe a value
|
|
660
|
+
// that the caller explicitly requested us to redact.
|
|
661
|
+
const shouldRedact = withPrivacyMode(client, privacyMode, false) === null;
|
|
662
|
+
const safeInput = shouldRedact ? null : toJsonSafeValue(options.input);
|
|
663
|
+
const safeOutput = shouldRedact ? null : toJsonSafeValue(options.output);
|
|
664
|
+
let httpStatus = options.httpStatus;
|
|
665
|
+
let errorData = {};
|
|
666
|
+
if (options.error) {
|
|
667
|
+
if (httpStatus === undefined) {
|
|
668
|
+
if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
|
|
669
|
+
httpStatus = options.error.status;
|
|
670
|
+
} else {
|
|
671
|
+
httpStatus = 500;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
let exceptionId;
|
|
675
|
+
if (client.options?.enableExceptionAutocapture) {
|
|
676
|
+
exceptionId = uuidv7();
|
|
677
|
+
client.captureException(options.error, undefined, {
|
|
678
|
+
$ai_trace_id: traceId
|
|
679
|
+
}, exceptionId);
|
|
680
|
+
if (typeof options.error === 'object') {
|
|
681
|
+
;
|
|
682
|
+
options.error.__posthog_previously_captured_error = true;
|
|
683
|
+
}
|
|
675
684
|
}
|
|
685
|
+
errorData = {
|
|
686
|
+
$ai_is_error: true,
|
|
687
|
+
$ai_error: stringifyError(options.error),
|
|
688
|
+
$exception_event_id: exceptionId
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
httpStatus = httpStatus ?? 200;
|
|
692
|
+
let costOverrideData = {};
|
|
693
|
+
if (options.costOverride) {
|
|
694
|
+
const inputCostUSD = (options.costOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
|
|
695
|
+
const outputCostUSD = (options.costOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
|
|
696
|
+
costOverrideData = {
|
|
697
|
+
$ai_input_cost_usd: inputCostUSD,
|
|
698
|
+
$ai_output_cost_usd: outputCostUSD,
|
|
699
|
+
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
700
|
+
};
|
|
676
701
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
702
|
+
const additionalTokenValues = {
|
|
703
|
+
...(usage.reasoningTokens ? {
|
|
704
|
+
$ai_reasoning_tokens: usage.reasoningTokens
|
|
705
|
+
} : {}),
|
|
706
|
+
...(usage.cacheReadInputTokens ? {
|
|
707
|
+
$ai_cache_read_input_tokens: usage.cacheReadInputTokens
|
|
708
|
+
} : {}),
|
|
709
|
+
...(usage.cacheCreationInputTokens ? {
|
|
710
|
+
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
711
|
+
} : {}),
|
|
712
|
+
...(usage.webSearchCount ? {
|
|
713
|
+
$ai_web_search_count: usage.webSearchCount
|
|
714
|
+
} : {}),
|
|
715
|
+
...(usage.rawUsage ? {
|
|
716
|
+
$ai_usage: usage.rawUsage
|
|
717
|
+
} : {})
|
|
681
718
|
};
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
$
|
|
690
|
-
$
|
|
691
|
-
$
|
|
719
|
+
const properties = {
|
|
720
|
+
$ai_lib: 'posthog-ai',
|
|
721
|
+
$ai_lib_version: version,
|
|
722
|
+
$ai_provider: options.providerOverride ?? options.provider,
|
|
723
|
+
$ai_model: options.modelOverride ?? options.model,
|
|
724
|
+
$ai_model_parameters: options.modelParameters ?? {},
|
|
725
|
+
$ai_input: safeInput,
|
|
726
|
+
$ai_output_choices: safeOutput,
|
|
727
|
+
$ai_http_status: httpStatus,
|
|
728
|
+
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
729
|
+
...(usage.outputTokens !== undefined ? {
|
|
730
|
+
$ai_output_tokens: usage.outputTokens
|
|
731
|
+
} : {}),
|
|
732
|
+
...additionalTokenValues,
|
|
733
|
+
$ai_latency: options.latency ?? 0,
|
|
734
|
+
...(options.timeToFirstToken !== undefined ? {
|
|
735
|
+
$ai_time_to_first_token: options.timeToFirstToken
|
|
736
|
+
} : {}),
|
|
737
|
+
$ai_trace_id: traceId,
|
|
738
|
+
$ai_base_url: options.baseURL ?? '',
|
|
739
|
+
...options.properties,
|
|
740
|
+
$ai_tokens_source: getTokensSource(options.properties),
|
|
741
|
+
...(options.distinctId ? {} : {
|
|
742
|
+
$process_person_profile: false
|
|
743
|
+
}),
|
|
744
|
+
...(options.stopReason ? {
|
|
745
|
+
$ai_stop_reason: options.stopReason
|
|
746
|
+
} : {}),
|
|
747
|
+
...(options.tools ? {
|
|
748
|
+
$ai_tools: options.tools
|
|
749
|
+
} : {}),
|
|
750
|
+
...(options.completionId ? {
|
|
751
|
+
$ai_completion_id: options.completionId
|
|
752
|
+
} : {}),
|
|
753
|
+
...(options.providerMetadata && Object.keys(options.providerMetadata).length > 0 ? {
|
|
754
|
+
$ai_provider_metadata: options.providerMetadata
|
|
755
|
+
} : {}),
|
|
756
|
+
...errorData,
|
|
757
|
+
...costOverrideData
|
|
692
758
|
};
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
...(usage.rawUsage ? {
|
|
708
|
-
$ai_usage: usage.rawUsage
|
|
709
|
-
} : {})
|
|
710
|
-
};
|
|
711
|
-
const properties = {
|
|
712
|
-
$ai_lib: 'posthog-ai',
|
|
713
|
-
$ai_lib_version: version,
|
|
714
|
-
$ai_provider: options.providerOverride ?? options.provider,
|
|
715
|
-
$ai_model: options.modelOverride ?? options.model,
|
|
716
|
-
$ai_model_parameters: options.modelParameters ?? {},
|
|
717
|
-
$ai_input: withPrivacyMode(client, privacyMode, safeInput),
|
|
718
|
-
$ai_output_choices: withPrivacyMode(client, privacyMode, safeOutput),
|
|
719
|
-
$ai_http_status: httpStatus,
|
|
720
|
-
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
721
|
-
...(usage.outputTokens !== undefined ? {
|
|
722
|
-
$ai_output_tokens: usage.outputTokens
|
|
723
|
-
} : {}),
|
|
724
|
-
...additionalTokenValues,
|
|
725
|
-
$ai_latency: options.latency ?? 0,
|
|
726
|
-
...(options.timeToFirstToken !== undefined ? {
|
|
727
|
-
$ai_time_to_first_token: options.timeToFirstToken
|
|
728
|
-
} : {}),
|
|
729
|
-
$ai_trace_id: traceId,
|
|
730
|
-
$ai_base_url: options.baseURL ?? '',
|
|
731
|
-
...options.properties,
|
|
732
|
-
$ai_tokens_source: getTokensSource(options.properties),
|
|
733
|
-
...(options.distinctId ? {} : {
|
|
734
|
-
$process_person_profile: false
|
|
735
|
-
}),
|
|
736
|
-
...(options.stopReason ? {
|
|
737
|
-
$ai_stop_reason: options.stopReason
|
|
738
|
-
} : {}),
|
|
739
|
-
...(options.tools ? {
|
|
740
|
-
$ai_tools: options.tools
|
|
741
|
-
} : {}),
|
|
742
|
-
...(options.completionId ? {
|
|
743
|
-
$ai_completion_id: options.completionId
|
|
744
|
-
} : {}),
|
|
745
|
-
...(options.providerMetadata && Object.keys(options.providerMetadata).length > 0 ? {
|
|
746
|
-
$ai_provider_metadata: options.providerMetadata
|
|
747
|
-
} : {}),
|
|
748
|
-
...errorData,
|
|
749
|
-
...costOverrideData
|
|
750
|
-
};
|
|
751
|
-
const event = {
|
|
752
|
-
distinctId: options.distinctId ?? traceId,
|
|
753
|
-
event: eventType,
|
|
754
|
-
properties,
|
|
755
|
-
groups: options.groups
|
|
756
|
-
};
|
|
757
|
-
if (options.captureImmediate) {
|
|
758
|
-
await client.captureImmediate(event);
|
|
759
|
-
} else {
|
|
760
|
-
client.capture(event);
|
|
759
|
+
const event = {
|
|
760
|
+
distinctId: options.distinctId ?? traceId,
|
|
761
|
+
event: eventType,
|
|
762
|
+
properties,
|
|
763
|
+
groups: options.groups
|
|
764
|
+
};
|
|
765
|
+
if (options.captureImmediate) {
|
|
766
|
+
await client.captureImmediate(event);
|
|
767
|
+
} else {
|
|
768
|
+
client.capture(event);
|
|
769
|
+
}
|
|
770
|
+
} catch (error) {
|
|
771
|
+
// Telemetry failures must never affect the instrumented provider call.
|
|
772
|
+
console.warn('[PostHog AI] Failed to capture generation telemetry:', error);
|
|
761
773
|
}
|
|
762
774
|
};
|
|
763
775
|
|
|
@@ -834,6 +846,220 @@ function buildProviderMetadata(fields) {
|
|
|
834
846
|
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
835
847
|
}
|
|
836
848
|
|
|
849
|
+
/**
|
|
850
|
+
* Splits an SDK stream into a monitoring branch and a caller branch without
|
|
851
|
+
* allowing either branch to read ahead of the other. Unlike the SDKs' `tee()`
|
|
852
|
+
* implementations, this keeps at most one result in flight and makes caller
|
|
853
|
+
* cancellation terminate the monitoring branch and the source iterator.
|
|
854
|
+
*/
|
|
855
|
+
function monitoredStreamTee(source, createStream) {
|
|
856
|
+
const controller = source.controller ?? new AbortController();
|
|
857
|
+
const sourceIterator = source[Symbol.asyncIterator]();
|
|
858
|
+
const callerQueue = [];
|
|
859
|
+
let monitorPending;
|
|
860
|
+
let monitorActive = true;
|
|
861
|
+
let operationInFlight = false;
|
|
862
|
+
let terminalResult;
|
|
863
|
+
let bufferedMonitorResult;
|
|
864
|
+
let terminalError;
|
|
865
|
+
let hasTerminalError = false;
|
|
866
|
+
let cancellationPromise;
|
|
867
|
+
let abortListener;
|
|
868
|
+
const removeAbortListener = () => {
|
|
869
|
+
if (abortListener) {
|
|
870
|
+
controller.signal.removeEventListener('abort', abortListener);
|
|
871
|
+
abortListener = undefined;
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
const settleMonitorTerminal = () => {
|
|
875
|
+
if (!monitorPending) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
const pending = monitorPending;
|
|
879
|
+
monitorPending = undefined;
|
|
880
|
+
if (hasTerminalError) {
|
|
881
|
+
pending.reject(terminalError);
|
|
882
|
+
} else if (terminalResult) {
|
|
883
|
+
pending.resolve(terminalResult);
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
const settleCallersTerminal = () => {
|
|
887
|
+
while (callerQueue.length > 0) {
|
|
888
|
+
const pending = callerQueue.shift();
|
|
889
|
+
if (hasTerminalError) {
|
|
890
|
+
pending.reject(terminalError);
|
|
891
|
+
} else if (terminalResult) {
|
|
892
|
+
pending.resolve(terminalResult);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
const pump = () => {
|
|
897
|
+
if (operationInFlight || callerQueue.length === 0 || monitorActive && !monitorPending) {
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
const pendingCaller = callerQueue.shift();
|
|
901
|
+
const pendingMonitor = monitorPending;
|
|
902
|
+
monitorPending = undefined;
|
|
903
|
+
operationInFlight = true;
|
|
904
|
+
void sourceIterator.next().then(result => {
|
|
905
|
+
operationInFlight = false;
|
|
906
|
+
if (result.done) {
|
|
907
|
+
terminalResult = result;
|
|
908
|
+
removeAbortListener();
|
|
909
|
+
}
|
|
910
|
+
pendingCaller.resolve(result);
|
|
911
|
+
pendingMonitor?.resolve(result);
|
|
912
|
+
if (result.done) {
|
|
913
|
+
settleCallersTerminal();
|
|
914
|
+
} else {
|
|
915
|
+
pump();
|
|
916
|
+
}
|
|
917
|
+
}, error => {
|
|
918
|
+
operationInFlight = false;
|
|
919
|
+
terminalError = error;
|
|
920
|
+
hasTerminalError = true;
|
|
921
|
+
removeAbortListener();
|
|
922
|
+
pendingCaller.reject(error);
|
|
923
|
+
pendingMonitor?.reject(error);
|
|
924
|
+
settleCallersTerminal();
|
|
925
|
+
});
|
|
926
|
+
};
|
|
927
|
+
const monitoringStream = {
|
|
928
|
+
[Symbol.asyncIterator]() {
|
|
929
|
+
return {
|
|
930
|
+
next: () => {
|
|
931
|
+
if (hasTerminalError) {
|
|
932
|
+
return Promise.reject(terminalError);
|
|
933
|
+
}
|
|
934
|
+
if (terminalResult) {
|
|
935
|
+
return Promise.resolve(terminalResult);
|
|
936
|
+
}
|
|
937
|
+
if (bufferedMonitorResult) {
|
|
938
|
+
const result = bufferedMonitorResult;
|
|
939
|
+
bufferedMonitorResult = undefined;
|
|
940
|
+
return Promise.resolve(result);
|
|
941
|
+
}
|
|
942
|
+
return new Promise((resolve, reject) => {
|
|
943
|
+
monitorPending = {
|
|
944
|
+
resolve,
|
|
945
|
+
reject
|
|
946
|
+
};
|
|
947
|
+
pump();
|
|
948
|
+
});
|
|
949
|
+
},
|
|
950
|
+
return: async value => {
|
|
951
|
+
monitorActive = false;
|
|
952
|
+
monitorPending = undefined;
|
|
953
|
+
pump();
|
|
954
|
+
return {
|
|
955
|
+
done: true,
|
|
956
|
+
value: value
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
const cancelSource = value => {
|
|
963
|
+
if (cancellationPromise) {
|
|
964
|
+
return cancellationPromise;
|
|
965
|
+
}
|
|
966
|
+
removeAbortListener();
|
|
967
|
+
if (!controller.signal.aborted) {
|
|
968
|
+
controller.abort();
|
|
969
|
+
}
|
|
970
|
+
cancellationPromise = (async () => {
|
|
971
|
+
try {
|
|
972
|
+
const defaultResult = {
|
|
973
|
+
done: true,
|
|
974
|
+
value
|
|
975
|
+
};
|
|
976
|
+
const result = sourceIterator.return ? await sourceIterator.return(value) : defaultResult;
|
|
977
|
+
if (result.done) {
|
|
978
|
+
terminalResult = result;
|
|
979
|
+
removeAbortListener();
|
|
980
|
+
settleMonitorTerminal();
|
|
981
|
+
settleCallersTerminal();
|
|
982
|
+
} else if (monitorPending) {
|
|
983
|
+
monitorPending.resolve(result);
|
|
984
|
+
monitorPending = undefined;
|
|
985
|
+
cancellationPromise = undefined;
|
|
986
|
+
} else {
|
|
987
|
+
bufferedMonitorResult = result;
|
|
988
|
+
cancellationPromise = undefined;
|
|
989
|
+
}
|
|
990
|
+
return result;
|
|
991
|
+
} catch (error) {
|
|
992
|
+
terminalError = error;
|
|
993
|
+
hasTerminalError = true;
|
|
994
|
+
removeAbortListener();
|
|
995
|
+
settleMonitorTerminal();
|
|
996
|
+
settleCallersTerminal();
|
|
997
|
+
throw error;
|
|
998
|
+
}
|
|
999
|
+
})();
|
|
1000
|
+
// An AbortController cancellation has no caller awaiting this promise.
|
|
1001
|
+
void cancellationPromise.catch(() => undefined);
|
|
1002
|
+
return cancellationPromise;
|
|
1003
|
+
};
|
|
1004
|
+
abortListener = () => {
|
|
1005
|
+
void cancelSource();
|
|
1006
|
+
};
|
|
1007
|
+
if (controller.signal.aborted) {
|
|
1008
|
+
abortListener();
|
|
1009
|
+
} else {
|
|
1010
|
+
controller.signal.addEventListener('abort', abortListener, {
|
|
1011
|
+
once: true
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
const callerStream = createStream(() => ({
|
|
1015
|
+
next: () => {
|
|
1016
|
+
if (hasTerminalError) {
|
|
1017
|
+
return Promise.reject(terminalError);
|
|
1018
|
+
}
|
|
1019
|
+
if (terminalResult) {
|
|
1020
|
+
return Promise.resolve(terminalResult);
|
|
1021
|
+
}
|
|
1022
|
+
return new Promise((resolve, reject) => {
|
|
1023
|
+
callerQueue.push({
|
|
1024
|
+
resolve,
|
|
1025
|
+
reject
|
|
1026
|
+
});
|
|
1027
|
+
pump();
|
|
1028
|
+
});
|
|
1029
|
+
},
|
|
1030
|
+
return: value => cancelSource(value),
|
|
1031
|
+
throw: async error => {
|
|
1032
|
+
if (!sourceIterator.throw) {
|
|
1033
|
+
await cancelSource();
|
|
1034
|
+
throw error;
|
|
1035
|
+
}
|
|
1036
|
+
try {
|
|
1037
|
+
const result = await sourceIterator.throw(error);
|
|
1038
|
+
if (result.done) {
|
|
1039
|
+
terminalResult = result;
|
|
1040
|
+
removeAbortListener();
|
|
1041
|
+
settleCallersTerminal();
|
|
1042
|
+
}
|
|
1043
|
+
if (monitorPending) {
|
|
1044
|
+
monitorPending.resolve(result);
|
|
1045
|
+
monitorPending = undefined;
|
|
1046
|
+
} else {
|
|
1047
|
+
bufferedMonitorResult = result;
|
|
1048
|
+
}
|
|
1049
|
+
return result;
|
|
1050
|
+
} catch (sourceError) {
|
|
1051
|
+
terminalError = sourceError;
|
|
1052
|
+
hasTerminalError = true;
|
|
1053
|
+
removeAbortListener();
|
|
1054
|
+
settleMonitorTerminal();
|
|
1055
|
+
settleCallersTerminal();
|
|
1056
|
+
throw sourceError;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}), controller);
|
|
1060
|
+
return [monitoringStream, callerStream];
|
|
1061
|
+
}
|
|
1062
|
+
|
|
837
1063
|
class PostHogAzureOpenAI extends AzureOpenAI {
|
|
838
1064
|
constructor(config) {
|
|
839
1065
|
const {
|
|
@@ -876,8 +1102,8 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
876
1102
|
const parentPromise = super.create(openAIParams, options);
|
|
877
1103
|
if (openAIParams.stream) {
|
|
878
1104
|
return parentPromise.then(value => {
|
|
879
|
-
if (
|
|
880
|
-
const [stream1, stream2] = value
|
|
1105
|
+
if (Symbol.asyncIterator in value) {
|
|
1106
|
+
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
881
1107
|
(async () => {
|
|
882
1108
|
// Hoisted so the catch block can surface whatever was accumulated
|
|
883
1109
|
// from the streamed chunks before the failure.
|
|
@@ -1128,8 +1354,8 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1128
1354
|
const parentPromise = super.create(openAIParams, options);
|
|
1129
1355
|
if (openAIParams.stream) {
|
|
1130
1356
|
return parentPromise.then(value => {
|
|
1131
|
-
if (
|
|
1132
|
-
const [stream1, stream2] = value
|
|
1357
|
+
if (Symbol.asyncIterator in value) {
|
|
1358
|
+
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
1133
1359
|
(async () => {
|
|
1134
1360
|
// Hoisted so the catch block can surface the completion ID that
|
|
1135
1361
|
// was accumulated from the streamed chunks before the failure.
|
|
@@ -1163,12 +1389,12 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1163
1389
|
if (chunk.type === 'response.completed' && 'response' in chunk && chunk.response?.output && chunk.response.output.length > 0) {
|
|
1164
1390
|
finalContent = chunk.response.output;
|
|
1165
1391
|
}
|
|
1166
|
-
if ('
|
|
1392
|
+
if ('response' in chunk && chunk.response?.usage) {
|
|
1167
1393
|
usage = {
|
|
1168
|
-
inputTokens: chunk.usage.input_tokens ?? 0,
|
|
1169
|
-
outputTokens: chunk.usage.output_tokens ?? 0,
|
|
1170
|
-
reasoningTokens: chunk.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1171
|
-
cacheReadInputTokens: chunk.usage.input_tokens_details?.cached_tokens ?? 0
|
|
1394
|
+
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
1395
|
+
outputTokens: chunk.response.usage.output_tokens ?? 0,
|
|
1396
|
+
reasoningTokens: chunk.response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1397
|
+
cacheReadInputTokens: chunk.response.usage.input_tokens_details?.cached_tokens ?? 0
|
|
1172
1398
|
};
|
|
1173
1399
|
}
|
|
1174
1400
|
}
|
|
@@ -1459,8 +1685,8 @@ class WrappedCompletions extends Completions {
|
|
|
1459
1685
|
const parentPromise = super.create(openAIParams, options);
|
|
1460
1686
|
if (openAIParams.stream) {
|
|
1461
1687
|
const wrappedPromise = parentPromise.then(value => {
|
|
1462
|
-
if (
|
|
1463
|
-
const [stream1, stream2] = value
|
|
1688
|
+
if (Symbol.asyncIterator in value) {
|
|
1689
|
+
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
1464
1690
|
(async () => {
|
|
1465
1691
|
// Hoisted so the catch block can surface whatever was accumulated
|
|
1466
1692
|
// from the streamed chunks before the failure.
|
|
@@ -1740,8 +1966,8 @@ class WrappedResponses extends Responses {
|
|
|
1740
1966
|
const parentPromise = super.create(openAIParams, options);
|
|
1741
1967
|
if (openAIParams.stream) {
|
|
1742
1968
|
const wrappedPromise = parentPromise.then(value => {
|
|
1743
|
-
if (
|
|
1744
|
-
const [stream1, stream2] = value
|
|
1969
|
+
if (Symbol.asyncIterator in value) {
|
|
1970
|
+
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
1745
1971
|
(async () => {
|
|
1746
1972
|
// Hoisted so the catch block can surface the completion ID that
|
|
1747
1973
|
// was accumulated from the streamed chunks before the failure.
|
|
@@ -2073,8 +2299,8 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2073
2299
|
const parentPromise = openAIParams.stream ? super.create(openAIParams, options) : super.create(openAIParams, options);
|
|
2074
2300
|
if (openAIParams.stream) {
|
|
2075
2301
|
const wrappedPromise = parentPromise.then(value => {
|
|
2076
|
-
if (
|
|
2077
|
-
const [stream1, stream2] = value
|
|
2302
|
+
if (Symbol.asyncIterator in value) {
|
|
2303
|
+
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
2078
2304
|
(async () => {
|
|
2079
2305
|
try {
|
|
2080
2306
|
let finalContent = '';
|