PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.8.4
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.8.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 / rest.php
ai-engine / classes Last commit date
engines 1 year ago modules 1 year ago queries 1 year ago admin.php 1 year ago api.php 1 year ago core.php 1 year ago discussion.php 1 year ago event.php 1 year ago init.php 1 year ago logging.php 1 year ago reply.php 1 year ago rest.php 1 year ago
rest.php
1155 lines
1 <?php
2
3 class Meow_MWAI_Rest
4 {
5 private $core = null;
6 private $namespace = 'mwai/v1';
7
8 public function __construct( $core ) {
9 $this->core = $core;
10 add_action( 'rest_api_init', array( $this, 'rest_init' ) );
11 }
12
13 /**
14 * Retrieve the message from the parameters and optionally sanitize it.
15 *
16 * @param array &$params The parameters array, passed by reference.
17 * @param bool $sanitize Whether to sanitize the message using sanitize_text_field.
18 * @return string The retrieved (and optionally sanitized) message.
19 */
20 function retrieve_message( &$params, $sanitize = false ) : string {
21 if ( isset( $params['message'] ) ) {
22 $message = $params['message'];
23 }
24 elseif ( isset( $params['prompt'] ) ) {
25 $message = $params['prompt'];
26 unset( $params['prompt'] );
27 $params['message'] = $message;
28 Meow_MWAI_Logging::deprecated( '"prompt" is deprecated, please use "message" instead.' );
29 }
30 else {
31 $message = "";
32 }
33
34 if ( $sanitize ) {
35 $message = sanitize_text_field( $message );
36 }
37
38 return $message;
39 }
40
41 function rest_init() {
42 try {
43 // Session Endpoint
44 register_rest_route( $this->namespace, '/start_session', array(
45 'methods' => 'POST',
46 'permission_callback' => [ $this->core, 'can_start_session' ],
47 'callback' => [ $this, 'rest_start_session' ],
48 ) );
49
50 // Settings Endpoints
51 register_rest_route( $this->namespace, '/settings/update', array(
52 'methods' => 'POST',
53 'permission_callback' => [ $this->core, 'can_access_settings' ],
54 'callback' => [ $this, 'rest_settings_update' ],
55 ) );
56 register_rest_route( $this->namespace, '/settings/options', array(
57 'methods' => 'GET',
58 'permission_callback' => [ $this->core, 'can_access_settings' ],
59 'callback' => [ $this, 'rest_settings_list' ],
60 ) );
61 register_rest_route( $this->namespace, '/settings/reset', array(
62 'methods' => 'POST',
63 'permission_callback' => [ $this->core, 'can_access_settings' ],
64 'callback' => [ $this, 'rest_settings_reset' ],
65 ) );
66 register_rest_route( $this->namespace, '/settings/chatbots', array(
67 'methods' => ['GET', 'POST'],
68 'permission_callback' => [ $this->core, 'can_access_settings' ],
69 'callback' => [ $this, 'rest_settings_chatbots' ],
70 ) );
71 register_rest_route( $this->namespace, '/settings/themes', array(
72 'methods' => ['GET', 'POST'],
73 'permission_callback' => [ $this->core, 'can_access_settings' ],
74 'callback' => [ $this, 'rest_settings_themes' ],
75 ) );
76
77 // System Endpoints
78 register_rest_route( $this->namespace, '/system/logs/list', array(
79 'methods' => 'POST',
80 'permission_callback' => [ $this->core, 'can_access_settings' ],
81 'callback' => [ $this, 'rest_system_logs_list' ],
82 ) );
83 register_rest_route( $this->namespace, '/system/logs/delete', array(
84 'methods' => 'POST',
85 'permission_callback' => [ $this->core, 'can_access_settings' ],
86 'callback' => [ $this, 'rest_system_logs_delete' ],
87 ) );
88 register_rest_route( $this->namespace, '/system/logs/meta', array(
89 'methods' => 'POST',
90 'permission_callback' => [ $this->core, 'can_access_settings' ],
91 'callback' => [ $this, 'rest_system_logs_meta_get' ],
92 ) );
93 register_rest_route( $this->namespace, '/system/logs/activity', array(
94 'methods' => 'POST',
95 'permission_callback' => [ $this->core, 'can_access_settings' ],
96 'callback' => [ $this, 'rest_system_logs_activity' ],
97 ) );
98 register_rest_route( $this->namespace, '/system/logs/activity_daily', array(
99 'methods' => 'POST',
100 'permission_callback' => [ $this->core, 'can_access_settings' ],
101 'callback' => [ $this, 'rest_system_logs_activity_daily' ],
102 ) );
103 register_rest_route( $this->namespace, '/system/templates', array(
104 'methods' => 'POST',
105 'permission_callback' => [ $this->core, 'can_access_features' ],
106 'callback' => [ $this, 'rest_system_templates_save' ],
107 ) );
108 register_rest_route( $this->namespace, '/system/templates', array(
109 'methods' => 'GET',
110 'permission_callback' => [ $this->core, 'can_access_features' ],
111 'callback' => [ $this, 'rest_system_templates_get' ],
112 ) );
113
114 // AI Endpoints
115 register_rest_route( $this->namespace, '/ai/models', array(
116 'methods' => 'POST',
117 'permission_callback' => [ $this->core, 'can_access_features' ],
118 'callback' => [ $this, 'rest_ai_models' ],
119 ) );
120 register_rest_route( $this->namespace, '/ai/completions', array(
121 'methods' => 'POST',
122 'permission_callback' => [ $this->core, 'can_access_features' ],
123 'callback' => [ $this, 'rest_ai_completions' ],
124 ) );
125 register_rest_route( $this->namespace, '/ai/images', array(
126 'methods' => 'POST',
127 'permission_callback' => [ $this->core, 'can_access_features' ],
128 'callback' => [ $this, 'rest_ai_images' ],
129 ) );
130 register_rest_route( $this->namespace, '/ai/image_edit', array(
131 'methods' => 'POST',
132 'permission_callback' => [ $this->core, 'can_access_features' ],
133 'callback' => [ $this, 'rest_ai_image_edit' ],
134 ) );
135 register_rest_route( $this->namespace, '/ai/copilot', array(
136 'methods' => 'POST',
137 'permission_callback' => [ $this->core, 'can_access_features' ],
138 'callback' => [ $this, 'rest_ai_copilot' ],
139 ) );
140
141 register_rest_route( $this->namespace, '/ai/magic_wand', array(
142 'methods' => 'POST',
143 'callback' => [ $this, 'rest_ai_magic_wand' ],
144 'permission_callback' => [ $this->core, 'can_access_features' ],
145 ) );
146 register_rest_route( $this->namespace, '/ai/moderate', array(
147 'methods' => 'POST',
148 'permission_callback' => [ $this->core, 'can_access_settings' ],
149 'callback' => [ $this, 'rest_ai_moderate' ],
150 ) );
151 register_rest_route( $this->namespace, '/ai/transcribe_audio', array(
152 'methods' => 'POST',
153 'permission_callback' => [ $this->core, 'can_access_settings' ],
154 'callback' => [ $this, 'rest_ai_transcribe_audio' ],
155 ) );
156 register_rest_route( $this->namespace, '/ai/transcribe_image', array(
157 'methods' => 'POST',
158 'permission_callback' => [ $this->core, 'can_access_settings' ],
159 'callback' => [ $this, 'rest_ai_transcribe_image' ],
160 ) );
161 register_rest_route( $this->namespace, '/ai/json', array(
162 'methods' => 'POST',
163 'permission_callback' => [ $this->core, 'can_access_settings' ],
164 'callback' => [ $this, 'rest_ai_json' ],
165 ) );
166
167 // MCP Endpoints
168 register_rest_route( $this->namespace, '/mcp/functions', array(
169 'methods' => 'GET',
170 'permission_callback' => [ $this->core, 'can_access_settings' ],
171 'callback' => [ $this, 'rest_mcp_functions' ],
172 ) );
173
174 // Helpers Endpoints
175 register_rest_route( $this->namespace, '/helpers/update_post_title', array(
176 'methods' => 'POST',
177 'permission_callback' => [ $this->core, 'can_access_features' ],
178 'callback' => [ $this, 'rest_helpers_update_title' ],
179 ) );
180 register_rest_route( $this->namespace, '/helpers/update_post_excerpt', array(
181 'methods' => 'POST',
182 'permission_callback' => [ $this->core, 'can_access_features' ],
183 'callback' => [ $this, 'rest_helpers_update_excerpt' ],
184 ) );
185 register_rest_route( $this->namespace, '/helpers/create_post', array(
186 'methods' => 'POST',
187 'permission_callback' => [ $this->core, 'can_access_features' ],
188 'callback' => [ $this, 'rest_helpers_create_post' ],
189 ) );
190 register_rest_route( $this->namespace, '/helpers/create_image', array(
191 'methods' => 'POST',
192 'permission_callback' => [ $this->core, 'can_access_features' ],
193 'callback' => [ $this, 'rest_helpers_create_images' ],
194 ) );
195 register_rest_route( $this->namespace, '/helpers/generate_image_meta', array(
196 'methods' => 'POST',
197 'permission_callback' => [ $this->core, 'can_access_features' ],
198 'callback' => [ $this, 'rest_helpers_generate_image_meta' ],
199 ) );
200 register_rest_route( $this->namespace, '/helpers/count_posts', array(
201 'methods' => 'GET',
202 'permission_callback' => [ $this->core, 'can_access_features' ],
203 'callback' => [ $this, 'rest_helpers_count_posts' ],
204 ) );
205 register_rest_route( $this->namespace, '/helpers/posts_ids', array(
206 'methods' => 'GET',
207 'permission_callback' => [ $this->core, 'can_access_features' ],
208 'callback' => [ $this, 'rest_helpers_posts_ids' ],
209 ) );
210 register_rest_route( $this->namespace, '/helpers/post_types', array(
211 'methods' => 'GET',
212 'permission_callback' => [ $this->core, 'can_access_features' ],
213 'callback' => [ $this, 'rest_helpers_post_types' ],
214 ) );
215 register_rest_route( $this->namespace, '/helpers/post_content', array(
216 'methods' => 'GET',
217 'permission_callback' => [ $this->core, 'can_access_features' ],
218 'callback' => [ $this, 'rest_helpers_post_content' ],
219 ) );
220 register_rest_route( $this->namespace, '/helpers/run_tasks', array(
221 'methods' => 'POST',
222 'permission_callback' => [ $this->core, 'can_access_features' ],
223 'callback' => [ $this, 'rest_helpers_run_tasks' ],
224 ) );
225
226 // OpenAI Endpoints
227 register_rest_route( $this->namespace, '/openai/files/list', array(
228 'methods' => 'GET',
229 'permission_callback' => [ $this->core, 'can_access_settings' ],
230 'callback' => [ $this, 'rest_openai_files_get' ],
231 ) );
232 register_rest_route( $this->namespace, '/openai/files/upload', array(
233 'methods' => 'POST',
234 'permission_callback' => [ $this->core, 'can_access_settings' ],
235 'callback' => [ $this, 'rest_openai_files_upload' ],
236 ) );
237 register_rest_route( $this->namespace, '/openai/files/delete', array(
238 'methods' => 'POST',
239 'permission_callback' => [ $this->core, 'can_access_settings' ],
240 'callback' => [ $this, 'rest_openai_files_delete' ],
241 ) );
242 register_rest_route( $this->namespace, '/openai/files/download', array(
243 'methods' => 'POST',
244 'permission_callback' => [ $this->core, 'can_access_settings' ],
245 'callback' => [ $this, 'rest_openai_files_download' ],
246 ) );
247 register_rest_route( $this->namespace, '/openai/files/finetune', array(
248 'methods' => 'POST',
249 'permission_callback' => [ $this->core, 'can_access_settings' ],
250 'callback' => [ $this, 'rest_openai_files_finetune' ],
251 ) );
252 register_rest_route( $this->namespace, '/openai/finetunes/list_deleted', array(
253 'methods' => 'GET',
254 'permission_callback' => [ $this->core, 'can_access_settings' ],
255 'callback' => [ $this, 'rest_openai_deleted_finetunes_get' ],
256 ) );
257
258 // register_rest_route( $this->namespace, '/openai/models', array(
259 // 'methods' => 'GET',
260 // 'permission_callback' => [ $this->core, 'can_access_settings' ],
261 // 'callback' => [ $this, 'rest_openai_models_get' ],
262 // ) );
263
264 register_rest_route( $this->namespace, '/openai/finetunes/list', array(
265 'methods' => 'GET',
266 'permission_callback' => [ $this->core, 'can_access_settings' ],
267 'callback' => [ $this, 'rest_openai_finetunes_get' ],
268 ) );
269 register_rest_route( $this->namespace, '/openai/finetunes/delete', array(
270 'methods' => 'POST',
271 'permission_callback' => [ $this->core, 'can_access_settings' ],
272 'callback' => [ $this, 'rest_openai_finetunes_delete' ],
273 ) );
274 register_rest_route( $this->namespace, '/openai/finetunes/cancel', array(
275 'methods' => 'POST',
276 'permission_callback' => [ $this->core, 'can_access_settings' ],
277 'callback' => [ $this, 'rest_openai_finetunes_cancel' ],
278 ) );
279
280 // Logging Endpoints
281 register_rest_route( $this->namespace, '/get_logs', array(
282 'methods' => 'GET',
283 'permission_callback' => array( $this->core, 'can_access_features' ),
284 'callback' => array( $this, 'rest_get_logs' )
285 ) );
286 register_rest_route( $this->namespace, '/clear_logs', array(
287 'methods' => 'GET',
288 'permission_callback' => array( $this->core, 'can_access_features' ),
289 'callback' => array( $this, 'rest_clear_logs' )
290 ) );
291 }
292 catch ( Exception $e ) {
293 var_dump( $e );
294 }
295 }
296
297 function rest_start_session() {
298 try {
299 $sessionId = $this->core->get_session_id();
300 $restNonce = $this->core->get_nonce( true );
301 return new WP_REST_Response( [
302 'success' => true,
303 'sessionId' => $sessionId,
304 'restNonce' => $restNonce
305 ], 200 );
306 }
307 catch ( Exception $e ) {
308 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
309 return new WP_REST_Response( [ 'success' => false, 'message' => $message ], 500 );
310 }
311 }
312
313 function rest_settings_list() {
314 return new WP_REST_Response( [
315 'success' => true,
316 'options' => $this->core->get_all_options()
317 ], 200 );
318 }
319
320 function rest_settings_update( $request ) {
321 try {
322 $params = $request->get_json_params();
323 $value = $params['options'];
324 $options = $this->core->update_options( $value );
325 $success = !!$options;
326 $message = __( $success ? 'OK' : "Could not update options.", 'ai-engine' );
327 return new WP_REST_Response([ 'success' => $success, 'message' => $message, 'options' => $options ], 200 );
328 }
329 catch ( Exception $e ) {
330 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
331 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
332 }
333 }
334
335 function rest_settings_reset() {
336 try {
337 $options = $this->core->reset_options();
338 $success = !!$options;
339 $message = __( $success ? 'OK' : "Could not reset options.", 'ai-engine' );
340 return new WP_REST_Response([ 'success' => $success, 'message' => $message, 'options' => $options ], 200 );
341 }
342 catch ( Exception $e ) {
343 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
344 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
345 }
346 }
347
348 function rest_ai_models( $request ) {
349 try {
350 $params = $request->get_json_params();
351 $envId = $params['envId'];
352 $engine = Meow_MWAI_Engines_Factory::get( $this->core, $envId );
353 $models = $engine->retrieve_models();
354 return new WP_REST_Response([ 'success' => true, 'models' => $models ], 200 );
355 }
356 catch ( Exception $e ) {
357 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
358 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
359 }
360 }
361
362 function rest_ai_completions( $request ) {
363 try {
364 $params = $request->get_json_params();
365 $message = $this->retrieve_message( $params );
366 $query = new Meow_MWAI_Query_Text( $message );
367 $query->inject_params( $params );
368
369 // Handle streaming
370 $stream = $params['stream'] ?? false;
371 $streamCallback = null;
372 if ( $stream ) {
373 $streamCallback = function( $reply ) use ( $query ) {
374 //$raw = _wp_specialchars( $reply, ENT_NOQUOTES, 'UTF-8', true );
375 $raw = $reply;
376 $this->core->stream_push( [ 'type' => 'live', 'data' => $raw ], $query );
377 if ( ob_get_level() > 0 ) {
378 ob_flush();
379 }
380 flush();
381 };
382 header( 'Cache-Control: no-cache' );
383 header( 'Content-Type: text/event-stream' );
384 header( 'X-Accel-Buffering: no' ); // This is useful to disable buffering in nginx through headers.
385 ob_implicit_flush( true );
386 ob_end_flush();
387 }
388
389 // Process Reply
390 $reply = $this->core->run_query( $query, $streamCallback );
391 $restRes = [
392 'success' => true,
393 'data' => $reply->result,
394 'usage' => $reply->usage
395 ];
396 if ( $stream ) {
397 $this->core->stream_push( [ 'type' => 'end', 'data' => json_encode( $restRes ) ], $query );
398 die();
399 }
400 return new WP_REST_Response( $restRes, 200 );
401 }
402 catch ( Exception $e ) {
403 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
404 if ( $stream ) {
405 $this->core->stream_push( [ 'type' => 'error', 'data' => $message ], $query );
406 }
407 else {
408 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
409 }
410 }
411 }
412
413 function rest_ai_images( $request ) {
414 try {
415 $params = $request->get_json_params();
416 $message = $this->retrieve_message( $params );
417 $query = new Meow_MWAI_Query_Image( $message );
418 $query->inject_params( $params );
419 $reply = $this->core->run_query( $query );
420 return new WP_REST_Response([ 'success' => true, 'data' => $reply->results, 'usage' => $reply->usage ], 200 );
421 }
422 catch ( Exception $e ) {
423 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
424 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
425 }
426 }
427
428 function rest_ai_image_edit( $request ) {
429 try {
430 // Check if this is a multipart request with files
431 $files = $request->get_file_params();
432 $params = null;
433
434 // Log all request data
435 error_log( "Image Edit Request - Method: " . $request->get_method() );
436 $content_type = $request->get_content_type();
437 if ( is_array( $content_type ) ) {
438 error_log( "Image Edit Request - Content-Type: " . $content_type['value'] );
439 } else {
440 error_log( "Image Edit Request - Content-Type: " . $content_type );
441 }
442 error_log( "Image Edit Request - Has files: " . ( !empty( $files ) ? 'yes (' . count($files) . ')' : 'no' ) );
443
444 if ( !empty( $files ) ) {
445 // Handle multipart form data - get all params including POST data
446 $params = $request->get_params();
447 error_log( "Image Edit Request - Using form data params" );
448 } else {
449 // Try to get body params first (for form data without files)
450 $body_params = $request->get_body_params();
451 if ( !empty( $body_params ) ) {
452 $params = $body_params;
453 error_log( "Image Edit Request - Using body params" );
454 } else {
455 // Handle JSON request
456 $params = $request->get_json_params();
457 error_log( "Image Edit Request - Using JSON params" );
458 }
459 }
460
461 // Ensure params is always an array
462 if ( empty( $params ) ) {
463 $params = [];
464 }
465
466 // Debug logging
467 error_log( "Image Edit Request - Has files: " . ( !empty( $files ) ? 'yes' : 'no' ) );
468 error_log( "Image Edit Request - Params: " . json_encode( $params ) );
469
470 $message = $this->retrieve_message( $params );
471 $mediaId = isset( $params['mediaId'] ) ? intval( $params['mediaId'] ) : 0;
472 $query = new Meow_MWAI_Query_EditImage( $message );
473
474 // The inject_params method will handle setting the file from mediaId
475 $query->inject_params( $params );
476
477 // Handle mask file if provided
478 if ( !empty( $files['mask'] ) ) {
479 $mask_file = $files['mask'];
480 if ( $mask_file['error'] === UPLOAD_ERR_OK ) {
481 $mask_data = file_get_contents( $mask_file['tmp_name'] );
482 $query->set_mask( Meow_MWAI_Query_DroppedFile::from_data( $mask_data, 'vision', $mask_file['type'] ) );
483 }
484 }
485
486 $reply = $this->core->run_query( $query );
487 return new WP_REST_Response([ 'success' => true, 'data' => $reply->results, 'usage' => $reply->usage ], 200 );
488 }
489 catch ( Exception $e ) {
490 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
491 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
492 }
493 }
494
495 function rest_ai_magic_wand( $request ) {
496 try {
497 $params = $request->get_json_params();
498 $action = isset( $params['action'] ) ? $params['action'] : null;
499 $data = isset( $params['data'] ) ? $params['data'] : null;
500 if ( empty( $data ) || empty( $action ) ) {
501 return new WP_REST_Response([ 'success' => false, 'message' => "An action and some data are required." ], 500 );
502 }
503 $data = apply_filters( 'mwai_magic_wand_' . $action, "", $data );
504 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
505 }
506 catch ( Exception $e ) {
507 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
508 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
509 }
510 }
511
512 function rest_ai_copilot( $request ) {
513 try {
514 $params = $request->get_json_params();
515 $action = sanitize_text_field( $params['action'] );
516 $message = $this->retrieve_message( $params, true );
517 $context = sanitize_text_field( $params['context'] );
518 $postId = !empty( $params['postId'] ) ? intval( $params['postId'] ) : null;
519 if ( empty( $action ) || empty( $message ) ) {
520 return new WP_REST_Response([ 'success' => false, 'message' => "Copilot needs an action and a prompt." ], 500 );
521 }
522
523 global $mwai;
524 $result = null;
525 $params = [ 'scope' => 'copilot' ];
526
527 if ( $action === 'text' ) {
528 $prompt = "Here is the current article: \n\n===\n\n" . $context . "\n\n===\n\nIn this article, instead of the [== CURRENT BLOCK ==] placeholder, the author needs additional content. This new content should use the same tone, style, context, it should naturally flow in the article. The author shared additional information for this request:\n\n===\n\n" . $message . "\n\n===\n\nPlease provide the additional content. Only output the additional content, not the entire article, no need for extra information, and no need for the placeholders. Only output the content that should be added.";
529 if ( !empty( $model ) ) {
530 $params['model'] = $model;
531 }
532 $result = $mwai->simpleTextQuery( $prompt, $params );
533 }
534 else if ( $action === 'image' ) {
535 $prompt = "Here is the current article: \n\n===\n\n" . $context . "\n\n===\n\nIn this article, instead of the [== CURRENT BLOCK ==] placeholder, the author needs an image. Please write a detailed description (prompt) for that image that would fit this context. The image should be relevant to the article. The author shared additional information for this request:\n\n===\n\n" . $message . "\n\n===\n\nPlease only output the description for the image, not the entire article, no need for extra information, and no need for the placeholders. Only output the description.";
536
537 // Create the image
538 $simplifiedPrompt = $mwai->simpleTextQuery( $prompt, $params );
539 $media = $mwai->imageQueryForMediaLibrary( $simplifiedPrompt, $params, $postId );
540 $result = [ 'media' => $media ];
541 }
542 return new WP_REST_Response([ 'success' => true, 'data' => $result ], 200 );
543 }
544 catch ( Exception $e ) {
545 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
546 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
547 }
548 }
549
550 function rest_helpers_update_title( $request ) {
551 try {
552 $params = $request->get_json_params();
553 $title = sanitize_text_field( $params['title'] );
554 $postId = intval( $params['postId'] );
555 $post = get_post( $postId );
556 if ( !$post ) {
557 throw new Exception( 'There is no post with this ID.' );
558 }
559 $post->post_title = $title;
560 //$post->post_name = sanitize_title( $title );
561 wp_update_post( $post );
562 return new WP_REST_Response([ 'success' => true, 'message' => "Title updated." ], 200 );
563 }
564 catch ( Exception $e ) {
565 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
566 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
567 }
568 }
569
570 function rest_helpers_update_excerpt( $request ) {
571 try {
572 $params = $request->get_json_params();
573 $excerpt = sanitize_text_field( $params['excerpt'] );
574 $postId = intval( $params['postId'] );
575 $post = get_post( $postId );
576 if ( !$post ) {
577 throw new Exception( 'There is no post with this ID.' );
578 }
579 $post->post_excerpt = $excerpt;
580 wp_update_post( $post );
581 return new WP_REST_Response([ 'success' => true, 'message' => "Excerpt updated." ], 200 );
582 }
583 catch ( Exception $e ) {
584 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
585 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
586 }
587 }
588
589 function rest_helpers_create_post( $request ) {
590 try {
591 $params = $request->get_json_params();
592 $title = sanitize_text_field( $params['title'] );
593 $content = sanitize_textarea_field( $params['content'] );
594 $excerpt = sanitize_text_field( $params['excerpt'] );
595 $postType = sanitize_text_field( $params['postType'] );
596 $post = new stdClass();
597 $post->post_title = $title;
598 $post->post_excerpt = $excerpt;
599 $post->post_content = $content;
600 $post->post_status = 'draft';
601 $post->post_type = isset( $postType ) ? $postType : 'post';
602 // TODO: Let's try to avoid using Markdown to create the Post
603 // Instead, we should create Gutenberg Blocks, or simple HTML.
604 // Then, we can get rid of the library for Markdown.
605 $post->post_content = $this->core->markdown_to_html( $post->post_content );
606 $postId = wp_insert_post( $post );
607 return new WP_REST_Response([ 'success' => true, 'postId' => $postId ], 200 );
608 }
609 catch ( Exception $e ) {
610 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
611 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
612 }
613 }
614
615 function rest_helpers_create_images( $request ) {
616 try {
617 $params = $request->get_json_params();
618 $title = sanitize_text_field( $params['title'] );
619 $caption = sanitize_text_field( $params['caption'] );
620 $alt = sanitize_text_field( $params['alt'] );
621 $description = sanitize_text_field( $params['description'] );
622 $url = $params['url'];
623 $filename = sanitize_text_field( $params['filename'] );
624 $attachmentId = $this->core->add_image_from_url( $url, $filename, $title, $description, $caption, $alt );
625 return new WP_REST_Response([ 'success' => true, 'attachmentId' => $attachmentId ], 200 );
626 }
627 catch ( Exception $e ) {
628 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
629 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
630 }
631 }
632
633 function rest_helpers_generate_image_meta( $request ) {
634 try {
635 global $mwai;
636 $params = $request->get_json_params();
637 $url = isset( $params['url'] ) ? esc_url_raw( $params['url'] ) : null;
638 if ( empty( $url ) ) {
639 throw new Exception( 'The url is required.' );
640 }
641 $prompt = 'Describe this image and suggest a short title, description and SEO-friendly (ASCII and lowercase) filename. '
642 . 'Return a JSON with the keys title, description, alt, caption, filename.';
643 $result = $mwai->simpleVisionQuery( $prompt, $url, null, [ 'image_remote_upload' => 'url', 'scope' => 'admin-tools' ] );
644 $result = preg_replace( '/^```json\s*/', '', $result );
645 $result = preg_replace( '/\s*```$/', '', $result );
646 if ( is_string( $result ) ) {
647 $data = json_decode( $result, true );
648 }
649 else {
650 $data = $result;
651 }
652 if ( !is_array( $data ) ) {
653 $data = [];
654 }
655 $data = array_merge( [ 'title' => '', 'description' => '', 'caption' => '', 'alt' => '', 'filename' => '' ], $data );
656 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
657 }
658 catch ( Exception $e ) {
659 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
660 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
661 }
662 }
663
664 function rest_openai_files_get() {
665 try {
666 $envId = isset( $_GET['envId'] ) ? $_GET['envId'] : null;
667 $purposeFilter = isset( $_GET['purpose'] ) ? $_GET['purpose'] : null;
668 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
669 $files = $openai->list_files( $purposeFilter );
670 return new WP_REST_Response([ 'success' => true, 'files' => $files ], 200 );
671 }
672 catch ( Exception $e ) {
673 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
674 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
675 }
676 }
677
678 function rest_openai_deleted_finetunes_get() {
679 try {
680 $envId = isset( $_GET['envId'] ) ? $_GET['envId'] : null;
681 $legacy = isset( $_GET['legacy'] ) ? $_GET['legacy'] === 'true' : false;
682 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
683 $finetunes = $openai->list_deleted_finetunes( $legacy );
684 return new WP_REST_Response([ 'success' => true, 'finetunes' => $finetunes ], 200 );
685 }
686 catch ( Exception $e ) {
687 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
688 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
689 }
690 }
691
692 function rest_openai_finetunes_get() {
693 try {
694 $envId = isset( $_GET['envId'] ) ? $_GET['envId'] : null;
695 $legacy = isset( $_GET['legacy'] ) ? $_GET['legacy'] === 'true' : false;
696 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
697 $finetunes = $openai->list_finetunes( $legacy );
698 return new WP_REST_Response([ 'success' => true, 'finetunes' => $finetunes ], 200 );
699 }
700 catch ( Exception $e ) {
701 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
702 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
703 }
704 }
705
706 function rest_openai_files_upload( $request ) {
707 try {
708 $params = $request->get_json_params();
709 $envId = $params['envId'];;
710 $filename = sanitize_text_field( $params['filename'] );
711 $data = $params['data'];
712 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
713 $file = $openai->upload_file( $filename, $data );
714 return new WP_REST_Response([ 'success' => true, 'file' => $file ], 200 );
715 }
716 catch ( Exception $e ) {
717 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
718 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
719 }
720 }
721
722 function rest_openai_files_delete( $request ) {
723 try {
724 $params = $request->get_json_params();
725 $envId = $params['envId'];;
726 $fileId = $params['fileId'];
727 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
728 $openai->delete_file( $fileId );
729 return new WP_REST_Response([ 'success' => true ], 200 );
730 }
731 catch ( Exception $e ) {
732 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
733 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
734 }
735 }
736
737 function rest_openai_finetunes_cancel( $request ) {
738 try {
739 $params = $request->get_json_params();
740 $envId = $params['envId'];;
741 $finetuneId = $params['finetuneId'];
742 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
743 $openai->cancel_finetune( $finetuneId );
744 return new WP_REST_Response([ 'success' => true ], 200 );
745 }
746 catch ( Exception $e ) {
747 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
748 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
749 }
750 }
751
752 function rest_openai_finetunes_delete( $request ) {
753 try {
754 $params = $request->get_json_params();
755 $envId = $params['envId'];;
756 $modelId = $params['modelId'];
757 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
758 $openai->delete_finetune( $modelId );
759 return new WP_REST_Response([ 'success' => true ], 200 );
760 }
761 catch ( Exception $e ) {
762 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
763 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
764 }
765 }
766
767 function rest_openai_files_download( $request ) {
768 try {
769 $params = $request->get_json_params();
770 $envId = $params['envId'];;
771 $fileId = $params['fileId'];
772 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
773 $filename = $openai->download_file( $fileId );
774 $data = file_get_contents( $filename );
775 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
776 }
777 catch ( Exception $e ) {
778 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
779 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
780 }
781 }
782
783 function rest_openai_files_finetune( $request ) {
784 try {
785 $params = $request->get_json_params();
786 $envId = $params['envId'];;
787 $fileId = $params['fileId'];
788 $model = $params['model'];
789 $suffix = $params['suffix'];
790 $hyperparams = [
791 "nEpochs" => isset( $params['nEpochs'] ) ? $params['nEpochs'] : null,
792 "batchSize" => isset( $params['batchSize'] ) ? $params['batchSize'] : null,
793 ];
794 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
795 $finetune = $openai->run_finetune( $fileId, $model, $suffix, $hyperparams );
796 return new WP_REST_Response([ 'success' => true, 'finetune' => $finetune ], 200 );
797 }
798 catch ( Exception $e ) {
799 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
800 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
801 }
802 }
803
804 function rest_helpers_count_posts( $request ) {
805 try {
806 $params = $request->get_query_params();
807 $postType = $params['postType'];
808 $postStatus = !empty( $params['postStatus'] ) ? explode( ',', $params['postStatus'] ) : [ 'publish' ];
809 $count = wp_count_posts( $postType );
810 $count = array_sum( array_intersect_key( (array)$count, array_flip( $postStatus ) ) );
811 return new WP_REST_Response([ 'success' => true, 'count' => $count ], 200 );
812 }
813 catch ( Exception $e ) {
814 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
815 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
816 }
817 }
818
819 function rest_helpers_posts_ids( $request ) {
820 try {
821 $params = $request->get_query_params();
822 $postType = $params['postType'];
823 $postStatus = !empty( $params['postStatus'] ) ? explode( ',', $params['postStatus'] ) : [ 'publish' ];
824 $posts = get_posts( [
825 'posts_per_page' => -1,
826 'post_type' => $postType,
827 'post_status' => $postStatus,
828 'fields' => 'ids'
829 ] );
830 return new WP_REST_Response([ 'success' => true, 'postIds' => $posts ], 200 );
831 }
832 catch ( Exception $e ) {
833 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
834 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
835 }
836 }
837
838 function rest_helpers_post_content( $request ) {
839 try {
840 $params = $request->get_query_params();
841 $offset = (int)$params['offset'];
842 $postType = $params['postType'];
843 $postStatus = isset( $params['postStatus'] ) ? explode( ',', $params['postStatus'] ) : [ 'publish' ];
844 $postId = (int)$params['postId'];
845
846 $post = null;
847 if ( !empty( $postId ) ) {
848 $post = get_post( $postId );
849 if ( $post->post_status !== 'publish' && $post->post_status !== 'future'
850 && $post->post_status !== 'draft' && $post->post_status !== 'private' ) {
851 $post = null;
852 }
853 }
854 else {
855 $posts = get_posts( [
856 'posts_per_page' => 1,
857 'post_type' => $postType,
858 'offset' => $offset,
859 'post_status' => $postStatus,
860 ] );
861 $post = count( $posts ) === 0 ? null : $posts[0];
862 }
863 if ( !$post ) {
864 return new WP_REST_Response([ 'success' => false, 'message' => 'Post not found' ], 404 );
865 }
866 $cleanPost = $this->core->get_post( $post );
867 return new WP_REST_Response([ 'success' => true, 'content' => $cleanPost['content'],
868 'checksum' => $cleanPost['checksum'], 'language' => $cleanPost['language'], 'excerpt' => $cleanPost['excerpt'],
869 'postId' => $cleanPost['postId'], 'title' => $cleanPost['title'], 'url' => $cleanPost['url'] ], 200 );
870 }
871 catch ( Exception $e ) {
872 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
873 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
874 }
875 }
876
877 function rest_helpers_run_tasks( $request ) {
878 try {
879 do_action( 'mwai_tasks_run' );
880 return new WP_REST_Response([ 'success' => true ], 200 );
881 }
882 catch ( Exception $e ) {
883 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
884 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
885 }
886 }
887
888 function rest_system_templates_get( $request ) {
889 try {
890 $params = $request->get_query_params();
891 $category = $params['category'];
892 $templates = [];
893 $templates_option = get_option( 'mwai_templates', [] );
894 if ( !is_array( $templates_option ) ) {
895 update_option( 'mwai_templates', [] );
896 }
897 $categories = array_column( $templates_option, 'category' );
898 $index = array_search( $category, $categories );
899 $templates = [];
900 if ( $index !== false ) {
901 $templates = $templates_option[$index]['templates'];
902 }
903 return new WP_REST_Response([ 'success' => true, 'templates' => $templates ], 200 );
904 }
905 catch ( Exception $e ) {
906 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
907 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
908 }
909 }
910
911 function rest_system_templates_save( $request ) {
912 try {
913 $params = $request->get_json_params();
914 $category = $params['category'];
915 $templates = $params['templates'];
916 $templates_option = get_option( 'mwai_templates', [] );
917 $categories = array_column( $templates_option, 'category' );
918 $index = array_search( $category, $categories );
919 if ( $index !== false && $index >= 0 ) {
920 $templates_option[$index]['templates'] = $templates;
921 }
922 else {
923 $group = [ 'category' => $category, 'templates' => $templates ];
924 $templates_option[] = $group;
925 }
926
927 update_option( 'mwai_templates', $templates_option );
928 return new WP_REST_Response([ 'success' => true ], 200 );
929 }
930 catch ( Exception $e ) {
931 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
932 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
933 }
934 }
935
936 function rest_system_logs_list( $request ) {
937 try {
938 $params = $request->get_json_params();
939 $offset = $params['offset'];
940 $limit = $params['limit'];
941 $filters = $params['filters'];
942 $sort = $params['sort'];
943 $logs = apply_filters( 'mwai_stats_logs_list', [], $offset, $limit, $filters, $sort );
944 return new WP_REST_Response([ 'success' => true, 'total' => $logs['total'], 'logs' => $logs['rows'] ], 200 );
945 }
946 catch ( Exception $e ) {
947 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
948 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
949 }
950 }
951
952 function rest_system_logs_delete( $request ) {
953 try {
954 $params = $request->get_json_params();
955 $logIds = $params['logIds'];
956 $success = apply_filters( 'mwai_stats_logs_delete', true, $logIds );
957 return new WP_REST_Response([ 'success' => $success ], 200 );
958 }
959 catch ( Exception $e ) {
960 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
961 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
962 }
963 }
964
965 function rest_system_logs_meta_get( $request ) {
966 try {
967 $params = $request->get_json_params();
968 $logId = $params['logId'];
969 $metaKeys = $params['metaKeys'];
970 $data = apply_filters( 'mwai_stats_logs_meta', [], $logId, $metaKeys );
971 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
972 }
973 catch ( Exception $e ) {
974 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
975 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
976 }
977 }
978
979 function rest_system_logs_activity( $request ) {
980 try {
981 $params = $request->get_json_params();
982 $hours = isset( $params['hours'] ) ? intval( $params['hours'] ) : 24;
983 $data = apply_filters( 'mwai_stats_logs_activity', [], $hours );
984 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
985 }
986 catch ( Exception $e ) {
987 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
988 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
989 }
990 }
991
992 function rest_system_logs_activity_daily( $request ) {
993 try {
994 $params = $request->get_json_params();
995 $days = isset( $params['days'] ) ? intval( $params['days'] ) : 31;
996 $data = apply_filters( 'mwai_stats_logs_activity_daily', [], $days );
997 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
998 }
999 catch ( Exception $e ) {
1000 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1001 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1002 }
1003 }
1004
1005 function rest_ai_moderate( $request ) {
1006 try {
1007 $params = $request->get_json_params();
1008 $envId = $params['envId'];
1009 $text = $params['text'];
1010 if ( !$text ) {
1011 return new WP_REST_Response([ 'success' => false, 'message' => 'Text not found.' ], 404 );
1012 }
1013 $openai = Meow_MWAI_Engines_Factory::get_openai( $this->core, $envId );
1014 $results = $openai->moderate( $text );
1015 return new WP_REST_Response([ 'success' => true, 'results' => $results ], 200 );
1016 }
1017 catch ( Exception $e ) {
1018 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1019 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1020 }
1021 }
1022
1023 function rest_ai_transcribe_audio( $request ) {
1024 try {
1025 $params = $request->get_json_params();
1026 $query = new Meow_MWAI_Query_Transcribe();
1027 $query->inject_params( $params );
1028 $query->set_scope('admin-tools');
1029 $reply = $this->core->run_query( $query );
1030 return new WP_REST_Response([ 'success' => true, 'data' => $reply->result ], 200 );
1031 }
1032 catch ( Exception $e ) {
1033 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1034 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1035 }
1036 }
1037
1038 function rest_ai_transcribe_image( $request ) {
1039 try {
1040 global $mwai;
1041 $params = $request->get_json_params();
1042 $message = $this->retrieve_message( $params );
1043 $url = !empty( $params['url'] ) ? $params['url'] : null;
1044 // This could lead to a security issue, so let's avoid using path directly.
1045 //$path = !empty( $params['path'] ) ? $params['path'] : null;
1046 $result = $mwai->simpleVisionQuery( $message, $url );
1047 return new WP_REST_Response([ 'success' => true, 'data' => $result ], 200 );
1048 }
1049 catch ( Exception $e ) {
1050 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1051 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1052 }
1053 }
1054
1055 function rest_ai_json( $request ) {
1056 try {
1057 global $mwai;
1058 $params = $request->get_json_params();
1059 $message = $this->retrieve_message( $params );
1060 $result = $mwai->simpleJsonQuery( $message );
1061 return new WP_REST_Response([ 'success' => true, 'data' => $result ], 200 );
1062 }
1063 catch ( Exception $e ) {
1064 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1065 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1066 }
1067 }
1068
1069 function rest_mcp_functions( $request ) {
1070 try {
1071 // Get all registered MCP tools
1072 $tools = apply_filters( 'mwai_mcp_tools', [] );
1073
1074 // Format the response
1075 $response = [
1076 'success' => true,
1077 'count' => count( $tools ),
1078 'functions' => $tools
1079 ];
1080
1081 return new WP_REST_Response( $response, 200 );
1082 }
1083 catch ( Exception $e ) {
1084 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1085 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1086 }
1087 }
1088
1089 function rest_helpers_post_types() {
1090 try {
1091 $postTypes = $this->core->get_post_types();
1092 return new WP_REST_Response([ 'success' => true, 'postTypes' => $postTypes ], 200 );
1093 }
1094 catch ( Exception $e ) {
1095 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1096 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1097 }
1098 }
1099
1100 function rest_settings_themes( $request ) {
1101 try {
1102 $method = $request->get_method();
1103 if ( $method === 'GET' ) {
1104 $themes = $this->core->get_themes();
1105 return new WP_REST_Response([ 'success' => true, 'themes' => $themes ], 200 );
1106 }
1107 else if ( $method === 'POST' ) {
1108 $params = $request->get_json_params();
1109 $themes = $params['themes'];
1110 $themes = $this->core->update_themes( $themes );
1111 return new WP_REST_Response([ 'success' => true, 'themes' => $themes ], 200 );
1112 }
1113 }
1114 catch ( Exception $e ) {
1115 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1116 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1117 }
1118 }
1119
1120 function rest_settings_chatbots( $request ) {
1121 try {
1122 $method = $request->get_method();
1123 if ( $method === 'GET' ) {
1124 $chatbots = $this->core->get_chatbots();
1125 return new WP_REST_Response([ 'success' => true, 'chatbots' => $chatbots ], 200 );
1126 }
1127 else if ( $method === 'POST' ) {
1128 $params = $request->get_json_params();
1129 $chatbots = $params['chatbots'];
1130 $chatbots = $this->core->update_chatbots( $chatbots );
1131 return new WP_REST_Response([ 'success' => true, 'chatbots' => $chatbots ], 200 );
1132 }
1133 return new WP_REST_Response([ 'success' => false, 'message' => 'Method not allowed' ], 405 );
1134 }
1135 catch ( Exception $e ) {
1136 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
1137 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
1138 }
1139 }
1140
1141 #region Logs
1142
1143 function rest_get_logs() {
1144 $logs = Meow_MWAI_Logging::get();
1145 return new WP_REST_Response( [ 'success' => true, 'data' => $logs ], 200 );
1146 }
1147
1148 function rest_clear_logs() {
1149 Meow_MWAI_Logging::clear();
1150 return new WP_REST_Response( [ 'success' => true ], 200 );
1151 }
1152
1153 #endregion
1154 }
1155