@posthog/ai 4.2.1 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/lib/anthropic/index.cjs.js +84 -84
- package/lib/anthropic/index.cjs.js.map +1 -1
- package/lib/anthropic/index.d.ts +1 -1
- package/lib/anthropic/index.esm.js +84 -84
- package/lib/anthropic/index.esm.js.map +1 -1
- package/lib/index.cjs.js +127 -115
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.esm.js +127 -115
- package/lib/index.esm.js.map +1 -1
- package/lib/langchain/index.cjs.js.map +1 -1
- package/lib/langchain/index.esm.js.map +1 -1
- package/lib/openai/index.cjs.js +84 -84
- package/lib/openai/index.cjs.js.map +1 -1
- package/lib/openai/index.d.ts +1 -1
- package/lib/openai/index.esm.js +84 -84
- package/lib/openai/index.esm.js.map +1 -1
- package/lib/posthog-ai/src/utils.d.ts +3 -3
- package/lib/posthog-ai/src/vercel/middleware.d.ts +2 -2
- package/lib/vercel/index.cjs.js +82 -85
- package/lib/vercel/index.cjs.js.map +1 -1
- package/lib/vercel/index.d.ts +1 -1
- package/lib/vercel/index.esm.js +82 -85
- package/lib/vercel/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/anthropic/index.ts +11 -6
- package/src/openai/azure.ts +11 -6
- package/src/openai/index.ts +11 -6
- package/src/utils.ts +63 -74
- package/src/vercel/middleware.ts +15 -13
- package/tests/openai.test.ts +65 -2
- package/tsconfig.json +1 -1
package/lib/openai/index.cjs.js
CHANGED
|
@@ -53,7 +53,7 @@ function sanitizeValues(obj) {
|
|
|
53
53
|
}
|
|
54
54
|
return jsonSafe;
|
|
55
55
|
}
|
|
56
|
-
const sendEventToPosthog = ({
|
|
56
|
+
const sendEventToPosthog = async ({
|
|
57
57
|
client,
|
|
58
58
|
distinctId,
|
|
59
59
|
traceId,
|
|
@@ -69,82 +69,77 @@ const sendEventToPosthog = ({
|
|
|
69
69
|
isError = false,
|
|
70
70
|
error,
|
|
71
71
|
tools,
|
|
72
|
-
|
|
72
|
+
captureImmediate = false
|
|
73
73
|
}) => {
|
|
74
|
-
if (client.capture) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
let costOverrideData = {};
|
|
87
|
-
if (params.posthogCostOverride) {
|
|
88
|
-
const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
|
|
89
|
-
const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
|
|
90
|
-
costOverrideData = {
|
|
91
|
-
$ai_input_cost_usd: inputCostUSD,
|
|
92
|
-
$ai_output_cost_usd: outputCostUSD,
|
|
93
|
-
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
const additionalTokenValues = {
|
|
97
|
-
...(usage.reasoningTokens ? {
|
|
98
|
-
$ai_reasoning_tokens: usage.reasoningTokens
|
|
99
|
-
} : {}),
|
|
100
|
-
...(usage.cacheReadInputTokens ? {
|
|
101
|
-
$ai_cache_read_input_tokens: usage.cacheReadInputTokens
|
|
102
|
-
} : {}),
|
|
103
|
-
...(usage.cacheCreationInputTokens ? {
|
|
104
|
-
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
105
|
-
} : {})
|
|
74
|
+
if (!client.capture) {
|
|
75
|
+
return Promise.resolve();
|
|
76
|
+
}
|
|
77
|
+
// sanitize input and output for UTF-8 validity
|
|
78
|
+
const safeInput = sanitizeValues(input);
|
|
79
|
+
const safeOutput = sanitizeValues(output);
|
|
80
|
+
const safeError = sanitizeValues(error);
|
|
81
|
+
let errorData = {};
|
|
82
|
+
if (isError) {
|
|
83
|
+
errorData = {
|
|
84
|
+
$ai_is_error: true,
|
|
85
|
+
$ai_error: safeError
|
|
106
86
|
};
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
$
|
|
114
|
-
$
|
|
115
|
-
$
|
|
116
|
-
...additionalTokenValues,
|
|
117
|
-
$ai_latency: latency,
|
|
118
|
-
$ai_trace_id: traceId,
|
|
119
|
-
$ai_base_url: baseURL,
|
|
120
|
-
...params.posthogProperties,
|
|
121
|
-
...(distinctId ? {} : {
|
|
122
|
-
$process_person_profile: false
|
|
123
|
-
}),
|
|
124
|
-
...(tools ? {
|
|
125
|
-
$ai_tools: tools
|
|
126
|
-
} : {}),
|
|
127
|
-
...errorData,
|
|
128
|
-
...costOverrideData
|
|
87
|
+
}
|
|
88
|
+
let costOverrideData = {};
|
|
89
|
+
if (params.posthogCostOverride) {
|
|
90
|
+
const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
|
|
91
|
+
const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
|
|
92
|
+
costOverrideData = {
|
|
93
|
+
$ai_input_cost_usd: inputCostUSD,
|
|
94
|
+
$ai_output_cost_usd: outputCostUSD,
|
|
95
|
+
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
129
96
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
97
|
+
}
|
|
98
|
+
const additionalTokenValues = {
|
|
99
|
+
...(usage.reasoningTokens ? {
|
|
100
|
+
$ai_reasoning_tokens: usage.reasoningTokens
|
|
101
|
+
} : {}),
|
|
102
|
+
...(usage.cacheReadInputTokens ? {
|
|
103
|
+
$ai_cache_read_input_tokens: usage.cacheReadInputTokens
|
|
104
|
+
} : {}),
|
|
105
|
+
...(usage.cacheCreationInputTokens ? {
|
|
106
|
+
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
107
|
+
} : {})
|
|
108
|
+
};
|
|
109
|
+
const properties = {
|
|
110
|
+
$ai_provider: params.posthogProviderOverride ?? provider,
|
|
111
|
+
$ai_model: params.posthogModelOverride ?? model,
|
|
112
|
+
$ai_model_parameters: getModelParams(params),
|
|
113
|
+
$ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),
|
|
114
|
+
$ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),
|
|
115
|
+
$ai_http_status: httpStatus,
|
|
116
|
+
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
117
|
+
$ai_output_tokens: usage.outputTokens ?? 0,
|
|
118
|
+
...additionalTokenValues,
|
|
119
|
+
$ai_latency: latency,
|
|
120
|
+
$ai_trace_id: traceId,
|
|
121
|
+
$ai_base_url: baseURL,
|
|
122
|
+
...params.posthogProperties,
|
|
123
|
+
...(distinctId ? {} : {
|
|
124
|
+
$process_person_profile: false
|
|
125
|
+
}),
|
|
126
|
+
...(tools ? {
|
|
127
|
+
$ai_tools: tools
|
|
128
|
+
} : {}),
|
|
129
|
+
...errorData,
|
|
130
|
+
...costOverrideData
|
|
131
|
+
};
|
|
132
|
+
const event = {
|
|
133
|
+
distinctId: distinctId ?? traceId,
|
|
134
|
+
event: '$ai_generation',
|
|
135
|
+
properties,
|
|
136
|
+
groups: params.posthogGroups
|
|
137
|
+
};
|
|
138
|
+
if (captureImmediate) {
|
|
139
|
+
// await capture promise to send single event in serverless environments
|
|
140
|
+
await client.captureImmediate(event);
|
|
141
|
+
} else {
|
|
142
|
+
client.capture(event);
|
|
148
143
|
}
|
|
149
144
|
};
|
|
150
145
|
|
|
@@ -186,6 +181,7 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
186
181
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
187
182
|
posthogPrivacyMode = false,
|
|
188
183
|
posthogGroups,
|
|
184
|
+
posthogCaptureImmediate,
|
|
189
185
|
...openAIParams
|
|
190
186
|
} = body;
|
|
191
187
|
const traceId = posthogTraceId ?? uuid.v4();
|
|
@@ -215,7 +211,7 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
215
211
|
}
|
|
216
212
|
}
|
|
217
213
|
const latency = (Date.now() - startTime) / 1000;
|
|
218
|
-
sendEventToPosthog({
|
|
214
|
+
await sendEventToPosthog({
|
|
219
215
|
client: this.phClient,
|
|
220
216
|
distinctId: posthogDistinctId ?? traceId,
|
|
221
217
|
traceId,
|
|
@@ -230,10 +226,11 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
230
226
|
baseURL: this.baseURL ?? '',
|
|
231
227
|
params: body,
|
|
232
228
|
httpStatus: 200,
|
|
233
|
-
usage
|
|
229
|
+
usage,
|
|
230
|
+
captureImmediate: posthogCaptureImmediate
|
|
234
231
|
});
|
|
235
232
|
} catch (error) {
|
|
236
|
-
sendEventToPosthog({
|
|
233
|
+
await sendEventToPosthog({
|
|
237
234
|
client: this.phClient,
|
|
238
235
|
distinctId: posthogDistinctId ?? traceId,
|
|
239
236
|
traceId,
|
|
@@ -250,7 +247,8 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
250
247
|
outputTokens: 0
|
|
251
248
|
},
|
|
252
249
|
isError: true,
|
|
253
|
-
error: JSON.stringify(error)
|
|
250
|
+
error: JSON.stringify(error),
|
|
251
|
+
captureImmediate: posthogCaptureImmediate
|
|
254
252
|
});
|
|
255
253
|
}
|
|
256
254
|
})();
|
|
@@ -261,10 +259,10 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
261
259
|
return value;
|
|
262
260
|
});
|
|
263
261
|
} else {
|
|
264
|
-
const wrappedPromise = parentPromise.then(result => {
|
|
262
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
265
263
|
if ('choices' in result) {
|
|
266
264
|
const latency = (Date.now() - startTime) / 1000;
|
|
267
|
-
sendEventToPosthog({
|
|
265
|
+
await sendEventToPosthog({
|
|
268
266
|
client: this.phClient,
|
|
269
267
|
distinctId: posthogDistinctId ?? traceId,
|
|
270
268
|
traceId,
|
|
@@ -281,12 +279,13 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
281
279
|
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
282
280
|
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
283
281
|
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
284
|
-
}
|
|
282
|
+
},
|
|
283
|
+
captureImmediate: posthogCaptureImmediate
|
|
285
284
|
});
|
|
286
285
|
}
|
|
287
286
|
return result;
|
|
288
|
-
}, error => {
|
|
289
|
-
sendEventToPosthog({
|
|
287
|
+
}, async error => {
|
|
288
|
+
await sendEventToPosthog({
|
|
290
289
|
client: this.phClient,
|
|
291
290
|
distinctId: posthogDistinctId ?? traceId,
|
|
292
291
|
traceId,
|
|
@@ -303,7 +302,8 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
303
302
|
outputTokens: 0
|
|
304
303
|
},
|
|
305
304
|
isError: true,
|
|
306
|
-
error: JSON.stringify(error)
|
|
305
|
+
error: JSON.stringify(error),
|
|
306
|
+
captureImmediate: posthogCaptureImmediate
|
|
307
307
|
});
|
|
308
308
|
throw error;
|
|
309
309
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../src/utils.ts","../../src/openai/index.ts"],"sourcesContent":["import { PostHog } from 'posthog-node'\nimport { Buffer } from 'buffer'\nimport OpenAIOrignal from 'openai'\nimport AnthropicOriginal from '@anthropic-ai/sdk'\n\ntype ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams\ntype MessageCreateParams = AnthropicOriginal.Messages.MessageCreateParams\n\n// limit large outputs by truncating to 200kb (approx 200k bytes)\nexport const MAX_OUTPUT_SIZE = 200000\nconst STRING_FORMAT = 'utf8'\n\nexport interface MonitoringParams {\n posthogDistinctId?: string\n posthogTraceId?: string\n posthogProperties?: Record<string, any>\n posthogPrivacyMode?: boolean\n posthogGroups?: Record<string, any>\n posthogModelOverride?: string\n posthogProviderOverride?: string\n posthogCostOverride?: CostOverride\n fullDebug?: boolean\n}\n\nexport interface CostOverride {\n inputCost: number\n outputCost: number\n}\n\nexport const getModelParams = (\n params: ((ChatCompletionCreateParamsBase | MessageCreateParams) & MonitoringParams) | null\n): Record<string, any> => {\n if (!params) {\n return {}\n }\n const modelParams: Record<string, any> = {}\n const paramKeys = [\n 'temperature',\n 'max_tokens',\n 'max_completion_tokens',\n 'top_p',\n 'frequency_penalty',\n 'presence_penalty',\n 'n',\n 'stop',\n 'stream',\n 'streaming',\n ] as const\n\n for (const key of paramKeys) {\n if (key in params && (params as any)[key] !== undefined) {\n modelParams[key] = (params as any)[key]\n }\n }\n return modelParams\n}\n\n/**\n * Helper to format responses (non-streaming) for consumption, mirroring Python's openai vs. anthropic approach.\n */\nexport const formatResponse = (response: any, provider: string): Array<{ role: string; content: string }> => {\n if (!response) {\n return []\n }\n if (provider === 'anthropic') {\n return formatResponseAnthropic(response)\n } else if (provider === 'openai') {\n return formatResponseOpenAI(response)\n }\n return []\n}\n\nexport const formatResponseAnthropic = (response: any): Array<{ role: string; content: string }> => {\n // Example approach if \"response.content\" holds array of text segments, etc.\n const output: Array<{ role: string; content: string }> = []\n for (const choice of response.content ?? []) {\n if (choice?.text) {\n output.push({\n role: 'assistant',\n content: choice.text,\n })\n }\n }\n return output\n}\n\nexport const formatResponseOpenAI = (response: any): Array<{ role: string; content: string }> => {\n const output: Array<{ role: string; content: string }> = []\n for (const choice of response.choices ?? []) {\n if (choice.message?.content) {\n output.push({\n role: choice.message.role,\n content: choice.message.content,\n })\n }\n }\n return output\n}\n\nexport const mergeSystemPrompt = (params: MessageCreateParams & MonitoringParams, provider: string): any => {\n if (provider == 'anthropic') {\n const messages = params.messages || []\n if (!(params as any).system) {\n return messages\n }\n const systemMessage = (params as any).system\n return [{ role: 'system', content: systemMessage }, ...messages]\n }\n return params.messages\n}\n\nexport const withPrivacyMode = (client: PostHog, privacyMode: boolean, input: any): any => {\n return (client as any).privacy_mode || privacyMode ? null : input\n}\n\nexport const truncate = (str: string): string => {\n try {\n const buffer = Buffer.from(str, STRING_FORMAT)\n if (buffer.length <= MAX_OUTPUT_SIZE) {\n return str\n }\n const truncatedBuffer = buffer.slice(0, MAX_OUTPUT_SIZE)\n return `${truncatedBuffer.toString(STRING_FORMAT)}... [truncated]`\n } catch (error) {\n console.error('Error truncating, likely not a string')\n return str\n }\n}\n\nexport type SendEventToPosthogParams = {\n client: PostHog\n distinctId?: string\n traceId: string\n model: string\n provider: string\n input: any\n output: any\n latency: number\n baseURL: string\n httpStatus: number\n usage?: {\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: any\n cacheReadInputTokens?: any\n cacheCreationInputTokens?: any\n }\n params: (ChatCompletionCreateParamsBase | MessageCreateParams) & MonitoringParams\n isError?: boolean\n error?: string\n tools?: any\n fullDebug?: boolean\n}\n\nfunction sanitizeValues(obj: any): any {\n if (obj === undefined || obj === null) {\n return obj\n }\n const jsonSafe = JSON.parse(JSON.stringify(obj))\n if (typeof jsonSafe === 'string') {\n return Buffer.from(jsonSafe, STRING_FORMAT).toString(STRING_FORMAT)\n } else if (Array.isArray(jsonSafe)) {\n return jsonSafe.map(sanitizeValues)\n } else if (jsonSafe && typeof jsonSafe === 'object') {\n return Object.fromEntries(Object.entries(jsonSafe).map(([k, v]) => [k, sanitizeValues(v)]))\n }\n return jsonSafe\n}\n\nexport const sendEventToPosthog = ({\n client,\n distinctId,\n traceId,\n model,\n provider,\n input,\n output,\n latency,\n baseURL,\n params,\n httpStatus = 200,\n usage = {},\n isError = false,\n error,\n tools,\n fullDebug = false,\n}: SendEventToPosthogParams): void => {\n if (client.capture) {\n // sanitize input and output for UTF-8 validity\n const safeInput = sanitizeValues(input)\n const safeOutput = sanitizeValues(output)\n const safeError = sanitizeValues(error)\n\n let errorData = {}\n if (isError) {\n errorData = {\n $ai_is_error: true,\n $ai_error: safeError,\n }\n }\n let costOverrideData = {}\n if (params.posthogCostOverride) {\n const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0)\n const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0)\n costOverrideData = {\n $ai_input_cost_usd: inputCostUSD,\n $ai_output_cost_usd: outputCostUSD,\n $ai_total_cost_usd: inputCostUSD + outputCostUSD,\n }\n }\n\n const additionalTokenValues = {\n ...(usage.reasoningTokens ? { $ai_reasoning_tokens: usage.reasoningTokens } : {}),\n ...(usage.cacheReadInputTokens ? { $ai_cache_read_input_tokens: usage.cacheReadInputTokens } : {}),\n ...(usage.cacheCreationInputTokens ? { $ai_cache_creation_input_tokens: usage.cacheCreationInputTokens } : {}),\n }\n\n const properties = {\n $ai_provider: params.posthogProviderOverride ?? provider,\n $ai_model: params.posthogModelOverride ?? model,\n $ai_model_parameters: getModelParams(params),\n $ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),\n $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),\n $ai_http_status: httpStatus,\n $ai_input_tokens: usage.inputTokens ?? 0,\n $ai_output_tokens: usage.outputTokens ?? 0,\n ...additionalTokenValues,\n $ai_latency: latency,\n $ai_trace_id: traceId,\n $ai_base_url: baseURL,\n ...params.posthogProperties,\n ...(distinctId ? {} : { $process_person_profile: false }),\n ...(tools ? { $ai_tools: tools } : {}),\n ...errorData,\n ...costOverrideData,\n }\n\n if (fullDebug) {\n // @ts-ignore\n console.log('Sending event to PostHog', JSON.stringify(properties))\n try {\n // @ts-ignore\n console.log(\n 'Size of properties (kb)',\n Math.round((Buffer.byteLength(JSON.stringify(properties), STRING_FORMAT) / 1024) * 10000) / 10000\n )\n // @ts-ignore\n console.log(\n 'Size of properties (mb)',\n Math.round((Buffer.byteLength(JSON.stringify(properties), STRING_FORMAT) / 1024 / 1024) * 10000) / 10000\n )\n } catch (error) {\n console.error('Error printing size of properties', error)\n }\n }\n\n client.capture({\n distinctId: distinctId ?? traceId,\n event: '$ai_generation',\n properties,\n groups: params.posthogGroups,\n })\n }\n}\n","import OpenAIOrignal, { ClientOptions } from 'openai'\nimport { PostHog } from 'posthog-node'\nimport { v4 as uuidv4 } from 'uuid'\nimport { formatResponseOpenAI, MonitoringParams, sendEventToPosthog } from '../utils'\n\ntype ChatCompletion = OpenAIOrignal.ChatCompletion\ntype ChatCompletionChunk = OpenAIOrignal.ChatCompletionChunk\ntype ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams\ntype ChatCompletionCreateParamsNonStreaming = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParamsNonStreaming\ntype ChatCompletionCreateParamsStreaming = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParamsStreaming\nimport type { APIPromise, RequestOptions } from 'openai/core'\nimport type { Stream } from 'openai/streaming'\n\ninterface MonitoringOpenAIConfig extends ClientOptions {\n apiKey: string\n posthog: PostHog\n baseURL?: string\n}\n\nexport class PostHogOpenAI extends OpenAIOrignal {\n private readonly phClient: PostHog\n public chat: WrappedChat\n\n constructor(config: MonitoringOpenAIConfig) {\n const { posthog, ...openAIConfig } = config\n super(openAIConfig)\n this.phClient = posthog\n this.chat = new WrappedChat(this, this.phClient)\n }\n}\n\nexport class WrappedChat extends OpenAIOrignal.Chat {\n constructor(parentClient: PostHogOpenAI, phClient: PostHog) {\n super(parentClient)\n this.completions = new WrappedCompletions(parentClient, phClient)\n }\n\n public completions: WrappedCompletions\n}\n\nexport class WrappedCompletions extends OpenAIOrignal.Chat.Completions {\n private readonly phClient: PostHog\n\n constructor(client: OpenAIOrignal, phClient: PostHog) {\n super(client)\n this.phClient = phClient\n }\n\n // --- Overload #1: Non-streaming\n public create(\n body: ChatCompletionCreateParamsNonStreaming & MonitoringParams,\n options?: RequestOptions\n ): APIPromise<ChatCompletion>\n\n // --- Overload #2: Streaming\n public create(\n body: ChatCompletionCreateParamsStreaming & MonitoringParams,\n options?: RequestOptions\n ): APIPromise<Stream<ChatCompletionChunk>>\n\n // --- Overload #3: Generic base\n public create(\n body: ChatCompletionCreateParamsBase & MonitoringParams,\n options?: RequestOptions\n ): APIPromise<ChatCompletion | Stream<ChatCompletionChunk>>\n\n // --- Implementation Signature\n public create(\n body: ChatCompletionCreateParamsBase & MonitoringParams,\n options?: RequestOptions\n ): APIPromise<ChatCompletion | Stream<ChatCompletionChunk>> {\n const {\n posthogDistinctId,\n posthogTraceId,\n posthogProperties,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n posthogPrivacyMode = false,\n posthogGroups,\n ...openAIParams\n } = body\n\n const traceId = posthogTraceId ?? uuidv4()\n const startTime = Date.now()\n\n const parentPromise = super.create(openAIParams, options)\n\n if (openAIParams.stream) {\n return parentPromise.then((value) => {\n if ('tee' in value) {\n const [stream1, stream2] = value.tee()\n ;(async () => {\n try {\n let accumulatedContent = ''\n let usage: {\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: number\n cacheReadInputTokens?: number\n } = {\n inputTokens: 0,\n outputTokens: 0,\n }\n\n for await (const chunk of stream1) {\n const delta = chunk?.choices?.[0]?.delta?.content ?? ''\n accumulatedContent += delta\n if (chunk.usage) {\n usage = {\n inputTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,\n cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n }\n }\n\n const latency = (Date.now() - startTime) / 1000\n sendEventToPosthog({\n client: this.phClient,\n distinctId: posthogDistinctId ?? traceId,\n traceId,\n model: openAIParams.model,\n provider: 'openai',\n input: openAIParams.messages,\n output: [{ content: accumulatedContent, role: 'assistant' }],\n latency,\n baseURL: (this as any).baseURL ?? '',\n params: body,\n httpStatus: 200,\n usage,\n })\n } catch (error: any) {\n sendEventToPosthog({\n client: this.phClient,\n distinctId: posthogDistinctId ?? traceId,\n traceId,\n model: openAIParams.model,\n provider: 'openai',\n input: openAIParams.messages,\n output: [],\n latency: 0,\n baseURL: (this as any).baseURL ?? '',\n params: body,\n httpStatus: error?.status ? error.status : 500,\n usage: { inputTokens: 0, outputTokens: 0 },\n isError: true,\n error: JSON.stringify(error),\n })\n }\n })()\n\n // Return the other stream to the user\n return stream2\n }\n return value\n }) as APIPromise<Stream<ChatCompletionChunk>>\n } else {\n const wrappedPromise = parentPromise.then(\n (result) => {\n if ('choices' in result) {\n const latency = (Date.now() - startTime) / 1000\n sendEventToPosthog({\n client: this.phClient,\n distinctId: posthogDistinctId ?? traceId,\n traceId,\n model: openAIParams.model,\n provider: 'openai',\n input: openAIParams.messages,\n output: formatResponseOpenAI(result),\n latency,\n baseURL: (this as any).baseURL ?? '',\n params: body,\n httpStatus: 200,\n usage: {\n inputTokens: result.usage?.prompt_tokens ?? 0,\n outputTokens: result.usage?.completion_tokens ?? 0,\n reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,\n cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0,\n },\n })\n }\n return result\n },\n (error: any) => {\n sendEventToPosthog({\n client: this.phClient,\n distinctId: posthogDistinctId ?? traceId,\n traceId,\n model: openAIParams.model,\n provider: 'openai',\n input: openAIParams.messages,\n output: [],\n latency: 0,\n baseURL: (this as any).baseURL ?? '',\n params: body,\n httpStatus: error?.status ? error.status : 500,\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n isError: true,\n error: JSON.stringify(error),\n })\n throw error\n }\n ) as APIPromise<ChatCompletion>\n\n return wrappedPromise\n }\n }\n}\n\nexport default PostHogOpenAI\n\nexport { PostHogOpenAI as OpenAI }\n"],"names":["STRING_FORMAT","getModelParams","params","modelParams","paramKeys","key","undefined","formatResponseOpenAI","response","output","choice","choices","message","content","push","role","withPrivacyMode","client","privacyMode","input","privacy_mode","sanitizeValues","obj","jsonSafe","JSON","parse","stringify","Buffer","from","toString","Array","isArray","map","Object","fromEntries","entries","k","v","sendEventToPosthog","distinctId","traceId","model","provider","latency","baseURL","httpStatus","usage","isError","error","tools","fullDebug","capture","safeInput","safeOutput","safeError","errorData","$ai_is_error","$ai_error","costOverrideData","posthogCostOverride","inputCostUSD","inputCost","inputTokens","outputCostUSD","outputCost","outputTokens","$ai_input_cost_usd","$ai_output_cost_usd","$ai_total_cost_usd","additionalTokenValues","reasoningTokens","$ai_reasoning_tokens","cacheReadInputTokens","$ai_cache_read_input_tokens","cacheCreationInputTokens","$ai_cache_creation_input_tokens","properties","$ai_provider","posthogProviderOverride","$ai_model","posthogModelOverride","$ai_model_parameters","$ai_input","posthogPrivacyMode","$ai_output_choices","$ai_http_status","$ai_input_tokens","$ai_output_tokens","$ai_latency","$ai_trace_id","$ai_base_url","posthogProperties","$process_person_profile","$ai_tools","console","log","Math","round","byteLength","event","groups","posthogGroups","PostHogOpenAI","OpenAIOrignal","constructor","config","posthog","openAIConfig","phClient","chat","WrappedChat","Chat","parentClient","completions","WrappedCompletions","Completions","create","body","options","posthogDistinctId","posthogTraceId","openAIParams","uuidv4","startTime","Date","now","parentPromise","stream","then","value","stream1","stream2","tee","accumulatedContent","chunk","delta","prompt_tokens","completion_tokens","completion_tokens_details","reasoning_tokens","prompt_tokens_details","cached_tokens","messages","status","wrappedPromise","result"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../src/utils.ts","../../src/openai/index.ts"],"sourcesContent":["import { PostHog } from 'posthog-node'\nimport { Buffer } from 'buffer'\nimport OpenAIOrignal from 'openai'\nimport AnthropicOriginal from '@anthropic-ai/sdk'\n\ntype ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams\ntype MessageCreateParams = AnthropicOriginal.Messages.MessageCreateParams\n\n// limit large outputs by truncating to 200kb (approx 200k bytes)\nexport const MAX_OUTPUT_SIZE = 200000\nconst STRING_FORMAT = 'utf8'\n\nexport interface MonitoringParams {\n posthogDistinctId?: string\n posthogTraceId?: string\n posthogProperties?: Record<string, any>\n posthogPrivacyMode?: boolean\n posthogGroups?: Record<string, any>\n posthogModelOverride?: string\n posthogProviderOverride?: string\n posthogCostOverride?: CostOverride\n posthogCaptureImmediate?: boolean\n}\n\nexport interface CostOverride {\n inputCost: number\n outputCost: number\n}\n\nexport const getModelParams = (\n params: ((ChatCompletionCreateParamsBase | MessageCreateParams) & MonitoringParams) | null\n): Record<string, any> => {\n if (!params) {\n return {}\n }\n const modelParams: Record<string, any> = {}\n const paramKeys = [\n 'temperature',\n 'max_tokens',\n 'max_completion_tokens',\n 'top_p',\n 'frequency_penalty',\n 'presence_penalty',\n 'n',\n 'stop',\n 'stream',\n 'streaming',\n ] as const\n\n for (const key of paramKeys) {\n if (key in params && (params as any)[key] !== undefined) {\n modelParams[key] = (params as any)[key]\n }\n }\n return modelParams\n}\n\n/**\n * Helper to format responses (non-streaming) for consumption, mirroring Python's openai vs. anthropic approach.\n */\nexport const formatResponse = (response: any, provider: string): Array<{ role: string; content: string }> => {\n if (!response) {\n return []\n }\n if (provider === 'anthropic') {\n return formatResponseAnthropic(response)\n } else if (provider === 'openai') {\n return formatResponseOpenAI(response)\n }\n return []\n}\n\nexport const formatResponseAnthropic = (response: any): Array<{ role: string; content: string }> => {\n // Example approach if \"response.content\" holds array of text segments, etc.\n const output: Array<{ role: string; content: string }> = []\n for (const choice of response.content ?? []) {\n if (choice?.text) {\n output.push({\n role: 'assistant',\n content: choice.text,\n })\n }\n }\n return output\n}\n\nexport const formatResponseOpenAI = (response: any): Array<{ role: string; content: string }> => {\n const output: Array<{ role: string; content: string }> = []\n for (const choice of response.choices ?? []) {\n if (choice.message?.content) {\n output.push({\n role: choice.message.role,\n content: choice.message.content,\n })\n }\n }\n return output\n}\n\nexport const mergeSystemPrompt = (params: MessageCreateParams & MonitoringParams, provider: string): any => {\n if (provider == 'anthropic') {\n const messages = params.messages || []\n if (!(params as any).system) {\n return messages\n }\n const systemMessage = (params as any).system\n return [{ role: 'system', content: systemMessage }, ...messages]\n }\n return params.messages\n}\n\nexport const withPrivacyMode = (client: PostHog, privacyMode: boolean, input: any): any => {\n return (client as any).privacy_mode || privacyMode ? null : input\n}\n\nexport const truncate = (str: string): string => {\n try {\n const buffer = Buffer.from(str, STRING_FORMAT)\n if (buffer.length <= MAX_OUTPUT_SIZE) {\n return str\n }\n const truncatedBuffer = buffer.slice(0, MAX_OUTPUT_SIZE)\n return `${truncatedBuffer.toString(STRING_FORMAT)}... [truncated]`\n } catch (error) {\n console.error('Error truncating, likely not a string')\n return str\n }\n}\n\nexport type SendEventToPosthogParams = {\n client: PostHog\n distinctId?: string\n traceId: string\n model: string\n provider: string\n input: any\n output: any\n latency: number\n baseURL: string\n httpStatus: number\n usage?: {\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: any\n cacheReadInputTokens?: any\n cacheCreationInputTokens?: any\n }\n params: (ChatCompletionCreateParamsBase | MessageCreateParams) & MonitoringParams\n isError?: boolean\n error?: string\n tools?: any\n captureImmediate?: boolean\n}\n\nfunction sanitizeValues(obj: any): any {\n if (obj === undefined || obj === null) {\n return obj\n }\n const jsonSafe = JSON.parse(JSON.stringify(obj))\n if (typeof jsonSafe === 'string') {\n return Buffer.from(jsonSafe, STRING_FORMAT).toString(STRING_FORMAT)\n } else if (Array.isArray(jsonSafe)) {\n return jsonSafe.map(sanitizeValues)\n } else if (jsonSafe && typeof jsonSafe === 'object') {\n return Object.fromEntries(Object.entries(jsonSafe).map(([k, v]) => [k, sanitizeValues(v)]))\n }\n return jsonSafe\n}\n\nexport const sendEventToPosthog = async ({\n client,\n distinctId,\n traceId,\n model,\n provider,\n input,\n output,\n latency,\n baseURL,\n params,\n httpStatus = 200,\n usage = {},\n isError = false,\n error,\n tools,\n captureImmediate = false,\n}: SendEventToPosthogParams): Promise<void> => {\n if (!client.capture) {\n return Promise.resolve()\n }\n // sanitize input and output for UTF-8 validity\n const safeInput = sanitizeValues(input)\n const safeOutput = sanitizeValues(output)\n const safeError = sanitizeValues(error)\n\n let errorData = {}\n if (isError) {\n errorData = {\n $ai_is_error: true,\n $ai_error: safeError,\n }\n }\n let costOverrideData = {}\n if (params.posthogCostOverride) {\n const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0)\n const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0)\n costOverrideData = {\n $ai_input_cost_usd: inputCostUSD,\n $ai_output_cost_usd: outputCostUSD,\n $ai_total_cost_usd: inputCostUSD + outputCostUSD,\n }\n }\n\n const additionalTokenValues = {\n ...(usage.reasoningTokens ? { $ai_reasoning_tokens: usage.reasoningTokens } : {}),\n ...(usage.cacheReadInputTokens ? { $ai_cache_read_input_tokens: usage.cacheReadInputTokens } : {}),\n ...(usage.cacheCreationInputTokens ? { $ai_cache_creation_input_tokens: usage.cacheCreationInputTokens } : {}),\n }\n\n const properties = {\n $ai_provider: params.posthogProviderOverride ?? provider,\n $ai_model: params.posthogModelOverride ?? model,\n $ai_model_parameters: getModelParams(params),\n $ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),\n $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),\n $ai_http_status: httpStatus,\n $ai_input_tokens: usage.inputTokens ?? 0,\n $ai_output_tokens: usage.outputTokens ?? 0,\n ...additionalTokenValues,\n $ai_latency: latency,\n $ai_trace_id: traceId,\n $ai_base_url: baseURL,\n ...params.posthogProperties,\n ...(distinctId ? {} : { $process_person_profile: false }),\n ...(tools ? { $ai_tools: tools } : {}),\n ...errorData,\n ...costOverrideData,\n }\n\n const event = {\n distinctId: distinctId ?? traceId,\n event: '$ai_generation',\n properties,\n groups: params.posthogGroups,\n }\n\n if (captureImmediate) {\n // await capture promise to send single event in serverless environments\n await client.captureImmediate(event)\n } else {\n client.capture(event)\n }\n}\n","import OpenAIOrignal, { ClientOptions } from 'openai'\nimport { PostHog } from 'posthog-node'\nimport { v4 as uuidv4 } from 'uuid'\nimport { formatResponseOpenAI, MonitoringParams, sendEventToPosthog } from '../utils'\n\ntype ChatCompletion = OpenAIOrignal.ChatCompletion\ntype ChatCompletionChunk = OpenAIOrignal.ChatCompletionChunk\ntype ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams\ntype ChatCompletionCreateParamsNonStreaming = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParamsNonStreaming\ntype ChatCompletionCreateParamsStreaming = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParamsStreaming\nimport type { APIPromise, RequestOptions } from 'openai/core'\nimport type { Stream } from 'openai/streaming'\n\ninterface MonitoringOpenAIConfig extends ClientOptions {\n apiKey: string\n posthog: PostHog\n baseURL?: string\n}\n\nexport class PostHogOpenAI extends OpenAIOrignal {\n private readonly phClient: PostHog\n public chat: WrappedChat\n\n constructor(config: MonitoringOpenAIConfig) {\n const { posthog, ...openAIConfig } = config\n super(openAIConfig)\n this.phClient = posthog\n this.chat = new WrappedChat(this, this.phClient)\n }\n}\n\nexport class WrappedChat extends OpenAIOrignal.Chat {\n constructor(parentClient: PostHogOpenAI, phClient: PostHog) {\n super(parentClient)\n this.completions = new WrappedCompletions(parentClient, phClient)\n }\n\n public completions: WrappedCompletions\n}\n\nexport class WrappedCompletions extends OpenAIOrignal.Chat.Completions {\n private readonly phClient: PostHog\n\n constructor(client: OpenAIOrignal, phClient: PostHog) {\n super(client)\n this.phClient = phClient\n }\n\n // --- Overload #1: Non-streaming\n public create(\n body: ChatCompletionCreateParamsNonStreaming & MonitoringParams,\n options?: RequestOptions\n ): APIPromise<ChatCompletion>\n\n // --- Overload #2: Streaming\n public create(\n body: ChatCompletionCreateParamsStreaming & MonitoringParams,\n options?: RequestOptions\n ): APIPromise<Stream<ChatCompletionChunk>>\n\n // --- Overload #3: Generic base\n public create(\n body: ChatCompletionCreateParamsBase & MonitoringParams,\n options?: RequestOptions\n ): APIPromise<ChatCompletion | Stream<ChatCompletionChunk>>\n\n // --- Implementation Signature\n public create(\n body: ChatCompletionCreateParamsBase & MonitoringParams,\n options?: RequestOptions\n ): APIPromise<ChatCompletion | Stream<ChatCompletionChunk>> {\n const {\n posthogDistinctId,\n posthogTraceId,\n posthogProperties,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n posthogPrivacyMode = false,\n posthogGroups,\n posthogCaptureImmediate,\n ...openAIParams\n } = body\n\n const traceId = posthogTraceId ?? uuidv4()\n const startTime = Date.now()\n\n const parentPromise = super.create(openAIParams, options)\n\n if (openAIParams.stream) {\n return parentPromise.then((value) => {\n if ('tee' in value) {\n const [stream1, stream2] = value.tee()\n ;(async () => {\n try {\n let accumulatedContent = ''\n let usage: {\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: number\n cacheReadInputTokens?: number\n } = {\n inputTokens: 0,\n outputTokens: 0,\n }\n\n for await (const chunk of stream1) {\n const delta = chunk?.choices?.[0]?.delta?.content ?? ''\n accumulatedContent += delta\n if (chunk.usage) {\n usage = {\n inputTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,\n cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n }\n }\n\n const latency = (Date.now() - startTime) / 1000\n await sendEventToPosthog({\n client: this.phClient,\n distinctId: posthogDistinctId ?? traceId,\n traceId,\n model: openAIParams.model,\n provider: 'openai',\n input: openAIParams.messages,\n output: [{ content: accumulatedContent, role: 'assistant' }],\n latency,\n baseURL: (this as any).baseURL ?? '',\n params: body,\n httpStatus: 200,\n usage,\n captureImmediate: posthogCaptureImmediate,\n })\n } catch (error: any) {\n await sendEventToPosthog({\n client: this.phClient,\n distinctId: posthogDistinctId ?? traceId,\n traceId,\n model: openAIParams.model,\n provider: 'openai',\n input: openAIParams.messages,\n output: [],\n latency: 0,\n baseURL: (this as any).baseURL ?? '',\n params: body,\n httpStatus: error?.status ? error.status : 500,\n usage: { inputTokens: 0, outputTokens: 0 },\n isError: true,\n error: JSON.stringify(error),\n captureImmediate: posthogCaptureImmediate,\n })\n }\n })()\n\n // Return the other stream to the user\n return stream2\n }\n return value\n }) as APIPromise<Stream<ChatCompletionChunk>>\n } else {\n const wrappedPromise = parentPromise.then(\n async (result) => {\n if ('choices' in result) {\n const latency = (Date.now() - startTime) / 1000\n await sendEventToPosthog({\n client: this.phClient,\n distinctId: posthogDistinctId ?? traceId,\n traceId,\n model: openAIParams.model,\n provider: 'openai',\n input: openAIParams.messages,\n output: formatResponseOpenAI(result),\n latency,\n baseURL: (this as any).baseURL ?? '',\n params: body,\n httpStatus: 200,\n usage: {\n inputTokens: result.usage?.prompt_tokens ?? 0,\n outputTokens: result.usage?.completion_tokens ?? 0,\n reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,\n cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0,\n },\n captureImmediate: posthogCaptureImmediate,\n })\n }\n return result\n },\n async (error: any) => {\n await sendEventToPosthog({\n client: this.phClient,\n distinctId: posthogDistinctId ?? traceId,\n traceId,\n model: openAIParams.model,\n provider: 'openai',\n input: openAIParams.messages,\n output: [],\n latency: 0,\n baseURL: (this as any).baseURL ?? '',\n params: body,\n httpStatus: error?.status ? error.status : 500,\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n isError: true,\n error: JSON.stringify(error),\n captureImmediate: posthogCaptureImmediate,\n })\n throw error\n }\n ) as APIPromise<ChatCompletion>\n\n return wrappedPromise\n }\n }\n}\n\nexport default PostHogOpenAI\n\nexport { PostHogOpenAI as OpenAI }\n"],"names":["STRING_FORMAT","getModelParams","params","modelParams","paramKeys","key","undefined","formatResponseOpenAI","response","output","choice","choices","message","content","push","role","withPrivacyMode","client","privacyMode","input","privacy_mode","sanitizeValues","obj","jsonSafe","JSON","parse","stringify","Buffer","from","toString","Array","isArray","map","Object","fromEntries","entries","k","v","sendEventToPosthog","distinctId","traceId","model","provider","latency","baseURL","httpStatus","usage","isError","error","tools","captureImmediate","capture","Promise","resolve","safeInput","safeOutput","safeError","errorData","$ai_is_error","$ai_error","costOverrideData","posthogCostOverride","inputCostUSD","inputCost","inputTokens","outputCostUSD","outputCost","outputTokens","$ai_input_cost_usd","$ai_output_cost_usd","$ai_total_cost_usd","additionalTokenValues","reasoningTokens","$ai_reasoning_tokens","cacheReadInputTokens","$ai_cache_read_input_tokens","cacheCreationInputTokens","$ai_cache_creation_input_tokens","properties","$ai_provider","posthogProviderOverride","$ai_model","posthogModelOverride","$ai_model_parameters","$ai_input","posthogPrivacyMode","$ai_output_choices","$ai_http_status","$ai_input_tokens","$ai_output_tokens","$ai_latency","$ai_trace_id","$ai_base_url","posthogProperties","$process_person_profile","$ai_tools","event","groups","posthogGroups","PostHogOpenAI","OpenAIOrignal","constructor","config","posthog","openAIConfig","phClient","chat","WrappedChat","Chat","parentClient","completions","WrappedCompletions","Completions","create","body","options","posthogDistinctId","posthogTraceId","posthogCaptureImmediate","openAIParams","uuidv4","startTime","Date","now","parentPromise","stream","then","value","stream1","stream2","tee","accumulatedContent","chunk","delta","prompt_tokens","completion_tokens","completion_tokens_details","reasoning_tokens","prompt_tokens_details","cached_tokens","messages","status","wrappedPromise","result"],"mappings":"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"}
|
package/lib/openai/index.d.ts
CHANGED
package/lib/openai/index.esm.js
CHANGED
|
@@ -45,7 +45,7 @@ function sanitizeValues(obj) {
|
|
|
45
45
|
}
|
|
46
46
|
return jsonSafe;
|
|
47
47
|
}
|
|
48
|
-
const sendEventToPosthog = ({
|
|
48
|
+
const sendEventToPosthog = async ({
|
|
49
49
|
client,
|
|
50
50
|
distinctId,
|
|
51
51
|
traceId,
|
|
@@ -61,82 +61,77 @@ const sendEventToPosthog = ({
|
|
|
61
61
|
isError = false,
|
|
62
62
|
error,
|
|
63
63
|
tools,
|
|
64
|
-
|
|
64
|
+
captureImmediate = false
|
|
65
65
|
}) => {
|
|
66
|
-
if (client.capture) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
let costOverrideData = {};
|
|
79
|
-
if (params.posthogCostOverride) {
|
|
80
|
-
const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
|
|
81
|
-
const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
|
|
82
|
-
costOverrideData = {
|
|
83
|
-
$ai_input_cost_usd: inputCostUSD,
|
|
84
|
-
$ai_output_cost_usd: outputCostUSD,
|
|
85
|
-
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
const additionalTokenValues = {
|
|
89
|
-
...(usage.reasoningTokens ? {
|
|
90
|
-
$ai_reasoning_tokens: usage.reasoningTokens
|
|
91
|
-
} : {}),
|
|
92
|
-
...(usage.cacheReadInputTokens ? {
|
|
93
|
-
$ai_cache_read_input_tokens: usage.cacheReadInputTokens
|
|
94
|
-
} : {}),
|
|
95
|
-
...(usage.cacheCreationInputTokens ? {
|
|
96
|
-
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
97
|
-
} : {})
|
|
66
|
+
if (!client.capture) {
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
// sanitize input and output for UTF-8 validity
|
|
70
|
+
const safeInput = sanitizeValues(input);
|
|
71
|
+
const safeOutput = sanitizeValues(output);
|
|
72
|
+
const safeError = sanitizeValues(error);
|
|
73
|
+
let errorData = {};
|
|
74
|
+
if (isError) {
|
|
75
|
+
errorData = {
|
|
76
|
+
$ai_is_error: true,
|
|
77
|
+
$ai_error: safeError
|
|
98
78
|
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
$
|
|
106
|
-
$
|
|
107
|
-
$
|
|
108
|
-
...additionalTokenValues,
|
|
109
|
-
$ai_latency: latency,
|
|
110
|
-
$ai_trace_id: traceId,
|
|
111
|
-
$ai_base_url: baseURL,
|
|
112
|
-
...params.posthogProperties,
|
|
113
|
-
...(distinctId ? {} : {
|
|
114
|
-
$process_person_profile: false
|
|
115
|
-
}),
|
|
116
|
-
...(tools ? {
|
|
117
|
-
$ai_tools: tools
|
|
118
|
-
} : {}),
|
|
119
|
-
...errorData,
|
|
120
|
-
...costOverrideData
|
|
79
|
+
}
|
|
80
|
+
let costOverrideData = {};
|
|
81
|
+
if (params.posthogCostOverride) {
|
|
82
|
+
const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
|
|
83
|
+
const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
|
|
84
|
+
costOverrideData = {
|
|
85
|
+
$ai_input_cost_usd: inputCostUSD,
|
|
86
|
+
$ai_output_cost_usd: outputCostUSD,
|
|
87
|
+
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
121
88
|
};
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
89
|
+
}
|
|
90
|
+
const additionalTokenValues = {
|
|
91
|
+
...(usage.reasoningTokens ? {
|
|
92
|
+
$ai_reasoning_tokens: usage.reasoningTokens
|
|
93
|
+
} : {}),
|
|
94
|
+
...(usage.cacheReadInputTokens ? {
|
|
95
|
+
$ai_cache_read_input_tokens: usage.cacheReadInputTokens
|
|
96
|
+
} : {}),
|
|
97
|
+
...(usage.cacheCreationInputTokens ? {
|
|
98
|
+
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
99
|
+
} : {})
|
|
100
|
+
};
|
|
101
|
+
const properties = {
|
|
102
|
+
$ai_provider: params.posthogProviderOverride ?? provider,
|
|
103
|
+
$ai_model: params.posthogModelOverride ?? model,
|
|
104
|
+
$ai_model_parameters: getModelParams(params),
|
|
105
|
+
$ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),
|
|
106
|
+
$ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),
|
|
107
|
+
$ai_http_status: httpStatus,
|
|
108
|
+
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
109
|
+
$ai_output_tokens: usage.outputTokens ?? 0,
|
|
110
|
+
...additionalTokenValues,
|
|
111
|
+
$ai_latency: latency,
|
|
112
|
+
$ai_trace_id: traceId,
|
|
113
|
+
$ai_base_url: baseURL,
|
|
114
|
+
...params.posthogProperties,
|
|
115
|
+
...(distinctId ? {} : {
|
|
116
|
+
$process_person_profile: false
|
|
117
|
+
}),
|
|
118
|
+
...(tools ? {
|
|
119
|
+
$ai_tools: tools
|
|
120
|
+
} : {}),
|
|
121
|
+
...errorData,
|
|
122
|
+
...costOverrideData
|
|
123
|
+
};
|
|
124
|
+
const event = {
|
|
125
|
+
distinctId: distinctId ?? traceId,
|
|
126
|
+
event: '$ai_generation',
|
|
127
|
+
properties,
|
|
128
|
+
groups: params.posthogGroups
|
|
129
|
+
};
|
|
130
|
+
if (captureImmediate) {
|
|
131
|
+
// await capture promise to send single event in serverless environments
|
|
132
|
+
await client.captureImmediate(event);
|
|
133
|
+
} else {
|
|
134
|
+
client.capture(event);
|
|
140
135
|
}
|
|
141
136
|
};
|
|
142
137
|
|
|
@@ -178,6 +173,7 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
178
173
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
179
174
|
posthogPrivacyMode = false,
|
|
180
175
|
posthogGroups,
|
|
176
|
+
posthogCaptureImmediate,
|
|
181
177
|
...openAIParams
|
|
182
178
|
} = body;
|
|
183
179
|
const traceId = posthogTraceId ?? v4();
|
|
@@ -207,7 +203,7 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
207
203
|
}
|
|
208
204
|
}
|
|
209
205
|
const latency = (Date.now() - startTime) / 1000;
|
|
210
|
-
sendEventToPosthog({
|
|
206
|
+
await sendEventToPosthog({
|
|
211
207
|
client: this.phClient,
|
|
212
208
|
distinctId: posthogDistinctId ?? traceId,
|
|
213
209
|
traceId,
|
|
@@ -222,10 +218,11 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
222
218
|
baseURL: this.baseURL ?? '',
|
|
223
219
|
params: body,
|
|
224
220
|
httpStatus: 200,
|
|
225
|
-
usage
|
|
221
|
+
usage,
|
|
222
|
+
captureImmediate: posthogCaptureImmediate
|
|
226
223
|
});
|
|
227
224
|
} catch (error) {
|
|
228
|
-
sendEventToPosthog({
|
|
225
|
+
await sendEventToPosthog({
|
|
229
226
|
client: this.phClient,
|
|
230
227
|
distinctId: posthogDistinctId ?? traceId,
|
|
231
228
|
traceId,
|
|
@@ -242,7 +239,8 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
242
239
|
outputTokens: 0
|
|
243
240
|
},
|
|
244
241
|
isError: true,
|
|
245
|
-
error: JSON.stringify(error)
|
|
242
|
+
error: JSON.stringify(error),
|
|
243
|
+
captureImmediate: posthogCaptureImmediate
|
|
246
244
|
});
|
|
247
245
|
}
|
|
248
246
|
})();
|
|
@@ -253,10 +251,10 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
253
251
|
return value;
|
|
254
252
|
});
|
|
255
253
|
} else {
|
|
256
|
-
const wrappedPromise = parentPromise.then(result => {
|
|
254
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
257
255
|
if ('choices' in result) {
|
|
258
256
|
const latency = (Date.now() - startTime) / 1000;
|
|
259
|
-
sendEventToPosthog({
|
|
257
|
+
await sendEventToPosthog({
|
|
260
258
|
client: this.phClient,
|
|
261
259
|
distinctId: posthogDistinctId ?? traceId,
|
|
262
260
|
traceId,
|
|
@@ -273,12 +271,13 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
273
271
|
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
274
272
|
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
275
273
|
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
276
|
-
}
|
|
274
|
+
},
|
|
275
|
+
captureImmediate: posthogCaptureImmediate
|
|
277
276
|
});
|
|
278
277
|
}
|
|
279
278
|
return result;
|
|
280
|
-
}, error => {
|
|
281
|
-
sendEventToPosthog({
|
|
279
|
+
}, async error => {
|
|
280
|
+
await sendEventToPosthog({
|
|
282
281
|
client: this.phClient,
|
|
283
282
|
distinctId: posthogDistinctId ?? traceId,
|
|
284
283
|
traceId,
|
|
@@ -295,7 +294,8 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
295
294
|
outputTokens: 0
|
|
296
295
|
},
|
|
297
296
|
isError: true,
|
|
298
|
-
error: JSON.stringify(error)
|
|
297
|
+
error: JSON.stringify(error),
|
|
298
|
+
captureImmediate: posthogCaptureImmediate
|
|
299
299
|
});
|
|
300
300
|
throw error;
|
|
301
301
|
});
|