@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.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.6";
|
|
542
552
|
|
|
543
553
|
const DEFAULT_MAX_DEPTH = 3;
|
|
544
554
|
const MAX_STACK_LINES = 20;
|
|
@@ -736,7 +746,9 @@ const captureAiGeneration$1 = async (client, options) => {
|
|
|
736
746
|
$ai_output_tokens: usage.outputTokens
|
|
737
747
|
} : {}),
|
|
738
748
|
...additionalTokenValues,
|
|
739
|
-
|
|
749
|
+
...(options.latency !== undefined ? {
|
|
750
|
+
$ai_latency: options.latency
|
|
751
|
+
} : {}),
|
|
740
752
|
...(options.timeToFirstToken !== undefined ? {
|
|
741
753
|
$ai_time_to_first_token: options.timeToFirstToken
|
|
742
754
|
} : {}),
|
|
@@ -838,7 +850,7 @@ function extractRequestId(result) {
|
|
|
838
850
|
* Assembles the `$ai_provider_metadata` blob for OpenAI / Azure OpenAI events.
|
|
839
851
|
* Provider-specific fields (system fingerprint, request id) live here rather
|
|
840
852
|
* than in the shared, provider-agnostic `$ai_*` namespace. Only keys with a
|
|
841
|
-
*
|
|
853
|
+
* meaningful value are included, and `undefined` is returned when there is nothing
|
|
842
854
|
* to report so the property can be omitted from the event entirely.
|
|
843
855
|
*/
|
|
844
856
|
function buildProviderMetadata(fields) {
|
|
@@ -849,8 +861,104 @@ function buildProviderMetadata(fields) {
|
|
|
849
861
|
if (fields.requestId) {
|
|
850
862
|
metadata.request_id = fields.requestId;
|
|
851
863
|
}
|
|
864
|
+
if (fields.incompleteDetails != null) {
|
|
865
|
+
metadata.incomplete_details = fields.incompleteDetails;
|
|
866
|
+
}
|
|
852
867
|
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
853
868
|
}
|
|
869
|
+
const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* Checks whether a Responses API response has reached a status that should
|
|
873
|
+
* produce a final `$ai_generation` event.
|
|
874
|
+
*/
|
|
875
|
+
function isTerminalResponse(response) {
|
|
876
|
+
return !!response?.status && TERMINAL_RESPONSE_STATUSES.has(response.status);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* Returns an isolated copy of a failed Responses API error for `$ai_error`, or
|
|
881
|
+
* creates a fallback error when the provider omitted failure details.
|
|
882
|
+
*/
|
|
883
|
+
function getResponseFailure(response) {
|
|
884
|
+
if (response?.status !== 'failed') {
|
|
885
|
+
return undefined;
|
|
886
|
+
}
|
|
887
|
+
return response.error ? {
|
|
888
|
+
...response.error
|
|
889
|
+
} : new Error(`OpenAI response ${response.id} failed without error details`);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
function isPendingBackgroundResponse(params, response) {
|
|
893
|
+
return params.background === true && !!response.status && !isTerminalResponse(response);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* Uses provider timestamps so background polling cadence does not inflate
|
|
898
|
+
* generation latency. Non-completed responses do not expose a terminal time.
|
|
899
|
+
*/
|
|
900
|
+
function getBackgroundResponseLatency(response) {
|
|
901
|
+
if (typeof response.created_at !== 'number' || typeof response.completed_at !== 'number') {
|
|
902
|
+
return undefined;
|
|
903
|
+
}
|
|
904
|
+
return Math.max(0, response.completed_at - response.created_at);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Keeps the original create context available while a background response is
|
|
909
|
+
* polled. Entries are insertion ordered, so the oldest context is discarded
|
|
910
|
+
* when the bound is reached.
|
|
911
|
+
*/
|
|
912
|
+
class BackgroundResponseTracker {
|
|
913
|
+
contexts = new Map();
|
|
914
|
+
constructor(maxEntries = 1000) {
|
|
915
|
+
this.maxEntries = maxEntries;
|
|
916
|
+
}
|
|
917
|
+
set(responseID, context) {
|
|
918
|
+
// Refresh an existing response's insertion order.
|
|
919
|
+
this.contexts.delete(responseID);
|
|
920
|
+
this.contexts.set(responseID, context);
|
|
921
|
+
while (this.contexts.size > this.maxEntries) {
|
|
922
|
+
const oldestResponseID = this.contexts.keys().next().value;
|
|
923
|
+
if (oldestResponseID === undefined) {
|
|
924
|
+
break;
|
|
925
|
+
}
|
|
926
|
+
this.contexts.delete(oldestResponseID);
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
get(responseID) {
|
|
930
|
+
return this.contexts.get(responseID);
|
|
931
|
+
}
|
|
932
|
+
take(responseID) {
|
|
933
|
+
const context = this.contexts.get(responseID);
|
|
934
|
+
if (context !== undefined) {
|
|
935
|
+
this.contexts.delete(responseID);
|
|
936
|
+
}
|
|
937
|
+
return context;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* Inspects a streamed background retrieval without consuming it on the
|
|
943
|
+
* caller's behalf. The stored create context is consumed only by a terminal
|
|
944
|
+
* response; an interrupted or nonterminal stream may be followed by another
|
|
945
|
+
* retrieval while the background job continues.
|
|
946
|
+
*/
|
|
947
|
+
function wrapBackgroundResponseStream(stream, responseID, tracker, captureTerminalResponse) {
|
|
948
|
+
async function* inspectStream() {
|
|
949
|
+
for await (const event of stream) {
|
|
950
|
+
if ('response' in event && isTerminalResponse(event.response)) {
|
|
951
|
+
const context = tracker.take(responseID);
|
|
952
|
+
if (context) {
|
|
953
|
+
// Monitoring must not delay or disrupt delivery of the provider stream.
|
|
954
|
+
void captureTerminalResponse(event.response, context).catch(() => undefined);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
yield event;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return new streaming.Stream(() => inspectStream(), stream.controller);
|
|
961
|
+
}
|
|
854
962
|
|
|
855
963
|
function addRequestId(result, response, requestIdHeader) {
|
|
856
964
|
if (!result || typeof result !== 'object' || Array.isArray(result)) {
|
|
@@ -1330,7 +1438,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1330
1438
|
model: openAIParams.model ?? modelFromResponse,
|
|
1331
1439
|
provider: 'azure',
|
|
1332
1440
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1333
|
-
output: formattedOutput,
|
|
1441
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1334
1442
|
latency,
|
|
1335
1443
|
timeToFirstToken,
|
|
1336
1444
|
baseURL: this.baseURL,
|
|
@@ -1386,8 +1494,8 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1386
1494
|
...posthogParams,
|
|
1387
1495
|
model: openAIParams.model ?? result.model,
|
|
1388
1496
|
provider: 'azure',
|
|
1389
|
-
input: openAIParams.messages,
|
|
1390
|
-
output: formatResponseOpenAI(result),
|
|
1497
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
1498
|
+
output: sanitizeOpenAIResponse(formatResponseOpenAI(result)),
|
|
1391
1499
|
latency,
|
|
1392
1500
|
baseURL: this.baseURL,
|
|
1393
1501
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1412,7 +1520,7 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1412
1520
|
...posthogParams,
|
|
1413
1521
|
model: openAIParams.model,
|
|
1414
1522
|
provider: 'azure',
|
|
1415
|
-
input: openAIParams.messages,
|
|
1523
|
+
input: sanitizeOpenAI(openAIParams.messages),
|
|
1416
1524
|
output: [],
|
|
1417
1525
|
latency: 0,
|
|
1418
1526
|
baseURL: this.baseURL,
|
|
@@ -1431,11 +1539,43 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1431
1539
|
}
|
|
1432
1540
|
};
|
|
1433
1541
|
let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Responses {
|
|
1542
|
+
backgroundResponses = new BackgroundResponseTracker();
|
|
1434
1543
|
constructor(client, phClient) {
|
|
1435
1544
|
super(client);
|
|
1436
1545
|
this.phClient = phClient;
|
|
1437
1546
|
this.baseURL = client.baseURL;
|
|
1438
1547
|
}
|
|
1548
|
+
async captureBackgroundResponse(result, context) {
|
|
1549
|
+
const {
|
|
1550
|
+
openAIParams,
|
|
1551
|
+
posthogParams
|
|
1552
|
+
} = context;
|
|
1553
|
+
await captureAiGeneration(this.phClient, {
|
|
1554
|
+
...posthogParams,
|
|
1555
|
+
model: openAIParams.model ?? result.model,
|
|
1556
|
+
provider: 'azure',
|
|
1557
|
+
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1558
|
+
output: result.output,
|
|
1559
|
+
latency: getBackgroundResponseLatency(result),
|
|
1560
|
+
baseURL: this.baseURL,
|
|
1561
|
+
modelParameters: getModelParams(openAIParams, result.service_tier),
|
|
1562
|
+
httpStatus: 200,
|
|
1563
|
+
usage: {
|
|
1564
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1565
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1566
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1567
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1568
|
+
rawUsage: result.usage
|
|
1569
|
+
},
|
|
1570
|
+
stopReason: result.status ?? undefined,
|
|
1571
|
+
completionId: result.id,
|
|
1572
|
+
providerMetadata: buildProviderMetadata({
|
|
1573
|
+
requestId: extractRequestId(result),
|
|
1574
|
+
incompleteDetails: result.incomplete_details
|
|
1575
|
+
}),
|
|
1576
|
+
error: getResponseFailure(result)
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1439
1579
|
|
|
1440
1580
|
// --- Overload #1: Non-streaming
|
|
1441
1581
|
|
|
@@ -1468,6 +1608,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1468
1608
|
inputTokens: 0,
|
|
1469
1609
|
outputTokens: 0
|
|
1470
1610
|
};
|
|
1611
|
+
let terminalResponse;
|
|
1471
1612
|
for await (const chunk of stream1) {
|
|
1472
1613
|
// Track first token time on content delta events
|
|
1473
1614
|
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
@@ -1481,12 +1622,19 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1481
1622
|
if (!completionIdFromResponse && chunk.response.id) {
|
|
1482
1623
|
completionIdFromResponse = chunk.response.id;
|
|
1483
1624
|
}
|
|
1625
|
+
if (openAIParams.background === true && !this.backgroundResponses.get(chunk.response.id)) {
|
|
1626
|
+
this.backgroundResponses.set(chunk.response.id, {
|
|
1627
|
+
openAIParams,
|
|
1628
|
+
posthogParams
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1484
1631
|
if (chunk.response.service_tier != null) {
|
|
1485
1632
|
serviceTierFromResponse = chunk.response.service_tier;
|
|
1486
1633
|
}
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1634
|
+
if (isTerminalResponse(chunk.response)) {
|
|
1635
|
+
terminalResponse = chunk.response;
|
|
1636
|
+
finalContent = chunk.response.output ?? [];
|
|
1637
|
+
}
|
|
1490
1638
|
}
|
|
1491
1639
|
if ('response' in chunk && chunk.response?.usage) {
|
|
1492
1640
|
usage = {
|
|
@@ -1497,28 +1645,45 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1497
1645
|
};
|
|
1498
1646
|
}
|
|
1499
1647
|
}
|
|
1648
|
+
if (openAIParams.background === true) {
|
|
1649
|
+
if (terminalResponse) {
|
|
1650
|
+
const context = this.backgroundResponses.take(terminalResponse.id);
|
|
1651
|
+
if (context) {
|
|
1652
|
+
await this.captureBackgroundResponse(terminalResponse, context).catch(() => undefined);
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
return;
|
|
1656
|
+
}
|
|
1500
1657
|
const latency = (Date.now() - startTime) / 1000;
|
|
1501
1658
|
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
1502
1659
|
await captureAiGeneration(this.phClient, {
|
|
1503
1660
|
...posthogParams,
|
|
1504
1661
|
model: openAIParams.model ?? modelFromResponse,
|
|
1505
1662
|
provider: 'azure',
|
|
1506
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1507
|
-
output: finalContent,
|
|
1663
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1664
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
1508
1665
|
latency,
|
|
1509
1666
|
timeToFirstToken,
|
|
1510
1667
|
baseURL: this.baseURL,
|
|
1511
1668
|
modelParameters: getModelParams(body, serviceTierFromResponse),
|
|
1512
1669
|
httpStatus: 200,
|
|
1513
1670
|
usage,
|
|
1514
|
-
|
|
1671
|
+
stopReason: terminalResponse?.status ?? undefined,
|
|
1672
|
+
completionId: completionIdFromResponse,
|
|
1673
|
+
providerMetadata: buildProviderMetadata({
|
|
1674
|
+
incompleteDetails: terminalResponse?.incomplete_details
|
|
1675
|
+
}),
|
|
1676
|
+
error: getResponseFailure(terminalResponse)
|
|
1515
1677
|
});
|
|
1516
1678
|
} catch (error) {
|
|
1679
|
+
if (openAIParams.background === true && completionIdFromResponse && this.backgroundResponses.get(completionIdFromResponse)) {
|
|
1680
|
+
throw error;
|
|
1681
|
+
}
|
|
1517
1682
|
await captureAiGeneration(this.phClient, {
|
|
1518
1683
|
...posthogParams,
|
|
1519
1684
|
model: openAIParams.model,
|
|
1520
1685
|
provider: 'azure',
|
|
1521
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1686
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1522
1687
|
output: [],
|
|
1523
1688
|
latency: 0,
|
|
1524
1689
|
baseURL: this.baseURL,
|
|
@@ -1546,13 +1711,20 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1546
1711
|
} else {
|
|
1547
1712
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1548
1713
|
if ('output' in result) {
|
|
1714
|
+
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
1715
|
+
this.backgroundResponses.set(result.id, {
|
|
1716
|
+
openAIParams,
|
|
1717
|
+
posthogParams
|
|
1718
|
+
});
|
|
1719
|
+
return result;
|
|
1720
|
+
}
|
|
1549
1721
|
const latency = (Date.now() - startTime) / 1000;
|
|
1550
1722
|
await captureAiGeneration(this.phClient, {
|
|
1551
1723
|
...posthogParams,
|
|
1552
1724
|
model: openAIParams.model ?? result.model,
|
|
1553
1725
|
provider: 'azure',
|
|
1554
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1555
|
-
output: result.output,
|
|
1726
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1727
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
1556
1728
|
latency,
|
|
1557
1729
|
baseURL: this.baseURL,
|
|
1558
1730
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1561,12 +1733,16 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1561
1733
|
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1562
1734
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1563
1735
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1564
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1736
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1737
|
+
rawUsage: result.usage
|
|
1565
1738
|
},
|
|
1739
|
+
stopReason: result.status ?? undefined,
|
|
1566
1740
|
completionId: result.id,
|
|
1567
1741
|
providerMetadata: buildProviderMetadata({
|
|
1568
|
-
requestId: extractRequestId(result)
|
|
1569
|
-
|
|
1742
|
+
requestId: extractRequestId(result),
|
|
1743
|
+
incompleteDetails: result.incomplete_details
|
|
1744
|
+
}),
|
|
1745
|
+
error: getResponseFailure(result)
|
|
1570
1746
|
});
|
|
1571
1747
|
}
|
|
1572
1748
|
return result;
|
|
@@ -1576,7 +1752,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1576
1752
|
...posthogParams,
|
|
1577
1753
|
model: openAIParams.model,
|
|
1578
1754
|
provider: 'azure',
|
|
1579
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1755
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1580
1756
|
output: [],
|
|
1581
1757
|
latency: 0,
|
|
1582
1758
|
baseURL: this.baseURL,
|
|
@@ -1593,6 +1769,55 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1593
1769
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
1594
1770
|
}
|
|
1595
1771
|
}
|
|
1772
|
+
retrieve(responseID, query = {}, options) {
|
|
1773
|
+
const parentPromise = super.retrieve(responseID, query, options);
|
|
1774
|
+
|
|
1775
|
+
// Preserve the upstream promise and stream unchanged for responses that
|
|
1776
|
+
// were not created through this client.
|
|
1777
|
+
if (!this.backgroundResponses.get(responseID)) {
|
|
1778
|
+
return parentPromise;
|
|
1779
|
+
}
|
|
1780
|
+
if (query.stream) {
|
|
1781
|
+
return parentPromise._thenUnwrap(result => {
|
|
1782
|
+
if ('controller' in result) {
|
|
1783
|
+
return wrapBackgroundResponseStream(result, responseID, this.backgroundResponses, (response, context) => this.captureBackgroundResponse(response, context));
|
|
1784
|
+
}
|
|
1785
|
+
return result;
|
|
1786
|
+
});
|
|
1787
|
+
}
|
|
1788
|
+
return parentPromise._thenUnwrap(async result => {
|
|
1789
|
+
if (!('output' in result) || !isTerminalResponse(result)) {
|
|
1790
|
+
return result;
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
// Removing the context before capture makes concurrent or repeated
|
|
1794
|
+
// terminal polls idempotent.
|
|
1795
|
+
const context = this.backgroundResponses.take(responseID);
|
|
1796
|
+
if (context) {
|
|
1797
|
+
await this.captureBackgroundResponse(result, context).catch(() => undefined);
|
|
1798
|
+
}
|
|
1799
|
+
return result;
|
|
1800
|
+
});
|
|
1801
|
+
}
|
|
1802
|
+
cancel(responseID, options) {
|
|
1803
|
+
const parentPromise = super.cancel(responseID, options);
|
|
1804
|
+
|
|
1805
|
+
// Avoid wrapping calls that do not belong to a background response created
|
|
1806
|
+
// through this client, preserving the upstream APIPromise unchanged.
|
|
1807
|
+
if (!this.backgroundResponses.get(responseID)) {
|
|
1808
|
+
return parentPromise;
|
|
1809
|
+
}
|
|
1810
|
+
return parentPromise._thenUnwrap(async result => {
|
|
1811
|
+
if (!isTerminalResponse(result)) {
|
|
1812
|
+
return result;
|
|
1813
|
+
}
|
|
1814
|
+
const context = this.backgroundResponses.take(responseID);
|
|
1815
|
+
if (context) {
|
|
1816
|
+
await this.captureBackgroundResponse(result, context).catch(() => undefined);
|
|
1817
|
+
}
|
|
1818
|
+
return result;
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1596
1821
|
parse(body, options) {
|
|
1597
1822
|
const {
|
|
1598
1823
|
providerParams: openAIParams,
|
|
@@ -1601,13 +1826,20 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1601
1826
|
const startTime = Date.now();
|
|
1602
1827
|
const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
|
|
1603
1828
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1829
|
+
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
1830
|
+
this.backgroundResponses.set(result.id, {
|
|
1831
|
+
openAIParams,
|
|
1832
|
+
posthogParams
|
|
1833
|
+
});
|
|
1834
|
+
return result;
|
|
1835
|
+
}
|
|
1604
1836
|
const latency = (Date.now() - startTime) / 1000;
|
|
1605
1837
|
await captureAiGeneration(this.phClient, {
|
|
1606
1838
|
...posthogParams,
|
|
1607
1839
|
model: openAIParams.model ?? result.model,
|
|
1608
1840
|
provider: 'azure',
|
|
1609
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1610
|
-
output: result.output,
|
|
1841
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1842
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
1611
1843
|
latency,
|
|
1612
1844
|
baseURL: this.baseURL,
|
|
1613
1845
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -1616,12 +1848,16 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1616
1848
|
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1617
1849
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1618
1850
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1619
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1851
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1852
|
+
rawUsage: result.usage
|
|
1620
1853
|
},
|
|
1854
|
+
stopReason: result.status ?? undefined,
|
|
1621
1855
|
completionId: result.id,
|
|
1622
1856
|
providerMetadata: buildProviderMetadata({
|
|
1623
|
-
requestId: extractRequestId(result)
|
|
1624
|
-
|
|
1857
|
+
requestId: extractRequestId(result),
|
|
1858
|
+
incompleteDetails: result.incomplete_details
|
|
1859
|
+
}),
|
|
1860
|
+
error: getResponseFailure(result)
|
|
1625
1861
|
});
|
|
1626
1862
|
return result;
|
|
1627
1863
|
}, async error => {
|
|
@@ -1629,7 +1865,7 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1629
1865
|
...posthogParams,
|
|
1630
1866
|
model: openAIParams.model,
|
|
1631
1867
|
provider: 'azure',
|
|
1632
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1868
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1633
1869
|
output: [],
|
|
1634
1870
|
latency: 0,
|
|
1635
1871
|
baseURL: this.baseURL,
|
|
@@ -1719,10 +1955,6 @@ async function captureAiGenerationAfterSuccess(...args) {
|
|
|
1719
1955
|
captureAiGenerationInBackground(...args);
|
|
1720
1956
|
}
|
|
1721
1957
|
}
|
|
1722
|
-
const TERMINAL_RESPONSE_STATUSES = new Set(['completed', 'failed', 'cancelled', 'incomplete']);
|
|
1723
|
-
function isPendingBackgroundResponse(params, response) {
|
|
1724
|
-
return params.background === true && !response.usage && !!response.status && !TERMINAL_RESPONSE_STATUSES.has(response.status);
|
|
1725
|
-
}
|
|
1726
1958
|
class PostHogOpenAI extends openai.OpenAI {
|
|
1727
1959
|
constructor(config) {
|
|
1728
1960
|
const {
|
|
@@ -1909,7 +2141,7 @@ class WrappedCompletions extends Completions {
|
|
|
1909
2141
|
model: openAIParams.model ?? modelFromResponse,
|
|
1910
2142
|
provider: 'openai',
|
|
1911
2143
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1912
|
-
output: formattedOutput,
|
|
2144
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1913
2145
|
latency,
|
|
1914
2146
|
timeToFirstToken,
|
|
1915
2147
|
baseURL: this.baseURL,
|
|
@@ -1977,7 +2209,7 @@ class WrappedCompletions extends Completions {
|
|
|
1977
2209
|
model: openAIParams.model ?? result.model,
|
|
1978
2210
|
provider: 'openai',
|
|
1979
2211
|
input: sanitizeOpenAI(openAIParams.messages),
|
|
1980
|
-
output: formattedOutput,
|
|
2212
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1981
2213
|
latency,
|
|
1982
2214
|
baseURL: this.baseURL,
|
|
1983
2215
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -2025,11 +2257,47 @@ class WrappedCompletions extends Completions {
|
|
|
2025
2257
|
}
|
|
2026
2258
|
}
|
|
2027
2259
|
class WrappedResponses extends Responses {
|
|
2260
|
+
backgroundResponses = new BackgroundResponseTracker();
|
|
2028
2261
|
constructor(client, phClient) {
|
|
2029
2262
|
super(client);
|
|
2030
2263
|
this.phClient = phClient;
|
|
2031
2264
|
this.baseURL = client.baseURL;
|
|
2032
2265
|
}
|
|
2266
|
+
async captureBackgroundResponse(result, context) {
|
|
2267
|
+
const {
|
|
2268
|
+
openAIParams,
|
|
2269
|
+
posthogParams
|
|
2270
|
+
} = context;
|
|
2271
|
+
await captureAiGenerationAfterSuccess(this.phClient, {
|
|
2272
|
+
...posthogParams,
|
|
2273
|
+
model: openAIParams.model ?? result.model,
|
|
2274
|
+
provider: 'openai',
|
|
2275
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2276
|
+
output: formatResponseOpenAI({
|
|
2277
|
+
output: result.output
|
|
2278
|
+
}),
|
|
2279
|
+
latency: getBackgroundResponseLatency(result),
|
|
2280
|
+
baseURL: this.baseURL,
|
|
2281
|
+
modelParameters: getModelParams(openAIParams, result.service_tier),
|
|
2282
|
+
httpStatus: 200,
|
|
2283
|
+
usage: {
|
|
2284
|
+
inputTokens: result.usage?.input_tokens ?? 0,
|
|
2285
|
+
outputTokens: result.usage?.output_tokens ?? 0,
|
|
2286
|
+
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2287
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
2288
|
+
webSearchCount: calculateWebSearchCount(result),
|
|
2289
|
+
rawUsage: result.usage
|
|
2290
|
+
},
|
|
2291
|
+
stopReason: result.status ?? undefined,
|
|
2292
|
+
tools: extractAvailableToolCalls('openai', openAIParams),
|
|
2293
|
+
completionId: result.id,
|
|
2294
|
+
providerMetadata: buildProviderMetadata({
|
|
2295
|
+
requestId: extractRequestId(result),
|
|
2296
|
+
incompleteDetails: result.incomplete_details
|
|
2297
|
+
}),
|
|
2298
|
+
error: getResponseFailure(result)
|
|
2299
|
+
});
|
|
2300
|
+
}
|
|
2033
2301
|
|
|
2034
2302
|
// --- Overload #1: Non-streaming
|
|
2035
2303
|
|
|
@@ -2065,6 +2333,7 @@ class WrappedResponses extends Responses {
|
|
|
2065
2333
|
webSearchCount: 0
|
|
2066
2334
|
};
|
|
2067
2335
|
let rawUsageData;
|
|
2336
|
+
let terminalResponse;
|
|
2068
2337
|
for await (const chunk of stream1) {
|
|
2069
2338
|
// Track first token time on content delta events
|
|
2070
2339
|
if (firstTokenTime === undefined && isResponseTokenChunk(chunk)) {
|
|
@@ -2078,6 +2347,12 @@ class WrappedResponses extends Responses {
|
|
|
2078
2347
|
if (!completionIdFromResponse && chunk.response.id) {
|
|
2079
2348
|
completionIdFromResponse = chunk.response.id;
|
|
2080
2349
|
}
|
|
2350
|
+
if (openAIParams.background === true && !this.backgroundResponses.get(chunk.response.id)) {
|
|
2351
|
+
this.backgroundResponses.set(chunk.response.id, {
|
|
2352
|
+
openAIParams,
|
|
2353
|
+
posthogParams
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2081
2356
|
if (chunk.response.service_tier != null) {
|
|
2082
2357
|
serviceTierFromResponse = chunk.response.service_tier;
|
|
2083
2358
|
}
|
|
@@ -2085,10 +2360,9 @@ class WrappedResponses extends Responses {
|
|
|
2085
2360
|
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2086
2361
|
usage.webSearchCount = chunkWebSearchCount;
|
|
2087
2362
|
}
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
if (chunk.response.status) {
|
|
2363
|
+
if (isTerminalResponse(chunk.response)) {
|
|
2364
|
+
terminalResponse = chunk.response;
|
|
2365
|
+
finalContent = chunk.response.output ?? [];
|
|
2092
2366
|
stopReason = chunk.response.status;
|
|
2093
2367
|
}
|
|
2094
2368
|
}
|
|
@@ -2103,6 +2377,15 @@ class WrappedResponses extends Responses {
|
|
|
2103
2377
|
};
|
|
2104
2378
|
}
|
|
2105
2379
|
}
|
|
2380
|
+
if (openAIParams.background === true) {
|
|
2381
|
+
if (terminalResponse) {
|
|
2382
|
+
const context = this.backgroundResponses.take(terminalResponse.id);
|
|
2383
|
+
if (context) {
|
|
2384
|
+
await this.captureBackgroundResponse(terminalResponse, context).catch(() => undefined);
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
return;
|
|
2388
|
+
}
|
|
2106
2389
|
const latency = (Date.now() - startTime) / 1000;
|
|
2107
2390
|
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
2108
2391
|
const availableTools = extractAvailableToolCalls('openai', openAIParams);
|
|
@@ -2111,7 +2394,7 @@ class WrappedResponses extends Responses {
|
|
|
2111
2394
|
model: openAIParams.model ?? modelFromResponse,
|
|
2112
2395
|
provider: 'openai',
|
|
2113
2396
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2114
|
-
output: finalContent,
|
|
2397
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
2115
2398
|
latency,
|
|
2116
2399
|
timeToFirstToken,
|
|
2117
2400
|
baseURL: this.baseURL,
|
|
@@ -2127,9 +2410,16 @@ class WrappedResponses extends Responses {
|
|
|
2127
2410
|
},
|
|
2128
2411
|
stopReason,
|
|
2129
2412
|
tools: availableTools,
|
|
2130
|
-
completionId: completionIdFromResponse
|
|
2413
|
+
completionId: completionIdFromResponse,
|
|
2414
|
+
providerMetadata: buildProviderMetadata({
|
|
2415
|
+
incompleteDetails: terminalResponse?.incomplete_details
|
|
2416
|
+
}),
|
|
2417
|
+
error: getResponseFailure(terminalResponse)
|
|
2131
2418
|
});
|
|
2132
2419
|
} catch (error) {
|
|
2420
|
+
if (openAIParams.background === true && completionIdFromResponse && this.backgroundResponses.get(completionIdFromResponse)) {
|
|
2421
|
+
throw error;
|
|
2422
|
+
}
|
|
2133
2423
|
await captureAiGeneration(this.phClient, {
|
|
2134
2424
|
...posthogParams,
|
|
2135
2425
|
model: openAIParams.model,
|
|
@@ -2163,6 +2453,10 @@ class WrappedResponses extends Responses {
|
|
|
2163
2453
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2164
2454
|
if ('output' in result) {
|
|
2165
2455
|
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
2456
|
+
this.backgroundResponses.set(result.id, {
|
|
2457
|
+
openAIParams,
|
|
2458
|
+
posthogParams
|
|
2459
|
+
});
|
|
2166
2460
|
return result;
|
|
2167
2461
|
}
|
|
2168
2462
|
const latency = (Date.now() - startTime) / 1000;
|
|
@@ -2175,7 +2469,7 @@ class WrappedResponses extends Responses {
|
|
|
2175
2469
|
model: openAIParams.model ?? result.model,
|
|
2176
2470
|
provider: 'openai',
|
|
2177
2471
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2178
|
-
output: formattedOutput,
|
|
2472
|
+
output: sanitizeOpenAIResponse(formattedOutput),
|
|
2179
2473
|
latency,
|
|
2180
2474
|
baseURL: this.baseURL,
|
|
2181
2475
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -2192,8 +2486,10 @@ class WrappedResponses extends Responses {
|
|
|
2192
2486
|
tools: availableTools,
|
|
2193
2487
|
completionId: result.id,
|
|
2194
2488
|
providerMetadata: buildProviderMetadata({
|
|
2195
|
-
requestId: extractRequestId(result)
|
|
2196
|
-
|
|
2489
|
+
requestId: extractRequestId(result),
|
|
2490
|
+
incompleteDetails: result.incomplete_details
|
|
2491
|
+
}),
|
|
2492
|
+
error: getResponseFailure(result)
|
|
2197
2493
|
});
|
|
2198
2494
|
}
|
|
2199
2495
|
return result;
|
|
@@ -2220,6 +2516,55 @@ class WrappedResponses extends Responses {
|
|
|
2220
2516
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
2221
2517
|
}
|
|
2222
2518
|
}
|
|
2519
|
+
retrieve(responseID, query = {}, options) {
|
|
2520
|
+
const parentPromise = super.retrieve(responseID, query, options);
|
|
2521
|
+
|
|
2522
|
+
// Preserve the upstream promise and stream unchanged for responses that
|
|
2523
|
+
// were not created through this client.
|
|
2524
|
+
if (!this.backgroundResponses.get(responseID)) {
|
|
2525
|
+
return parentPromise;
|
|
2526
|
+
}
|
|
2527
|
+
if (query.stream) {
|
|
2528
|
+
return parentPromise._thenUnwrap(result => {
|
|
2529
|
+
if ('controller' in result) {
|
|
2530
|
+
return wrapBackgroundResponseStream(result, responseID, this.backgroundResponses, (response, context) => this.captureBackgroundResponse(response, context));
|
|
2531
|
+
}
|
|
2532
|
+
return result;
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
return parentPromise._thenUnwrap(async result => {
|
|
2536
|
+
if (!('output' in result) || !isTerminalResponse(result)) {
|
|
2537
|
+
return result;
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
// Removing the context before capture makes concurrent or repeated
|
|
2541
|
+
// terminal polls idempotent.
|
|
2542
|
+
const context = this.backgroundResponses.take(responseID);
|
|
2543
|
+
if (context) {
|
|
2544
|
+
await this.captureBackgroundResponse(result, context).catch(() => undefined);
|
|
2545
|
+
}
|
|
2546
|
+
return result;
|
|
2547
|
+
});
|
|
2548
|
+
}
|
|
2549
|
+
cancel(responseID, options) {
|
|
2550
|
+
const parentPromise = super.cancel(responseID, options);
|
|
2551
|
+
|
|
2552
|
+
// Avoid wrapping calls that do not belong to a background response created
|
|
2553
|
+
// through this client, preserving the upstream APIPromise unchanged.
|
|
2554
|
+
if (!this.backgroundResponses.get(responseID)) {
|
|
2555
|
+
return parentPromise;
|
|
2556
|
+
}
|
|
2557
|
+
return parentPromise._thenUnwrap(async result => {
|
|
2558
|
+
if (!isTerminalResponse(result)) {
|
|
2559
|
+
return result;
|
|
2560
|
+
}
|
|
2561
|
+
const context = this.backgroundResponses.take(responseID);
|
|
2562
|
+
if (context) {
|
|
2563
|
+
await this.captureBackgroundResponse(result, context).catch(() => undefined);
|
|
2564
|
+
}
|
|
2565
|
+
return result;
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2223
2568
|
parse(body, options) {
|
|
2224
2569
|
const {
|
|
2225
2570
|
providerParams: openAIParams,
|
|
@@ -2229,6 +2574,10 @@ class WrappedResponses extends Responses {
|
|
|
2229
2574
|
const parentPromise = callWithOriginalCreate(this, super.create.bind(this), () => super.parse(openAIParams, options));
|
|
2230
2575
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2231
2576
|
if (isPendingBackgroundResponse(openAIParams, result)) {
|
|
2577
|
+
this.backgroundResponses.set(result.id, {
|
|
2578
|
+
openAIParams,
|
|
2579
|
+
posthogParams
|
|
2580
|
+
});
|
|
2232
2581
|
return result;
|
|
2233
2582
|
}
|
|
2234
2583
|
const latency = (Date.now() - startTime) / 1000;
|
|
@@ -2237,7 +2586,7 @@ class WrappedResponses extends Responses {
|
|
|
2237
2586
|
model: openAIParams.model ?? result.model,
|
|
2238
2587
|
provider: 'openai',
|
|
2239
2588
|
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2240
|
-
output: result.output,
|
|
2589
|
+
output: sanitizeOpenAIResponse(result.output),
|
|
2241
2590
|
latency,
|
|
2242
2591
|
baseURL: this.baseURL,
|
|
2243
2592
|
modelParameters: getModelParams(body, result.service_tier),
|
|
@@ -2252,8 +2601,10 @@ class WrappedResponses extends Responses {
|
|
|
2252
2601
|
stopReason: result.status ?? undefined,
|
|
2253
2602
|
completionId: result.id,
|
|
2254
2603
|
providerMetadata: buildProviderMetadata({
|
|
2255
|
-
requestId: extractRequestId(result)
|
|
2256
|
-
|
|
2604
|
+
requestId: extractRequestId(result),
|
|
2605
|
+
incompleteDetails: result.incomplete_details
|
|
2606
|
+
}),
|
|
2607
|
+
error: getResponseFailure(result)
|
|
2257
2608
|
});
|
|
2258
2609
|
return result;
|
|
2259
2610
|
}, async error => {
|
|
@@ -2406,7 +2757,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2406
2757
|
model: openAIParams.model,
|
|
2407
2758
|
provider: 'openai',
|
|
2408
2759
|
input: openAIParams.prompt,
|
|
2409
|
-
output: finalContent,
|
|
2760
|
+
output: sanitizeOpenAIResponse(finalContent),
|
|
2410
2761
|
latency,
|
|
2411
2762
|
timeToFirstToken,
|
|
2412
2763
|
baseURL: this.baseURL,
|
|
@@ -2451,7 +2802,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2451
2802
|
model: openAIParams.model,
|
|
2452
2803
|
provider: 'openai',
|
|
2453
2804
|
input: openAIParams.prompt,
|
|
2454
|
-
output: result.text,
|
|
2805
|
+
output: sanitizeOpenAIResponse(result.text),
|
|
2455
2806
|
latency,
|
|
2456
2807
|
baseURL: this.baseURL,
|
|
2457
2808
|
modelParameters: getModelParams(body),
|