@posthog/ai 6.0.0 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -258,77 +258,75 @@ const mapVercelPrompt = messages => {
258
258
  return inputs;
259
259
  };
260
260
  const mapVercelOutput = result => {
261
- const content = [];
262
- if (result.text) {
263
- content.push({
264
- type: 'text',
265
- text: truncate(result.text)
266
- });
267
- }
268
- if (result.toolCalls && Array.isArray(result.toolCalls)) {
269
- for (const toolCall of result.toolCalls) {
270
- content.push({
271
- type: 'function',
272
- id: toolCall.toolCallId,
261
+ const content = result.map(item => {
262
+ if (item.type === 'text') {
263
+ return {
264
+ type: 'text',
265
+ text: truncate(item.text)
266
+ };
267
+ }
268
+ if (item.type === 'tool-call') {
269
+ return {
270
+ type: 'tool-call',
271
+ id: item.toolCallId,
273
272
  function: {
274
- name: toolCall.toolName,
275
- arguments: typeof toolCall.args === 'string' ? toolCall.args : JSON.stringify(toolCall.args)
273
+ name: item.toolName,
274
+ arguments: item.args || JSON.stringify(item.arguments || {})
276
275
  }
277
- });
276
+ };
278
277
  }
279
- }
278
+ if (item.type === 'reasoning') {
279
+ return {
280
+ type: 'reasoning',
281
+ text: truncate(item.text)
282
+ };
283
+ }
284
+ if (item.type === 'file') {
285
+ // Handle files similar to input mapping - avoid large base64 data
286
+ let fileData;
287
+ if (item.data instanceof URL) {
288
+ fileData = item.data.toString();
289
+ } else if (typeof item.data === 'string') {
290
+ // Check if it's base64 data and potentially large
291
+ if (item.data.startsWith('data:') || item.data.length > 1000) {
292
+ fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
293
+ } else {
294
+ fileData = item.data;
295
+ }
296
+ } else {
297
+ fileData = `[binary ${item.mediaType} file]`;
298
+ }
299
+ return {
300
+ type: 'file',
301
+ name: 'generated_file',
302
+ mediaType: item.mediaType,
303
+ data: fileData
304
+ };
305
+ }
306
+ if (item.type === 'source') {
307
+ return {
308
+ type: 'source',
309
+ sourceType: item.sourceType,
310
+ id: item.id,
311
+ url: item.url || '',
312
+ title: item.title || ''
313
+ };
314
+ }
315
+ // Fallback for unknown types - try to extract text if possible
316
+ return {
317
+ type: 'text',
318
+ text: truncate(JSON.stringify(item))
319
+ };
320
+ });
280
321
  if (content.length > 0) {
281
322
  return [{
282
323
  role: 'assistant',
283
324
  content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
284
325
  }];
285
326
  }
286
- // Fallback to original behavior for other result types TODO: check if we can remove this
287
- const normalizedResult = typeof result === 'string' ? {
288
- text: result
289
- } : result;
290
- const output = {
291
- ...(normalizedResult.text ? {
292
- text: normalizedResult.text
293
- } : {}),
294
- ...(normalizedResult.object ? {
295
- object: normalizedResult.object
296
- } : {}),
297
- ...(normalizedResult.reasoningText ? {
298
- reasoning: normalizedResult.reasoningText
299
- } : {}),
300
- ...(normalizedResult.response ? {
301
- response: normalizedResult.response
302
- } : {}),
303
- ...(normalizedResult.finishReason ? {
304
- finishReason: normalizedResult.finishReason
305
- } : {}),
306
- ...(normalizedResult.usage ? {
307
- usage: normalizedResult.usage
308
- } : {}),
309
- ...(normalizedResult.warnings ? {
310
- warnings: normalizedResult.warnings
311
- } : {}),
312
- ...(normalizedResult.providerMetadata ? {
313
- toolCalls: normalizedResult.providerMetadata
314
- } : {}),
315
- ...(normalizedResult.files ? {
316
- files: normalizedResult.files.map(file => ({
317
- name: file.name,
318
- size: file.size,
319
- type: file.type
320
- }))
321
- } : {})
322
- };
323
- if (output.text && !output.object && !output.reasoning) {
324
- return [{
325
- content: truncate(output.text),
326
- role: 'assistant'
327
- }];
328
- }
329
327
  // otherwise stringify and truncate
330
328
  try {
331
- const jsonOutput = JSON.stringify(output);
329
+ const jsonOutput = JSON.stringify(result);
332
330
  return [{
333
331
  content: truncate(jsonOutput),
334
332
  role: 'assistant'
@@ -360,7 +358,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
360
358
  const modelId = options.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
361
359
  const provider = options.posthogProviderOverride ?? extractProvider(model);
362
360
  const baseURL = ''; // cannot currently get baseURL from vercel
363
- const content = mapVercelOutput(result);
361
+ const content = mapVercelOutput(result.content);
364
362
  const latency = (Date.now() - startTime) / 1000;
365
363
  const providerMetadata = result.providerMetadata;
366
364
  const additionalTokenValues = {
@@ -475,7 +473,26 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
475
473
  },
476
474
  flush: async () => {
477
475
  const latency = (Date.now() - startTime) / 1000;
478
- const outputContent = reasoningText ? `${reasoningText}\n\n${generatedText}` : generatedText;
476
+ // Build content array similar to mapVercelOutput structure
477
+ const content = [];
478
+ if (reasoningText) {
479
+ content.push({
480
+ type: 'reasoning',
481
+ text: truncate(reasoningText)
482
+ });
483
+ }
484
+ if (generatedText) {
485
+ content.push({
486
+ type: 'text',
487
+ text: truncate(generatedText)
488
+ });
489
+ }
490
+
491
+ // Structure output like mapVercelOutput does
492
+ const output = content.length > 0 ? [{
493
+ role: 'assistant',
494
+ content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
495
+ }] : [];
479
496
  await sendEventToPosthog({
480
497
  client: phClient,
481
498
  distinctId: options.posthogDistinctId,
@@ -483,10 +500,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
483
500
  model: modelId,
484
501
  provider: provider,
485
502
  input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
486
- output: [{
487
- content: outputContent,
488
- role: 'assistant'
489
- }],
503
+ output: output,
490
504
  latency,
491
505
  baseURL,
492
506
  params: mergedParams,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","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'\nimport type { ChatCompletionTool } from 'openai/resources/chat/completions'\nimport type { Tool as GeminiTool } from '@google/genai'\nimport type { FormattedMessage, FormattedContent, TokenUsage } from './types'\n\ntype ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams\ntype MessageCreateParams = AnthropicOriginal.Messages.MessageCreateParams\ntype ResponseCreateParams = OpenAIOrignal.Responses.ResponseCreateParams\ntype AnthropicTool = AnthropicOriginal.Tool\n\n// limit large outputs by truncating to 200kb (approx 200k bytes)\nexport const MAX_OUTPUT_SIZE = 200000\nconst STRING_FORMAT = 'utf8'\n\nexport interface MonitoringParams {\n posthogDistinctId?: string\n posthogTraceId?: string\n posthogProperties?: Record<string, any>\n posthogPrivacyMode?: boolean\n posthogGroups?: Record<string, any>\n posthogModelOverride?: string\n posthogProviderOverride?: string\n posthogCostOverride?: CostOverride\n posthogCaptureImmediate?: boolean\n}\n\nexport interface CostOverride {\n inputCost: number\n outputCost: number\n}\n\nexport const getModelParams = (\n params: ((ChatCompletionCreateParamsBase | MessageCreateParams | ResponseCreateParams) & 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): FormattedMessage[] => {\n if (!response) {\n return []\n }\n if (provider === 'anthropic') {\n return formatResponseAnthropic(response)\n } else if (provider === 'openai') {\n return formatResponseOpenAI(response)\n } else if (provider === 'gemini') {\n return formatResponseGemini(response)\n }\n return []\n}\n\nexport const formatResponseAnthropic = (response: any): FormattedMessage[] => {\n const output: FormattedMessage[] = []\n const content: FormattedContent = []\n\n for (const choice of response.content ?? []) {\n if (choice?.type === 'text' && choice?.text) {\n content.push({ type: 'text', text: choice.text })\n } else if (choice?.type === 'tool_use' && choice?.name && choice?.id) {\n content.push({\n type: 'function',\n id: choice.id,\n function: {\n name: choice.name,\n arguments: choice.input || {},\n },\n })\n }\n }\n\n if (content.length > 0) {\n output.push({\n role: 'assistant',\n content,\n })\n }\n\n return output\n}\n\nexport const formatResponseOpenAI = (response: any): FormattedMessage[] => {\n const output: FormattedMessage[] = []\n\n if (response.choices) {\n for (const choice of response.choices) {\n const content: FormattedContent = []\n let role = 'assistant'\n\n if (choice.message) {\n if (choice.message.role) {\n role = choice.message.role\n }\n\n if (choice.message.content) {\n content.push({ type: 'text', text: choice.message.content })\n }\n\n if (choice.message.tool_calls) {\n for (const toolCall of choice.message.tool_calls) {\n content.push({\n type: 'function',\n id: toolCall.id,\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })\n }\n }\n }\n\n if (content.length > 0) {\n output.push({\n role,\n content,\n })\n }\n }\n }\n\n // Handle Responses API format\n if (response.output) {\n const content: FormattedContent = []\n let role = 'assistant'\n\n for (const item of response.output) {\n if (item.type === 'message') {\n role = item.role\n\n if (item.content && Array.isArray(item.content)) {\n for (const contentItem of item.content) {\n if (contentItem.type === 'output_text' && contentItem.text) {\n content.push({ type: 'text', text: contentItem.text })\n } else if (contentItem.text) {\n content.push({ type: 'text', text: contentItem.text })\n } else if (contentItem.type === 'input_image' && contentItem.image_url) {\n content.push({\n type: 'image',\n image: contentItem.image_url,\n })\n }\n }\n } else if (item.content) {\n content.push({ type: 'text', text: String(item.content) })\n }\n } else if (item.type === 'function_call') {\n content.push({\n type: 'function',\n id: item.call_id || item.id || '',\n function: {\n name: item.name,\n arguments: item.arguments || {},\n },\n })\n }\n }\n\n if (content.length > 0) {\n output.push({\n role,\n content,\n })\n }\n }\n\n return output\n}\n\nexport const formatResponseGemini = (response: any): FormattedMessage[] => {\n const output: FormattedMessage[] = []\n\n if (response.candidates && Array.isArray(response.candidates)) {\n for (const candidate of response.candidates) {\n if (candidate.content && candidate.content.parts) {\n const content: FormattedContent = []\n\n for (const part of candidate.content.parts) {\n if (part.text) {\n content.push({ type: 'text', text: part.text })\n } else if (part.functionCall) {\n content.push({\n type: 'function',\n function: {\n name: part.functionCall.name,\n arguments: part.functionCall.args,\n },\n })\n }\n }\n\n if (content.length > 0) {\n output.push({\n role: 'assistant',\n content,\n })\n }\n } else if (candidate.text) {\n output.push({\n role: 'assistant',\n content: [{ type: 'text', text: candidate.text }],\n })\n }\n }\n } else if (response.text) {\n output.push({\n role: 'assistant',\n content: [{ type: 'text', text: response.text }],\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\n/**\n * Extract available tool calls from the request parameters.\n * These are the tools provided to the LLM, not the tool calls in the response.\n */\nexport const extractAvailableToolCalls = (\n provider: string,\n params: any\n): ChatCompletionTool[] | AnthropicTool[] | GeminiTool[] | null => {\n if (provider === 'anthropic') {\n if (params.tools) {\n return params.tools\n }\n\n return null\n } else if (provider === 'gemini') {\n if (params.config && params.config.tools) {\n return params.config.tools\n }\n\n return null\n } else if (provider === 'openai') {\n if (params.tools) {\n return params.tools\n }\n\n return null\n } else if (provider === 'vercel') {\n // Vercel AI SDK stores tools in params.mode.tools when mode type is 'regular'\n if (params.mode?.type === 'regular' && params.mode.tools) {\n return params.mode.tools\n }\n\n return null\n }\n\n return null\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?: TokenUsage\n params: (ChatCompletionCreateParamsBase | MessageCreateParams | ResponseCreateParams) & MonitoringParams\n isError?: boolean\n error?: string\n tools?: ChatCompletionTool[] | AnthropicTool[] | GeminiTool[] | null\n captureImmediate?: boolean\n}\n\nfunction sanitizeValues(obj: any): any {\n if (obj === undefined || obj === null) {\n return obj\n }\n const jsonSafe = JSON.parse(JSON.stringify(obj))\n if (typeof jsonSafe === 'string') {\n return Buffer.from(jsonSafe, STRING_FORMAT).toString(STRING_FORMAT)\n } else if (Array.isArray(jsonSafe)) {\n return jsonSafe.map(sanitizeValues)\n } else if (jsonSafe && typeof jsonSafe === 'object') {\n return Object.fromEntries(Object.entries(jsonSafe).map(([k, v]) => [k, sanitizeValues(v)]))\n }\n return jsonSafe\n}\n\nexport const sendEventToPosthog = async ({\n client,\n distinctId,\n traceId,\n model,\n provider,\n input,\n output,\n latency,\n baseURL,\n params,\n httpStatus = 200,\n usage = {},\n isError = false,\n error,\n tools,\n captureImmediate = false,\n}: SendEventToPosthogParams): Promise<void> => {\n if (!client.capture) {\n return Promise.resolve()\n }\n // sanitize input and output for UTF-8 validity\n const safeInput = sanitizeValues(input)\n const safeOutput = sanitizeValues(output)\n const safeError = sanitizeValues(error)\n\n let errorData = {}\n if (isError) {\n errorData = {\n $ai_is_error: true,\n $ai_error: safeError,\n }\n }\n let costOverrideData = {}\n if (params.posthogCostOverride) {\n const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0)\n const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0)\n costOverrideData = {\n $ai_input_cost_usd: inputCostUSD,\n $ai_output_cost_usd: outputCostUSD,\n $ai_total_cost_usd: inputCostUSD + outputCostUSD,\n }\n }\n\n const additionalTokenValues = {\n ...(usage.reasoningTokens ? { $ai_reasoning_tokens: usage.reasoningTokens } : {}),\n ...(usage.cacheReadInputTokens ? { $ai_cache_read_input_tokens: usage.cacheReadInputTokens } : {}),\n ...(usage.cacheCreationInputTokens ? { $ai_cache_creation_input_tokens: usage.cacheCreationInputTokens } : {}),\n }\n\n const properties = {\n $ai_provider: params.posthogProviderOverride ?? provider,\n $ai_model: params.posthogModelOverride ?? model,\n $ai_model_parameters: getModelParams(params),\n $ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),\n $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),\n $ai_http_status: httpStatus,\n $ai_input_tokens: usage.inputTokens ?? 0,\n $ai_output_tokens: usage.outputTokens ?? 0,\n ...additionalTokenValues,\n $ai_latency: latency,\n $ai_trace_id: traceId,\n $ai_base_url: baseURL,\n ...params.posthogProperties,\n ...(distinctId ? {} : { $process_person_profile: false }),\n ...(tools ? { $ai_tools: tools } : {}),\n ...errorData,\n ...costOverrideData,\n }\n\n const event = {\n distinctId: distinctId ?? traceId,\n event: '$ai_generation',\n properties,\n groups: params.posthogGroups,\n }\n\n if (captureImmediate) {\n // await capture promise to send single event in serverless environments\n await client.captureImmediate(event)\n } else {\n client.capture(event)\n }\n}\n","import { wrapLanguageModel } from 'ai'\nimport type {\n LanguageModelV2,\n LanguageModelV2Middleware,\n LanguageModelV2Prompt,\n LanguageModelV2StreamPart,\n} from '@ai-sdk/provider'\nimport { v4 as uuidv4 } from 'uuid'\nimport { PostHog } from 'posthog-node'\nimport { CostOverride, sendEventToPosthog, truncate, MAX_OUTPUT_SIZE, extractAvailableToolCalls } from '../utils'\nimport { Buffer } from 'buffer'\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 posthogCaptureImmediate?: boolean\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 posthogCaptureImmediate?: boolean\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_output_tokens: params.maxOutputTokens,\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 = (messages: LanguageModelV2Prompt): PostHogInput[] => {\n // Map and truncate individual content\n const inputs: PostHogInput[] = messages.map((message) => {\n let content: any\n\n // Handle system role which has string content\n if (message.role === 'system') {\n content = [\n {\n type: 'text',\n text: truncate(String(message.content)),\n },\n ]\n } else {\n // Handle other roles which have array content\n if (Array.isArray(message.content)) {\n content = message.content.map((c: any) => {\n if (c.type === 'text') {\n return {\n type: 'text',\n text: truncate(c.text),\n }\n } else if (c.type === 'file') {\n return {\n type: 'file',\n file: c.data instanceof URL ? c.data.toString() : 'raw files not supported',\n mediaType: c.mediaType,\n }\n } else if (c.type === 'reasoning') {\n return {\n type: 'reasoning',\n text: truncate(c.reasoning),\n }\n } else if (c.type === 'tool-call') {\n return {\n type: 'tool-call',\n toolCallId: c.toolCallId,\n toolName: c.toolName,\n input: c.input,\n }\n } else if (c.type === 'tool-result') {\n return {\n type: 'tool-result',\n toolCallId: c.toolCallId,\n toolName: c.toolName,\n output: c.output,\n isError: c.isError,\n }\n }\n return {\n type: 'text',\n text: '',\n }\n })\n } else {\n // Fallback for non-array content\n content = [\n {\n type: 'text',\n text: truncate(String(message.content)),\n },\n ]\n }\n }\n\n return {\n role: message.role,\n content,\n }\n })\n\n try {\n // Trim the inputs array until its JSON size fits within MAX_OUTPUT_SIZE\n let serialized = JSON.stringify(inputs)\n let removedCount = 0\n // We need to keep track of the initial size of the inputs array because we're going to be mutating it\n const initialSize = inputs.length\n for (let i = 0; i < initialSize && Buffer.byteLength(serialized, 'utf8') > MAX_OUTPUT_SIZE; i++) {\n inputs.shift()\n removedCount++\n serialized = JSON.stringify(inputs)\n }\n if (removedCount > 0) {\n // Add one placeholder to indicate how many were removed\n inputs.unshift({\n role: 'posthog',\n content: `[${removedCount} message${removedCount === 1 ? '' : 's'} removed due to size limit]`,\n })\n }\n } catch (error) {\n console.error('Error stringifying inputs', error)\n return [{ role: 'posthog', content: 'An error occurred while processing your request. Please try again.' }]\n }\n return inputs\n}\n\nconst mapVercelOutput = (result: any): PostHogInput[] => {\n const content: any[] = []\n\n if (result.text) {\n content.push({ type: 'text', text: truncate(result.text) })\n }\n\n if (result.toolCalls && Array.isArray(result.toolCalls)) {\n for (const toolCall of result.toolCalls) {\n content.push({\n type: 'function',\n id: toolCall.toolCallId,\n function: {\n name: toolCall.toolName,\n arguments: typeof toolCall.args === 'string' ? toolCall.args : JSON.stringify(toolCall.args),\n },\n })\n }\n }\n\n if (content.length > 0) {\n return [\n {\n role: 'assistant',\n content: content.length === 1 && content[0].type === 'text' ? content[0].text : content,\n },\n ]\n }\n // Fallback to original behavior for other result types TODO: check if we can remove this\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.reasoningText ? { reasoning: normalizedResult.reasoningText } : {}),\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: LanguageModelV2): 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: LanguageModelV2,\n options: CreateInstrumentationMiddlewareOptions\n): LanguageModelV2Middleware => {\n const middleware: LanguageModelV2Middleware = {\n wrapGenerate: async ({ doGenerate, params }) => {\n const startTime = Date.now()\n const mergedParams = {\n ...options,\n ...mapVercelParams(params),\n }\n const availableTools = extractAvailableToolCalls('vercel', params)\n\n try {\n const result = await doGenerate()\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 const latency = (Date.now() - startTime) / 1000\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 await sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId ?? uuidv4(),\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: content,\n latency,\n baseURL,\n params: mergedParams as any,\n httpStatus: 200,\n usage: {\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n ...additionalTokenValues,\n },\n tools: availableTools,\n captureImmediate: options.posthogCaptureImmediate,\n })\n\n return result\n } catch (error: any) {\n const modelId = model.modelId\n await sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId ?? uuidv4(),\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 tools: availableTools,\n captureImmediate: options.posthogCaptureImmediate,\n })\n throw error\n }\n },\n\n wrapStream: async ({ doStream, params }) => {\n const startTime = Date.now()\n let generatedText = ''\n let reasoningText = ''\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 availableTools = extractAvailableToolCalls('vercel', params)\n const baseURL = '' // cannot currently get baseURL from vercel\n\n try {\n const { stream, ...rest } = await doStream()\n const transformStream = new TransformStream<LanguageModelV2StreamPart, LanguageModelV2StreamPart>({\n transform(chunk, controller) {\n // Handle new v5 streaming patterns\n if (chunk.type === 'text-delta') {\n generatedText += chunk.delta\n }\n if (chunk.type === 'reasoning-delta') {\n reasoningText += chunk.delta // New in v5\n }\n if (chunk.type === 'finish') {\n usage = {\n inputTokens: chunk.usage?.inputTokens,\n outputTokens: chunk.usage?.outputTokens,\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: async () => {\n const latency = (Date.now() - startTime) / 1000\n const outputContent = reasoningText ? `${reasoningText}\\n\\n${generatedText}` : generatedText\n await sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId ?? uuidv4(),\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: [{ content: outputContent, role: 'assistant' }],\n latency,\n baseURL,\n params: mergedParams as any,\n httpStatus: 200,\n usage,\n tools: availableTools,\n captureImmediate: options.posthogCaptureImmediate,\n })\n },\n })\n\n return {\n stream: stream.pipeThrough(transformStream),\n ...rest,\n }\n } catch (error: any) {\n await sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId ?? uuidv4(),\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 tools: availableTools,\n captureImmediate: options.posthogCaptureImmediate,\n })\n throw error\n }\n },\n }\n\n return middleware\n}\n\nexport const wrapVercelLanguageModel = (\n model: LanguageModelV2,\n phClient: PostHog,\n options: ClientOptions\n): LanguageModelV2 => {\n const traceId = options.posthogTraceId ?? uuidv4()\n const middleware = createInstrumentationMiddleware(phClient, model, {\n ...options,\n posthogTraceId: traceId,\n posthogDistinctId: options.posthogDistinctId,\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","extractAvailableToolCalls","provider","mode","type","tools","sanitizeValues","obj","jsonSafe","JSON","parse","stringify","Array","isArray","map","Object","fromEntries","entries","k","v","sendEventToPosthog","distinctId","traceId","model","output","latency","baseURL","httpStatus","usage","isError","captureImmediate","capture","Promise","resolve","safeInput","safeOutput","safeError","errorData","$ai_is_error","$ai_error","costOverrideData","posthogCostOverride","inputCostUSD","inputCost","inputTokens","outputCostUSD","outputCost","outputTokens","$ai_input_cost_usd","$ai_output_cost_usd","$ai_total_cost_usd","additionalTokenValues","reasoningTokens","$ai_reasoning_tokens","cacheReadInputTokens","$ai_cache_read_input_tokens","cacheCreationInputTokens","$ai_cache_creation_input_tokens","properties","$ai_provider","posthogProviderOverride","$ai_model","posthogModelOverride","$ai_model_parameters","$ai_input","posthogPrivacyMode","$ai_output_choices","$ai_http_status","$ai_input_tokens","$ai_output_tokens","$ai_latency","$ai_trace_id","$ai_base_url","posthogProperties","$process_person_profile","$ai_tools","event","groups","posthogGroups","mapVercelParams","temperature","max_output_tokens","maxOutputTokens","top_p","topP","frequency_penalty","frequencyPenalty","presence_penalty","presencePenalty","stop","stopSequences","stream","mapVercelPrompt","messages","inputs","message","content","role","text","String","c","file","data","URL","mediaType","reasoning","toolCallId","toolName","serialized","removedCount","initialSize","i","byteLength","shift","unshift","mapVercelOutput","result","push","toolCalls","toolCall","id","function","name","arguments","args","normalizedResult","object","reasoningText","response","finishReason","warnings","providerMetadata","files","size","jsonOutput","extractProvider","toLowerCase","providerName","split","createInstrumentationMiddleware","phClient","options","middleware","wrapGenerate","doGenerate","startTime","Date","now","mergedParams","availableTools","modelId","openai","cachedPromptTokens","anthropic","posthogDistinctId","posthogTraceId","uuidv4","prompt","posthogCaptureImmediate","status","wrapStream","doStream","generatedText","rest","transformStream","TransformStream","transform","chunk","controller","delta","enqueue","flush","outputContent","pipeThrough","wrapVercelLanguageModel","wrappedModel","wrapLanguageModel"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","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'\nimport type { ChatCompletionTool } from 'openai/resources/chat/completions'\nimport type { Tool as GeminiTool } from '@google/genai'\nimport type { FormattedMessage, FormattedContent, TokenUsage } from './types'\n\ntype ChatCompletionCreateParamsBase = OpenAIOrignal.Chat.Completions.ChatCompletionCreateParams\ntype MessageCreateParams = AnthropicOriginal.Messages.MessageCreateParams\ntype ResponseCreateParams = OpenAIOrignal.Responses.ResponseCreateParams\ntype AnthropicTool = AnthropicOriginal.Tool\n\n// limit large outputs by truncating to 200kb (approx 200k bytes)\nexport const MAX_OUTPUT_SIZE = 200000\nconst STRING_FORMAT = 'utf8'\n\nexport interface MonitoringParams {\n posthogDistinctId?: string\n posthogTraceId?: string\n posthogProperties?: Record<string, any>\n posthogPrivacyMode?: boolean\n posthogGroups?: Record<string, any>\n posthogModelOverride?: string\n posthogProviderOverride?: string\n posthogCostOverride?: CostOverride\n posthogCaptureImmediate?: boolean\n}\n\nexport interface CostOverride {\n inputCost: number\n outputCost: number\n}\n\nexport const getModelParams = (\n params: ((ChatCompletionCreateParamsBase | MessageCreateParams | ResponseCreateParams) & 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): FormattedMessage[] => {\n if (!response) {\n return []\n }\n if (provider === 'anthropic') {\n return formatResponseAnthropic(response)\n } else if (provider === 'openai') {\n return formatResponseOpenAI(response)\n } else if (provider === 'gemini') {\n return formatResponseGemini(response)\n }\n return []\n}\n\nexport const formatResponseAnthropic = (response: any): FormattedMessage[] => {\n const output: FormattedMessage[] = []\n const content: FormattedContent = []\n\n for (const choice of response.content ?? []) {\n if (choice?.type === 'text' && choice?.text) {\n content.push({ type: 'text', text: choice.text })\n } else if (choice?.type === 'tool_use' && choice?.name && choice?.id) {\n content.push({\n type: 'function',\n id: choice.id,\n function: {\n name: choice.name,\n arguments: choice.input || {},\n },\n })\n }\n }\n\n if (content.length > 0) {\n output.push({\n role: 'assistant',\n content,\n })\n }\n\n return output\n}\n\nexport const formatResponseOpenAI = (response: any): FormattedMessage[] => {\n const output: FormattedMessage[] = []\n\n if (response.choices) {\n for (const choice of response.choices) {\n const content: FormattedContent = []\n let role = 'assistant'\n\n if (choice.message) {\n if (choice.message.role) {\n role = choice.message.role\n }\n\n if (choice.message.content) {\n content.push({ type: 'text', text: choice.message.content })\n }\n\n if (choice.message.tool_calls) {\n for (const toolCall of choice.message.tool_calls) {\n content.push({\n type: 'function',\n id: toolCall.id,\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })\n }\n }\n }\n\n if (content.length > 0) {\n output.push({\n role,\n content,\n })\n }\n }\n }\n\n // Handle Responses API format\n if (response.output) {\n const content: FormattedContent = []\n let role = 'assistant'\n\n for (const item of response.output) {\n if (item.type === 'message') {\n role = item.role\n\n if (item.content && Array.isArray(item.content)) {\n for (const contentItem of item.content) {\n if (contentItem.type === 'output_text' && contentItem.text) {\n content.push({ type: 'text', text: contentItem.text })\n } else if (contentItem.text) {\n content.push({ type: 'text', text: contentItem.text })\n } else if (contentItem.type === 'input_image' && contentItem.image_url) {\n content.push({\n type: 'image',\n image: contentItem.image_url,\n })\n }\n }\n } else if (item.content) {\n content.push({ type: 'text', text: String(item.content) })\n }\n } else if (item.type === 'function_call') {\n content.push({\n type: 'function',\n id: item.call_id || item.id || '',\n function: {\n name: item.name,\n arguments: item.arguments || {},\n },\n })\n }\n }\n\n if (content.length > 0) {\n output.push({\n role,\n content,\n })\n }\n }\n\n return output\n}\n\nexport const formatResponseGemini = (response: any): FormattedMessage[] => {\n const output: FormattedMessage[] = []\n\n if (response.candidates && Array.isArray(response.candidates)) {\n for (const candidate of response.candidates) {\n if (candidate.content && candidate.content.parts) {\n const content: FormattedContent = []\n\n for (const part of candidate.content.parts) {\n if (part.text) {\n content.push({ type: 'text', text: part.text })\n } else if (part.functionCall) {\n content.push({\n type: 'function',\n function: {\n name: part.functionCall.name,\n arguments: part.functionCall.args,\n },\n })\n }\n }\n\n if (content.length > 0) {\n output.push({\n role: 'assistant',\n content,\n })\n }\n } else if (candidate.text) {\n output.push({\n role: 'assistant',\n content: [{ type: 'text', text: candidate.text }],\n })\n }\n }\n } else if (response.text) {\n output.push({\n role: 'assistant',\n content: [{ type: 'text', text: response.text }],\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\n/**\n * Extract available tool calls from the request parameters.\n * These are the tools provided to the LLM, not the tool calls in the response.\n */\nexport const extractAvailableToolCalls = (\n provider: string,\n params: any\n): ChatCompletionTool[] | AnthropicTool[] | GeminiTool[] | null => {\n if (provider === 'anthropic') {\n if (params.tools) {\n return params.tools\n }\n\n return null\n } else if (provider === 'gemini') {\n if (params.config && params.config.tools) {\n return params.config.tools\n }\n\n return null\n } else if (provider === 'openai') {\n if (params.tools) {\n return params.tools\n }\n\n return null\n } else if (provider === 'vercel') {\n // Vercel AI SDK stores tools in params.mode.tools when mode type is 'regular'\n if (params.mode?.type === 'regular' && params.mode.tools) {\n return params.mode.tools\n }\n\n return null\n }\n\n return null\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?: TokenUsage\n params: (ChatCompletionCreateParamsBase | MessageCreateParams | ResponseCreateParams) & MonitoringParams\n isError?: boolean\n error?: string\n tools?: ChatCompletionTool[] | AnthropicTool[] | GeminiTool[] | null\n captureImmediate?: boolean\n}\n\nfunction sanitizeValues(obj: any): any {\n if (obj === undefined || obj === null) {\n return obj\n }\n const jsonSafe = JSON.parse(JSON.stringify(obj))\n if (typeof jsonSafe === 'string') {\n return Buffer.from(jsonSafe, STRING_FORMAT).toString(STRING_FORMAT)\n } else if (Array.isArray(jsonSafe)) {\n return jsonSafe.map(sanitizeValues)\n } else if (jsonSafe && typeof jsonSafe === 'object') {\n return Object.fromEntries(Object.entries(jsonSafe).map(([k, v]) => [k, sanitizeValues(v)]))\n }\n return jsonSafe\n}\n\nexport const sendEventToPosthog = async ({\n client,\n distinctId,\n traceId,\n model,\n provider,\n input,\n output,\n latency,\n baseURL,\n params,\n httpStatus = 200,\n usage = {},\n isError = false,\n error,\n tools,\n captureImmediate = false,\n}: SendEventToPosthogParams): Promise<void> => {\n if (!client.capture) {\n return Promise.resolve()\n }\n // sanitize input and output for UTF-8 validity\n const safeInput = sanitizeValues(input)\n const safeOutput = sanitizeValues(output)\n const safeError = sanitizeValues(error)\n\n let errorData = {}\n if (isError) {\n errorData = {\n $ai_is_error: true,\n $ai_error: safeError,\n }\n }\n let costOverrideData = {}\n if (params.posthogCostOverride) {\n const inputCostUSD = (params.posthogCostOverride.inputCost ?? 0) * (usage.inputTokens ?? 0)\n const outputCostUSD = (params.posthogCostOverride.outputCost ?? 0) * (usage.outputTokens ?? 0)\n costOverrideData = {\n $ai_input_cost_usd: inputCostUSD,\n $ai_output_cost_usd: outputCostUSD,\n $ai_total_cost_usd: inputCostUSD + outputCostUSD,\n }\n }\n\n const additionalTokenValues = {\n ...(usage.reasoningTokens ? { $ai_reasoning_tokens: usage.reasoningTokens } : {}),\n ...(usage.cacheReadInputTokens ? { $ai_cache_read_input_tokens: usage.cacheReadInputTokens } : {}),\n ...(usage.cacheCreationInputTokens ? { $ai_cache_creation_input_tokens: usage.cacheCreationInputTokens } : {}),\n }\n\n const properties = {\n $ai_provider: params.posthogProviderOverride ?? provider,\n $ai_model: params.posthogModelOverride ?? model,\n $ai_model_parameters: getModelParams(params),\n $ai_input: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeInput),\n $ai_output_choices: withPrivacyMode(client, params.posthogPrivacyMode ?? false, safeOutput),\n $ai_http_status: httpStatus,\n $ai_input_tokens: usage.inputTokens ?? 0,\n $ai_output_tokens: usage.outputTokens ?? 0,\n ...additionalTokenValues,\n $ai_latency: latency,\n $ai_trace_id: traceId,\n $ai_base_url: baseURL,\n ...params.posthogProperties,\n ...(distinctId ? {} : { $process_person_profile: false }),\n ...(tools ? { $ai_tools: tools } : {}),\n ...errorData,\n ...costOverrideData,\n }\n\n const event = {\n distinctId: distinctId ?? traceId,\n event: '$ai_generation',\n properties,\n groups: params.posthogGroups,\n }\n\n if (captureImmediate) {\n // await capture promise to send single event in serverless environments\n await client.captureImmediate(event)\n } else {\n client.capture(event)\n }\n}\n","import { wrapLanguageModel } from 'ai'\nimport type {\n LanguageModelV2,\n LanguageModelV2Content,\n LanguageModelV2Middleware,\n LanguageModelV2Prompt,\n LanguageModelV2StreamPart,\n} from '@ai-sdk/provider'\nimport { v4 as uuidv4 } from 'uuid'\nimport { PostHog } from 'posthog-node'\nimport { CostOverride, sendEventToPosthog, truncate, MAX_OUTPUT_SIZE, extractAvailableToolCalls } from '../utils'\nimport { Buffer } from 'buffer'\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 posthogCaptureImmediate?: boolean\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 posthogCaptureImmediate?: boolean\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_output_tokens: params.maxOutputTokens,\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 = (messages: LanguageModelV2Prompt): PostHogInput[] => {\n // Map and truncate individual content\n const inputs: PostHogInput[] = messages.map((message) => {\n let content: any\n\n // Handle system role which has string content\n if (message.role === 'system') {\n content = [\n {\n type: 'text',\n text: truncate(String(message.content)),\n },\n ]\n } else {\n // Handle other roles which have array content\n if (Array.isArray(message.content)) {\n content = message.content.map((c: any) => {\n if (c.type === 'text') {\n return {\n type: 'text',\n text: truncate(c.text),\n }\n } else if (c.type === 'file') {\n return {\n type: 'file',\n file: c.data instanceof URL ? c.data.toString() : 'raw files not supported',\n mediaType: c.mediaType,\n }\n } else if (c.type === 'reasoning') {\n return {\n type: 'reasoning',\n text: truncate(c.reasoning),\n }\n } else if (c.type === 'tool-call') {\n return {\n type: 'tool-call',\n toolCallId: c.toolCallId,\n toolName: c.toolName,\n input: c.input,\n }\n } else if (c.type === 'tool-result') {\n return {\n type: 'tool-result',\n toolCallId: c.toolCallId,\n toolName: c.toolName,\n output: c.output,\n isError: c.isError,\n }\n }\n return {\n type: 'text',\n text: '',\n }\n })\n } else {\n // Fallback for non-array content\n content = [\n {\n type: 'text',\n text: truncate(String(message.content)),\n },\n ]\n }\n }\n\n return {\n role: message.role,\n content,\n }\n })\n\n try {\n // Trim the inputs array until its JSON size fits within MAX_OUTPUT_SIZE\n let serialized = JSON.stringify(inputs)\n let removedCount = 0\n // We need to keep track of the initial size of the inputs array because we're going to be mutating it\n const initialSize = inputs.length\n for (let i = 0; i < initialSize && Buffer.byteLength(serialized, 'utf8') > MAX_OUTPUT_SIZE; i++) {\n inputs.shift()\n removedCount++\n serialized = JSON.stringify(inputs)\n }\n if (removedCount > 0) {\n // Add one placeholder to indicate how many were removed\n inputs.unshift({\n role: 'posthog',\n content: `[${removedCount} message${removedCount === 1 ? '' : 's'} removed due to size limit]`,\n })\n }\n } catch (error) {\n console.error('Error stringifying inputs', error)\n return [{ role: 'posthog', content: 'An error occurred while processing your request. Please try again.' }]\n }\n return inputs\n}\n\nconst mapVercelOutput = (result: LanguageModelV2Content[]): PostHogInput[] => {\n const content: any[] = result.map((item) => {\n if (item.type === 'text') {\n return { type: 'text', text: truncate(item.text) }\n }\n if (item.type === 'tool-call') {\n return {\n type: 'tool-call',\n id: item.toolCallId,\n function: {\n name: item.toolName,\n arguments: (item as any).args || JSON.stringify((item as any).arguments || {}),\n },\n }\n }\n if (item.type === 'reasoning') {\n return { type: 'reasoning', text: truncate(item.text) }\n }\n if (item.type === 'file') {\n // Handle files similar to input mapping - avoid large base64 data\n let fileData: string\n if (item.data instanceof URL) {\n fileData = item.data.toString()\n } else if (typeof item.data === 'string') {\n // Check if it's base64 data and potentially large\n if (item.data.startsWith('data:') || item.data.length > 1000) {\n fileData = `[${item.mediaType} file - ${item.data.length} bytes]`\n } else {\n fileData = item.data\n }\n } else {\n fileData = `[binary ${item.mediaType} file]`\n }\n\n return {\n type: 'file',\n name: 'generated_file',\n mediaType: item.mediaType,\n data: fileData,\n }\n }\n if (item.type === 'source') {\n return {\n type: 'source',\n sourceType: item.sourceType,\n id: item.id,\n url: (item as any).url || '',\n title: item.title || '',\n }\n }\n // Fallback for unknown types - try to extract text if possible\n return { type: 'text', text: truncate(JSON.stringify(item)) }\n })\n\n if (content.length > 0) {\n return [\n {\n role: 'assistant',\n content: content.length === 1 && content[0].type === 'text' ? content[0].text : content,\n },\n ]\n }\n // otherwise stringify and truncate\n try {\n const jsonOutput = JSON.stringify(result)\n return [{ content: truncate(jsonOutput), role: 'assistant' }]\n } catch (error) {\n console.error('Error stringifying output')\n return []\n }\n}\n\nconst extractProvider = (model: LanguageModelV2): 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: LanguageModelV2,\n options: CreateInstrumentationMiddlewareOptions\n): LanguageModelV2Middleware => {\n const middleware: LanguageModelV2Middleware = {\n wrapGenerate: async ({ doGenerate, params }) => {\n const startTime = Date.now()\n const mergedParams = {\n ...options,\n ...mapVercelParams(params),\n }\n const availableTools = extractAvailableToolCalls('vercel', params)\n\n try {\n const result = await doGenerate()\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.content)\n const latency = (Date.now() - startTime) / 1000\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 await sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId ?? uuidv4(),\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: content,\n latency,\n baseURL,\n params: mergedParams as any,\n httpStatus: 200,\n usage: {\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n ...additionalTokenValues,\n },\n tools: availableTools,\n captureImmediate: options.posthogCaptureImmediate,\n })\n\n return result\n } catch (error: any) {\n const modelId = model.modelId\n await sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId ?? uuidv4(),\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 tools: availableTools,\n captureImmediate: options.posthogCaptureImmediate,\n })\n throw error\n }\n },\n\n wrapStream: async ({ doStream, params }) => {\n const startTime = Date.now()\n let generatedText = ''\n let reasoningText = ''\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 availableTools = extractAvailableToolCalls('vercel', params)\n const baseURL = '' // cannot currently get baseURL from vercel\n\n try {\n const { stream, ...rest } = await doStream()\n const transformStream = new TransformStream<LanguageModelV2StreamPart, LanguageModelV2StreamPart>({\n transform(chunk, controller) {\n // Handle new v5 streaming patterns\n if (chunk.type === 'text-delta') {\n generatedText += chunk.delta\n }\n if (chunk.type === 'reasoning-delta') {\n reasoningText += chunk.delta // New in v5\n }\n if (chunk.type === 'finish') {\n usage = {\n inputTokens: chunk.usage?.inputTokens,\n outputTokens: chunk.usage?.outputTokens,\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: async () => {\n const latency = (Date.now() - startTime) / 1000\n // Build content array similar to mapVercelOutput structure\n const content = []\n if (reasoningText) {\n content.push({ type: 'reasoning', text: truncate(reasoningText) })\n }\n if (generatedText) {\n content.push({ type: 'text', text: truncate(generatedText) })\n }\n\n // Structure output like mapVercelOutput does\n const output =\n content.length > 0\n ? [\n {\n role: 'assistant',\n content: content.length === 1 && content[0].type === 'text' ? content[0].text : content,\n },\n ]\n : []\n\n await sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId ?? uuidv4(),\n model: modelId,\n provider: provider,\n input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),\n output: output,\n latency,\n baseURL,\n params: mergedParams as any,\n httpStatus: 200,\n usage,\n tools: availableTools,\n captureImmediate: options.posthogCaptureImmediate,\n })\n },\n })\n\n return {\n stream: stream.pipeThrough(transformStream),\n ...rest,\n }\n } catch (error: any) {\n await sendEventToPosthog({\n client: phClient,\n distinctId: options.posthogDistinctId,\n traceId: options.posthogTraceId ?? uuidv4(),\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 tools: availableTools,\n captureImmediate: options.posthogCaptureImmediate,\n })\n throw error\n }\n },\n }\n\n return middleware\n}\n\nexport const wrapVercelLanguageModel = (\n model: LanguageModelV2,\n phClient: PostHog,\n options: ClientOptions\n): LanguageModelV2 => {\n const traceId = options.posthogTraceId ?? uuidv4()\n const middleware = createInstrumentationMiddleware(phClient, model, {\n ...options,\n posthogTraceId: traceId,\n posthogDistinctId: options.posthogDistinctId,\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","extractAvailableToolCalls","provider","mode","type","tools","sanitizeValues","obj","jsonSafe","JSON","parse","stringify","Array","isArray","map","Object","fromEntries","entries","k","v","sendEventToPosthog","distinctId","traceId","model","output","latency","baseURL","httpStatus","usage","isError","captureImmediate","capture","Promise","resolve","safeInput","safeOutput","safeError","errorData","$ai_is_error","$ai_error","costOverrideData","posthogCostOverride","inputCostUSD","inputCost","inputTokens","outputCostUSD","outputCost","outputTokens","$ai_input_cost_usd","$ai_output_cost_usd","$ai_total_cost_usd","additionalTokenValues","reasoningTokens","$ai_reasoning_tokens","cacheReadInputTokens","$ai_cache_read_input_tokens","cacheCreationInputTokens","$ai_cache_creation_input_tokens","properties","$ai_provider","posthogProviderOverride","$ai_model","posthogModelOverride","$ai_model_parameters","$ai_input","posthogPrivacyMode","$ai_output_choices","$ai_http_status","$ai_input_tokens","$ai_output_tokens","$ai_latency","$ai_trace_id","$ai_base_url","posthogProperties","$process_person_profile","$ai_tools","event","groups","posthogGroups","mapVercelParams","temperature","max_output_tokens","maxOutputTokens","top_p","topP","frequency_penalty","frequencyPenalty","presence_penalty","presencePenalty","stop","stopSequences","stream","mapVercelPrompt","messages","inputs","message","content","role","text","String","c","file","data","URL","mediaType","reasoning","toolCallId","toolName","serialized","removedCount","initialSize","i","byteLength","shift","unshift","mapVercelOutput","result","item","id","function","name","arguments","args","fileData","startsWith","sourceType","url","title","jsonOutput","extractProvider","toLowerCase","providerName","split","createInstrumentationMiddleware","phClient","options","middleware","wrapGenerate","doGenerate","startTime","Date","now","mergedParams","availableTools","modelId","response","providerMetadata","openai","cachedPromptTokens","anthropic","posthogDistinctId","posthogTraceId","uuidv4","prompt","posthogCaptureImmediate","status","wrapStream","doStream","generatedText","reasoningText","rest","transformStream","TransformStream","transform","chunk","controller","delta","enqueue","flush","push","pipeThrough","wrapVercelLanguageModel","wrappedModel","wrapLanguageModel"],"mappings":"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"}
@@ -256,77 +256,75 @@ const mapVercelPrompt = messages => {
256
256
  return inputs;
257
257
  };
258
258
  const mapVercelOutput = result => {
259
- const content = [];
260
- if (result.text) {
261
- content.push({
262
- type: 'text',
263
- text: truncate(result.text)
264
- });
265
- }
266
- if (result.toolCalls && Array.isArray(result.toolCalls)) {
267
- for (const toolCall of result.toolCalls) {
268
- content.push({
269
- type: 'function',
270
- id: toolCall.toolCallId,
259
+ const content = result.map(item => {
260
+ if (item.type === 'text') {
261
+ return {
262
+ type: 'text',
263
+ text: truncate(item.text)
264
+ };
265
+ }
266
+ if (item.type === 'tool-call') {
267
+ return {
268
+ type: 'tool-call',
269
+ id: item.toolCallId,
271
270
  function: {
272
- name: toolCall.toolName,
273
- arguments: typeof toolCall.args === 'string' ? toolCall.args : JSON.stringify(toolCall.args)
271
+ name: item.toolName,
272
+ arguments: item.args || JSON.stringify(item.arguments || {})
274
273
  }
275
- });
274
+ };
276
275
  }
277
- }
276
+ if (item.type === 'reasoning') {
277
+ return {
278
+ type: 'reasoning',
279
+ text: truncate(item.text)
280
+ };
281
+ }
282
+ if (item.type === 'file') {
283
+ // Handle files similar to input mapping - avoid large base64 data
284
+ let fileData;
285
+ if (item.data instanceof URL) {
286
+ fileData = item.data.toString();
287
+ } else if (typeof item.data === 'string') {
288
+ // Check if it's base64 data and potentially large
289
+ if (item.data.startsWith('data:') || item.data.length > 1000) {
290
+ fileData = `[${item.mediaType} file - ${item.data.length} bytes]`;
291
+ } else {
292
+ fileData = item.data;
293
+ }
294
+ } else {
295
+ fileData = `[binary ${item.mediaType} file]`;
296
+ }
297
+ return {
298
+ type: 'file',
299
+ name: 'generated_file',
300
+ mediaType: item.mediaType,
301
+ data: fileData
302
+ };
303
+ }
304
+ if (item.type === 'source') {
305
+ return {
306
+ type: 'source',
307
+ sourceType: item.sourceType,
308
+ id: item.id,
309
+ url: item.url || '',
310
+ title: item.title || ''
311
+ };
312
+ }
313
+ // Fallback for unknown types - try to extract text if possible
314
+ return {
315
+ type: 'text',
316
+ text: truncate(JSON.stringify(item))
317
+ };
318
+ });
278
319
  if (content.length > 0) {
279
320
  return [{
280
321
  role: 'assistant',
281
322
  content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
282
323
  }];
283
324
  }
284
- // Fallback to original behavior for other result types TODO: check if we can remove this
285
- const normalizedResult = typeof result === 'string' ? {
286
- text: result
287
- } : result;
288
- const output = {
289
- ...(normalizedResult.text ? {
290
- text: normalizedResult.text
291
- } : {}),
292
- ...(normalizedResult.object ? {
293
- object: normalizedResult.object
294
- } : {}),
295
- ...(normalizedResult.reasoningText ? {
296
- reasoning: normalizedResult.reasoningText
297
- } : {}),
298
- ...(normalizedResult.response ? {
299
- response: normalizedResult.response
300
- } : {}),
301
- ...(normalizedResult.finishReason ? {
302
- finishReason: normalizedResult.finishReason
303
- } : {}),
304
- ...(normalizedResult.usage ? {
305
- usage: normalizedResult.usage
306
- } : {}),
307
- ...(normalizedResult.warnings ? {
308
- warnings: normalizedResult.warnings
309
- } : {}),
310
- ...(normalizedResult.providerMetadata ? {
311
- toolCalls: normalizedResult.providerMetadata
312
- } : {}),
313
- ...(normalizedResult.files ? {
314
- files: normalizedResult.files.map(file => ({
315
- name: file.name,
316
- size: file.size,
317
- type: file.type
318
- }))
319
- } : {})
320
- };
321
- if (output.text && !output.object && !output.reasoning) {
322
- return [{
323
- content: truncate(output.text),
324
- role: 'assistant'
325
- }];
326
- }
327
325
  // otherwise stringify and truncate
328
326
  try {
329
- const jsonOutput = JSON.stringify(output);
327
+ const jsonOutput = JSON.stringify(result);
330
328
  return [{
331
329
  content: truncate(jsonOutput),
332
330
  role: 'assistant'
@@ -358,7 +356,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
358
356
  const modelId = options.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
359
357
  const provider = options.posthogProviderOverride ?? extractProvider(model);
360
358
  const baseURL = ''; // cannot currently get baseURL from vercel
361
- const content = mapVercelOutput(result);
359
+ const content = mapVercelOutput(result.content);
362
360
  const latency = (Date.now() - startTime) / 1000;
363
361
  const providerMetadata = result.providerMetadata;
364
362
  const additionalTokenValues = {
@@ -473,7 +471,26 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
473
471
  },
474
472
  flush: async () => {
475
473
  const latency = (Date.now() - startTime) / 1000;
476
- const outputContent = reasoningText ? `${reasoningText}\n\n${generatedText}` : generatedText;
474
+ // Build content array similar to mapVercelOutput structure
475
+ const content = [];
476
+ if (reasoningText) {
477
+ content.push({
478
+ type: 'reasoning',
479
+ text: truncate(reasoningText)
480
+ });
481
+ }
482
+ if (generatedText) {
483
+ content.push({
484
+ type: 'text',
485
+ text: truncate(generatedText)
486
+ });
487
+ }
488
+
489
+ // Structure output like mapVercelOutput does
490
+ const output = content.length > 0 ? [{
491
+ role: 'assistant',
492
+ content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
493
+ }] : [];
477
494
  await sendEventToPosthog({
478
495
  client: phClient,
479
496
  distinctId: options.posthogDistinctId,
@@ -481,10 +498,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
481
498
  model: modelId,
482
499
  provider: provider,
483
500
  input: options.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
484
- output: [{
485
- content: outputContent,
486
- role: 'assistant'
487
- }],
501
+ output: output,
488
502
  latency,
489
503
  baseURL,
490
504
  params: mergedParams,