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