@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.
@@ -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: 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, input),
74
- $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, output),
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
- return prompt.map(p => {
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
- ...(result.text ? {
174
- text: result.text
224
+ ...(normalizedResult.text ? {
225
+ text: normalizedResult.text
226
+ } : {}),
227
+ ...(normalizedResult.object ? {
228
+ object: normalizedResult.object
175
229
  } : {}),
176
- ...(result.object ? {
177
- object: result.object
230
+ ...(normalizedResult.reasoning ? {
231
+ reasoning: normalizedResult.reasoning
178
232
  } : {}),
179
- ...(result.reasoning ? {
180
- reasoning: result.reasoning
233
+ ...(normalizedResult.response ? {
234
+ response: normalizedResult.response
181
235
  } : {}),
182
- ...(result.response ? {
183
- response: result.response
236
+ ...(normalizedResult.finishReason ? {
237
+ finishReason: normalizedResult.finishReason
184
238
  } : {}),
185
- ...(result.finishReason ? {
186
- finishReason: result.finishReason
239
+ ...(normalizedResult.usage ? {
240
+ usage: normalizedResult.usage
187
241
  } : {}),
188
- ...(result.usage ? {
189
- usage: result.usage
242
+ ...(normalizedResult.warnings ? {
243
+ warnings: normalizedResult.warnings
190
244
  } : {}),
191
- ...(result.warnings ? {
192
- warnings: result.warnings
245
+ ...(normalizedResult.providerMetadata ? {
246
+ toolCalls: normalizedResult.providerMetadata
193
247
  } : {}),
194
- ...(result.providerMetadata ? {
195
- toolCalls: result.providerMetadata
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/ai",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "PostHog Node.js AI integrations",
5
5
  "repository": {
6
6
  "type": "git",
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: 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, input),
184
- $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, output),
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,
@@ -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
- return prompt.map((p) => {
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
- ...(result.text ? { text: result.text } : {}),
118
- ...(result.object ? { object: result.object } : {}),
119
- ...(result.reasoning ? { reasoning: result.reasoning } : {}),
120
- ...(result.response ? { response: result.response } : {}),
121
- ...(result.finishReason ? { finishReason: result.finishReason } : {}),
122
- ...(result.usage ? { usage: result.usage } : {}),
123
- ...(result.warnings ? { warnings: result.warnings } : {}),
124
- ...(result.providerMetadata ? { toolCalls: result.providerMetadata } : {}),
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
  }