PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.7.6
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.7.6
3.6.2 3.6.1 3.6.0 3.5.9 3.5.8 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 3 years ago modules 3 years ago queries 3 years ago admin.php 3 years ago api.php 3 years ago core.php 3 years ago init.php 3 years ago reply.php 3 years ago rest.php 3 years ago
rest.php
915 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 function rest_init() {
14 try {
15 // Settings Endpoints
16 register_rest_route( $this->namespace, '/settings/update', array(
17 'methods' => 'POST',
18 'permission_callback' => array( $this->core, 'can_access_settings' ),
19 'callback' => array( $this, 'rest_settings_update' )
20 ) );
21 register_rest_route( $this->namespace, '/settings/list', array(
22 'methods' => 'GET',
23 'permission_callback' => array( $this->core, 'can_access_settings' ),
24 'callback' => array( $this, 'rest_settings_list' ),
25 ) );
26 register_rest_route( $this->namespace, '/settings/reset', array(
27 'methods' => 'POST',
28 'permission_callback' => array( $this->core, 'can_access_settings' ),
29 'callback' => array( $this, 'rest_settings_reset' ),
30 ) );
31 register_rest_route( $this->namespace, '/settings/chatbots', array(
32 'methods' => ['GET', 'POST'],
33 'permission_callback' => array( $this->core, 'can_access_settings' ),
34 'callback' => array( $this, 'rest_settings_chatbots' ),
35 ) );
36 register_rest_route( $this->namespace, '/settings/themes', array(
37 'methods' => ['GET', 'POST'],
38 'permission_callback' => array( $this->core, 'can_access_settings' ),
39 'callback' => array( $this, 'rest_settings_themes' ),
40 ) );
41
42 // System Endpoints
43 register_rest_route( $this->namespace, '/system/logs/list', array(
44 'methods' => 'POST',
45 'permission_callback' => array( $this->core, 'can_access_settings' ),
46 'callback' => array( $this, 'rest_system_logs_list' ),
47 ) );
48 register_rest_route( $this->namespace, '/system/logs/delete', array(
49 'methods' => 'POST',
50 'permission_callback' => array( $this->core, 'can_access_settings' ),
51 'callback' => array( $this, 'rest_system_logs_delete' ),
52 ) );
53 register_rest_route( $this->namespace, '/system/logs/meta', array(
54 'methods' => 'POST',
55 'permission_callback' => array( $this->core, 'can_access_settings' ),
56 'callback' => array( $this, 'rest_system_logs_meta_get' ),
57 ) );
58 register_rest_route( $this->namespace, '/system/templates', array(
59 'methods' => 'POST',
60 'permission_callback' => array( $this->core, 'can_access_features' ),
61 'callback' => array( $this, 'rest_system_templates_save' ),
62 ) );
63 register_rest_route( $this->namespace, '/system/templates', array(
64 'methods' => 'GET',
65 'permission_callback' => array( $this->core, 'can_access_features' ),
66 'callback' => array( $this, 'rest_system_templates_get' ),
67 ) );
68
69 // AI Endpoints
70 register_rest_route( $this->namespace, '/ai/completions', array(
71 'methods' => 'POST',
72 'permission_callback' => array( $this->core, 'can_access_features' ),
73 'callback' => array( $this, 'rest_ai_completions' ),
74 ) );
75 register_rest_route( $this->namespace, '/ai/images', array(
76 'methods' => 'POST',
77 'permission_callback' => array( $this->core, 'can_access_features' ),
78 'callback' => array( $this, 'rest_ai_images' ),
79 ) );
80 register_rest_route( $this->namespace, '/ai/copilot', array(
81 'methods' => 'POST',
82 'permission_callback' => array( $this->core, 'can_access_features' ),
83 'callback' => array( $this, 'rest_ai_copilot' ),
84 ) );
85
86 register_rest_route( $this->namespace, '/ai/magic_wand', array(
87 'methods' => 'POST',
88 'callback' => array( $this, 'rest_ai_magic_wand' ),
89 'permission_callback' => array( $this->core, 'can_access_features' ),
90 ) );
91 register_rest_route( $this->namespace, '/ai/moderate', array(
92 'methods' => 'POST',
93 'permission_callback' => array( $this->core, 'can_access_settings' ),
94 'callback' => array( $this, 'rest_ai_moderate' ),
95 ) );
96 register_rest_route( $this->namespace, '/ai/transcribe', array(
97 'methods' => 'POST',
98 'permission_callback' => array( $this->core, 'can_access_settings' ),
99 'callback' => array( $this, 'rest_ai_transcribe' ),
100 ) );
101
102 // Helpers Endpoints
103 register_rest_route( $this->namespace, '/helpers/update_post_title', array(
104 'methods' => 'POST',
105 'permission_callback' => array( $this->core, 'can_access_features' ),
106 'callback' => array( $this, 'rest_helpers_update_title' ),
107 ) );
108 register_rest_route( $this->namespace, '/helpers/update_post_excerpt', array(
109 'methods' => 'POST',
110 'permission_callback' => array( $this->core, 'can_access_features' ),
111 'callback' => array( $this, 'rest_helpers_update_excerpt' ),
112 ) );
113 register_rest_route( $this->namespace, '/helpers/create_post', array(
114 'methods' => 'POST',
115 'permission_callback' => array( $this->core, 'can_access_features' ),
116 'callback' => array( $this, 'rest_helpers_create_post' ),
117 ) );
118 register_rest_route( $this->namespace, '/helpers/create_image', array(
119 'methods' => 'POST',
120 'permission_callback' => array( $this->core, 'can_access_features' ),
121 'callback' => array( $this, 'rest_helpers_create_images' ),
122 ) );
123 register_rest_route( $this->namespace, '/helpers/count_posts', array(
124 'methods' => 'GET',
125 'permission_callback' => array( $this->core, 'can_access_features' ),
126 'callback' => array( $this, 'rest_helpers_count_posts' ),
127 ) );
128 register_rest_route( $this->namespace, '/helpers/post_types', array(
129 'methods' => 'GET',
130 'permission_callback' => array( $this->core, 'can_access_features' ),
131 'callback' => array( $this, 'rest_helpers_post_types' ),
132 ) );
133 register_rest_route( $this->namespace, '/helpers/post_content', array(
134 'methods' => 'GET',
135 'permission_callback' => array( $this->core, 'can_access_features' ),
136 'callback' => array( $this, 'rest_helpers_post_content' ),
137 ) );
138
139 // OpenAI Endpoints
140 register_rest_route( $this->namespace, '/openai/files/list', array(
141 'methods' => 'GET',
142 'permission_callback' => array( $this->core, 'can_access_settings' ),
143 'callback' => array( $this, 'rest_openai_files_get' ),
144 ) );
145 register_rest_route( $this->namespace, '/openai/files/upload', array(
146 'methods' => 'POST',
147 'permission_callback' => array( $this->core, 'can_access_settings' ),
148 'callback' => array( $this, 'rest_openai_files_upload' ),
149 ) );
150 register_rest_route( $this->namespace, '/openai/files/delete', array(
151 'methods' => 'POST',
152 'permission_callback' => array( $this->core, 'can_access_settings' ),
153 'callback' => array( $this, 'rest_openai_files_delete' ),
154 ) );
155 register_rest_route( $this->namespace, '/openai/files/download', array(
156 'methods' => 'POST',
157 'permission_callback' => array( $this->core, 'can_access_settings' ),
158 'callback' => array( $this, 'rest_openai_files_download' ),
159 ) );
160 register_rest_route( $this->namespace, '/openai/files/finetune', array(
161 'methods' => 'POST',
162 'permission_callback' => array( $this->core, 'can_access_settings' ),
163 'callback' => array( $this, 'rest_openai_files_finetune' ),
164 ) );
165 register_rest_route( $this->namespace, '/openai/finetunes/list_deleted', array(
166 'methods' => 'GET',
167 'permission_callback' => array( $this->core, 'can_access_settings' ),
168 'callback' => array( $this, 'rest_openai_deleted_finetunes_get' ),
169 ) );
170 register_rest_route( $this->namespace, '/openai/finetunes/list', array(
171 'methods' => 'GET',
172 'permission_callback' => array( $this->core, 'can_access_settings' ),
173 'callback' => array( $this, 'rest_openai_finetunes_get' ),
174 ) );
175 register_rest_route( $this->namespace, '/openai/finetunes/delete', array(
176 'methods' => 'POST',
177 'permission_callback' => array( $this->core, 'can_access_settings' ),
178 'callback' => array( $this, 'rest_openai_finetunes_delete' ),
179 ) );
180 register_rest_route( $this->namespace, '/openai/finetunes/cancel', array(
181 'methods' => 'POST',
182 'permission_callback' => array( $this->core, 'can_access_settings' ),
183 'callback' => array( $this, 'rest_openai_finetunes_cancel' ),
184 ) );
185 register_rest_route( $this->namespace, '/openai/incidents', array(
186 'methods' => 'GET',
187 'permission_callback' => array( $this->core, 'can_access_settings' ),
188 'callback' => array( $this, 'rest_openai_incidents' ),
189 ) );
190 }
191 catch ( Exception $e ) {
192 var_dump( $e );
193 }
194 }
195
196 function rest_settings_list() {
197 return new WP_REST_Response( [
198 'success' => true,
199 'options' => $this->core->get_all_options()
200 ], 200 );
201 }
202
203 function rest_settings_update( $request ) {
204 try {
205 $params = $request->get_json_params();
206 $value = $params['options'];
207 $options = $this->core->update_options( $value );
208 $success = !!$options;
209 $message = __( $success ? 'OK' : "Could not update options.", 'ai-engine' );
210 return new WP_REST_Response([ 'success' => $success, 'message' => $message, 'options' => $options ], 200 );
211 }
212 catch ( Exception $e ) {
213 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
214 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
215 }
216 }
217
218 function rest_settings_reset() {
219 try {
220 $options = $this->core->reset_options();
221 $success = !!$options;
222 $message = __( $success ? 'OK' : "Could not reset options.", 'ai-engine' );
223 return new WP_REST_Response([ 'success' => $success, 'message' => $message, 'options' => $options ], 200 );
224 }
225 catch ( Exception $e ) {
226 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
227 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
228 }
229 }
230
231 function createValidationResult( $result = true, $message = null) {
232 $message = $message ? $message : __( 'OK', 'ai-engine' );
233 return [ 'result' => $result, 'message' => $message ];
234 }
235
236 function validate_updated_option( $option_name ) {
237 $option_checkbox = get_option( 'mwai_option_checkbox', false );
238 $option_text = get_option( 'mwai_option_text', 'Default' );
239 if ( $option_checkbox === '' )
240 update_option( 'mwai_option_checkbox', false );
241 if ( $option_text === '' )
242 update_option( 'mwai_option_text', 'Default' );
243 return $this->createValidationResult();
244 }
245
246 function rest_ai_completions( $request ) {
247 try {
248 $params = $request->get_json_params();
249 $prompt = $params['prompt'];
250 $query = new Meow_MWAI_Query_Text( $prompt );
251 $query->injectParams( $params );
252
253 $stream = $params['stream'] ?? false;
254 if ( $stream ) {
255 $streamCallback = function( $reply ) {
256 //$raw = _wp_specialchars( $reply, ENT_NOQUOTES, 'UTF-8', true );
257 $raw = $reply;
258 $this->core->stream_push( [ 'type' => 'live', 'data' => $raw ] );
259 if ( ob_get_level() > 0 ) {
260 ob_flush();
261 }
262 flush();
263 };
264 header( 'Cache-Control: no-cache' );
265 header( 'Content-Type: text/event-stream' );
266 header( 'X-Accel-Buffering: no' ); // This is useful to disable buffering in nginx through headers.
267 ob_implicit_flush( true );
268 ob_end_flush();
269 }
270
271 $reply = $this->core->ai->run( $query, $streamCallback );
272
273 // Process Reply
274 $restRes = [
275 'success' => true,
276 'data' => $reply->result,
277 'usage' => $reply->usage
278 ];
279 if ( $stream ) {
280 $this->core->stream_push( [ 'type' => 'end', 'data' => json_encode( $restRes ) ] );
281 die();
282 }
283 return new WP_REST_Response( $restRes, 200 );
284 }
285 catch ( Exception $e ) {
286 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
287 if ( $stream ) {
288 $this->core->stream_push( [ 'type' => 'error', 'data' => $message ] );
289 }
290 else {
291 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
292 }
293 }
294 }
295
296 function rest_ai_images( $request ) {
297 try {
298 $params = $request->get_json_params();
299 $prompt = $params['prompt'];
300 $query = new Meow_MWAI_Query_Image( $prompt );
301 $query->injectParams( $params );
302 $reply = $this->core->ai->run( $query );
303 return new WP_REST_Response([ 'success' => true, 'data' => $reply->results, 'usage' => $reply->usage ], 200 );
304 }
305 catch ( Exception $e ) {
306 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
307 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
308 }
309 }
310
311 function rest_ai_magic_wand( $request ) {
312 try {
313 $params = $request->get_json_params();
314 $action = isset( $params['action'] ) ? $params['action'] : null;
315 $data = isset( $params['data'] ) ? $params['data'] : null;
316 if ( empty( $data ) || empty( $action ) ) {
317 return new WP_REST_Response([ 'success' => false, 'message' => "An action and some data are required." ], 500 );
318 }
319 $postId = isset( $data['postId'] ) ? $data['postId'] : null;
320 $text = isset( $data['text'] ) ? $data['text'] : null;
321 $selectedText = isset( $data['selectedText'] ) ? $data['selectedText'] : null;
322
323 // NOTE: As soon as we have a wide range of usages and possibilities,
324 // let's refactor this into a nice and extensible UI/API.
325 $query = new Meow_MWAI_Query_Text( "", 1024 );
326 $query->setEnv( 'admin-tools' );
327 $model = $this->core->get_option( 'assistants_model' );
328 if ( !empty( $model ) ) {
329 $query->setModel( $model );
330 }
331 $mode = 'replace';
332
333 $language = "";
334 $keepLanguage = "";
335 if ( !empty( $postId ) ) {
336 $language = $this->core->get_post_language( $postId );
337 $keepLanguage = " Ensure the reply is in the same language as the original text ({$language}).";
338 }
339
340 if ( $action === 'correctText' ) {
341 $query->setPrompt( "Correct the typos and grammar mistakes in this text without altering its content. Return only the corrected text, without explanations or additional content.{$keepLanguage}\n\n" . $text );
342 }
343 else if ( $action === 'enhanceText' ) {
344 $query->setPrompt( "Enhance this text by eliminating redundancies, utilizing a more suitable vocabulary, and refining its structure. Provide only the revised text, without explanations or any additional content.{$keepLanguage}\n\n" . $text );
345 }
346 else if ( $action === 'longerText' ) {
347 $query->setPrompt( "Expand the subsequent text to a minimum of three times its original length, integrating relevant and accurate information to enrich its content. If the text is a story, amplify its charm by elaborating on essential aspects, enhancing readability, and creating a sense of engagement for the reader. Maintain consistency in tone and vocabulary throughout the expansion process.{$keepLanguage}\n\n" . $text );
348 }
349 else if ( $action === 'shorterText' ) {
350 $query->setPrompt( "Condense the following text by reducing its length to half, while retaining the core elements of the original narrative. Focus on maintaining the essence of the story and its key details.{$keepLanguage}\n\n" . $text );
351 }
352 else if ( $action === 'suggestSynonyms' ) {
353 $mode = 'suggest';
354 $query->setPrompt( "Provide a synonym or rephrase the given word or sentence while retaining the original meaning and preserving the initial and final punctuation. Offer only the resulting word or expression, without additional context. If a suitable synonym or alternative cannot be identified, ensure that a creative response is still provided.{$keepLanguage}\n\n" . $selectedText );
355 $query->setTemperature( 1 );
356 $query->setMaxResults( 5 );
357 }
358 else if ( $action === 'translateText' ) {
359 $query->setPrompt( "Translate the text into {$language}, preserving the tone, mood, and nuance, while staying as true as possible to the original meaning. Provide only the translated text, without any additional content.\n\n" . $text );
360 }
361 else if ( $action === 'suggestExcerpts' ) {
362 $text = $this->core->getCleanPostContent( $postId );
363 $query->setPrompt( "Craft a clear, SEO-optimized introduction for the following text, using 120 to 170 characters. Ensure the introduction is concise and relevant, without including any URLs.{$keepLanguage}\n\n" . $text );
364 $query->setMaxResults( 5 );
365 }
366 else if ( $action === 'suggestTitles' ) {
367 $text = $this->core->getCleanPostContent( $postId );
368 $query->setPrompt( "Generate a concise, SEO-optimized title for the following text, without using quotes or any other formatting. Focus on clarity and relevance to the content.{$keepLanguage}\n\n" . $text );
369 $query->setMaxResults( 5 );
370 }
371 $reply = $this->core->ai->run( $query );
372 return new WP_REST_Response([ 'success' => true, 'data' => [
373 'mode' => $mode,
374 'result' => $reply->result,
375 'results' => $reply->results
376 ] ], 200 );
377 }
378 catch ( Exception $e ) {
379 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
380 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
381 }
382 }
383
384 function rest_ai_copilot( $request ) {
385 try {
386 $params = $request->get_json_params();
387 $action = sanitize_text_field( $params['action'] );
388 $prompt = sanitize_text_field( $params['prompt'] );
389 if ( empty( $action ) || empty( $prompt ) ) {
390 return new WP_REST_Response([ 'success' => false, 'message' => "Copilot needs an action and a prompt." ], 500 );
391 }
392 $query = new Meow_MWAI_Query_Text( $prompt, 2048 );
393 $query->setEnv( 'admin-tools' );
394 $model = $this->core->get_option( 'assistants_model' );
395 if ( !empty( $model ) ) {
396 $query->setModel( $model );
397 }
398 $reply = $this->core->ai->run( $query );
399 return new WP_REST_Response([ 'success' => true, 'data' => $reply->result ], 200 );
400 }
401 catch ( Exception $e ) {
402 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
403 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
404 }
405 }
406
407 function rest_helpers_update_title( $request ) {
408 try {
409 $params = $request->get_json_params();
410 $title = sanitize_text_field( $params['title'] );
411 $postId = intval( $params['postId'] );
412 $post = get_post( $postId );
413 if ( !$post ) {
414 throw new Exception( 'There is no post with this ID.' );
415 }
416 $post->post_title = $title;
417 //$post->post_name = sanitize_title( $title );
418 wp_update_post( $post );
419 return new WP_REST_Response([ 'success' => true, 'message' => "Title updated." ], 200 );
420 }
421 catch ( Exception $e ) {
422 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
423 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
424 }
425 }
426
427 function rest_helpers_update_excerpt( $request ) {
428 try {
429 $params = $request->get_json_params();
430 $excerpt = sanitize_text_field( $params['excerpt'] );
431 $postId = intval( $params['postId'] );
432 $post = get_post( $postId );
433 if ( !$post ) {
434 throw new Exception( 'There is no post with this ID.' );
435 }
436 $post->post_excerpt = $excerpt;
437 wp_update_post( $post );
438 return new WP_REST_Response([ 'success' => true, 'message' => "Excerpt updated." ], 200 );
439 }
440 catch ( Exception $e ) {
441 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
442 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
443 }
444 }
445
446 function rest_helpers_create_post( $request ) {
447 try {
448 $params = $request->get_json_params();
449 $title = sanitize_text_field( $params['title'] );
450 $content = sanitize_textarea_field( $params['content'] );
451 $excerpt = sanitize_text_field( $params['excerpt'] );
452 $postType = sanitize_text_field( $params['postType'] );
453 $post = new stdClass();
454 $post->post_title = $title;
455 $post->post_excerpt = $excerpt;
456 $post->post_content = $content;
457 $post->post_status = 'draft';
458 $post->post_type = isset( $postType ) ? $postType : 'post';
459 $post->post_content = $this->core->markdown_to_html( $post->post_content );
460 $postId = wp_insert_post( $post );
461 return new WP_REST_Response([ 'success' => true, 'postId' => $postId ], 200 );
462 }
463 catch ( Exception $e ) {
464 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
465 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
466 }
467 }
468
469 function image_download( $url ) {
470 $args = array( 'timeout' => 60, );
471 $response = wp_remote_get( $url, $args );
472 if ( is_wp_error( $response ) ) {
473 throw new Exception( $response->get_error_message() );
474 }
475 $output = wp_remote_retrieve_body( $response );
476 if ( is_wp_error( $output ) ) {
477 throw new Exception( $output->get_error_message() );
478 }
479 return $output;
480 }
481
482 function rest_helpers_create_images( $request ) {
483 try {
484 $params = $request->get_json_params();
485 $title = sanitize_text_field( $params['title'] );
486 $caption = sanitize_text_field( $params['caption'] );
487 $alt = sanitize_text_field( $params['alt'] );
488 $description = sanitize_text_field( $params['description'] );
489 $url = $params['url'];
490 $filename = sanitize_text_field( $params['filename'] );
491 $image_data = $this->image_download( $url );
492 if ( !$image_data ) {
493 throw new Exception( 'Could not download the image.' );
494 }
495 $upload_dir = wp_upload_dir();
496 if ( empty( $filename ) ) {
497 $filename = basename( $url );
498 }
499 $wp_filetype = wp_check_filetype( $filename );
500 if ( wp_mkdir_p( $upload_dir['path'] ) ) {
501 $file = $upload_dir['path'] . '/' . $filename;
502 }
503 else {
504 $file = $upload_dir['basedir'] . '/' . $filename;
505 }
506
507 // Make sure the file is unique, if not, add a number to the end of the file before the extension
508 $i = 1;
509 $parts = pathinfo( $file );
510 while ( file_exists( $file ) ) {
511 $file = $parts['dirname'] . '/' . $parts['filename'] . '-' . $i . '.' . $parts['extension'];
512 $i++;
513 }
514
515 // Write the file
516 file_put_contents( $file, $image_data );
517 $attachment = [
518 'post_mime_type' => $wp_filetype['type'],
519 'post_title' => $title,
520 'post_content' => $description,
521 'post_excerpt' => $caption,
522 'post_status' => 'inherit'
523 ];
524 // Register the file as a Media Library attachment
525 $attachmentId = wp_insert_attachment( $attachment, $file );
526 require_once( ABSPATH . 'wp-admin/includes/image.php' );
527 $attachment_data = wp_generate_attachment_metadata( $attachmentId, $file );
528 wp_update_attachment_metadata( $attachmentId, $attachment_data );
529 update_post_meta( $attachmentId, '_wp_attachment_image_alt', $alt );
530 return new WP_REST_Response([ 'success' => true, 'attachmentId' => $attachmentId ], 200 );
531 }
532 catch ( Exception $e ) {
533 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
534 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
535 }
536 }
537
538 function rest_openai_files_get() {
539 try {
540 //$params = $request->get_json_params();
541 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
542 $files = $openai->listFiles();
543 return new WP_REST_Response([ 'success' => true, 'files' => $files ], 200 );
544 }
545 catch ( Exception $e ) {
546 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
547 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
548 }
549 }
550
551 function rest_openai_deleted_finetunes_get() {
552 try {
553 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
554 $finetunes = $openai->listDeletedFineTunes();
555 return new WP_REST_Response([ 'success' => true, 'finetunes' => $finetunes ], 200 );
556 }
557 catch ( Exception $e ) {
558 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
559 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
560 }
561 }
562
563 function rest_openai_finetunes_get() {
564 try {
565 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
566 $finetunes = $openai->listFineTunes();
567 return new WP_REST_Response([ 'success' => true, 'finetunes' => $finetunes ], 200 );
568 }
569 catch ( Exception $e ) {
570 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
571 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
572 }
573 }
574
575 function rest_openai_files_upload( $request ) {
576 try {
577 $params = $request->get_json_params();
578 $filename = sanitize_text_field( $params['filename'] );
579 $data = $params['data'];
580 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
581 $file = $openai->uploadFile( $filename, $data );
582 return new WP_REST_Response([ 'success' => true, 'file' => $file ], 200 );
583 }
584 catch ( Exception $e ) {
585 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
586 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
587 }
588 }
589
590 function rest_openai_files_delete( $request ) {
591 try {
592 $params = $request->get_json_params();
593 $fileId = $params['fileId'];
594 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
595 $openai->deleteFile( $fileId );
596 return new WP_REST_Response([ 'success' => true ], 200 );
597 }
598 catch ( Exception $e ) {
599 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
600 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
601 }
602 }
603
604 function rest_openai_finetunes_cancel( $request ) {
605 try {
606 $params = $request->get_json_params();
607 $finetuneId = $params['finetuneId'];
608 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
609 $openai->cancelFineTune( $finetuneId );
610 return new WP_REST_Response([ 'success' => true ], 200 );
611 }
612 catch ( Exception $e ) {
613 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
614 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
615 }
616 }
617
618 function rest_openai_finetunes_delete( $request ) {
619 try {
620 $params = $request->get_json_params();
621 $modelId = $params['modelId'];
622 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
623 $openai->deleteFineTune( $modelId );
624 return new WP_REST_Response([ 'success' => true ], 200 );
625 }
626 catch ( Exception $e ) {
627 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
628 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
629 }
630 }
631
632 function rest_openai_files_download( $request ) {
633 try {
634 $params = $request->get_json_params();
635 $fileId = $params['fileId'];
636 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
637 $data = $openai->downloadFile( $fileId );
638 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
639 }
640 catch ( Exception $e ) {
641 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
642 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
643 }
644 }
645
646 function rest_openai_files_finetune( $request ) {
647 try {
648 $params = $request->get_json_params();
649 $fileId = $params['fileId'];
650 $model = $params['model'];
651 $suffix = $params['suffix'];
652 $hyperparams = [
653 "nEpochs" => $params['nEpochs'],
654 "batchSize" => $params['batchSize']
655 ];
656 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
657 $finetune = $openai->fineTuneFile( $fileId, $model, $suffix, $hyperparams );
658 return new WP_REST_Response([ 'success' => true, 'finetune' => $finetune ], 200 );
659 }
660 catch ( Exception $e ) {
661 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
662 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
663 }
664 }
665
666 function rest_openai_incidents() {
667 try {
668 $transient = get_transient( 'mwai_openai_incidents' );
669 if ( $transient ) {
670 return new WP_REST_Response([ 'success' => true, 'incidents' => $transient ], 200 );
671 }
672 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
673 $incidents = $openai->getIncidents();
674 set_transient( 'mwai_openai_incidents', $incidents, 60 * 10 );
675 return new WP_REST_Response([ 'success' => true, 'incidents' => $incidents ], 200 );
676 }
677 catch ( Exception $e ) {
678 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
679 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
680 }
681 }
682
683 function rest_helpers_count_posts( $request ) {
684 try {
685 $params = $request->get_query_params();
686 $postType = $params['postType'];
687 $postStatus = $params['postStatus'];
688 $postStatus = !empty( $params['postStatus'] ) ? explode( ',', $postStatus ) : [ 'publish' ];
689 $count = wp_count_posts( $postType );
690 $count = array_sum( array_intersect_key( (array)$count, array_flip( $postStatus ) ) );
691 return new WP_REST_Response([ 'success' => true, 'count' => $count ], 200 );
692 }
693 catch ( Exception $e ) {
694 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
695 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
696 }
697 }
698
699 function rest_helpers_post_content( $request ) {
700 try {
701 $params = $request->get_query_params();
702 $offset = (int)$params['offset'];
703 $postType = $params['postType'];
704 $postStatus = $params['postStatus'];
705 $postStatus = !empty( $params['postStatus'] ) ? explode( ',', $postStatus ) : [ 'publish' ];
706 $postId = (int)$params['postId'];
707
708 $post = null;
709 if ( !empty( $postId ) ) {
710 $post = get_post( $postId );
711 if ( $post->post_status !== 'publish' && $post->post_status !== 'future'
712 && $post->post_status !== 'draft' && $post->post_status !== 'private' ) {
713 $post = null;
714 }
715 }
716 else {
717 $posts = get_posts( [
718 'posts_per_page' => 1,
719 'post_type' => $postType,
720 'offset' => $offset,
721 'post_status' => $postStatus,
722 ] );
723 $post = count( $posts ) === 0 ? null : $posts[0];
724 }
725 if ( !$post ) {
726 return new WP_REST_Response([ 'success' => false, 'message' => 'Post not found' ], 404 );
727 }
728 $cleanPost = $this->core->getCleanPost( $post );
729 return new WP_REST_Response([ 'success' => true, 'content' => $cleanPost['content'],
730 'checksum' => $cleanPost['checksum'], 'language' => $cleanPost['language'], 'excerpt' => $cleanPost['excerpt'],
731 'postId' => $cleanPost['postId'], 'title' => $cleanPost['title'], 'url' => $cleanPost['url'] ], 200 );
732 }
733 catch ( Exception $e ) {
734 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
735 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
736 }
737 }
738
739 function rest_system_templates_get( $request ) {
740 try {
741 $params = $request->get_query_params();
742 $category = $params['category'];
743 $templates = [];
744 $templates_option = get_option( 'mwai_templates', [] );
745 if ( !is_array( $templates_option ) ) {
746 update_option( 'mwai_templates', [] );
747 }
748 $categories = array_column( $templates_option, 'category' );
749 $index = array_search( $category, $categories );
750 $templates = [];
751 if ( $index !== false ) {
752 $templates = $templates_option[$index]['templates'];
753 }
754 return new WP_REST_Response([ 'success' => true, 'templates' => $templates ], 200 );
755 }
756 catch ( Exception $e ) {
757 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
758 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
759 }
760 }
761
762 function rest_system_templates_save( $request ) {
763 try {
764 $params = $request->get_json_params();
765 $category = $params['category'];
766 $templates = $params['templates'];
767 $templates_option = get_option( 'mwai_templates', [] );
768 $categories = array_column( $templates_option, 'category' );
769 $index = array_search( $category, $categories );
770 if ( $index !== false && $index >= 0 ) {
771 $templates_option[$index]['templates'] = $templates;
772 }
773 else {
774 $group = [ 'category' => $category, 'templates' => $templates ];
775 $templates_option[] = $group;
776 }
777
778 update_option( 'mwai_templates', $templates_option );
779 return new WP_REST_Response([ 'success' => true ], 200 );
780 }
781 catch ( Exception $e ) {
782 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
783 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
784 }
785 }
786
787 function rest_system_logs_list( $request ) {
788 try {
789 $params = $request->get_json_params();
790 $offset = $params['offset'];
791 $limit = $params['limit'];
792 $filters = $params['filters'];
793 $sort = $params['sort'];
794 $logs = apply_filters( 'mwai_stats_logs', [], $offset, $limit, $filters, $sort );
795 return new WP_REST_Response([ 'success' => true, 'total' => $logs['total'], 'logs' => $logs['rows'] ], 200 );
796 }
797 catch ( Exception $e ) {
798 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
799 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
800 }
801 }
802
803 function rest_system_logs_delete( $request ) {
804 try {
805 $params = $request->get_json_params();
806 $logIds = $params['logIds'];
807 $success = apply_filters( 'mwai_stats_logs_delete', true, $logIds );
808 return new WP_REST_Response([ 'success' => $success ], 200 );
809 }
810 catch ( Exception $e ) {
811 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
812 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
813 }
814 }
815
816 function rest_system_logs_meta_get( $request ) {
817 try {
818 $params = $request->get_json_params();
819 $logId = $params['logId'];
820 $metaKeys = $params['metaKeys'];
821 $data = apply_filters( 'mwai_stats_logs_meta', [], $logId, $metaKeys );
822 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
823 }
824 catch ( Exception $e ) {
825 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
826 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
827 }
828 }
829
830 function rest_ai_moderate( $request ) {
831 try {
832 $params = $request->get_json_params();
833 $text = $params['text'];
834 if ( !$text ) {
835 return new WP_REST_Response([ 'success' => false, 'message' => 'Text not found.' ], 404 );
836 }
837 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
838 $results = $openai->moderate( $text );
839 return new WP_REST_Response([ 'success' => true, 'results' => $results ], 200 );
840 }
841 catch ( Exception $e ) {
842 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
843 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
844 }
845
846 }
847
848 function rest_ai_transcribe( $request ) {
849 try {
850 $params = $request->get_json_params();
851 $query = new Meow_MWAI_Query_Transcribe();
852 $query->injectParams( $params );
853 $query->setEnv('admin-tools');
854 $reply = $this->core->ai->run( $query );
855 return new WP_REST_Response([ 'success' => true, 'data' => $reply->result ], 200 );
856 }
857 catch ( Exception $e ) {
858 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
859 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
860 }
861 }
862
863 function rest_helpers_post_types() {
864 try {
865 $postTypes = $this->core->getPostTypes();
866 return new WP_REST_Response([ 'success' => true, 'postTypes' => $postTypes ], 200 );
867 }
868 catch ( Exception $e ) {
869 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
870 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
871 }
872 }
873
874 function rest_settings_themes( $request ) {
875 try {
876 $method = $request->get_method();
877 if ( $method === 'GET' ) {
878 $themes = $this->core->getThemes();
879 return new WP_REST_Response([ 'success' => true, 'themes' => $themes ], 200 );
880 }
881 else if ( $method === 'POST' ) {
882 $params = $request->get_json_params();
883 $themes = $params['themes'];
884 $themes = $this->core->updateThemes( $themes );
885 return new WP_REST_Response([ 'success' => true, 'themes' => $themes ], 200 );
886 }
887 }
888 catch ( Exception $e ) {
889 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
890 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
891 }
892 }
893
894 function rest_settings_chatbots( $request ) {
895 try {
896 $method = $request->get_method();
897 if ( $method === 'GET' ) {
898 $chatbots = $this->core->getChatbots();
899 return new WP_REST_Response([ 'success' => true, 'chatbots' => $chatbots ], 200 );
900 }
901 else if ( $method === 'POST' ) {
902 $params = $request->get_json_params();
903 $chatbots = $params['chatbots'];
904 $chatbots = $this->core->updateChatbots( $chatbots );
905 return new WP_REST_Response([ 'success' => true, 'chatbots' => $chatbots ], 200 );
906 }
907 return new WP_REST_Response([ 'success' => false, 'message' => 'Method not allowed' ], 405 );
908 }
909 catch ( Exception $e ) {
910 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
911 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
912 }
913 }
914 }
915