@posthog/ai 4.0.0 → 4.1.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 +9 -1
- package/lib/anthropic/index.cjs.js +23 -3
- package/lib/anthropic/index.cjs.js.map +1 -1
- package/lib/anthropic/index.esm.js +23 -3
- package/lib/anthropic/index.esm.js.map +1 -1
- package/lib/index.cjs.js +94 -31
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.esm.js +94 -31
- package/lib/index.esm.js.map +1 -1
- package/lib/langchain/index.cjs.js +1 -0
- package/lib/langchain/index.cjs.js.map +1 -1
- package/lib/langchain/index.esm.js +1 -0
- package/lib/langchain/index.esm.js.map +1 -1
- package/lib/openai/index.cjs.js +23 -3
- package/lib/openai/index.cjs.js.map +1 -1
- package/lib/openai/index.esm.js +23 -3
- package/lib/openai/index.esm.js.map +1 -1
- package/lib/posthog-ai/src/utils.d.ts +1 -0
- package/lib/vercel/index.cjs.js +94 -31
- package/lib/vercel/index.cjs.js.map +1 -1
- package/lib/vercel/index.esm.js +94 -31
- package/lib/vercel/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/utils.ts +42 -3
- package/src/vercel/middleware.ts +44 -19
package/lib/vercel/index.esm.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { experimental_wrapLanguageModel } from 'ai';
|
|
2
2
|
import { v4 } from 'uuid';
|
|
3
|
+
import { Buffer } from 'buffer';
|
|
3
4
|
|
|
5
|
+
// limit large outputs by truncating to 200kb (approx 200k bytes)
|
|
6
|
+
const MAX_OUTPUT_SIZE = 200000;
|
|
7
|
+
const STRING_FORMAT = 'utf8';
|
|
4
8
|
const getModelParams = params => {
|
|
5
9
|
if (!params) {
|
|
6
10
|
return {};
|
|
@@ -17,6 +21,33 @@ const getModelParams = params => {
|
|
|
17
21
|
const withPrivacyMode = (client, privacyMode, input) => {
|
|
18
22
|
return client.privacy_mode || privacyMode ? null : input;
|
|
19
23
|
};
|
|
24
|
+
const truncate = str => {
|
|
25
|
+
try {
|
|
26
|
+
const buffer = Buffer.from(str, STRING_FORMAT);
|
|
27
|
+
if (buffer.length <= MAX_OUTPUT_SIZE) {
|
|
28
|
+
return str;
|
|
29
|
+
}
|
|
30
|
+
const truncatedBuffer = buffer.slice(0, MAX_OUTPUT_SIZE);
|
|
31
|
+
return `${truncatedBuffer.toString(STRING_FORMAT)}... [truncated]`;
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('Error truncating, likely not a string');
|
|
34
|
+
return str;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
function sanitizeValues(obj) {
|
|
38
|
+
if (obj === undefined || obj === null) {
|
|
39
|
+
return obj;
|
|
40
|
+
}
|
|
41
|
+
const jsonSafe = JSON.parse(JSON.stringify(obj));
|
|
42
|
+
if (typeof jsonSafe === 'string') {
|
|
43
|
+
return Buffer.from(jsonSafe, STRING_FORMAT).toString(STRING_FORMAT);
|
|
44
|
+
} else if (Array.isArray(jsonSafe)) {
|
|
45
|
+
return jsonSafe.map(sanitizeValues);
|
|
46
|
+
} else if (jsonSafe && typeof jsonSafe === 'object') {
|
|
47
|
+
return Object.fromEntries(Object.entries(jsonSafe).map(([k, v]) => [k, sanitizeValues(v)]));
|
|
48
|
+
}
|
|
49
|
+
return jsonSafe;
|
|
50
|
+
}
|
|
20
51
|
const sendEventToPosthog = ({
|
|
21
52
|
client,
|
|
22
53
|
distinctId,
|
|
@@ -35,11 +66,15 @@ const sendEventToPosthog = ({
|
|
|
35
66
|
tools
|
|
36
67
|
}) => {
|
|
37
68
|
if (client.capture) {
|
|
69
|
+
// sanitize input and output for UTF-8 validity
|
|
70
|
+
const safeInput = sanitizeValues(input);
|
|
71
|
+
const safeOutput = sanitizeValues(output);
|
|
72
|
+
const safeError = sanitizeValues(error);
|
|
38
73
|
let errorData = {};
|
|
39
74
|
if (isError) {
|
|
40
75
|
errorData = {
|
|
41
76
|
$ai_is_error: true,
|
|
42
|
-
$ai_error:
|
|
77
|
+
$ai_error: safeError
|
|
43
78
|
};
|
|
44
79
|
}
|
|
45
80
|
let costOverrideData = {};
|
|
@@ -70,8 +105,8 @@ const sendEventToPosthog = ({
|
|
|
70
105
|
$ai_provider: params.posthogProviderOverride ?? provider,
|
|
71
106
|
$ai_model: params.posthogModelOverride ?? model,
|
|
72
107
|
$ai_model_parameters: getModelParams(params),
|
|
73
|
-
$ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false,
|
|
74
|
-
$ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false,
|
|
108
|
+
$ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),
|
|
109
|
+
$ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),
|
|
75
110
|
$ai_http_status: httpStatus,
|
|
76
111
|
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
77
112
|
$ai_output_tokens: usage.outputTokens ?? 0,
|
|
@@ -106,14 +141,26 @@ const mapVercelParams = params => {
|
|
|
106
141
|
};
|
|
107
142
|
};
|
|
108
143
|
const mapVercelPrompt = prompt => {
|
|
109
|
-
|
|
144
|
+
// normalize single inputs into an array of messages
|
|
145
|
+
let promptsArray;
|
|
146
|
+
if (typeof prompt === 'string') {
|
|
147
|
+
promptsArray = [{
|
|
148
|
+
role: 'user',
|
|
149
|
+
content: prompt
|
|
150
|
+
}];
|
|
151
|
+
} else if (!Array.isArray(prompt)) {
|
|
152
|
+
promptsArray = [prompt];
|
|
153
|
+
} else {
|
|
154
|
+
promptsArray = prompt;
|
|
155
|
+
}
|
|
156
|
+
return promptsArray.map(p => {
|
|
110
157
|
let content = {};
|
|
111
158
|
if (Array.isArray(p.content)) {
|
|
112
159
|
content = p.content.map(c => {
|
|
113
160
|
if (c.type === 'text') {
|
|
114
161
|
return {
|
|
115
162
|
type: 'text',
|
|
116
|
-
content: c.text
|
|
163
|
+
content: truncate(c.text)
|
|
117
164
|
};
|
|
118
165
|
} else if (c.type === 'image') {
|
|
119
166
|
return {
|
|
@@ -159,7 +206,7 @@ const mapVercelPrompt = prompt => {
|
|
|
159
206
|
} else {
|
|
160
207
|
content = {
|
|
161
208
|
type: 'text',
|
|
162
|
-
text: p.content
|
|
209
|
+
text: truncate(p.content)
|
|
163
210
|
};
|
|
164
211
|
}
|
|
165
212
|
return {
|
|
@@ -169,46 +216,62 @@ const mapVercelPrompt = prompt => {
|
|
|
169
216
|
});
|
|
170
217
|
};
|
|
171
218
|
const mapVercelOutput = result => {
|
|
219
|
+
// normalize string results to object
|
|
220
|
+
const normalizedResult = typeof result === 'string' ? {
|
|
221
|
+
text: result
|
|
222
|
+
} : result;
|
|
172
223
|
const output = {
|
|
173
|
-
...(
|
|
174
|
-
text:
|
|
224
|
+
...(normalizedResult.text ? {
|
|
225
|
+
text: normalizedResult.text
|
|
226
|
+
} : {}),
|
|
227
|
+
...(normalizedResult.object ? {
|
|
228
|
+
object: normalizedResult.object
|
|
175
229
|
} : {}),
|
|
176
|
-
...(
|
|
177
|
-
|
|
230
|
+
...(normalizedResult.reasoning ? {
|
|
231
|
+
reasoning: normalizedResult.reasoning
|
|
178
232
|
} : {}),
|
|
179
|
-
...(
|
|
180
|
-
|
|
233
|
+
...(normalizedResult.response ? {
|
|
234
|
+
response: normalizedResult.response
|
|
181
235
|
} : {}),
|
|
182
|
-
...(
|
|
183
|
-
|
|
236
|
+
...(normalizedResult.finishReason ? {
|
|
237
|
+
finishReason: normalizedResult.finishReason
|
|
184
238
|
} : {}),
|
|
185
|
-
...(
|
|
186
|
-
|
|
239
|
+
...(normalizedResult.usage ? {
|
|
240
|
+
usage: normalizedResult.usage
|
|
187
241
|
} : {}),
|
|
188
|
-
...(
|
|
189
|
-
|
|
242
|
+
...(normalizedResult.warnings ? {
|
|
243
|
+
warnings: normalizedResult.warnings
|
|
190
244
|
} : {}),
|
|
191
|
-
...(
|
|
192
|
-
|
|
245
|
+
...(normalizedResult.providerMetadata ? {
|
|
246
|
+
toolCalls: normalizedResult.providerMetadata
|
|
193
247
|
} : {}),
|
|
194
|
-
...(
|
|
195
|
-
|
|
248
|
+
...(normalizedResult.files ? {
|
|
249
|
+
files: normalizedResult.files.map(file => ({
|
|
250
|
+
name: file.name,
|
|
251
|
+
size: file.size,
|
|
252
|
+
type: file.type
|
|
253
|
+
}))
|
|
196
254
|
} : {})
|
|
197
255
|
};
|
|
198
|
-
// if text and no object or reasoning, return text
|
|
199
256
|
if (output.text && !output.object && !output.reasoning) {
|
|
200
257
|
return [{
|
|
201
|
-
content: output.text,
|
|
258
|
+
content: truncate(output.text),
|
|
259
|
+
role: 'assistant'
|
|
260
|
+
}];
|
|
261
|
+
}
|
|
262
|
+
// otherwise stringify and truncate
|
|
263
|
+
try {
|
|
264
|
+
const jsonOutput = JSON.stringify(output);
|
|
265
|
+
return [{
|
|
266
|
+
content: truncate(jsonOutput),
|
|
202
267
|
role: 'assistant'
|
|
203
268
|
}];
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error('Error stringifying output');
|
|
271
|
+
return [];
|
|
204
272
|
}
|
|
205
|
-
return [{
|
|
206
|
-
content: JSON.stringify(output),
|
|
207
|
-
role: 'assistant'
|
|
208
|
-
}];
|
|
209
273
|
};
|
|
210
274
|
const extractProvider = model => {
|
|
211
|
-
// vercel provider is in the format of provider.endpoint
|
|
212
275
|
const provider = model.provider.toLowerCase();
|
|
213
276
|
const providerName = provider.split('.')[0];
|
|
214
277
|
return providerName;
|
|
@@ -286,7 +349,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
286
349
|
outputTokens: 0
|
|
287
350
|
},
|
|
288
351
|
isError: true,
|
|
289
|
-
error: JSON.stringify(error)
|
|
352
|
+
error: truncate(JSON.stringify(error))
|
|
290
353
|
});
|
|
291
354
|
throw error;
|
|
292
355
|
}
|
|
@@ -378,7 +441,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
378
441
|
outputTokens: 0
|
|
379
442
|
},
|
|
380
443
|
isError: true,
|
|
381
|
-
error: JSON.stringify(error)
|
|
444
|
+
error: truncate(JSON.stringify(error))
|
|
382
445
|
});
|
|
383
446
|
throw error;
|
|
384
447
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../../src/utils.ts","../../src/vercel/middleware.ts"],"sourcesContent":["import { PostHog } from 'posthog-node'\nimport OpenAIOrignal from 'openai'\nimport AnthropicOriginal from '@anthropic-ai/sdk'\n\ntype ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams\ntype MessageCreateParams = AnthropicOriginal.Messages.MessageCreateParams\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}\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 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}\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}: SendEventToPosthogParams): void => {\n if (client.capture) {\n let errorData = {}\n if (isError) {\n errorData = {\n $ai_is_error: true,\n $ai_error: error,\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 client.capture({\n distinctId: distinctId ?? traceId,\n event: '$ai_generation',\n 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, input),\n $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, output),\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 groups: params.posthogGroups,\n })\n }\n}\n","import { experimental_wrapLanguageModel as wrapLanguageModel } from 'ai'\nimport type { LanguageModelV1, LanguageModelV1Middleware, LanguageModelV1Prompt, LanguageModelV1StreamPart } from 'ai'\nimport { v4 as uuidv4 } from 'uuid'\nimport { PostHog } from 'posthog-node'\nimport { CostOverride, sendEventToPosthog } from '../utils'\n\ninterface ClientOptions {\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}\n\ninterface CreateInstrumentationMiddlewareOptions {\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}\n\ninterface PostHogInput {\n role: string\n type?: string\n content?:\n | string\n | {\n [key: string]: any\n }\n}\n\nconst mapVercelParams = (params: any): Record<string, any> => {\n return {\n temperature: params.temperature,\n max_tokens: params.maxTokens,\n top_p: params.topP,\n frequency_penalty: params.frequencyPenalty,\n presence_penalty: params.presencePenalty,\n stop: params.stopSequences,\n stream: params.stream,\n }\n}\n\nconst mapVercelPrompt = (prompt: LanguageModelV1Prompt): PostHogInput[] => {\n return prompt.map((p) => {\n let content = {}\n if (Array.isArray(p.content)) {\n content = p.content.map((c) => {\n if (c.type === 'text') {\n return {\n type: 'text',\n content: c.text,\n }\n } else if (c.type === 'image') {\n return {\n type: 'image',\n content: {\n // if image is a url use it, or use \"none supported\"\n image: c.image instanceof URL ? c.image.toString() : 'raw images not supported',\n mimeType: c.mimeType,\n },\n }\n } else if (c.type === 'file') {\n return {\n type: 'file',\n content: {\n file: c.data instanceof URL ? c.data.toString() : 'raw files not supported',\n mimeType: c.mimeType,\n },\n }\n } else if (c.type === 'tool-call') {\n return {\n type: 'tool-call',\n content: {\n toolCallId: c.toolCallId,\n toolName: c.toolName,\n args: c.args,\n },\n }\n } else if (c.type === 'tool-result') {\n return {\n type: 'tool-result',\n content: {\n toolCallId: c.toolCallId,\n toolName: c.toolName,\n result: c.result,\n isError: c.isError,\n },\n }\n }\n return {\n content: '',\n }\n })\n } else {\n content = {\n type: 'text',\n text: p.content,\n }\n }\n return {\n role: p.role,\n content,\n }\n })\n}\n\nconst mapVercelOutput = (result: any): PostHogInput[] => {\n const output = {\n ...(result.text ? { text: result.text } : {}),\n ...(result.object ? { object: result.object } : {}),\n ...(result.reasoning ? { reasoning: result.reasoning } : {}),\n ...(result.response ? { response: result.response } : {}),\n ...(result.finishReason ? { finishReason: result.finishReason } : {}),\n ...(result.usage ? { usage: result.usage } : {}),\n ...(result.warnings ? { warnings: result.warnings } : {}),\n ...(result.providerMetadata ? { toolCalls: result.providerMetadata } : {}),\n }\n // if text and no object or reasoning, return text\n if (output.text && !output.object && !output.reasoning) {\n return [{ content: output.text, role: 'assistant' }]\n }\n return [{ content: JSON.stringify(output), role: 'assistant' }]\n}\n\nconst extractProvider = (model: LanguageModelV1): string => {\n // vercel provider is in the format of provider.endpoint\n const provider = model.provider.toLowerCase()\n const providerName = provider.split('.')[0]\n return providerName\n}\n\nexport const createInstrumentationMiddleware = (\n phClient: PostHog,\n model: LanguageModelV1,\n options: CreateInstrumentationMiddlewareOptions\n): LanguageModelV1Middleware => {\n const middleware: LanguageModelV1Middleware = {\n wrapGenerate: async ({ doGenerate, params }) => {\n const startTime = Date.now()\n const mergedParams = {\n ...options,\n ...mapVercelParams(params),\n }\n try {\n const result = await doGenerate()\n const latency = (Date.now() - startTime) / 1000\n const modelId =\n options.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId)\n const provider = options.posthogProviderOverride ?? extractProvider(model)\n const baseURL = '' // cannot currently get baseURL from vercel\n const content = mapVercelOutput(result)\n // let tools = result.toolCalls\n const providerMetadata = result.providerMetadata\n const additionalTokenValues = {\n ...(providerMetadata?.openai?.reasoningTokens\n ? { reasoningTokens: providerMetadata.openai.reasoningTokens }\n : {}),\n ...(providerMetadata?.openai?.cachedPromptTokens\n ? { cacheReadInputTokens: providerMetadata.openai.cachedPromptTokens }\n : {}),\n ...(providerMetadata?.anthropic\n ? {\n cacheReadInputTokens: providerMetadata.anthropic.cacheReadInputTokens,\n cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens,\n }\n : {}),\n }\n sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId,\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [{ content, role: 'assistant' }],\n latency,\n baseURL,\n params: mergedParams as any,\n httpStatus: 200,\n usage: {\n inputTokens: result.usage.promptTokens,\n outputTokens: result.usage.completionTokens,\n ...additionalTokenValues,\n },\n })\n\n return result\n } catch (error: any) {\n const modelId = model.modelId\n sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId,\n model: modelId,\n provider: model.provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [],\n latency: 0,\n baseURL: '',\n params: mergedParams as any,\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 },\n\n wrapStream: async ({ doStream, params }) => {\n const startTime = Date.now()\n let generatedText = ''\n let usage: {\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: any\n cacheReadInputTokens?: any\n cacheCreationInputTokens?: any\n } = {}\n const mergedParams = {\n ...options,\n ...mapVercelParams(params),\n }\n\n const modelId = options.posthogModelOverride ?? model.modelId\n const provider = options.posthogProviderOverride ?? extractProvider(model)\n const baseURL = '' // cannot currently get baseURL from vercel\n try {\n const { stream, ...rest } = await doStream()\n const transformStream = new TransformStream<LanguageModelV1StreamPart, LanguageModelV1StreamPart>({\n transform(chunk, controller) {\n if (chunk.type === 'text-delta') {\n generatedText += chunk.textDelta\n }\n if (chunk.type === 'finish') {\n usage = {\n inputTokens: chunk.usage?.promptTokens,\n outputTokens: chunk.usage?.completionTokens,\n }\n if (chunk.providerMetadata?.openai?.reasoningTokens) {\n usage.reasoningTokens = chunk.providerMetadata.openai.reasoningTokens\n }\n if (chunk.providerMetadata?.openai?.cachedPromptTokens) {\n usage.cacheReadInputTokens = chunk.providerMetadata.openai.cachedPromptTokens\n }\n if (chunk.providerMetadata?.anthropic?.cacheReadInputTokens) {\n usage.cacheReadInputTokens = chunk.providerMetadata.anthropic.cacheReadInputTokens\n }\n if (chunk.providerMetadata?.anthropic?.cacheCreationInputTokens) {\n usage.cacheCreationInputTokens = chunk.providerMetadata.anthropic.cacheCreationInputTokens\n }\n }\n controller.enqueue(chunk)\n },\n\n flush() {\n const latency = (Date.now() - startTime) / 1000\n sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId,\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [{ content: generatedText, role: 'assistant' }],\n latency,\n baseURL,\n params: mergedParams as any,\n httpStatus: 200,\n usage,\n })\n },\n })\n\n return {\n stream: stream.pipeThrough(transformStream),\n ...rest,\n }\n } catch (error: any) {\n sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId,\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [],\n latency: 0,\n baseURL: '',\n params: mergedParams as any,\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 },\n }\n\n return middleware\n}\n\nexport const wrapVercelLanguageModel = (\n model: LanguageModelV1,\n phClient: PostHog,\n options: ClientOptions\n): LanguageModelV1 => {\n const traceId = options.posthogTraceId ?? uuidv4()\n const middleware = createInstrumentationMiddleware(phClient, model, {\n ...options,\n posthogTraceId: traceId,\n posthogDistinctId: options.posthogDistinctId ?? traceId,\n })\n\n const wrappedModel = wrapLanguageModel({\n model,\n middleware,\n })\n\n return wrappedModel\n}\n"],"names":["getModelParams","params","modelParams","paramKeys","key","undefined","withPrivacyMode","client","privacyMode","input","privacy_mode","sendEventToPosthog","distinctId","traceId","model","provider","output","latency","baseURL","httpStatus","usage","isError","error","tools","capture","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","event","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","groups","posthogGroups","mapVercelParams","temperature","max_tokens","maxTokens","top_p","topP","frequency_penalty","frequencyPenalty","presence_penalty","presencePenalty","stop","stopSequences","stream","mapVercelPrompt","prompt","map","p","content","Array","isArray","c","type","text","image","URL","toString","mimeType","file","data","toolCallId","toolName","args","result","role","mapVercelOutput","object","reasoning","response","finishReason","warnings","providerMetadata","toolCalls","JSON","stringify","extractProvider","toLowerCase","providerName","split","createInstrumentationMiddleware","phClient","options","middleware","wrapGenerate","doGenerate","startTime","Date","now","mergedParams","modelId","openai","cachedPromptTokens","anthropic","posthogDistinctId","posthogTraceId","promptTokens","completionTokens","status","wrapStream","doStream","generatedText","rest","transformStream","TransformStream","transform","chunk","controller","textDelta","enqueue","flush","pipeThrough","wrapVercelLanguageModel","uuidv4","wrappedModel","wrapLanguageModel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../../src/utils.ts","../../src/vercel/middleware.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)\nconst 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}\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}\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}: 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 client.capture({\n distinctId: distinctId ?? traceId,\n event: '$ai_generation',\n 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 groups: params.posthogGroups,\n })\n }\n}\n","import { experimental_wrapLanguageModel as wrapLanguageModel } from 'ai'\nimport type { LanguageModelV1, LanguageModelV1Middleware, LanguageModelV1Prompt, LanguageModelV1StreamPart } from 'ai'\nimport { v4 as uuidv4 } from 'uuid'\nimport { PostHog } from 'posthog-node'\nimport { CostOverride, sendEventToPosthog, truncate } from '../utils'\n\ninterface ClientOptions {\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}\n\ninterface CreateInstrumentationMiddlewareOptions {\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}\n\ninterface PostHogInput {\n role: string\n type?: string\n content?:\n | string\n | {\n [key: string]: any\n }\n}\n\nconst mapVercelParams = (params: any): Record<string, any> => {\n return {\n temperature: params.temperature,\n max_tokens: params.maxTokens,\n top_p: params.topP,\n frequency_penalty: params.frequencyPenalty,\n presence_penalty: params.presencePenalty,\n stop: params.stopSequences,\n stream: params.stream,\n }\n}\n\nconst mapVercelPrompt = (prompt: LanguageModelV1Prompt): PostHogInput[] => {\n // normalize single inputs into an array of messages\n let promptsArray: any[]\n if (typeof prompt === 'string') {\n promptsArray = [{ role: 'user', content: prompt }]\n } else if (!Array.isArray(prompt)) {\n promptsArray = [prompt]\n } else {\n promptsArray = prompt\n }\n return promptsArray.map((p) => {\n let content = {}\n if (Array.isArray(p.content)) {\n content = p.content.map((c: any) => {\n if (c.type === 'text') {\n return {\n type: 'text',\n content: truncate(c.text),\n }\n } else if (c.type === 'image') {\n return {\n type: 'image',\n content: {\n // if image is a url use it, or use \"none supported\"\n image: c.image instanceof URL ? c.image.toString() : 'raw images not supported',\n mimeType: c.mimeType,\n },\n }\n } else if (c.type === 'file') {\n return {\n type: 'file',\n content: {\n file: c.data instanceof URL ? c.data.toString() : 'raw files not supported',\n mimeType: c.mimeType,\n },\n }\n } else if (c.type === 'tool-call') {\n return {\n type: 'tool-call',\n content: {\n toolCallId: c.toolCallId,\n toolName: c.toolName,\n args: c.args,\n },\n }\n } else if (c.type === 'tool-result') {\n return {\n type: 'tool-result',\n content: {\n toolCallId: c.toolCallId,\n toolName: c.toolName,\n result: c.result,\n isError: c.isError,\n },\n }\n }\n return {\n content: '',\n }\n })\n } else {\n content = {\n type: 'text',\n text: truncate(p.content),\n }\n }\n return {\n role: p.role,\n content,\n }\n })\n}\n\nconst mapVercelOutput = (result: any): PostHogInput[] => {\n // normalize string results to object\n const normalizedResult = typeof result === 'string' ? { text: result } : result\n const output = {\n ...(normalizedResult.text ? { text: normalizedResult.text } : {}),\n ...(normalizedResult.object ? { object: normalizedResult.object } : {}),\n ...(normalizedResult.reasoning ? { reasoning: normalizedResult.reasoning } : {}),\n ...(normalizedResult.response ? { response: normalizedResult.response } : {}),\n ...(normalizedResult.finishReason ? { finishReason: normalizedResult.finishReason } : {}),\n ...(normalizedResult.usage ? { usage: normalizedResult.usage } : {}),\n ...(normalizedResult.warnings ? { warnings: normalizedResult.warnings } : {}),\n ...(normalizedResult.providerMetadata ? { toolCalls: normalizedResult.providerMetadata } : {}),\n ...(normalizedResult.files\n ? {\n files: normalizedResult.files.map((file: any) => ({\n name: file.name,\n size: file.size,\n type: file.type,\n })),\n }\n : {}),\n }\n if (output.text && !output.object && !output.reasoning) {\n return [{ content: truncate(output.text as string), role: 'assistant' }]\n }\n // otherwise stringify and truncate\n try {\n const jsonOutput = JSON.stringify(output)\n return [{ content: truncate(jsonOutput), role: 'assistant' }]\n } catch (error) {\n console.error('Error stringifying output')\n return []\n }\n}\n\nconst extractProvider = (model: LanguageModelV1): string => {\n const provider = model.provider.toLowerCase()\n const providerName = provider.split('.')[0]\n return providerName\n}\n\nexport const createInstrumentationMiddleware = (\n phClient: PostHog,\n model: LanguageModelV1,\n options: CreateInstrumentationMiddlewareOptions\n): LanguageModelV1Middleware => {\n const middleware: LanguageModelV1Middleware = {\n wrapGenerate: async ({ doGenerate, params }) => {\n const startTime = Date.now()\n const mergedParams = {\n ...options,\n ...mapVercelParams(params),\n }\n try {\n const result = await doGenerate()\n const latency = (Date.now() - startTime) / 1000\n const modelId =\n options.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId)\n const provider = options.posthogProviderOverride ?? extractProvider(model)\n const baseURL = '' // cannot currently get baseURL from vercel\n const content = mapVercelOutput(result)\n // let tools = result.toolCalls\n const providerMetadata = result.providerMetadata\n const additionalTokenValues = {\n ...(providerMetadata?.openai?.reasoningTokens\n ? { reasoningTokens: providerMetadata.openai.reasoningTokens }\n : {}),\n ...(providerMetadata?.openai?.cachedPromptTokens\n ? { cacheReadInputTokens: providerMetadata.openai.cachedPromptTokens }\n : {}),\n ...(providerMetadata?.anthropic\n ? {\n cacheReadInputTokens: providerMetadata.anthropic.cacheReadInputTokens,\n cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens,\n }\n : {}),\n }\n sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId,\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [{ content, role: 'assistant' }],\n latency,\n baseURL,\n params: mergedParams as any,\n httpStatus: 200,\n usage: {\n inputTokens: result.usage.promptTokens,\n outputTokens: result.usage.completionTokens,\n ...additionalTokenValues,\n },\n })\n\n return result\n } catch (error: any) {\n const modelId = model.modelId\n sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId,\n model: modelId,\n provider: model.provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [],\n latency: 0,\n baseURL: '',\n params: mergedParams as any,\n httpStatus: error?.status ? error.status : 500,\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n isError: true,\n error: truncate(JSON.stringify(error)),\n })\n throw error\n }\n },\n\n wrapStream: async ({ doStream, params }) => {\n const startTime = Date.now()\n let generatedText = ''\n let usage: {\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: any\n cacheReadInputTokens?: any\n cacheCreationInputTokens?: any\n } = {}\n const mergedParams = {\n ...options,\n ...mapVercelParams(params),\n }\n\n const modelId = options.posthogModelOverride ?? model.modelId\n const provider = options.posthogProviderOverride ?? extractProvider(model)\n const baseURL = '' // cannot currently get baseURL from vercel\n try {\n const { stream, ...rest } = await doStream()\n const transformStream = new TransformStream<LanguageModelV1StreamPart, LanguageModelV1StreamPart>({\n transform(chunk, controller) {\n if (chunk.type === 'text-delta') {\n generatedText += chunk.textDelta\n }\n if (chunk.type === 'finish') {\n usage = {\n inputTokens: chunk.usage?.promptTokens,\n outputTokens: chunk.usage?.completionTokens,\n }\n if (chunk.providerMetadata?.openai?.reasoningTokens) {\n usage.reasoningTokens = chunk.providerMetadata.openai.reasoningTokens\n }\n if (chunk.providerMetadata?.openai?.cachedPromptTokens) {\n usage.cacheReadInputTokens = chunk.providerMetadata.openai.cachedPromptTokens\n }\n if (chunk.providerMetadata?.anthropic?.cacheReadInputTokens) {\n usage.cacheReadInputTokens = chunk.providerMetadata.anthropic.cacheReadInputTokens\n }\n if (chunk.providerMetadata?.anthropic?.cacheCreationInputTokens) {\n usage.cacheCreationInputTokens = chunk.providerMetadata.anthropic.cacheCreationInputTokens\n }\n }\n controller.enqueue(chunk)\n },\n\n flush() {\n const latency = (Date.now() - startTime) / 1000\n sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId,\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [{ content: generatedText, role: 'assistant' }],\n latency,\n baseURL,\n params: mergedParams as any,\n httpStatus: 200,\n usage,\n })\n },\n })\n\n return {\n stream: stream.pipeThrough(transformStream),\n ...rest,\n }\n } catch (error: any) {\n sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId,\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [],\n latency: 0,\n baseURL: '',\n params: mergedParams as any,\n httpStatus: error?.status ? error.status : 500,\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n isError: true,\n error: truncate(JSON.stringify(error)),\n })\n throw error\n }\n },\n }\n\n return middleware\n}\n\nexport const wrapVercelLanguageModel = (\n model: LanguageModelV1,\n phClient: PostHog,\n options: ClientOptions\n): LanguageModelV1 => {\n const traceId = options.posthogTraceId ?? uuidv4()\n const middleware = createInstrumentationMiddleware(phClient, model, {\n ...options,\n posthogTraceId: traceId,\n posthogDistinctId: options.posthogDistinctId ?? traceId,\n })\n\n const wrappedModel = wrapLanguageModel({\n model,\n middleware,\n })\n\n return wrappedModel\n}\n"],"names":["MAX_OUTPUT_SIZE","STRING_FORMAT","getModelParams","params","modelParams","paramKeys","key","undefined","withPrivacyMode","client","privacyMode","input","privacy_mode","truncate","str","buffer","Buffer","from","length","truncatedBuffer","slice","toString","error","console","sanitizeValues","obj","jsonSafe","JSON","parse","stringify","Array","isArray","map","Object","fromEntries","entries","k","v","sendEventToPosthog","distinctId","traceId","model","provider","output","latency","baseURL","httpStatus","usage","isError","tools","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","event","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","groups","posthogGroups","mapVercelParams","temperature","max_tokens","maxTokens","top_p","topP","frequency_penalty","frequencyPenalty","presence_penalty","presencePenalty","stop","stopSequences","stream","mapVercelPrompt","prompt","promptsArray","role","content","p","c","type","text","image","URL","mimeType","file","data","toolCallId","toolName","args","result","mapVercelOutput","normalizedResult","object","reasoning","response","finishReason","warnings","providerMetadata","toolCalls","files","name","size","jsonOutput","extractProvider","toLowerCase","providerName","split","createInstrumentationMiddleware","phClient","options","middleware","wrapGenerate","doGenerate","startTime","Date","now","mergedParams","modelId","openai","cachedPromptTokens","anthropic","posthogDistinctId","posthogTraceId","promptTokens","completionTokens","status","wrapStream","doStream","generatedText","rest","transformStream","TransformStream","transform","chunk","controller","textDelta","enqueue","flush","pipeThrough","wrapVercelLanguageModel","uuidv4","wrappedModel","wrapLanguageModel"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/utils.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { PostHog } from 'posthog-node'
|
|
2
|
+
import { Buffer } from 'buffer'
|
|
2
3
|
import OpenAIOrignal from 'openai'
|
|
3
4
|
import AnthropicOriginal from '@anthropic-ai/sdk'
|
|
4
5
|
|
|
5
6
|
type ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams
|
|
6
7
|
type MessageCreateParams = AnthropicOriginal.Messages.MessageCreateParams
|
|
7
8
|
|
|
9
|
+
// limit large outputs by truncating to 200kb (approx 200k bytes)
|
|
10
|
+
const MAX_OUTPUT_SIZE = 200000
|
|
11
|
+
const STRING_FORMAT = 'utf8'
|
|
12
|
+
|
|
8
13
|
export interface MonitoringParams {
|
|
9
14
|
posthogDistinctId?: string
|
|
10
15
|
posthogTraceId?: string
|
|
@@ -107,6 +112,20 @@ export const withPrivacyMode = (client: PostHog, privacyMode: boolean, input: an
|
|
|
107
112
|
return (client as any).privacy_mode || privacyMode ? null : input
|
|
108
113
|
}
|
|
109
114
|
|
|
115
|
+
export const truncate = (str: string): string => {
|
|
116
|
+
try {
|
|
117
|
+
const buffer = Buffer.from(str, STRING_FORMAT)
|
|
118
|
+
if (buffer.length <= MAX_OUTPUT_SIZE) {
|
|
119
|
+
return str
|
|
120
|
+
}
|
|
121
|
+
const truncatedBuffer = buffer.slice(0, MAX_OUTPUT_SIZE)
|
|
122
|
+
return `${truncatedBuffer.toString(STRING_FORMAT)}... [truncated]`
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error('Error truncating, likely not a string')
|
|
125
|
+
return str
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
110
129
|
export type SendEventToPosthogParams = {
|
|
111
130
|
client: PostHog
|
|
112
131
|
distinctId?: string
|
|
@@ -131,6 +150,21 @@ export type SendEventToPosthogParams = {
|
|
|
131
150
|
tools?: any
|
|
132
151
|
}
|
|
133
152
|
|
|
153
|
+
function sanitizeValues(obj: any): any {
|
|
154
|
+
if (obj === undefined || obj === null) {
|
|
155
|
+
return obj
|
|
156
|
+
}
|
|
157
|
+
const jsonSafe = JSON.parse(JSON.stringify(obj))
|
|
158
|
+
if (typeof jsonSafe === 'string') {
|
|
159
|
+
return Buffer.from(jsonSafe, STRING_FORMAT).toString(STRING_FORMAT)
|
|
160
|
+
} else if (Array.isArray(jsonSafe)) {
|
|
161
|
+
return jsonSafe.map(sanitizeValues)
|
|
162
|
+
} else if (jsonSafe && typeof jsonSafe === 'object') {
|
|
163
|
+
return Object.fromEntries(Object.entries(jsonSafe).map(([k, v]) => [k, sanitizeValues(v)]))
|
|
164
|
+
}
|
|
165
|
+
return jsonSafe
|
|
166
|
+
}
|
|
167
|
+
|
|
134
168
|
export const sendEventToPosthog = ({
|
|
135
169
|
client,
|
|
136
170
|
distinctId,
|
|
@@ -149,11 +183,16 @@ export const sendEventToPosthog = ({
|
|
|
149
183
|
tools,
|
|
150
184
|
}: SendEventToPosthogParams): void => {
|
|
151
185
|
if (client.capture) {
|
|
186
|
+
// sanitize input and output for UTF-8 validity
|
|
187
|
+
const safeInput = sanitizeValues(input)
|
|
188
|
+
const safeOutput = sanitizeValues(output)
|
|
189
|
+
const safeError = sanitizeValues(error)
|
|
190
|
+
|
|
152
191
|
let errorData = {}
|
|
153
192
|
if (isError) {
|
|
154
193
|
errorData = {
|
|
155
194
|
$ai_is_error: true,
|
|
156
|
-
$ai_error:
|
|
195
|
+
$ai_error: safeError,
|
|
157
196
|
}
|
|
158
197
|
}
|
|
159
198
|
let costOverrideData = {}
|
|
@@ -180,8 +219,8 @@ export const sendEventToPosthog = ({
|
|
|
180
219
|
$ai_provider: params.posthogProviderOverride ?? provider,
|
|
181
220
|
$ai_model: params.posthogModelOverride ?? model,
|
|
182
221
|
$ai_model_parameters: getModelParams(params),
|
|
183
|
-
$ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false,
|
|
184
|
-
$ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false,
|
|
222
|
+
$ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),
|
|
223
|
+
$ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),
|
|
185
224
|
$ai_http_status: httpStatus,
|
|
186
225
|
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
187
226
|
$ai_output_tokens: usage.outputTokens ?? 0,
|
package/src/vercel/middleware.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { experimental_wrapLanguageModel as wrapLanguageModel } from 'ai'
|
|
|
2
2
|
import type { LanguageModelV1, LanguageModelV1Middleware, LanguageModelV1Prompt, LanguageModelV1StreamPart } from 'ai'
|
|
3
3
|
import { v4 as uuidv4 } from 'uuid'
|
|
4
4
|
import { PostHog } from 'posthog-node'
|
|
5
|
-
import { CostOverride, sendEventToPosthog } from '../utils'
|
|
5
|
+
import { CostOverride, sendEventToPosthog, truncate } from '../utils'
|
|
6
6
|
|
|
7
7
|
interface ClientOptions {
|
|
8
8
|
posthogDistinctId?: string
|
|
@@ -49,14 +49,23 @@ const mapVercelParams = (params: any): Record<string, any> => {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const mapVercelPrompt = (prompt: LanguageModelV1Prompt): PostHogInput[] => {
|
|
52
|
-
|
|
52
|
+
// normalize single inputs into an array of messages
|
|
53
|
+
let promptsArray: any[]
|
|
54
|
+
if (typeof prompt === 'string') {
|
|
55
|
+
promptsArray = [{ role: 'user', content: prompt }]
|
|
56
|
+
} else if (!Array.isArray(prompt)) {
|
|
57
|
+
promptsArray = [prompt]
|
|
58
|
+
} else {
|
|
59
|
+
promptsArray = prompt
|
|
60
|
+
}
|
|
61
|
+
return promptsArray.map((p) => {
|
|
53
62
|
let content = {}
|
|
54
63
|
if (Array.isArray(p.content)) {
|
|
55
|
-
content = p.content.map((c) => {
|
|
64
|
+
content = p.content.map((c: any) => {
|
|
56
65
|
if (c.type === 'text') {
|
|
57
66
|
return {
|
|
58
67
|
type: 'text',
|
|
59
|
-
content: c.text,
|
|
68
|
+
content: truncate(c.text),
|
|
60
69
|
}
|
|
61
70
|
} else if (c.type === 'image') {
|
|
62
71
|
return {
|
|
@@ -102,7 +111,7 @@ const mapVercelPrompt = (prompt: LanguageModelV1Prompt): PostHogInput[] => {
|
|
|
102
111
|
} else {
|
|
103
112
|
content = {
|
|
104
113
|
type: 'text',
|
|
105
|
-
text: p.content,
|
|
114
|
+
text: truncate(p.content),
|
|
106
115
|
}
|
|
107
116
|
}
|
|
108
117
|
return {
|
|
@@ -113,25 +122,41 @@ const mapVercelPrompt = (prompt: LanguageModelV1Prompt): PostHogInput[] => {
|
|
|
113
122
|
}
|
|
114
123
|
|
|
115
124
|
const mapVercelOutput = (result: any): PostHogInput[] => {
|
|
125
|
+
// normalize string results to object
|
|
126
|
+
const normalizedResult = typeof result === 'string' ? { text: result } : result
|
|
116
127
|
const output = {
|
|
117
|
-
...(
|
|
118
|
-
...(
|
|
119
|
-
...(
|
|
120
|
-
...(
|
|
121
|
-
...(
|
|
122
|
-
...(
|
|
123
|
-
...(
|
|
124
|
-
...(
|
|
128
|
+
...(normalizedResult.text ? { text: normalizedResult.text } : {}),
|
|
129
|
+
...(normalizedResult.object ? { object: normalizedResult.object } : {}),
|
|
130
|
+
...(normalizedResult.reasoning ? { reasoning: normalizedResult.reasoning } : {}),
|
|
131
|
+
...(normalizedResult.response ? { response: normalizedResult.response } : {}),
|
|
132
|
+
...(normalizedResult.finishReason ? { finishReason: normalizedResult.finishReason } : {}),
|
|
133
|
+
...(normalizedResult.usage ? { usage: normalizedResult.usage } : {}),
|
|
134
|
+
...(normalizedResult.warnings ? { warnings: normalizedResult.warnings } : {}),
|
|
135
|
+
...(normalizedResult.providerMetadata ? { toolCalls: normalizedResult.providerMetadata } : {}),
|
|
136
|
+
...(normalizedResult.files
|
|
137
|
+
? {
|
|
138
|
+
files: normalizedResult.files.map((file: any) => ({
|
|
139
|
+
name: file.name,
|
|
140
|
+
size: file.size,
|
|
141
|
+
type: file.type,
|
|
142
|
+
})),
|
|
143
|
+
}
|
|
144
|
+
: {}),
|
|
125
145
|
}
|
|
126
|
-
// if text and no object or reasoning, return text
|
|
127
146
|
if (output.text && !output.object && !output.reasoning) {
|
|
128
|
-
return [{ content: output.text, role: 'assistant' }]
|
|
147
|
+
return [{ content: truncate(output.text as string), role: 'assistant' }]
|
|
148
|
+
}
|
|
149
|
+
// otherwise stringify and truncate
|
|
150
|
+
try {
|
|
151
|
+
const jsonOutput = JSON.stringify(output)
|
|
152
|
+
return [{ content: truncate(jsonOutput), role: 'assistant' }]
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error('Error stringifying output')
|
|
155
|
+
return []
|
|
129
156
|
}
|
|
130
|
-
return [{ content: JSON.stringify(output), role: 'assistant' }]
|
|
131
157
|
}
|
|
132
158
|
|
|
133
159
|
const extractProvider = (model: LanguageModelV1): string => {
|
|
134
|
-
// vercel provider is in the format of provider.endpoint
|
|
135
160
|
const provider = model.provider.toLowerCase()
|
|
136
161
|
const providerName = provider.split('.')[0]
|
|
137
162
|
return providerName
|
|
@@ -212,7 +237,7 @@ export const createInstrumentationMiddleware = (
|
|
|
212
237
|
outputTokens: 0,
|
|
213
238
|
},
|
|
214
239
|
isError: true,
|
|
215
|
-
error: JSON.stringify(error),
|
|
240
|
+
error: truncate(JSON.stringify(error)),
|
|
216
241
|
})
|
|
217
242
|
throw error
|
|
218
243
|
}
|
|
@@ -305,7 +330,7 @@ export const createInstrumentationMiddleware = (
|
|
|
305
330
|
outputTokens: 0,
|
|
306
331
|
},
|
|
307
332
|
isError: true,
|
|
308
|
-
error: JSON.stringify(error),
|
|
333
|
+
error: truncate(JSON.stringify(error)),
|
|
309
334
|
})
|
|
310
335
|
throw error
|
|
311
336
|
}
|