@posthog/ai 8.7.1 → 8.8.1
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 +36 -13
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +36 -13
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +36 -13
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +36 -13
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +60 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +60 -35
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +27 -13
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +27 -13
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +645 -898
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +645 -898
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +25 -4
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.mjs +25 -4
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/otel/index.cjs +1 -5
- package/dist/otel/index.cjs.map +1 -1
- package/dist/otel/index.mjs +1 -5
- package/dist/otel/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +67 -35
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +67 -35
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +8 -8
package/dist/openai/index.mjs
CHANGED
|
@@ -9,6 +9,33 @@ const isString = value => {
|
|
|
9
9
|
return typeof value === 'string';
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
/** @internal */
|
|
13
|
+
|
|
14
|
+
/** @internal */
|
|
15
|
+
|
|
16
|
+
/** @internal */
|
|
17
|
+
function isFullAiCaptureEnabled(client) {
|
|
18
|
+
return client?.enableFullAiCapture === true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** @internal */
|
|
22
|
+
function captureAiEvent(client, event) {
|
|
23
|
+
if (isFullAiCaptureEnabled(client) && typeof client.captureAi === 'function') {
|
|
24
|
+
client.captureAi(event);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
client.capture(event);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** @internal */
|
|
31
|
+
async function captureAiEventImmediate(client, event) {
|
|
32
|
+
if (isFullAiCaptureEnabled(client) && typeof client.captureAiImmediate === 'function') {
|
|
33
|
+
await client.captureAiImmediate(event);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await client.captureImmediate(event);
|
|
37
|
+
}
|
|
38
|
+
|
|
12
39
|
const DATA_URL_PREFIX_RE = /^data:([^;,\s]+)(?:;[^;,\s]+)*;base64,/i;
|
|
13
40
|
const BASE64_ALPHABET_RE = /^[A-Za-z0-9+/_=-]+$/;
|
|
14
41
|
class Base64Recognizer {
|
|
@@ -114,7 +141,6 @@ class BinaryContentRedactor {
|
|
|
114
141
|
this.recognizer = recognizer;
|
|
115
142
|
}
|
|
116
143
|
redact(value, mediaType) {
|
|
117
|
-
if (this.isMultimodalEnabled()) return value;
|
|
118
144
|
this.visited = new WeakSet();
|
|
119
145
|
return this.walk(value, mediaType ? new MediaTypeContext(undefined, undefined, mediaType) : MediaTypeContext.EMPTY);
|
|
120
146
|
}
|
|
@@ -158,15 +184,12 @@ class BinaryContentRedactor {
|
|
|
158
184
|
if (mediaType === 'application/octet-stream') return '[base64 file redacted]';
|
|
159
185
|
return `[base64 ${mediaType} redacted]`;
|
|
160
186
|
}
|
|
161
|
-
isMultimodalEnabled() {
|
|
162
|
-
const val = process.env._INTERNAL_LLMA_MULTIMODAL || '';
|
|
163
|
-
return val.toLowerCase() === 'true' || val === '1' || val.toLowerCase() === 'yes';
|
|
164
|
-
}
|
|
165
187
|
}
|
|
166
188
|
|
|
167
189
|
const redactor = new BinaryContentRedactor();
|
|
168
|
-
const
|
|
169
|
-
const
|
|
190
|
+
const sanitize = (data, client) => isFullAiCaptureEnabled(client) ? data : redactor.redact(data);
|
|
191
|
+
const sanitizeOpenAI = (data, client) => sanitize(data, client);
|
|
192
|
+
const sanitizeOpenAIResponse = (data, client) => sanitize(data, client);
|
|
170
193
|
|
|
171
194
|
const TOKEN_PROPERTY_KEYS = new Set(['$ai_input_tokens', '$ai_output_tokens', '$ai_cache_read_input_tokens', '$ai_cache_creation_input_tokens', '$ai_total_tokens', '$ai_reasoning_tokens']);
|
|
172
195
|
|
|
@@ -317,6 +340,11 @@ const formatResponseOpenAI = response => {
|
|
|
317
340
|
arguments: item.arguments || {}
|
|
318
341
|
}
|
|
319
342
|
});
|
|
343
|
+
} else if (item.type === 'image_generation_call' && item.result) {
|
|
344
|
+
content.push({
|
|
345
|
+
type: 'image',
|
|
346
|
+
image: item.result
|
|
347
|
+
});
|
|
320
348
|
}
|
|
321
349
|
}
|
|
322
350
|
if (content.length > 0) {
|
|
@@ -549,7 +577,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
549
577
|
return messages;
|
|
550
578
|
}
|
|
551
579
|
|
|
552
|
-
var version = "8.
|
|
580
|
+
var version = "8.8.1";
|
|
553
581
|
|
|
554
582
|
const DEFAULT_MAX_DEPTH = 3;
|
|
555
583
|
const MAX_STACK_LINES = 20;
|
|
@@ -798,9 +826,9 @@ const captureAiGeneration$1 = async (client, options) => {
|
|
|
798
826
|
groups: options.groups
|
|
799
827
|
};
|
|
800
828
|
if (options.captureImmediate) {
|
|
801
|
-
await client
|
|
829
|
+
await captureAiEventImmediate(client, event);
|
|
802
830
|
} else {
|
|
803
|
-
client
|
|
831
|
+
captureAiEvent(client, event);
|
|
804
832
|
}
|
|
805
833
|
} catch (error) {
|
|
806
834
|
// Telemetry failures must never affect the instrumented provider call.
|
|
@@ -1295,6 +1323,340 @@ function monitoredStreamTee(source, createStream) {
|
|
|
1295
1323
|
return [monitoringStream, callerStream];
|
|
1296
1324
|
}
|
|
1297
1325
|
|
|
1326
|
+
/** Pure state accumulator for OpenAI-compatible Chat Completions chunks. */
|
|
1327
|
+
class OpenAIChatStreamAccumulator {
|
|
1328
|
+
accumulatedContent = '';
|
|
1329
|
+
usage = {
|
|
1330
|
+
inputTokens: 0,
|
|
1331
|
+
outputTokens: 0,
|
|
1332
|
+
webSearchCount: 0
|
|
1333
|
+
};
|
|
1334
|
+
toolCalls = new Map();
|
|
1335
|
+
consume(chunk, receivedAt = Date.now()) {
|
|
1336
|
+
this.model ||= chunk.model || undefined;
|
|
1337
|
+
this.completionId ||= chunk.id || undefined;
|
|
1338
|
+
this.systemFingerprint ||= chunk.system_fingerprint || undefined;
|
|
1339
|
+
if (chunk.service_tier != null) {
|
|
1340
|
+
this.serviceTier = chunk.service_tier;
|
|
1341
|
+
}
|
|
1342
|
+
const choice = chunk.choices?.[0];
|
|
1343
|
+
if (choice?.finish_reason) {
|
|
1344
|
+
this.stopReason = choice.finish_reason;
|
|
1345
|
+
}
|
|
1346
|
+
const webSearchCount = calculateWebSearchCount(chunk);
|
|
1347
|
+
if (webSearchCount > (this.usage.webSearchCount ?? 0)) {
|
|
1348
|
+
this.usage.webSearchCount = webSearchCount;
|
|
1349
|
+
}
|
|
1350
|
+
if (choice?.delta?.content) {
|
|
1351
|
+
this.firstTokenTime ??= receivedAt;
|
|
1352
|
+
this.accumulatedContent += choice.delta.content;
|
|
1353
|
+
}
|
|
1354
|
+
if (Array.isArray(choice?.delta?.tool_calls)) {
|
|
1355
|
+
this.firstTokenTime ??= receivedAt;
|
|
1356
|
+
for (const toolCall of choice.delta.tool_calls) {
|
|
1357
|
+
if (toolCall.index === undefined) {
|
|
1358
|
+
continue;
|
|
1359
|
+
}
|
|
1360
|
+
const current = this.toolCalls.get(toolCall.index) ?? {
|
|
1361
|
+
id: '',
|
|
1362
|
+
name: '',
|
|
1363
|
+
arguments: ''
|
|
1364
|
+
};
|
|
1365
|
+
if (toolCall.id) {
|
|
1366
|
+
current.id = toolCall.id;
|
|
1367
|
+
}
|
|
1368
|
+
if (toolCall.function?.name) {
|
|
1369
|
+
current.name = toolCall.function.name;
|
|
1370
|
+
}
|
|
1371
|
+
if (toolCall.function?.arguments) {
|
|
1372
|
+
current.arguments += toolCall.function.arguments;
|
|
1373
|
+
}
|
|
1374
|
+
this.toolCalls.set(toolCall.index, current);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
if (chunk.usage) {
|
|
1378
|
+
this.usage = {
|
|
1379
|
+
...this.usage,
|
|
1380
|
+
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
1381
|
+
outputTokens: chunk.usage.completion_tokens ?? 0,
|
|
1382
|
+
reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
1383
|
+
cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,
|
|
1384
|
+
cacheCreationInputTokens: extractCacheWriteTokens(chunk.usage.prompt_tokens_details),
|
|
1385
|
+
rawUsage: chunk.usage
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
result() {
|
|
1390
|
+
const content = [];
|
|
1391
|
+
if (this.accumulatedContent) {
|
|
1392
|
+
content.push({
|
|
1393
|
+
type: 'text',
|
|
1394
|
+
text: this.accumulatedContent
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
for (const toolCall of this.toolCalls.values()) {
|
|
1398
|
+
if (toolCall.name) {
|
|
1399
|
+
content.push({
|
|
1400
|
+
type: 'function',
|
|
1401
|
+
id: toolCall.id,
|
|
1402
|
+
function: {
|
|
1403
|
+
name: toolCall.name,
|
|
1404
|
+
arguments: toolCall.arguments
|
|
1405
|
+
}
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
return {
|
|
1410
|
+
output: [{
|
|
1411
|
+
role: 'assistant',
|
|
1412
|
+
content: content.length > 0 ? content : [{
|
|
1413
|
+
type: 'text',
|
|
1414
|
+
text: ''
|
|
1415
|
+
}]
|
|
1416
|
+
}],
|
|
1417
|
+
model: this.model,
|
|
1418
|
+
completionId: this.completionId,
|
|
1419
|
+
systemFingerprint: this.systemFingerprint,
|
|
1420
|
+
serviceTier: this.serviceTier,
|
|
1421
|
+
firstTokenTime: this.firstTokenTime,
|
|
1422
|
+
stopReason: this.stopReason,
|
|
1423
|
+
usage: {
|
|
1424
|
+
...this.usage
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
/** Pure state accumulator for OpenAI-compatible Responses stream events. */
|
|
1430
|
+
class OpenAIResponsesStreamAccumulator {
|
|
1431
|
+
output = [];
|
|
1432
|
+
usage = {
|
|
1433
|
+
inputTokens: 0,
|
|
1434
|
+
outputTokens: 0,
|
|
1435
|
+
webSearchCount: 0
|
|
1436
|
+
};
|
|
1437
|
+
consume(event, receivedAt = Date.now()) {
|
|
1438
|
+
if (this.firstTokenTime === undefined && isResponseTokenChunk(event)) {
|
|
1439
|
+
this.firstTokenTime = receivedAt;
|
|
1440
|
+
}
|
|
1441
|
+
if (!('response' in event) || !event.response) {
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
const response = event.response;
|
|
1445
|
+
this.model ||= response.model || undefined;
|
|
1446
|
+
this.completionId ||= response.id || undefined;
|
|
1447
|
+
if (response.service_tier != null) {
|
|
1448
|
+
this.serviceTier = response.service_tier;
|
|
1449
|
+
}
|
|
1450
|
+
const webSearchCount = calculateWebSearchCount(response);
|
|
1451
|
+
if (webSearchCount > (this.usage.webSearchCount ?? 0)) {
|
|
1452
|
+
this.usage.webSearchCount = webSearchCount;
|
|
1453
|
+
}
|
|
1454
|
+
if (response.usage) {
|
|
1455
|
+
this.usage = {
|
|
1456
|
+
...this.usage,
|
|
1457
|
+
inputTokens: response.usage.input_tokens ?? 0,
|
|
1458
|
+
outputTokens: response.usage.output_tokens ?? 0,
|
|
1459
|
+
reasoningTokens: response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1460
|
+
cacheReadInputTokens: response.usage.input_tokens_details?.cached_tokens ?? 0,
|
|
1461
|
+
cacheCreationInputTokens: extractCacheWriteTokens(response.usage.input_tokens_details),
|
|
1462
|
+
rawUsage: response.usage
|
|
1463
|
+
};
|
|
1464
|
+
}
|
|
1465
|
+
if (isTerminalResponse(response)) {
|
|
1466
|
+
this.terminalResponse = response;
|
|
1467
|
+
this.output = response.output ?? [];
|
|
1468
|
+
this.stopReason = response.status;
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
result() {
|
|
1472
|
+
return {
|
|
1473
|
+
output: [...this.output],
|
|
1474
|
+
model: this.model,
|
|
1475
|
+
completionId: this.completionId,
|
|
1476
|
+
serviceTier: this.serviceTier,
|
|
1477
|
+
firstTokenTime: this.firstTokenTime,
|
|
1478
|
+
stopReason: this.stopReason,
|
|
1479
|
+
usage: {
|
|
1480
|
+
...this.usage
|
|
1481
|
+
},
|
|
1482
|
+
terminalResponse: this.terminalResponse
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
function captureAiGenerationInBackground(...args) {
|
|
1488
|
+
void captureAiGeneration(...args).catch(() => undefined);
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
/** Preserve immediate delivery while isolating normal telemetry from provider latency/failures. */
|
|
1492
|
+
async function captureAiGenerationAfterSuccess(...args) {
|
|
1493
|
+
if (args[1].captureImmediate) {
|
|
1494
|
+
await captureAiGeneration(...args);
|
|
1495
|
+
} else {
|
|
1496
|
+
captureAiGenerationInBackground(...args);
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
function buildChatUsage(usage, webSearchSource) {
|
|
1500
|
+
return {
|
|
1501
|
+
inputTokens: usage?.prompt_tokens ?? 0,
|
|
1502
|
+
outputTokens: usage?.completion_tokens ?? 0,
|
|
1503
|
+
reasoningTokens: usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
1504
|
+
cacheReadInputTokens: usage?.prompt_tokens_details?.cached_tokens ?? 0,
|
|
1505
|
+
cacheCreationInputTokens: extractCacheWriteTokens(usage?.prompt_tokens_details),
|
|
1506
|
+
webSearchCount: calculateWebSearchCount(webSearchSource),
|
|
1507
|
+
rawUsage: usage
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
function buildResponsesUsage(usage, webSearchSource) {
|
|
1511
|
+
return {
|
|
1512
|
+
inputTokens: usage?.input_tokens ?? 0,
|
|
1513
|
+
outputTokens: usage?.output_tokens ?? 0,
|
|
1514
|
+
reasoningTokens: usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1515
|
+
cacheReadInputTokens: usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1516
|
+
cacheCreationInputTokens: extractCacheWriteTokens(usage?.input_tokens_details),
|
|
1517
|
+
webSearchCount: calculateWebSearchCount(webSearchSource),
|
|
1518
|
+
rawUsage: usage
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
function buildChatSuccessOptions(context, result) {
|
|
1522
|
+
return {
|
|
1523
|
+
...context.monitoring,
|
|
1524
|
+
model: context.params.model ?? result.model,
|
|
1525
|
+
provider: context.provider,
|
|
1526
|
+
input: sanitizeOpenAI(context.params.messages, context.client),
|
|
1527
|
+
output: sanitizeOpenAIResponse(result.output, context.client),
|
|
1528
|
+
latency: result.latency,
|
|
1529
|
+
timeToFirstToken: result.timeToFirstToken,
|
|
1530
|
+
baseURL: context.baseURL,
|
|
1531
|
+
modelParameters: getModelParams(context.modelParametersSource, result.serviceTier),
|
|
1532
|
+
httpStatus: 200,
|
|
1533
|
+
usage: result.usage,
|
|
1534
|
+
stopReason: result.stopReason,
|
|
1535
|
+
tools: extractAvailableToolCalls('openai', context.params),
|
|
1536
|
+
completionId: result.completionId,
|
|
1537
|
+
providerMetadata: buildProviderMetadata({
|
|
1538
|
+
systemFingerprint: result.systemFingerprint,
|
|
1539
|
+
requestId: result.requestId
|
|
1540
|
+
})
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
function buildChatErrorOptions(context, error, metadata = {}) {
|
|
1544
|
+
return {
|
|
1545
|
+
...context.monitoring,
|
|
1546
|
+
model: context.params.model,
|
|
1547
|
+
provider: context.provider,
|
|
1548
|
+
input: sanitizeOpenAI(context.params.messages, context.client),
|
|
1549
|
+
output: [],
|
|
1550
|
+
latency: 0,
|
|
1551
|
+
baseURL: context.baseURL,
|
|
1552
|
+
modelParameters: getModelParams(context.modelParametersSource),
|
|
1553
|
+
usage: {
|
|
1554
|
+
inputTokens: 0,
|
|
1555
|
+
outputTokens: 0
|
|
1556
|
+
},
|
|
1557
|
+
completionId: metadata.completionId,
|
|
1558
|
+
providerMetadata: buildProviderMetadata({
|
|
1559
|
+
systemFingerprint: metadata.systemFingerprint
|
|
1560
|
+
}),
|
|
1561
|
+
error
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
function buildSanitizedResponsesInput(context) {
|
|
1565
|
+
return formatOpenAIResponsesInput(sanitizeOpenAIResponse(context.params.input, context.client), sanitizeOpenAIResponse(context.params.instructions, context.client));
|
|
1566
|
+
}
|
|
1567
|
+
function buildResponsesSuccessOptions(context, result) {
|
|
1568
|
+
const response = result.response;
|
|
1569
|
+
return {
|
|
1570
|
+
...context.monitoring,
|
|
1571
|
+
model: context.params.model ?? response.model,
|
|
1572
|
+
provider: context.provider,
|
|
1573
|
+
input: buildSanitizedResponsesInput(context),
|
|
1574
|
+
output: sanitizeOpenAIResponse(result.output, context.client),
|
|
1575
|
+
latency: result.latency,
|
|
1576
|
+
timeToFirstToken: result.timeToFirstToken,
|
|
1577
|
+
baseURL: context.baseURL,
|
|
1578
|
+
modelParameters: getModelParams(context.modelParametersSource, response.service_tier),
|
|
1579
|
+
httpStatus: 200,
|
|
1580
|
+
usage: result.usage ?? buildResponsesUsage(response.usage, response),
|
|
1581
|
+
stopReason: response.status ?? undefined,
|
|
1582
|
+
tools: result.includeTools ? extractAvailableToolCalls('openai', context.params) : undefined,
|
|
1583
|
+
completionId: response.id,
|
|
1584
|
+
providerMetadata: buildProviderMetadata({
|
|
1585
|
+
requestId: result.includeRequestId ? extractRequestId(response) : undefined,
|
|
1586
|
+
incompleteDetails: response.incomplete_details
|
|
1587
|
+
}),
|
|
1588
|
+
error: getResponseFailure({
|
|
1589
|
+
id: response.id,
|
|
1590
|
+
status: response.status,
|
|
1591
|
+
error: response.error ?? null
|
|
1592
|
+
})
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
function buildBackgroundResponseOptions(context, response) {
|
|
1596
|
+
return buildResponsesSuccessOptions(context, {
|
|
1597
|
+
response,
|
|
1598
|
+
output: formatResponseOpenAI({
|
|
1599
|
+
output: response.output
|
|
1600
|
+
}),
|
|
1601
|
+
latency: getBackgroundResponseLatency(response),
|
|
1602
|
+
includeTools: true,
|
|
1603
|
+
includeRequestId: true
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
function buildResponsesErrorOptions(context, error, completionId) {
|
|
1607
|
+
return {
|
|
1608
|
+
...context.monitoring,
|
|
1609
|
+
model: context.params.model,
|
|
1610
|
+
provider: context.provider,
|
|
1611
|
+
input: buildSanitizedResponsesInput(context),
|
|
1612
|
+
output: [],
|
|
1613
|
+
latency: 0,
|
|
1614
|
+
baseURL: context.baseURL,
|
|
1615
|
+
modelParameters: getModelParams(context.modelParametersSource),
|
|
1616
|
+
usage: {
|
|
1617
|
+
inputTokens: 0,
|
|
1618
|
+
outputTokens: 0
|
|
1619
|
+
},
|
|
1620
|
+
completionId,
|
|
1621
|
+
error
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
function buildEmbeddingSuccessOptions(context, usage, latency) {
|
|
1625
|
+
return {
|
|
1626
|
+
eventType: AIEvent.Embedding,
|
|
1627
|
+
...context.monitoring,
|
|
1628
|
+
model: context.params.model,
|
|
1629
|
+
provider: context.provider,
|
|
1630
|
+
input: withPrivacyMode(context.client, context.monitoring.privacyMode, context.params.input),
|
|
1631
|
+
output: null,
|
|
1632
|
+
latency,
|
|
1633
|
+
baseURL: context.baseURL,
|
|
1634
|
+
modelParameters: getModelParams(context.modelParametersSource),
|
|
1635
|
+
httpStatus: 200,
|
|
1636
|
+
usage: {
|
|
1637
|
+
inputTokens: usage?.prompt_tokens ?? 0,
|
|
1638
|
+
rawUsage: usage
|
|
1639
|
+
}
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
function buildEmbeddingErrorOptions(context, error) {
|
|
1643
|
+
return {
|
|
1644
|
+
eventType: AIEvent.Embedding,
|
|
1645
|
+
...context.monitoring,
|
|
1646
|
+
model: context.params.model,
|
|
1647
|
+
provider: context.provider,
|
|
1648
|
+
input: withPrivacyMode(context.client, context.monitoring.privacyMode, context.params.input),
|
|
1649
|
+
output: null,
|
|
1650
|
+
latency: 0,
|
|
1651
|
+
baseURL: context.baseURL,
|
|
1652
|
+
modelParameters: getModelParams(context.modelParametersSource),
|
|
1653
|
+
usage: {
|
|
1654
|
+
inputTokens: 0
|
|
1655
|
+
},
|
|
1656
|
+
error
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1298
1660
|
class PostHogAzureOpenAI extends AzureOpenAI {
|
|
1299
1661
|
constructor(config) {
|
|
1300
1662
|
const {
|
|
@@ -1340,169 +1702,37 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1340
1702
|
if (Symbol.asyncIterator in value) {
|
|
1341
1703
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
1342
1704
|
(async () => {
|
|
1343
|
-
|
|
1344
|
-
// from the streamed chunks before the failure.
|
|
1345
|
-
let completionIdFromResponse;
|
|
1346
|
-
let systemFingerprintFromResponse;
|
|
1705
|
+
const accumulator = new OpenAIChatStreamAccumulator();
|
|
1347
1706
|
try {
|
|
1348
|
-
const contentBlocks = [];
|
|
1349
|
-
let accumulatedContent = '';
|
|
1350
|
-
let modelFromResponse;
|
|
1351
|
-
let serviceTierFromResponse;
|
|
1352
|
-
let firstTokenTime;
|
|
1353
|
-
let usage = {
|
|
1354
|
-
inputTokens: 0,
|
|
1355
|
-
outputTokens: 0
|
|
1356
|
-
};
|
|
1357
|
-
|
|
1358
|
-
// Map to track in-progress tool calls
|
|
1359
|
-
const toolCallsInProgress = new Map();
|
|
1360
1707
|
for await (const chunk of stream1) {
|
|
1361
|
-
|
|
1362
|
-
if (!modelFromResponse && chunk.model) {
|
|
1363
|
-
modelFromResponse = chunk.model;
|
|
1364
|
-
}
|
|
1365
|
-
if (!completionIdFromResponse && chunk.id) {
|
|
1366
|
-
completionIdFromResponse = chunk.id;
|
|
1367
|
-
}
|
|
1368
|
-
if (!systemFingerprintFromResponse && chunk.system_fingerprint) {
|
|
1369
|
-
systemFingerprintFromResponse = chunk.system_fingerprint;
|
|
1370
|
-
}
|
|
1371
|
-
if (chunk.service_tier != null) {
|
|
1372
|
-
serviceTierFromResponse = chunk.service_tier;
|
|
1373
|
-
}
|
|
1374
|
-
const choice = chunk?.choices?.[0];
|
|
1375
|
-
|
|
1376
|
-
// Handle text content
|
|
1377
|
-
const deltaContent = choice?.delta?.content;
|
|
1378
|
-
if (deltaContent) {
|
|
1379
|
-
if (firstTokenTime === undefined) {
|
|
1380
|
-
firstTokenTime = Date.now();
|
|
1381
|
-
}
|
|
1382
|
-
accumulatedContent += deltaContent;
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
// Handle tool calls
|
|
1386
|
-
const deltaToolCalls = choice?.delta?.tool_calls;
|
|
1387
|
-
if (deltaToolCalls && Array.isArray(deltaToolCalls)) {
|
|
1388
|
-
if (firstTokenTime === undefined) {
|
|
1389
|
-
firstTokenTime = Date.now();
|
|
1390
|
-
}
|
|
1391
|
-
for (const toolCall of deltaToolCalls) {
|
|
1392
|
-
const index = toolCall.index;
|
|
1393
|
-
if (index !== undefined) {
|
|
1394
|
-
if (!toolCallsInProgress.has(index)) {
|
|
1395
|
-
// New tool call
|
|
1396
|
-
toolCallsInProgress.set(index, {
|
|
1397
|
-
id: toolCall.id || '',
|
|
1398
|
-
name: toolCall.function?.name || '',
|
|
1399
|
-
arguments: ''
|
|
1400
|
-
});
|
|
1401
|
-
}
|
|
1402
|
-
const inProgressCall = toolCallsInProgress.get(index);
|
|
1403
|
-
if (inProgressCall) {
|
|
1404
|
-
// Update tool call data
|
|
1405
|
-
if (toolCall.id) {
|
|
1406
|
-
inProgressCall.id = toolCall.id;
|
|
1407
|
-
}
|
|
1408
|
-
if (toolCall.function?.name) {
|
|
1409
|
-
inProgressCall.name = toolCall.function.name;
|
|
1410
|
-
}
|
|
1411
|
-
if (toolCall.function?.arguments) {
|
|
1412
|
-
inProgressCall.arguments += toolCall.function.arguments;
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
// Handle usage information
|
|
1420
|
-
if (chunk.usage) {
|
|
1421
|
-
usage = {
|
|
1422
|
-
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
1423
|
-
outputTokens: chunk.usage.completion_tokens ?? 0,
|
|
1424
|
-
reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
1425
|
-
cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,
|
|
1426
|
-
cacheCreationInputTokens: extractCacheWriteTokens(chunk.usage.prompt_tokens_details)
|
|
1427
|
-
};
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
|
-
// Build final content blocks
|
|
1432
|
-
if (accumulatedContent) {
|
|
1433
|
-
contentBlocks.push({
|
|
1434
|
-
type: 'text',
|
|
1435
|
-
text: accumulatedContent
|
|
1436
|
-
});
|
|
1708
|
+
accumulator.consume(chunk);
|
|
1437
1709
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
if (toolCall.name) {
|
|
1442
|
-
contentBlocks.push({
|
|
1443
|
-
type: 'function',
|
|
1444
|
-
id: toolCall.id,
|
|
1445
|
-
function: {
|
|
1446
|
-
name: toolCall.name,
|
|
1447
|
-
arguments: toolCall.arguments
|
|
1448
|
-
}
|
|
1449
|
-
});
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
// Format output to match non-streaming version
|
|
1454
|
-
const formattedOutput = contentBlocks.length > 0 ? [{
|
|
1455
|
-
role: 'assistant',
|
|
1456
|
-
content: contentBlocks
|
|
1457
|
-
}] : [{
|
|
1458
|
-
role: 'assistant',
|
|
1459
|
-
content: [{
|
|
1460
|
-
type: 'text',
|
|
1461
|
-
text: ''
|
|
1462
|
-
}]
|
|
1463
|
-
}];
|
|
1464
|
-
const latency = (Date.now() - startTime) / 1000;
|
|
1465
|
-
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
1466
|
-
await captureAiGeneration(this.phClient, {
|
|
1467
|
-
...posthogParams,
|
|
1468
|
-
model: openAIParams.model ?? modelFromResponse,
|
|
1710
|
+
const accumulated = accumulator.result();
|
|
1711
|
+
await captureAiGeneration(this.phClient, buildChatSuccessOptions({
|
|
1712
|
+
client: this.phClient,
|
|
1469
1713
|
provider: 'azure',
|
|
1470
|
-
input: sanitizeOpenAI(openAIParams.messages),
|
|
1471
|
-
output: sanitizeOpenAIResponse(formattedOutput),
|
|
1472
|
-
latency,
|
|
1473
|
-
timeToFirstToken,
|
|
1474
1714
|
baseURL: this.baseURL,
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
});
|
|
1715
|
+
params: openAIParams,
|
|
1716
|
+
monitoring: posthogParams,
|
|
1717
|
+
modelParametersSource: body
|
|
1718
|
+
}, {
|
|
1719
|
+
...accumulated,
|
|
1720
|
+
latency: (Date.now() - startTime) / 1000,
|
|
1721
|
+
timeToFirstToken: accumulated.firstTokenTime === undefined ? undefined : (accumulated.firstTokenTime - startTime) / 1000
|
|
1722
|
+
}));
|
|
1483
1723
|
} catch (error) {
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1724
|
+
const accumulated = accumulator.result();
|
|
1725
|
+
await captureAiGeneration(this.phClient, buildChatErrorOptions({
|
|
1726
|
+
client: this.phClient,
|
|
1487
1727
|
provider: 'azure',
|
|
1488
|
-
input: sanitizeOpenAI(openAIParams.messages),
|
|
1489
|
-
output: [],
|
|
1490
|
-
latency: 0,
|
|
1491
1728
|
baseURL: this.baseURL,
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
// event can still be correlated to OpenAI's Logs dashboard.
|
|
1500
|
-
completionId: completionIdFromResponse,
|
|
1501
|
-
providerMetadata: buildProviderMetadata({
|
|
1502
|
-
systemFingerprint: systemFingerprintFromResponse
|
|
1503
|
-
}),
|
|
1504
|
-
error: error
|
|
1505
|
-
});
|
|
1729
|
+
params: openAIParams,
|
|
1730
|
+
monitoring: posthogParams,
|
|
1731
|
+
modelParametersSource: body
|
|
1732
|
+
}, error, {
|
|
1733
|
+
completionId: accumulated.completionId,
|
|
1734
|
+
systemFingerprint: accumulated.systemFingerprint
|
|
1735
|
+
}));
|
|
1506
1736
|
throw error;
|
|
1507
1737
|
}
|
|
1508
1738
|
})().catch(() => {
|
|
@@ -1519,50 +1749,35 @@ let WrappedCompletions$1 = class WrappedCompletions extends AzureOpenAI.Chat.Com
|
|
|
1519
1749
|
} else {
|
|
1520
1750
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1521
1751
|
if ('choices' in result) {
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
...posthogParams,
|
|
1525
|
-
model: openAIParams.model ?? result.model,
|
|
1752
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildChatSuccessOptions({
|
|
1753
|
+
client: this.phClient,
|
|
1526
1754
|
provider: 'azure',
|
|
1527
|
-
input: sanitizeOpenAI(openAIParams.messages),
|
|
1528
|
-
output: sanitizeOpenAIResponse(formatResponseOpenAI(result)),
|
|
1529
|
-
latency,
|
|
1530
1755
|
baseURL: this.baseURL,
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1756
|
+
params: openAIParams,
|
|
1757
|
+
monitoring: posthogParams,
|
|
1758
|
+
modelParametersSource: body
|
|
1759
|
+
}, {
|
|
1760
|
+
output: formatResponseOpenAI(result),
|
|
1761
|
+
model: result.model,
|
|
1762
|
+
serviceTier: result.service_tier ?? undefined,
|
|
1763
|
+
latency: (Date.now() - startTime) / 1000,
|
|
1764
|
+
usage: buildChatUsage(result.usage, result),
|
|
1765
|
+
stopReason: result.choices[0]?.finish_reason ?? undefined,
|
|
1540
1766
|
completionId: result.id,
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
})
|
|
1545
|
-
});
|
|
1767
|
+
systemFingerprint: result.system_fingerprint,
|
|
1768
|
+
requestId: result._request_id
|
|
1769
|
+
}));
|
|
1546
1770
|
}
|
|
1547
1771
|
return result;
|
|
1548
1772
|
}, async error => {
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
...posthogParams,
|
|
1552
|
-
model: openAIParams.model,
|
|
1773
|
+
await captureAiGeneration(this.phClient, buildChatErrorOptions({
|
|
1774
|
+
client: this.phClient,
|
|
1553
1775
|
provider: 'azure',
|
|
1554
|
-
input: sanitizeOpenAI(openAIParams.messages),
|
|
1555
|
-
output: [],
|
|
1556
|
-
latency: 0,
|
|
1557
1776
|
baseURL: this.baseURL,
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
outputTokens: 0
|
|
1563
|
-
},
|
|
1564
|
-
error
|
|
1565
|
-
});
|
|
1777
|
+
params: openAIParams,
|
|
1778
|
+
monitoring: posthogParams,
|
|
1779
|
+
modelParametersSource: body
|
|
1780
|
+
}, error));
|
|
1566
1781
|
throw error;
|
|
1567
1782
|
});
|
|
1568
1783
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -1581,32 +1796,14 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1581
1796
|
openAIParams,
|
|
1582
1797
|
posthogParams
|
|
1583
1798
|
} = context;
|
|
1584
|
-
await
|
|
1585
|
-
|
|
1586
|
-
model: openAIParams.model ?? result.model,
|
|
1799
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildBackgroundResponseOptions({
|
|
1800
|
+
client: this.phClient,
|
|
1587
1801
|
provider: 'azure',
|
|
1588
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1589
|
-
output: result.output,
|
|
1590
|
-
latency: getBackgroundResponseLatency(result),
|
|
1591
1802
|
baseURL: this.baseURL,
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1597
|
-
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1598
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1599
|
-
cacheCreationInputTokens: extractCacheWriteTokens(result.usage?.input_tokens_details),
|
|
1600
|
-
rawUsage: result.usage
|
|
1601
|
-
},
|
|
1602
|
-
stopReason: result.status ?? undefined,
|
|
1603
|
-
completionId: result.id,
|
|
1604
|
-
providerMetadata: buildProviderMetadata({
|
|
1605
|
-
requestId: extractRequestId(result),
|
|
1606
|
-
incompleteDetails: result.incomplete_details
|
|
1607
|
-
}),
|
|
1608
|
-
error: getResponseFailure(result)
|
|
1609
|
-
});
|
|
1803
|
+
params: openAIParams,
|
|
1804
|
+
monitoring: posthogParams,
|
|
1805
|
+
modelParametersSource: openAIParams
|
|
1806
|
+
}, result));
|
|
1610
1807
|
}
|
|
1611
1808
|
|
|
1612
1809
|
// --- Overload #1: Non-streaming
|
|
@@ -1628,108 +1825,61 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1628
1825
|
if (Symbol.asyncIterator in value) {
|
|
1629
1826
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
1630
1827
|
(async () => {
|
|
1631
|
-
|
|
1632
|
-
// was accumulated from the streamed chunks before the failure.
|
|
1633
|
-
let completionIdFromResponse;
|
|
1828
|
+
const accumulator = new OpenAIResponsesStreamAccumulator();
|
|
1634
1829
|
try {
|
|
1635
|
-
let finalContent = [];
|
|
1636
|
-
let modelFromResponse;
|
|
1637
|
-
let serviceTierFromResponse;
|
|
1638
|
-
let firstTokenTime;
|
|
1639
|
-
let usage = {
|
|
1640
|
-
inputTokens: 0,
|
|
1641
|
-
outputTokens: 0
|
|
1642
|
-
};
|
|
1643
|
-
let terminalResponse;
|
|
1644
1830
|
for await (const chunk of stream1) {
|
|
1645
|
-
|
|
1646
|
-
if (
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
if (!modelFromResponse && chunk.response.model) {
|
|
1652
|
-
modelFromResponse = chunk.response.model;
|
|
1653
|
-
}
|
|
1654
|
-
if (!completionIdFromResponse && chunk.response.id) {
|
|
1655
|
-
completionIdFromResponse = chunk.response.id;
|
|
1656
|
-
}
|
|
1657
|
-
if (openAIParams.background === true && !this.backgroundResponses.get(chunk.response.id)) {
|
|
1658
|
-
this.backgroundResponses.set(chunk.response.id, {
|
|
1659
|
-
openAIParams,
|
|
1660
|
-
posthogParams
|
|
1661
|
-
});
|
|
1662
|
-
}
|
|
1663
|
-
if (chunk.response.service_tier != null) {
|
|
1664
|
-
serviceTierFromResponse = chunk.response.service_tier;
|
|
1665
|
-
}
|
|
1666
|
-
if (isTerminalResponse(chunk.response)) {
|
|
1667
|
-
terminalResponse = chunk.response;
|
|
1668
|
-
finalContent = chunk.response.output ?? [];
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
if ('response' in chunk && chunk.response?.usage) {
|
|
1672
|
-
usage = {
|
|
1673
|
-
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
1674
|
-
outputTokens: chunk.response.usage.output_tokens ?? 0,
|
|
1675
|
-
reasoningTokens: chunk.response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1676
|
-
cacheReadInputTokens: chunk.response.usage.input_tokens_details?.cached_tokens ?? 0,
|
|
1677
|
-
cacheCreationInputTokens: extractCacheWriteTokens(chunk.response.usage.input_tokens_details)
|
|
1678
|
-
};
|
|
1831
|
+
accumulator.consume(chunk);
|
|
1832
|
+
if (openAIParams.background === true && 'response' in chunk && chunk.response && !this.backgroundResponses.get(chunk.response.id)) {
|
|
1833
|
+
this.backgroundResponses.set(chunk.response.id, {
|
|
1834
|
+
openAIParams,
|
|
1835
|
+
posthogParams
|
|
1836
|
+
});
|
|
1679
1837
|
}
|
|
1680
1838
|
}
|
|
1839
|
+
const accumulated = accumulator.result();
|
|
1681
1840
|
if (openAIParams.background === true) {
|
|
1682
|
-
if (terminalResponse) {
|
|
1683
|
-
const context = this.backgroundResponses.take(terminalResponse.id);
|
|
1841
|
+
if (accumulated.terminalResponse) {
|
|
1842
|
+
const context = this.backgroundResponses.take(accumulated.terminalResponse.id);
|
|
1684
1843
|
if (context) {
|
|
1685
|
-
await this.captureBackgroundResponse(terminalResponse, context).catch(() => undefined);
|
|
1844
|
+
await this.captureBackgroundResponse(accumulated.terminalResponse, context).catch(() => undefined);
|
|
1686
1845
|
}
|
|
1687
1846
|
}
|
|
1688
1847
|
return;
|
|
1689
1848
|
}
|
|
1690
|
-
const
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1849
|
+
const response = accumulated.terminalResponse ?? {
|
|
1850
|
+
id: accumulated.completionId ?? '',
|
|
1851
|
+
model: accumulated.model ?? openAIParams.model,
|
|
1852
|
+
status: accumulated.stopReason,
|
|
1853
|
+
service_tier: accumulated.serviceTier
|
|
1854
|
+
};
|
|
1855
|
+
await captureAiGeneration(this.phClient, buildResponsesSuccessOptions({
|
|
1856
|
+
client: this.phClient,
|
|
1695
1857
|
provider: 'azure',
|
|
1696
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1697
|
-
output: sanitizeOpenAIResponse(finalContent),
|
|
1698
|
-
latency,
|
|
1699
|
-
timeToFirstToken,
|
|
1700
1858
|
baseURL: this.baseURL,
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1859
|
+
params: openAIParams,
|
|
1860
|
+
monitoring: posthogParams,
|
|
1861
|
+
modelParametersSource: body
|
|
1862
|
+
}, {
|
|
1863
|
+
response,
|
|
1864
|
+
output: accumulated.output,
|
|
1865
|
+
latency: (Date.now() - startTime) / 1000,
|
|
1866
|
+
timeToFirstToken: accumulated.firstTokenTime === undefined ? undefined : (accumulated.firstTokenTime - startTime) / 1000,
|
|
1867
|
+
usage: accumulated.usage,
|
|
1868
|
+
includeTools: true
|
|
1869
|
+
}));
|
|
1711
1870
|
} catch (error) {
|
|
1712
|
-
|
|
1871
|
+
const accumulated = accumulator.result();
|
|
1872
|
+
if (openAIParams.background === true && accumulated.completionId && this.backgroundResponses.get(accumulated.completionId)) {
|
|
1713
1873
|
throw error;
|
|
1714
1874
|
}
|
|
1715
|
-
await captureAiGeneration(this.phClient, {
|
|
1716
|
-
|
|
1717
|
-
model: openAIParams.model,
|
|
1875
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
1876
|
+
client: this.phClient,
|
|
1718
1877
|
provider: 'azure',
|
|
1719
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1720
|
-
output: [],
|
|
1721
|
-
latency: 0,
|
|
1722
1878
|
baseURL: this.baseURL,
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
},
|
|
1728
|
-
// Surface the completion ID from any chunks consumed before
|
|
1729
|
-
// the stream failed so the error event remains correlatable.
|
|
1730
|
-
completionId: completionIdFromResponse,
|
|
1731
|
-
error: error
|
|
1732
|
-
});
|
|
1879
|
+
params: openAIParams,
|
|
1880
|
+
monitoring: posthogParams,
|
|
1881
|
+
modelParametersSource: body
|
|
1882
|
+
}, error, accumulated.completionId));
|
|
1733
1883
|
throw error;
|
|
1734
1884
|
}
|
|
1735
1885
|
})().catch(() => {
|
|
@@ -1751,53 +1901,33 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1751
1901
|
});
|
|
1752
1902
|
return result;
|
|
1753
1903
|
}
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
...posthogParams,
|
|
1757
|
-
model: openAIParams.model ?? result.model,
|
|
1904
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildResponsesSuccessOptions({
|
|
1905
|
+
client: this.phClient,
|
|
1758
1906
|
provider: 'azure',
|
|
1759
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1760
|
-
output: sanitizeOpenAIResponse(result.output),
|
|
1761
|
-
latency,
|
|
1762
1907
|
baseURL: this.baseURL,
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
cacheCreationInputTokens: extractCacheWriteTokens(result.usage?.input_tokens_details),
|
|
1771
|
-
rawUsage: result.usage
|
|
1772
|
-
},
|
|
1773
|
-
stopReason: result.status ?? undefined,
|
|
1774
|
-
completionId: result.id,
|
|
1775
|
-
providerMetadata: buildProviderMetadata({
|
|
1776
|
-
requestId: extractRequestId(result),
|
|
1777
|
-
incompleteDetails: result.incomplete_details
|
|
1908
|
+
params: openAIParams,
|
|
1909
|
+
monitoring: posthogParams,
|
|
1910
|
+
modelParametersSource: body
|
|
1911
|
+
}, {
|
|
1912
|
+
response: result,
|
|
1913
|
+
output: formatResponseOpenAI({
|
|
1914
|
+
output: result.output
|
|
1778
1915
|
}),
|
|
1779
|
-
|
|
1780
|
-
|
|
1916
|
+
latency: (Date.now() - startTime) / 1000,
|
|
1917
|
+
includeTools: true,
|
|
1918
|
+
includeRequestId: true
|
|
1919
|
+
}));
|
|
1781
1920
|
}
|
|
1782
1921
|
return result;
|
|
1783
1922
|
}, async error => {
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
...posthogParams,
|
|
1787
|
-
model: openAIParams.model,
|
|
1923
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
1924
|
+
client: this.phClient,
|
|
1788
1925
|
provider: 'azure',
|
|
1789
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1790
|
-
output: [],
|
|
1791
|
-
latency: 0,
|
|
1792
1926
|
baseURL: this.baseURL,
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
outputTokens: 0
|
|
1798
|
-
},
|
|
1799
|
-
error
|
|
1800
|
-
});
|
|
1927
|
+
params: openAIParams,
|
|
1928
|
+
monitoring: posthogParams,
|
|
1929
|
+
modelParametersSource: body
|
|
1930
|
+
}, error));
|
|
1801
1931
|
throw error;
|
|
1802
1932
|
});
|
|
1803
1933
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -1867,51 +1997,29 @@ let WrappedResponses$1 = class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1867
1997
|
});
|
|
1868
1998
|
return result;
|
|
1869
1999
|
}
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
...posthogParams,
|
|
1873
|
-
model: openAIParams.model ?? result.model,
|
|
2000
|
+
await captureAiGeneration(this.phClient, buildResponsesSuccessOptions({
|
|
2001
|
+
client: this.phClient,
|
|
1874
2002
|
provider: 'azure',
|
|
1875
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1876
|
-
output: sanitizeOpenAIResponse(result.output),
|
|
1877
|
-
latency,
|
|
1878
2003
|
baseURL: this.baseURL,
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
},
|
|
1889
|
-
stopReason: result.status ?? undefined,
|
|
1890
|
-
completionId: result.id,
|
|
1891
|
-
providerMetadata: buildProviderMetadata({
|
|
1892
|
-
requestId: extractRequestId(result),
|
|
1893
|
-
incompleteDetails: result.incomplete_details
|
|
1894
|
-
}),
|
|
1895
|
-
error: getResponseFailure(result)
|
|
1896
|
-
});
|
|
2004
|
+
params: openAIParams,
|
|
2005
|
+
monitoring: posthogParams,
|
|
2006
|
+
modelParametersSource: body
|
|
2007
|
+
}, {
|
|
2008
|
+
response: result,
|
|
2009
|
+
output: result.output,
|
|
2010
|
+
latency: (Date.now() - startTime) / 1000,
|
|
2011
|
+
includeRequestId: true
|
|
2012
|
+
}));
|
|
1897
2013
|
return result;
|
|
1898
2014
|
}, async error => {
|
|
1899
|
-
await captureAiGeneration(this.phClient, {
|
|
1900
|
-
|
|
1901
|
-
model: openAIParams.model,
|
|
2015
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
2016
|
+
client: this.phClient,
|
|
1902
2017
|
provider: 'azure',
|
|
1903
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1904
|
-
output: [],
|
|
1905
|
-
latency: 0,
|
|
1906
2018
|
baseURL: this.baseURL,
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
outputTokens: 0
|
|
1912
|
-
},
|
|
1913
|
-
error
|
|
1914
|
-
});
|
|
2019
|
+
params: openAIParams,
|
|
2020
|
+
monitoring: posthogParams,
|
|
2021
|
+
modelParametersSource: body
|
|
2022
|
+
}, error));
|
|
1915
2023
|
throw error;
|
|
1916
2024
|
});
|
|
1917
2025
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -1931,42 +2039,24 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends AzureOpenAI.Embeddings
|
|
|
1931
2039
|
const startTime = Date.now();
|
|
1932
2040
|
const parentPromise = super.create(openAIParams, options);
|
|
1933
2041
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
eventType: AIEvent.Embedding,
|
|
1937
|
-
...posthogParams,
|
|
1938
|
-
model: openAIParams.model,
|
|
2042
|
+
await captureAiGeneration(this.phClient, buildEmbeddingSuccessOptions({
|
|
2043
|
+
client: this.phClient,
|
|
1939
2044
|
provider: 'azure',
|
|
1940
|
-
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
1941
|
-
output: null,
|
|
1942
|
-
// Embeddings don't have output content
|
|
1943
|
-
latency,
|
|
1944
2045
|
baseURL: this.baseURL,
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
}
|
|
1950
|
-
});
|
|
2046
|
+
params: openAIParams,
|
|
2047
|
+
monitoring: posthogParams,
|
|
2048
|
+
modelParametersSource: body
|
|
2049
|
+
}, result.usage, (Date.now() - startTime) / 1000));
|
|
1951
2050
|
return result;
|
|
1952
2051
|
}, async error => {
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
eventType: AIEvent.Embedding,
|
|
1956
|
-
...posthogParams,
|
|
1957
|
-
model: openAIParams.model,
|
|
2052
|
+
await captureAiGeneration(this.phClient, buildEmbeddingErrorOptions({
|
|
2053
|
+
client: this.phClient,
|
|
1958
2054
|
provider: 'azure',
|
|
1959
|
-
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
1960
|
-
output: null,
|
|
1961
|
-
latency: 0,
|
|
1962
2055
|
baseURL: this.baseURL,
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
},
|
|
1968
|
-
error
|
|
1969
|
-
});
|
|
2056
|
+
params: openAIParams,
|
|
2057
|
+
monitoring: posthogParams,
|
|
2058
|
+
modelParametersSource: body
|
|
2059
|
+
}, error));
|
|
1970
2060
|
throw error;
|
|
1971
2061
|
});
|
|
1972
2062
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -1979,17 +2069,6 @@ const Responses = OpenAI.Responses;
|
|
|
1979
2069
|
const Embeddings = OpenAI.Embeddings;
|
|
1980
2070
|
const Audio = OpenAI.Audio;
|
|
1981
2071
|
const Transcriptions = OpenAI.Audio.Transcriptions;
|
|
1982
|
-
function captureAiGenerationInBackground(...args) {
|
|
1983
|
-
void captureAiGeneration(...args).catch(() => undefined);
|
|
1984
|
-
}
|
|
1985
|
-
async function captureAiGenerationAfterSuccess(...args) {
|
|
1986
|
-
const [, options] = args;
|
|
1987
|
-
if (options.captureImmediate) {
|
|
1988
|
-
await captureAiGeneration(...args);
|
|
1989
|
-
} else {
|
|
1990
|
-
captureAiGenerationInBackground(...args);
|
|
1991
|
-
}
|
|
1992
|
-
}
|
|
1993
2072
|
class PostHogOpenAI extends OpenAI {
|
|
1994
2073
|
constructor(config) {
|
|
1995
2074
|
const {
|
|
@@ -2036,192 +2115,37 @@ class WrappedCompletions extends Completions {
|
|
|
2036
2115
|
if (Symbol.asyncIterator in value) {
|
|
2037
2116
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
2038
2117
|
(async () => {
|
|
2039
|
-
|
|
2040
|
-
// from the streamed chunks before the failure.
|
|
2041
|
-
let completionIdFromResponse;
|
|
2042
|
-
let systemFingerprintFromResponse;
|
|
2118
|
+
const accumulator = new OpenAIChatStreamAccumulator();
|
|
2043
2119
|
try {
|
|
2044
|
-
const contentBlocks = [];
|
|
2045
|
-
let accumulatedContent = '';
|
|
2046
|
-
let modelFromResponse;
|
|
2047
|
-
let serviceTierFromResponse;
|
|
2048
|
-
let firstTokenTime;
|
|
2049
|
-
let stopReason;
|
|
2050
|
-
let usage = {
|
|
2051
|
-
inputTokens: 0,
|
|
2052
|
-
outputTokens: 0,
|
|
2053
|
-
webSearchCount: 0
|
|
2054
|
-
};
|
|
2055
|
-
|
|
2056
|
-
// Map to track in-progress tool calls
|
|
2057
|
-
const toolCallsInProgress = new Map();
|
|
2058
|
-
let rawUsageData;
|
|
2059
2120
|
for await (const chunk of stream1) {
|
|
2060
|
-
|
|
2061
|
-
if (!modelFromResponse && chunk.model) {
|
|
2062
|
-
modelFromResponse = chunk.model;
|
|
2063
|
-
}
|
|
2064
|
-
if (!completionIdFromResponse && chunk.id) {
|
|
2065
|
-
completionIdFromResponse = chunk.id;
|
|
2066
|
-
}
|
|
2067
|
-
if (!systemFingerprintFromResponse && chunk.system_fingerprint) {
|
|
2068
|
-
systemFingerprintFromResponse = chunk.system_fingerprint;
|
|
2069
|
-
}
|
|
2070
|
-
if (chunk.service_tier != null) {
|
|
2071
|
-
serviceTierFromResponse = chunk.service_tier;
|
|
2072
|
-
}
|
|
2073
|
-
const choice = chunk?.choices?.[0];
|
|
2074
|
-
if (choice?.finish_reason) {
|
|
2075
|
-
stopReason = choice.finish_reason;
|
|
2076
|
-
}
|
|
2077
|
-
const chunkWebSearchCount = calculateWebSearchCount(chunk);
|
|
2078
|
-
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2079
|
-
usage.webSearchCount = chunkWebSearchCount;
|
|
2080
|
-
}
|
|
2081
|
-
|
|
2082
|
-
// Handle text content
|
|
2083
|
-
const deltaContent = choice?.delta?.content;
|
|
2084
|
-
if (deltaContent) {
|
|
2085
|
-
if (firstTokenTime === undefined) {
|
|
2086
|
-
firstTokenTime = Date.now();
|
|
2087
|
-
}
|
|
2088
|
-
accumulatedContent += deltaContent;
|
|
2089
|
-
}
|
|
2090
|
-
|
|
2091
|
-
// Handle tool calls
|
|
2092
|
-
const deltaToolCalls = choice?.delta?.tool_calls;
|
|
2093
|
-
if (deltaToolCalls && Array.isArray(deltaToolCalls)) {
|
|
2094
|
-
if (firstTokenTime === undefined) {
|
|
2095
|
-
firstTokenTime = Date.now();
|
|
2096
|
-
}
|
|
2097
|
-
for (const toolCall of deltaToolCalls) {
|
|
2098
|
-
const index = toolCall.index;
|
|
2099
|
-
if (index !== undefined) {
|
|
2100
|
-
if (!toolCallsInProgress.has(index)) {
|
|
2101
|
-
// New tool call
|
|
2102
|
-
toolCallsInProgress.set(index, {
|
|
2103
|
-
id: toolCall.id || '',
|
|
2104
|
-
name: toolCall.function?.name || '',
|
|
2105
|
-
arguments: ''
|
|
2106
|
-
});
|
|
2107
|
-
}
|
|
2108
|
-
const inProgressCall = toolCallsInProgress.get(index);
|
|
2109
|
-
if (inProgressCall) {
|
|
2110
|
-
// Update tool call data
|
|
2111
|
-
if (toolCall.id) {
|
|
2112
|
-
inProgressCall.id = toolCall.id;
|
|
2113
|
-
}
|
|
2114
|
-
if (toolCall.function?.name) {
|
|
2115
|
-
inProgressCall.name = toolCall.function.name;
|
|
2116
|
-
}
|
|
2117
|
-
if (toolCall.function?.arguments) {
|
|
2118
|
-
inProgressCall.arguments += toolCall.function.arguments;
|
|
2119
|
-
}
|
|
2120
|
-
}
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
}
|
|
2124
|
-
|
|
2125
|
-
// Handle usage information
|
|
2126
|
-
if (chunk.usage) {
|
|
2127
|
-
rawUsageData = chunk.usage;
|
|
2128
|
-
usage = {
|
|
2129
|
-
...usage,
|
|
2130
|
-
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
2131
|
-
outputTokens: chunk.usage.completion_tokens ?? 0,
|
|
2132
|
-
reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
2133
|
-
cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,
|
|
2134
|
-
cacheCreationInputTokens: extractCacheWriteTokens(chunk.usage.prompt_tokens_details)
|
|
2135
|
-
};
|
|
2136
|
-
}
|
|
2137
|
-
}
|
|
2138
|
-
|
|
2139
|
-
// Build final content blocks
|
|
2140
|
-
if (accumulatedContent) {
|
|
2141
|
-
contentBlocks.push({
|
|
2142
|
-
type: 'text',
|
|
2143
|
-
text: accumulatedContent
|
|
2144
|
-
});
|
|
2121
|
+
accumulator.consume(chunk);
|
|
2145
2122
|
}
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
if (toolCall.name) {
|
|
2150
|
-
contentBlocks.push({
|
|
2151
|
-
type: 'function',
|
|
2152
|
-
id: toolCall.id,
|
|
2153
|
-
function: {
|
|
2154
|
-
name: toolCall.name,
|
|
2155
|
-
arguments: toolCall.arguments
|
|
2156
|
-
}
|
|
2157
|
-
});
|
|
2158
|
-
}
|
|
2159
|
-
}
|
|
2160
|
-
|
|
2161
|
-
// Format output to match non-streaming version
|
|
2162
|
-
const formattedOutput = contentBlocks.length > 0 ? [{
|
|
2163
|
-
role: 'assistant',
|
|
2164
|
-
content: contentBlocks
|
|
2165
|
-
}] : [{
|
|
2166
|
-
role: 'assistant',
|
|
2167
|
-
content: [{
|
|
2168
|
-
type: 'text',
|
|
2169
|
-
text: ''
|
|
2170
|
-
}]
|
|
2171
|
-
}];
|
|
2172
|
-
const latency = (Date.now() - startTime) / 1000;
|
|
2173
|
-
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
2174
|
-
const availableTools = extractAvailableToolCalls('openai', openAIParams);
|
|
2175
|
-
await captureAiGeneration(this.phClient, {
|
|
2176
|
-
...posthogParams,
|
|
2177
|
-
model: openAIParams.model ?? modelFromResponse,
|
|
2123
|
+
const accumulated = accumulator.result();
|
|
2124
|
+
await captureAiGeneration(this.phClient, buildChatSuccessOptions({
|
|
2125
|
+
client: this.phClient,
|
|
2178
2126
|
provider: 'openai',
|
|
2179
|
-
input: sanitizeOpenAI(openAIParams.messages),
|
|
2180
|
-
output: sanitizeOpenAIResponse(formattedOutput),
|
|
2181
|
-
latency,
|
|
2182
|
-
timeToFirstToken,
|
|
2183
2127
|
baseURL: this.baseURL,
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
webSearchCount: usage.webSearchCount,
|
|
2193
|
-
rawUsage: rawUsageData
|
|
2194
|
-
},
|
|
2195
|
-
stopReason,
|
|
2196
|
-
tools: availableTools,
|
|
2197
|
-
completionId: completionIdFromResponse,
|
|
2198
|
-
providerMetadata: buildProviderMetadata({
|
|
2199
|
-
systemFingerprint: systemFingerprintFromResponse
|
|
2200
|
-
})
|
|
2201
|
-
});
|
|
2128
|
+
params: openAIParams,
|
|
2129
|
+
monitoring: posthogParams,
|
|
2130
|
+
modelParametersSource: body
|
|
2131
|
+
}, {
|
|
2132
|
+
...accumulated,
|
|
2133
|
+
latency: (Date.now() - startTime) / 1000,
|
|
2134
|
+
timeToFirstToken: accumulated.firstTokenTime === undefined ? undefined : (accumulated.firstTokenTime - startTime) / 1000
|
|
2135
|
+
}));
|
|
2202
2136
|
} catch (error) {
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2137
|
+
const accumulated = accumulator.result();
|
|
2138
|
+
await captureAiGeneration(this.phClient, buildChatErrorOptions({
|
|
2139
|
+
client: this.phClient,
|
|
2206
2140
|
provider: 'openai',
|
|
2207
|
-
input: sanitizeOpenAI(openAIParams.messages),
|
|
2208
|
-
output: [],
|
|
2209
|
-
latency: 0,
|
|
2210
2141
|
baseURL: this.baseURL,
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
// event can still be correlated to OpenAI's Logs dashboard.
|
|
2219
|
-
completionId: completionIdFromResponse,
|
|
2220
|
-
providerMetadata: buildProviderMetadata({
|
|
2221
|
-
systemFingerprint: systemFingerprintFromResponse
|
|
2222
|
-
}),
|
|
2223
|
-
error
|
|
2224
|
-
});
|
|
2142
|
+
params: openAIParams,
|
|
2143
|
+
monitoring: posthogParams,
|
|
2144
|
+
modelParametersSource: body
|
|
2145
|
+
}, error, {
|
|
2146
|
+
completionId: accumulated.completionId,
|
|
2147
|
+
systemFingerprint: accumulated.systemFingerprint
|
|
2148
|
+
}));
|
|
2225
2149
|
throw error;
|
|
2226
2150
|
}
|
|
2227
2151
|
})().catch(() => {
|
|
@@ -2238,56 +2162,35 @@ class WrappedCompletions extends Completions {
|
|
|
2238
2162
|
} else {
|
|
2239
2163
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2240
2164
|
if ('choices' in result) {
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
const formattedOutput = formatResponseOpenAI(result);
|
|
2244
|
-
await captureAiGenerationAfterSuccess(this.phClient, {
|
|
2245
|
-
...posthogParams,
|
|
2246
|
-
model: openAIParams.model ?? result.model,
|
|
2165
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildChatSuccessOptions({
|
|
2166
|
+
client: this.phClient,
|
|
2247
2167
|
provider: 'openai',
|
|
2248
|
-
input: sanitizeOpenAI(openAIParams.messages),
|
|
2249
|
-
output: sanitizeOpenAIResponse(formattedOutput),
|
|
2250
|
-
latency,
|
|
2251
2168
|
baseURL: this.baseURL,
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
rawUsage: result.usage
|
|
2262
|
-
},
|
|
2169
|
+
params: openAIParams,
|
|
2170
|
+
monitoring: posthogParams,
|
|
2171
|
+
modelParametersSource: body
|
|
2172
|
+
}, {
|
|
2173
|
+
output: formatResponseOpenAI(result),
|
|
2174
|
+
model: result.model,
|
|
2175
|
+
serviceTier: result.service_tier ?? undefined,
|
|
2176
|
+
latency: (Date.now() - startTime) / 1000,
|
|
2177
|
+
usage: buildChatUsage(result.usage, result),
|
|
2263
2178
|
stopReason: result.choices[0]?.finish_reason ?? undefined,
|
|
2264
|
-
tools: availableTools,
|
|
2265
2179
|
completionId: result.id,
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
})
|
|
2270
|
-
});
|
|
2180
|
+
systemFingerprint: result.system_fingerprint,
|
|
2181
|
+
requestId: extractRequestId(result)
|
|
2182
|
+
}));
|
|
2271
2183
|
}
|
|
2272
2184
|
return result;
|
|
2273
2185
|
}, async error => {
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
...posthogParams,
|
|
2277
|
-
model: openAIParams.model,
|
|
2186
|
+
await captureAiGeneration(this.phClient, buildChatErrorOptions({
|
|
2187
|
+
client: this.phClient,
|
|
2278
2188
|
provider: 'openai',
|
|
2279
|
-
input: sanitizeOpenAI(openAIParams.messages),
|
|
2280
|
-
output: [],
|
|
2281
|
-
latency: 0,
|
|
2282
2189
|
baseURL: this.baseURL,
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
outputTokens: 0
|
|
2288
|
-
},
|
|
2289
|
-
error
|
|
2290
|
-
});
|
|
2190
|
+
params: openAIParams,
|
|
2191
|
+
monitoring: posthogParams,
|
|
2192
|
+
modelParametersSource: body
|
|
2193
|
+
}, error));
|
|
2291
2194
|
throw error;
|
|
2292
2195
|
});
|
|
2293
2196
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -2306,36 +2209,14 @@ class WrappedResponses extends Responses {
|
|
|
2306
2209
|
openAIParams,
|
|
2307
2210
|
posthogParams
|
|
2308
2211
|
} = context;
|
|
2309
|
-
await captureAiGenerationAfterSuccess(this.phClient, {
|
|
2310
|
-
|
|
2311
|
-
model: openAIParams.model ?? result.model,
|
|
2212
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildBackgroundResponseOptions({
|
|
2213
|
+
client: this.phClient,
|
|
2312
2214
|
provider: 'openai',
|
|
2313
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2314
|
-
output: formatResponseOpenAI({
|
|
2315
|
-
output: result.output
|
|
2316
|
-
}),
|
|
2317
|
-
latency: getBackgroundResponseLatency(result),
|
|
2318
2215
|
baseURL: this.baseURL,
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
outputTokens: result.usage?.output_tokens ?? 0,
|
|
2324
|
-
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2325
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
2326
|
-
cacheCreationInputTokens: extractCacheWriteTokens(result.usage?.input_tokens_details),
|
|
2327
|
-
webSearchCount: calculateWebSearchCount(result),
|
|
2328
|
-
rawUsage: result.usage
|
|
2329
|
-
},
|
|
2330
|
-
stopReason: result.status ?? undefined,
|
|
2331
|
-
tools: extractAvailableToolCalls('openai', openAIParams),
|
|
2332
|
-
completionId: result.id,
|
|
2333
|
-
providerMetadata: buildProviderMetadata({
|
|
2334
|
-
requestId: extractRequestId(result),
|
|
2335
|
-
incompleteDetails: result.incomplete_details
|
|
2336
|
-
}),
|
|
2337
|
-
error: getResponseFailure(result)
|
|
2338
|
-
});
|
|
2216
|
+
params: openAIParams,
|
|
2217
|
+
monitoring: posthogParams,
|
|
2218
|
+
modelParametersSource: openAIParams
|
|
2219
|
+
}, result));
|
|
2339
2220
|
}
|
|
2340
2221
|
|
|
2341
2222
|
// --- Overload #1: Non-streaming
|
|
@@ -2357,128 +2238,61 @@ class WrappedResponses extends Responses {
|
|
|
2357
2238
|
if (Symbol.asyncIterator in value) {
|
|
2358
2239
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new Stream(iterator, controller));
|
|
2359
2240
|
(async () => {
|
|
2360
|
-
|
|
2361
|
-
// was accumulated from the streamed chunks before the failure.
|
|
2362
|
-
let completionIdFromResponse;
|
|
2241
|
+
const accumulator = new OpenAIResponsesStreamAccumulator();
|
|
2363
2242
|
try {
|
|
2364
|
-
let finalContent = [];
|
|
2365
|
-
let modelFromResponse;
|
|
2366
|
-
let serviceTierFromResponse;
|
|
2367
|
-
let firstTokenTime;
|
|
2368
|
-
let stopReason;
|
|
2369
|
-
let usage = {
|
|
2370
|
-
inputTokens: 0,
|
|
2371
|
-
outputTokens: 0,
|
|
2372
|
-
webSearchCount: 0
|
|
2373
|
-
};
|
|
2374
|
-
let rawUsageData;
|
|
2375
|
-
let terminalResponse;
|
|
2376
2243
|
for await (const chunk of stream1) {
|
|
2377
|
-
|
|
2378
|
-
if (
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
if (!modelFromResponse && chunk.response.model) {
|
|
2384
|
-
modelFromResponse = chunk.response.model;
|
|
2385
|
-
}
|
|
2386
|
-
if (!completionIdFromResponse && chunk.response.id) {
|
|
2387
|
-
completionIdFromResponse = chunk.response.id;
|
|
2388
|
-
}
|
|
2389
|
-
if (openAIParams.background === true && !this.backgroundResponses.get(chunk.response.id)) {
|
|
2390
|
-
this.backgroundResponses.set(chunk.response.id, {
|
|
2391
|
-
openAIParams,
|
|
2392
|
-
posthogParams
|
|
2393
|
-
});
|
|
2394
|
-
}
|
|
2395
|
-
if (chunk.response.service_tier != null) {
|
|
2396
|
-
serviceTierFromResponse = chunk.response.service_tier;
|
|
2397
|
-
}
|
|
2398
|
-
const chunkWebSearchCount = calculateWebSearchCount(chunk.response);
|
|
2399
|
-
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2400
|
-
usage.webSearchCount = chunkWebSearchCount;
|
|
2401
|
-
}
|
|
2402
|
-
if (isTerminalResponse(chunk.response)) {
|
|
2403
|
-
terminalResponse = chunk.response;
|
|
2404
|
-
finalContent = chunk.response.output ?? [];
|
|
2405
|
-
stopReason = chunk.response.status;
|
|
2406
|
-
}
|
|
2407
|
-
}
|
|
2408
|
-
if ('response' in chunk && chunk.response?.usage) {
|
|
2409
|
-
rawUsageData = chunk.response.usage;
|
|
2410
|
-
usage = {
|
|
2411
|
-
...usage,
|
|
2412
|
-
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
2413
|
-
outputTokens: chunk.response.usage.output_tokens ?? 0,
|
|
2414
|
-
reasoningTokens: chunk.response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2415
|
-
cacheReadInputTokens: chunk.response.usage.input_tokens_details?.cached_tokens ?? 0,
|
|
2416
|
-
cacheCreationInputTokens: extractCacheWriteTokens(chunk.response.usage.input_tokens_details)
|
|
2417
|
-
};
|
|
2244
|
+
accumulator.consume(chunk);
|
|
2245
|
+
if (openAIParams.background === true && 'response' in chunk && chunk.response && !this.backgroundResponses.get(chunk.response.id)) {
|
|
2246
|
+
this.backgroundResponses.set(chunk.response.id, {
|
|
2247
|
+
openAIParams,
|
|
2248
|
+
posthogParams
|
|
2249
|
+
});
|
|
2418
2250
|
}
|
|
2419
2251
|
}
|
|
2252
|
+
const accumulated = accumulator.result();
|
|
2420
2253
|
if (openAIParams.background === true) {
|
|
2421
|
-
if (terminalResponse) {
|
|
2422
|
-
const context = this.backgroundResponses.take(terminalResponse.id);
|
|
2254
|
+
if (accumulated.terminalResponse) {
|
|
2255
|
+
const context = this.backgroundResponses.take(accumulated.terminalResponse.id);
|
|
2423
2256
|
if (context) {
|
|
2424
|
-
await this.captureBackgroundResponse(terminalResponse, context).catch(() => undefined);
|
|
2257
|
+
await this.captureBackgroundResponse(accumulated.terminalResponse, context).catch(() => undefined);
|
|
2425
2258
|
}
|
|
2426
2259
|
}
|
|
2427
2260
|
return;
|
|
2428
2261
|
}
|
|
2429
|
-
const
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2262
|
+
const response = accumulated.terminalResponse ?? {
|
|
2263
|
+
id: accumulated.completionId ?? '',
|
|
2264
|
+
model: accumulated.model ?? openAIParams.model,
|
|
2265
|
+
status: accumulated.stopReason,
|
|
2266
|
+
service_tier: accumulated.serviceTier
|
|
2267
|
+
};
|
|
2268
|
+
await captureAiGeneration(this.phClient, buildResponsesSuccessOptions({
|
|
2269
|
+
client: this.phClient,
|
|
2435
2270
|
provider: 'openai',
|
|
2436
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2437
|
-
output: sanitizeOpenAIResponse(finalContent),
|
|
2438
|
-
latency,
|
|
2439
|
-
timeToFirstToken,
|
|
2440
2271
|
baseURL: this.baseURL,
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
stopReason,
|
|
2453
|
-
tools: availableTools,
|
|
2454
|
-
completionId: completionIdFromResponse,
|
|
2455
|
-
providerMetadata: buildProviderMetadata({
|
|
2456
|
-
incompleteDetails: terminalResponse?.incomplete_details
|
|
2457
|
-
}),
|
|
2458
|
-
error: getResponseFailure(terminalResponse)
|
|
2459
|
-
});
|
|
2272
|
+
params: openAIParams,
|
|
2273
|
+
monitoring: posthogParams,
|
|
2274
|
+
modelParametersSource: body
|
|
2275
|
+
}, {
|
|
2276
|
+
response,
|
|
2277
|
+
output: accumulated.output,
|
|
2278
|
+
latency: (Date.now() - startTime) / 1000,
|
|
2279
|
+
timeToFirstToken: accumulated.firstTokenTime === undefined ? undefined : (accumulated.firstTokenTime - startTime) / 1000,
|
|
2280
|
+
usage: accumulated.usage,
|
|
2281
|
+
includeTools: true
|
|
2282
|
+
}));
|
|
2460
2283
|
} catch (error) {
|
|
2461
|
-
|
|
2284
|
+
const accumulated = accumulator.result();
|
|
2285
|
+
if (openAIParams.background === true && accumulated.completionId && this.backgroundResponses.get(accumulated.completionId)) {
|
|
2462
2286
|
throw error;
|
|
2463
2287
|
}
|
|
2464
|
-
await captureAiGeneration(this.phClient, {
|
|
2465
|
-
|
|
2466
|
-
model: openAIParams.model,
|
|
2288
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
2289
|
+
client: this.phClient,
|
|
2467
2290
|
provider: 'openai',
|
|
2468
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2469
|
-
output: [],
|
|
2470
|
-
latency: 0,
|
|
2471
2291
|
baseURL: this.baseURL,
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
},
|
|
2477
|
-
// Surface the completion ID from any chunks consumed before
|
|
2478
|
-
// the stream failed so the error event remains correlatable.
|
|
2479
|
-
completionId: completionIdFromResponse,
|
|
2480
|
-
error
|
|
2481
|
-
});
|
|
2292
|
+
params: openAIParams,
|
|
2293
|
+
monitoring: posthogParams,
|
|
2294
|
+
modelParametersSource: body
|
|
2295
|
+
}, error, accumulated.completionId));
|
|
2482
2296
|
throw error;
|
|
2483
2297
|
}
|
|
2484
2298
|
})().catch(() => {
|
|
@@ -2500,59 +2314,33 @@ class WrappedResponses extends Responses {
|
|
|
2500
2314
|
});
|
|
2501
2315
|
return result;
|
|
2502
2316
|
}
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
const formattedOutput = formatResponseOpenAI({
|
|
2506
|
-
output: result.output
|
|
2507
|
-
});
|
|
2508
|
-
await captureAiGenerationAfterSuccess(this.phClient, {
|
|
2509
|
-
...posthogParams,
|
|
2510
|
-
model: openAIParams.model ?? result.model,
|
|
2317
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildResponsesSuccessOptions({
|
|
2318
|
+
client: this.phClient,
|
|
2511
2319
|
provider: 'openai',
|
|
2512
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2513
|
-
output: sanitizeOpenAIResponse(formattedOutput),
|
|
2514
|
-
latency,
|
|
2515
2320
|
baseURL: this.baseURL,
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
cacheCreationInputTokens: extractCacheWriteTokens(result.usage?.input_tokens_details),
|
|
2524
|
-
webSearchCount: calculateWebSearchCount(result),
|
|
2525
|
-
rawUsage: result.usage
|
|
2526
|
-
},
|
|
2527
|
-
stopReason: result.status ?? undefined,
|
|
2528
|
-
tools: availableTools,
|
|
2529
|
-
completionId: result.id,
|
|
2530
|
-
providerMetadata: buildProviderMetadata({
|
|
2531
|
-
requestId: extractRequestId(result),
|
|
2532
|
-
incompleteDetails: result.incomplete_details
|
|
2321
|
+
params: openAIParams,
|
|
2322
|
+
monitoring: posthogParams,
|
|
2323
|
+
modelParametersSource: body
|
|
2324
|
+
}, {
|
|
2325
|
+
response: result,
|
|
2326
|
+
output: formatResponseOpenAI({
|
|
2327
|
+
output: result.output
|
|
2533
2328
|
}),
|
|
2534
|
-
|
|
2535
|
-
|
|
2329
|
+
latency: (Date.now() - startTime) / 1000,
|
|
2330
|
+
includeTools: true,
|
|
2331
|
+
includeRequestId: true
|
|
2332
|
+
}));
|
|
2536
2333
|
}
|
|
2537
2334
|
return result;
|
|
2538
2335
|
}, async error => {
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
...posthogParams,
|
|
2542
|
-
model: openAIParams.model,
|
|
2336
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
2337
|
+
client: this.phClient,
|
|
2543
2338
|
provider: 'openai',
|
|
2544
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2545
|
-
output: [],
|
|
2546
|
-
latency: 0,
|
|
2547
2339
|
baseURL: this.baseURL,
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
outputTokens: 0
|
|
2553
|
-
},
|
|
2554
|
-
error
|
|
2555
|
-
});
|
|
2340
|
+
params: openAIParams,
|
|
2341
|
+
monitoring: posthogParams,
|
|
2342
|
+
modelParametersSource: body
|
|
2343
|
+
}, error));
|
|
2556
2344
|
throw error;
|
|
2557
2345
|
});
|
|
2558
2346
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -2622,50 +2410,29 @@ class WrappedResponses extends Responses {
|
|
|
2622
2410
|
});
|
|
2623
2411
|
return result;
|
|
2624
2412
|
}
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
...posthogParams,
|
|
2628
|
-
model: openAIParams.model ?? result.model,
|
|
2413
|
+
await captureAiGeneration(this.phClient, buildResponsesSuccessOptions({
|
|
2414
|
+
client: this.phClient,
|
|
2629
2415
|
provider: 'openai',
|
|
2630
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2631
|
-
output: sanitizeOpenAIResponse(result.output),
|
|
2632
|
-
latency,
|
|
2633
2416
|
baseURL: this.baseURL,
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
},
|
|
2644
|
-
stopReason: result.status ?? undefined,
|
|
2645
|
-
completionId: result.id,
|
|
2646
|
-
providerMetadata: buildProviderMetadata({
|
|
2647
|
-
requestId: extractRequestId(result),
|
|
2648
|
-
incompleteDetails: result.incomplete_details
|
|
2649
|
-
}),
|
|
2650
|
-
error: getResponseFailure(result)
|
|
2651
|
-
});
|
|
2417
|
+
params: openAIParams,
|
|
2418
|
+
monitoring: posthogParams,
|
|
2419
|
+
modelParametersSource: body
|
|
2420
|
+
}, {
|
|
2421
|
+
response: result,
|
|
2422
|
+
output: result.output,
|
|
2423
|
+
latency: (Date.now() - startTime) / 1000,
|
|
2424
|
+
includeRequestId: true
|
|
2425
|
+
}));
|
|
2652
2426
|
return result;
|
|
2653
2427
|
}, async error => {
|
|
2654
|
-
await captureAiGeneration(this.phClient, {
|
|
2655
|
-
|
|
2656
|
-
model: openAIParams.model,
|
|
2428
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
2429
|
+
client: this.phClient,
|
|
2657
2430
|
provider: 'openai',
|
|
2658
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
2659
|
-
output: [],
|
|
2660
|
-
latency: 0,
|
|
2661
2431
|
baseURL: this.baseURL,
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
},
|
|
2667
|
-
error
|
|
2668
|
-
});
|
|
2432
|
+
params: openAIParams,
|
|
2433
|
+
monitoring: posthogParams,
|
|
2434
|
+
modelParametersSource: body
|
|
2435
|
+
}, error));
|
|
2669
2436
|
throw error;
|
|
2670
2437
|
});
|
|
2671
2438
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -2685,44 +2452,24 @@ class WrappedEmbeddings extends Embeddings {
|
|
|
2685
2452
|
const startTime = Date.now();
|
|
2686
2453
|
const parentPromise = super.create(openAIParams, options);
|
|
2687
2454
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
...posthogParams,
|
|
2691
|
-
eventType: AIEvent.Embedding,
|
|
2692
|
-
model: openAIParams.model,
|
|
2455
|
+
await captureAiGeneration(this.phClient, buildEmbeddingSuccessOptions({
|
|
2456
|
+
client: this.phClient,
|
|
2693
2457
|
provider: 'openai',
|
|
2694
|
-
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
2695
|
-
output: null,
|
|
2696
|
-
// Embeddings don't have output content
|
|
2697
|
-
latency,
|
|
2698
2458
|
baseURL: this.baseURL,
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
rawUsage: result.usage
|
|
2704
|
-
}
|
|
2705
|
-
});
|
|
2459
|
+
params: openAIParams,
|
|
2460
|
+
monitoring: posthogParams,
|
|
2461
|
+
modelParametersSource: body
|
|
2462
|
+
}, result.usage, (Date.now() - startTime) / 1000));
|
|
2706
2463
|
return result;
|
|
2707
2464
|
}, async error => {
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
eventType: AIEvent.Embedding,
|
|
2711
|
-
...posthogParams,
|
|
2712
|
-
model: openAIParams.model,
|
|
2465
|
+
await captureAiGeneration(this.phClient, buildEmbeddingErrorOptions({
|
|
2466
|
+
client: this.phClient,
|
|
2713
2467
|
provider: 'openai',
|
|
2714
|
-
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
2715
|
-
output: null,
|
|
2716
|
-
// Embeddings don't have output content
|
|
2717
|
-
latency: 0,
|
|
2718
2468
|
baseURL: this.baseURL,
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
},
|
|
2724
|
-
error
|
|
2725
|
-
});
|
|
2469
|
+
params: openAIParams,
|
|
2470
|
+
monitoring: posthogParams,
|
|
2471
|
+
modelParametersSource: body
|
|
2472
|
+
}, error));
|
|
2726
2473
|
throw error;
|
|
2727
2474
|
});
|
|
2728
2475
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -2800,7 +2547,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2800
2547
|
model: openAIParams.model,
|
|
2801
2548
|
provider: 'openai',
|
|
2802
2549
|
input: openAIParams.prompt,
|
|
2803
|
-
output: sanitizeOpenAIResponse(finalContent),
|
|
2550
|
+
output: sanitizeOpenAIResponse(finalContent, this.phClient),
|
|
2804
2551
|
latency,
|
|
2805
2552
|
timeToFirstToken,
|
|
2806
2553
|
baseURL: this.baseURL,
|
|
@@ -2845,7 +2592,7 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
2845
2592
|
model: openAIParams.model,
|
|
2846
2593
|
provider: 'openai',
|
|
2847
2594
|
input: openAIParams.prompt,
|
|
2848
|
-
output: sanitizeOpenAIResponse(result.text),
|
|
2595
|
+
output: sanitizeOpenAIResponse(result.text, this.phClient),
|
|
2849
2596
|
latency,
|
|
2850
2597
|
baseURL: this.baseURL,
|
|
2851
2598
|
modelParameters: getModelParams(body),
|