@posthog/ai 7.5.4 → 7.6.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 +71 -63
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +71 -63
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +106 -54
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +106 -54
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +308 -223
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +308 -223
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +161 -136
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.mjs +161 -136
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +163 -133
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +163 -133
- package/dist/openai/index.mjs.map +1 -1
- package/dist/vercel/index.cjs +82 -57
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +82 -57
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/openai/index.cjs
CHANGED
|
@@ -7,7 +7,7 @@ var buffer = require('buffer');
|
|
|
7
7
|
var uuid = require('uuid');
|
|
8
8
|
var core = require('@posthog/core');
|
|
9
9
|
|
|
10
|
-
var version = "7.
|
|
10
|
+
var version = "7.6.0";
|
|
11
11
|
|
|
12
12
|
// Type guards for safer type checking
|
|
13
13
|
|
|
@@ -18,6 +18,139 @@ const isObject = value => {
|
|
|
18
18
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
const REDACTED_IMAGE_PLACEHOLDER = '[base64 image redacted]';
|
|
22
|
+
|
|
23
|
+
// ============================================
|
|
24
|
+
// Multimodal Feature Toggle
|
|
25
|
+
// ============================================
|
|
26
|
+
|
|
27
|
+
const isMultimodalEnabled = () => {
|
|
28
|
+
const val = process.env._INTERNAL_LLMA_MULTIMODAL || '';
|
|
29
|
+
return val.toLowerCase() === 'true' || val === '1' || val.toLowerCase() === 'yes';
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// ============================================
|
|
33
|
+
// Base64 Detection Helpers
|
|
34
|
+
// ============================================
|
|
35
|
+
|
|
36
|
+
const isBase64DataUrl = str => {
|
|
37
|
+
return /^data:([^;]+);base64,/.test(str);
|
|
38
|
+
};
|
|
39
|
+
const isValidUrl = str => {
|
|
40
|
+
try {
|
|
41
|
+
new URL(str);
|
|
42
|
+
return true;
|
|
43
|
+
} catch {
|
|
44
|
+
// Not an absolute URL, check if it's a relative URL or path
|
|
45
|
+
return str.startsWith('/') || str.startsWith('./') || str.startsWith('../');
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const isRawBase64 = str => {
|
|
49
|
+
// Skip if it's a valid URL or path
|
|
50
|
+
if (isValidUrl(str)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check if it's a valid base64 string
|
|
55
|
+
// Base64 images are typically at least a few hundred chars, but we'll be conservative
|
|
56
|
+
return str.length > 20 && /^[A-Za-z0-9+/]+=*$/.test(str);
|
|
57
|
+
};
|
|
58
|
+
function redactBase64DataUrl(str) {
|
|
59
|
+
if (isMultimodalEnabled()) return str;
|
|
60
|
+
if (!isString(str)) return str;
|
|
61
|
+
|
|
62
|
+
// Check for data URL format
|
|
63
|
+
if (isBase64DataUrl(str)) {
|
|
64
|
+
return REDACTED_IMAGE_PLACEHOLDER;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Check for raw base64 (Vercel sends raw base64 for inline images)
|
|
68
|
+
if (isRawBase64(str)) {
|
|
69
|
+
return REDACTED_IMAGE_PLACEHOLDER;
|
|
70
|
+
}
|
|
71
|
+
return str;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ============================================
|
|
75
|
+
// Common Message Processing
|
|
76
|
+
// ============================================
|
|
77
|
+
|
|
78
|
+
const processMessages = (messages, transformContent) => {
|
|
79
|
+
if (!messages) return messages;
|
|
80
|
+
const processContent = content => {
|
|
81
|
+
if (typeof content === 'string') return content;
|
|
82
|
+
if (!content) return content;
|
|
83
|
+
if (Array.isArray(content)) {
|
|
84
|
+
return content.map(transformContent);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Handle single object content
|
|
88
|
+
return transformContent(content);
|
|
89
|
+
};
|
|
90
|
+
const processMessage = msg => {
|
|
91
|
+
if (!isObject(msg) || !('content' in msg)) return msg;
|
|
92
|
+
return {
|
|
93
|
+
...msg,
|
|
94
|
+
content: processContent(msg.content)
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Handle both arrays and single messages
|
|
99
|
+
if (Array.isArray(messages)) {
|
|
100
|
+
return messages.map(processMessage);
|
|
101
|
+
}
|
|
102
|
+
return processMessage(messages);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// ============================================
|
|
106
|
+
// Provider-Specific Image Sanitizers
|
|
107
|
+
// ============================================
|
|
108
|
+
|
|
109
|
+
const sanitizeOpenAIImage = item => {
|
|
110
|
+
if (!isObject(item)) return item;
|
|
111
|
+
|
|
112
|
+
// Handle image_url format
|
|
113
|
+
if (item.type === 'image_url' && 'image_url' in item && isObject(item.image_url) && 'url' in item.image_url) {
|
|
114
|
+
return {
|
|
115
|
+
...item,
|
|
116
|
+
image_url: {
|
|
117
|
+
...item.image_url,
|
|
118
|
+
url: redactBase64DataUrl(item.image_url.url)
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Handle audio format
|
|
124
|
+
if (item.type === 'audio' && 'data' in item) {
|
|
125
|
+
if (isMultimodalEnabled()) return item;
|
|
126
|
+
return {
|
|
127
|
+
...item,
|
|
128
|
+
data: REDACTED_IMAGE_PLACEHOLDER
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return item;
|
|
132
|
+
};
|
|
133
|
+
const sanitizeOpenAIResponseImage = item => {
|
|
134
|
+
if (!isObject(item)) return item;
|
|
135
|
+
|
|
136
|
+
// Handle input_image format
|
|
137
|
+
if (item.type === 'input_image' && 'image_url' in item) {
|
|
138
|
+
return {
|
|
139
|
+
...item,
|
|
140
|
+
image_url: redactBase64DataUrl(item.image_url)
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return item;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// Export individual sanitizers for tree-shaking
|
|
147
|
+
const sanitizeOpenAI = data => {
|
|
148
|
+
return processMessages(data, sanitizeOpenAIImage);
|
|
149
|
+
};
|
|
150
|
+
const sanitizeOpenAIResponse = data => {
|
|
151
|
+
return processMessages(data, sanitizeOpenAIResponseImage);
|
|
152
|
+
};
|
|
153
|
+
|
|
21
154
|
const STRING_FORMAT = 'utf8';
|
|
22
155
|
|
|
23
156
|
/**
|
|
@@ -413,6 +546,9 @@ const sendEventToPosthog = async ({
|
|
|
413
546
|
} : {}),
|
|
414
547
|
...(usage.webSearchCount ? {
|
|
415
548
|
$ai_web_search_count: usage.webSearchCount
|
|
549
|
+
} : {}),
|
|
550
|
+
...(usage.rawUsage ? {
|
|
551
|
+
$ai_usage: usage.rawUsage
|
|
416
552
|
} : {})
|
|
417
553
|
};
|
|
418
554
|
const properties = {
|
|
@@ -502,124 +638,6 @@ function formatOpenAIResponsesInput(input, instructions) {
|
|
|
502
638
|
return messages;
|
|
503
639
|
}
|
|
504
640
|
|
|
505
|
-
const REDACTED_IMAGE_PLACEHOLDER = '[base64 image redacted]';
|
|
506
|
-
|
|
507
|
-
// ============================================
|
|
508
|
-
// Multimodal Feature Toggle
|
|
509
|
-
// ============================================
|
|
510
|
-
|
|
511
|
-
const isMultimodalEnabled = () => {
|
|
512
|
-
const val = process.env._INTERNAL_LLMA_MULTIMODAL || '';
|
|
513
|
-
return val.toLowerCase() === 'true' || val === '1' || val.toLowerCase() === 'yes';
|
|
514
|
-
};
|
|
515
|
-
|
|
516
|
-
// ============================================
|
|
517
|
-
// Base64 Detection Helpers
|
|
518
|
-
// ============================================
|
|
519
|
-
|
|
520
|
-
const isBase64DataUrl = str => {
|
|
521
|
-
return /^data:([^;]+);base64,/.test(str);
|
|
522
|
-
};
|
|
523
|
-
const isValidUrl = str => {
|
|
524
|
-
try {
|
|
525
|
-
new URL(str);
|
|
526
|
-
return true;
|
|
527
|
-
} catch {
|
|
528
|
-
// Not an absolute URL, check if it's a relative URL or path
|
|
529
|
-
return str.startsWith('/') || str.startsWith('./') || str.startsWith('../');
|
|
530
|
-
}
|
|
531
|
-
};
|
|
532
|
-
const isRawBase64 = str => {
|
|
533
|
-
// Skip if it's a valid URL or path
|
|
534
|
-
if (isValidUrl(str)) {
|
|
535
|
-
return false;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
// Check if it's a valid base64 string
|
|
539
|
-
// Base64 images are typically at least a few hundred chars, but we'll be conservative
|
|
540
|
-
return str.length > 20 && /^[A-Za-z0-9+/]+=*$/.test(str);
|
|
541
|
-
};
|
|
542
|
-
function redactBase64DataUrl(str) {
|
|
543
|
-
if (isMultimodalEnabled()) return str;
|
|
544
|
-
if (!isString(str)) return str;
|
|
545
|
-
|
|
546
|
-
// Check for data URL format
|
|
547
|
-
if (isBase64DataUrl(str)) {
|
|
548
|
-
return REDACTED_IMAGE_PLACEHOLDER;
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// Check for raw base64 (Vercel sends raw base64 for inline images)
|
|
552
|
-
if (isRawBase64(str)) {
|
|
553
|
-
return REDACTED_IMAGE_PLACEHOLDER;
|
|
554
|
-
}
|
|
555
|
-
return str;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
// ============================================
|
|
559
|
-
// Common Message Processing
|
|
560
|
-
// ============================================
|
|
561
|
-
|
|
562
|
-
const processMessages = (messages, transformContent) => {
|
|
563
|
-
if (!messages) return messages;
|
|
564
|
-
const processContent = content => {
|
|
565
|
-
if (typeof content === 'string') return content;
|
|
566
|
-
if (!content) return content;
|
|
567
|
-
if (Array.isArray(content)) {
|
|
568
|
-
return content.map(transformContent);
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// Handle single object content
|
|
572
|
-
return transformContent(content);
|
|
573
|
-
};
|
|
574
|
-
const processMessage = msg => {
|
|
575
|
-
if (!isObject(msg) || !('content' in msg)) return msg;
|
|
576
|
-
return {
|
|
577
|
-
...msg,
|
|
578
|
-
content: processContent(msg.content)
|
|
579
|
-
};
|
|
580
|
-
};
|
|
581
|
-
|
|
582
|
-
// Handle both arrays and single messages
|
|
583
|
-
if (Array.isArray(messages)) {
|
|
584
|
-
return messages.map(processMessage);
|
|
585
|
-
}
|
|
586
|
-
return processMessage(messages);
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
// ============================================
|
|
590
|
-
// Provider-Specific Image Sanitizers
|
|
591
|
-
// ============================================
|
|
592
|
-
|
|
593
|
-
const sanitizeOpenAIImage = item => {
|
|
594
|
-
if (!isObject(item)) return item;
|
|
595
|
-
|
|
596
|
-
// Handle image_url format
|
|
597
|
-
if (item.type === 'image_url' && 'image_url' in item && isObject(item.image_url) && 'url' in item.image_url) {
|
|
598
|
-
return {
|
|
599
|
-
...item,
|
|
600
|
-
image_url: {
|
|
601
|
-
...item.image_url,
|
|
602
|
-
url: redactBase64DataUrl(item.image_url.url)
|
|
603
|
-
}
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// Handle audio format
|
|
608
|
-
if (item.type === 'audio' && 'data' in item) {
|
|
609
|
-
if (isMultimodalEnabled()) return item;
|
|
610
|
-
return {
|
|
611
|
-
...item,
|
|
612
|
-
data: REDACTED_IMAGE_PLACEHOLDER
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
return item;
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
// Export individual sanitizers for tree-shaking
|
|
619
|
-
const sanitizeOpenAI = data => {
|
|
620
|
-
return processMessages(data, sanitizeOpenAIImage);
|
|
621
|
-
};
|
|
622
|
-
|
|
623
641
|
const Chat = openai.OpenAI.Chat;
|
|
624
642
|
const Completions = Chat.Completions;
|
|
625
643
|
const Responses = openai.OpenAI.Responses;
|
|
@@ -684,6 +702,7 @@ class WrappedCompletions extends Completions {
|
|
|
684
702
|
|
|
685
703
|
// Map to track in-progress tool calls
|
|
686
704
|
const toolCallsInProgress = new Map();
|
|
705
|
+
let rawUsageData;
|
|
687
706
|
for await (const chunk of stream1) {
|
|
688
707
|
// Extract model from chunk (Chat Completions chunks have model field)
|
|
689
708
|
if (!modelFromResponse && chunk.model) {
|
|
@@ -734,6 +753,7 @@ class WrappedCompletions extends Completions {
|
|
|
734
753
|
|
|
735
754
|
// Handle usage information
|
|
736
755
|
if (chunk.usage) {
|
|
756
|
+
rawUsageData = chunk.usage;
|
|
737
757
|
usage = {
|
|
738
758
|
...usage,
|
|
739
759
|
inputTokens: chunk.usage.prompt_tokens ?? 0,
|
|
@@ -795,7 +815,8 @@ class WrappedCompletions extends Completions {
|
|
|
795
815
|
outputTokens: usage.outputTokens,
|
|
796
816
|
reasoningTokens: usage.reasoningTokens,
|
|
797
817
|
cacheReadInputTokens: usage.cacheReadInputTokens,
|
|
798
|
-
webSearchCount: usage.webSearchCount
|
|
818
|
+
webSearchCount: usage.webSearchCount,
|
|
819
|
+
rawUsage: rawUsageData
|
|
799
820
|
},
|
|
800
821
|
tools: availableTools
|
|
801
822
|
});
|
|
@@ -847,7 +868,8 @@ class WrappedCompletions extends Completions {
|
|
|
847
868
|
outputTokens: result.usage?.completion_tokens ?? 0,
|
|
848
869
|
reasoningTokens: result.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
849
870
|
cacheReadInputTokens: result.usage?.prompt_tokens_details?.cached_tokens ?? 0,
|
|
850
|
-
webSearchCount: calculateWebSearchCount(result)
|
|
871
|
+
webSearchCount: calculateWebSearchCount(result),
|
|
872
|
+
rawUsage: result.usage
|
|
851
873
|
},
|
|
852
874
|
tools: availableTools
|
|
853
875
|
});
|
|
@@ -912,6 +934,7 @@ class WrappedResponses extends Responses {
|
|
|
912
934
|
outputTokens: 0,
|
|
913
935
|
webSearchCount: 0
|
|
914
936
|
};
|
|
937
|
+
let rawUsageData;
|
|
915
938
|
for await (const chunk of stream1) {
|
|
916
939
|
if ('response' in chunk && chunk.response) {
|
|
917
940
|
// Extract model from response object in chunk (for stored prompts)
|
|
@@ -927,6 +950,7 @@ class WrappedResponses extends Responses {
|
|
|
927
950
|
finalContent = chunk.response.output;
|
|
928
951
|
}
|
|
929
952
|
if ('response' in chunk && chunk.response?.usage) {
|
|
953
|
+
rawUsageData = chunk.response.usage;
|
|
930
954
|
usage = {
|
|
931
955
|
...usage,
|
|
932
956
|
inputTokens: chunk.response.usage.input_tokens ?? 0,
|
|
@@ -943,7 +967,7 @@ class WrappedResponses extends Responses {
|
|
|
943
967
|
...posthogParams,
|
|
944
968
|
model: openAIParams.model ?? modelFromResponse,
|
|
945
969
|
provider: 'openai',
|
|
946
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
970
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
947
971
|
output: finalContent,
|
|
948
972
|
latency,
|
|
949
973
|
baseURL: this.baseURL,
|
|
@@ -954,7 +978,8 @@ class WrappedResponses extends Responses {
|
|
|
954
978
|
outputTokens: usage.outputTokens,
|
|
955
979
|
reasoningTokens: usage.reasoningTokens,
|
|
956
980
|
cacheReadInputTokens: usage.cacheReadInputTokens,
|
|
957
|
-
webSearchCount: usage.webSearchCount
|
|
981
|
+
webSearchCount: usage.webSearchCount,
|
|
982
|
+
rawUsage: rawUsageData
|
|
958
983
|
},
|
|
959
984
|
tools: availableTools
|
|
960
985
|
});
|
|
@@ -964,7 +989,7 @@ class WrappedResponses extends Responses {
|
|
|
964
989
|
...posthogParams,
|
|
965
990
|
model: openAIParams.model,
|
|
966
991
|
provider: 'openai',
|
|
967
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
992
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
968
993
|
output: [],
|
|
969
994
|
latency: 0,
|
|
970
995
|
baseURL: this.baseURL,
|
|
@@ -995,7 +1020,7 @@ class WrappedResponses extends Responses {
|
|
|
995
1020
|
...posthogParams,
|
|
996
1021
|
model: openAIParams.model ?? result.model,
|
|
997
1022
|
provider: 'openai',
|
|
998
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1023
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
999
1024
|
output: formattedOutput,
|
|
1000
1025
|
latency,
|
|
1001
1026
|
baseURL: this.baseURL,
|
|
@@ -1006,7 +1031,8 @@ class WrappedResponses extends Responses {
|
|
|
1006
1031
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1007
1032
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1008
1033
|
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1009
|
-
webSearchCount: calculateWebSearchCount(result)
|
|
1034
|
+
webSearchCount: calculateWebSearchCount(result),
|
|
1035
|
+
rawUsage: result.usage
|
|
1010
1036
|
},
|
|
1011
1037
|
tools: availableTools
|
|
1012
1038
|
});
|
|
@@ -1019,7 +1045,7 @@ class WrappedResponses extends Responses {
|
|
|
1019
1045
|
...posthogParams,
|
|
1020
1046
|
model: openAIParams.model,
|
|
1021
1047
|
provider: 'openai',
|
|
1022
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1048
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1023
1049
|
output: [],
|
|
1024
1050
|
latency: 0,
|
|
1025
1051
|
baseURL: this.baseURL,
|
|
@@ -1055,7 +1081,7 @@ class WrappedResponses extends Responses {
|
|
|
1055
1081
|
...posthogParams,
|
|
1056
1082
|
model: openAIParams.model ?? result.model,
|
|
1057
1083
|
provider: 'openai',
|
|
1058
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1084
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1059
1085
|
output: result.output,
|
|
1060
1086
|
latency,
|
|
1061
1087
|
baseURL: this.baseURL,
|
|
@@ -1065,7 +1091,8 @@ class WrappedResponses extends Responses {
|
|
|
1065
1091
|
inputTokens: result.usage?.input_tokens ?? 0,
|
|
1066
1092
|
outputTokens: result.usage?.output_tokens ?? 0,
|
|
1067
1093
|
reasoningTokens: result.usage?.output_tokens_details?.reasoning_tokens ?? 0,
|
|
1068
|
-
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0
|
|
1094
|
+
cacheReadInputTokens: result.usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
1095
|
+
rawUsage: result.usage
|
|
1069
1096
|
}
|
|
1070
1097
|
});
|
|
1071
1098
|
return result;
|
|
@@ -1075,7 +1102,7 @@ class WrappedResponses extends Responses {
|
|
|
1075
1102
|
...posthogParams,
|
|
1076
1103
|
model: openAIParams.model,
|
|
1077
1104
|
provider: 'openai',
|
|
1078
|
-
input: formatOpenAIResponsesInput(openAIParams.input, openAIParams.instructions),
|
|
1105
|
+
input: formatOpenAIResponsesInput(sanitizeOpenAIResponse(openAIParams.input), openAIParams.instructions),
|
|
1079
1106
|
output: [],
|
|
1080
1107
|
latency: 0,
|
|
1081
1108
|
baseURL: this.baseURL,
|
|
@@ -1124,7 +1151,8 @@ class WrappedEmbeddings extends Embeddings {
|
|
|
1124
1151
|
params: body,
|
|
1125
1152
|
httpStatus: 200,
|
|
1126
1153
|
usage: {
|
|
1127
|
-
inputTokens: result.usage?.prompt_tokens ?? 0
|
|
1154
|
+
inputTokens: result.usage?.prompt_tokens ?? 0,
|
|
1155
|
+
rawUsage: result.usage
|
|
1128
1156
|
}
|
|
1129
1157
|
});
|
|
1130
1158
|
return result;
|
|
@@ -1207,7 +1235,8 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
1207
1235
|
if ('usage' in chunk && chunk.usage) {
|
|
1208
1236
|
usage = {
|
|
1209
1237
|
inputTokens: chunk.usage?.type === 'tokens' ? chunk.usage.input_tokens ?? 0 : 0,
|
|
1210
|
-
outputTokens: chunk.usage?.type === 'tokens' ? chunk.usage.output_tokens ?? 0 : 0
|
|
1238
|
+
outputTokens: chunk.usage?.type === 'tokens' ? chunk.usage.output_tokens ?? 0 : 0,
|
|
1239
|
+
rawUsage: chunk.usage
|
|
1211
1240
|
};
|
|
1212
1241
|
}
|
|
1213
1242
|
}
|
|
@@ -1268,7 +1297,8 @@ class WrappedTranscriptions extends Transcriptions {
|
|
|
1268
1297
|
httpStatus: 200,
|
|
1269
1298
|
usage: {
|
|
1270
1299
|
inputTokens: result.usage?.type === 'tokens' ? result.usage.input_tokens ?? 0 : 0,
|
|
1271
|
-
outputTokens: result.usage?.type === 'tokens' ? result.usage.output_tokens ?? 0 : 0
|
|
1300
|
+
outputTokens: result.usage?.type === 'tokens' ? result.usage.output_tokens ?? 0 : 0,
|
|
1301
|
+
rawUsage: result.usage
|
|
1272
1302
|
}
|
|
1273
1303
|
});
|
|
1274
1304
|
return result;
|