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