PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.2.3
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.2.3
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 / api.php
ai-engine / classes Last commit date
engines 2 years ago modules 2 years ago queries 2 years ago admin.php 2 years ago api.php 2 years ago core.php 2 years ago init.php 3 years ago reply.php 2 years ago rest.php 2 years ago
api.php
399 lines
1 <?php
2
3 class Meow_MWAI_API {
4 public $core;
5 private $chatbot_module;
6 private $discussions_module;
7 private $bearer_token;
8
9 public function __construct( $chatbot_module, $discussions_module ) {
10 global $mwai_core;
11 $this->core = $mwai_core;
12 $this->chatbot_module = $chatbot_module;
13 $this->discussions_module = $discussions_module;
14 add_action( 'rest_api_init', [ $this, 'rest_api_init' ] );
15 }
16
17 #region REST API
18 function rest_api_init() {
19 $public_api = $this->core->get_option( 'public_api' );
20 if ( !$public_api ) { return; }
21 $this->bearer_token = $this->core->get_option( 'public_api_bearer_token' );
22 if ( !empty( $this->bearer_token ) ) {
23 add_filter( 'mwai_allow_public_api', [ $this, 'auth_via_bearer_token' ], 10, 3 );
24 }
25
26 register_rest_route( 'mwai/v1', '/simpleAuthCheck', array(
27 'methods' => 'GET',
28 'callback' => array( $this, 'rest_simpleAuthCheck' ),
29 'permission_callback' => function( $request ) {
30 return $this->core->can_access_public_api( 'simpleAuthCheck', $request );
31 },
32 ) );
33 register_rest_route( 'mwai/v1', '/simpleTextQuery', array(
34 'methods' => 'POST',
35 'callback' => array( $this, 'rest_simpleTextQuery' ),
36 'permission_callback' => function( $request ) {
37 return $this->core->can_access_public_api( 'simpleTextQuery', $request );
38 },
39 ) );
40 register_rest_route( 'mwai/v1', '/simpleImageQuery', array(
41 'methods' => 'POST',
42 'callback' => array( $this, 'rest_simpleImageQuery' ),
43 'permission_callback' => function( $request ) {
44 return $this->core->can_access_public_api( 'simpleImageQuery', $request );
45 },
46 ) );
47 register_rest_route( 'mwai/v1', '/simpleVisionQuery', array(
48 'methods' => 'POST',
49 'callback' => array( $this, 'rest_simpleVisionQuery' ),
50 'permission_callback' => function( $request ) {
51 return $this->core->can_access_public_api( 'simpleVisionQuery', $request );
52 },
53 ) );
54 register_rest_route( 'mwai/v1', '/simpleJsonQuery', array(
55 'methods' => 'POST',
56 'callback' => array( $this, 'rest_simpleJsonQuery' ),
57 'permission_callback' => function( $request ) {
58 return $this->core->can_access_public_api( 'simpleJsonQuery', $request );
59 },
60 ) );
61 register_rest_route( 'mwai/v1', '/moderationCheck', array(
62 'methods' => 'POST',
63 'callback' => array( $this, 'rest_moderationCheck' ),
64 'permission_callback' => function( $request ) {
65 return $this->core->can_access_public_api( 'moderationCheck', $request );
66 },
67 ) );
68
69 if ( $this->chatbot_module ) {
70 register_rest_route( 'mwai/v1', '/simpleChatbotQuery', array(
71 'methods' => 'POST',
72 'callback' => array( $this, 'rest_simpleChatbotQuery' ),
73 'permission_callback' => function( $request ) {
74 return $this->core->can_access_public_api( 'simpleChatbotQuery', $request );
75 },
76 ) );
77 }
78 }
79
80 public function rest_simpleAuthCheck( $request ) {
81 try {
82 $params = $request->get_params();
83 $current_user = wp_get_current_user();
84 $current_email = $current_user->user_email;
85 return new WP_REST_Response([ 'success' => true, 'data' => [
86 'type' => 'email',
87 'value' => $current_email
88 ] ], 200 );
89 }
90 catch (Exception $e) {
91 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
92 }
93 }
94
95 public function auth_via_bearer_token( $allow, $feature, $extra ) {
96 if ( !empty( $extra ) && !empty( $extra->get_header( 'Authorization' ) ) ) {
97 $token = $extra->get_header( 'Authorization' );
98 $token = str_replace( 'Bearer ', '', $token );
99 if ( $token === $this->bearer_token ) {
100 // We set the current user to the first admin.
101 $admin = $this->core->get_admin_user();
102 wp_set_current_user( $admin->ID, $admin->user_login );
103 return true;
104 }
105 }
106 return $allow;
107 }
108
109 public function rest_simpleChatbotQuery( $request ) {
110 try {
111 $params = $request->get_params();
112 $botId = isset( $params['botId'] ) ? $params['botId'] : '';
113 $message = isset( $params['message'] ) ? $params['message'] : '';
114 if ( empty( $message ) ) {
115 $message = isset( $params['prompt'] ) ? $params['prompt'] : '';
116 }
117 $chatId = isset( $params['chatId'] ) ? $params['chatId'] : null;
118 $params = null;
119 if ( !empty( $chatId ) ) {
120 $params = array( 'chatId' => $chatId );
121 }
122 if ( empty( $botId ) || empty( $message ) ) {
123 throw new Exception( 'The botId and message are required.' );
124 }
125 $reply = $this->simpleChatbotQuery( $botId, $message, $params );
126 return new WP_REST_Response([ 'success' => true, 'data' => $reply ], 200 );
127 }
128 catch (Exception $e) {
129 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
130 }
131 }
132
133
134 public function rest_simpleTextQuery( $request ) {
135 try {
136 $params = $request->get_params();
137 $message = isset( $params['message'] ) ? $params['message'] : '';
138 if ( empty( $message ) ) {
139 $message = isset( $params['prompt'] ) ? $params['prompt'] : '';
140 }
141 $options = isset( $params['options'] ) ? $params['options'] : [];
142 $scope = isset( $params['scope'] ) ? $params['scope'] : 'public-api';
143 if ( !empty( $scope ) ) {
144 $options['scope'] = $scope;
145 }
146 if ( empty( $message ) ) {
147 throw new Exception( 'The message is required.' );
148 }
149 $reply = $this->simpleTextQuery( $message, $options );
150 return new WP_REST_Response([ 'success' => true, 'data' => $reply ], 200 );
151 }
152 catch (Exception $e) {
153 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
154 }
155 }
156
157 public function rest_simpleImageQuery( $request ) {
158 try {
159 $params = $request->get_params();
160 $message = isset( $params['message'] ) ? $params['message'] : '';
161 if ( empty( $message ) ) {
162 $message = isset( $params['prompt'] ) ? $params['prompt'] : '';
163 }
164 $options = isset( $params['options'] ) ? $params['options'] : [];
165 $resolution = isset( $params['resolution'] ) ? $params['resolution'] : '';
166 $scope = isset( $params['scope'] ) ? $params['scope'] : 'public-api';
167 if ( !empty( $scope ) ) {
168 $options['scope'] = $scope;
169 }
170 if ( empty( $message ) ) {
171 throw new Exception( 'The message is required.' );
172 }
173 if ( !empty( $resolution ) ) {
174 $options['resolution'] = $resolution;
175 }
176 $reply = $this->simpleImageQuery( $message, $options );
177 return new WP_REST_Response([ 'success' => true, 'data' => $reply ], 200 );
178 }
179 catch (Exception $e) {
180 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
181 }
182 }
183
184 public function rest_simpleVisionQuery( $request ) {
185 try {
186 $params = $request->get_params();
187 $message = isset( $params['message'] ) ? $params['message'] : '';
188 if ( empty( $message ) ) {
189 $message = isset( $params['prompt'] ) ? $params['prompt'] : '';
190 }
191 $url = isset( $params['url'] ) ? $params['url'] : '';
192 $path = isset( $params['path'] ) ? $params['path'] : '';
193 $options = isset( $params['options'] ) ? $params['options'] : [];
194 $scope = isset( $params['scope'] ) ? $params['scope'] : 'public-api';
195 if ( !empty( $scope ) ) {
196 $options['scope'] = $scope;
197 }
198 if ( empty( $message ) ) {
199 throw new Exception( 'The message is required.' );
200 }
201 if ( empty( $url ) && empty( $path ) ) {
202 throw new Exception( 'The url or path is required.' );
203 }
204 $reply = $this->simpleVisionQuery( $message, $url, $path, $options );
205 return new WP_REST_Response([ 'success' => true, 'data' => $reply ], 200 );
206 }
207 catch (Exception $e) {
208 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
209 }
210 }
211
212 public function rest_simpleJsonQuery( $request ) {
213 try {
214 $params = $request->get_params();
215 $message = isset( $params['message'] ) ? $params['message'] : '';
216 if ( empty( $message ) ) {
217 $message = isset( $params['prompt'] ) ? $params['prompt'] : '';
218 }
219 $options = isset( $params['options'] ) ? $params['options'] : [];
220 $scope = isset( $params['scope'] ) ? $params['scope'] : 'public-api';
221 if ( !empty( $scope ) ) {
222 $options['scope'] = $scope;
223 }
224 if ( empty( $message ) ) {
225 throw new Exception( 'The message is required.' );
226 }
227 $reply = $this->simpleJsonQuery( $message, $options );
228 return new WP_REST_Response([ 'success' => true, 'data' => $reply ], 200 );
229 }
230 catch (Exception $e) {
231 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
232 }
233 }
234
235 public function rest_moderationCheck( $request ) {
236 try {
237 $params = $request->get_params();
238 $text = $params['text'];
239 $reply = $this->moderationCheck( $text );
240 return new WP_REST_Response([ 'success' => true, 'data' => $reply ], 200 );
241 }
242 catch (Exception $e) {
243 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
244 }
245 }
246 #endregion
247
248 #region Simple API
249 /**
250 * Executes a vision query.`
251 *
252 * @param string $message The prompt for the AI.
253 * @param string $url The URL of the image to analyze.
254 * @param string|null $path The path to the image file. If provided, the image data will be read from this file.
255 * @param array $params Additional parameters for the AI query.
256 *
257 * @return string The result of the AI query.
258 */
259 public function simpleVisionQuery( $message, $url, $path = null, $params = [] ) {
260 global $mwai_core;
261 $ai_vision_default_env = $this->core->get_option( 'ai_vision_default_env' );
262 $ai_vision_default_model = $this->core->get_option( 'ai_vision_default_model' );
263 if ( empty( $ai_vision_default_model ) ) {
264 $ai_vision_default_model = MWAI_FALLBACK_MODEL_VISION;
265 }
266 $query = new Meow_MWAI_Query_Text( $message );
267 if ( !empty( $ai_vision_default_env ) ) {
268 $query->set_env_id( $ai_vision_default_env );
269 }
270 if ( !empty( $ai_vision_default_model ) ) {
271 $query->set_model( $ai_vision_default_model );
272 }
273 $query->inject_params( $params );
274 $remote_upload = $this->core->get_option( 'image_remote_upload' );
275 $preferURL = $remote_upload === 'url';
276
277 if ( $preferURL && $url ) {
278 $query->set_file( $url, 'url', 'vision' );
279 }
280 else if ( !$preferURL && !empty( $path ) ) {
281 $binary = file_get_contents( $path );
282 // Check if there is an error and what
283 if ( $binary === false ) {
284 throw new Exception( 'The file could not be read.' );
285 }
286 $data = base64_encode( $binary );
287 $query->set_file( $data, 'data', 'vision' );
288 }
289 else if ( $url ) {
290 $query->set_file( $url, 'url', 'vision' );
291 }
292 else if ( !empty($path ) ) {
293 $data = base64_encode( file_get_contents( $path ) );
294 $query->set_file( $data, 'data', 'vision' );
295 }
296
297 $reply = $mwai_core->run_query( $query );
298 return $reply->result;
299 }
300
301 /**
302 * Executes a chatbot query.
303 * It will use the discussion if chatId is provided in the parameters.
304 *
305 * @param string $botId The ID of the chatbot.
306 * @param string $message The prompt for the AI.
307 * @param array $params Additional parameters for the AI query.
308 *
309 * @return string The result of the AI query.
310 */
311 public function simpleChatbotQuery( $botId, $message, $params = [] ) {
312 if ( !isset( $params['messages'] ) && isset( $params['chatId'] ) ) {
313 $discussion = $this->discussions_module->get_discussion( $botId, $params['chatId'] );
314 if ( !empty( $discussion ) ) {
315 $params['messages'] = $discussion->messages;
316 }
317 }
318 $data = $this->chatbot_module->chat_submit( $botId, $message, $params );
319 return $data['reply'];
320 }
321
322 /**
323 * Executes a text query.
324 *
325 * @param string $message The prompt for the AI.
326 * @param array $params Additional parameters for the AI query.
327 *
328 * @return string The result of the AI query.
329 */
330 public function simpleTextQuery( $message, $params = [] ) {
331 global $mwai_core;
332 $query = new Meow_MWAI_Query_Text( $message );
333 $query->inject_params( $params );
334 $reply = $mwai_core->run_query( $query );
335 return $reply->result;
336 }
337
338 public function simpleImageQuery( $message, $params = [] ) {
339 global $mwai_core;
340 $query = new Meow_MWAI_Query_Image( $message );
341 $query->inject_params( $params );
342 $reply = $mwai_core->run_query( $query );
343 return $reply->result;
344 }
345
346 /**
347 * Executes a query that will have to return a JSON result.
348 *
349 * @param string $message The prompt for the AI.
350 * @param array $params Additional parameters for the AI query.
351 *
352 * @return array The result of the AI query.
353 */
354 public function simpleJsonQuery( $message, $url = null, $path = null, $params = [] ) {
355 if ( !empty( $url ) || !empty( $path ) ) {
356 throw new Exception( 'The url and path are not supported yet by the simpleJsonQuery.' );
357 }
358 global $mwai_core;
359 $query = new Meow_MWAI_Query_Text( $message . "\nYour reply must be a formatted JSON." );
360 $query->inject_params( $params );
361 $query->set_response_format( 'json' );
362 $ai_json_default_env = $mwai_core->get_option( 'ai_json_default_env' );
363 $ai_json_default_model = $mwai_core->get_option( 'ai_json_default_model' );
364 if ( !empty( $ai_json_default_env ) ) {
365 $query->set_env_id( $ai_json_default_env );
366 }
367 if ( !empty( $ai_json_default_model ) ) {
368 $query->set_model( $ai_json_default_model );
369 }
370 else {
371 $query->set_model( MWAI_FALLBACK_MODEL_JSON );
372 }
373 $reply = $mwai_core->run_query( $query );
374 try {
375 $json = json_decode( $reply->result, true );
376 return $json;
377 }
378 catch ( Exception $e ) {
379 throw new Exception( 'The result is not a valid JSON.' );
380 }
381 }
382
383 /**
384 * Checks if a text is safe or not.
385 *
386 * @param string $text The text to check.
387 *
388 * @return bool True if the text is safe, false otherwise.
389 */
390 public function moderationCheck( $text ) {
391 global $mwai_core;
392 $openai = Meow_MWAI_Engines_Factory::get_openai( $mwai_core );
393 $res = $openai->moderate( $text );
394 if ( !empty( $res ) && !empty( $res['results'] ) ) {
395 return (bool)$res['results'][0]['flagged'];
396 }
397 }
398 #endregion
399 }