@posthog/ai 8.6.4 → 8.6.6
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 +19 -7
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +19 -7
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +22 -10
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +22 -10
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +38 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +38 -32
- 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 +402 -51
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.d.ts +13 -1
- package/dist/openai/index.mjs +402 -51
- 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 +38 -32
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +38 -32
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +2 -2
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.6";
|
|
538
548
|
|
|
539
549
|
const DEFAULT_MAX_DEPTH = 3;
|
|
540
550
|
const MAX_STACK_LINES = 20;
|
|
@@ -732,7 +742,9 @@ const captureAiGeneration$1 = async (client, options) => {
|
|
|
732
742
|
$ai_output_tokens: usage.outputTokens
|
|
733
743
|
} : {}),
|
|
734
744
|
...additionalTokenValues,
|
|
735
|
-
|
|
745
|
+
...(options.latency !== undefined ? {
|
|
746
|
+
$ai_latency: options.latency
|
|
747
|
+
} : {}),
|
|
736
748
|
...(options.timeToFirstToken !== undefined ? {
|
|
737
749
|
$ai_time_to_first_token: options.timeToFirstToken
|
|
738
750
|
} : {}),
|
|
@@ -834,7 +846,7 @@ function extractRequestId(result) {
|
|
|
834
846
|
* Assembles the `$ai_provider_metadata` blob for OpenAI / Azure OpenAI events.
|
|
835
847
|
* Provider-specific fields (system fingerprint, request id) live here rather
|
|
836
848
|
* than in the shared, provider-agnostic `$ai_*` namespace. Only keys with a
|
|
837
|
-
*
|
|
849
|
+
* meaningful value are included, and `undefined` is returned when there is nothing
|
|
838
850
|
* to report so the property can be omitted from the event entirely.
|
|
839
851
|
*/
|
|
840
852
|
function buildProviderMetadata(fields) {
|
|
@@ -845,8 +857,104 @@ function buildProviderMetadata(fields) {
|
|
|
845
857
|
if (fields.requestId) {
|
|
846
858
|
metadata.request_id = fields.requestId;
|
|
847
859
|
}
|
|
860
|
+
if (fields.incompleteDetails != null) {
|
|
861
|
+
metadata.incomplete_details = fields.incompleteDetails;
|
|
862
|
+
}
|
|
848
863
|
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
849
864
|
}
|
|
865
|
+
const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Checks whether a Responses API response has reached a status that should
|
|
869
|
+
* produce a final `$ai_generation` event.
|
|
870
|
+
*/
|
|
871
|
+
function isTerminalResponse(response) {
|
|
872
|
+
return !!response?.status && TERMINAL_RESPONSE_STATUSES.has(response.status);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Returns an isolated copy of a failed Responses API error for `$ai_error`, or
|
|
877
|
+
* creates a fallback error when the provider omitted failure details.
|
|
878
|
+
*/
|
|
879
|
+
function getResponseFailure(response) {
|
|
880
|
+
if (response?.status !== 'failed') {
|
|
881
|
+
return undefined;
|
|
882
|
+
}
|
|
883
|
+
return response.error ? {
|
|
884
|
+
...response.error
|
|
885
|
+
} : new Error(`OpenAI response ${response.id} failed without error details`);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
function isPendingBackgroundResponse(params, response) {
|
|
889
|
+
return params.background === true && !!response.status && !isTerminalResponse(response);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Uses provider timestamps so background polling cadence does not inflate
|
|
894
|
+
* generation latency. Non-completed responses do not expose a terminal time.
|
|
895
|
+
*/
|
|
896
|
+
function getBackgroundResponseLatency(response) {
|
|
897
|
+
if (typeof response.created_at !== 'number' || typeof response.completed_at !== 'number') {
|
|
898
|
+
return undefined;
|
|
899
|
+
}
|
|
900
|
+
return Math.max(0, response.completed_at - response.created_at);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Keeps the original create context available while a background response is
|
|
905
|
+
* polled. Entries are insertion ordered, so the oldest context is discarded
|
|
906
|
+
* when the bound is reached.
|
|
907
|
+
*/
|
|
908
|
+
class BackgroundResponseTracker {
|
|
909
|
+
contexts = new Map();
|
|
910
|
+
constructor(maxEntries = 1000) {
|
|
911
|
+
this.maxEntries = maxEntries;
|
|
912
|
+
}
|
|
913
|
+
set(responseID, context) {
|
|
914
|
+
// Refresh an existing response's insertion order.
|
|
915
|
+
this.contexts.delete(responseID);
|
|
916
|
+
this.contexts.set(responseID, context);
|
|
917
|
+
while (this.contexts.size > this.maxEntries) {
|
|
918
|
+
const oldestResponseID = this.contexts.keys().next().value;
|
|
919
|
+
if (oldestResponseID === undefined) {
|
|
920
|
+
break;
|
|
921
|
+
}
|
|
922
|
+
this.contexts.delete(oldestResponseID);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
get(responseID) {
|
|
926
|
+
return this.contexts.get(responseID);
|
|
927
|
+
}
|
|
928
|
+
take(responseID) {
|
|
929
|
+
const context = this.contexts.get(responseID);
|
|
930
|
+
if (context !== undefined) {
|
|
931
|
+
this.contexts.delete(responseID);
|
|
932
|
+
}
|
|
933
|
+
return context;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
/**
|
|
938
|
+
* Inspects a streamed background retrieval without consuming it on the
|
|
939
|
+
* caller's behalf. The stored create context is consumed only by a terminal
|
|
940
|
+
* response; an interrupted or nonterminal stream may be followed by another
|
|
941
|
+
* retrieval while the background job continues.
|
|
942
|
+
*/
|
|
943
|
+
function wrapBackgroundResponseStream(stream, responseID, tracker, captureTerminalResponse) {
|
|
944
|
+
async function* inspectStream() {
|
|
945
|
+
for await (const event of stream) {
|
|
946
|
+
if ('response' in event && isTerminalResponse(event.response)) {
|
|
947
|
+
const context = tracker.take(responseID);
|
|
948
|
+
if (context) {
|
|
949
|
+
// Monitoring must not delay or disrupt delivery of the provider stream.
|
|
950
|
+
void captureTerminalResponse(event.response, context).catch(() => undefined);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
yield event;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return new Stream(() => inspectStream(), stream.controller);
|
|
957
|
+
}
|
|
850
958
|
|
|
851
959
|
function addRequestId(result, response, requestIdHeader) {
|
|
852
960
|
if (!result || typeof result !== 'object' || Array.isArray(result)) {
|
|
@@ -1326,7 +1434,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1326
1434
|
model: openAIParams.model ?? modelFromResponse,
|
|
1327
1435
|
provider: 'azure',
|
|
1328
1436
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1329
|
-
output: formattedOutput,
|
|
1437
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1330
1438
|
latency,
|
|
1331
1439
|
timeToFirstToken,
|
|
1332
1440
|
baseURL: this.baseURL,
|
|
@@ -1382,8 +1490,8 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1382
1490
|
...posthogParams,
|
|
1383
1491
|
model: openAIParams.model ?? result.model,
|
|
1384
1492
|
provider: 'azure',
|
|
1385
|
-
input: openAIParams.messages,
|
|
1386
|
-
output: formatResponseOpenAI(result),
|
|
1493
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
1494
|
+
output: sanitizeOpenAIResponse(formatResponseOpenAI(result)),
|
|
1387
1495
|
latency,
|
|
1388
1496
|
baseURL: this.baseURL,
|
|
1389
1497
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1408,7 +1516,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1408
1516
|
...posthogParams,
|
|
1409
1517
|
model: openAIParams.model,
|
|
1410
1518
|
provider: 'azure',
|
|
1411
|
-
input: openAIParams.messages,
|
|
1519
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
1412
1520
|
output: [],
|
|
1413
1521
|
latency: 0,
|
|
1414
1522
|
baseURL: this.baseURL,
|
|
@@ -1427,11 +1535,43 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1427
1535
|
}
|
|
1428
1536
|
};
|
|
1429
1537
|
let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
1538
|
+
backgroundResponses = new BackgroundResponseTracker();
|
|
1430
1539
|
constructor(client, phClient) {
|
|
1431
1540
|
super(client);
|
|
1432
1541
|
this.phClient = phClient;
|
|
1433
1542
|
this.baseURL = client.baseURL;
|
|
1434
1543
|
}
|
|
1544
|
+
async captureBackgroundResponse(result, context) {
|
|
1545
|
+
const {
|
|
1546
|
+
openAIParams,
|
|
1547
|
+
posthogParams
|
|
1548
|
+
} = context;
|
|
1549
|
+
await captureAiGeneration(this.phClient, {
|
|
1550
|
+
...posthogParams,
|
|
1551
|
+
model: openAIParams.model ?? result.model,
|
|
1552
|
+
provider: 'azure',
|
|
1553
|
+
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1554
|
+
output: result.output,
|
|
1555
|
+
latency: getBackgroundResponseLatency(result),
|
|
1556
|
+
baseURL: this.baseURL,
|
|
1557
|
+
modelParameters: getModelParams(openAIParams, result.service_tier),
|
|
1558
|
+
httpStatus: 200,
|
|
1559
|
+
usage: {
|
|
1560
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1561
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1562
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1563
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1564
|
+
rawUsage: result.usage
|
|
1565
|
+
},
|
|
1566
|
+
stopReason: result.status ?? undefined,
|
|
1567
|
+
completionId: result.id,
|
|
1568
|
+
providerMetadata: buildProviderMetadata({
|
|
1569
|
+
requestId: extractRequestId(result),
|
|
1570
|
+
incompleteDetails: result.incomplete_details
|
|
1571
|
+
}),
|
|
1572
|
+
error: getResponseFailure(result)
|
|
1573
|
+
});
|
|
1574
|
+
}
|
|
1435
1575
|
|
|
1436
1576
|
// --- Overload #1: Non-streaming
|
|
1437
1577
|
|
|
@@ -1464,6 +1604,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1464
1604
|
inputTokens: 0,
|
|
1465
1605
|
outputTokens: 0
|
|
1466
1606
|
};
|
|
1607
|
+
let terminalResponse;
|
|
1467
1608
|
for await (const chunk of stream1) {
|
|
1468
1609
|
// Track first token time on content delta events
|
|
1469
1610
|
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
@@ -1477,12 +1618,19 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1477
1618
|
if (!completionIdFromResponse && chunk.response.id) {
|
|
1478
1619
|
completionIdFromResponse = chunk.response.id;
|
|
1479
1620
|
}
|
|
1621
|
+
if (openAIParams.background === true && !this.backgroundResponses.get(chunk.response.id)) {
|
|
1622
|
+
this.backgroundResponses.set(chunk.response.id, {
|
|
1623
|
+
openAIParams,
|
|
1624
|
+
posthogParams
|
|
1625
|
+
});
|
|
1626
|
+
}
|
|
1480
1627
|
if (chunk.response.service_tier != null) {
|
|
1481
1628
|
serviceTierFromResponse = chunk.response.service_tier;
|
|
1482
1629
|
}
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1630
|
+
if (isTerminalResponse(chunk.response)) {
|
|
1631
|
+
terminalResponse = chunk.response;
|
|
1632
|
+
finalContent = chunk.response.output ?? [];
|
|
1633
|
+
}
|
|
1486
1634
|
}
|
|
1487
1635
|
if ('response' in chunk && chunk.response?.usage) {
|
|
1488
1636
|
usage = {
|
|
@@ -1493,28 +1641,45 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1493
1641
|
};
|
|
1494
1642
|
}
|
|
1495
1643
|
}
|
|
1644
|
+
if (openAIParams.background === true) {
|
|
1645
|
+
if (terminalResponse) {
|
|
1646
|
+
const context = this.backgroundResponses.take(terminalResponse.id);
|
|
1647
|
+
if (context) {
|
|
1648
|
+
await this.captureBackgroundResponse(terminalResponse, context).catch(() => undefined);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
return;
|
|
1652
|
+
}
|
|
1496
1653
|
const latency = (Date.now() - startTime) / 1000;
|
|
1497
1654
|
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
1498
1655
|
await captureAiGeneration(this.phClient, {
|
|
1499
1656
|
...posthogParams,
|
|
1500
1657
|
model: openAIParams.model ?? modelFromResponse,
|
|
1501
1658
|
provider: 'azure',
|
|
1502
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1503
|
-
output: finalContent,
|
|
1659
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1660
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
1504
1661
|
latency,
|
|
1505
1662
|
timeToFirstToken,
|
|
1506
1663
|
baseURL: this.baseURL,
|
|
1507
1664
|
modelParameters: getModelParams(body, serviceTierFromResponse),
|
|
1508
1665
|
httpStatus: 200,
|
|
1509
1666
|
usage,
|
|
1510
|
-
|
|
1667
|
+
stopReason: terminalResponse?.status ?? undefined,
|
|
1668
|
+
completionId: completionIdFromResponse,
|
|
1669
|
+
providerMetadata: buildProviderMetadata({
|
|
1670
|
+
incompleteDetails: terminalResponse?.incomplete_details
|
|
1671
|
+
}),
|
|
1672
|
+
error: getResponseFailure(terminalResponse)
|
|
1511
1673
|
});
|
|
1512
1674
|
} catch (error) {
|
|
1675
|
+
if (openAIParams.background === true && completionIdFromResponse && this.backgroundResponses.get(completionIdFromResponse)) {
|
|
1676
|
+
throw error;
|
|
1677
|
+
}
|
|
1513
1678
|
await captureAiGeneration(this.phClient, {
|
|
1514
1679
|
...posthogParams,
|
|
1515
1680
|
model: openAIParams.model,
|
|
1516
1681
|
provider: 'azure',
|
|
1517
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1682
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1518
1683
|
output: [],
|
|
1519
1684
|
latency: 0,
|
|
1520
1685
|
baseURL: this.baseURL,
|
|
@@ -1542,13 +1707,20 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1542
1707
|
} else {
|
|
1543
1708
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1544
1709
|
if ('output' in result) {
|
|
1710
|
+
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
1711
|
+
this.backgroundResponses.set(result.id, {
|
|
1712
|
+
openAIParams,
|
|
1713
|
+
posthogParams
|
|
1714
|
+
});
|
|
1715
|
+
return result;
|
|
1716
|
+
}
|
|
1545
1717
|
const latency = (Date.now() - startTime) / 1000;
|
|
1546
1718
|
await captureAiGeneration(this.phClient, {
|
|
1547
1719
|
...posthogParams,
|
|
1548
1720
|
model: openAIParams.model ?? result.model,
|
|
1549
1721
|
provider: 'azure',
|
|
1550
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1551
|
-
output: result.output,
|
|
1722
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1723
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
1552
1724
|
latency,
|
|
1553
1725
|
baseURL: this.baseURL,
|
|
1554
1726
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1557,12 +1729,16 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1557
1729
|
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1558
1730
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1559
1731
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1560
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1732
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1733
|
+
rawUsage: result.usage
|
|
1561
1734
|
},
|
|
1735
|
+
stopReason: result.status ?? undefined,
|
|
1562
1736
|
completionId: result.id,
|
|
1563
1737
|
providerMetadata: buildProviderMetadata({
|
|
1564
|
-
requestId: extractRequestId(result)
|
|
1565
|
-
|
|
1738
|
+
requestId: extractRequestId(result),
|
|
1739
|
+
incompleteDetails: result.incomplete_details
|
|
1740
|
+
}),
|
|
1741
|
+
error: getResponseFailure(result)
|
|
1566
1742
|
});
|
|
1567
1743
|
}
|
|
1568
1744
|
return result;
|
|
@@ -1572,7 +1748,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1572
1748
|
...posthogParams,
|
|
1573
1749
|
model: openAIParams.model,
|
|
1574
1750
|
provider: 'azure',
|
|
1575
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1751
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1576
1752
|
output: [],
|
|
1577
1753
|
latency: 0,
|
|
1578
1754
|
baseURL: this.baseURL,
|
|
@@ -1589,6 +1765,55 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1589
1765
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1590
1766
|
}
|
|
1591
1767
|
}
|
|
1768
|
+
retrieve(responseID, query = {}, options) {
|
|
1769
|
+
const parentPromise = super.retrieve(responseID, query, options);
|
|
1770
|
+
|
|
1771
|
+
// Preserve the upstream promise and stream unchanged for responses that
|
|
1772
|
+
// were not created through this client.
|
|
1773
|
+
if (!this.backgroundResponses.get(responseID)) {
|
|
1774
|
+
return parentPromise;
|
|
1775
|
+
}
|
|
1776
|
+
if (query.stream) {
|
|
1777
|
+
return parentPromise._thenUnwrap(result => {
|
|
1778
|
+
if ('controller' in result) {
|
|
1779
|
+
return wrapBackgroundResponseStream(result, responseID, this.backgroundResponses, (response, context) => this.captureBackgroundResponse(response, context));
|
|
1780
|
+
}
|
|
1781
|
+
return result;
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
return parentPromise._thenUnwrap(async result => {
|
|
1785
|
+
if (!('output' in result) || !isTerminalResponse(result)) {
|
|
1786
|
+
return result;
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
// Removing the context before capture makes concurrent or repeated
|
|
1790
|
+
// terminal polls idempotent.
|
|
1791
|
+
const context = this.backgroundResponses.take(responseID);
|
|
1792
|
+
if (context) {
|
|
1793
|
+
await this.captureBackgroundResponse(result, context).catch(() => undefined);
|
|
1794
|
+
}
|
|
1795
|
+
return result;
|
|
1796
|
+
});
|
|
1797
|
+
}
|
|
1798
|
+
cancel(responseID, options) {
|
|
1799
|
+
const parentPromise = super.cancel(responseID, options);
|
|
1800
|
+
|
|
1801
|
+
// Avoid wrapping calls that do not belong to a background response created
|
|
1802
|
+
// through this client, preserving the upstream APIPromise unchanged.
|
|
1803
|
+
if (!this.backgroundResponses.get(responseID)) {
|
|
1804
|
+
return parentPromise;
|
|
1805
|
+
}
|
|
1806
|
+
return parentPromise._thenUnwrap(async result => {
|
|
1807
|
+
if (!isTerminalResponse(result)) {
|
|
1808
|
+
return result;
|
|
1809
|
+
}
|
|
1810
|
+
const context = this.backgroundResponses.take(responseID);
|
|
1811
|
+
if (context) {
|
|
1812
|
+
await this.captureBackgroundResponse(result, context).catch(() => undefined);
|
|
1813
|
+
}
|
|
1814
|
+
return result;
|
|
1815
|
+
});
|
|
1816
|
+
}
|
|
1592
1817
|
parse(body, options) {
|
|
1593
1818
|
const {
|
|
1594
1819
|
providerParams: openAIParams,
|
|
@@ -1597,13 +1822,20 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1597
1822
|
const startTime = Date.now();
|
|
1598
1823
|
const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
|
|
1599
1824
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1825
|
+
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
1826
|
+
this.backgroundResponses.set(result.id, {
|
|
1827
|
+
openAIParams,
|
|
1828
|
+
posthogParams
|
|
1829
|
+
});
|
|
1830
|
+
return result;
|
|
1831
|
+
}
|
|
1600
1832
|
const latency = (Date.now() - startTime) / 1000;
|
|
1601
1833
|
await captureAiGeneration(this.phClient, {
|
|
1602
1834
|
...posthogParams,
|
|
1603
1835
|
model: openAIParams.model ?? result.model,
|
|
1604
1836
|
provider: 'azure',
|
|
1605
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1606
|
-
output: result.output,
|
|
1837
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1838
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
1607
1839
|
latency,
|
|
1608
1840
|
baseURL: this.baseURL,
|
|
1609
1841
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1612,12 +1844,16 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1612
1844
|
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1613
1845
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1614
1846
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1615
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1847
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1848
|
+
rawUsage: result.usage
|
|
1616
1849
|
},
|
|
1850
|
+
stopReason: result.status ?? undefined,
|
|
1617
1851
|
completionId: result.id,
|
|
1618
1852
|
providerMetadata: buildProviderMetadata({
|
|
1619
|
-
requestId: extractRequestId(result)
|
|
1620
|
-
|
|
1853
|
+
requestId: extractRequestId(result),
|
|
1854
|
+
incompleteDetails: result.incomplete_details
|
|
1855
|
+
}),
|
|
1856
|
+
error: getResponseFailure(result)
|
|
1621
1857
|
});
|
|
1622
1858
|
return result;
|
|
1623
1859
|
}, async error => {
|
|
@@ -1625,7 +1861,7 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1625
1861
|
...posthogParams,
|
|
1626
1862
|
model: openAIParams.model,
|
|
1627
1863
|
provider: 'azure',
|
|
1628
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1864
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1629
1865
|
output: [],
|
|
1630
1866
|
latency: 0,
|
|
1631
1867
|
baseURL: this.baseURL,
|
|
@@ -1715,10 +1951,6 @@ async function captureAiGenerationAfterSuccess(...args) {
|
|
|
1715
1951
|
captureAiGenerationInBackground(...args);
|
|
1716
1952
|
}
|
|
1717
1953
|
}
|
|
1718
|
-
const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
|
|
1719
|
-
function isPendingBackgroundResponse(params, response) {
|
|
1720
|
-
return params.background === true && !response.usage && !!response.status && !TERMINAL_RESPONSE_STATUSES.has(response.status);
|
|
1721
|
-
}
|
|
1722
1954
|
class PostHogOpenAI extends OpenAI {
|
|
1723
1955
|
constructor(config) {
|
|
1724
1956
|
const {
|
|
@@ -1905,7 +2137,7 @@ class WrappedCompletions extends Completions {
|
|
|
1905
2137
|
model: openAIParams.model ?? modelFromResponse,
|
|
1906
2138
|
provider: 'openai',
|
|
1907
2139
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1908
|
-
output: formattedOutput,
|
|
2140
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1909
2141
|
latency,
|
|
1910
2142
|
timeToFirstToken,
|
|
1911
2143
|
baseURL: this.baseURL,
|
|
@@ -1973,7 +2205,7 @@ class WrappedCompletions extends Completions {
|
|
|
1973
2205
|
model: openAIParams.model ?? result.model,
|
|
1974
2206
|
provider: 'openai',
|
|
1975
2207
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1976
|
-
output: formattedOutput,
|
|
2208
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1977
2209
|
latency,
|
|
1978
2210
|
baseURL: this.baseURL,
|
|
1979
2211
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -2021,11 +2253,47 @@ class WrappedCompletions extends Completions {
|
|
|
2021
2253
|
}
|
|
2022
2254
|
}
|
|
2023
2255
|
class WrappedResponses extends Responses {
|
|
2256
|
+
backgroundResponses = new BackgroundResponseTracker();
|
|
2024
2257
|
constructor(client, phClient) {
|
|
2025
2258
|
super(client);
|
|
2026
2259
|
this.phClient = phClient;
|
|
2027
2260
|
this.baseURL = client.baseURL;
|
|
2028
2261
|
}
|
|
2262
|
+
async captureBackgroundResponse(result, context) {
|
|
2263
|
+
const {
|
|
2264
|
+
openAIParams,
|
|
2265
|
+
posthogParams
|
|
2266
|
+
} = context;
|
|
2267
|
+
await captureAiGenerationAfterSuccess(this.phClient, {
|
|
2268
|
+
...posthogParams,
|
|
2269
|
+
model: openAIParams.model ?? result.model,
|
|
2270
|
+
provider: 'openai',
|
|
2271
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2272
|
+
output: formatResponseOpenAI({
|
|
2273
|
+
output: result.output
|
|
2274
|
+
}),
|
|
2275
|
+
latency: getBackgroundResponseLatency(result),
|
|
2276
|
+
baseURL: this.baseURL,
|
|
2277
|
+
modelParameters: getModelParams(openAIParams, result.service_tier),
|
|
2278
|
+
httpStatus: 200,
|
|
2279
|
+
usage: {
|
|
2280
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
2281
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
2282
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2283
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
2284
|
+
webSearchCount: calculateWebSearchCount(result),
|
|
2285
|
+
rawUsage: result.usage
|
|
2286
|
+
},
|
|
2287
|
+
stopReason: result.status ?? undefined,
|
|
2288
|
+
tools: extractAvailableToolCalls('openai', openAIParams),
|
|
2289
|
+
completionId: result.id,
|
|
2290
|
+
providerMetadata: buildProviderMetadata({
|
|
2291
|
+
requestId: extractRequestId(result),
|
|
2292
|
+
incompleteDetails: result.incomplete_details
|
|
2293
|
+
}),
|
|
2294
|
+
error: getResponseFailure(result)
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2029
2297
|
|
|
2030
2298
|
// --- Overload #1: Non-streaming
|
|
2031
2299
|
|
|
@@ -2061,6 +2329,7 @@ class WrappedResponses extends Responses {
|
|
|
2061
2329
|
webSearchCount: 0
|
|
2062
2330
|
};
|
|
2063
2331
|
let rawUsageData;
|
|
2332
|
+
let terminalResponse;
|
|
2064
2333
|
for await (const chunk of stream1) {
|
|
2065
2334
|
// Track first token time on content delta events
|
|
2066
2335
|
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
@@ -2074,6 +2343,12 @@ class WrappedResponses extends Responses {
|
|
|
2074
2343
|
if (!completionIdFromResponse && chunk.response.id) {
|
|
2075
2344
|
completionIdFromResponse = chunk.response.id;
|
|
2076
2345
|
}
|
|
2346
|
+
if (openAIParams.background === true && !this.backgroundResponses.get(chunk.response.id)) {
|
|
2347
|
+
this.backgroundResponses.set(chunk.response.id, {
|
|
2348
|
+
openAIParams,
|
|
2349
|
+
posthogParams
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2077
2352
|
if (chunk.response.service_tier != null) {
|
|
2078
2353
|
serviceTierFromResponse = chunk.response.service_tier;
|
|
2079
2354
|
}
|
|
@@ -2081,10 +2356,9 @@ class WrappedResponses extends Responses {
|
|
|
2081
2356
|
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2082
2357
|
usage.webSearchCount = chunkWebSearchCount;
|
|
2083
2358
|
}
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
if (chunk.response.status) {
|
|
2359
|
+
if (isTerminalResponse(chunk.response)) {
|
|
2360
|
+
terminalResponse = chunk.response;
|
|
2361
|
+
finalContent = chunk.response.output ?? [];
|
|
2088
2362
|
stopReason = chunk.response.status;
|
|
2089
2363
|
}
|
|
2090
2364
|
}
|
|
@@ -2099,6 +2373,15 @@ class WrappedResponses extends Responses {
|
|
|
2099
2373
|
};
|
|
2100
2374
|
}
|
|
2101
2375
|
}
|
|
2376
|
+
if (openAIParams.background === true) {
|
|
2377
|
+
if (terminalResponse) {
|
|
2378
|
+
const context = this.backgroundResponses.take(terminalResponse.id);
|
|
2379
|
+
if (context) {
|
|
2380
|
+
await this.captureBackgroundResponse(terminalResponse, context).catch(() => undefined);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
return;
|
|
2384
|
+
}
|
|
2102
2385
|
const latency = (Date.now() - startTime) / 1000;
|
|
2103
2386
|
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
2104
2387
|
const availableTools = extractAvailableToolCalls('openai', openAIParams);
|
|
@@ -2107,7 +2390,7 @@ class WrappedResponses extends Responses {
|
|
|
2107
2390
|
model: openAIParams.model ?? modelFromResponse,
|
|
2108
2391
|
provider: 'openai',
|
|
2109
2392
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2110
|
-
output: finalContent,
|
|
2393
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
2111
2394
|
latency,
|
|
2112
2395
|
timeToFirstToken,
|
|
2113
2396
|
baseURL: this.baseURL,
|
|
@@ -2123,9 +2406,16 @@ class WrappedResponses extends Responses {
|
|
|
2123
2406
|
},
|
|
2124
2407
|
stopReason,
|
|
2125
2408
|
tools: availableTools,
|
|
2126
|
-
completionId: completionIdFromResponse
|
|
2409
|
+
completionId: completionIdFromResponse,
|
|
2410
|
+
providerMetadata: buildProviderMetadata({
|
|
2411
|
+
incompleteDetails: terminalResponse?.incomplete_details
|
|
2412
|
+
}),
|
|
2413
|
+
error: getResponseFailure(terminalResponse)
|
|
2127
2414
|
});
|
|
2128
2415
|
} catch (error) {
|
|
2416
|
+
if (openAIParams.background === true && completionIdFromResponse && this.backgroundResponses.get(completionIdFromResponse)) {
|
|
2417
|
+
throw error;
|
|
2418
|
+
}
|
|
2129
2419
|
await captureAiGeneration(this.phClient, {
|
|
2130
2420
|
...posthogParams,
|
|
2131
2421
|
model: openAIParams.model,
|
|
@@ -2159,6 +2449,10 @@ class WrappedResponses extends Responses {
|
|
|
2159
2449
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2160
2450
|
if ('output' in result) {
|
|
2161
2451
|
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
2452
|
+
this.backgroundResponses.set(result.id, {
|
|
2453
|
+
openAIParams,
|
|
2454
|
+
posthogParams
|
|
2455
|
+
});
|
|
2162
2456
|
return result;
|
|
2163
2457
|
}
|
|
2164
2458
|
const latency = (Date.now() - startTime) / 1000;
|
|
@@ -2171,7 +2465,7 @@ class WrappedResponses extends Responses {
|
|
|
2171
2465
|
model: openAIParams.model ?? result.model,
|
|
2172
2466
|
provider: 'openai',
|
|
2173
2467
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2174
|
-
output: formattedOutput,
|
|
2468
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
2175
2469
|
latency,
|
|
2176
2470
|
baseURL: this.baseURL,
|
|
2177
2471
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -2188,8 +2482,10 @@ class WrappedResponses extends Responses {
|
|
|
2188
2482
|
tools: availableTools,
|
|
2189
2483
|
completionId: result.id,
|
|
2190
2484
|
providerMetadata: buildProviderMetadata({
|
|
2191
|
-
requestId: extractRequestId(result)
|
|
2192
|
-
|
|
2485
|
+
requestId: extractRequestId(result),
|
|
2486
|
+
incompleteDetails: result.incomplete_details
|
|
2487
|
+
}),
|
|
2488
|
+
error: getResponseFailure(result)
|
|
2193
2489
|
});
|
|
2194
2490
|
}
|
|
2195
2491
|
return result;
|
|
@@ -2216,6 +2512,55 @@ class WrappedResponses extends Responses {
|
|
|
2216
2512
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2217
2513
|
}
|
|
2218
2514
|
}
|
|
2515
|
+
retrieve(responseID, query = {}, options) {
|
|
2516
|
+
const parentPromise = super.retrieve(responseID, query, options);
|
|
2517
|
+
|
|
2518
|
+
// Preserve the upstream promise and stream unchanged for responses that
|
|
2519
|
+
// were not created through this client.
|
|
2520
|
+
if (!this.backgroundResponses.get(responseID)) {
|
|
2521
|
+
return parentPromise;
|
|
2522
|
+
}
|
|
2523
|
+
if (query.stream) {
|
|
2524
|
+
return parentPromise._thenUnwrap(result => {
|
|
2525
|
+
if ('controller' in result) {
|
|
2526
|
+
return wrapBackgroundResponseStream(result, responseID, this.backgroundResponses, (response, context) => this.captureBackgroundResponse(response, context));
|
|
2527
|
+
}
|
|
2528
|
+
return result;
|
|
2529
|
+
});
|
|
2530
|
+
}
|
|
2531
|
+
return parentPromise._thenUnwrap(async result => {
|
|
2532
|
+
if (!('output' in result) || !isTerminalResponse(result)) {
|
|
2533
|
+
return result;
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
// Removing the context before capture makes concurrent or repeated
|
|
2537
|
+
// terminal polls idempotent.
|
|
2538
|
+
const context = this.backgroundResponses.take(responseID);
|
|
2539
|
+
if (context) {
|
|
2540
|
+
await this.captureBackgroundResponse(result, context).catch(() => undefined);
|
|
2541
|
+
}
|
|
2542
|
+
return result;
|
|
2543
|
+
});
|
|
2544
|
+
}
|
|
2545
|
+
cancel(responseID, options) {
|
|
2546
|
+
const parentPromise = super.cancel(responseID, options);
|
|
2547
|
+
|
|
2548
|
+
// Avoid wrapping calls that do not belong to a background response created
|
|
2549
|
+
// through this client, preserving the upstream APIPromise unchanged.
|
|
2550
|
+
if (!this.backgroundResponses.get(responseID)) {
|
|
2551
|
+
return parentPromise;
|
|
2552
|
+
}
|
|
2553
|
+
return parentPromise._thenUnwrap(async result => {
|
|
2554
|
+
if (!isTerminalResponse(result)) {
|
|
2555
|
+
return result;
|
|
2556
|
+
}
|
|
2557
|
+
const context = this.backgroundResponses.take(responseID);
|
|
2558
|
+
if (context) {
|
|
2559
|
+
await this.captureBackgroundResponse(result, context).catch(() => undefined);
|
|
2560
|
+
}
|
|
2561
|
+
return result;
|
|
2562
|
+
});
|
|
2563
|
+
}
|
|
2219
2564
|
parse(body, options) {
|
|
2220
2565
|
const {
|
|
2221
2566
|
providerParams: openAIParams,
|
|
@@ -2225,6 +2570,10 @@ class WrappedResponses extends Responses {
|
|
|
2225
2570
|
const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
|
|
2226
2571
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2227
2572
|
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
2573
|
+
this.backgroundResponses.set(result.id, {
|
|
2574
|
+
openAIParams,
|
|
2575
|
+
posthogParams
|
|
2576
|
+
});
|
|
2228
2577
|
return result;
|
|
2229
2578
|
}
|
|
2230
2579
|
const latency = (Date.now() - startTime) / 1000;
|
|
@@ -2233,7 +2582,7 @@ class WrappedResponses extends Responses {
|
|
|
2233
2582
|
model: openAIParams.model ?? result.model,
|
|
2234
2583
|
provider: 'openai',
|
|
2235
2584
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2236
|
-
output: result.output,
|
|
2585
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
2237
2586
|
latency,
|
|
2238
2587
|
baseURL: this.baseURL,
|
|
2239
2588
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -2248,8 +2597,10 @@ class WrappedResponses extends Responses {
|
|
|
2248
2597
|
stopReason: result.status ?? undefined,
|
|
2249
2598
|
completionId: result.id,
|
|
2250
2599
|
providerMetadata: buildProviderMetadata({
|
|
2251
|
-
requestId: extractRequestId(result)
|
|
2252
|
-
|
|
2600
|
+
requestId: extractRequestId(result),
|
|
2601
|
+
incompleteDetails: result.incomplete_details
|
|
2602
|
+
}),
|
|
2603
|
+
error: getResponseFailure(result)
|
|
2253
2604
|
});
|
|
2254
2605
|
return result;
|
|
2255
2606
|
}, async error => {
|
|
@@ -2402,7 +2753,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2402
2753
|
model: openAIParams.model,
|
|
2403
2754
|
provider: 'openai',
|
|
2404
2755
|
input: openAIParams.prompt,
|
|
2405
|
-
output: finalContent,
|
|
2756
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
2406
2757
|
latency,
|
|
2407
2758
|
timeToFirstToken,
|
|
2408
2759
|
baseURL: this.baseURL,
|
|
@@ -2447,7 +2798,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2447
2798
|
model: openAIParams.model,
|
|
2448
2799
|
provider: 'openai',
|
|
2449
2800
|
input: openAIParams.prompt,
|
|
2450
|
-
output: result.text,
|
|
2801
|
+
output: sanitizeOpenAIResponse(result.text),
|
|
2451
2802
|
latency,
|
|
2452
2803
|
baseURL: this.baseURL,
|
|
2453
2804
|
modelParameters: getModelParams(body),
|