PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / trunk
AI Engine – The Chatbot, AI Framework & MCP for WordPress vtrunk
3.7.3 3.7.2 3.7.1 3.7.0 3.6.9 3.6.8 3.6.7 3.6.6 3.6.4 3.6.5 3.6.3 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 / modules / editor-assistant.php
ai-engine / classes / modules Last commit date
advisor.php 5 months ago chatbot.php 1 week ago discussions.php 1 week ago editor-assistant.php 1 week ago files.php 1 month ago forms-manager.php 5 months ago gdpr.php 6 months ago search.php 5 months ago security.php 1 year ago tasks-examples.php 8 months ago tasks.php 1 month ago wand.php 5 months ago workspace.php 4 weeks ago
editor-assistant.php
206 lines
1 <?php
2
3 class Meow_MWAI_Modules_Editor_Assistant {
4 protected $core = null;
5 protected $botId = 'mwai_assistant';
6 protected $namespace = 'mwai-ui/v1';
7
8 public function __construct( $core ) {
9 $this->core = $core;
10 add_filter( 'mwai_internal_chatbot', [ $this, 'get_internal_chatbot' ], 10, 3 );
11 add_action( 'rest_api_init', [ $this, 'rest_api_init' ] );
12 add_action( 'admin_head', [ $this, 'admin_head' ] );
13 add_action( 'admin_footer', [ $this, 'admin_footer' ] );
14 }
15
16 public function admin_head() {
17 ?>
18 <style id="mwai-editor-assistant-base">
19 html.mwai-assistant-active {
20 transition: margin-top 0.3s ease !important;
21 }
22 html.mwai-assistant-active .interface-interface-skeleton {
23 transition: top 0.3s ease, left 0.3s ease, right 0.3s ease,
24 bottom 0.3s ease, border-radius 0.3s ease, filter 0.3s ease !important;
25 }
26 html.mwai-assistant-active #wpadminbar,
27 html.mwai-assistant-active #adminmenuwrap,
28 html.mwai-assistant-active #adminmenuback {
29 transition: transform 0.3s ease, opacity 0.3s ease !important;
30 }
31 html.mwai-assistant-active #wpcontent,
32 html.mwai-assistant-active #wpfooter {
33 transition: margin-left 0.3s ease !important;
34 }
35 html.mwai-assistant-open {
36 margin-top: 0 !important;
37 background: #f0f0f1 !important;
38 }
39 html.mwai-assistant-open body {
40 background: transparent !important;
41 }
42 html.mwai-assistant-open #wpadminbar {
43 transform: translateY(-100%);
44 opacity: 0;
45 pointer-events: none;
46 }
47 html.mwai-assistant-open #adminmenuwrap,
48 html.mwai-assistant-open #adminmenuback {
49 transform: translateX(-100%);
50 opacity: 0;
51 pointer-events: none;
52 }
53 html.mwai-assistant-open #wpcontent,
54 html.mwai-assistant-open #wpfooter {
55 margin-left: 0 !important;
56 }
57 html.mwai-assistant-open .interface-interface-skeleton {
58 position: fixed !important;
59 top: 15px !important;
60 left: 15px !important;
61 right: 410px !important;
62 bottom: 15px !important;
63 border-radius: 12px !important;
64 overflow: hidden !important;
65 filter: drop-shadow(0 0 12px rgba(0, 0, 0, 0.15)) !important;
66 }
67 html.mwai-assistant-busy .interface-interface-skeleton {
68 pointer-events: none !important;
69 opacity: 0.6 !important;
70 }
71 </style>
72 <?php
73 }
74
75 public function admin_footer() {
76 echo '<div id="mwai-editor-assistant-root"></div>';
77 }
78
79 /**
80 * Who may use the Assistant: exactly who the panel is shipped to.
81 *
82 * Meow_MWAI_Admin enqueues the admin bundle when can_access_features() OR
83 * can_access_settings() passes, and this pair has to mirror that, or a user gets a
84 * panel that answers 403. can_access_features() tests the role names 'editor' and
85 * 'administrator', so on its own it misses admin-equivalent accounts under another
86 * role name, which membership and security plugins create routinely. Those hold
87 * manage_options, well above what this feature needs. Sites that widened access with
88 * the mwai_allow_usage filter keep working, since can_access_features() applies it.
89 */
90 public function can_use_assistant() {
91 return $this->core->can_access_features() || $this->core->can_access_settings();
92 }
93
94 public function rest_api_init() {
95 // A capability, not just a nonce. check_rest_nonce() is a bare wp_verify_nonce(), and
96 // /start_session is a public endpoint that hands a valid wp_rest nonce to anonymous
97 // visitors, so a nonce alone proved nothing about who was calling. This route accepts
98 // instructions, model and envId by design (the panel owns its system prompt and has
99 // env/model pickers), which made it an unauthenticated way to spend the site owner's
100 // provider account.
101 register_rest_route( $this->namespace, '/editor/submit', [
102 'methods' => 'POST',
103 'callback' => [ $this, 'rest_submit' ],
104 'permission_callback' => [ $this, 'can_use_assistant' ],
105 ] );
106 }
107
108 public function get_internal_chatbot( $chatbot, $botId, $params ) {
109 if ( $botId !== $this->botId ) {
110 return $chatbot;
111 }
112 // Reachable from the public chats/submit endpoint too, via the reserved "mwai_"
113 // botId prefix, which is nonce-only by design. Gate it like the Workspace does with
114 // its own internal bot: nothing in the shipped UI ever asks chats/submit for this
115 // bot, the panel calls editor/submit directly.
116 if ( !$this->can_use_assistant() ) {
117 return $chatbot;
118 }
119 $envId = $params['envId'] ?? null;
120 return [
121 'botId' => $this->botId,
122 'name' => 'AI Assistant',
123 'mode' => 'chat',
124 'scope' => 'editor-assistant',
125 'envId' => $envId,
126 'instructions' => '',
127 'textInputMaxLength' => 16384,
128 'startSentence' => '',
129 'contentAware' => false,
130 ];
131 }
132
133 protected function create_response( $data, $status = 200 ) {
134 $current_nonce = $this->core->get_nonce( true );
135 $request_nonce = isset( $_SERVER['HTTP_X_WP_NONCE'] ) ? $_SERVER['HTTP_X_WP_NONCE'] : null;
136 $should_refresh = false;
137 if ( $request_nonce ) {
138 $verify = wp_verify_nonce( $request_nonce, 'wp_rest' );
139 if ( $verify === 2 ) {
140 $should_refresh = true;
141 }
142 }
143 if ( $should_refresh || ( $request_nonce && $current_nonce !== $request_nonce ) ) {
144 $data['new_token'] = $current_nonce;
145 }
146 return new WP_REST_Response( $data, $status );
147 }
148
149 protected function build_response( $reply ) {
150 return [
151 'success' => true,
152 'reply' => $reply->result,
153 'actions' => [],
154 'feedbackId' => null,
155 'usage' => $reply->usage,
156 ];
157 }
158
159 public function rest_submit( $request ) {
160 try {
161 $params = $request->get_json_params();
162 $newMessage = trim( $params['newMessage'] ?? '' );
163 $instructions = $params['instructions'] ?? '';
164 $messages = $params['messages'] ?? [];
165 $envId = $params['envId'] ?? null;
166 $model = $params['model'] ?? null;
167 $chatId = $params['chatId'] ?? null;
168
169 if ( empty( $newMessage ) ) {
170 return $this->create_response( [ 'success' => false, 'message' => 'Empty message.' ], 400 );
171 }
172
173 $query = new Meow_MWAI_Query_Text( $newMessage, 4096 );
174 $queryParams = [
175 'botId' => $this->botId,
176 'scope' => 'editor-assistant',
177 'instructions' => $instructions,
178 'messages' => $messages,
179 ];
180 if ( $envId ) {
181 $queryParams['envId'] = $envId;
182 }
183 if ( $model ) {
184 $queryParams['model'] = $model;
185 }
186 if ( $chatId ) {
187 $queryParams['chatId'] = $chatId;
188 }
189 $query->inject_params( $queryParams );
190 $query = apply_filters( 'mwai_chatbot_query', $query, $queryParams );
191
192 Meow_MWAI_Logging::log( "Editor Assistant: Submitting query: \"{$newMessage}\"" );
193 $reply = $this->core->run_query( $query );
194
195 return $this->create_response( $this->build_response( $reply ) );
196 }
197 catch ( Exception $e ) {
198 Meow_MWAI_Logging::error( 'Editor Assistant: ' . $e->getMessage() );
199 return $this->create_response( [
200 'success' => false,
201 'message' => apply_filters( 'mwai_ai_exception', $e->getMessage() ),
202 ], 500 );
203 }
204 }
205 }
206