@posthog/ai 7.2.2 → 7.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/dist/anthropic/index.cjs +1 -1
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +1 -1
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +1 -1
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +1 -1
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +167 -141
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.mjs +167 -141
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +1 -1
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +1 -1
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +21 -14
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +21 -14
- package/dist/openai/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +131 -113
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.d.ts +7 -2
- package/dist/vercel/index.mjs +131 -113
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +10 -5
package/dist/vercel/index.cjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var ai = require('ai');
|
|
4
3
|
var uuid = require('uuid');
|
|
5
4
|
var buffer = require('buffer');
|
|
6
5
|
|
|
7
|
-
var version = "7.
|
|
6
|
+
var version = "7.3.0";
|
|
8
7
|
|
|
9
8
|
// Type guards for safer type checking
|
|
10
9
|
|
|
@@ -584,68 +583,126 @@ const extractProvider = model => {
|
|
|
584
583
|
const providerName = provider.split('.')[0];
|
|
585
584
|
return providerName;
|
|
586
585
|
};
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
586
|
+
|
|
587
|
+
// Extract web search count from provider metadata (works for both V2 and V3)
|
|
588
|
+
const extractWebSearchCount = (providerMetadata, usage) => {
|
|
589
|
+
// Try Anthropic-specific extraction
|
|
590
|
+
if (providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'server_tool_use' in providerMetadata.anthropic) {
|
|
591
|
+
const serverToolUse = providerMetadata.anthropic.server_tool_use;
|
|
592
|
+
if (serverToolUse && typeof serverToolUse === 'object' && 'web_search_requests' in serverToolUse && typeof serverToolUse.web_search_requests === 'number') {
|
|
593
|
+
return serverToolUse.web_search_requests;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// Fall back to generic calculation
|
|
598
|
+
return calculateWebSearchCount({
|
|
599
|
+
usage,
|
|
600
|
+
providerMetadata
|
|
601
|
+
});
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
// Extract additional token values from provider metadata
|
|
605
|
+
const extractAdditionalTokenValues = providerMetadata => {
|
|
606
|
+
if (providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'cacheCreationInputTokens' in providerMetadata.anthropic) {
|
|
607
|
+
return {
|
|
608
|
+
cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
return {};
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
// Helper to extract numeric token value from V2 (number) or V3 (object with .total) usage formats
|
|
615
|
+
const extractTokenCount = value => {
|
|
616
|
+
if (typeof value === 'number') {
|
|
617
|
+
return value;
|
|
618
|
+
}
|
|
619
|
+
if (value && typeof value === 'object' && 'total' in value && typeof value.total === 'number') {
|
|
620
|
+
return value.total;
|
|
621
|
+
}
|
|
622
|
+
return undefined;
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
// Helper to extract reasoning tokens from V2 (usage.reasoningTokens) or V3 (usage.outputTokens.reasoning)
|
|
626
|
+
const extractReasoningTokens = usage => {
|
|
627
|
+
// V2 style: top-level reasoningTokens
|
|
628
|
+
if ('reasoningTokens' in usage) {
|
|
629
|
+
return usage.reasoningTokens;
|
|
630
|
+
}
|
|
631
|
+
// V3 style: nested in outputTokens.reasoning
|
|
632
|
+
if ('outputTokens' in usage && usage.outputTokens && typeof usage.outputTokens === 'object' && 'reasoning' in usage.outputTokens) {
|
|
633
|
+
return usage.outputTokens.reasoning;
|
|
634
|
+
}
|
|
635
|
+
return undefined;
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
// Helper to extract cached input tokens from V2 (usage.cachedInputTokens) or V3 (usage.inputTokens.cacheRead)
|
|
639
|
+
const extractCacheReadTokens = usage => {
|
|
640
|
+
// V2 style: top-level cachedInputTokens
|
|
641
|
+
if ('cachedInputTokens' in usage) {
|
|
642
|
+
return usage.cachedInputTokens;
|
|
643
|
+
}
|
|
644
|
+
// V3 style: nested in inputTokens.cacheRead
|
|
645
|
+
if ('inputTokens' in usage && usage.inputTokens && typeof usage.inputTokens === 'object' && 'cacheRead' in usage.inputTokens) {
|
|
646
|
+
return usage.inputTokens.cacheRead;
|
|
647
|
+
}
|
|
648
|
+
return undefined;
|
|
649
|
+
};
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Wraps a Vercel AI SDK language model (V2 or V3) with PostHog tracing.
|
|
653
|
+
* Automatically detects the model version and applies appropriate instrumentation.
|
|
654
|
+
*/
|
|
655
|
+
const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
656
|
+
const traceId = options.posthogTraceId ?? uuid.v4();
|
|
657
|
+
const mergedOptions = {
|
|
658
|
+
...options,
|
|
659
|
+
posthogTraceId: traceId,
|
|
660
|
+
posthogDistinctId: options.posthogDistinctId,
|
|
661
|
+
posthogProperties: {
|
|
662
|
+
...options.posthogProperties,
|
|
663
|
+
$ai_framework: 'vercel',
|
|
664
|
+
$ai_framework_version: model.specificationVersion === 'v3' ? '6' : '5'
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
// Create wrapped model that preserves the original type
|
|
669
|
+
const wrappedModel = {
|
|
670
|
+
...model,
|
|
671
|
+
doGenerate: async params => {
|
|
593
672
|
const startTime = Date.now();
|
|
594
673
|
const mergedParams = {
|
|
595
|
-
...
|
|
596
|
-
...mapVercelParams(params)
|
|
597
|
-
posthogProperties: {
|
|
598
|
-
...options.posthogProperties,
|
|
599
|
-
$ai_framework: 'vercel'
|
|
600
|
-
}
|
|
674
|
+
...mergedOptions,
|
|
675
|
+
...mapVercelParams(params)
|
|
601
676
|
};
|
|
602
677
|
const availableTools = extractAvailableToolCalls('vercel', params);
|
|
603
678
|
try {
|
|
604
|
-
const result = await doGenerate();
|
|
605
|
-
const modelId =
|
|
606
|
-
const provider =
|
|
679
|
+
const result = await model.doGenerate(params);
|
|
680
|
+
const modelId = mergedOptions.posthogModelOverride ?? (result.response?.modelId ? result.response.modelId : model.modelId);
|
|
681
|
+
const provider = mergedOptions.posthogProviderOverride ?? extractProvider(model);
|
|
607
682
|
const baseURL = ''; // cannot currently get baseURL from vercel
|
|
608
683
|
const content = mapVercelOutput(result.content);
|
|
609
684
|
const latency = (Date.now() - startTime) / 1000;
|
|
610
685
|
const providerMetadata = result.providerMetadata;
|
|
611
|
-
const additionalTokenValues =
|
|
612
|
-
|
|
613
|
-
cacheCreationInputTokens: providerMetadata.anthropic.cacheCreationInputTokens
|
|
614
|
-
} : {})
|
|
615
|
-
};
|
|
686
|
+
const additionalTokenValues = extractAdditionalTokenValues(providerMetadata);
|
|
687
|
+
const webSearchCount = extractWebSearchCount(providerMetadata, result.usage);
|
|
616
688
|
|
|
617
|
-
//
|
|
618
|
-
|
|
619
|
-
if (providerMetadata?.anthropic && typeof providerMetadata.anthropic === 'object' && 'server_tool_use' in providerMetadata.anthropic) {
|
|
620
|
-
// Anthropic-specific extraction
|
|
621
|
-
const serverToolUse = providerMetadata.anthropic.server_tool_use;
|
|
622
|
-
if (serverToolUse && typeof serverToolUse === 'object' && 'web_search_requests' in serverToolUse && typeof serverToolUse.web_search_requests === 'number') {
|
|
623
|
-
webSearchCount = serverToolUse.web_search_requests;
|
|
624
|
-
}
|
|
625
|
-
} else {
|
|
626
|
-
// For other providers through Vercel, pass available metadata to helper
|
|
627
|
-
// Note: Vercel abstracts provider responses, so we may not have access to
|
|
628
|
-
// raw citations/annotations unless Vercel exposes them in usage/metadata
|
|
629
|
-
webSearchCount = calculateWebSearchCount({
|
|
630
|
-
usage: result.usage,
|
|
631
|
-
providerMetadata: providerMetadata
|
|
632
|
-
});
|
|
633
|
-
}
|
|
689
|
+
// V2 usage has simple numbers, V3 has objects with .total - normalize both
|
|
690
|
+
const usageObj = result.usage;
|
|
634
691
|
const usage = {
|
|
635
|
-
inputTokens: result.usage.inputTokens,
|
|
636
|
-
outputTokens: result.usage.outputTokens,
|
|
637
|
-
reasoningTokens:
|
|
638
|
-
cacheReadInputTokens:
|
|
692
|
+
inputTokens: extractTokenCount(result.usage.inputTokens),
|
|
693
|
+
outputTokens: extractTokenCount(result.usage.outputTokens),
|
|
694
|
+
reasoningTokens: extractReasoningTokens(usageObj),
|
|
695
|
+
cacheReadInputTokens: extractCacheReadTokens(usageObj),
|
|
639
696
|
webSearchCount,
|
|
640
697
|
...additionalTokenValues
|
|
641
698
|
};
|
|
642
699
|
await sendEventToPosthog({
|
|
643
700
|
client: phClient,
|
|
644
|
-
distinctId:
|
|
645
|
-
traceId:
|
|
701
|
+
distinctId: mergedOptions.posthogDistinctId,
|
|
702
|
+
traceId: mergedOptions.posthogTraceId ?? uuid.v4(),
|
|
646
703
|
model: modelId,
|
|
647
704
|
provider: provider,
|
|
648
|
-
input:
|
|
705
|
+
input: mergedOptions.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
|
|
649
706
|
output: content,
|
|
650
707
|
latency,
|
|
651
708
|
baseURL,
|
|
@@ -653,18 +710,18 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
653
710
|
httpStatus: 200,
|
|
654
711
|
usage,
|
|
655
712
|
tools: availableTools,
|
|
656
|
-
captureImmediate:
|
|
713
|
+
captureImmediate: mergedOptions.posthogCaptureImmediate
|
|
657
714
|
});
|
|
658
715
|
return result;
|
|
659
716
|
} catch (error) {
|
|
660
717
|
const modelId = model.modelId;
|
|
661
718
|
await sendEventToPosthog({
|
|
662
719
|
client: phClient,
|
|
663
|
-
distinctId:
|
|
664
|
-
traceId:
|
|
720
|
+
distinctId: mergedOptions.posthogDistinctId,
|
|
721
|
+
traceId: mergedOptions.posthogTraceId ?? uuid.v4(),
|
|
665
722
|
model: modelId,
|
|
666
723
|
provider: model.provider,
|
|
667
|
-
input:
|
|
724
|
+
input: mergedOptions.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
|
|
668
725
|
output: [],
|
|
669
726
|
latency: 0,
|
|
670
727
|
baseURL: '',
|
|
@@ -677,30 +734,23 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
677
734
|
isError: true,
|
|
678
735
|
error: truncate(JSON.stringify(error)),
|
|
679
736
|
tools: availableTools,
|
|
680
|
-
captureImmediate:
|
|
737
|
+
captureImmediate: mergedOptions.posthogCaptureImmediate
|
|
681
738
|
});
|
|
682
739
|
throw error;
|
|
683
740
|
}
|
|
684
741
|
},
|
|
685
|
-
|
|
686
|
-
doStream,
|
|
687
|
-
params
|
|
688
|
-
}) => {
|
|
742
|
+
doStream: async params => {
|
|
689
743
|
const startTime = Date.now();
|
|
690
744
|
let generatedText = '';
|
|
691
745
|
let reasoningText = '';
|
|
692
746
|
let usage = {};
|
|
693
747
|
let providerMetadata = undefined;
|
|
694
748
|
const mergedParams = {
|
|
695
|
-
...
|
|
696
|
-
...mapVercelParams(params)
|
|
697
|
-
posthogProperties: {
|
|
698
|
-
...options.posthogProperties,
|
|
699
|
-
$ai_framework: 'vercel'
|
|
700
|
-
}
|
|
749
|
+
...mergedOptions,
|
|
750
|
+
...mapVercelParams(params)
|
|
701
751
|
};
|
|
702
|
-
const modelId =
|
|
703
|
-
const provider =
|
|
752
|
+
const modelId = mergedOptions.posthogModelOverride ?? model.modelId;
|
|
753
|
+
const provider = mergedOptions.posthogProviderOverride ?? extractProvider(model);
|
|
704
754
|
const availableTools = extractAvailableToolCalls('vercel', params);
|
|
705
755
|
const baseURL = ''; // cannot currently get baseURL from vercel
|
|
706
756
|
|
|
@@ -710,15 +760,15 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
710
760
|
const {
|
|
711
761
|
stream,
|
|
712
762
|
...rest
|
|
713
|
-
} = await doStream();
|
|
763
|
+
} = await model.doStream(params);
|
|
714
764
|
const transformStream = new TransformStream({
|
|
715
765
|
transform(chunk, controller) {
|
|
716
|
-
// Handle
|
|
766
|
+
// Handle streaming patterns - compatible with both V2 and V3
|
|
717
767
|
if (chunk.type === 'text-delta') {
|
|
718
768
|
generatedText += chunk.delta;
|
|
719
769
|
}
|
|
720
770
|
if (chunk.type === 'reasoning-delta') {
|
|
721
|
-
reasoningText += chunk.delta;
|
|
771
|
+
reasoningText += chunk.delta;
|
|
722
772
|
}
|
|
723
773
|
|
|
724
774
|
// Handle tool call chunks
|
|
@@ -739,7 +789,6 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
739
789
|
}
|
|
740
790
|
if (chunk.type === 'tool-input-end') {
|
|
741
791
|
// Tool call is complete, keep it in the map for final processing
|
|
742
|
-
// Nothing specific to do here, the tool call is already complete
|
|
743
792
|
}
|
|
744
793
|
if (chunk.type === 'tool-call') {
|
|
745
794
|
// Direct tool call chunk (complete tool call)
|
|
@@ -751,14 +800,13 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
751
800
|
}
|
|
752
801
|
if (chunk.type === 'finish') {
|
|
753
802
|
providerMetadata = chunk.providerMetadata;
|
|
754
|
-
const additionalTokenValues = providerMetadata
|
|
755
|
-
|
|
756
|
-
} : {};
|
|
803
|
+
const additionalTokenValues = extractAdditionalTokenValues(providerMetadata);
|
|
804
|
+
const chunkUsage = chunk.usage || {};
|
|
757
805
|
usage = {
|
|
758
|
-
inputTokens: chunk.usage?.inputTokens,
|
|
759
|
-
outputTokens: chunk.usage?.outputTokens,
|
|
760
|
-
reasoningTokens:
|
|
761
|
-
cacheReadInputTokens:
|
|
806
|
+
inputTokens: extractTokenCount(chunk.usage?.inputTokens),
|
|
807
|
+
outputTokens: extractTokenCount(chunk.usage?.outputTokens),
|
|
808
|
+
reasoningTokens: extractReasoningTokens(chunkUsage),
|
|
809
|
+
cacheReadInputTokens: extractCacheReadTokens(chunkUsage),
|
|
762
810
|
...additionalTokenValues
|
|
763
811
|
};
|
|
764
812
|
}
|
|
@@ -800,24 +848,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
800
848
|
role: 'assistant',
|
|
801
849
|
content: content.length === 1 && content[0].type === 'text' ? content[0].text : content
|
|
802
850
|
}] : [];
|
|
803
|
-
|
|
804
|
-
// Calculate web search count based on provider
|
|
805
|
-
let webSearchCount = 0;
|
|
806
|
-
if (providerMetadata && typeof providerMetadata === 'object' && 'anthropic' in providerMetadata && providerMetadata.anthropic && typeof providerMetadata.anthropic === 'object' && 'server_tool_use' in providerMetadata.anthropic) {
|
|
807
|
-
// Anthropic-specific extraction
|
|
808
|
-
const serverToolUse = providerMetadata.anthropic.server_tool_use;
|
|
809
|
-
if (serverToolUse && typeof serverToolUse === 'object' && 'web_search_requests' in serverToolUse && typeof serverToolUse.web_search_requests === 'number') {
|
|
810
|
-
webSearchCount = serverToolUse.web_search_requests;
|
|
811
|
-
}
|
|
812
|
-
} else {
|
|
813
|
-
// For other providers through Vercel, pass available metadata to helper
|
|
814
|
-
// Note: Vercel abstracts provider responses, so we may not have access to
|
|
815
|
-
// raw citations/annotations unless Vercel exposes them in usage/metadata
|
|
816
|
-
webSearchCount = calculateWebSearchCount({
|
|
817
|
-
usage: usage,
|
|
818
|
-
providerMetadata: providerMetadata
|
|
819
|
-
});
|
|
820
|
-
}
|
|
851
|
+
const webSearchCount = extractWebSearchCount(providerMetadata, usage);
|
|
821
852
|
|
|
822
853
|
// Update usage with web search count
|
|
823
854
|
const finalUsage = {
|
|
@@ -826,11 +857,11 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
826
857
|
};
|
|
827
858
|
await sendEventToPosthog({
|
|
828
859
|
client: phClient,
|
|
829
|
-
distinctId:
|
|
830
|
-
traceId:
|
|
860
|
+
distinctId: mergedOptions.posthogDistinctId,
|
|
861
|
+
traceId: mergedOptions.posthogTraceId ?? uuid.v4(),
|
|
831
862
|
model: modelId,
|
|
832
863
|
provider: provider,
|
|
833
|
-
input:
|
|
864
|
+
input: mergedOptions.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
|
|
834
865
|
output: output,
|
|
835
866
|
latency,
|
|
836
867
|
baseURL,
|
|
@@ -838,7 +869,7 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
838
869
|
httpStatus: 200,
|
|
839
870
|
usage: finalUsage,
|
|
840
871
|
tools: availableTools,
|
|
841
|
-
captureImmediate:
|
|
872
|
+
captureImmediate: mergedOptions.posthogCaptureImmediate
|
|
842
873
|
});
|
|
843
874
|
}
|
|
844
875
|
});
|
|
@@ -849,11 +880,11 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
849
880
|
} catch (error) {
|
|
850
881
|
await sendEventToPosthog({
|
|
851
882
|
client: phClient,
|
|
852
|
-
distinctId:
|
|
853
|
-
traceId:
|
|
883
|
+
distinctId: mergedOptions.posthogDistinctId,
|
|
884
|
+
traceId: mergedOptions.posthogTraceId ?? uuid.v4(),
|
|
854
885
|
model: modelId,
|
|
855
886
|
provider: provider,
|
|
856
|
-
input:
|
|
887
|
+
input: mergedOptions.posthogPrivacyMode ? '' : mapVercelPrompt(params.prompt),
|
|
857
888
|
output: [],
|
|
858
889
|
latency: 0,
|
|
859
890
|
baseURL: '',
|
|
@@ -866,25 +897,12 @@ const createInstrumentationMiddleware = (phClient, model, options) => {
|
|
|
866
897
|
isError: true,
|
|
867
898
|
error: truncate(JSON.stringify(error)),
|
|
868
899
|
tools: availableTools,
|
|
869
|
-
captureImmediate:
|
|
900
|
+
captureImmediate: mergedOptions.posthogCaptureImmediate
|
|
870
901
|
});
|
|
871
902
|
throw error;
|
|
872
903
|
}
|
|
873
904
|
}
|
|
874
905
|
};
|
|
875
|
-
return middleware;
|
|
876
|
-
};
|
|
877
|
-
const wrapVercelLanguageModel = (model, phClient, options) => {
|
|
878
|
-
const traceId = options.posthogTraceId ?? uuid.v4();
|
|
879
|
-
const middleware = createInstrumentationMiddleware(phClient, model, {
|
|
880
|
-
...options,
|
|
881
|
-
posthogTraceId: traceId,
|
|
882
|
-
posthogDistinctId: options.posthogDistinctId
|
|
883
|
-
});
|
|
884
|
-
const wrappedModel = ai.wrapLanguageModel({
|
|
885
|
-
model,
|
|
886
|
-
middleware
|
|
887
|
-
});
|
|
888
906
|
return wrappedModel;
|
|
889
907
|
};
|
|
890
908
|
|