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