PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.1.4
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.1.4
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 / ai.php
ai-engine / classes Last commit date
modules 3 years ago admin.php 3 years ago ai.php 3 years ago answer.php 3 years ago core.php 3 years ago init.php 3 years ago openai.php 3 years ago query.php 3 years ago queryimage.php 3 years ago querytext.php 3 years ago rest.php 3 years ago ui.php 3 years ago
ai.php
229 lines
1 <?php
2
3 class Meow_MWAI_AI {
4 private $core = null;
5 private $localApiKey = null;
6
7 public function __construct( $core ) {
8 $this->core = $core;
9 $this->localApiKey = $this->core->get_option( 'openai_apikey' );
10 }
11
12 // Record usage of the API on a monthly basis
13 public function record_usage( $model, $prompt_tokens, $completion_tokens = 0 ) {
14 if ( !is_numeric( $prompt_tokens ) ) {
15 throw new Exception( 'Record usage: prompt_tokens is not a number.' );
16 }
17 if ( !is_numeric( $completion_tokens ) ) {
18 $completion_tokens = 0;
19 }
20 if ( !$model ) {
21 throw new Exception( 'Record usage: model is missing.' );
22 }
23 $usage = $this->core->get_option( 'openai_usage' );
24 $month = date( 'Y-m' );
25 if ( !isset( $usage[$month] ) ) {
26 $usage[$month] = array();
27 }
28 if ( !isset( $usage[$month][$model] ) ) {
29 $usage[$month][$model] = array(
30 'prompt_tokens' => 0,
31 'completion_tokens' => 0,
32 'total_tokens' => 0
33 );
34 }
35 $usage[$month][$model]['prompt_tokens'] += $prompt_tokens;
36 $usage[$month][$model]['completion_tokens'] += $completion_tokens;
37 $usage[$month][$model]['total_tokens'] += $prompt_tokens + $completion_tokens;
38 $this->core->update_option( 'openai_usage', $usage );
39 return [
40 'prompt_tokens' => $prompt_tokens,
41 'completion_tokens' => $completion_tokens,
42 'total_tokens' => $prompt_tokens + $completion_tokens
43 ];
44 }
45
46 public function record_image_usage( $model, $resolution, $images ) {
47 if ( !$model || !$resolution || !$images ) {
48 throw new Exception( 'Missing parameters for record_dalle_usage.' );
49 }
50 $usage = $this->core->get_option( 'openai_usage' );
51 $month = date( 'Y-m' );
52 if ( !isset( $usage[$month] ) ) {
53 $usage[$month] = array();
54 }
55 if ( !isset( $usage[$month][$model] ) ) {
56 $usage[$month][$model] = array(
57 'resolution' => array(),
58 'images' => 0
59 );
60 }
61 if ( !isset( $usage[$month][$model]['resolution'][$resolution] ) ) {
62 $usage[$month][$model]['resolution'][$resolution] = 0;
63 }
64 $usage[$month][$model]['resolution'][$resolution] += $images;
65 $usage[$month][$model]['images'] += $images;
66 $this->core->update_option( 'openai_usage', $usage );
67 return [
68 'resolution' => $resolution,
69 'images' => $images
70 ];
71 }
72
73 public function runTextQuery( $query ) {
74 if ( empty( $query->apiKey ) ) {
75 $query->apiKey = $this->localApiKey;
76 }
77
78 $url = "";
79 $body = array(
80 "model" => $query->model,
81 "stop" => $query->stop,
82 "n" => $query->maxResults,
83 "max_tokens" => $query->maxTokens,
84 "temperature" => $query->temperature,
85 );
86
87 if ( $query->mode === 'chat' ) {
88 $url = 'https://api.openai.com/v1/chat/completions';
89 $body['messages'] = $query->messages;
90 }
91 else if ( $query->mode === 'completion' ) {
92 $url = 'https://api.openai.com/v1/completions';
93 $body['prompt'] = $query->prompt;
94 }
95 else {
96 throw new Exception( 'Unknown mode for query: ' . $query->mode );
97 }
98
99 $options = array(
100 "headers" => "Content-Type: application/json\r\n" . "Authorization: Bearer " . $query->apiKey . "\r\n",
101 "method" => "POST",
102 "timeout" => 120,
103 "body" => json_encode( $body ),
104 "sslverify" => false
105 );
106
107 try {
108 $response = wp_remote_get( $url, $options );
109 if ( is_wp_error( $response ) ) {
110 throw new Exception( $response->get_error_message() );
111 }
112 $response = wp_remote_retrieve_body( $response );
113 $data = json_decode( $response, true );
114
115 // Error handling
116 if ( isset( $data['error'] ) ) {
117 $message = $data['error']['message'];
118 // If the message contains "Incorrect API key provided: THE_KEY.", replace the key by "----".
119 if ( preg_match( '/API key provided(: .*)\./', $message, $matches ) ) {
120 $message = str_replace( $matches[1], '', $message );
121 }
122 throw new Exception( $message );
123 }
124 if ( !$data['model'] ) {
125 error_log( print_r( $data, 1 ) );
126 throw new Exception( "Got an unexpected response from OpenAI. Check your PHP Error Logs." );
127 }
128 $answer = new Meow_MWAI_Answer( $query );
129 $usage = $this->record_usage( $data['model'], $data['usage']['prompt_tokens'],
130 $data['usage']['completion_tokens'] );
131 $answer->setUsage( $usage );
132 $answer->setChoices( $data['choices'] );
133 return $answer;
134 }
135 catch ( Exception $e ) {
136 error_log( $e->getMessage() );
137 throw new Exception( 'Error while calling OpenAI: ' . $e->getMessage() );
138 }
139 }
140
141 // Request to DALL-E API
142 public function runImageQuery( $query ) {
143 if ( empty( $query->apiKey ) ) {
144 $query->apiKey = $this->localApiKey;
145 }
146 $url = 'https://api.openai.com/v1/images/generations';
147 $options = array(
148 "headers" => "Content-Type: application/json\r\n" . "Authorization: Bearer " . $query->apiKey . "\r\n",
149 "method" => "POST",
150 "timeout" => 120,
151 "body" => json_encode( array(
152 "prompt" => $query->prompt,
153 "n" => $query->maxResults,
154 "size" => '1024x1024',
155 ) ),
156 "sslverify" => false
157 );
158
159 try {
160 $response = wp_remote_get( $url, $options );
161 if ( is_wp_error( $response ) ) {
162 throw new Exception( $response->get_error_message() );
163 }
164 $response = wp_remote_retrieve_body( $response );
165 $data = json_decode( $response, true );
166
167 // Error handling
168 if ( isset( $data['error'] ) ) {
169 $message = $data['error']['message'];
170 // If the message contains "Incorrect API key provided: THE_KEY.", replace the key by "----".
171 if ( preg_match( '/API key provided(: .*)\./', $message, $matches ) ) {
172 $message = str_replace( $matches[1], '', $message );
173 }
174 throw new Exception( $message );
175 }
176
177 $answer = new Meow_MWAI_Answer( $query );
178 $usage = $this->record_image_usage( "dall-e", "1024x1024", $query->maxResults );
179 $answer->setUsage( $usage );
180 $answer->setChoices( $data['data'] );
181 return $answer;
182 }
183 catch ( Exception $e ) {
184 error_log( $e->getMessage() );
185 throw new Exception( 'Error while calling OpenAI: ' . $e->getMessage() );
186 }
187 }
188
189 public function throwException( $message ) {
190 $message = apply_filters( 'mwai_ai_exception', $message );
191 throw new Exception( $message );
192 }
193
194 public function run( $query ) {
195
196 // Check if the query is allowed
197 $limits = $this->core->get_option( 'limits' );
198 $ok = apply_filters( 'mwai_ai_allowed', true, $query, $limits );
199 if ( $ok !== true ) {
200 $message = is_string( $ok ) ? $ok : 'Unauthorized query.';
201 $this->throwException( $message );
202 }
203
204 // Allow to modify the query
205 $query = apply_filters( 'mwai_ai_query', $query );
206
207 // Run the query
208 $answer = null;
209 try {
210 if ( $query instanceof Meow_MWAI_QueryText ) {
211 $answer = $this->runTextQuery( $query );
212 }
213 else if ( $query instanceof Meow_MWAI_QueryImage ) {
214 $answer = $this->runImageQuery( $query );
215 }
216 else {
217 $this->throwException( 'Invalid query.' );
218 }
219 }
220 catch ( Exception $e ) {
221 $this->throwException( $e->getMessage() );
222 }
223
224 // Let's allow some modififications of the answer
225 $answer = apply_filters( 'mwai_ai_reply', $answer, $query );
226 return $answer;
227 }
228 }
229