@posthog/ai 8.6.3 → 8.6.5
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 +98 -9
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.d.ts +2 -3
- package/dist/anthropic/index.mjs +98 -9
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +21 -9
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +21 -9
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +37 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +37 -31
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +16 -6
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +16 -6
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +255 -132
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.d.ts +2 -2
- package/dist/openai/index.mjs +255 -132
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +10 -2
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.mjs +10 -2
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/otel/index.cjs +15 -5
- package/dist/otel/index.cjs.map +1 -1
- package/dist/otel/index.mjs +15 -5
- package/dist/otel/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +37 -31
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +37 -31
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/openai/index.mjs
CHANGED
|
@@ -41,14 +41,16 @@ const FILE_FAMILY_TYPES = new Set(['file', 'input_file', 'document', 'media', 'f
|
|
|
41
41
|
const KNOWN_AUDIO_FORMATS = new Set(['wav', 'mp3', 'ogg', 'flac', 'm4a', 'aac', 'webm']);
|
|
42
42
|
class MediaTypeContext {
|
|
43
43
|
static EMPTY = new MediaTypeContext(undefined, undefined);
|
|
44
|
-
constructor(parent, key) {
|
|
44
|
+
constructor(parent, key, explicitMediaType) {
|
|
45
45
|
this.parent = parent;
|
|
46
46
|
this.key = key;
|
|
47
|
+
this.explicitMediaType = explicitMediaType;
|
|
47
48
|
}
|
|
48
49
|
inferMediaType() {
|
|
49
50
|
return this.inferFromSiblingMime() ?? this.inferFromSiblingFormat() ?? this.inferFromParentType() ?? this.inferFromKey();
|
|
50
51
|
}
|
|
51
52
|
inferFromSiblingMime() {
|
|
53
|
+
if (this.explicitMediaType) return this.explicitMediaType;
|
|
52
54
|
if (!this.parent) return undefined;
|
|
53
55
|
for (const hint of MIME_HINT_KEYS) {
|
|
54
56
|
const v = this.parent[hint];
|
|
@@ -83,7 +85,13 @@ class MediaTypeContext {
|
|
|
83
85
|
if (key.includes('file') || key.includes('document')) return 'application/octet-stream';
|
|
84
86
|
return undefined;
|
|
85
87
|
}
|
|
88
|
+
hasExplicitBinaryMediaType() {
|
|
89
|
+
if (!this.explicitMediaType && (!this.parent || !this.key || !STRONG_CONTEXT_KEYS.has(this.key))) return false;
|
|
90
|
+
const mediaType = this.inferFromSiblingMime();
|
|
91
|
+
return mediaType !== undefined && !mediaType.toLowerCase().startsWith('text/');
|
|
92
|
+
}
|
|
86
93
|
signalsBinary() {
|
|
94
|
+
if (this.explicitMediaType) return true;
|
|
87
95
|
if (this.parent) {
|
|
88
96
|
for (const hint of MIME_HINT_KEYS) {
|
|
89
97
|
if (typeof this.parent[hint] === 'string') return true;
|
|
@@ -105,10 +113,10 @@ class BinaryContentRedactor {
|
|
|
105
113
|
constructor(recognizer = new Base64Recognizer()) {
|
|
106
114
|
this.recognizer = recognizer;
|
|
107
115
|
}
|
|
108
|
-
redact(value) {
|
|
116
|
+
redact(value, mediaType) {
|
|
109
117
|
if (this.isMultimodalEnabled()) return value;
|
|
110
118
|
this.visited = new WeakSet();
|
|
111
|
-
return this.walk(value, MediaTypeContext.EMPTY);
|
|
119
|
+
return this.walk(value, mediaType ? new MediaTypeContext(undefined, undefined, mediaType) : MediaTypeContext.EMPTY);
|
|
112
120
|
}
|
|
113
121
|
walk(value, ctx) {
|
|
114
122
|
if (value === null || value === undefined) return value;
|
|
@@ -132,8 +140,10 @@ class BinaryContentRedactor {
|
|
|
132
140
|
return out;
|
|
133
141
|
}
|
|
134
142
|
redactString(value, ctx) {
|
|
135
|
-
const
|
|
136
|
-
const
|
|
143
|
+
const hasExplicitBinaryMediaType = ctx.hasExplicitBinaryMediaType();
|
|
144
|
+
const recognitionValue = hasExplicitBinaryMediaType ? value.replace(/[\r\n]/g, '') : value;
|
|
145
|
+
const minLength = hasExplicitBinaryMediaType ? Math.min(recognitionValue.length, STRONG_CONTEXT_MIN_LENGTH) : ctx.signalsBinary() ? STRONG_CONTEXT_MIN_LENGTH : WEAK_CONTEXT_MIN_LENGTH;
|
|
146
|
+
const recognition = this.recognizer.recognize(recognitionValue, minLength);
|
|
137
147
|
switch (recognition.kind) {
|
|
138
148
|
case 'data-url':
|
|
139
149
|
return this.placeholderFor(recognition.mediaType);
|
|
@@ -534,7 +544,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
534
544
|
return messages;
|
|
535
545
|
}
|
|
536
546
|
|
|
537
|
-
var version = "8.6.
|
|
547
|
+
var version = "8.6.5";
|
|
538
548
|
|
|
539
549
|
const DEFAULT_MAX_DEPTH = 3;
|
|
540
550
|
const MAX_STACK_LINES = 20;
|
|
@@ -667,6 +677,8 @@ const captureAiGeneration$1 = async (client, options) => {
|
|
|
667
677
|
if (httpStatus === undefined) {
|
|
668
678
|
if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
|
|
669
679
|
httpStatus = options.error.status;
|
|
680
|
+
} else if (typeof options.error === 'object' && 'statusCode' in options.error && typeof options.error.statusCode === 'number') {
|
|
681
|
+
httpStatus = options.error.statusCode;
|
|
670
682
|
} else {
|
|
671
683
|
httpStatus = 500;
|
|
672
684
|
}
|
|
@@ -832,7 +844,7 @@ function extractRequestId(result) {
|
|
|
832
844
|
* Assembles the `$ai_provider_metadata` blob for OpenAI / Azure OpenAI events.
|
|
833
845
|
* Provider-specific fields (system fingerprint, request id) live here rather
|
|
834
846
|
* than in the shared, provider-agnostic `$ai_*` namespace. Only keys with a
|
|
835
|
-
*
|
|
847
|
+
* meaningful value are included, and `undefined` is returned when there is nothing
|
|
836
848
|
* to report so the property can be omitted from the event entirely.
|
|
837
849
|
*/
|
|
838
850
|
function buildProviderMetadata(fields) {
|
|
@@ -843,8 +855,125 @@ function buildProviderMetadata(fields) {
|
|
|
843
855
|
if (fields.requestId) {
|
|
844
856
|
metadata.request_id = fields.requestId;
|
|
845
857
|
}
|
|
858
|
+
if (fields.incompleteDetails != null) {
|
|
859
|
+
metadata.incomplete_details = fields.incompleteDetails;
|
|
860
|
+
}
|
|
846
861
|
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
847
862
|
}
|
|
863
|
+
const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* Checks whether a Responses API response has reached a status that should
|
|
867
|
+
* produce a final `$ai_generation` event.
|
|
868
|
+
*/
|
|
869
|
+
function isTerminalResponse(response) {
|
|
870
|
+
return !!response?.status && TERMINAL_RESPONSE_STATUSES.has(response.status);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Returns an isolated copy of a failed Responses API error for `$ai_error`, or
|
|
875
|
+
* creates a fallback error when the provider omitted failure details.
|
|
876
|
+
*/
|
|
877
|
+
function getResponseFailure(response) {
|
|
878
|
+
if (response?.status !== 'failed') {
|
|
879
|
+
return undefined;
|
|
880
|
+
}
|
|
881
|
+
return response.error ? {
|
|
882
|
+
...response.error
|
|
883
|
+
} : new Error(`OpenAI response ${response.id} failed without error details`);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
function addRequestId(result, response, requestIdHeader) {
|
|
887
|
+
if (!result || typeof result !== 'object' || Array.isArray(result)) {
|
|
888
|
+
return result;
|
|
889
|
+
}
|
|
890
|
+
return Object.defineProperty(result, '_request_id', {
|
|
891
|
+
value: response.headers.get(requestIdHeader),
|
|
892
|
+
enumerable: false
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
function getResponsePropsPromise(parentPromise) {
|
|
896
|
+
const responsePromise = parentPromise.responsePromise;
|
|
897
|
+
if (!responsePromise || typeof responsePromise.then !== 'function') {
|
|
898
|
+
return undefined;
|
|
899
|
+
}
|
|
900
|
+
return responsePromise;
|
|
901
|
+
}
|
|
902
|
+
function decorateProviderPromise(wrappedPromise, responsePropsPromise, requestIdHeader, preserveThenUnwrap) {
|
|
903
|
+
const providerPromise = wrappedPromise;
|
|
904
|
+
if (responsePropsPromise) {
|
|
905
|
+
providerPromise.asResponse = async () => (await responsePropsPromise).response;
|
|
906
|
+
providerPromise.withResponse = async () => {
|
|
907
|
+
const [props, data] = await Promise.all([responsePropsPromise, wrappedPromise]);
|
|
908
|
+
return {
|
|
909
|
+
response: props.response,
|
|
910
|
+
data,
|
|
911
|
+
request_id: props.response.headers.get(requestIdHeader)
|
|
912
|
+
};
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
if (preserveThenUnwrap) {
|
|
916
|
+
providerPromise._thenUnwrap = transform => {
|
|
917
|
+
if (!responsePropsPromise) {
|
|
918
|
+
throw new Error('The provider promise response metadata is unavailable');
|
|
919
|
+
}
|
|
920
|
+
const transformedPromise = Promise.all([wrappedPromise, responsePropsPromise]).then(([data, props]) => addRequestId(transform(data, props), props.response, requestIdHeader));
|
|
921
|
+
return decorateProviderPromise(transformedPromise, responsePropsPromise, requestIdHeader, true);
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
return providerPromise;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Keep the provider SDK helpers on a promise whose resolved value is instrumented.
|
|
929
|
+
* OpenAI's parse helpers compose create calls through `_thenUnwrap`, while both
|
|
930
|
+
* OpenAI and Anthropic expose the raw response through `asResponse` and
|
|
931
|
+
* `withResponse`.
|
|
932
|
+
*/
|
|
933
|
+
|
|
934
|
+
function preserveProviderPromise(parentPromise, wrappedPromise, options = {}) {
|
|
935
|
+
const responsePropsPromise = getResponsePropsPromise(parentPromise);
|
|
936
|
+
const preserveThenUnwrap = typeof parentPromise._thenUnwrap === 'function';
|
|
937
|
+
const providerPromise = decorateProviderPromise(wrappedPromise, responsePropsPromise, options.requestIdHeader ?? 'x-request-id', preserveThenUnwrap);
|
|
938
|
+
if (!responsePropsPromise) {
|
|
939
|
+
const asResponse = parentPromise.asResponse?.bind(parentPromise);
|
|
940
|
+
if (asResponse) {
|
|
941
|
+
providerPromise.asResponse = asResponse;
|
|
942
|
+
}
|
|
943
|
+
const withResponse = parentPromise.withResponse?.bind(parentPromise);
|
|
944
|
+
if (withResponse) {
|
|
945
|
+
providerPromise.withResponse = async () => {
|
|
946
|
+
const [response, data] = await Promise.all([withResponse(), wrappedPromise]);
|
|
947
|
+
return {
|
|
948
|
+
...response,
|
|
949
|
+
data
|
|
950
|
+
};
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
return providerPromise;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* OpenAI's `Responses.parse` dispatches through `this._client.responses.create`.
|
|
959
|
+
* Temporarily use the provider's original `create` implementation so parsing a
|
|
960
|
+
* wrapped response does not capture the same request twice.
|
|
961
|
+
*/
|
|
962
|
+
function callWithOriginalCreate(resource, originalCreate, callback) {
|
|
963
|
+
const resourceRecord = resource;
|
|
964
|
+
const hadOwnCreate = Object.prototype.hasOwnProperty.call(resource, 'create');
|
|
965
|
+
const wrappedCreate = resourceRecord['create'];
|
|
966
|
+
resourceRecord['create'] = originalCreate;
|
|
967
|
+
try {
|
|
968
|
+
return callback();
|
|
969
|
+
} finally {
|
|
970
|
+
if (hadOwnCreate) {
|
|
971
|
+
resourceRecord['create'] = wrappedCreate;
|
|
972
|
+
} else {
|
|
973
|
+
delete resourceRecord['create'];
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
848
977
|
|
|
849
978
|
/**
|
|
850
979
|
* Splits an SDK stream into a monitoring branch and a caller branch without
|
|
@@ -1101,7 +1230,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1101
1230
|
const startTime = Date.now();
|
|
1102
1231
|
const parentPromise = super.create(openAIParams, options);
|
|
1103
1232
|
if (openAIParams.stream) {
|
|
1104
|
-
|
|
1233
|
+
const wrappedPromise = parentPromise.then(value => {
|
|
1105
1234
|
if (Symbol.asyncIterator in value) {
|
|
1106
1235
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
1107
1236
|
(async () => {
|
|
@@ -1232,7 +1361,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1232
1361
|
model: openAIParams.model ?? modelFromResponse,
|
|
1233
1362
|
provider: 'azure',
|
|
1234
1363
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1235
|
-
output: formattedOutput,
|
|
1364
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1236
1365
|
latency,
|
|
1237
1366
|
timeToFirstToken,
|
|
1238
1367
|
baseURL: this.baseURL,
|
|
@@ -1279,6 +1408,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1279
1408
|
}
|
|
1280
1409
|
return value;
|
|
1281
1410
|
});
|
|
1411
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1282
1412
|
} else {
|
|
1283
1413
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1284
1414
|
if ('choices' in result) {
|
|
@@ -1287,8 +1417,8 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1287
1417
|
...posthogParams,
|
|
1288
1418
|
model: openAIParams.model ?? result.model,
|
|
1289
1419
|
provider: 'azure',
|
|
1290
|
-
input: openAIParams.messages,
|
|
1291
|
-
output: formatResponseOpenAI(result),
|
|
1420
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
1421
|
+
output: sanitizeOpenAIResponse(formatResponseOpenAI(result)),
|
|
1292
1422
|
latency,
|
|
1293
1423
|
baseURL: this.baseURL,
|
|
1294
1424
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1313,7 +1443,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1313
1443
|
...posthogParams,
|
|
1314
1444
|
model: openAIParams.model,
|
|
1315
1445
|
provider: 'azure',
|
|
1316
|
-
input: openAIParams.messages,
|
|
1446
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
1317
1447
|
output: [],
|
|
1318
1448
|
latency: 0,
|
|
1319
1449
|
baseURL: this.baseURL,
|
|
@@ -1327,7 +1457,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1327
1457
|
});
|
|
1328
1458
|
throw error;
|
|
1329
1459
|
});
|
|
1330
|
-
return wrappedPromise;
|
|
1460
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1331
1461
|
}
|
|
1332
1462
|
}
|
|
1333
1463
|
};
|
|
@@ -1353,7 +1483,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1353
1483
|
const startTime = Date.now();
|
|
1354
1484
|
const parentPromise = super.create(openAIParams, options);
|
|
1355
1485
|
if (openAIParams.stream) {
|
|
1356
|
-
|
|
1486
|
+
const wrappedPromise = parentPromise.then(value => {
|
|
1357
1487
|
if (Symbol.asyncIterator in value) {
|
|
1358
1488
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
1359
1489
|
(async () => {
|
|
@@ -1369,6 +1499,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1369
1499
|
inputTokens: 0,
|
|
1370
1500
|
outputTokens: 0
|
|
1371
1501
|
};
|
|
1502
|
+
let terminalResponse;
|
|
1372
1503
|
for await (const chunk of stream1) {
|
|
1373
1504
|
// Track first token time on content delta events
|
|
1374
1505
|
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
@@ -1385,9 +1516,10 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1385
1516
|
if (chunk.response.service_tier != null) {
|
|
1386
1517
|
serviceTierFromResponse = chunk.response.service_tier;
|
|
1387
1518
|
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1519
|
+
if (isTerminalResponse(chunk.response)) {
|
|
1520
|
+
terminalResponse = chunk.response;
|
|
1521
|
+
finalContent = chunk.response.output ?? [];
|
|
1522
|
+
}
|
|
1391
1523
|
}
|
|
1392
1524
|
if ('response' in chunk && chunk.response?.usage) {
|
|
1393
1525
|
usage = {
|
|
@@ -1404,22 +1536,27 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1404
1536
|
...posthogParams,
|
|
1405
1537
|
model: openAIParams.model ?? modelFromResponse,
|
|
1406
1538
|
provider: 'azure',
|
|
1407
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1408
|
-
output: finalContent,
|
|
1539
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1540
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
1409
1541
|
latency,
|
|
1410
1542
|
timeToFirstToken,
|
|
1411
1543
|
baseURL: this.baseURL,
|
|
1412
1544
|
modelParameters: getModelParams(body, serviceTierFromResponse),
|
|
1413
1545
|
httpStatus: 200,
|
|
1414
1546
|
usage,
|
|
1415
|
-
|
|
1547
|
+
stopReason: terminalResponse?.status ?? undefined,
|
|
1548
|
+
completionId: completionIdFromResponse,
|
|
1549
|
+
providerMetadata: buildProviderMetadata({
|
|
1550
|
+
incompleteDetails: terminalResponse?.incomplete_details
|
|
1551
|
+
}),
|
|
1552
|
+
error: getResponseFailure(terminalResponse)
|
|
1416
1553
|
});
|
|
1417
1554
|
} catch (error) {
|
|
1418
1555
|
await captureAiGeneration(this.phClient, {
|
|
1419
1556
|
...posthogParams,
|
|
1420
1557
|
model: openAIParams.model,
|
|
1421
1558
|
provider: 'azure',
|
|
1422
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1559
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1423
1560
|
output: [],
|
|
1424
1561
|
latency: 0,
|
|
1425
1562
|
baseURL: this.baseURL,
|
|
@@ -1443,6 +1580,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1443
1580
|
}
|
|
1444
1581
|
return value;
|
|
1445
1582
|
});
|
|
1583
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1446
1584
|
} else {
|
|
1447
1585
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1448
1586
|
if ('output' in result) {
|
|
@@ -1451,8 +1589,8 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1451
1589
|
...posthogParams,
|
|
1452
1590
|
model: openAIParams.model ?? result.model,
|
|
1453
1591
|
provider: 'azure',
|
|
1454
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1455
|
-
output: result.output,
|
|
1592
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1593
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
1456
1594
|
latency,
|
|
1457
1595
|
baseURL: this.baseURL,
|
|
1458
1596
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1463,10 +1601,13 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1463
1601
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1464
1602
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1465
1603
|
},
|
|
1604
|
+
stopReason: result.status ?? undefined,
|
|
1466
1605
|
completionId: result.id,
|
|
1467
1606
|
providerMetadata: buildProviderMetadata({
|
|
1468
|
-
requestId: extractRequestId(result)
|
|
1469
|
-
|
|
1607
|
+
requestId: extractRequestId(result),
|
|
1608
|
+
incompleteDetails: result.incomplete_details
|
|
1609
|
+
}),
|
|
1610
|
+
error: getResponseFailure(result)
|
|
1470
1611
|
});
|
|
1471
1612
|
}
|
|
1472
1613
|
return result;
|
|
@@ -1476,7 +1617,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1476
1617
|
...posthogParams,
|
|
1477
1618
|
model: openAIParams.model,
|
|
1478
1619
|
provider: 'azure',
|
|
1479
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1620
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1480
1621
|
output: [],
|
|
1481
1622
|
latency: 0,
|
|
1482
1623
|
baseURL: this.baseURL,
|
|
@@ -1490,7 +1631,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1490
1631
|
});
|
|
1491
1632
|
throw error;
|
|
1492
1633
|
});
|
|
1493
|
-
return wrappedPromise;
|
|
1634
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1494
1635
|
}
|
|
1495
1636
|
}
|
|
1496
1637
|
parse(body, options) {
|
|
@@ -1499,15 +1640,15 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1499
1640
|
posthogParams
|
|
1500
1641
|
} = extractPosthogParams(body);
|
|
1501
1642
|
const startTime = Date.now();
|
|
1502
|
-
const parentPromise = super.parse(openAIParams, options);
|
|
1643
|
+
const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
|
|
1503
1644
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1504
1645
|
const latency = (Date.now() - startTime) / 1000;
|
|
1505
1646
|
await captureAiGeneration(this.phClient, {
|
|
1506
1647
|
...posthogParams,
|
|
1507
1648
|
model: openAIParams.model ?? result.model,
|
|
1508
1649
|
provider: 'azure',
|
|
1509
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1510
|
-
output: result.output,
|
|
1650
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1651
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
1511
1652
|
latency,
|
|
1512
1653
|
baseURL: this.baseURL,
|
|
1513
1654
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1518,10 +1659,13 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1518
1659
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1519
1660
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1520
1661
|
},
|
|
1662
|
+
stopReason: result.status ?? undefined,
|
|
1521
1663
|
completionId: result.id,
|
|
1522
1664
|
providerMetadata: buildProviderMetadata({
|
|
1523
|
-
requestId: extractRequestId(result)
|
|
1524
|
-
|
|
1665
|
+
requestId: extractRequestId(result),
|
|
1666
|
+
incompleteDetails: result.incomplete_details
|
|
1667
|
+
}),
|
|
1668
|
+
error: getResponseFailure(result)
|
|
1525
1669
|
});
|
|
1526
1670
|
return result;
|
|
1527
1671
|
}, async error => {
|
|
@@ -1529,7 +1673,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1529
1673
|
...posthogParams,
|
|
1530
1674
|
model: openAIParams.model,
|
|
1531
1675
|
provider: 'azure',
|
|
1532
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1676
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1533
1677
|
output: [],
|
|
1534
1678
|
latency: 0,
|
|
1535
1679
|
baseURL: this.baseURL,
|
|
@@ -1543,7 +1687,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1543
1687
|
});
|
|
1544
1688
|
throw error;
|
|
1545
1689
|
});
|
|
1546
|
-
return wrappedPromise;
|
|
1690
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1547
1691
|
}
|
|
1548
1692
|
};
|
|
1549
1693
|
let WrappedEmbeddings$1 = class WrappedEmbeddings extends AzureOpenAI.Embeddings {
|
|
@@ -1598,7 +1742,7 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends AzureOpenAI.Embeddings
|
|
|
1598
1742
|
});
|
|
1599
1743
|
throw error;
|
|
1600
1744
|
});
|
|
1601
|
-
return wrappedPromise;
|
|
1745
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1602
1746
|
}
|
|
1603
1747
|
};
|
|
1604
1748
|
|
|
@@ -1619,28 +1763,8 @@ async function captureAiGenerationAfterSuccess(...args) {
|
|
|
1619
1763
|
captureAiGenerationInBackground(...args);
|
|
1620
1764
|
}
|
|
1621
1765
|
}
|
|
1622
|
-
function preserveAPIPromiseHelpers(parentPromise, wrappedPromise) {
|
|
1623
|
-
const apiPromise = wrappedPromise;
|
|
1624
|
-
if (typeof parentPromise.asResponse === 'function') {
|
|
1625
|
-
apiPromise.asResponse = () => parentPromise.asResponse();
|
|
1626
|
-
}
|
|
1627
|
-
if (typeof parentPromise.withResponse === 'function') {
|
|
1628
|
-
apiPromise.withResponse = async () => {
|
|
1629
|
-
const [response, data] = await Promise.all([parentPromise.withResponse(), wrappedPromise]);
|
|
1630
|
-
// swaps the `data` payload inside the SDK's generic withResponse shape; the compiler
|
|
1631
|
-
// cannot relate the Input- and Output-instantiated conditional types
|
|
1632
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1633
|
-
return {
|
|
1634
|
-
...response,
|
|
1635
|
-
data
|
|
1636
|
-
};
|
|
1637
|
-
};
|
|
1638
|
-
}
|
|
1639
|
-
return apiPromise;
|
|
1640
|
-
}
|
|
1641
|
-
const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
|
|
1642
1766
|
function isPendingBackgroundResponse(params, response) {
|
|
1643
|
-
return params.background === true && !response.usage && !!response.status && !
|
|
1767
|
+
return params.background === true && !response.usage && !!response.status && !isTerminalResponse(response);
|
|
1644
1768
|
}
|
|
1645
1769
|
class PostHogOpenAI extends OpenAI {
|
|
1646
1770
|
constructor(config) {
|
|
@@ -1828,7 +1952,7 @@ class WrappedCompletions extends Completions {
|
|
|
1828
1952
|
model: openAIParams.model ?? modelFromResponse,
|
|
1829
1953
|
provider: 'openai',
|
|
1830
1954
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1831
|
-
output: formattedOutput,
|
|
1955
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1832
1956
|
latency,
|
|
1833
1957
|
timeToFirstToken,
|
|
1834
1958
|
baseURL: this.baseURL,
|
|
@@ -1884,7 +2008,7 @@ class WrappedCompletions extends Completions {
|
|
|
1884
2008
|
}
|
|
1885
2009
|
return value;
|
|
1886
2010
|
});
|
|
1887
|
-
return
|
|
2011
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1888
2012
|
} else {
|
|
1889
2013
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1890
2014
|
if ('choices' in result) {
|
|
@@ -1896,7 +2020,7 @@ class WrappedCompletions extends Completions {
|
|
|
1896
2020
|
model: openAIParams.model ?? result.model,
|
|
1897
2021
|
provider: 'openai',
|
|
1898
2022
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1899
|
-
output: formattedOutput,
|
|
2023
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1900
2024
|
latency,
|
|
1901
2025
|
baseURL: this.baseURL,
|
|
1902
2026
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1939,7 +2063,7 @@ class WrappedCompletions extends Completions {
|
|
|
1939
2063
|
});
|
|
1940
2064
|
throw error;
|
|
1941
2065
|
});
|
|
1942
|
-
return
|
|
2066
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1943
2067
|
}
|
|
1944
2068
|
}
|
|
1945
2069
|
}
|
|
@@ -1984,6 +2108,7 @@ class WrappedResponses extends Responses {
|
|
|
1984
2108
|
webSearchCount: 0
|
|
1985
2109
|
};
|
|
1986
2110
|
let rawUsageData;
|
|
2111
|
+
let terminalResponse;
|
|
1987
2112
|
for await (const chunk of stream1) {
|
|
1988
2113
|
// Track first token time on content delta events
|
|
1989
2114
|
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
@@ -2004,10 +2129,9 @@ class WrappedResponses extends Responses {
|
|
|
2004
2129
|
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2005
2130
|
usage.webSearchCount = chunkWebSearchCount;
|
|
2006
2131
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
if (chunk.response.status) {
|
|
2132
|
+
if (isTerminalResponse(chunk.response)) {
|
|
2133
|
+
terminalResponse = chunk.response;
|
|
2134
|
+
finalContent = chunk.response.output ?? [];
|
|
2011
2135
|
stopReason = chunk.response.status;
|
|
2012
2136
|
}
|
|
2013
2137
|
}
|
|
@@ -2030,7 +2154,7 @@ class WrappedResponses extends Responses {
|
|
|
2030
2154
|
model: openAIParams.model ?? modelFromResponse,
|
|
2031
2155
|
provider: 'openai',
|
|
2032
2156
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2033
|
-
output: finalContent,
|
|
2157
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
2034
2158
|
latency,
|
|
2035
2159
|
timeToFirstToken,
|
|
2036
2160
|
baseURL: this.baseURL,
|
|
@@ -2046,7 +2170,11 @@ class WrappedResponses extends Responses {
|
|
|
2046
2170
|
},
|
|
2047
2171
|
stopReason,
|
|
2048
2172
|
tools: availableTools,
|
|
2049
|
-
completionId: completionIdFromResponse
|
|
2173
|
+
completionId: completionIdFromResponse,
|
|
2174
|
+
providerMetadata: buildProviderMetadata({
|
|
2175
|
+
incompleteDetails: terminalResponse?.incomplete_details
|
|
2176
|
+
}),
|
|
2177
|
+
error: getResponseFailure(terminalResponse)
|
|
2050
2178
|
});
|
|
2051
2179
|
} catch (error) {
|
|
2052
2180
|
await captureAiGeneration(this.phClient, {
|
|
@@ -2077,7 +2205,7 @@ class WrappedResponses extends Responses {
|
|
|
2077
2205
|
}
|
|
2078
2206
|
return value;
|
|
2079
2207
|
});
|
|
2080
|
-
return
|
|
2208
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2081
2209
|
} else {
|
|
2082
2210
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2083
2211
|
if ('output' in result) {
|
|
@@ -2094,7 +2222,7 @@ class WrappedResponses extends Responses {
|
|
|
2094
2222
|
model: openAIParams.model ?? result.model,
|
|
2095
2223
|
provider: 'openai',
|
|
2096
2224
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2097
|
-
output: formattedOutput,
|
|
2225
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
2098
2226
|
latency,
|
|
2099
2227
|
baseURL: this.baseURL,
|
|
2100
2228
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -2111,8 +2239,10 @@ class WrappedResponses extends Responses {
|
|
|
2111
2239
|
tools: availableTools,
|
|
2112
2240
|
completionId: result.id,
|
|
2113
2241
|
providerMetadata: buildProviderMetadata({
|
|
2114
|
-
requestId: extractRequestId(result)
|
|
2115
|
-
|
|
2242
|
+
requestId: extractRequestId(result),
|
|
2243
|
+
incompleteDetails: result.incomplete_details
|
|
2244
|
+
}),
|
|
2245
|
+
error: getResponseFailure(result)
|
|
2116
2246
|
});
|
|
2117
2247
|
}
|
|
2118
2248
|
return result;
|
|
@@ -2136,7 +2266,7 @@ class WrappedResponses extends Responses {
|
|
|
2136
2266
|
});
|
|
2137
2267
|
throw error;
|
|
2138
2268
|
});
|
|
2139
|
-
return
|
|
2269
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2140
2270
|
}
|
|
2141
2271
|
}
|
|
2142
2272
|
parse(body, options) {
|
|
@@ -2145,64 +2275,57 @@ class WrappedResponses extends Responses {
|
|
|
2145
2275
|
posthogParams
|
|
2146
2276
|
} = extractPosthogParams(body);
|
|
2147
2277
|
const startTime = Date.now();
|
|
2148
|
-
const
|
|
2149
|
-
const
|
|
2150
|
-
|
|
2151
|
-
originalSelfRecord['create'] = originalCreate;
|
|
2152
|
-
try {
|
|
2153
|
-
const parentPromise = super.parse(openAIParams, options);
|
|
2154
|
-
const wrappedPromise = parentPromise.then(async result => {
|
|
2155
|
-
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
2156
|
-
return result;
|
|
2157
|
-
}
|
|
2158
|
-
const latency = (Date.now() - startTime) / 1000;
|
|
2159
|
-
await captureAiGeneration(this.phClient, {
|
|
2160
|
-
...posthogParams,
|
|
2161
|
-
model: openAIParams.model ?? result.model,
|
|
2162
|
-
provider: 'openai',
|
|
2163
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2164
|
-
output: result.output,
|
|
2165
|
-
latency,
|
|
2166
|
-
baseURL: this.baseURL,
|
|
2167
|
-
modelParameters: getModelParams(body, result.service_tier),
|
|
2168
|
-
httpStatus: 200,
|
|
2169
|
-
usage: {
|
|
2170
|
-
inputTokens: result.usage?.input_tokens ?? 0,
|
|
2171
|
-
outputTokens: result.usage?.output_tokens ?? 0,
|
|
2172
|
-
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2173
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
2174
|
-
rawUsage: result.usage
|
|
2175
|
-
},
|
|
2176
|
-
stopReason: result.status ?? undefined,
|
|
2177
|
-
completionId: result.id,
|
|
2178
|
-
providerMetadata: buildProviderMetadata({
|
|
2179
|
-
requestId: extractRequestId(result)
|
|
2180
|
-
})
|
|
2181
|
-
});
|
|
2278
|
+
const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
|
|
2279
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
2280
|
+
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
2182
2281
|
return result;
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2282
|
+
}
|
|
2283
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
2284
|
+
await captureAiGeneration(this.phClient, {
|
|
2285
|
+
...posthogParams,
|
|
2286
|
+
model: openAIParams.model ?? result.model,
|
|
2287
|
+
provider: 'openai',
|
|
2288
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2289
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
2290
|
+
latency,
|
|
2291
|
+
baseURL: this.baseURL,
|
|
2292
|
+
modelParameters: getModelParams(body, result.service_tier),
|
|
2293
|
+
httpStatus: 200,
|
|
2294
|
+
usage: {
|
|
2295
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
2296
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
2297
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2298
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
2299
|
+
rawUsage: result.usage
|
|
2300
|
+
},
|
|
2301
|
+
stopReason: result.status ?? undefined,
|
|
2302
|
+
completionId: result.id,
|
|
2303
|
+
providerMetadata: buildProviderMetadata({
|
|
2304
|
+
requestId: extractRequestId(result),
|
|
2305
|
+
incompleteDetails: result.incomplete_details
|
|
2306
|
+
}),
|
|
2307
|
+
error: getResponseFailure(result)
|
|
2200
2308
|
});
|
|
2201
|
-
return
|
|
2202
|
-
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2309
|
+
return result;
|
|
2310
|
+
}, async error => {
|
|
2311
|
+
await captureAiGeneration(this.phClient, {
|
|
2312
|
+
...posthogParams,
|
|
2313
|
+
model: openAIParams.model,
|
|
2314
|
+
provider: 'openai',
|
|
2315
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2316
|
+
output: [],
|
|
2317
|
+
latency: 0,
|
|
2318
|
+
baseURL: this.baseURL,
|
|
2319
|
+
modelParameters: getModelParams(body),
|
|
2320
|
+
usage: {
|
|
2321
|
+
inputTokens: 0,
|
|
2322
|
+
outputTokens: 0
|
|
2323
|
+
},
|
|
2324
|
+
error
|
|
2325
|
+
});
|
|
2326
|
+
throw error;
|
|
2327
|
+
});
|
|
2328
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2206
2329
|
}
|
|
2207
2330
|
}
|
|
2208
2331
|
class WrappedEmbeddings extends Embeddings {
|
|
@@ -2259,7 +2382,7 @@ class WrappedEmbeddings extends Embeddings {
|
|
|
2259
2382
|
});
|
|
2260
2383
|
throw error;
|
|
2261
2384
|
});
|
|
2262
|
-
return
|
|
2385
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2263
2386
|
}
|
|
2264
2387
|
}
|
|
2265
2388
|
class WrappedAudio extends Audio {
|
|
@@ -2334,7 +2457,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2334
2457
|
model: openAIParams.model,
|
|
2335
2458
|
provider: 'openai',
|
|
2336
2459
|
input: openAIParams.prompt,
|
|
2337
|
-
output: finalContent,
|
|
2460
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
2338
2461
|
latency,
|
|
2339
2462
|
timeToFirstToken,
|
|
2340
2463
|
baseURL: this.baseURL,
|
|
@@ -2369,7 +2492,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2369
2492
|
}
|
|
2370
2493
|
return value;
|
|
2371
2494
|
});
|
|
2372
|
-
return
|
|
2495
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2373
2496
|
} else {
|
|
2374
2497
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2375
2498
|
if (result && typeof result === 'object' && 'text' in result) {
|
|
@@ -2379,7 +2502,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2379
2502
|
model: openAIParams.model,
|
|
2380
2503
|
provider: 'openai',
|
|
2381
2504
|
input: openAIParams.prompt,
|
|
2382
|
-
output: result.text,
|
|
2505
|
+
output: sanitizeOpenAIResponse(result.text),
|
|
2383
2506
|
latency,
|
|
2384
2507
|
baseURL: this.baseURL,
|
|
2385
2508
|
modelParameters: getModelParams(body),
|
|
@@ -2410,7 +2533,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2410
2533
|
});
|
|
2411
2534
|
throw error;
|
|
2412
2535
|
});
|
|
2413
|
-
return
|
|
2536
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2414
2537
|
}
|
|
2415
2538
|
}
|
|
2416
2539
|
}
|