PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.6.0
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.6.0
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 api.php 3 years ago core.php 3 years ago init.php 3 years ago openai.php 3 years ago query.php 3 years ago queryembed.php 3 years ago queryimage.php 3 years ago querytext.php 3 years ago querytranscribe.php 3 years ago rest.php 3 years ago security.php 3 years ago
ai.php
299 lines
1 <?php
2
3 class Meow_MWAI_AI {
4 private $core = null;
5 private $localApiKey = null;
6 private $localService = null;
7 private $localAzureEndpoint = null;
8 private $localAzureApiKey = null;
9 private $localAzureDeployments = null;
10
11 public function __construct( $core ) {
12 $this->core = $core;
13 $this->localService = $this->core->get_option( 'openai_service' );
14 $this->localApiKey = $this->core->get_option( 'openai_apikey' );
15 $this->localAzureEndpoint = $this->core->get_option( 'openai_azure_endpoint' );
16 $this->localAzureApiKey = $this->core->get_option( 'openai_azure_apikey' );
17 $this->localAzureDeployments = $this->core->get_option( 'openai_azure_deployments' );
18 }
19
20 private function runQuery( $url, $options ) {
21 try {
22 $response = wp_remote_get( $url, $options );
23 if ( is_wp_error( $response ) ) {
24 throw new Exception( $response->get_error_message() );
25 }
26 $response = wp_remote_retrieve_body( $response );
27 $data = json_decode( $response, true );
28
29 if ( isset( $data['error'] ) ) {
30 $message = $data['error']['message'];
31 if ( preg_match( '/API key provided(: .*)\./', $message, $matches ) ) {
32 $message = str_replace( $matches[1], '', $message );
33 }
34 throw new Exception( $message );
35 }
36
37 return $data;
38 }
39 catch ( Exception $e ) {
40 error_log( $e->getMessage() );
41 throw new Exception( 'Error while calling OpenAI: ' . $e->getMessage() );
42 }
43 }
44
45 public function applyQueryParameters( $query ) {
46 // OpenAI will be used by default for everything
47 // But if the service is set to Azure and the deployments/models are available,
48 // then we will use Azure instead.
49 if ( empty( $query->service ) ) {
50 $query->service = $this->localService;
51 }
52
53 // OpenAI
54 if ( empty( $query->apiKey ) ) {
55 $query->apiKey = $this->localApiKey;
56 }
57
58 // Azure
59 if ( $query->service === 'azure' && !empty( $this->localAzureDeployments ) ) {
60 $found = false;
61 foreach ( $this->localAzureDeployments as $deployment ) {
62 if ( $deployment['model'] === $query->model ) {
63 $query->azureDeployment = $deployment['name'];
64 if ( empty( $query->azureEndpoint ) ) {
65 $query->azureEndpoint = $this->localAzureEndpoint;
66 }
67 if ( empty( $query->azureApiKey ) ) {
68 $query->azureApiKey = $this->localAzureApiKey;
69 }
70 $found = true;
71 break;
72 }
73 }
74 if ( !$found ) {
75 error_log( 'Azure deployment not found for model: ' . $query->model );
76 $query->service = 'openai';
77 }
78 }
79 }
80
81 public function runTranscribe( $query ) {
82 $this->applyQueryParameters( $query );
83 $openai = new Meow_MWAI_OpenAI( $this->core );
84 $fields = array(
85 'prompt' => $query->prompt,
86 'model' => $query->model,
87 'response_format' => 'text',
88 'file' => basename( $query->url ),
89 'data' => file_get_contents( $query->url )
90 );
91 $modeEndpoint = $query->mode === 'translation' ? 'translations' : 'transcriptions';
92 $data = $openai->run( 'POST', '/audio/' . $modeEndpoint, null, $fields, false );
93 if ( empty( $data ) ) {
94 throw new Exception( 'Invalid data for transcription.' );
95 }
96 //$usage = $data['usage'];
97 //$this->core->record_tokens_usage( $query->model, $usage['prompt_tokens'] );
98 $answer = new Meow_MWAI_Answer( $query );
99 //$answer->setUsage( $usage );
100 $answer->setChoices( $data );
101 return $answer;
102 }
103
104 public function runEmbedding( $query ) {
105 $this->applyQueryParameters( $query );
106
107 // TODO: Let's follow closely the changes at Azure.
108 // Seems we need to specify an API version, otherwise it breaks.
109 if ( $query->service === 'azure' ) {
110 $url = trailingslashit( $query->azureEndpoint ) . 'openai/deployments/' .
111 $query->azureDeployment . '/embeddings?api-version=2023-03-15-preview';
112 $headers = array( 'Content-Type' => 'application/json', 'api-key' => $query->azureApiKey );
113 $body = array( "input" => $query->prompt );
114 $options = array(
115 "headers" => $headers,
116 "method" => "POST",
117 "timeout" => 120,
118 "body" => json_encode( $body ),
119 "sslverify" => false
120 );
121 $data = $this->runQuery( $url, $options );
122 }
123 else {
124 $openai = new Meow_MWAI_OpenAI( $this->core );
125 $body = array( 'input' => $query->prompt, 'model' => $query->model );
126 $data = $openai->run( 'POST', '/embeddings', $body );
127 }
128 if ( empty( $data ) || !isset( $data['data'] ) ) {
129 throw new Exception( 'Invalid data for embedding.' );
130 }
131 $usage = $data['usage'];
132 $this->core->record_tokens_usage( $query->model, $usage['prompt_tokens'] );
133 $answer = new Meow_MWAI_Answer( $query );
134 $answer->setUsage( $usage );
135 $answer->setChoices( $data['data'] );
136 return $answer;
137 }
138
139 public function runCompletion( $query ) {
140 $this->applyQueryParameters( $query );
141 if ( $query->mode !== 'chat' && $query->mode !== 'completion' ) {
142 throw new Exception( 'Unknown mode for query: ' . $query->mode );
143 }
144 $url = "";
145 $headers = array(
146 'Content-Type' => 'application/json',
147 'Authorization' => 'Bearer ' . $query->apiKey,
148 );
149
150 // Body
151 $body = array(
152 "model" => $query->model,
153 "stop" => $query->stop,
154 "n" => $query->maxResults,
155 "max_tokens" => $query->maxTokens,
156 "temperature" => $query->temperature,
157 );
158 if ( $query->mode === 'chat' ) {
159 $body['messages'] = $query->messages;
160 }
161 else if ( $query->mode === 'completion' ) {
162 $body['prompt'] = $query->getPrompt();
163 }
164
165 // Azure
166 if ( $query->service === 'azure' ) {
167 $headers = array( 'Content-Type' => 'application/json', 'api-key' => $query->azureApiKey );
168 if ( $query->mode === 'chat' ) {
169 $url = trailingslashit( $query->azureEndpoint ) . 'openai/deployments/' .
170 $query->azureDeployment . '/chat/completions?api-version=2023-03-15-preview';
171
172 }
173 else if ( $query->mode === 'completion' ) {
174 $url = trailingslashit( $query->azureEndpoint ) . 'openai/deployments/' .
175 $query->azureDeployment . '/completions?api-version=2023-03-15-preview';
176 }
177 }
178 // OpenAI
179 else {
180 if ( $query->mode === 'chat' ) {
181 $url = 'https://api.openai.com/v1/chat/completions';
182 }
183 else if ( $query->mode === 'completion' ) {
184 $url = 'https://api.openai.com/v1/completions';
185 }
186 }
187
188 $options = array(
189 "headers" => $headers,
190 "method" => "POST",
191 "timeout" => 120,
192 "body" => json_encode( $body ),
193 "sslverify" => false
194 );
195
196 try {
197 $data = $this->runQuery( $url, $options );
198 if ( !$data['model'] ) {
199 error_log( print_r( $data, 1 ) );
200 throw new Exception( "Got an unexpected response from OpenAI. Check your PHP Error Logs." );
201 }
202 $answer = new Meow_MWAI_Answer( $query );
203 try {
204 $usage = $this->core->record_tokens_usage(
205 $data['model'],
206 $data['usage']['prompt_tokens'],
207 $data['usage']['completion_tokens']
208 );
209 }
210 catch ( Exception $e ) {
211 error_log( $e->getMessage() );
212 }
213 $answer->setUsage( $usage );
214 $answer->setChoices( $data['choices'] );
215 return $answer;
216 }
217 catch ( Exception $e ) {
218 error_log( $e->getMessage() );
219 throw new Exception( 'Error while calling OpenAI: ' . $e->getMessage() );
220 }
221 }
222
223 // Request to DALL-E API
224 public function runCreateImages( $query ) {
225 $this->applyQueryParameters( $query );
226 $url = 'https://api.openai.com/v1/images/generations';
227 $options = array(
228 "headers" => "Content-Type: application/json\r\n" . "Authorization: Bearer " . $query->apiKey . "\r\n",
229 "method" => "POST",
230 "timeout" => 120,
231 "body" => json_encode( array(
232 "prompt" => $query->prompt,
233 "n" => $query->maxResults,
234 "size" => '1024x1024',
235 ) ),
236 "sslverify" => false
237 );
238
239 try {
240 $data = $this->runQuery( $url, $options );
241 $answer = new Meow_MWAI_Answer( $query );
242 $usage = $this->core->record_images_usage( "dall-e", "1024x1024", $query->maxResults );
243 $answer->setUsage( $usage );
244 $answer->setChoices( $data['data'] );
245 return $answer;
246 }
247 catch ( Exception $e ) {
248 error_log( $e->getMessage() );
249 throw new Exception( 'Error while calling OpenAI: ' . $e->getMessage() );
250 }
251 }
252
253 public function throwException( $message ) {
254 $message = apply_filters( 'mwai_ai_exception', $message );
255 throw new Exception( $message );
256 }
257
258 public function run( $query ) {
259 // Check if the query is allowed
260 $limits = $this->core->get_option( 'limits' );
261 $ok = apply_filters( 'mwai_ai_allowed', true, $query, $limits );
262 if ( $ok !== true ) {
263 $message = is_string( $ok ) ? $ok : 'Unauthorized query.';
264 $this->throwException( $message );
265 }
266
267 // Allow to modify the query
268 $query = apply_filters( 'mwai_ai_query', $query );
269 $query->finalChecks();
270
271 // Run the query
272 $answer = null;
273 try {
274 if ( $query instanceof Meow_MWAI_QueryText ) {
275 $answer = $this->runCompletion( $query );
276 }
277 else if ( $query instanceof Meow_MWAI_QueryEmbed ) {
278 $answer = $this->runEmbedding( $query );
279 }
280 else if ( $query instanceof Meow_MWAI_QueryImage ) {
281 $answer = $this->runCreateImages( $query );
282 }
283 else if ( $query instanceof Meow_MWAI_QueryTranscribe ) {
284 $answer = $this->runTranscribe( $query );
285 }
286 else {
287 $this->throwException( 'Invalid query.' );
288 }
289 }
290 catch ( Exception $e ) {
291 $this->throwException( $e->getMessage() );
292 }
293
294 // Let's allow some modififications of the answer
295 $answer = apply_filters( 'mwai_ai_reply', $answer, $query );
296 return $answer;
297 }
298 }
299