PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.0.3
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.0.3
3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.9 3.4.8 3.4.7 0.2.1 1.6.91 0.2.2 1.6.92 0.2.3 1.6.93 0.2.4 1.6.94 0.2.5 1.6.95 0.2.6 1.6.96 0.2.7 1.6.97 0.2.8 1.6.98 0.2.9 1.6.99 0.3.0 1.7.0 0.3.1 1.7.1 0.3.2 1.7.2 0.3.3 1.7.3 0.3.4 1.7.4 0.3.5 1.7.5 0.3.6 1.7.6 0.4.0 1.7.7 0.4.1 1.7.8 0.4.2 1.7.9 0.4.3 1.8.0 0.4.4 1.8.1 0.4.5 1.8.2 0.4.6 1.8.3 0.4.7 1.8.4 0.4.8 1.8.5 0.4.9 1.8.6 0.5.0 1.8.7 0.5.1 1.8.8 0.5.2 1.8.9 0.5.3 1.9.0 0.5.4 1.9.1 0.5.5 1.9.2 0.5.6 1.9.3 0.5.7 1.9.4 0.5.8 1.9.5 0.5.9 1.9.6 0.6.0 1.9.7 0.6.1 1.9.8 0.6.2 1.9.81 0.6.3 1.9.82 0.6.4 1.9.83 0.6.5 1.9.84 0.6.6 1.9.85 0.6.7 1.9.86 0.6.8 1.9.87 0.6.9 1.9.88 0.7.0 1.9.89 0.7.1 1.9.90 0.7.2 1.9.91 0.7.3 1.9.92 0.7.4 1.9.93 0.7.5 1.9.94 0.7.6 1.9.95 0.7.7 1.9.96 0.7.8 1.9.97 0.7.9 1.9.98 0.8.0 1.9.99 0.8.1 2.0.0 0.8.2 2.0.1 0.8.3 2.0.2 0.8.4 2.0.3 0.8.5 2.0.4 0.8.6 2.0.5 0.8.7 2.0.6 0.8.8 2.0.7 0.8.9 2.0.8 0.9.0 2.0.9 0.9.2 2.1.0 0.9.3 2.1.1 0.9.4 2.1.2 0.9.5 2.1.3 0.9.6 2.1.4 0.9.7 2.1.5 0.9.8 2.1.6 0.9.81 2.1.7 0.9.82 2.1.8 0.9.83 2.1.9 0.9.84 2.2.0 0.9.85 2.2.1 0.9.86 2.2.2 0.9.87 2.2.3 0.9.88 2.2.4 0.9.89 2.2.5 0.9.9 2.2.51 0.9.91 2.2.52 0.9.92 2.2.53 0.9.93 2.2.54 0.9.94 2.2.56 0.9.95 2.2.57 0.9.96 2.2.6 0.9.97 2.2.60 0.9.98 2.2.61 0.9.99 2.2.62 1.0.0 2.2.63 1.0.01 2.2.70 1.0.1 2.2.80 1.0.2 2.2.81 1.0.3 2.2.90 1.0.4 2.2.91 1.0.5 2.2.92 1.0.6 2.2.93 1.0.7 2.2.94 1.0.8 2.2.95 1.0.9 2.3.0 1.1.0 2.3.1 1.1.1 2.3.2 1.1.2 2.3.3 1.1.3 2.3.4 1.1.4 2.3.5 1.1.5 2.3.6 1.1.6 2.3.7 1.1.7 2.3.8 1.1.8 2.3.9 1.1.9 2.4.0 1.2.0 2.4.1 1.2.1 2.4.2 1.2.2 2.4.3 1.2.21 2.4.4 1.2.3 2.4.5 1.2.30 2.4.6 1.3.0 2.4.7 1.3.1 2.4.8 1.3.2 2.4.9 1.3.3 2.5.0 1.3.31 2.5.1 1.3.32 2.5.2 1.3.33 2.5.3 1.3.34 2.5.4 1.3.35 2.5.5 1.3.36 2.5.6 1.3.37 2.5.7 1.3.38 2.5.8 1.3.39 2.5.9 1.3.40 2.6.0 1.3.41 2.6.1 1.3.42 2.6.2 1.3.43 2.6.3 1.3.44 2.6.5 1.3.45 2.6.6 1.3.46 2.6.7 1.3.47 2.6.8 1.3.48 2.6.9 1.3.49 2.7.0 1.3.50 2.7.1 1.3.51 2.7.2 1.3.52 2.7.3 1.3.53 2.7.4 1.3.54 2.7.5 1.3.56 2.7.6 1.3.57 2.7.7 1.3.58 2.7.8 1.3.59 2.7.9 1.3.60 2.8.0 1.3.61 2.8.1 1.3.62 2.8.2 1.3.63 2.8.3 1.3.64 2.8.4 1.3.65 2.8.5 1.3.66 2.8.6 1.3.67 2.8.7 1.3.68 2.8.8 1.3.69 2.8.9 1.3.70 2.9.0 1.3.71 2.9.1 1.3.72 2.9.2 1.3.73 2.9.3 1.3.74 2.9.4 1.3.75 2.9.5 1.3.76 2.9.6 1.3.77 2.9.7 1.3.78 2.9.8 1.3.79 2.9.9 1.3.80 3.0.0 1.3.81 3.0.1 1.3.82 3.0.2 1.3.83 3.0.3 1.3.84 3.0.4 1.3.85 3.0.5 1.3.86 3.0.6 1.3.87 3.0.7 1.3.88 3.0.8 1.3.89 3.0.9 1.3.90 3.1.0 1.3.91 3.1.1 1.3.92 3.1.2 1.3.93 3.1.3 1.3.94 3.1.4 1.3.95 3.1.5 1.3.96 3.1.6 1.3.97 3.1.7 1.3.98 3.1.8 1.3.99 3.1.9 1.4.0 3.2.0 1.4.1 3.2.1 1.4.2 3.2.2 1.4.3 3.2.3 1.4.4 3.2.4 1.4.5 3.2.5 1.4.6 3.2.6 1.4.7 3.2.7 1.4.8 3.2.8 1.4.9 3.2.9 1.5.0 3.3.0 1.5.1 3.3.1 1.5.2 3.3.2 1.5.3 3.3.3 1.5.4 3.3.4 1.5.5 3.3.5 1.5.6 3.3.6 1.5.7 3.3.7 1.5.8 3.3.8 1.5.9 3.3.9 1.6.0 3.4.0 1.6.1 3.4.1 1.6.2 3.4.2 1.6.3 3.4.3 1.6.5 3.4.4 1.6.51 3.4.5 1.6.52 3.4.6 1.6.53 1.6.54 1.6.55 1.6.56 1.6.57 1.6.58 1.6.59 1.6.60 1.6.61 1.6.62 1.6.63 1.6.64 1.6.65 1.6.66 1.6.67 1.6.68 trunk 1.6.69 0.0.1 1.6.70 0.0.2 1.6.71 0.0.3 1.6.72 0.0.4 1.6.73 0.0.5 1.6.74 0.0.6 1.6.75 0.0.7 1.6.76 0.0.8 1.6.77 0.0.9 1.6.78 0.1.0 1.6.79 0.1.1 1.6.81 0.1.2 1.6.82 0.1.3 1.6.83 0.1.4 1.6.84 0.1.5 1.6.85 0.1.6 1.6.86 0.1.7 1.6.87 0.1.8 1.6.88 0.1.9 1.6.89 0.2.0 1.6.90
ai-engine / classes / services / usage-stats.php
ai-engine / classes / services Last commit date
image.php 11 months ago message-builder.php 10 months ago model-environment.php 11 months ago response-id-manager.php 11 months ago session.php 11 months ago usage-stats.php 11 months ago
usage-stats.php
275 lines
1 <?php
2
3 class Meow_MWAI_Services_UsageStats {
4 private $core;
5
6 public function __construct( $core ) {
7 $this->core = $core;
8 }
9
10 public function estimate_tokens( ...$args ) {
11 // Handle multiple argument formats for backward compatibility
12 $text = '';
13 $model = null;
14
15 // If first argument is an array, process messages
16 if ( !empty( $args[0] ) && is_array( $args[0] ) ) {
17 foreach ( $args[0] as $message ) {
18 $text .= isset( $message['content']['text'] ) ? $message['content']['text'] : '';
19 $text .= isset( $message['content'] ) && is_string( $message['content'] ) ? $message['content'] : '';
20 }
21 $model = $args[1] ?? null;
22 }
23 // Otherwise treat first argument as text
24 else {
25 $text = $args[0] ?? '';
26 $model = $args[1] ?? null;
27 }
28
29 // Convert to string if needed
30 if ( !is_string( $text ) ) {
31 // Handle arrays that weren't caught by the first condition
32 if ( is_array( $text ) ) {
33 $text = json_encode( $text );
34 }
35 // Handle objects
36 elseif ( is_object( $text ) ) {
37 $text = method_exists( $text, '__toString' ) ? (string) $text : json_encode( $text );
38 }
39 // Handle other types (int, float, bool, null)
40 else {
41 $text = (string) $text;
42 }
43 }
44
45 // Many other tools (https://platform.openai.com/tokenizer) say 1 token ~= 4 chars in English.
46 // However, the tokens are usually calculated with the exact tokenizer for the model, but this is not really possible easily yet.
47 $text = apply_filters( 'mwai_estimate_tokens_text', $text, $model );
48 $tokens = apply_filters( 'mwai_estimate_tokens', null, $text, $model );
49 if ( $tokens !== null ) {
50 return $tokens;
51 }
52 $multiplier = 4;
53 $hasChineseChars = preg_match( '/[\x{4e00}-\x{9fa5}]/u', $text );
54 $hasJapaneseChars = preg_match( '/[\x{3040}-\x{309f}\x{30a0}-\x{30ff}]/u', $text );
55 $hasKoreanChars = preg_match( '/[\x{ac00}-\x{d7af}]/u', $text );
56 if ( $hasChineseChars || $hasJapaneseChars || $hasKoreanChars ) {
57 $multiplier = 2;
58 }
59 $tokens = (int) ( ( function_exists( 'mb_strlen' ) ? mb_strlen( $text ) : strlen( $text ) ) / $multiplier );
60 return $tokens;
61 }
62
63 public function record_tokens_usage( $model, $in_tokens, $out_tokens = 0, $returned_price = null ) {
64 if ( !is_numeric( $in_tokens ) ) {
65 $in_tokens = 0;
66 }
67 if ( !is_numeric( $out_tokens ) ) {
68 $out_tokens = 0;
69 }
70
71 // Record monthly usage
72 $usage = $this->core->get_option( 'ai_usage' );
73 $month = date( 'Y-m' );
74 if ( !isset( $usage[$month] ) ) {
75 $usage[$month] = [];
76 }
77 if ( !isset( $usage[$month][$model] ) ) {
78 $usage[$month][$model] = [
79 'prompt_tokens' => 0,
80 'completion_tokens' => 0,
81 'total_tokens' => 0,
82 'returned_price' => 0,
83 'queries' => 0
84 ];
85 }
86 // Ensure queries field exists for existing data
87 if ( !isset( $usage[$month][$model]['queries'] ) ) {
88 $usage[$month][$model]['queries'] = 0;
89 }
90 $usage[$month][$model]['prompt_tokens'] += $in_tokens;
91 $usage[$month][$model]['completion_tokens'] += $out_tokens;
92 $usage[$month][$model]['total_tokens'] += $in_tokens + $out_tokens;
93 $usage[$month][$model]['queries'] += 1;
94 if ( !empty( $returned_price ) ) {
95 // Ensure returned_price is numeric to avoid type errors
96 $price_value = is_array( $returned_price ) ?
97 ( isset( $returned_price['price'] ) ? $returned_price['price'] : 0 ) :
98 ( is_numeric( $returned_price ) ? $returned_price : 0 );
99 $usage[$month][$model]['returned_price'] += $price_value;
100 }
101
102 // Clean up old monthly data (keep only last 2 years)
103 $this->cleanup_old_monthly_data( $usage );
104 $this->core->update_option( 'ai_usage', $usage );
105
106 // Record daily usage
107 $daily_usage = $this->core->get_option( 'ai_usage_daily', [] );
108 $day = date( 'Y-m-d' );
109 if ( !isset( $daily_usage[$day] ) ) {
110 $daily_usage[$day] = [];
111 }
112 if ( !isset( $daily_usage[$day][$model] ) ) {
113 $daily_usage[$day][$model] = [
114 'prompt_tokens' => 0,
115 'completion_tokens' => 0,
116 'total_tokens' => 0,
117 'returned_price' => 0,
118 'queries' => 0
119 ];
120 }
121 // Ensure queries field exists for existing data
122 if ( !isset( $daily_usage[$day][$model]['queries'] ) ) {
123 $daily_usage[$day][$model]['queries'] = 0;
124 }
125 $daily_usage[$day][$model]['prompt_tokens'] += $in_tokens;
126 $daily_usage[$day][$model]['completion_tokens'] += $out_tokens;
127 $daily_usage[$day][$model]['total_tokens'] += $in_tokens + $out_tokens;
128 $daily_usage[$day][$model]['queries'] += 1;
129 if ( !empty( $returned_price ) ) {
130 $daily_usage[$day][$model]['returned_price'] += $returned_price;
131 }
132
133 // Clean up old daily data (keep only last 30 days)
134 $this->cleanup_old_daily_data( $daily_usage );
135 $this->core->update_option( 'ai_usage_daily', $daily_usage );
136
137 // Return the usage data for this specific request
138 return [
139 'prompt_tokens' => $in_tokens,
140 'completion_tokens' => $out_tokens,
141 'total_tokens' => $in_tokens + $out_tokens,
142 'price' => $returned_price,
143 'queries' => 1
144 ];
145 }
146
147 public function record_audio_usage( $model, $seconds ) {
148 // Record monthly usage
149 $usage = $this->core->get_option( 'ai_usage' );
150 $month = date( 'Y-m' );
151 if ( !isset( $usage[$month] ) ) {
152 $usage[$month] = [];
153 }
154 if ( !isset( $usage[$month][$model] ) ) {
155 $usage[$month][$model] = [ 'seconds' => 0, 'queries' => 0 ];
156 }
157 if ( !isset( $usage[$month][$model]['seconds'] ) ) {
158 $usage[$month][$model]['seconds'] = 0;
159 }
160 if ( !isset( $usage[$month][$model]['queries'] ) ) {
161 $usage[$month][$model]['queries'] = 0;
162 }
163 $usage[$month][$model]['seconds'] += $seconds;
164 $usage[$month][$model]['queries'] += 1;
165 $this->cleanup_old_monthly_data( $usage );
166 $this->core->update_option( 'ai_usage', $usage );
167
168 // Record daily usage
169 $daily_usage = $this->core->get_option( 'ai_usage_daily', [] );
170 $day = date( 'Y-m-d' );
171 if ( !isset( $daily_usage[$day] ) ) {
172 $daily_usage[$day] = [];
173 }
174 if ( !isset( $daily_usage[$day][$model] ) ) {
175 $daily_usage[$day][$model] = [ 'seconds' => 0, 'queries' => 0 ];
176 }
177 if ( !isset( $daily_usage[$day][$model]['seconds'] ) ) {
178 $daily_usage[$day][$model]['seconds'] = 0;
179 }
180 if ( !isset( $daily_usage[$day][$model]['queries'] ) ) {
181 $daily_usage[$day][$model]['queries'] = 0;
182 }
183 $daily_usage[$day][$model]['seconds'] += $seconds;
184 $daily_usage[$day][$model]['queries'] += 1;
185 $this->cleanup_old_daily_data( $daily_usage );
186 $this->core->update_option( 'ai_usage_daily', $daily_usage );
187
188 // Return the usage data for this specific request
189 return [
190 'seconds' => $seconds,
191 'queries' => 1
192 ];
193 }
194
195 public function record_images_usage( $model, $resolution, $images ) {
196 // Record monthly usage
197 $usage = $this->core->get_option( 'ai_usage' );
198 $month = date( 'Y-m' );
199 if ( !isset( $usage[$month] ) ) {
200 $usage[$month] = [];
201 }
202 if ( !isset( $usage[$month][$model] ) ) {
203 $usage[$month][$model] = [ 'resolution' => [], 'images' => 0, 'queries' => 0 ];
204 }
205 if ( !isset( $usage[$month][$model]['images'] ) ) {
206 $usage[$month][$model]['images'] = 0;
207 }
208 if ( !isset( $usage[$month][$model]['resolution'] ) ) {
209 $usage[$month][$model]['resolution'] = [];
210 }
211 if ( !isset( $usage[$month][$model]['resolution'][$resolution] ) ) {
212 $usage[$month][$model]['resolution'][$resolution] = 0;
213 }
214 if ( !isset( $usage[$month][$model]['queries'] ) ) {
215 $usage[$month][$model]['queries'] = 0;
216 }
217 $usage[$month][$model]['images'] += $images;
218 $usage[$month][$model]['resolution'][$resolution] += $images;
219 $usage[$month][$model]['queries'] += 1;
220 $this->cleanup_old_monthly_data( $usage );
221 $this->core->update_option( 'ai_usage', $usage );
222
223 // Record daily usage
224 $daily_usage = $this->core->get_option( 'ai_usage_daily', [] );
225 $day = date( 'Y-m-d' );
226 if ( !isset( $daily_usage[$day] ) ) {
227 $daily_usage[$day] = [];
228 }
229 if ( !isset( $daily_usage[$day][$model] ) ) {
230 $daily_usage[$day][$model] = [ 'resolution' => [], 'images' => 0, 'queries' => 0 ];
231 }
232 if ( !isset( $daily_usage[$day][$model]['images'] ) ) {
233 $daily_usage[$day][$model]['images'] = 0;
234 }
235 if ( !isset( $daily_usage[$day][$model]['resolution'] ) ) {
236 $daily_usage[$day][$model]['resolution'] = [];
237 }
238 if ( !isset( $daily_usage[$day][$model]['resolution'][$resolution] ) ) {
239 $daily_usage[$day][$model]['resolution'][$resolution] = 0;
240 }
241 if ( !isset( $daily_usage[$day][$model]['queries'] ) ) {
242 $daily_usage[$day][$model]['queries'] = 0;
243 }
244 $daily_usage[$day][$model]['images'] += $images;
245 $daily_usage[$day][$model]['resolution'][$resolution] += $images;
246 $daily_usage[$day][$model]['queries'] += 1;
247 $this->cleanup_old_daily_data( $daily_usage );
248 $this->core->update_option( 'ai_usage_daily', $daily_usage );
249
250 // Return the usage data for this specific request
251 return [
252 'images' => $images,
253 'queries' => 1
254 ];
255 }
256
257 private function cleanup_old_monthly_data( &$usage ) {
258 $two_years_ago = date( 'Y-m', strtotime( '-2 years' ) );
259 foreach ( $usage as $month => $data ) {
260 if ( $month < $two_years_ago ) {
261 unset( $usage[$month] );
262 }
263 }
264 }
265
266 private function cleanup_old_daily_data( &$usage ) {
267 $thirty_days_ago = date( 'Y-m-d', strtotime( '-30 days' ) );
268 foreach ( $usage as $day => $data ) {
269 if ( $day < $thirty_days_ago ) {
270 unset( $usage[$day] );
271 }
272 }
273 }
274 }
275