PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.9.7
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.9.7
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 1 year ago message-builder.php 11 months ago model-environment.php 11 months ago response-id-manager.php 1 year ago session.php 11 months ago usage-stats.php 11 months ago
usage-stats.php
271 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 $usage[$month][$model]['returned_price'] += $returned_price;
96 }
97
98 // Clean up old monthly data (keep only last 2 years)
99 $this->cleanup_old_monthly_data( $usage );
100 $this->core->update_option( 'ai_usage', $usage );
101
102 // Record daily usage
103 $daily_usage = $this->core->get_option( 'ai_usage_daily', [] );
104 $day = date( 'Y-m-d' );
105 if ( !isset( $daily_usage[$day] ) ) {
106 $daily_usage[$day] = [];
107 }
108 if ( !isset( $daily_usage[$day][$model] ) ) {
109 $daily_usage[$day][$model] = [
110 'prompt_tokens' => 0,
111 'completion_tokens' => 0,
112 'total_tokens' => 0,
113 'returned_price' => 0,
114 'queries' => 0
115 ];
116 }
117 // Ensure queries field exists for existing data
118 if ( !isset( $daily_usage[$day][$model]['queries'] ) ) {
119 $daily_usage[$day][$model]['queries'] = 0;
120 }
121 $daily_usage[$day][$model]['prompt_tokens'] += $in_tokens;
122 $daily_usage[$day][$model]['completion_tokens'] += $out_tokens;
123 $daily_usage[$day][$model]['total_tokens'] += $in_tokens + $out_tokens;
124 $daily_usage[$day][$model]['queries'] += 1;
125 if ( !empty( $returned_price ) ) {
126 $daily_usage[$day][$model]['returned_price'] += $returned_price;
127 }
128
129 // Clean up old daily data (keep only last 30 days)
130 $this->cleanup_old_daily_data( $daily_usage );
131 $this->core->update_option( 'ai_usage_daily', $daily_usage );
132
133 // Return the usage data for this specific request
134 return [
135 'prompt_tokens' => $in_tokens,
136 'completion_tokens' => $out_tokens,
137 'total_tokens' => $in_tokens + $out_tokens,
138 'price' => $returned_price,
139 'queries' => 1
140 ];
141 }
142
143 public function record_audio_usage( $model, $seconds ) {
144 // Record monthly usage
145 $usage = $this->core->get_option( 'ai_usage' );
146 $month = date( 'Y-m' );
147 if ( !isset( $usage[$month] ) ) {
148 $usage[$month] = [];
149 }
150 if ( !isset( $usage[$month][$model] ) ) {
151 $usage[$month][$model] = [ 'seconds' => 0, 'queries' => 0 ];
152 }
153 if ( !isset( $usage[$month][$model]['seconds'] ) ) {
154 $usage[$month][$model]['seconds'] = 0;
155 }
156 if ( !isset( $usage[$month][$model]['queries'] ) ) {
157 $usage[$month][$model]['queries'] = 0;
158 }
159 $usage[$month][$model]['seconds'] += $seconds;
160 $usage[$month][$model]['queries'] += 1;
161 $this->cleanup_old_monthly_data( $usage );
162 $this->core->update_option( 'ai_usage', $usage );
163
164 // Record daily usage
165 $daily_usage = $this->core->get_option( 'ai_usage_daily', [] );
166 $day = date( 'Y-m-d' );
167 if ( !isset( $daily_usage[$day] ) ) {
168 $daily_usage[$day] = [];
169 }
170 if ( !isset( $daily_usage[$day][$model] ) ) {
171 $daily_usage[$day][$model] = [ 'seconds' => 0, 'queries' => 0 ];
172 }
173 if ( !isset( $daily_usage[$day][$model]['seconds'] ) ) {
174 $daily_usage[$day][$model]['seconds'] = 0;
175 }
176 if ( !isset( $daily_usage[$day][$model]['queries'] ) ) {
177 $daily_usage[$day][$model]['queries'] = 0;
178 }
179 $daily_usage[$day][$model]['seconds'] += $seconds;
180 $daily_usage[$day][$model]['queries'] += 1;
181 $this->cleanup_old_daily_data( $daily_usage );
182 $this->core->update_option( 'ai_usage_daily', $daily_usage );
183
184 // Return the usage data for this specific request
185 return [
186 'seconds' => $seconds,
187 'queries' => 1
188 ];
189 }
190
191 public function record_images_usage( $model, $resolution, $images ) {
192 // Record monthly usage
193 $usage = $this->core->get_option( 'ai_usage' );
194 $month = date( 'Y-m' );
195 if ( !isset( $usage[$month] ) ) {
196 $usage[$month] = [];
197 }
198 if ( !isset( $usage[$month][$model] ) ) {
199 $usage[$month][$model] = [ 'resolution' => [], 'images' => 0, 'queries' => 0 ];
200 }
201 if ( !isset( $usage[$month][$model]['images'] ) ) {
202 $usage[$month][$model]['images'] = 0;
203 }
204 if ( !isset( $usage[$month][$model]['resolution'] ) ) {
205 $usage[$month][$model]['resolution'] = [];
206 }
207 if ( !isset( $usage[$month][$model]['resolution'][$resolution] ) ) {
208 $usage[$month][$model]['resolution'][$resolution] = 0;
209 }
210 if ( !isset( $usage[$month][$model]['queries'] ) ) {
211 $usage[$month][$model]['queries'] = 0;
212 }
213 $usage[$month][$model]['images'] += $images;
214 $usage[$month][$model]['resolution'][$resolution] += $images;
215 $usage[$month][$model]['queries'] += 1;
216 $this->cleanup_old_monthly_data( $usage );
217 $this->core->update_option( 'ai_usage', $usage );
218
219 // Record daily usage
220 $daily_usage = $this->core->get_option( 'ai_usage_daily', [] );
221 $day = date( 'Y-m-d' );
222 if ( !isset( $daily_usage[$day] ) ) {
223 $daily_usage[$day] = [];
224 }
225 if ( !isset( $daily_usage[$day][$model] ) ) {
226 $daily_usage[$day][$model] = [ 'resolution' => [], 'images' => 0, 'queries' => 0 ];
227 }
228 if ( !isset( $daily_usage[$day][$model]['images'] ) ) {
229 $daily_usage[$day][$model]['images'] = 0;
230 }
231 if ( !isset( $daily_usage[$day][$model]['resolution'] ) ) {
232 $daily_usage[$day][$model]['resolution'] = [];
233 }
234 if ( !isset( $daily_usage[$day][$model]['resolution'][$resolution] ) ) {
235 $daily_usage[$day][$model]['resolution'][$resolution] = 0;
236 }
237 if ( !isset( $daily_usage[$day][$model]['queries'] ) ) {
238 $daily_usage[$day][$model]['queries'] = 0;
239 }
240 $daily_usage[$day][$model]['images'] += $images;
241 $daily_usage[$day][$model]['resolution'][$resolution] += $images;
242 $daily_usage[$day][$model]['queries'] += 1;
243 $this->cleanup_old_daily_data( $daily_usage );
244 $this->core->update_option( 'ai_usage_daily', $daily_usage );
245
246 // Return the usage data for this specific request
247 return [
248 'images' => $images,
249 'queries' => 1
250 ];
251 }
252
253 private function cleanup_old_monthly_data( &$usage ) {
254 $two_years_ago = date( 'Y-m', strtotime( '-2 years' ) );
255 foreach ( $usage as $month => $data ) {
256 if ( $month < $two_years_ago ) {
257 unset( $usage[$month] );
258 }
259 }
260 }
261
262 private function cleanup_old_daily_data( &$usage ) {
263 $thirty_days_ago = date( 'Y-m-d', strtotime( '-30 days' ) );
264 foreach ( $usage as $day => $data ) {
265 if ( $day < $thirty_days_ago ) {
266 unset( $usage[$day] );
267 }
268 }
269 }
270 }
271