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