@posthog/ai 3.2.1 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.esm.js CHANGED
@@ -73,7 +73,8 @@ const sendEventToPosthog = ({
73
73
  httpStatus = 200,
74
74
  usage = {},
75
75
  isError = false,
76
- error
76
+ error,
77
+ tools
77
78
  }) => {
78
79
  if (client.capture) {
79
80
  let errorData = {};
@@ -93,6 +94,17 @@ const sendEventToPosthog = ({
93
94
  $ai_total_cost_usd: inputCostUSD + outputCostUSD
94
95
  };
95
96
  }
97
+ let additionalTokenValues = {
98
+ ...(usage.reasoningTokens ? {
99
+ $ai_reasoning_tokens: usage.reasoningTokens
100
+ } : {}),
101
+ ...(usage.cacheReadInputTokens ? {
102
+ $ai_cache_read_input_tokens: usage.cacheReadInputTokens
103
+ } : {}),
104
+ ...(usage.cacheCreationInputTokens ? {
105
+ $ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
106
+ } : {})
107
+ };
96
108
  client.capture({
97
109
  distinctId: distinctId ?? traceId,
98
110
  event: '$ai_generation',
@@ -105,6 +117,7 @@ const sendEventToPosthog = ({
105
117
  $ai_http_status: httpStatus,
106
118
  $ai_input_tokens: usage.inputTokens ?? 0,
107
119
  $ai_output_tokens: usage.outputTokens ?? 0,
120
+ ...additionalTokenValues,
108
121
  $ai_latency: latency,
109
122
  $ai_trace_id: traceId,
110
123
  $ai_base_url: baseURL,
@@ -112,6 +125,9 @@ const sendEventToPosthog = ({
112
125
  ...(distinctId ? {} : {
113
126
  $process_person_profile: false
114
127
  }),
128
+ ...(tools ? {
129
+ $ai_tools: tools
130
+ } : {}),
115
131
  ...errorData,
116
132
  ...costOverrideData
117
133
  },
@@ -173,7 +189,9 @@ class WrappedCompletions$1 extends OpenAIOrignal.Chat.Completions {
173
189
  if (chunk.usage) {
174
190
  usage = {
175
191
  inputTokens: chunk.usage.prompt_tokens ?? 0,
176
- outputTokens: chunk.usage.completion_tokens ?? 0
192
+ outputTokens: chunk.usage.completion_tokens ?? 0,
193
+ reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
194
+ cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0
177
195
  };
178
196
  }
179
197
  }
@@ -240,7 +258,9 @@ class WrappedCompletions$1 extends OpenAIOrignal.Chat.Completions {
240
258
  httpStatus: 200,
241
259
  usage: {
242
260
  inputTokens: result.usage?.prompt_tokens ?? 0,
243
- outputTokens: result.usage?.completion_tokens ?? 0
261
+ outputTokens: result.usage?.completion_tokens ?? 0,
262
+ reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
263
+ cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
244
264
  }
245
265
  });
246
266
  }
@@ -329,7 +349,9 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
329
349
  }
330
350
  usage = {
331
351
  inputTokens: chunk.usage.prompt_tokens ?? 0,
332
- outputTokens: chunk.usage.completion_tokens ?? 0
352
+ outputTokens: chunk.usage.completion_tokens ?? 0,
353
+ reasoningTokens: chunk.usage.completion_tokens_details?.reasoning_tokens ?? 0,
354
+ cacheReadInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0
333
355
  };
334
356
  }
335
357
  }
@@ -401,7 +423,9 @@ class WrappedCompletions extends AzureOpenAI.Chat.Completions {
401
423
  httpStatus: 200,
402
424
  usage: {
403
425
  inputTokens: result.usage?.prompt_tokens ?? 0,
404
- outputTokens: result.usage?.completion_tokens ?? 0
426
+ outputTokens: result.usage?.completion_tokens ?? 0,
427
+ reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
428
+ cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0
405
429
  }
406
430
  });
407
431
  }
@@ -446,16 +470,60 @@ const mapVercelParams = params => {
446
470
  };
447
471
  const mapVercelPrompt = prompt => {
448
472
  return prompt.map(p => {
449
- let content = '';
473
+ let content = {};
450
474
  if (Array.isArray(p.content)) {
451
475
  content = p.content.map(c => {
452
476
  if (c.type === 'text') {
453
- return c.text;
477
+ return {
478
+ type: 'text',
479
+ content: c.text
480
+ };
481
+ } else if (c.type === 'image') {
482
+ return {
483
+ type: 'image',
484
+ content: {
485
+ // if image is a url use it, or use "none supported"
486
+ image: c.image instanceof URL ? c.image.toString() : 'raw images not supported',
487
+ mimeType: c.mimeType
488
+ }
489
+ };
490
+ } else if (c.type === 'file') {
491
+ return {
492
+ type: 'file',
493
+ content: {
494
+ file: c.data instanceof URL ? c.data.toString() : 'raw files not supported',
495
+ mimeType: c.mimeType
496
+ }
497
+ };
498
+ } else if (c.type === 'tool-call') {
499
+ return {
500
+ type: 'tool-call',
501
+ content: {
502
+ toolCallId: c.toolCallId,
503
+ toolName: c.toolName,
504
+ args: c.args
505
+ }
506
+ };
507
+ } else if (c.type === 'tool-result') {
508
+ return {
509
+ type: 'tool-result',
510
+ content: {
511
+ toolCallId: c.toolCallId,
512
+ toolName: c.toolName,
513
+ result: c.result,
514
+ isError: c.isError
515
+ }
516
+ };
454
517
  }
455
- return '';
456
- }).join('');
518
+ return {
519
+ content: ''
520
+ };
521
+ });
457
522
  } else {
458
- content = p.content;
523
+ content = {
524
+ type: 'text',
525
+ text: p.content
526
+ };
459
527
  }
460
528
  return {
461
529
  role: p.role,
@@ -486,11 +554,21 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
486
554
  const modelId = options.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
487
555
  const provider = options.posthogProviderOverride ?? extractProvider(model);
488
556
  const baseURL = ''; // cannot currently get baseURL from vercel
489
- let content = result.text;
490
- if (!content) {
491
- // support generate Object
492
- content = result.toolCalls?.[0].args || JSON.stringify(result);
493
- }
557
+ let content = result.text || JSON.stringify(result);
558
+ // let tools = result.toolCalls
559
+ let providerMetadata = result.providerMetadata;
560
+ let additionalTokenValues = {
561
+ ...(providerMetadata?.openai?.reasoningTokens ? {
562
+ reasoningTokens: providerMetadata.openai.reasoningTokens
563
+ } : {}),
564
+ ...(providerMetadata?.openai?.cachedPromptToken ? {
565
+ cacheReadInputTokens: providerMetadata.openai.cachedPromptTokens
566
+ } : {}),
567
+ ...(providerMetadata?.anthropic ? {
568
+ cacheReadInputTokens: providerMetadata.anthropic.cacheReadInputTokens,
569
+ cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
570
+ } : {})
571
+ };
494
572
  sendEventToPosthog({
495
573
  client: phClient,
496
574
  distinctId: options.posthogDistinctId,
@@ -508,7 +586,8 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
508
586
  httpStatus: 200,
509
587
  usage: {
510
588
  inputTokens: result.usage.promptTokens,
511
- outputTokens: result.usage.completionTokens
589
+ outputTokens: result.usage.completionTokens,
590
+ ...additionalTokenValues
512
591
  }
513
592
  });
514
593
  return result;
@@ -565,6 +644,18 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
565
644
  inputTokens: chunk.usage?.promptTokens,
566
645
  outputTokens: chunk.usage?.completionTokens
567
646
  };
647
+ if (chunk.providerMetadata?.openai?.reasoningTokens) {
648
+ usage.reasoningTokens = chunk.providerMetadata.openai.reasoningTokens;
649
+ }
650
+ if (chunk.providerMetadata?.openai?.cachedPromptToken) {
651
+ usage.cacheReadInputTokens = chunk.providerMetadata.openai.cachedPromptToken;
652
+ }
653
+ if (chunk.providerMetadata?.anthropic?.cacheReadInputTokens) {
654
+ usage.cacheReadInputTokens = chunk.providerMetadata.anthropic.cacheReadInputTokens;
655
+ }
656
+ if (chunk.providerMetadata?.anthropic?.cacheCreationInputTokens) {
657
+ usage.cacheCreationInputTokens = chunk.providerMetadata.anthropic.cacheCreationInputTokens;
658
+ }
568
659
  }
569
660
  controller.enqueue(chunk);
570
661
  },
@@ -667,7 +758,9 @@ class WrappedMessages extends AnthropicOriginal.Messages {
667
758
  let accumulatedContent = '';
668
759
  const usage = {
669
760
  inputTokens: 0,
670
- outputTokens: 0
761
+ outputTokens: 0,
762
+ cacheCreationInputTokens: 0,
763
+ cacheReadInputTokens: 0
671
764
  };
672
765
  if ('tee' in value) {
673
766
  const [stream1, stream2] = value.tee();
@@ -682,6 +775,8 @@ class WrappedMessages extends AnthropicOriginal.Messages {
682
775
  }
683
776
  if (chunk.type == 'message_start') {
684
777
  usage.inputTokens = chunk.message.usage.input_tokens ?? 0;
778
+ usage.cacheCreationInputTokens = chunk.message.usage.cache_creation_input_tokens ?? 0;
779
+ usage.cacheReadInputTokens = chunk.message.usage.cache_read_input_tokens ?? 0;
685
780
  }
686
781
  if ('usage' in chunk) {
687
782
  usage.outputTokens = chunk.usage.output_tokens ?? 0;
@@ -751,7 +846,9 @@ class WrappedMessages extends AnthropicOriginal.Messages {
751
846
  httpStatus: 200,
752
847
  usage: {
753
848
  inputTokens: result.usage.input_tokens ?? 0,
754
- outputTokens: result.usage.output_tokens ?? 0
849
+ outputTokens: result.usage.output_tokens ?? 0,
850
+ cacheCreationInputTokens: result.usage.cache_creation_input_tokens ?? 0,
851
+ cacheReadInputTokens: result.usage.cache_read_input_tokens ?? 0
755
852
  }
756
853
  });
757
854
  }
@@ -1522,6 +1619,9 @@ class LangChainCallbackHandler extends BaseCallbackHandler {
1522
1619
  $ai_latency: latency,
1523
1620
  $ai_base_url: run.baseUrl
1524
1621
  };
1622
+ if (run.tools) {
1623
+ eventProperties['$ai_tools'] = withPrivacyMode(this.client, this.privacyMode, run.tools);
1624
+ }
1525
1625
  if (output instanceof Error) {
1526
1626
  eventProperties['$ai_http_status'] = output.status || 500;
1527
1627
  eventProperties['$ai_error'] = output.toString();