PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.3.2
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.3.2
3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.9 3.4.8 3.4.7 0.2.1 1.6.91 0.2.2 1.6.92 0.2.3 1.6.93 0.2.4 1.6.94 0.2.5 1.6.95 0.2.6 1.6.96 0.2.7 1.6.97 0.2.8 1.6.98 0.2.9 1.6.99 0.3.0 1.7.0 0.3.1 1.7.1 0.3.2 1.7.2 0.3.3 1.7.3 0.3.4 1.7.4 0.3.5 1.7.5 0.3.6 1.7.6 0.4.0 1.7.7 0.4.1 1.7.8 0.4.2 1.7.9 0.4.3 1.8.0 0.4.4 1.8.1 0.4.5 1.8.2 0.4.6 1.8.3 0.4.7 1.8.4 0.4.8 1.8.5 0.4.9 1.8.6 0.5.0 1.8.7 0.5.1 1.8.8 0.5.2 1.8.9 0.5.3 1.9.0 0.5.4 1.9.1 0.5.5 1.9.2 0.5.6 1.9.3 0.5.7 1.9.4 0.5.8 1.9.5 0.5.9 1.9.6 0.6.0 1.9.7 0.6.1 1.9.8 0.6.2 1.9.81 0.6.3 1.9.82 0.6.4 1.9.83 0.6.5 1.9.84 0.6.6 1.9.85 0.6.7 1.9.86 0.6.8 1.9.87 0.6.9 1.9.88 0.7.0 1.9.89 0.7.1 1.9.90 0.7.2 1.9.91 0.7.3 1.9.92 0.7.4 1.9.93 0.7.5 1.9.94 0.7.6 1.9.95 0.7.7 1.9.96 0.7.8 1.9.97 0.7.9 1.9.98 0.8.0 1.9.99 0.8.1 2.0.0 0.8.2 2.0.1 0.8.3 2.0.2 0.8.4 2.0.3 0.8.5 2.0.4 0.8.6 2.0.5 0.8.7 2.0.6 0.8.8 2.0.7 0.8.9 2.0.8 0.9.0 2.0.9 0.9.2 2.1.0 0.9.3 2.1.1 0.9.4 2.1.2 0.9.5 2.1.3 0.9.6 2.1.4 0.9.7 2.1.5 0.9.8 2.1.6 0.9.81 2.1.7 0.9.82 2.1.8 0.9.83 2.1.9 0.9.84 2.2.0 0.9.85 2.2.1 0.9.86 2.2.2 0.9.87 2.2.3 0.9.88 2.2.4 0.9.89 2.2.5 0.9.9 2.2.51 0.9.91 2.2.52 0.9.92 2.2.53 0.9.93 2.2.54 0.9.94 2.2.56 0.9.95 2.2.57 0.9.96 2.2.6 0.9.97 2.2.60 0.9.98 2.2.61 0.9.99 2.2.62 1.0.0 2.2.63 1.0.01 2.2.70 1.0.1 2.2.80 1.0.2 2.2.81 1.0.3 2.2.90 1.0.4 2.2.91 1.0.5 2.2.92 1.0.6 2.2.93 1.0.7 2.2.94 1.0.8 2.2.95 1.0.9 2.3.0 1.1.0 2.3.1 1.1.1 2.3.2 1.1.2 2.3.3 1.1.3 2.3.4 1.1.4 2.3.5 1.1.5 2.3.6 1.1.6 2.3.7 1.1.7 2.3.8 1.1.8 2.3.9 1.1.9 2.4.0 1.2.0 2.4.1 1.2.1 2.4.2 1.2.2 2.4.3 1.2.21 2.4.4 1.2.3 2.4.5 1.2.30 2.4.6 1.3.0 2.4.7 1.3.1 2.4.8 1.3.2 2.4.9 1.3.3 2.5.0 1.3.31 2.5.1 1.3.32 2.5.2 1.3.33 2.5.3 1.3.34 2.5.4 1.3.35 2.5.5 1.3.36 2.5.6 1.3.37 2.5.7 1.3.38 2.5.8 1.3.39 2.5.9 1.3.40 2.6.0 1.3.41 2.6.1 1.3.42 2.6.2 1.3.43 2.6.3 1.3.44 2.6.5 1.3.45 2.6.6 1.3.46 2.6.7 1.3.47 2.6.8 1.3.48 2.6.9 1.3.49 2.7.0 1.3.50 2.7.1 1.3.51 2.7.2 1.3.52 2.7.3 1.3.53 2.7.4 1.3.54 2.7.5 1.3.56 2.7.6 1.3.57 2.7.7 1.3.58 2.7.8 1.3.59 2.7.9 1.3.60 2.8.0 1.3.61 2.8.1 1.3.62 2.8.2 1.3.63 2.8.3 1.3.64 2.8.4 1.3.65 2.8.5 1.3.66 2.8.6 1.3.67 2.8.7 1.3.68 2.8.8 1.3.69 2.8.9 1.3.70 2.9.0 1.3.71 2.9.1 1.3.72 2.9.2 1.3.73 2.9.3 1.3.74 2.9.4 1.3.75 2.9.5 1.3.76 2.9.6 1.3.77 2.9.7 1.3.78 2.9.8 1.3.79 2.9.9 1.3.80 3.0.0 1.3.81 3.0.1 1.3.82 3.0.2 1.3.83 3.0.3 1.3.84 3.0.4 1.3.85 3.0.5 1.3.86 3.0.6 1.3.87 3.0.7 1.3.88 3.0.8 1.3.89 3.0.9 1.3.90 3.1.0 1.3.91 3.1.1 1.3.92 3.1.2 1.3.93 3.1.3 1.3.94 3.1.4 1.3.95 3.1.5 1.3.96 3.1.6 1.3.97 3.1.7 1.3.98 3.1.8 1.3.99 3.1.9 1.4.0 3.2.0 1.4.1 3.2.1 1.4.2 3.2.2 1.4.3 3.2.3 1.4.4 3.2.4 1.4.5 3.2.5 1.4.6 3.2.6 1.4.7 3.2.7 1.4.8 3.2.8 1.4.9 3.2.9 1.5.0 3.3.0 1.5.1 3.3.1 1.5.2 3.3.2 1.5.3 3.3.3 1.5.4 3.3.4 1.5.5 3.3.5 1.5.6 3.3.6 1.5.7 3.3.7 1.5.8 3.3.8 1.5.9 3.3.9 1.6.0 3.4.0 1.6.1 3.4.1 1.6.2 3.4.2 1.6.3 3.4.3 1.6.5 3.4.4 1.6.51 3.4.5 1.6.52 3.4.6 1.6.53 1.6.54 1.6.55 1.6.56 1.6.57 1.6.58 1.6.59 1.6.60 1.6.61 1.6.62 1.6.63 1.6.64 1.6.65 1.6.66 1.6.67 1.6.68 trunk 1.6.69 0.0.1 1.6.70 0.0.2 1.6.71 0.0.3 1.6.72 0.0.4 1.6.73 0.0.5 1.6.74 0.0.6 1.6.75 0.0.7 1.6.76 0.0.8 1.6.77 0.0.9 1.6.78 0.1.0 1.6.79 0.1.1 1.6.81 0.1.2 1.6.82 0.1.3 1.6.83 0.1.4 1.6.84 0.1.5 1.6.85 0.1.6 1.6.86 0.1.7 1.6.87 0.1.8 1.6.88 0.1.9 1.6.89 0.2.0 1.6.90
ai-engine / classes / modules / discussions.php
ai-engine / classes / modules Last commit date
chatbot.php 2 years ago discussions.php 2 years ago files.php 2 years ago security.php 2 years ago tasks.php 2 years ago utilities.php 2 years ago wand.php 2 years ago
discussions.php
321 lines
1 <?php
2
3 class Meow_MWAI_Modules_Discussions {
4 private $wpdb = null;
5 private $core = null;
6 private $table_chats = null;
7 private $db_check = false;
8 private $namespace_admin = 'mwai/v1';
9 private $namespace_ui = 'mwai-ui/v1';
10
11 public function __construct() {
12 global $wpdb;
13 global $mwai_core;
14 $this->core = $mwai_core;
15 $this->wpdb = $wpdb;
16 $this->table_chats = $wpdb->prefix . 'mwai_chats';
17
18 if ( $this->core->get_option( 'shortcode_chat_discussions' ) ) {
19 add_filter( 'mwai_chatbot_reply', [ $this, 'chatbot_reply' ], 10, 4 );
20 add_action( 'rest_api_init', [ $this, 'rest_api_init' ] );
21 }
22 }
23
24 public function rest_api_init() {
25
26 // Admin
27 register_rest_route( $this->namespace_admin, '/discussions/list', [
28 'methods' => 'POST',
29 'callback' => [ $this, 'rest_discussions_list' ],
30 'permission_callback' => [ $this->core, 'can_access_settings' ],
31 ] );
32 register_rest_route( $this->namespace_admin, '/discussions/delete', [
33 'methods' => 'POST',
34 'callback' => [ $this, 'rest_discussions_delete' ],
35 'permission_callback' => [ $this->core, 'can_access_settings' ],
36 ] );
37
38 // UI
39 register_rest_route( $this->namespace_ui, '/discussions/list', [
40 'methods' => 'POST',
41 'callback' => [ $this, 'rest_discussions_ui_list' ],
42 'permission_callback' => '__return_true'
43 ] );
44 }
45
46 function rest_discussions_list( $request ) {
47 try {
48 $params = $request->get_json_params();
49 $offset = $params['offset'];
50 $limit = $params['limit'];
51 $filters = $params['filters'];
52 $sort = $params['sort'];
53 $chats = $this->chats_query( [], $offset, $limit, $filters, $sort );
54 return new WP_REST_Response([ 'success' => true, 'total' => $chats['total'], 'chats' => $chats['rows'] ], 200 );
55 }
56 catch ( Exception $e ) {
57 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
58 }
59 }
60
61 function rest_discussions_ui_list( $request ) {
62 try {
63 $params = $request->get_json_params();
64 $offset = isset( $params['offset'] ) ? $params['offset'] : 0;
65 $limit = isset( $params['limit'] ) ? $params['limit'] : 10;
66 $botId = isset( $params['botId'] ) ? $params['botId'] : null;
67 $customId = isset( $params['customId'] ) ? $params['customId'] : null;
68
69 if ( !is_null( $customId ) ) {
70 $botId = $customId;
71 }
72
73 if ( is_null( $botId ) ) {
74 return new WP_REST_Response([ 'success' => false, 'message' => "Bot ID is required." ], 200 );
75 }
76
77 $userId = get_current_user_id();
78 if ( !$userId ) {
79 return new WP_REST_Response([ 'success' => false, 'message' => "You need to be connected." ], 200 );
80 }
81 $filters = [
82 [ 'accessor' => 'user', 'value' => $userId ],
83 [ 'accessor' => 'botId', 'value' => $botId ],
84 ];
85 $chats = $this->chats_query( [], $offset, $limit, $filters );
86 return new WP_REST_Response([ 'success' => true, 'total' => $chats['total'], 'chats' => $chats['rows'] ], 200 );
87 }
88 catch ( Exception $e ) {
89 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
90 }
91 }
92
93 function rest_discussions_delete( $request ) {
94 try {
95 $params = $request->get_json_params();
96 $chatsIds = $params['chatIds'];
97 if ( is_array( $chatsIds ) ) {
98 if ( count( $chatsIds ) === 0 ) {
99 $this->wpdb->query( "TRUNCATE TABLE $this->table_chats" );
100 }
101 foreach( $chatsIds as $chatId ) {
102 $this->wpdb->delete( $this->table_chats, [ 'chatId' => $chatId ] );
103 }
104 }
105 return new WP_REST_Response([ 'success' => true ], 200 );
106 }
107 catch ( Exception $e ) {
108 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
109 }
110 }
111
112 // Get latest discussion for the given parameter
113 function get_discussion( $botId, $chatId ) {
114 $this->check_db();
115 $chat = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT *
116 FROM $this->table_chats
117 WHERE chatId = %s AND botId = %s", $chatId, $botId
118 ), ARRAY_A );
119 if ( $chat ) {
120 $chat['messages'] = json_decode( $chat['messages'] );
121 return $chat;
122 }
123 return null;
124 }
125
126 function chats_query( $chats = [], $offset = 0, $limit = null, $filters = null, $sort = null ) {
127 $this->check_db();
128 $offset = !empty( $offset ) ? intval( $offset ) : 0;
129 $limit = !empty( $limit ) ? intval( $limit ) : 5;
130 $filters = !empty( $filters ) ? $filters : [];
131 $sort = !empty( $sort ) ? $sort : [ 'accessor' => 'updated', 'by' => 'desc' ];
132 $query = "SELECT * FROM $this->table_chats";
133
134 // Filters
135 if ( is_array( $filters ) ) {
136 $where = array();
137 foreach ( $filters as $filter ) {
138 if ( $filter['accessor'] === 'user' ) {
139 $value = esc_sql( $filter['value'] );
140 if ( is_null( $value ) || $value === '' ) {
141 continue;
142 }
143 $isIP = filter_var( $value, FILTER_VALIDATE_IP );
144 if ( $isIP ) {
145 $where[] = "ip = '{$value}'";
146 }
147 else {
148 $where[] = "userId = '{$value}'";
149 }
150 }
151 if ( $filter['accessor'] === 'botId' ) {
152 $value = esc_sql( $filter['value'] );
153 if ( is_null( $value ) || $value === '' ) {
154 continue;
155 }
156 $where[] = "botId = '{$value}'";
157 }
158 if ( $filter['accessor'] === 'preview' ) {
159 $value = $filter['value'];
160 if ( empty( $value ) ) {
161 continue;
162 }
163 $where[] = "messages LIKE '%{$value}%'";
164 }
165 }
166 if ( count( $where ) > 0 ) {
167 $query .= " WHERE " . implode( " AND ", $where );
168 }
169 }
170
171 // Count based on this query
172 $chats['total'] = $this->wpdb->get_var( "SELECT COUNT(*) FROM ($query) AS t" );
173
174 // Order by
175 $query .= " ORDER BY " . esc_sql( $sort['accessor'] ) . " " . esc_sql( $sort['by'] );
176
177 // Limits
178 if ( $limit > 0 ) {
179 $query .= " LIMIT $offset, $limit";
180 }
181
182 $chats['rows'] = $this->wpdb->get_results( $query, ARRAY_A );
183 return $chats;
184 }
185
186 public function chatbot_reply( $rawText, $query, $params, $extra ) {
187 global $mwai_core;
188 $userIp = $mwai_core->get_ip_address();
189 $userId = $mwai_core->get_user_id();
190 $botId = isset( $params['botId'] ) ? $params['botId'] : null;
191 $chatId = isset( $params['chatId'] ) ? $params['chatId'] : $query->session;
192 $customId = isset( $params['customId'] ) ? $params['customId'] : null;
193 $threadId = $query instanceof Meow_MWAI_Query_Assistant ? $query->threadId : null;
194 $storeId = $query instanceof Meow_MWAI_Query_Assistant ? $query->storeId : null;
195
196 if ( !empty( $customId ) ) {
197 $botId = $customId;
198 }
199 $newMessage = isset( $params['newMessage'] ) ? $params['newMessage'] : $query->get_message();
200
201 // If there is a file for "Vision", add it to the message
202 if ( isset( $query->filePurpose ) && $query->filePurpose === 'vision' && isset( $query->file ) ) {
203 $newMessage = "![Uploaded Image]({$query->file})\n" . $newMessage;
204 }
205
206 //$chatId = hash( 'sha256', $userIp . $userId . $clientChatId );
207 $this->check_db();
208 $chat = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM $this->table_chats WHERE chatId = %s", $chatId ) );
209 $messageExtra = [
210 'embeddings' => isset( $extra['embeddings'] ) ? $extra['embeddings'] : null
211 ];
212 $chatExtra = [
213 'session' => $query->session,
214 'model' => $query->model,
215 ];
216 if ( !empty( $query->temperature ) ) {
217 $chatExtra['temperature'] = $query->temperature;
218 }
219 if ( !empty( $query->context ) ) {
220 $chatExtra['context'] = $query->context;
221 }
222 if ( $query instanceof Meow_MWAI_Query_Assistant ) {
223 $chatExtra['assistantId'] = $query->assistantId;
224 $chatExtra['threadId'] = $query->threadId;
225 $chatExtra['storeId'] = $query->storeId;
226 }
227 if ( $chat ) {
228 $chat->messages = json_decode( $chat->messages );
229 $chat->messages[] = [ 'role' => 'user', 'content' => $newMessage ];
230 $chat->messages[] = [ 'role' => 'assistant', 'content' => $rawText, 'extra' => $messageExtra ];
231 $chat->messages = json_encode( $chat->messages );
232 $this->wpdb->update( $this->table_chats, [
233 'userId' => $userId,
234 'messages' => $chat->messages,
235 'updated' => date( 'Y-m-d H:i:s' )
236 ], [ 'id' => $chat->id ] );
237 }
238 else {
239 $chat = [
240 'userId' => $userId,
241 'ip' => $userIp,
242 'messages' => json_encode( [
243 [ 'role' => 'user', 'content' => $newMessage ],
244 [ 'role' => 'assistant', 'content' => $rawText, 'extra' => $messageExtra ]
245 ] ),
246 'extra' => json_encode( $chatExtra ),
247 'botId' => $botId,
248 'chatId' => $chatId,
249 'threadId' => $threadId,
250 'storeId' => $storeId,
251 'created' => date( 'Y-m-d H:i:s' ),
252 'updated' => date( 'Y-m-d H:i:s' )
253 ];
254 $this->wpdb->insert( $this->table_chats, $chat );
255 }
256 return $rawText;
257 }
258
259 function check_db() {
260 if ( $this->db_check ) {
261 return true;
262 }
263 $this->db_check = !( strtolower(
264 $this->wpdb->get_var( "SHOW TABLES LIKE '$this->table_chats'" ) ) != strtolower( $this->table_chats )
265 );
266 if ( !$this->db_check ) {
267 $this->create_db();
268 $this->db_check = !( strtolower(
269 $this->wpdb->get_var( "SHOW TABLES LIKE '$this->table_chats'" ) ) != strtolower( $this->table_chats )
270 );
271 }
272
273 // LATER: REMOVE THIS AFTER SEPTEMBER 2023
274 // Make sure the column "userId" and "ip "exist in the $this->table_chats table
275 $this->db_check = $this->db_check && $this->wpdb->get_var( "SHOW COLUMNS FROM $this->table_chats LIKE 'userId'" );
276 if ( !$this->db_check ) {
277 $this->wpdb->query( "ALTER TABLE $this->table_chats ADD COLUMN userId BIGINT(20) NULL" );
278 $this->wpdb->query( "ALTER TABLE $this->table_chats ADD COLUMN ip VARCHAR(64) NULL" );
279 $this->wpdb->query( "ALTER TABLE $this->table_chats ADD COLUMN botId VARCHAR(64) NULL" );
280 $this->db_check = true;
281 }
282
283 // LATER: REMOVE THIS AFTER JANUARY 2024
284 $this->db_check = $this->db_check && $this->wpdb->get_var( "SHOW COLUMNS FROM $this->table_chats LIKE 'threadId'" );
285 if ( !$this->db_check ) {
286 $this->wpdb->query( "ALTER TABLE $this->table_chats ADD COLUMN threadId VARCHAR(64) NULL" );
287 $this->db_check = true;
288 }
289
290 // LATER: REMOVE THIS AFTER SEPTEMBER 2024
291 $this->db_check = $this->db_check && $this->wpdb->get_var( "SHOW COLUMNS FROM $this->table_chats LIKE 'storeId'" );
292 if ( !$this->db_check ) {
293 $this->wpdb->query( "ALTER TABLE $this->table_chats ADD COLUMN storeId VARCHAR(64) NULL" );
294 $this->db_check = true;
295 }
296
297 return $this->db_check;
298 }
299
300 function create_db() {
301 $charset_collate = $this->wpdb->get_charset_collate();
302 $sqlLogs = "CREATE TABLE $this->table_chats (
303 id BIGINT(20) NOT NULL AUTO_INCREMENT,
304 userId BIGINT(20) NULL,
305 ip VARCHAR(64) NULL,
306 messages TEXT NOT NULL NULL,
307 extra TEXT NOT NULL NULL,
308 botId VARCHAR(64) NULL,
309 chatId VARCHAR(64) NOT NULL,
310 threadId VARCHAR(64) NULL,
311 storeId VARCHAR(64) NULL,
312 created DATETIME NOT NULL,
313 updated DATETIME NOT NULL,
314 PRIMARY KEY (id),
315 INDEX chatId (chatId)
316 ) $charset_collate;";
317 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
318 dbDelta( $sqlLogs );
319 }
320
321 }