@posthog/ai 8.8.0 → 8.9.0
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 +1 -1
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +1 -1
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +1 -1
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +1 -1
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +12 -6
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.d.ts +13 -11
- package/dist/langchain/index.mjs +12 -6
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/langchain/middleware/index.cjs +1273 -0
- package/dist/langchain/middleware/index.cjs.map +1 -0
- package/dist/langchain/middleware/index.d.ts +39 -0
- package/dist/langchain/middleware/index.mjs +1271 -0
- package/dist/langchain/middleware/index.mjs.map +1 -0
- package/dist/openai/index.cjs +611 -887
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +611 -887
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +1 -1
- package/dist/openai-agents/index.cjs.map +1 -1
- package/dist/openai-agents/index.mjs +1 -1
- package/dist/openai-agents/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +1 -1
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +1 -1
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +19 -9
package/dist/openai/index.cjs
CHANGED
|
@@ -344,6 +344,11 @@ const formatResponseOpenAI = response => {
|
|
|
344
344
|
arguments: item.arguments || {}
|
|
345
345
|
}
|
|
346
346
|
});
|
|
347
|
+
} else if (item.type === 'image_generation_call' && item.result) {
|
|
348
|
+
content.push({
|
|
349
|
+
type: 'image',
|
|
350
|
+
image: item.result
|
|
351
|
+
});
|
|
347
352
|
}
|
|
348
353
|
}
|
|
349
354
|
if (content.length > 0) {
|
|
@@ -576,7 +581,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
576
581
|
return messages;
|
|
577
582
|
}
|
|
578
583
|
|
|
579
|
-
var version = "8.
|
|
584
|
+
var version = "8.9.0";
|
|
580
585
|
|
|
581
586
|
const DEFAULT_MAX_DEPTH = 3;
|
|
582
587
|
const MAX_STACK_LINES = 20;
|
|
@@ -1322,6 +1327,340 @@ function monitoredStreamTee(source, createStream) {
|
|
|
1322
1327
|
return [monitoringStream, callerStream];
|
|
1323
1328
|
}
|
|
1324
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
|
+
|
|
1325
1664
|
class PostHogAzureOpenAI extends openai.AzureOpenAI {
|
|
1326
1665
|
constructor(config) {
|
|
1327
1666
|
const {
|
|
@@ -1367,169 +1706,37 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1367
1706
|
if (Symbol.asyncIterator in value) {
|
|
1368
1707
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
|
|
1369
1708
|
(async () => {
|
|
1370
|
-
|
|
1371
|
-
// from the streamed chunks before the failure.
|
|
1372
|
-
let completionIdFromResponse;
|
|
1373
|
-
let systemFingerprintFromResponse;
|
|
1709
|
+
const accumulator = new OpenAIChatStreamAccumulator();
|
|
1374
1710
|
try {
|
|
1375
|
-
const contentBlocks = [];
|
|
1376
|
-
let accumulatedContent = '';
|
|
1377
|
-
let modelFromResponse;
|
|
1378
|
-
let serviceTierFromResponse;
|
|
1379
|
-
let firstTokenTime;
|
|
1380
|
-
let usage = {
|
|
1381
|
-
inputTokens: 0,
|
|
1382
|
-
outputTokens: 0
|
|
1383
|
-
};
|
|
1384
|
-
|
|
1385
|
-
// Map to track in-progress tool calls
|
|
1386
|
-
const toolCallsInProgress = new Map();
|
|
1387
1711
|
for await (const chunk of stream1) {
|
|
1388
|
-
|
|
1389
|
-
if (!modelFromResponse && chunk.model) {
|
|
1390
|
-
modelFromResponse = chunk.model;
|
|
1391
|
-
}
|
|
1392
|
-
if (!completionIdFromResponse && chunk.id) {
|
|
1393
|
-
completionIdFromResponse = chunk.id;
|
|
1394
|
-
}
|
|
1395
|
-
if (!systemFingerprintFromResponse && chunk.system_fingerprint) {
|
|
1396
|
-
systemFingerprintFromResponse = chunk.system_fingerprint;
|
|
1397
|
-
}
|
|
1398
|
-
if (chunk.service_tier != null) {
|
|
1399
|
-
serviceTierFromResponse = chunk.service_tier;
|
|
1400
|
-
}
|
|
1401
|
-
const choice = chunk?.choices?.[0];
|
|
1402
|
-
|
|
1403
|
-
// Handle text content
|
|
1404
|
-
const deltaContent = choice?.delta?.content;
|
|
1405
|
-
if (deltaContent) {
|
|
1406
|
-
if (firstTokenTime === undefined) {
|
|
1407
|
-
firstTokenTime = Date.now();
|
|
1408
|
-
}
|
|
1409
|
-
accumulatedContent += deltaContent;
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
// Handle tool calls
|
|
1413
|
-
const deltaToolCalls = choice?.delta?.tool_calls;
|
|
1414
|
-
if (deltaToolCalls && Array.isArray(deltaToolCalls)) {
|
|
1415
|
-
if (firstTokenTime === undefined) {
|
|
1416
|
-
firstTokenTime = Date.now();
|
|
1417
|
-
}
|
|
1418
|
-
for (const toolCall of deltaToolCalls) {
|
|
1419
|
-
const index = toolCall.index;
|
|
1420
|
-
if (index !== undefined) {
|
|
1421
|
-
if (!toolCallsInProgress.has(index)) {
|
|
1422
|
-
// New tool call
|
|
1423
|
-
toolCallsInProgress.set(index, {
|
|
1424
|
-
id: toolCall.id || '',
|
|
1425
|
-
name: toolCall.function?.name || '',
|
|
1426
|
-
arguments: ''
|
|
1427
|
-
});
|
|
1428
|
-
}
|
|
1429
|
-
const inProgressCall = toolCallsInProgress.get(index);
|
|
1430
|
-
if (inProgressCall) {
|
|
1431
|
-
// Update tool call data
|
|
1432
|
-
if (toolCall.id) {
|
|
1433
|
-
inProgressCall.id = toolCall.id;
|
|
1434
|
-
}
|
|
1435
|
-
if (toolCall.function?.name) {
|
|
1436
|
-
inProgressCall.name = toolCall.function.name;
|
|
1437
|
-
}
|
|
1438
|
-
if (toolCall.function?.arguments) {
|
|
1439
|
-
inProgressCall.arguments += toolCall.function.arguments;
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
// Handle usage information
|
|
1447
|
-
if (chunk.usage) {
|
|
1448
|
-
usage = {
|
|
1449
|
-
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
1450
|
-
outputTokens: chunk.usage.completion_tokens ?? 0,
|
|
1451
|
-
reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
1452
|
-
cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,
|
|
1453
|
-
cacheCreationInputTokens: extractCacheWriteTokens(chunk.usage.prompt_tokens_details)
|
|
1454
|
-
};
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
// Build final content blocks
|
|
1459
|
-
if (accumulatedContent) {
|
|
1460
|
-
contentBlocks.push({
|
|
1461
|
-
type: 'text',
|
|
1462
|
-
text: accumulatedContent
|
|
1463
|
-
});
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
|
-
// Add completed tool calls to content blocks
|
|
1467
|
-
for (const toolCall of toolCallsInProgress.values()) {
|
|
1468
|
-
if (toolCall.name) {
|
|
1469
|
-
contentBlocks.push({
|
|
1470
|
-
type: 'function',
|
|
1471
|
-
id: toolCall.id,
|
|
1472
|
-
function: {
|
|
1473
|
-
name: toolCall.name,
|
|
1474
|
-
arguments: toolCall.arguments
|
|
1475
|
-
}
|
|
1476
|
-
});
|
|
1477
|
-
}
|
|
1712
|
+
accumulator.consume(chunk);
|
|
1478
1713
|
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
role: 'assistant',
|
|
1483
|
-
content: contentBlocks
|
|
1484
|
-
}] : [{
|
|
1485
|
-
role: 'assistant',
|
|
1486
|
-
content: [{
|
|
1487
|
-
type: 'text',
|
|
1488
|
-
text: ''
|
|
1489
|
-
}]
|
|
1490
|
-
}];
|
|
1491
|
-
const latency = (Date.now() - startTime) / 1000;
|
|
1492
|
-
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
1493
|
-
await captureAiGeneration(this.phClient, {
|
|
1494
|
-
...posthogParams,
|
|
1495
|
-
model: openAIParams.model ?? modelFromResponse,
|
|
1714
|
+
const accumulated = accumulator.result();
|
|
1715
|
+
await captureAiGeneration(this.phClient, buildChatSuccessOptions({
|
|
1716
|
+
client: this.phClient,
|
|
1496
1717
|
provider: 'azure',
|
|
1497
|
-
input: sanitizeOpenAI(openAIParams.messages, this.phClient),
|
|
1498
|
-
output: sanitizeOpenAIResponse(formattedOutput, this.phClient),
|
|
1499
|
-
latency,
|
|
1500
|
-
timeToFirstToken,
|
|
1501
1718
|
baseURL: this.baseURL,
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
});
|
|
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
|
+
}));
|
|
1510
1727
|
} catch (error) {
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1728
|
+
const accumulated = accumulator.result();
|
|
1729
|
+
await captureAiGeneration(this.phClient, buildChatErrorOptions({
|
|
1730
|
+
client: this.phClient,
|
|
1514
1731
|
provider: 'azure',
|
|
1515
|
-
input: sanitizeOpenAI(openAIParams.messages, this.phClient),
|
|
1516
|
-
output: [],
|
|
1517
|
-
latency: 0,
|
|
1518
1732
|
baseURL: this.baseURL,
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
// event can still be correlated to OpenAI's Logs dashboard.
|
|
1527
|
-
completionId: completionIdFromResponse,
|
|
1528
|
-
providerMetadata: buildProviderMetadata({
|
|
1529
|
-
systemFingerprint: systemFingerprintFromResponse
|
|
1530
|
-
}),
|
|
1531
|
-
error: error
|
|
1532
|
-
});
|
|
1733
|
+
params: openAIParams,
|
|
1734
|
+
monitoring: posthogParams,
|
|
1735
|
+
modelParametersSource: body
|
|
1736
|
+
}, error, {
|
|
1737
|
+
completionId: accumulated.completionId,
|
|
1738
|
+
systemFingerprint: accumulated.systemFingerprint
|
|
1739
|
+
}));
|
|
1533
1740
|
throw error;
|
|
1534
1741
|
}
|
|
1535
1742
|
})().catch(() => {
|
|
@@ -1546,50 +1753,35 @@ let WrappedCompletions$1 = class WrappedCompletions extends openai.AzureOpenAI.C
|
|
|
1546
1753
|
} else {
|
|
1547
1754
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1548
1755
|
if ('choices' in result) {
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
...posthogParams,
|
|
1552
|
-
model: openAIParams.model ?? result.model,
|
|
1756
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildChatSuccessOptions({
|
|
1757
|
+
client: this.phClient,
|
|
1553
1758
|
provider: 'azure',
|
|
1554
|
-
input: sanitizeOpenAI(openAIParams.messages, this.phClient),
|
|
1555
|
-
output: sanitizeOpenAIResponse(formatResponseOpenAI(result), this.phClient),
|
|
1556
|
-
latency,
|
|
1557
1759
|
baseURL: this.baseURL,
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
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,
|
|
1567
1770
|
completionId: result.id,
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
})
|
|
1572
|
-
});
|
|
1771
|
+
systemFingerprint: result.system_fingerprint,
|
|
1772
|
+
requestId: result._request_id
|
|
1773
|
+
}));
|
|
1573
1774
|
}
|
|
1574
1775
|
return result;
|
|
1575
1776
|
}, async error => {
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
...posthogParams,
|
|
1579
|
-
model: openAIParams.model,
|
|
1777
|
+
await captureAiGeneration(this.phClient, buildChatErrorOptions({
|
|
1778
|
+
client: this.phClient,
|
|
1580
1779
|
provider: 'azure',
|
|
1581
|
-
input: sanitizeOpenAI(openAIParams.messages, this.phClient),
|
|
1582
|
-
output: [],
|
|
1583
|
-
latency: 0,
|
|
1584
1780
|
baseURL: this.baseURL,
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
outputTokens: 0
|
|
1590
|
-
},
|
|
1591
|
-
error
|
|
1592
|
-
});
|
|
1781
|
+
params: openAIParams,
|
|
1782
|
+
monitoring: posthogParams,
|
|
1783
|
+
modelParametersSource: body
|
|
1784
|
+
}, error));
|
|
1593
1785
|
throw error;
|
|
1594
1786
|
});
|
|
1595
1787
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -1608,32 +1800,14 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1608
1800
|
openAIParams,
|
|
1609
1801
|
posthogParams
|
|
1610
1802
|
} = context;
|
|
1611
|
-
await
|
|
1612
|
-
|
|
1613
|
-
model: openAIParams.model ?? result.model,
|
|
1803
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildBackgroundResponseOptions({
|
|
1804
|
+
client: this.phClient,
|
|
1614
1805
|
provider: 'azure',
|
|
1615
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1616
|
-
output: result.output,
|
|
1617
|
-
latency: getBackgroundResponseLatency(result),
|
|
1618
1806
|
baseURL: this.baseURL,
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1624
|
-
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1625
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1626
|
-
cacheCreationInputTokens: extractCacheWriteTokens(result.usage?.input_tokens_details),
|
|
1627
|
-
rawUsage: result.usage
|
|
1628
|
-
},
|
|
1629
|
-
stopReason: result.status ?? undefined,
|
|
1630
|
-
completionId: result.id,
|
|
1631
|
-
providerMetadata: buildProviderMetadata({
|
|
1632
|
-
requestId: extractRequestId(result),
|
|
1633
|
-
incompleteDetails: result.incomplete_details
|
|
1634
|
-
}),
|
|
1635
|
-
error: getResponseFailure(result)
|
|
1636
|
-
});
|
|
1807
|
+
params: openAIParams,
|
|
1808
|
+
monitoring: posthogParams,
|
|
1809
|
+
modelParametersSource: openAIParams
|
|
1810
|
+
}, result));
|
|
1637
1811
|
}
|
|
1638
1812
|
|
|
1639
1813
|
// --- Overload #1: Non-streaming
|
|
@@ -1655,108 +1829,61 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1655
1829
|
if (Symbol.asyncIterator in value) {
|
|
1656
1830
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
|
|
1657
1831
|
(async () => {
|
|
1658
|
-
|
|
1659
|
-
// was accumulated from the streamed chunks before the failure.
|
|
1660
|
-
let completionIdFromResponse;
|
|
1832
|
+
const accumulator = new OpenAIResponsesStreamAccumulator();
|
|
1661
1833
|
try {
|
|
1662
|
-
let finalContent = [];
|
|
1663
|
-
let modelFromResponse;
|
|
1664
|
-
let serviceTierFromResponse;
|
|
1665
|
-
let firstTokenTime;
|
|
1666
|
-
let usage = {
|
|
1667
|
-
inputTokens: 0,
|
|
1668
|
-
outputTokens: 0
|
|
1669
|
-
};
|
|
1670
|
-
let terminalResponse;
|
|
1671
1834
|
for await (const chunk of stream1) {
|
|
1672
|
-
|
|
1673
|
-
if (
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
if (!modelFromResponse && chunk.response.model) {
|
|
1679
|
-
modelFromResponse = chunk.response.model;
|
|
1680
|
-
}
|
|
1681
|
-
if (!completionIdFromResponse && chunk.response.id) {
|
|
1682
|
-
completionIdFromResponse = chunk.response.id;
|
|
1683
|
-
}
|
|
1684
|
-
if (openAIParams.background === true && !this.backgroundResponses.get(chunk.response.id)) {
|
|
1685
|
-
this.backgroundResponses.set(chunk.response.id, {
|
|
1686
|
-
openAIParams,
|
|
1687
|
-
posthogParams
|
|
1688
|
-
});
|
|
1689
|
-
}
|
|
1690
|
-
if (chunk.response.service_tier != null) {
|
|
1691
|
-
serviceTierFromResponse = chunk.response.service_tier;
|
|
1692
|
-
}
|
|
1693
|
-
if (isTerminalResponse(chunk.response)) {
|
|
1694
|
-
terminalResponse = chunk.response;
|
|
1695
|
-
finalContent = chunk.response.output ?? [];
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
if ('response' in chunk && chunk.response?.usage) {
|
|
1699
|
-
usage = {
|
|
1700
|
-
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
1701
|
-
outputTokens: chunk.response.usage.output_tokens ?? 0,
|
|
1702
|
-
reasoningTokens: chunk.response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1703
|
-
cacheReadInputTokens: chunk.response.usage.input_tokens_details?.cached_tokens ?? 0,
|
|
1704
|
-
cacheCreationInputTokens: extractCacheWriteTokens(chunk.response.usage.input_tokens_details)
|
|
1705
|
-
};
|
|
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
|
+
});
|
|
1706
1841
|
}
|
|
1707
1842
|
}
|
|
1843
|
+
const accumulated = accumulator.result();
|
|
1708
1844
|
if (openAIParams.background === true) {
|
|
1709
|
-
if (terminalResponse) {
|
|
1710
|
-
const context = this.backgroundResponses.take(terminalResponse.id);
|
|
1845
|
+
if (accumulated.terminalResponse) {
|
|
1846
|
+
const context = this.backgroundResponses.take(accumulated.terminalResponse.id);
|
|
1711
1847
|
if (context) {
|
|
1712
|
-
await this.captureBackgroundResponse(terminalResponse, context).catch(() => undefined);
|
|
1848
|
+
await this.captureBackgroundResponse(accumulated.terminalResponse, context).catch(() => undefined);
|
|
1713
1849
|
}
|
|
1714
1850
|
}
|
|
1715
1851
|
return;
|
|
1716
1852
|
}
|
|
1717
|
-
const
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
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,
|
|
1722
1861
|
provider: 'azure',
|
|
1723
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
1724
|
-
output: sanitizeOpenAIResponse(finalContent, this.phClient),
|
|
1725
|
-
latency,
|
|
1726
|
-
timeToFirstToken,
|
|
1727
1862
|
baseURL: this.baseURL,
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
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
|
+
}));
|
|
1738
1874
|
} catch (error) {
|
|
1739
|
-
|
|
1875
|
+
const accumulated = accumulator.result();
|
|
1876
|
+
if (openAIParams.background === true && accumulated.completionId && this.backgroundResponses.get(accumulated.completionId)) {
|
|
1740
1877
|
throw error;
|
|
1741
1878
|
}
|
|
1742
|
-
await captureAiGeneration(this.phClient, {
|
|
1743
|
-
|
|
1744
|
-
model: openAIParams.model,
|
|
1879
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
1880
|
+
client: this.phClient,
|
|
1745
1881
|
provider: 'azure',
|
|
1746
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
1747
|
-
output: [],
|
|
1748
|
-
latency: 0,
|
|
1749
1882
|
baseURL: this.baseURL,
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
},
|
|
1755
|
-
// Surface the completion ID from any chunks consumed before
|
|
1756
|
-
// the stream failed so the error event remains correlatable.
|
|
1757
|
-
completionId: completionIdFromResponse,
|
|
1758
|
-
error: error
|
|
1759
|
-
});
|
|
1883
|
+
params: openAIParams,
|
|
1884
|
+
monitoring: posthogParams,
|
|
1885
|
+
modelParametersSource: body
|
|
1886
|
+
}, error, accumulated.completionId));
|
|
1760
1887
|
throw error;
|
|
1761
1888
|
}
|
|
1762
1889
|
})().catch(() => {
|
|
@@ -1778,53 +1905,33 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1778
1905
|
});
|
|
1779
1906
|
return result;
|
|
1780
1907
|
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
...posthogParams,
|
|
1784
|
-
model: openAIParams.model ?? result.model,
|
|
1908
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildResponsesSuccessOptions({
|
|
1909
|
+
client: this.phClient,
|
|
1785
1910
|
provider: 'azure',
|
|
1786
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
1787
|
-
output: sanitizeOpenAIResponse(result.output, this.phClient),
|
|
1788
|
-
latency,
|
|
1789
1911
|
baseURL: this.baseURL,
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
cacheCreationInputTokens: extractCacheWriteTokens(result.usage?.input_tokens_details),
|
|
1798
|
-
rawUsage: result.usage
|
|
1799
|
-
},
|
|
1800
|
-
stopReason: result.status ?? undefined,
|
|
1801
|
-
completionId: result.id,
|
|
1802
|
-
providerMetadata: buildProviderMetadata({
|
|
1803
|
-
requestId: extractRequestId(result),
|
|
1804
|
-
incompleteDetails: result.incomplete_details
|
|
1912
|
+
params: openAIParams,
|
|
1913
|
+
monitoring: posthogParams,
|
|
1914
|
+
modelParametersSource: body
|
|
1915
|
+
}, {
|
|
1916
|
+
response: result,
|
|
1917
|
+
output: formatResponseOpenAI({
|
|
1918
|
+
output: result.output
|
|
1805
1919
|
}),
|
|
1806
|
-
|
|
1807
|
-
|
|
1920
|
+
latency: (Date.now() - startTime) / 1000,
|
|
1921
|
+
includeTools: true,
|
|
1922
|
+
includeRequestId: true
|
|
1923
|
+
}));
|
|
1808
1924
|
}
|
|
1809
1925
|
return result;
|
|
1810
1926
|
}, async error => {
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
...posthogParams,
|
|
1814
|
-
model: openAIParams.model,
|
|
1927
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
1928
|
+
client: this.phClient,
|
|
1815
1929
|
provider: 'azure',
|
|
1816
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
1817
|
-
output: [],
|
|
1818
|
-
latency: 0,
|
|
1819
1930
|
baseURL: this.baseURL,
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
outputTokens: 0
|
|
1825
|
-
},
|
|
1826
|
-
error
|
|
1827
|
-
});
|
|
1931
|
+
params: openAIParams,
|
|
1932
|
+
monitoring: posthogParams,
|
|
1933
|
+
modelParametersSource: body
|
|
1934
|
+
}, error));
|
|
1828
1935
|
throw error;
|
|
1829
1936
|
});
|
|
1830
1937
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -1894,51 +2001,29 @@ let WrappedResponses$1 = class WrappedResponses extends openai.AzureOpenAI.Respo
|
|
|
1894
2001
|
});
|
|
1895
2002
|
return result;
|
|
1896
2003
|
}
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
...posthogParams,
|
|
1900
|
-
model: openAIParams.model ?? result.model,
|
|
2004
|
+
await captureAiGeneration(this.phClient, buildResponsesSuccessOptions({
|
|
2005
|
+
client: this.phClient,
|
|
1901
2006
|
provider: 'azure',
|
|
1902
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
1903
|
-
output: sanitizeOpenAIResponse(result.output, this.phClient),
|
|
1904
|
-
latency,
|
|
1905
2007
|
baseURL: this.baseURL,
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
},
|
|
1916
|
-
stopReason: result.status ?? undefined,
|
|
1917
|
-
completionId: result.id,
|
|
1918
|
-
providerMetadata: buildProviderMetadata({
|
|
1919
|
-
requestId: extractRequestId(result),
|
|
1920
|
-
incompleteDetails: result.incomplete_details
|
|
1921
|
-
}),
|
|
1922
|
-
error: getResponseFailure(result)
|
|
1923
|
-
});
|
|
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
|
+
}));
|
|
1924
2017
|
return result;
|
|
1925
2018
|
}, async error => {
|
|
1926
|
-
await captureAiGeneration(this.phClient, {
|
|
1927
|
-
|
|
1928
|
-
model: openAIParams.model,
|
|
2019
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
2020
|
+
client: this.phClient,
|
|
1929
2021
|
provider: 'azure',
|
|
1930
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
1931
|
-
output: [],
|
|
1932
|
-
latency: 0,
|
|
1933
2022
|
baseURL: this.baseURL,
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
outputTokens: 0
|
|
1939
|
-
},
|
|
1940
|
-
error
|
|
1941
|
-
});
|
|
2023
|
+
params: openAIParams,
|
|
2024
|
+
monitoring: posthogParams,
|
|
2025
|
+
modelParametersSource: body
|
|
2026
|
+
}, error));
|
|
1942
2027
|
throw error;
|
|
1943
2028
|
});
|
|
1944
2029
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -1958,42 +2043,24 @@ let WrappedEmbeddings$1 = class WrappedEmbeddings extends openai.AzureOpenAI.Emb
|
|
|
1958
2043
|
const startTime = Date.now();
|
|
1959
2044
|
const parentPromise = super.create(openAIParams, options);
|
|
1960
2045
|
const wrappedPromise = parentPromise.then(async result => {
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
eventType: AIEvent.Embedding,
|
|
1964
|
-
...posthogParams,
|
|
1965
|
-
model: openAIParams.model,
|
|
2046
|
+
await captureAiGeneration(this.phClient, buildEmbeddingSuccessOptions({
|
|
2047
|
+
client: this.phClient,
|
|
1966
2048
|
provider: 'azure',
|
|
1967
|
-
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
1968
|
-
output: null,
|
|
1969
|
-
// Embeddings don't have output content
|
|
1970
|
-
latency,
|
|
1971
2049
|
baseURL: this.baseURL,
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
}
|
|
1977
|
-
});
|
|
2050
|
+
params: openAIParams,
|
|
2051
|
+
monitoring: posthogParams,
|
|
2052
|
+
modelParametersSource: body
|
|
2053
|
+
}, result.usage, (Date.now() - startTime) / 1000));
|
|
1978
2054
|
return result;
|
|
1979
2055
|
}, async error => {
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
eventType: AIEvent.Embedding,
|
|
1983
|
-
...posthogParams,
|
|
1984
|
-
model: openAIParams.model,
|
|
2056
|
+
await captureAiGeneration(this.phClient, buildEmbeddingErrorOptions({
|
|
2057
|
+
client: this.phClient,
|
|
1985
2058
|
provider: 'azure',
|
|
1986
|
-
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
1987
|
-
output: null,
|
|
1988
|
-
latency: 0,
|
|
1989
2059
|
baseURL: this.baseURL,
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
},
|
|
1995
|
-
error
|
|
1996
|
-
});
|
|
2060
|
+
params: openAIParams,
|
|
2061
|
+
monitoring: posthogParams,
|
|
2062
|
+
modelParametersSource: body
|
|
2063
|
+
}, error));
|
|
1997
2064
|
throw error;
|
|
1998
2065
|
});
|
|
1999
2066
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -2006,17 +2073,6 @@ const Responses = openai.OpenAI.Responses;
|
|
|
2006
2073
|
const Embeddings = openai.OpenAI.Embeddings;
|
|
2007
2074
|
const Audio = openai.OpenAI.Audio;
|
|
2008
2075
|
const Transcriptions = openai.OpenAI.Audio.Transcriptions;
|
|
2009
|
-
function captureAiGenerationInBackground(...args) {
|
|
2010
|
-
void captureAiGeneration(...args).catch(() => undefined);
|
|
2011
|
-
}
|
|
2012
|
-
async function captureAiGenerationAfterSuccess(...args) {
|
|
2013
|
-
const [, options] = args;
|
|
2014
|
-
if (options.captureImmediate) {
|
|
2015
|
-
await captureAiGeneration(...args);
|
|
2016
|
-
} else {
|
|
2017
|
-
captureAiGenerationInBackground(...args);
|
|
2018
|
-
}
|
|
2019
|
-
}
|
|
2020
2076
|
class PostHogOpenAI extends openai.OpenAI {
|
|
2021
2077
|
constructor(config) {
|
|
2022
2078
|
const {
|
|
@@ -2063,192 +2119,37 @@ class WrappedCompletions extends Completions {
|
|
|
2063
2119
|
if (Symbol.asyncIterator in value) {
|
|
2064
2120
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
|
|
2065
2121
|
(async () => {
|
|
2066
|
-
|
|
2067
|
-
// from the streamed chunks before the failure.
|
|
2068
|
-
let completionIdFromResponse;
|
|
2069
|
-
let systemFingerprintFromResponse;
|
|
2122
|
+
const accumulator = new OpenAIChatStreamAccumulator();
|
|
2070
2123
|
try {
|
|
2071
|
-
const contentBlocks = [];
|
|
2072
|
-
let accumulatedContent = '';
|
|
2073
|
-
let modelFromResponse;
|
|
2074
|
-
let serviceTierFromResponse;
|
|
2075
|
-
let firstTokenTime;
|
|
2076
|
-
let stopReason;
|
|
2077
|
-
let usage = {
|
|
2078
|
-
inputTokens: 0,
|
|
2079
|
-
outputTokens: 0,
|
|
2080
|
-
webSearchCount: 0
|
|
2081
|
-
};
|
|
2082
|
-
|
|
2083
|
-
// Map to track in-progress tool calls
|
|
2084
|
-
const toolCallsInProgress = new Map();
|
|
2085
|
-
let rawUsageData;
|
|
2086
2124
|
for await (const chunk of stream1) {
|
|
2087
|
-
|
|
2088
|
-
if (!modelFromResponse && chunk.model) {
|
|
2089
|
-
modelFromResponse = chunk.model;
|
|
2090
|
-
}
|
|
2091
|
-
if (!completionIdFromResponse && chunk.id) {
|
|
2092
|
-
completionIdFromResponse = chunk.id;
|
|
2093
|
-
}
|
|
2094
|
-
if (!systemFingerprintFromResponse && chunk.system_fingerprint) {
|
|
2095
|
-
systemFingerprintFromResponse = chunk.system_fingerprint;
|
|
2096
|
-
}
|
|
2097
|
-
if (chunk.service_tier != null) {
|
|
2098
|
-
serviceTierFromResponse = chunk.service_tier;
|
|
2099
|
-
}
|
|
2100
|
-
const choice = chunk?.choices?.[0];
|
|
2101
|
-
if (choice?.finish_reason) {
|
|
2102
|
-
stopReason = choice.finish_reason;
|
|
2103
|
-
}
|
|
2104
|
-
const chunkWebSearchCount = calculateWebSearchCount(chunk);
|
|
2105
|
-
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2106
|
-
usage.webSearchCount = chunkWebSearchCount;
|
|
2107
|
-
}
|
|
2108
|
-
|
|
2109
|
-
// Handle text content
|
|
2110
|
-
const deltaContent = choice?.delta?.content;
|
|
2111
|
-
if (deltaContent) {
|
|
2112
|
-
if (firstTokenTime === undefined) {
|
|
2113
|
-
firstTokenTime = Date.now();
|
|
2114
|
-
}
|
|
2115
|
-
accumulatedContent += deltaContent;
|
|
2116
|
-
}
|
|
2117
|
-
|
|
2118
|
-
// Handle tool calls
|
|
2119
|
-
const deltaToolCalls = choice?.delta?.tool_calls;
|
|
2120
|
-
if (deltaToolCalls && Array.isArray(deltaToolCalls)) {
|
|
2121
|
-
if (firstTokenTime === undefined) {
|
|
2122
|
-
firstTokenTime = Date.now();
|
|
2123
|
-
}
|
|
2124
|
-
for (const toolCall of deltaToolCalls) {
|
|
2125
|
-
const index = toolCall.index;
|
|
2126
|
-
if (index !== undefined) {
|
|
2127
|
-
if (!toolCallsInProgress.has(index)) {
|
|
2128
|
-
// New tool call
|
|
2129
|
-
toolCallsInProgress.set(index, {
|
|
2130
|
-
id: toolCall.id || '',
|
|
2131
|
-
name: toolCall.function?.name || '',
|
|
2132
|
-
arguments: ''
|
|
2133
|
-
});
|
|
2134
|
-
}
|
|
2135
|
-
const inProgressCall = toolCallsInProgress.get(index);
|
|
2136
|
-
if (inProgressCall) {
|
|
2137
|
-
// Update tool call data
|
|
2138
|
-
if (toolCall.id) {
|
|
2139
|
-
inProgressCall.id = toolCall.id;
|
|
2140
|
-
}
|
|
2141
|
-
if (toolCall.function?.name) {
|
|
2142
|
-
inProgressCall.name = toolCall.function.name;
|
|
2143
|
-
}
|
|
2144
|
-
if (toolCall.function?.arguments) {
|
|
2145
|
-
inProgressCall.arguments += toolCall.function.arguments;
|
|
2146
|
-
}
|
|
2147
|
-
}
|
|
2148
|
-
}
|
|
2149
|
-
}
|
|
2150
|
-
}
|
|
2151
|
-
|
|
2152
|
-
// Handle usage information
|
|
2153
|
-
if (chunk.usage) {
|
|
2154
|
-
rawUsageData = chunk.usage;
|
|
2155
|
-
usage = {
|
|
2156
|
-
...usage,
|
|
2157
|
-
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
2158
|
-
outputTokens: chunk.usage.completion_tokens ?? 0,
|
|
2159
|
-
reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
2160
|
-
cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,
|
|
2161
|
-
cacheCreationInputTokens: extractCacheWriteTokens(chunk.usage.prompt_tokens_details)
|
|
2162
|
-
};
|
|
2163
|
-
}
|
|
2164
|
-
}
|
|
2165
|
-
|
|
2166
|
-
// Build final content blocks
|
|
2167
|
-
if (accumulatedContent) {
|
|
2168
|
-
contentBlocks.push({
|
|
2169
|
-
type: 'text',
|
|
2170
|
-
text: accumulatedContent
|
|
2171
|
-
});
|
|
2172
|
-
}
|
|
2173
|
-
|
|
2174
|
-
// Add completed tool calls to content blocks
|
|
2175
|
-
for (const toolCall of toolCallsInProgress.values()) {
|
|
2176
|
-
if (toolCall.name) {
|
|
2177
|
-
contentBlocks.push({
|
|
2178
|
-
type: 'function',
|
|
2179
|
-
id: toolCall.id,
|
|
2180
|
-
function: {
|
|
2181
|
-
name: toolCall.name,
|
|
2182
|
-
arguments: toolCall.arguments
|
|
2183
|
-
}
|
|
2184
|
-
});
|
|
2185
|
-
}
|
|
2125
|
+
accumulator.consume(chunk);
|
|
2186
2126
|
}
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
role: 'assistant',
|
|
2191
|
-
content: contentBlocks
|
|
2192
|
-
}] : [{
|
|
2193
|
-
role: 'assistant',
|
|
2194
|
-
content: [{
|
|
2195
|
-
type: 'text',
|
|
2196
|
-
text: ''
|
|
2197
|
-
}]
|
|
2198
|
-
}];
|
|
2199
|
-
const latency = (Date.now() - startTime) / 1000;
|
|
2200
|
-
const timeToFirstToken = firstTokenTime !== undefined ? (firstTokenTime - startTime) / 1000 : undefined;
|
|
2201
|
-
const availableTools = extractAvailableToolCalls('openai', openAIParams);
|
|
2202
|
-
await captureAiGeneration(this.phClient, {
|
|
2203
|
-
...posthogParams,
|
|
2204
|
-
model: openAIParams.model ?? modelFromResponse,
|
|
2127
|
+
const accumulated = accumulator.result();
|
|
2128
|
+
await captureAiGeneration(this.phClient, buildChatSuccessOptions({
|
|
2129
|
+
client: this.phClient,
|
|
2205
2130
|
provider: 'openai',
|
|
2206
|
-
input: sanitizeOpenAI(openAIParams.messages, this.phClient),
|
|
2207
|
-
output: sanitizeOpenAIResponse(formattedOutput, this.phClient),
|
|
2208
|
-
latency,
|
|
2209
|
-
timeToFirstToken,
|
|
2210
2131
|
baseURL: this.baseURL,
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
webSearchCount: usage.webSearchCount,
|
|
2220
|
-
rawUsage: rawUsageData
|
|
2221
|
-
},
|
|
2222
|
-
stopReason,
|
|
2223
|
-
tools: availableTools,
|
|
2224
|
-
completionId: completionIdFromResponse,
|
|
2225
|
-
providerMetadata: buildProviderMetadata({
|
|
2226
|
-
systemFingerprint: systemFingerprintFromResponse
|
|
2227
|
-
})
|
|
2228
|
-
});
|
|
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
|
+
}));
|
|
2229
2140
|
} catch (error) {
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2141
|
+
const accumulated = accumulator.result();
|
|
2142
|
+
await captureAiGeneration(this.phClient, buildChatErrorOptions({
|
|
2143
|
+
client: this.phClient,
|
|
2233
2144
|
provider: 'openai',
|
|
2234
|
-
input: sanitizeOpenAI(openAIParams.messages, this.phClient),
|
|
2235
|
-
output: [],
|
|
2236
|
-
latency: 0,
|
|
2237
2145
|
baseURL: this.baseURL,
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
// event can still be correlated to OpenAI's Logs dashboard.
|
|
2246
|
-
completionId: completionIdFromResponse,
|
|
2247
|
-
providerMetadata: buildProviderMetadata({
|
|
2248
|
-
systemFingerprint: systemFingerprintFromResponse
|
|
2249
|
-
}),
|
|
2250
|
-
error
|
|
2251
|
-
});
|
|
2146
|
+
params: openAIParams,
|
|
2147
|
+
monitoring: posthogParams,
|
|
2148
|
+
modelParametersSource: body
|
|
2149
|
+
}, error, {
|
|
2150
|
+
completionId: accumulated.completionId,
|
|
2151
|
+
systemFingerprint: accumulated.systemFingerprint
|
|
2152
|
+
}));
|
|
2252
2153
|
throw error;
|
|
2253
2154
|
}
|
|
2254
2155
|
})().catch(() => {
|
|
@@ -2265,56 +2166,35 @@ class WrappedCompletions extends Completions {
|
|
|
2265
2166
|
} else {
|
|
2266
2167
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2267
2168
|
if ('choices' in result) {
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
const formattedOutput = formatResponseOpenAI(result);
|
|
2271
|
-
await captureAiGenerationAfterSuccess(this.phClient, {
|
|
2272
|
-
...posthogParams,
|
|
2273
|
-
model: openAIParams.model ?? result.model,
|
|
2169
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildChatSuccessOptions({
|
|
2170
|
+
client: this.phClient,
|
|
2274
2171
|
provider: 'openai',
|
|
2275
|
-
input: sanitizeOpenAI(openAIParams.messages, this.phClient),
|
|
2276
|
-
output: sanitizeOpenAIResponse(formattedOutput, this.phClient),
|
|
2277
|
-
latency,
|
|
2278
2172
|
baseURL: this.baseURL,
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
rawUsage: result.usage
|
|
2289
|
-
},
|
|
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),
|
|
2290
2182
|
stopReason: result.choices[0]?.finish_reason ?? undefined,
|
|
2291
|
-
tools: availableTools,
|
|
2292
2183
|
completionId: result.id,
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
})
|
|
2297
|
-
});
|
|
2184
|
+
systemFingerprint: result.system_fingerprint,
|
|
2185
|
+
requestId: extractRequestId(result)
|
|
2186
|
+
}));
|
|
2298
2187
|
}
|
|
2299
2188
|
return result;
|
|
2300
2189
|
}, async error => {
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
...posthogParams,
|
|
2304
|
-
model: openAIParams.model,
|
|
2190
|
+
await captureAiGeneration(this.phClient, buildChatErrorOptions({
|
|
2191
|
+
client: this.phClient,
|
|
2305
2192
|
provider: 'openai',
|
|
2306
|
-
input: sanitizeOpenAI(openAIParams.messages, this.phClient),
|
|
2307
|
-
output: [],
|
|
2308
|
-
latency: 0,
|
|
2309
2193
|
baseURL: this.baseURL,
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
outputTokens: 0
|
|
2315
|
-
},
|
|
2316
|
-
error
|
|
2317
|
-
});
|
|
2194
|
+
params: openAIParams,
|
|
2195
|
+
monitoring: posthogParams,
|
|
2196
|
+
modelParametersSource: body
|
|
2197
|
+
}, error));
|
|
2318
2198
|
throw error;
|
|
2319
2199
|
});
|
|
2320
2200
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -2333,36 +2213,14 @@ class WrappedResponses extends Responses {
|
|
|
2333
2213
|
openAIParams,
|
|
2334
2214
|
posthogParams
|
|
2335
2215
|
} = context;
|
|
2336
|
-
await captureAiGenerationAfterSuccess(this.phClient, {
|
|
2337
|
-
|
|
2338
|
-
model: openAIParams.model ?? result.model,
|
|
2216
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildBackgroundResponseOptions({
|
|
2217
|
+
client: this.phClient,
|
|
2339
2218
|
provider: 'openai',
|
|
2340
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
2341
|
-
output: formatResponseOpenAI({
|
|
2342
|
-
output: result.output
|
|
2343
|
-
}),
|
|
2344
|
-
latency: getBackgroundResponseLatency(result),
|
|
2345
2219
|
baseURL: this.baseURL,
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
outputTokens: result.usage?.output_tokens ?? 0,
|
|
2351
|
-
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2352
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
2353
|
-
cacheCreationInputTokens: extractCacheWriteTokens(result.usage?.input_tokens_details),
|
|
2354
|
-
webSearchCount: calculateWebSearchCount(result),
|
|
2355
|
-
rawUsage: result.usage
|
|
2356
|
-
},
|
|
2357
|
-
stopReason: result.status ?? undefined,
|
|
2358
|
-
tools: extractAvailableToolCalls('openai', openAIParams),
|
|
2359
|
-
completionId: result.id,
|
|
2360
|
-
providerMetadata: buildProviderMetadata({
|
|
2361
|
-
requestId: extractRequestId(result),
|
|
2362
|
-
incompleteDetails: result.incomplete_details
|
|
2363
|
-
}),
|
|
2364
|
-
error: getResponseFailure(result)
|
|
2365
|
-
});
|
|
2220
|
+
params: openAIParams,
|
|
2221
|
+
monitoring: posthogParams,
|
|
2222
|
+
modelParametersSource: openAIParams
|
|
2223
|
+
}, result));
|
|
2366
2224
|
}
|
|
2367
2225
|
|
|
2368
2226
|
// --- Overload #1: Non-streaming
|
|
@@ -2384,128 +2242,61 @@ class WrappedResponses extends Responses {
|
|
|
2384
2242
|
if (Symbol.asyncIterator in value) {
|
|
2385
2243
|
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
|
|
2386
2244
|
(async () => {
|
|
2387
|
-
|
|
2388
|
-
// was accumulated from the streamed chunks before the failure.
|
|
2389
|
-
let completionIdFromResponse;
|
|
2245
|
+
const accumulator = new OpenAIResponsesStreamAccumulator();
|
|
2390
2246
|
try {
|
|
2391
|
-
let finalContent = [];
|
|
2392
|
-
let modelFromResponse;
|
|
2393
|
-
let serviceTierFromResponse;
|
|
2394
|
-
let firstTokenTime;
|
|
2395
|
-
let stopReason;
|
|
2396
|
-
let usage = {
|
|
2397
|
-
inputTokens: 0,
|
|
2398
|
-
outputTokens: 0,
|
|
2399
|
-
webSearchCount: 0
|
|
2400
|
-
};
|
|
2401
|
-
let rawUsageData;
|
|
2402
|
-
let terminalResponse;
|
|
2403
2247
|
for await (const chunk of stream1) {
|
|
2404
|
-
|
|
2405
|
-
if (
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
if (!modelFromResponse && chunk.response.model) {
|
|
2411
|
-
modelFromResponse = chunk.response.model;
|
|
2412
|
-
}
|
|
2413
|
-
if (!completionIdFromResponse && chunk.response.id) {
|
|
2414
|
-
completionIdFromResponse = chunk.response.id;
|
|
2415
|
-
}
|
|
2416
|
-
if (openAIParams.background === true && !this.backgroundResponses.get(chunk.response.id)) {
|
|
2417
|
-
this.backgroundResponses.set(chunk.response.id, {
|
|
2418
|
-
openAIParams,
|
|
2419
|
-
posthogParams
|
|
2420
|
-
});
|
|
2421
|
-
}
|
|
2422
|
-
if (chunk.response.service_tier != null) {
|
|
2423
|
-
serviceTierFromResponse = chunk.response.service_tier;
|
|
2424
|
-
}
|
|
2425
|
-
const chunkWebSearchCount = calculateWebSearchCount(chunk.response);
|
|
2426
|
-
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
2427
|
-
usage.webSearchCount = chunkWebSearchCount;
|
|
2428
|
-
}
|
|
2429
|
-
if (isTerminalResponse(chunk.response)) {
|
|
2430
|
-
terminalResponse = chunk.response;
|
|
2431
|
-
finalContent = chunk.response.output ?? [];
|
|
2432
|
-
stopReason = chunk.response.status;
|
|
2433
|
-
}
|
|
2434
|
-
}
|
|
2435
|
-
if ('response' in chunk && chunk.response?.usage) {
|
|
2436
|
-
rawUsageData = chunk.response.usage;
|
|
2437
|
-
usage = {
|
|
2438
|
-
...usage,
|
|
2439
|
-
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
2440
|
-
outputTokens: chunk.response.usage.output_tokens ?? 0,
|
|
2441
|
-
reasoningTokens: chunk.response.usage.output_tokens_details?.reasoning_tokens ?? 0,
|
|
2442
|
-
cacheReadInputTokens: chunk.response.usage.input_tokens_details?.cached_tokens ?? 0,
|
|
2443
|
-
cacheCreationInputTokens: extractCacheWriteTokens(chunk.response.usage.input_tokens_details)
|
|
2444
|
-
};
|
|
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
|
+
});
|
|
2445
2254
|
}
|
|
2446
2255
|
}
|
|
2256
|
+
const accumulated = accumulator.result();
|
|
2447
2257
|
if (openAIParams.background === true) {
|
|
2448
|
-
if (terminalResponse) {
|
|
2449
|
-
const context = this.backgroundResponses.take(terminalResponse.id);
|
|
2258
|
+
if (accumulated.terminalResponse) {
|
|
2259
|
+
const context = this.backgroundResponses.take(accumulated.terminalResponse.id);
|
|
2450
2260
|
if (context) {
|
|
2451
|
-
await this.captureBackgroundResponse(terminalResponse, context).catch(() => undefined);
|
|
2261
|
+
await this.captureBackgroundResponse(accumulated.terminalResponse, context).catch(() => undefined);
|
|
2452
2262
|
}
|
|
2453
2263
|
}
|
|
2454
2264
|
return;
|
|
2455
2265
|
}
|
|
2456
|
-
const
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
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,
|
|
2462
2274
|
provider: 'openai',
|
|
2463
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
2464
|
-
output: sanitizeOpenAIResponse(finalContent, this.phClient),
|
|
2465
|
-
latency,
|
|
2466
|
-
timeToFirstToken,
|
|
2467
2275
|
baseURL: this.baseURL,
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
stopReason,
|
|
2480
|
-
tools: availableTools,
|
|
2481
|
-
completionId: completionIdFromResponse,
|
|
2482
|
-
providerMetadata: buildProviderMetadata({
|
|
2483
|
-
incompleteDetails: terminalResponse?.incomplete_details
|
|
2484
|
-
}),
|
|
2485
|
-
error: getResponseFailure(terminalResponse)
|
|
2486
|
-
});
|
|
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
|
+
}));
|
|
2487
2287
|
} catch (error) {
|
|
2488
|
-
|
|
2288
|
+
const accumulated = accumulator.result();
|
|
2289
|
+
if (openAIParams.background === true && accumulated.completionId && this.backgroundResponses.get(accumulated.completionId)) {
|
|
2489
2290
|
throw error;
|
|
2490
2291
|
}
|
|
2491
|
-
await captureAiGeneration(this.phClient, {
|
|
2492
|
-
|
|
2493
|
-
model: openAIParams.model,
|
|
2292
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
2293
|
+
client: this.phClient,
|
|
2494
2294
|
provider: 'openai',
|
|
2495
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
2496
|
-
output: [],
|
|
2497
|
-
latency: 0,
|
|
2498
2295
|
baseURL: this.baseURL,
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
},
|
|
2504
|
-
// Surface the completion ID from any chunks consumed before
|
|
2505
|
-
// the stream failed so the error event remains correlatable.
|
|
2506
|
-
completionId: completionIdFromResponse,
|
|
2507
|
-
error
|
|
2508
|
-
});
|
|
2296
|
+
params: openAIParams,
|
|
2297
|
+
monitoring: posthogParams,
|
|
2298
|
+
modelParametersSource: body
|
|
2299
|
+
}, error, accumulated.completionId));
|
|
2509
2300
|
throw error;
|
|
2510
2301
|
}
|
|
2511
2302
|
})().catch(() => {
|
|
@@ -2527,59 +2318,33 @@ class WrappedResponses extends Responses {
|
|
|
2527
2318
|
});
|
|
2528
2319
|
return result;
|
|
2529
2320
|
}
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
const formattedOutput = formatResponseOpenAI({
|
|
2533
|
-
output: result.output
|
|
2534
|
-
});
|
|
2535
|
-
await captureAiGenerationAfterSuccess(this.phClient, {
|
|
2536
|
-
...posthogParams,
|
|
2537
|
-
model: openAIParams.model ?? result.model,
|
|
2321
|
+
await captureAiGenerationAfterSuccess(this.phClient, buildResponsesSuccessOptions({
|
|
2322
|
+
client: this.phClient,
|
|
2538
2323
|
provider: 'openai',
|
|
2539
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
2540
|
-
output: sanitizeOpenAIResponse(formattedOutput, this.phClient),
|
|
2541
|
-
latency,
|
|
2542
2324
|
baseURL: this.baseURL,
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
cacheCreationInputTokens: extractCacheWriteTokens(result.usage?.input_tokens_details),
|
|
2551
|
-
webSearchCount: calculateWebSearchCount(result),
|
|
2552
|
-
rawUsage: result.usage
|
|
2553
|
-
},
|
|
2554
|
-
stopReason: result.status ?? undefined,
|
|
2555
|
-
tools: availableTools,
|
|
2556
|
-
completionId: result.id,
|
|
2557
|
-
providerMetadata: buildProviderMetadata({
|
|
2558
|
-
requestId: extractRequestId(result),
|
|
2559
|
-
incompleteDetails: result.incomplete_details
|
|
2325
|
+
params: openAIParams,
|
|
2326
|
+
monitoring: posthogParams,
|
|
2327
|
+
modelParametersSource: body
|
|
2328
|
+
}, {
|
|
2329
|
+
response: result,
|
|
2330
|
+
output: formatResponseOpenAI({
|
|
2331
|
+
output: result.output
|
|
2560
2332
|
}),
|
|
2561
|
-
|
|
2562
|
-
|
|
2333
|
+
latency: (Date.now() - startTime) / 1000,
|
|
2334
|
+
includeTools: true,
|
|
2335
|
+
includeRequestId: true
|
|
2336
|
+
}));
|
|
2563
2337
|
}
|
|
2564
2338
|
return result;
|
|
2565
2339
|
}, async error => {
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
...posthogParams,
|
|
2569
|
-
model: openAIParams.model,
|
|
2340
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
2341
|
+
client: this.phClient,
|
|
2570
2342
|
provider: 'openai',
|
|
2571
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
2572
|
-
output: [],
|
|
2573
|
-
latency: 0,
|
|
2574
2343
|
baseURL: this.baseURL,
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
outputTokens: 0
|
|
2580
|
-
},
|
|
2581
|
-
error
|
|
2582
|
-
});
|
|
2344
|
+
params: openAIParams,
|
|
2345
|
+
monitoring: posthogParams,
|
|
2346
|
+
modelParametersSource: body
|
|
2347
|
+
}, error));
|
|
2583
2348
|
throw error;
|
|
2584
2349
|
});
|
|
2585
2350
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -2649,50 +2414,29 @@ class WrappedResponses extends Responses {
|
|
|
2649
2414
|
});
|
|
2650
2415
|
return result;
|
|
2651
2416
|
}
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
...posthogParams,
|
|
2655
|
-
model: openAIParams.model ?? result.model,
|
|
2417
|
+
await captureAiGeneration(this.phClient, buildResponsesSuccessOptions({
|
|
2418
|
+
client: this.phClient,
|
|
2656
2419
|
provider: 'openai',
|
|
2657
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
2658
|
-
output: sanitizeOpenAIResponse(result.output, this.phClient),
|
|
2659
|
-
latency,
|
|
2660
2420
|
baseURL: this.baseURL,
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
},
|
|
2671
|
-
stopReason: result.status ?? undefined,
|
|
2672
|
-
completionId: result.id,
|
|
2673
|
-
providerMetadata: buildProviderMetadata({
|
|
2674
|
-
requestId: extractRequestId(result),
|
|
2675
|
-
incompleteDetails: result.incomplete_details
|
|
2676
|
-
}),
|
|
2677
|
-
error: getResponseFailure(result)
|
|
2678
|
-
});
|
|
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
|
+
}));
|
|
2679
2430
|
return result;
|
|
2680
2431
|
}, async error => {
|
|
2681
|
-
await captureAiGeneration(this.phClient, {
|
|
2682
|
-
|
|
2683
|
-
model: openAIParams.model,
|
|
2432
|
+
await captureAiGeneration(this.phClient, buildResponsesErrorOptions({
|
|
2433
|
+
client: this.phClient,
|
|
2684
2434
|
provider: 'openai',
|
|
2685
|
-
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input, this.phClient), openAIParams.instructions),
|
|
2686
|
-
output: [],
|
|
2687
|
-
latency: 0,
|
|
2688
2435
|
baseURL: this.baseURL,
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
},
|
|
2694
|
-
error
|
|
2695
|
-
});
|
|
2436
|
+
params: openAIParams,
|
|
2437
|
+
monitoring: posthogParams,
|
|
2438
|
+
modelParametersSource: body
|
|
2439
|
+
}, error));
|
|
2696
2440
|
throw error;
|
|
2697
2441
|
});
|
|
2698
2442
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|
|
@@ -2712,44 +2456,24 @@ class WrappedEmbeddings extends Embeddings {
|
|
|
2712
2456
|
const startTime = Date.now();
|
|
2713
2457
|
const parentPromise = super.create(openAIParams, options);
|
|
2714
2458
|
const wrappedPromise = parentPromise.then(async result => {
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
...posthogParams,
|
|
2718
|
-
eventType: AIEvent.Embedding,
|
|
2719
|
-
model: openAIParams.model,
|
|
2459
|
+
await captureAiGeneration(this.phClient, buildEmbeddingSuccessOptions({
|
|
2460
|
+
client: this.phClient,
|
|
2720
2461
|
provider: 'openai',
|
|
2721
|
-
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
2722
|
-
output: null,
|
|
2723
|
-
// Embeddings don't have output content
|
|
2724
|
-
latency,
|
|
2725
2462
|
baseURL: this.baseURL,
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
rawUsage: result.usage
|
|
2731
|
-
}
|
|
2732
|
-
});
|
|
2463
|
+
params: openAIParams,
|
|
2464
|
+
monitoring: posthogParams,
|
|
2465
|
+
modelParametersSource: body
|
|
2466
|
+
}, result.usage, (Date.now() - startTime) / 1000));
|
|
2733
2467
|
return result;
|
|
2734
2468
|
}, async error => {
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
eventType: AIEvent.Embedding,
|
|
2738
|
-
...posthogParams,
|
|
2739
|
-
model: openAIParams.model,
|
|
2469
|
+
await captureAiGeneration(this.phClient, buildEmbeddingErrorOptions({
|
|
2470
|
+
client: this.phClient,
|
|
2740
2471
|
provider: 'openai',
|
|
2741
|
-
input: withPrivacyMode(this.phClient, posthogParams.privacyMode, openAIParams.input),
|
|
2742
|
-
output: null,
|
|
2743
|
-
// Embeddings don't have output content
|
|
2744
|
-
latency: 0,
|
|
2745
2472
|
baseURL: this.baseURL,
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
},
|
|
2751
|
-
error
|
|
2752
|
-
});
|
|
2473
|
+
params: openAIParams,
|
|
2474
|
+
monitoring: posthogParams,
|
|
2475
|
+
modelParametersSource: body
|
|
2476
|
+
}, error));
|
|
2753
2477
|
throw error;
|
|
2754
2478
|
});
|
|
2755
2479
|
return preserveProviderPromise(parentPromise, wrappedPromise);
|