@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.cjs
CHANGED
|
@@ -45,14 +45,16 @@ const FILE_FAMILY_TYPES = new Set(['file', 'input_file', 'document', 'media', 'f
|
|
|
45
45
|
const KNOWN_AUDIO_FORMATS = new Set(['wav', 'mp3', 'ogg', 'flac', 'm4a', 'aac', 'webm']);
|
|
46
46
|
class MediaTypeContext {
|
|
47
47
|
static EMPTY = new MediaTypeContext(undefined, undefined);
|
|
48
|
-
constructor(parent, key) {
|
|
48
|
+
constructor(parent, key, explicitMediaType) {
|
|
49
49
|
this.parent = parent;
|
|
50
50
|
this.key = key;
|
|
51
|
+
this.explicitMediaType = explicitMediaType;
|
|
51
52
|
}
|
|
52
53
|
inferMediaType() {
|
|
53
54
|
return this.inferFromSiblingMime() ?? this.inferFromSiblingFormat() ?? this.inferFromParentType() ?? this.inferFromKey();
|
|
54
55
|
}
|
|
55
56
|
inferFromSiblingMime() {
|
|
57
|
+
if (this.explicitMediaType) return this.explicitMediaType;
|
|
56
58
|
if (!this.parent) return undefined;
|
|
57
59
|
for (const hint of MIME_HINT_KEYS) {
|
|
58
60
|
const v = this.parent[hint];
|
|
@@ -87,7 +89,13 @@ class MediaTypeContext {
|
|
|
87
89
|
if (key.includes('file') || key.includes('document')) return 'application/octet-stream';
|
|
88
90
|
return undefined;
|
|
89
91
|
}
|
|
92
|
+
hasExplicitBinaryMediaType() {
|
|
93
|
+
if (!this.explicitMediaType && (!this.parent || !this.key || !STRONG_CONTEXT_KEYS.has(this.key))) return false;
|
|
94
|
+
const mediaType = this.inferFromSiblingMime();
|
|
95
|
+
return mediaType !== undefined && !mediaType.toLowerCase().startsWith('text/');
|
|
96
|
+
}
|
|
90
97
|
signalsBinary() {
|
|
98
|
+
if (this.explicitMediaType) return true;
|
|
91
99
|
if (this.parent) {
|
|
92
100
|
for (const hint of MIME_HINT_KEYS) {
|
|
93
101
|
if (typeof this.parent[hint] === 'string') return true;
|
|
@@ -109,10 +117,10 @@ class BinaryContentRedactor {
|
|
|
109
117
|
constructor(recognizer = new Base64Recognizer()) {
|
|
110
118
|
this.recognizer = recognizer;
|
|
111
119
|
}
|
|
112
|
-
redact(value) {
|
|
120
|
+
redact(value, mediaType) {
|
|
113
121
|
if (this.isMultimodalEnabled()) return value;
|
|
114
122
|
this.visited = new WeakSet();
|
|
115
|
-
return this.walk(value, MediaTypeContext.EMPTY);
|
|
123
|
+
return this.walk(value, mediaType ? new MediaTypeContext(undefined, undefined, mediaType) : MediaTypeContext.EMPTY);
|
|
116
124
|
}
|
|
117
125
|
walk(value, ctx) {
|
|
118
126
|
if (value === null || value === undefined) return value;
|
|
@@ -136,8 +144,10 @@ class BinaryContentRedactor {
|
|
|
136
144
|
return out;
|
|
137
145
|
}
|
|
138
146
|
redactString(value, ctx) {
|
|
139
|
-
const
|
|
140
|
-
const
|
|
147
|
+
const hasExplicitBinaryMediaType = ctx.hasExplicitBinaryMediaType();
|
|
148
|
+
const recognitionValue = hasExplicitBinaryMediaType ? value.replace(/[\r\n]/g, '') : value;
|
|
149
|
+
const minLength = hasExplicitBinaryMediaType ? Math.min(recognitionValue.length, STRONG_CONTEXT_MIN_LENGTH) : ctx.signalsBinary() ? STRONG_CONTEXT_MIN_LENGTH : WEAK_CONTEXT_MIN_LENGTH;
|
|
150
|
+
const recognition = this.recognizer.recognize(recognitionValue, minLength);
|
|
141
151
|
switch (recognition.kind) {
|
|
142
152
|
case 'data-url':
|
|
143
153
|
return this.placeholderFor(recognition.mediaType);
|
|
@@ -538,7 +548,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
538
548
|
return messages;
|
|
539
549
|
}
|
|
540
550
|
|
|
541
|
-
var version = "8.6.
|
|
551
|
+
var version = "8.6.5";
|
|
542
552
|
|
|
543
553
|
const DEFAULT_MAX_DEPTH = 3;
|
|
544
554
|
const MAX_STACK_LINES = 20;
|
|
@@ -671,6 +681,8 @@ const captureAiGeneration$1 = async (client, options) => {
|
|
|
671
681
|
if (httpStatus === undefined) {
|
|
672
682
|
if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
|
|
673
683
|
httpStatus = options.error.status;
|
|
684
|
+
} else if (typeof options.error === 'object' && 'statusCode' in options.error && typeof options.error.statusCode === 'number') {
|
|
685
|
+
httpStatus = options.error.statusCode;
|
|
674
686
|
} else {
|
|
675
687
|
httpStatus = 500;
|
|
676
688
|
}
|
|
@@ -836,7 +848,7 @@ function extractRequestId(result) {
|
|
|
836
848
|
* Assembles the `$ai_provider_metadata` blob for OpenAI / Azure OpenAI events.
|
|
837
849
|
* Provider-specific fields (system fingerprint, request id) live here rather
|
|
838
850
|
* than in the shared, provider-agnostic `$ai_*` namespace. Only keys with a
|
|
839
|
-
*
|
|
851
|
+
* meaningful value are included, and `undefined` is returned when there is nothing
|
|
840
852
|
* to report so the property can be omitted from the event entirely.
|
|
841
853
|
*/
|
|
842
854
|
function buildProviderMetadata(fields) {
|
|
@@ -847,8 +859,125 @@ function buildProviderMetadata(fields) {
|
|
|
847
859
|
if (fields.requestId) {
|
|
848
860
|
metadata.request_id = fields.requestId;
|
|
849
861
|
}
|
|
862
|
+
if (fields.incompleteDetails != null) {
|
|
863
|
+
metadata.incomplete_details = fields.incompleteDetails;
|
|
864
|
+
}
|
|
850
865
|
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
851
866
|
}
|
|
867
|
+
const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Checks whether a Responses API response has reached a status that should
|
|
871
|
+
* produce a final `$ai_generation` event.
|
|
872
|
+
*/
|
|
873
|
+
function isTerminalResponse(response) {
|
|
874
|
+
return !!response?.status && TERMINAL_RESPONSE_STATUSES.has(response.status);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Returns an isolated copy of a failed Responses API error for `$ai_error`, or
|
|
879
|
+
* creates a fallback error when the provider omitted failure details.
|
|
880
|
+
*/
|
|
881
|
+
function getResponseFailure(response) {
|
|
882
|
+
if (response?.status !== 'failed') {
|
|
883
|
+
return undefined;
|
|
884
|
+
}
|
|
885
|
+
return response.error ? {
|
|
886
|
+
...response.error
|
|
887
|
+
} : new Error(`OpenAI response ${response.id} failed without error details`);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
function addRequestId(result, response, requestIdHeader) {
|
|
891
|
+
if (!result || typeof result !== 'object' || Array.isArray(result)) {
|
|
892
|
+
return result;
|
|
893
|
+
}
|
|
894
|
+
return Object.defineProperty(result, '_request_id', {
|
|
895
|
+
value: response.headers.get(requestIdHeader),
|
|
896
|
+
enumerable: false
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
function getResponsePropsPromise(parentPromise) {
|
|
900
|
+
const responsePromise = parentPromise.responsePromise;
|
|
901
|
+
if (!responsePromise || typeof responsePromise.then !== 'function') {
|
|
902
|
+
return undefined;
|
|
903
|
+
}
|
|
904
|
+
return responsePromise;
|
|
905
|
+
}
|
|
906
|
+
function decorateProviderPromise(wrappedPromise, responsePropsPromise, requestIdHeader, preserveThenUnwrap) {
|
|
907
|
+
const providerPromise = wrappedPromise;
|
|
908
|
+
if (responsePropsPromise) {
|
|
909
|
+
providerPromise.asResponse = async () => (await responsePropsPromise).response;
|
|
910
|
+
providerPromise.withResponse = async () => {
|
|
911
|
+
const [props, data] = await Promise.all([responsePropsPromise, wrappedPromise]);
|
|
912
|
+
return {
|
|
913
|
+
response: props.response,
|
|
914
|
+
data,
|
|
915
|
+
request_id: props.response.headers.get(requestIdHeader)
|
|
916
|
+
};
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
if (preserveThenUnwrap) {
|
|
920
|
+
providerPromise._thenUnwrap = transform => {
|
|
921
|
+
if (!responsePropsPromise) {
|
|
922
|
+
throw new Error('The provider promise response metadata is unavailable');
|
|
923
|
+
}
|
|
924
|
+
const transformedPromise = Promise.all([wrappedPromise, responsePropsPromise]).then(([data, props]) => addRequestId(transform(data, props), props.response, requestIdHeader));
|
|
925
|
+
return decorateProviderPromise(transformedPromise, responsePropsPromise, requestIdHeader, true);
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
return providerPromise;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* Keep the provider SDK helpers on a promise whose resolved value is instrumented.
|
|
933
|
+
* OpenAI's parse helpers compose create calls through `_thenUnwrap`, while both
|
|
934
|
+
* OpenAI and Anthropic expose the raw response through `asResponse` and
|
|
935
|
+
* `withResponse`.
|
|
936
|
+
*/
|
|
937
|
+
|
|
938
|
+
function preserveProviderPromise(parentPromise, wrappedPromise, options = {}) {
|
|
939
|
+
const responsePropsPromise = getResponsePropsPromise(parentPromise);
|
|
940
|
+
const preserveThenUnwrap = typeof parentPromise._thenUnwrap === 'function';
|
|
941
|
+
const providerPromise = decorateProviderPromise(wrappedPromise, responsePropsPromise, options.requestIdHeader ?? 'x-request-id', preserveThenUnwrap);
|
|
942
|
+
if (!responsePropsPromise) {
|
|
943
|
+
const asResponse = parentPromise.asResponse?.bind(parentPromise);
|
|
944
|
+
if (asResponse) {
|
|
945
|
+
providerPromise.asResponse = asResponse;
|
|
946
|
+
}
|
|
947
|
+
const withResponse = parentPromise.withResponse?.bind(parentPromise);
|
|
948
|
+
if (withResponse) {
|
|
949
|
+
providerPromise.withResponse = async () => {
|
|
950
|
+
const [response, data] = await Promise.all([withResponse(), wrappedPromise]);
|
|
951
|
+
return {
|
|
952
|
+
...response,
|
|
953
|
+
data
|
|
954
|
+
};
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
return providerPromise;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* OpenAI's `Responses.parse` dispatches through `this._client.responses.create`.
|
|
963
|
+
* Temporarily use the provider's original `create` implementation so parsing a
|
|
964
|
+
* wrapped response does not capture the same request twice.
|
|
965
|
+
*/
|
|
966
|
+
function callWithOriginalCreate(resource, originalCreate, callback) {
|
|
967
|
+
const resourceRecord = resource;
|
|
968
|
+
const hadOwnCreate = Object.prototype.hasOwnProperty.call(resource, 'create');
|
|
969
|
+
const wrappedCreate = resourceRecord['create'];
|
|
970
|
+
resourceRecord['create'] = originalCreate;
|
|
971
|
+
try {
|
|
972
|
+
return callback();
|
|
973
|
+
} finally {
|
|
974
|
+
if (hadOwnCreate) {
|
|
975
|
+
resourceRecord['create'] = wrappedCreate;
|
|
976
|
+
} else {
|
|
977
|
+
delete resourceRecord['create'];
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
}
|
|
852
981
|
|
|
853
982
|
/**
|
|
854
983
|
* Splits an SDK stream into a monitoring branch and a caller branch without
|
|
@@ -1105,7 +1234,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1105
1234
|
const startTime = Date.now();
|
|
1106
1235
|
const parentPromise = super.create(openAIParams, options);
|
|
1107
1236
|
if (openAIParams.stream) {
|
|
1108
|
-
|
|
1237
|
+
const wrappedPromise = parentPromise.then(value => {
|
|
1109
1238
|
if (Symbol.asyncIterator in value) {
|
|
1110
1239
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
|
|
1111
1240
|
(async () => {
|
|
@@ -1236,7 +1365,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1236
1365
|
model: openAIParams.model ?? modelFromResponse,
|
|
1237
1366
|
provider: 'azure',
|
|
1238
1367
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1239
|
-
output: formattedOutput,
|
|
1368
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1240
1369
|
latency,
|
|
1241
1370
|
timeToFirstToken,
|
|
1242
1371
|
baseURL: this.baseURL,
|
|
@@ -1283,6 +1412,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1283
1412
|
}
|
|
1284
1413
|
return value;
|
|
1285
1414
|
});
|
|
1415
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1286
1416
|
} else {
|
|
1287
1417
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1288
1418
|
if ('choices' in result) {
|
|
@@ -1291,8 +1421,8 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1291
1421
|
...posthogParams,
|
|
1292
1422
|
model: openAIParams.model ?? result.model,
|
|
1293
1423
|
provider: 'azure',
|
|
1294
|
-
input: openAIParams.messages,
|
|
1295
|
-
output: formatResponseOpenAI(result),
|
|
1424
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
1425
|
+
output: sanitizeOpenAIResponse(formatResponseOpenAI(result)),
|
|
1296
1426
|
latency,
|
|
1297
1427
|
baseURL: this.baseURL,
|
|
1298
1428
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1317,7 +1447,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1317
1447
|
...posthogParams,
|
|
1318
1448
|
model: openAIParams.model,
|
|
1319
1449
|
provider: 'azure',
|
|
1320
|
-
input: openAIParams.messages,
|
|
1450
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
1321
1451
|
output: [],
|
|
1322
1452
|
latency: 0,
|
|
1323
1453
|
baseURL: this.baseURL,
|
|
@@ -1331,7 +1461,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1331
1461
|
});
|
|
1332
1462
|
throw error;
|
|
1333
1463
|
});
|
|
1334
|
-
return wrappedPromise;
|
|
1464
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1335
1465
|
}
|
|
1336
1466
|
}
|
|
1337
1467
|
};
|
|
@@ -1357,7 +1487,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1357
1487
|
const startTime = Date.now();
|
|
1358
1488
|
const parentPromise = super.create(openAIParams, options);
|
|
1359
1489
|
if (openAIParams.stream) {
|
|
1360
|
-
|
|
1490
|
+
const wrappedPromise = parentPromise.then(value => {
|
|
1361
1491
|
if (Symbol.asyncIterator in value) {
|
|
1362
1492
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
|
|
1363
1493
|
(async () => {
|
|
@@ -1373,6 +1503,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1373
1503
|
inputTokens: 0,
|
|
1374
1504
|
outputTokens: 0
|
|
1375
1505
|
};
|
|
1506
|
+
let terminalResponse;
|
|
1376
1507
|
for await (const chunk of stream1) {
|
|
1377
1508
|
// Track first token time on content delta events
|
|
1378
1509
|
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
@@ -1389,9 +1520,10 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1389
1520
|
if (chunk.response.service_tier != null) {
|
|
1390
1521
|
serviceTierFromResponse = chunk.response.service_tier;
|
|
1391
1522
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1523
|
+
if (isTerminalResponse(chunk.response)) {
|
|
1524
|
+
terminalResponse = chunk.response;
|
|
1525
|
+
finalContent = chunk.response.output ?? [];
|
|
1526
|
+
}
|
|
1395
1527
|
}
|
|
1396
1528
|
if ('response' in chunk && chunk.response?.usage) {
|
|
1397
1529
|
usage = {
|
|
@@ -1408,22 +1540,27 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1408
1540
|
...posthogParams,
|
|
1409
1541
|
model: openAIParams.model ?? modelFromResponse,
|
|
1410
1542
|
provider: 'azure',
|
|
1411
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1412
|
-
output: finalContent,
|
|
1543
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1544
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
1413
1545
|
latency,
|
|
1414
1546
|
timeToFirstToken,
|
|
1415
1547
|
baseURL: this.baseURL,
|
|
1416
1548
|
modelParameters: getModelParams(body, serviceTierFromResponse),
|
|
1417
1549
|
httpStatus: 200,
|
|
1418
1550
|
usage,
|
|
1419
|
-
|
|
1551
|
+
stopReason: terminalResponse?.status ?? undefined,
|
|
1552
|
+
completionId: completionIdFromResponse,
|
|
1553
|
+
providerMetadata: buildProviderMetadata({
|
|
1554
|
+
incompleteDetails: terminalResponse?.incomplete_details
|
|
1555
|
+
}),
|
|
1556
|
+
error: getResponseFailure(terminalResponse)
|
|
1420
1557
|
});
|
|
1421
1558
|
} catch (error) {
|
|
1422
1559
|
await captureAiGeneration(this.phClient, {
|
|
1423
1560
|
...posthogParams,
|
|
1424
1561
|
model: openAIParams.model,
|
|
1425
1562
|
provider: 'azure',
|
|
1426
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1563
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1427
1564
|
output: [],
|
|
1428
1565
|
latency: 0,
|
|
1429
1566
|
baseURL: this.baseURL,
|
|
@@ -1447,6 +1584,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1447
1584
|
}
|
|
1448
1585
|
return value;
|
|
1449
1586
|
});
|
|
1587
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1450
1588
|
} else {
|
|
1451
1589
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1452
1590
|
if ('output' in result) {
|
|
@@ -1455,8 +1593,8 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1455
1593
|
...posthogParams,
|
|
1456
1594
|
model: openAIParams.model ?? result.model,
|
|
1457
1595
|
provider: 'azure',
|
|
1458
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1459
|
-
output: result.output,
|
|
1596
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1597
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
1460
1598
|
latency,
|
|
1461
1599
|
baseURL: this.baseURL,
|
|
1462
1600
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1467,10 +1605,13 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1467
1605
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1468
1606
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1469
1607
|
},
|
|
1608
|
+
stopReason: result.status ?? undefined,
|
|
1470
1609
|
completionId: result.id,
|
|
1471
1610
|
providerMetadata: buildProviderMetadata({
|
|
1472
|
-
requestId: extractRequestId(result)
|
|
1473
|
-
|
|
1611
|
+
requestId: extractRequestId(result),
|
|
1612
|
+
incompleteDetails: result.incomplete_details
|
|
1613
|
+
}),
|
|
1614
|
+
error: getResponseFailure(result)
|
|
1474
1615
|
});
|
|
1475
1616
|
}
|
|
1476
1617
|
return result;
|
|
@@ -1480,7 +1621,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1480
1621
|
...posthogParams,
|
|
1481
1622
|
model: openAIParams.model,
|
|
1482
1623
|
provider: 'azure',
|
|
1483
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1624
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1484
1625
|
output: [],
|
|
1485
1626
|
latency: 0,
|
|
1486
1627
|
baseURL: this.baseURL,
|
|
@@ -1494,7 +1635,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1494
1635
|
});
|
|
1495
1636
|
throw error;
|
|
1496
1637
|
});
|
|
1497
|
-
return wrappedPromise;
|
|
1638
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1498
1639
|
}
|
|
1499
1640
|
}
|
|
1500
1641
|
parse(body, options) {
|
|
@@ -1503,15 +1644,15 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1503
1644
|
posthogParams
|
|
1504
1645
|
} = extractPosthogParams(body);
|
|
1505
1646
|
const startTime = Date.now();
|
|
1506
|
-
const parentPromise = super.parse(openAIParams, options);
|
|
1647
|
+
const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
|
|
1507
1648
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1508
1649
|
const latency = (Date.now() - startTime) / 1000;
|
|
1509
1650
|
await captureAiGeneration(this.phClient, {
|
|
1510
1651
|
...posthogParams,
|
|
1511
1652
|
model: openAIParams.model ?? result.model,
|
|
1512
1653
|
provider: 'azure',
|
|
1513
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1514
|
-
output: result.output,
|
|
1654
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1655
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
1515
1656
|
latency,
|
|
1516
1657
|
baseURL: this.baseURL,
|
|
1517
1658
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1522,10 +1663,13 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1522
1663
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1523
1664
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1524
1665
|
},
|
|
1666
|
+
stopReason: result.status ?? undefined,
|
|
1525
1667
|
completionId: result.id,
|
|
1526
1668
|
providerMetadata: buildProviderMetadata({
|
|
1527
|
-
requestId: extractRequestId(result)
|
|
1528
|
-
|
|
1669
|
+
requestId: extractRequestId(result),
|
|
1670
|
+
incompleteDetails: result.incomplete_details
|
|
1671
|
+
}),
|
|
1672
|
+
error: getResponseFailure(result)
|
|
1529
1673
|
});
|
|
1530
1674
|
return result;
|
|
1531
1675
|
}, async error => {
|
|
@@ -1533,7 +1677,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1533
1677
|
...posthogParams,
|
|
1534
1678
|
model: openAIParams.model,
|
|
1535
1679
|
provider: 'azure',
|
|
1536
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1680
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1537
1681
|
output: [],
|
|
1538
1682
|
latency: 0,
|
|
1539
1683
|
baseURL: this.baseURL,
|
|
@@ -1547,7 +1691,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1547
1691
|
});
|
|
1548
1692
|
throw error;
|
|
1549
1693
|
});
|
|
1550
|
-
return wrappedPromise;
|
|
1694
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1551
1695
|
}
|
|
1552
1696
|
};
|
|
1553
1697
|
let WrappedEmbeddings$1 = class WrappedEmbeddings extends openai.AzureOpenAI.Embeddings {
|
|
@@ -1602,7 +1746,7 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends openai.AzureOpenAI.Emb
|
|
|
1602
1746
|
});
|
|
1603
1747
|
throw error;
|
|
1604
1748
|
});
|
|
1605
|
-
return wrappedPromise;
|
|
1749
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1606
1750
|
}
|
|
1607
1751
|
};
|
|
1608
1752
|
|
|
@@ -1623,28 +1767,8 @@ async function captureAiGenerationAfterSuccess(...args) {
|
|
|
1623
1767
|
captureAiGenerationInBackground(...args);
|
|
1624
1768
|
}
|
|
1625
1769
|
}
|
|
1626
|
-
function preserveAPIPromiseHelpers(parentPromise, wrappedPromise) {
|
|
1627
|
-
const apiPromise = wrappedPromise;
|
|
1628
|
-
if (typeof parentPromise.asResponse === 'function') {
|
|
1629
|
-
apiPromise.asResponse = () => parentPromise.asResponse();
|
|
1630
|
-
}
|
|
1631
|
-
if (typeof parentPromise.withResponse === 'function') {
|
|
1632
|
-
apiPromise.withResponse = async () => {
|
|
1633
|
-
const [response, data] = await Promise.all([parentPromise.withResponse(), wrappedPromise]);
|
|
1634
|
-
// swaps the `data` payload inside the SDK's generic withResponse shape; the compiler
|
|
1635
|
-
// cannot relate the Input- and Output-instantiated conditional types
|
|
1636
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1637
|
-
return {
|
|
1638
|
-
...response,
|
|
1639
|
-
data
|
|
1640
|
-
};
|
|
1641
|
-
};
|
|
1642
|
-
}
|
|
1643
|
-
return apiPromise;
|
|
1644
|
-
}
|
|
1645
|
-
const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
|
|
1646
1770
|
function isPendingBackgroundResponse(params, response) {
|
|
1647
|
-
return params.background === true && !response.usage && !!response.status && !
|
|
1771
|
+
return params.background === true && !response.usage && !!response.status && !isTerminalResponse(response);
|
|
1648
1772
|
}
|
|
1649
1773
|
class PostHogOpenAI extends openai.OpenAI {
|
|
1650
1774
|
constructor(config) {
|
|
@@ -1832,7 +1956,7 @@ class WrappedCompletions extends Completions {
|
|
|
1832
1956
|
model: openAIParams.model ?? modelFromResponse,
|
|
1833
1957
|
provider: 'openai',
|
|
1834
1958
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1835
|
-
output: formattedOutput,
|
|
1959
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1836
1960
|
latency,
|
|
1837
1961
|
timeToFirstToken,
|
|
1838
1962
|
baseURL: this.baseURL,
|
|
@@ -1888,7 +2012,7 @@ class WrappedCompletions extends Completions {
|
|
|
1888
2012
|
}
|
|
1889
2013
|
return value;
|
|
1890
2014
|
});
|
|
1891
|
-
return
|
|
2015
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1892
2016
|
} else {
|
|
1893
2017
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1894
2018
|
if ('choices' in result) {
|
|
@@ -1900,7 +2024,7 @@ class WrappedCompletions extends Completions {
|
|
|
1900
2024
|
model: openAIParams.model ?? result.model,
|
|
1901
2025
|
provider: 'openai',
|
|
1902
2026
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1903
|
-
output: formattedOutput,
|
|
2027
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1904
2028
|
latency,
|
|
1905
2029
|
baseURL: this.baseURL,
|
|
1906
2030
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1943,7 +2067,7 @@ class WrappedCompletions extends Completions {
|
|
|
1943
2067
|
});
|
|
1944
2068
|
throw error;
|
|
1945
2069
|
});
|
|
1946
|
-
return
|
|
2070
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1947
2071
|
}
|
|
1948
2072
|
}
|
|
1949
2073
|
}
|
|
@@ -1988,6 +2112,7 @@ class WrappedResponses extends Responses {
|
|
|
1988
2112
|
webSearchCount: 0
|
|
1989
2113
|
};
|
|
1990
2114
|
let rawUsageData;
|
|
2115
|
+
let terminalResponse;
|
|
1991
2116
|
for await (const chunk of stream1) {
|
|
1992
2117
|
// Track first token time on content delta events
|
|
1993
2118
|
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
@@ -2008,10 +2133,9 @@ class WrappedResponses extends Responses {
|
|
|
2008
2133
|
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2009
2134
|
usage.webSearchCount = chunkWebSearchCount;
|
|
2010
2135
|
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
if (chunk.response.status) {
|
|
2136
|
+
if (isTerminalResponse(chunk.response)) {
|
|
2137
|
+
terminalResponse = chunk.response;
|
|
2138
|
+
finalContent = chunk.response.output ?? [];
|
|
2015
2139
|
stopReason = chunk.response.status;
|
|
2016
2140
|
}
|
|
2017
2141
|
}
|
|
@@ -2034,7 +2158,7 @@ class WrappedResponses extends Responses {
|
|
|
2034
2158
|
model: openAIParams.model ?? modelFromResponse,
|
|
2035
2159
|
provider: 'openai',
|
|
2036
2160
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2037
|
-
output: finalContent,
|
|
2161
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
2038
2162
|
latency,
|
|
2039
2163
|
timeToFirstToken,
|
|
2040
2164
|
baseURL: this.baseURL,
|
|
@@ -2050,7 +2174,11 @@ class WrappedResponses extends Responses {
|
|
|
2050
2174
|
},
|
|
2051
2175
|
stopReason,
|
|
2052
2176
|
tools: availableTools,
|
|
2053
|
-
completionId: completionIdFromResponse
|
|
2177
|
+
completionId: completionIdFromResponse,
|
|
2178
|
+
providerMetadata: buildProviderMetadata({
|
|
2179
|
+
incompleteDetails: terminalResponse?.incomplete_details
|
|
2180
|
+
}),
|
|
2181
|
+
error: getResponseFailure(terminalResponse)
|
|
2054
2182
|
});
|
|
2055
2183
|
} catch (error) {
|
|
2056
2184
|
await captureAiGeneration(this.phClient, {
|
|
@@ -2081,7 +2209,7 @@ class WrappedResponses extends Responses {
|
|
|
2081
2209
|
}
|
|
2082
2210
|
return value;
|
|
2083
2211
|
});
|
|
2084
|
-
return
|
|
2212
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2085
2213
|
} else {
|
|
2086
2214
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2087
2215
|
if ('output' in result) {
|
|
@@ -2098,7 +2226,7 @@ class WrappedResponses extends Responses {
|
|
|
2098
2226
|
model: openAIParams.model ?? result.model,
|
|
2099
2227
|
provider: 'openai',
|
|
2100
2228
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2101
|
-
output: formattedOutput,
|
|
2229
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
2102
2230
|
latency,
|
|
2103
2231
|
baseURL: this.baseURL,
|
|
2104
2232
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -2115,8 +2243,10 @@ class WrappedResponses extends Responses {
|
|
|
2115
2243
|
tools: availableTools,
|
|
2116
2244
|
completionId: result.id,
|
|
2117
2245
|
providerMetadata: buildProviderMetadata({
|
|
2118
|
-
requestId: extractRequestId(result)
|
|
2119
|
-
|
|
2246
|
+
requestId: extractRequestId(result),
|
|
2247
|
+
incompleteDetails: result.incomplete_details
|
|
2248
|
+
}),
|
|
2249
|
+
error: getResponseFailure(result)
|
|
2120
2250
|
});
|
|
2121
2251
|
}
|
|
2122
2252
|
return result;
|
|
@@ -2140,7 +2270,7 @@ class WrappedResponses extends Responses {
|
|
|
2140
2270
|
});
|
|
2141
2271
|
throw error;
|
|
2142
2272
|
});
|
|
2143
|
-
return
|
|
2273
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2144
2274
|
}
|
|
2145
2275
|
}
|
|
2146
2276
|
parse(body, options) {
|
|
@@ -2149,64 +2279,57 @@ class WrappedResponses extends Responses {
|
|
|
2149
2279
|
posthogParams
|
|
2150
2280
|
} = extractPosthogParams(body);
|
|
2151
2281
|
const startTime = Date.now();
|
|
2152
|
-
const
|
|
2153
|
-
const
|
|
2154
|
-
|
|
2155
|
-
originalSelfRecord['create'] = originalCreate;
|
|
2156
|
-
try {
|
|
2157
|
-
const parentPromise = super.parse(openAIParams, options);
|
|
2158
|
-
const wrappedPromise = parentPromise.then(async result => {
|
|
2159
|
-
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
2160
|
-
return result;
|
|
2161
|
-
}
|
|
2162
|
-
const latency = (Date.now() - startTime) / 1000;
|
|
2163
|
-
await captureAiGeneration(this.phClient, {
|
|
2164
|
-
...posthogParams,
|
|
2165
|
-
model: openAIParams.model ?? result.model,
|
|
2166
|
-
provider: 'openai',
|
|
2167
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2168
|
-
output: result.output,
|
|
2169
|
-
latency,
|
|
2170
|
-
baseURL: this.baseURL,
|
|
2171
|
-
modelParameters: getModelParams(body, result.service_tier),
|
|
2172
|
-
httpStatus: 200,
|
|
2173
|
-
usage: {
|
|
2174
|
-
inputTokens: result.usage?.input_tokens ?? 0,
|
|
2175
|
-
outputTokens: result.usage?.output_tokens ?? 0,
|
|
2176
|
-
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2177
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
2178
|
-
rawUsage: result.usage
|
|
2179
|
-
},
|
|
2180
|
-
stopReason: result.status ?? undefined,
|
|
2181
|
-
completionId: result.id,
|
|
2182
|
-
providerMetadata: buildProviderMetadata({
|
|
2183
|
-
requestId: extractRequestId(result)
|
|
2184
|
-
})
|
|
2185
|
-
});
|
|
2282
|
+
const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
|
|
2283
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
2284
|
+
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
2186
2285
|
return result;
|
|
2187
|
-
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2286
|
+
}
|
|
2287
|
+
const latency = (Date.now() - startTime) / 1000;
|
|
2288
|
+
await captureAiGeneration(this.phClient, {
|
|
2289
|
+
...posthogParams,
|
|
2290
|
+
model: openAIParams.model ?? result.model,
|
|
2291
|
+
provider: 'openai',
|
|
2292
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2293
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
2294
|
+
latency,
|
|
2295
|
+
baseURL: this.baseURL,
|
|
2296
|
+
modelParameters: getModelParams(body, result.service_tier),
|
|
2297
|
+
httpStatus: 200,
|
|
2298
|
+
usage: {
|
|
2299
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
2300
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
2301
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2302
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
2303
|
+
rawUsage: result.usage
|
|
2304
|
+
},
|
|
2305
|
+
stopReason: result.status ?? undefined,
|
|
2306
|
+
completionId: result.id,
|
|
2307
|
+
providerMetadata: buildProviderMetadata({
|
|
2308
|
+
requestId: extractRequestId(result),
|
|
2309
|
+
incompleteDetails: result.incomplete_details
|
|
2310
|
+
}),
|
|
2311
|
+
error: getResponseFailure(result)
|
|
2204
2312
|
});
|
|
2205
|
-
return
|
|
2206
|
-
}
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2313
|
+
return result;
|
|
2314
|
+
}, async error => {
|
|
2315
|
+
await captureAiGeneration(this.phClient, {
|
|
2316
|
+
...posthogParams,
|
|
2317
|
+
model: openAIParams.model,
|
|
2318
|
+
provider: 'openai',
|
|
2319
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2320
|
+
output: [],
|
|
2321
|
+
latency: 0,
|
|
2322
|
+
baseURL: this.baseURL,
|
|
2323
|
+
modelParameters: getModelParams(body),
|
|
2324
|
+
usage: {
|
|
2325
|
+
inputTokens: 0,
|
|
2326
|
+
outputTokens: 0
|
|
2327
|
+
},
|
|
2328
|
+
error
|
|
2329
|
+
});
|
|
2330
|
+
throw error;
|
|
2331
|
+
});
|
|
2332
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2210
2333
|
}
|
|
2211
2334
|
}
|
|
2212
2335
|
class WrappedEmbeddings extends Embeddings {
|
|
@@ -2263,7 +2386,7 @@ class WrappedEmbeddings extends Embeddings {
|
|
|
2263
2386
|
});
|
|
2264
2387
|
throw error;
|
|
2265
2388
|
});
|
|
2266
|
-
return
|
|
2389
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2267
2390
|
}
|
|
2268
2391
|
}
|
|
2269
2392
|
class WrappedAudio extends Audio {
|
|
@@ -2338,7 +2461,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2338
2461
|
model: openAIParams.model,
|
|
2339
2462
|
provider: 'openai',
|
|
2340
2463
|
input: openAIParams.prompt,
|
|
2341
|
-
output: finalContent,
|
|
2464
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
2342
2465
|
latency,
|
|
2343
2466
|
timeToFirstToken,
|
|
2344
2467
|
baseURL: this.baseURL,
|
|
@@ -2373,7 +2496,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2373
2496
|
}
|
|
2374
2497
|
return value;
|
|
2375
2498
|
});
|
|
2376
|
-
return
|
|
2499
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2377
2500
|
} else {
|
|
2378
2501
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2379
2502
|
if (result && typeof result === 'object' && 'text' in result) {
|
|
@@ -2383,7 +2506,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2383
2506
|
model: openAIParams.model,
|
|
2384
2507
|
provider: 'openai',
|
|
2385
2508
|
input: openAIParams.prompt,
|
|
2386
|
-
output: result.text,
|
|
2509
|
+
output: sanitizeOpenAIResponse(result.text),
|
|
2387
2510
|
latency,
|
|
2388
2511
|
baseURL: this.baseURL,
|
|
2389
2512
|
modelParameters: getModelParams(body),
|
|
@@ -2414,7 +2537,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2414
2537
|
});
|
|
2415
2538
|
throw error;
|
|
2416
2539
|
});
|
|
2417
|
-
return
|
|
2540
|
+
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2418
2541
|
}
|
|
2419
2542
|
}
|
|
2420
2543
|
}
|