@posthog/ai 7.19.7 → 7.20.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 +7 -1
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +7 -1
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +7 -1
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +7 -1
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +135 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.mjs +135 -15
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +1 -1
- package/dist/langchain/index.mjs +1 -1
- package/dist/openai/index.cjs +86 -8
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +86 -8
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +1 -1
- package/dist/openai-agents/index.mjs +1 -1
- package/dist/vercel/index.cjs +7 -1
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +7 -1
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -479,6 +479,19 @@ interface CaptureAiGenerationOptions {
|
|
|
479
479
|
costOverride?: CostOverride;
|
|
480
480
|
tools?: ChatCompletionTool[] | AnthropicTool[] | Tool[] | null;
|
|
481
481
|
stopReason?: string;
|
|
482
|
+
/**
|
|
483
|
+
* Provider-assigned ID for the generation (e.g. OpenAI's `chatcmpl-…` /
|
|
484
|
+
* `resp_…`). Maps to `$ai_completion_id`. Response IDs generalize across
|
|
485
|
+
* providers, so this lives in the shared schema rather than under
|
|
486
|
+
* `providerMetadata`.
|
|
487
|
+
*/
|
|
488
|
+
completionId?: string;
|
|
489
|
+
/**
|
|
490
|
+
* Provider-specific response metadata that has no place in the shared,
|
|
491
|
+
* provider-agnostic `$ai_*` schema (e.g. OpenAI's `system_fingerprint` and
|
|
492
|
+
* `request_id`). Maps to `$ai_provider_metadata`; omitted when empty.
|
|
493
|
+
*/
|
|
494
|
+
providerMetadata?: Record<string, unknown>;
|
|
482
495
|
/** When set, the event is captured as an error. */
|
|
483
496
|
error?: unknown;
|
|
484
497
|
/** Awaits delivery instead of batching. Useful in serverless environments. */
|
package/dist/index.mjs
CHANGED
|
@@ -709,7 +709,7 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
709
709
|
return messages;
|
|
710
710
|
}
|
|
711
711
|
|
|
712
|
-
var version = "7.
|
|
712
|
+
var version = "7.20.0";
|
|
713
713
|
|
|
714
714
|
const DEFAULT_MAX_DEPTH = 3;
|
|
715
715
|
const MAX_STACK_LINES = 20;
|
|
@@ -870,6 +870,12 @@ const captureAiGeneration = async (client, options) => {
|
|
|
870
870
|
...(options.tools ? {
|
|
871
871
|
$ai_tools: options.tools
|
|
872
872
|
} : {}),
|
|
873
|
+
...(options.completionId ? {
|
|
874
|
+
$ai_completion_id: options.completionId
|
|
875
|
+
} : {}),
|
|
876
|
+
...(options.providerMetadata && Object.keys(options.providerMetadata).length > 0 ? {
|
|
877
|
+
$ai_provider_metadata: options.providerMetadata
|
|
878
|
+
} : {}),
|
|
873
879
|
...errorData,
|
|
874
880
|
...costOverrideData
|
|
875
881
|
};
|
|
@@ -893,6 +899,32 @@ const captureAiGeneration = async (client, options) => {
|
|
|
893
899
|
function isResponseTokenChunk(chunk) {
|
|
894
900
|
return chunk.type === 'response.output_item.added' || chunk.type === 'response.content_part.added' || chunk.type === 'response.output_text.delta' || chunk.type === 'response.reasoning_text.delta' || chunk.type === 'response.reasoning_summary_text.delta' || chunk.type === 'response.audio.delta' || chunk.type === 'response.audio.transcript.delta' || chunk.type === 'response.refusal.delta';
|
|
895
901
|
}
|
|
902
|
+
/**
|
|
903
|
+
* Reads the OpenAI SDK's `_request_id` field from a response object. The SDK
|
|
904
|
+
* attaches the `x-request-id` response header here, but it is not part of the
|
|
905
|
+
* public response types, so it has to be read through a cast. Used to populate
|
|
906
|
+
* `$ai_provider_metadata.request_id`.
|
|
907
|
+
*/
|
|
908
|
+
function extractRequestId(result) {
|
|
909
|
+
return result?._request_id ?? undefined;
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Assembles the `$ai_provider_metadata` blob for OpenAI / Azure OpenAI events.
|
|
913
|
+
* Provider-specific fields (system fingerprint, request id) live here rather
|
|
914
|
+
* than in the shared, provider-agnostic `$ai_*` namespace. Only keys with a
|
|
915
|
+
* truthy value are included, and `undefined` is returned when there is nothing
|
|
916
|
+
* to report so the property can be omitted from the event entirely.
|
|
917
|
+
*/
|
|
918
|
+
function buildProviderMetadata(fields) {
|
|
919
|
+
const metadata = {};
|
|
920
|
+
if (fields.systemFingerprint) {
|
|
921
|
+
metadata.system_fingerprint = fields.systemFingerprint;
|
|
922
|
+
}
|
|
923
|
+
if (fields.requestId) {
|
|
924
|
+
metadata.request_id = fields.requestId;
|
|
925
|
+
}
|
|
926
|
+
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
927
|
+
}
|
|
896
928
|
|
|
897
929
|
const Chat = OpenAI.Chat;
|
|
898
930
|
const Completions = Chat.Completions;
|
|
@@ -939,6 +971,10 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
939
971
|
if ('tee' in value) {
|
|
940
972
|
const [stream1, stream2] = value.tee();
|
|
941
973
|
(async () => {
|
|
974
|
+
// Hoisted so the catch block can surface whatever was accumulated
|
|
975
|
+
// from the streamed chunks before the failure.
|
|
976
|
+
let completionIdFromResponse;
|
|
977
|
+
let systemFingerprintFromResponse;
|
|
942
978
|
try {
|
|
943
979
|
const contentBlocks = [];
|
|
944
980
|
let accumulatedContent = '';
|
|
@@ -954,10 +990,16 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
954
990
|
const toolCallsInProgress = new Map();
|
|
955
991
|
let rawUsageData;
|
|
956
992
|
for await (const chunk of stream1) {
|
|
957
|
-
// Extract model from chunk (Chat Completions chunks
|
|
993
|
+
// Extract model and completion metadata from chunk (Chat Completions chunks carry these fields)
|
|
958
994
|
if (!modelFromResponse && chunk.model) {
|
|
959
995
|
modelFromResponse = chunk.model;
|
|
960
996
|
}
|
|
997
|
+
if (!completionIdFromResponse && chunk.id) {
|
|
998
|
+
completionIdFromResponse = chunk.id;
|
|
999
|
+
}
|
|
1000
|
+
if (!systemFingerprintFromResponse && chunk.system_fingerprint) {
|
|
1001
|
+
systemFingerprintFromResponse = chunk.system_fingerprint;
|
|
1002
|
+
}
|
|
961
1003
|
const choice = chunk?.choices?.[0];
|
|
962
1004
|
if (choice?.finish_reason) {
|
|
963
1005
|
stopReason = choice.finish_reason;
|
|
@@ -1073,7 +1115,11 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
1073
1115
|
rawUsage: rawUsageData
|
|
1074
1116
|
},
|
|
1075
1117
|
stopReason,
|
|
1076
|
-
tools: availableTools
|
|
1118
|
+
tools: availableTools,
|
|
1119
|
+
completionId: completionIdFromResponse,
|
|
1120
|
+
providerMetadata: buildProviderMetadata({
|
|
1121
|
+
systemFingerprint: systemFingerprintFromResponse
|
|
1122
|
+
})
|
|
1077
1123
|
});
|
|
1078
1124
|
} catch (error) {
|
|
1079
1125
|
await captureAiGeneration(this.phClient, {
|
|
@@ -1089,6 +1135,13 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
1089
1135
|
inputTokens: 0,
|
|
1090
1136
|
outputTokens: 0
|
|
1091
1137
|
},
|
|
1138
|
+
// If the stream fails mid-flight, surface whatever completion
|
|
1139
|
+
// metadata the consumed chunks already provided so the error
|
|
1140
|
+
// event can still be correlated to OpenAI's Logs dashboard.
|
|
1141
|
+
completionId: completionIdFromResponse,
|
|
1142
|
+
providerMetadata: buildProviderMetadata({
|
|
1143
|
+
systemFingerprint: systemFingerprintFromResponse
|
|
1144
|
+
}),
|
|
1092
1145
|
error
|
|
1093
1146
|
});
|
|
1094
1147
|
throw error;
|
|
@@ -1124,7 +1177,12 @@ let WrappedCompletions$1 = class WrappedCompletions extends Completions {
|
|
|
1124
1177
|
rawUsage: result.usage
|
|
1125
1178
|
},
|
|
1126
1179
|
stopReason: result.choices[0]?.finish_reason ?? undefined,
|
|
1127
|
-
tools: availableTools
|
|
1180
|
+
tools: availableTools,
|
|
1181
|
+
completionId: result.id,
|
|
1182
|
+
providerMetadata: buildProviderMetadata({
|
|
1183
|
+
systemFingerprint: result.system_fingerprint,
|
|
1184
|
+
requestId: extractRequestId(result)
|
|
1185
|
+
})
|
|
1128
1186
|
});
|
|
1129
1187
|
}
|
|
1130
1188
|
return result;
|
|
@@ -1171,6 +1229,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1171
1229
|
if ('tee' in value && typeof value.tee === 'function') {
|
|
1172
1230
|
const [stream1, stream2] = value.tee();
|
|
1173
1231
|
(async () => {
|
|
1232
|
+
// Hoisted so the catch block can surface the completion ID that
|
|
1233
|
+
// was accumulated from the streamed chunks before the failure.
|
|
1234
|
+
let completionIdFromResponse;
|
|
1174
1235
|
try {
|
|
1175
1236
|
let finalContent = [];
|
|
1176
1237
|
let modelFromResponse;
|
|
@@ -1188,10 +1249,13 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1188
1249
|
firstTokenTime = Date.now();
|
|
1189
1250
|
}
|
|
1190
1251
|
if ('response' in chunk && chunk.response) {
|
|
1191
|
-
// Extract model from response object in chunk (for stored prompts)
|
|
1252
|
+
// Extract model and completion ID from the response object in the chunk (for stored prompts)
|
|
1192
1253
|
if (!modelFromResponse && chunk.response.model) {
|
|
1193
1254
|
modelFromResponse = chunk.response.model;
|
|
1194
1255
|
}
|
|
1256
|
+
if (!completionIdFromResponse && chunk.response.id) {
|
|
1257
|
+
completionIdFromResponse = chunk.response.id;
|
|
1258
|
+
}
|
|
1195
1259
|
const chunkWebSearchCount = calculateWebSearchCount(chunk.response);
|
|
1196
1260
|
if (chunkWebSearchCount > 0 && chunkWebSearchCount > (usage.webSearchCount ?? 0)) {
|
|
1197
1261
|
usage.webSearchCount = chunkWebSearchCount;
|
|
@@ -1237,7 +1301,8 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1237
1301
|
rawUsage: rawUsageData
|
|
1238
1302
|
},
|
|
1239
1303
|
stopReason,
|
|
1240
|
-
tools: availableTools
|
|
1304
|
+
tools: availableTools,
|
|
1305
|
+
completionId: completionIdFromResponse
|
|
1241
1306
|
});
|
|
1242
1307
|
} catch (error) {
|
|
1243
1308
|
await captureAiGeneration(this.phClient, {
|
|
@@ -1253,6 +1318,9 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1253
1318
|
inputTokens: 0,
|
|
1254
1319
|
outputTokens: 0
|
|
1255
1320
|
},
|
|
1321
|
+
// Surface the completion ID from any chunks consumed before
|
|
1322
|
+
// the stream failed so the error event remains correlatable.
|
|
1323
|
+
completionId: completionIdFromResponse,
|
|
1256
1324
|
error
|
|
1257
1325
|
});
|
|
1258
1326
|
throw error;
|
|
@@ -1289,7 +1357,11 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1289
1357
|
rawUsage: result.usage
|
|
1290
1358
|
},
|
|
1291
1359
|
stopReason: result.status ?? undefined,
|
|
1292
|
-
tools: availableTools
|
|
1360
|
+
tools: availableTools,
|
|
1361
|
+
completionId: result.id,
|
|
1362
|
+
providerMetadata: buildProviderMetadata({
|
|
1363
|
+
requestId: extractRequestId(result)
|
|
1364
|
+
})
|
|
1293
1365
|
});
|
|
1294
1366
|
}
|
|
1295
1367
|
return result;
|
|
@@ -1347,7 +1419,11 @@ let WrappedResponses$1 = class WrappedResponses extends Responses {
|
|
|
1347
1419
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1348
1420
|
rawUsage: result.usage
|
|
1349
1421
|
},
|
|
1350
|
-
stopReason: result.status ?? undefined
|
|
1422
|
+
stopReason: result.status ?? undefined,
|
|
1423
|
+
completionId: result.id,
|
|
1424
|
+
providerMetadata: buildProviderMetadata({
|
|
1425
|
+
requestId: extractRequestId(result)
|
|
1426
|
+
})
|
|
1351
1427
|
});
|
|
1352
1428
|
return result;
|
|
1353
1429
|
}, async error => {
|
|
@@ -1603,6 +1679,10 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
|
|
|
1603
1679
|
if ('tee' in value) {
|
|
1604
1680
|
const [stream1, stream2] = value.tee();
|
|
1605
1681
|
(async () => {
|
|
1682
|
+
// Hoisted so the catch block can surface whatever was accumulated
|
|
1683
|
+
// from the streamed chunks before the failure.
|
|
1684
|
+
let completionIdFromResponse;
|
|
1685
|
+
let systemFingerprintFromResponse;
|
|
1606
1686
|
try {
|
|
1607
1687
|
const contentBlocks = [];
|
|
1608
1688
|
let accumulatedContent = '';
|
|
@@ -1615,10 +1695,16 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
|
|
|
1615
1695
|
// Map to track in-progress tool calls
|
|
1616
1696
|
const toolCallsInProgress = new Map();
|
|
1617
1697
|
for await (const chunk of stream1) {
|
|
1618
|
-
// Extract model from
|
|
1698
|
+
// Extract model and completion metadata from chunk (Chat Completions chunks carry these fields)
|
|
1619
1699
|
if (!modelFromResponse && chunk.model) {
|
|
1620
1700
|
modelFromResponse = chunk.model;
|
|
1621
1701
|
}
|
|
1702
|
+
if (!completionIdFromResponse && chunk.id) {
|
|
1703
|
+
completionIdFromResponse = chunk.id;
|
|
1704
|
+
}
|
|
1705
|
+
if (!systemFingerprintFromResponse && chunk.system_fingerprint) {
|
|
1706
|
+
systemFingerprintFromResponse = chunk.system_fingerprint;
|
|
1707
|
+
}
|
|
1622
1708
|
const choice = chunk?.choices?.[0];
|
|
1623
1709
|
// Handle text content
|
|
1624
1710
|
const deltaContent = choice?.delta?.content;
|
|
@@ -1715,7 +1801,11 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
|
|
|
1715
1801
|
baseURL: this.baseURL,
|
|
1716
1802
|
modelParameters: getModelParams(body),
|
|
1717
1803
|
httpStatus: 200,
|
|
1718
|
-
usage
|
|
1804
|
+
usage,
|
|
1805
|
+
completionId: completionIdFromResponse,
|
|
1806
|
+
providerMetadata: buildProviderMetadata({
|
|
1807
|
+
systemFingerprint: systemFingerprintFromResponse
|
|
1808
|
+
})
|
|
1719
1809
|
});
|
|
1720
1810
|
} catch (error) {
|
|
1721
1811
|
await captureAiGeneration(this.phClient, {
|
|
@@ -1731,6 +1821,13 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
|
|
|
1731
1821
|
inputTokens: 0,
|
|
1732
1822
|
outputTokens: 0
|
|
1733
1823
|
},
|
|
1824
|
+
// If the stream fails mid-flight, surface whatever completion
|
|
1825
|
+
// metadata the consumed chunks already provided so the error
|
|
1826
|
+
// event can still be correlated to OpenAI's Logs dashboard.
|
|
1827
|
+
completionId: completionIdFromResponse,
|
|
1828
|
+
providerMetadata: buildProviderMetadata({
|
|
1829
|
+
systemFingerprint: systemFingerprintFromResponse
|
|
1830
|
+
}),
|
|
1734
1831
|
error: error
|
|
1735
1832
|
});
|
|
1736
1833
|
throw error;
|
|
@@ -1760,7 +1857,12 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
|
|
|
1760
1857
|
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
1761
1858
|
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
1762
1859
|
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
1763
|
-
}
|
|
1860
|
+
},
|
|
1861
|
+
completionId: result.id,
|
|
1862
|
+
providerMetadata: buildProviderMetadata({
|
|
1863
|
+
systemFingerprint: result.system_fingerprint,
|
|
1864
|
+
requestId: extractRequestId(result)
|
|
1865
|
+
})
|
|
1764
1866
|
});
|
|
1765
1867
|
}
|
|
1766
1868
|
return result;
|
|
@@ -1807,6 +1909,9 @@ class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1807
1909
|
if ('tee' in value && typeof value.tee === 'function') {
|
|
1808
1910
|
const [stream1, stream2] = value.tee();
|
|
1809
1911
|
(async () => {
|
|
1912
|
+
// Hoisted so the catch block can surface the completion ID that
|
|
1913
|
+
// was accumulated from the streamed chunks before the failure.
|
|
1914
|
+
let completionIdFromResponse;
|
|
1810
1915
|
try {
|
|
1811
1916
|
let finalContent = [];
|
|
1812
1917
|
let modelFromResponse;
|
|
@@ -1821,10 +1926,13 @@ class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1821
1926
|
firstTokenTime = Date.now();
|
|
1822
1927
|
}
|
|
1823
1928
|
if ('response' in chunk && chunk.response) {
|
|
1824
|
-
// Extract model from response
|
|
1929
|
+
// Extract model and completion ID from the response object in the chunk (for stored prompts)
|
|
1825
1930
|
if (!modelFromResponse && chunk.response.model) {
|
|
1826
1931
|
modelFromResponse = chunk.response.model;
|
|
1827
1932
|
}
|
|
1933
|
+
if (!completionIdFromResponse && chunk.response.id) {
|
|
1934
|
+
completionIdFromResponse = chunk.response.id;
|
|
1935
|
+
}
|
|
1828
1936
|
}
|
|
1829
1937
|
if (chunk.type === 'response.completed' && 'response' in chunk && chunk.response?.output && chunk.response.output.length > 0) {
|
|
1830
1938
|
finalContent = chunk.response.output;
|
|
@@ -1851,7 +1959,8 @@ class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1851
1959
|
baseURL: this.baseURL,
|
|
1852
1960
|
modelParameters: getModelParams(body),
|
|
1853
1961
|
httpStatus: 200,
|
|
1854
|
-
usage
|
|
1962
|
+
usage,
|
|
1963
|
+
completionId: completionIdFromResponse
|
|
1855
1964
|
});
|
|
1856
1965
|
} catch (error) {
|
|
1857
1966
|
await captureAiGeneration(this.phClient, {
|
|
@@ -1867,6 +1976,9 @@ class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1867
1976
|
inputTokens: 0,
|
|
1868
1977
|
outputTokens: 0
|
|
1869
1978
|
},
|
|
1979
|
+
// Surface the completion ID from any chunks consumed before
|
|
1980
|
+
// the stream failed so the error event remains correlatable.
|
|
1981
|
+
completionId: completionIdFromResponse,
|
|
1870
1982
|
error: error
|
|
1871
1983
|
});
|
|
1872
1984
|
throw error;
|
|
@@ -1895,7 +2007,11 @@ class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1895
2007
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1896
2008
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1897
2009
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1898
|
-
}
|
|
2010
|
+
},
|
|
2011
|
+
completionId: result.id,
|
|
2012
|
+
providerMetadata: buildProviderMetadata({
|
|
2013
|
+
requestId: extractRequestId(result)
|
|
2014
|
+
})
|
|
1899
2015
|
});
|
|
1900
2016
|
}
|
|
1901
2017
|
return result;
|
|
@@ -1946,7 +2062,11 @@ class WrappedResponses extends AzureOpenAI.Responses {
|
|
|
1946
2062
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1947
2063
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1948
2064
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1949
|
-
}
|
|
2065
|
+
},
|
|
2066
|
+
completionId: result.id,
|
|
2067
|
+
providerMetadata: buildProviderMetadata({
|
|
2068
|
+
requestId: extractRequestId(result)
|
|
2069
|
+
})
|
|
1950
2070
|
});
|
|
1951
2071
|
return result;
|
|
1952
2072
|
}, async error => {
|