@posthog/ai 4.2.1 → 4.3.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/CHANGELOG.md +5 -0
- package/lib/anthropic/index.cjs.js +82 -84
- package/lib/anthropic/index.cjs.js.map +1 -1
- package/lib/anthropic/index.d.ts +1 -1
- package/lib/anthropic/index.esm.js +82 -84
- package/lib/anthropic/index.esm.js.map +1 -1
- package/lib/index.cjs.js +125 -115
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.esm.js +125 -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 +82 -84
- package/lib/openai/index.cjs.js.map +1 -1
- package/lib/openai/index.d.ts +1 -1
- package/lib/openai/index.esm.js +82 -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 +80 -85
- package/lib/vercel/index.cjs.js.map +1 -1
- package/lib/vercel/index.d.ts +1 -1
- package/lib/vercel/index.esm.js +80 -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 +61 -74
- package/src/vercel/middleware.ts +15 -13
- package/tests/openai.test.ts +15 -0
- 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,75 @@ 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) return Promise.resolve();
|
|
75
|
+
// sanitize input and output for UTF-8 validity
|
|
76
|
+
const safeInput = sanitizeValues(input);
|
|
77
|
+
const safeOutput = sanitizeValues(output);
|
|
78
|
+
const safeError = sanitizeValues(error);
|
|
79
|
+
let errorData = {};
|
|
80
|
+
if (isError) {
|
|
81
|
+
errorData = {
|
|
82
|
+
$ai_is_error: true,
|
|
83
|
+
$ai_error: safeError
|
|
106
84
|
};
|
|
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
|
|
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
|
|
129
94
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
+
} : {})
|
|
106
|
+
};
|
|
107
|
+
const properties = {
|
|
108
|
+
$ai_provider: params.posthogProviderOverride ?? provider,
|
|
109
|
+
$ai_model: params.posthogModelOverride ?? model,
|
|
110
|
+
$ai_model_parameters: getModelParams(params),
|
|
111
|
+
$ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),
|
|
112
|
+
$ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),
|
|
113
|
+
$ai_http_status: httpStatus,
|
|
114
|
+
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
115
|
+
$ai_output_tokens: usage.outputTokens ?? 0,
|
|
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
|
|
129
|
+
};
|
|
130
|
+
const event = {
|
|
131
|
+
distinctId: distinctId ?? traceId,
|
|
132
|
+
event: '$ai_generation',
|
|
133
|
+
properties,
|
|
134
|
+
groups: params.posthogGroups
|
|
135
|
+
};
|
|
136
|
+
if (captureImmediate) {
|
|
137
|
+
// await capture promise to send single event in serverless environments
|
|
138
|
+
await client.captureImmediate(event);
|
|
139
|
+
} else {
|
|
140
|
+
client.capture(event);
|
|
148
141
|
}
|
|
149
142
|
};
|
|
150
143
|
|
|
@@ -186,6 +179,7 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
186
179
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
187
180
|
posthogPrivacyMode = false,
|
|
188
181
|
posthogGroups,
|
|
182
|
+
posthogCaptureImmediate,
|
|
189
183
|
...openAIParams
|
|
190
184
|
} = body;
|
|
191
185
|
const traceId = posthogTraceId ?? uuid.v4();
|
|
@@ -215,7 +209,7 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
215
209
|
}
|
|
216
210
|
}
|
|
217
211
|
const latency = (Date.now() - startTime) / 1000;
|
|
218
|
-
sendEventToPosthog({
|
|
212
|
+
await sendEventToPosthog({
|
|
219
213
|
client: this.phClient,
|
|
220
214
|
distinctId: posthogDistinctId ?? traceId,
|
|
221
215
|
traceId,
|
|
@@ -230,10 +224,11 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
230
224
|
baseURL: this.baseURL ?? '',
|
|
231
225
|
params: body,
|
|
232
226
|
httpStatus: 200,
|
|
233
|
-
usage
|
|
227
|
+
usage,
|
|
228
|
+
captureImmediate: posthogCaptureImmediate
|
|
234
229
|
});
|
|
235
230
|
} catch (error) {
|
|
236
|
-
sendEventToPosthog({
|
|
231
|
+
await sendEventToPosthog({
|
|
237
232
|
client: this.phClient,
|
|
238
233
|
distinctId: posthogDistinctId ?? traceId,
|
|
239
234
|
traceId,
|
|
@@ -250,7 +245,8 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
250
245
|
outputTokens: 0
|
|
251
246
|
},
|
|
252
247
|
isError: true,
|
|
253
|
-
error: JSON.stringify(error)
|
|
248
|
+
error: JSON.stringify(error),
|
|
249
|
+
captureImmediate: posthogCaptureImmediate
|
|
254
250
|
});
|
|
255
251
|
}
|
|
256
252
|
})();
|
|
@@ -261,10 +257,10 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
261
257
|
return value;
|
|
262
258
|
});
|
|
263
259
|
} else {
|
|
264
|
-
const wrappedPromise = parentPromise.then(result => {
|
|
260
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
265
261
|
if ('choices' in result) {
|
|
266
262
|
const latency = (Date.now() - startTime) / 1000;
|
|
267
|
-
sendEventToPosthog({
|
|
263
|
+
await sendEventToPosthog({
|
|
268
264
|
client: this.phClient,
|
|
269
265
|
distinctId: posthogDistinctId ?? traceId,
|
|
270
266
|
traceId,
|
|
@@ -281,12 +277,13 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
281
277
|
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
282
278
|
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
283
279
|
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
284
|
-
}
|
|
280
|
+
},
|
|
281
|
+
captureImmediate: posthogCaptureImmediate
|
|
285
282
|
});
|
|
286
283
|
}
|
|
287
284
|
return result;
|
|
288
|
-
}, error => {
|
|
289
|
-
sendEventToPosthog({
|
|
285
|
+
}, async error => {
|
|
286
|
+
await sendEventToPosthog({
|
|
290
287
|
client: this.phClient,
|
|
291
288
|
distinctId: posthogDistinctId ?? traceId,
|
|
292
289
|
traceId,
|
|
@@ -303,7 +300,8 @@ class WrappedCompletions extends OpenAIOrignal__default["default"].Chat.Completi
|
|
|
303
300
|
outputTokens: 0
|
|
304
301
|
},
|
|
305
302
|
isError: true,
|
|
306
|
-
error: JSON.stringify(error)
|
|
303
|
+
error: JSON.stringify(error),
|
|
304
|
+
captureImmediate: posthogCaptureImmediate
|
|
307
305
|
});
|
|
308
306
|
throw error;
|
|
309
307
|
});
|
|
@@ -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) return Promise.resolve()\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,75 @@ 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) return Promise.resolve();
|
|
67
|
+
// sanitize input and output for UTF-8 validity
|
|
68
|
+
const safeInput = sanitizeValues(input);
|
|
69
|
+
const safeOutput = sanitizeValues(output);
|
|
70
|
+
const safeError = sanitizeValues(error);
|
|
71
|
+
let errorData = {};
|
|
72
|
+
if (isError) {
|
|
73
|
+
errorData = {
|
|
74
|
+
$ai_is_error: true,
|
|
75
|
+
$ai_error: safeError
|
|
98
76
|
};
|
|
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
|
|
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
|
|
121
86
|
};
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
+
} : {})
|
|
98
|
+
};
|
|
99
|
+
const properties = {
|
|
100
|
+
$ai_provider: params.posthogProviderOverride ?? provider,
|
|
101
|
+
$ai_model: params.posthogModelOverride ?? model,
|
|
102
|
+
$ai_model_parameters: getModelParams(params),
|
|
103
|
+
$ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),
|
|
104
|
+
$ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),
|
|
105
|
+
$ai_http_status: httpStatus,
|
|
106
|
+
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
107
|
+
$ai_output_tokens: usage.outputTokens ?? 0,
|
|
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
|
|
121
|
+
};
|
|
122
|
+
const event = {
|
|
123
|
+
distinctId: distinctId ?? traceId,
|
|
124
|
+
event: '$ai_generation',
|
|
125
|
+
properties,
|
|
126
|
+
groups: params.posthogGroups
|
|
127
|
+
};
|
|
128
|
+
if (captureImmediate) {
|
|
129
|
+
// await capture promise to send single event in serverless environments
|
|
130
|
+
await client.captureImmediate(event);
|
|
131
|
+
} else {
|
|
132
|
+
client.capture(event);
|
|
140
133
|
}
|
|
141
134
|
};
|
|
142
135
|
|
|
@@ -178,6 +171,7 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
178
171
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
179
172
|
posthogPrivacyMode = false,
|
|
180
173
|
posthogGroups,
|
|
174
|
+
posthogCaptureImmediate,
|
|
181
175
|
...openAIParams
|
|
182
176
|
} = body;
|
|
183
177
|
const traceId = posthogTraceId ?? v4();
|
|
@@ -207,7 +201,7 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
207
201
|
}
|
|
208
202
|
}
|
|
209
203
|
const latency = (Date.now() - startTime) / 1000;
|
|
210
|
-
sendEventToPosthog({
|
|
204
|
+
await sendEventToPosthog({
|
|
211
205
|
client: this.phClient,
|
|
212
206
|
distinctId: posthogDistinctId ?? traceId,
|
|
213
207
|
traceId,
|
|
@@ -222,10 +216,11 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
222
216
|
baseURL: this.baseURL ?? '',
|
|
223
217
|
params: body,
|
|
224
218
|
httpStatus: 200,
|
|
225
|
-
usage
|
|
219
|
+
usage,
|
|
220
|
+
captureImmediate: posthogCaptureImmediate
|
|
226
221
|
});
|
|
227
222
|
} catch (error) {
|
|
228
|
-
sendEventToPosthog({
|
|
223
|
+
await sendEventToPosthog({
|
|
229
224
|
client: this.phClient,
|
|
230
225
|
distinctId: posthogDistinctId ?? traceId,
|
|
231
226
|
traceId,
|
|
@@ -242,7 +237,8 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
242
237
|
outputTokens: 0
|
|
243
238
|
},
|
|
244
239
|
isError: true,
|
|
245
|
-
error: JSON.stringify(error)
|
|
240
|
+
error: JSON.stringify(error),
|
|
241
|
+
captureImmediate: posthogCaptureImmediate
|
|
246
242
|
});
|
|
247
243
|
}
|
|
248
244
|
})();
|
|
@@ -253,10 +249,10 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
253
249
|
return value;
|
|
254
250
|
});
|
|
255
251
|
} else {
|
|
256
|
-
const wrappedPromise = parentPromise.then(result => {
|
|
252
|
+
const wrappedPromise = parentPromise.then(async result => {
|
|
257
253
|
if ('choices' in result) {
|
|
258
254
|
const latency = (Date.now() - startTime) / 1000;
|
|
259
|
-
sendEventToPosthog({
|
|
255
|
+
await sendEventToPosthog({
|
|
260
256
|
client: this.phClient,
|
|
261
257
|
distinctId: posthogDistinctId ?? traceId,
|
|
262
258
|
traceId,
|
|
@@ -273,12 +269,13 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
273
269
|
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
274
270
|
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
275
271
|
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
276
|
-
}
|
|
272
|
+
},
|
|
273
|
+
captureImmediate: posthogCaptureImmediate
|
|
277
274
|
});
|
|
278
275
|
}
|
|
279
276
|
return result;
|
|
280
|
-
}, error => {
|
|
281
|
-
sendEventToPosthog({
|
|
277
|
+
}, async error => {
|
|
278
|
+
await sendEventToPosthog({
|
|
282
279
|
client: this.phClient,
|
|
283
280
|
distinctId: posthogDistinctId ?? traceId,
|
|
284
281
|
traceId,
|
|
@@ -295,7 +292,8 @@ class WrappedCompletions extends OpenAIOrignal.Chat.Completions {
|
|
|
295
292
|
outputTokens: 0
|
|
296
293
|
},
|
|
297
294
|
isError: true,
|
|
298
|
-
error: JSON.stringify(error)
|
|
295
|
+
error: JSON.stringify(error),
|
|
296
|
+
captureImmediate: posthogCaptureImmediate
|
|
299
297
|
});
|
|
300
298
|
throw error;
|
|
301
299
|
});
|