PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.6.61
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.6.61
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 / chatbot.php
ai-engine / classes / modules Last commit date
assistants.php 3 years ago chatbot.php 3 years ago chatbot_legacy.php 3 years ago chatbot_logs.php 3 years ago discussions.php 3 years ago security.php 3 years ago
chatbot.php
303 lines
1 <?php
2
3 define( 'MWAI_CHATBOT_FRONT_PARAMS', [ 'aiName', 'userName', 'guestName', 'textSend', 'textClear',
4 'textInputPlaceholder', 'textInputMaxLength', 'textCompliance', 'startSentence', 'localMemory',
5 'themeId', 'window', 'icon', 'iconText', 'iconAlt', 'iconPosition', 'fullscreen', 'copyButton'
6 ] );
7
8 define( 'MWAI_CHATBOT_SERVER_PARAMS', [ 'id', 'env', 'mode', 'contentAware', 'embeddingsIndex', 'context',
9 'casuallyFineTuned', 'promptEnding', 'completionEnding', 'model', 'temperature', 'maxTokens',
10 'maxResults', 'apiKey', 'service'
11 ] );
12
13 class Meow_MWAI_Modules_Chatbot {
14 private $core = null;
15 private $namespace = 'mwai-bot/v1';
16 private $siteWideChatId = null;
17
18 public function __construct() {
19 global $mwai_core;
20 $this->core = $mwai_core;
21 add_shortcode( 'mwai_chatbot_v2', array( $this, 'chat_shortcode' ) );
22 add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
23 $this->siteWideChatId = $this->core->get_option( 'chatId' );
24 add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
25 }
26
27 public function register_scripts() {
28 wp_register_script( 'mwai_highlight', MWAI_URL . 'vendor/highlightjs/highlight.min.js', [], '11.7', false );
29 $physical_file = MWAI_PATH . '/app/chatbot.js';
30 $cache_buster = file_exists( $physical_file ) ? filemtime( $physical_file ) : MWAI_VERSION;
31 wp_register_script( 'mwai_chatbot', MWAI_URL . '/app/chatbot.js', [ 'wp-element' ], $cache_buster, false );
32 if ( !empty( $this->siteWideChatId ) && $this->siteWideChatId !== 'none' ) {
33 $this->enqueue_scripts();
34 add_action( 'wp_footer', array( $this, 'inject_chat' ) );
35 }
36 }
37
38 public function enqueue_scripts() {
39 wp_enqueue_script( "mwai_chatbot" );
40 if ( $this->core->get_option( 'shortcode_chat_syntax_highlighting' ) ) {
41 wp_enqueue_script( "mwai_highlight" );
42 }
43 }
44
45 public function rest_api_init() {
46 register_rest_route( $this->namespace, '/chat', array(
47 'methods' => 'POST',
48 'callback' => array( $this, 'rest_chat' ),
49 'permission_callback' => '__return_true'
50 ) );
51 }
52
53 public function basics_security_check( $params ) {
54 if ( empty( $params['newMessage'] ) ) {
55 error_log("AI Engine: The query was rejected - message was empty.");
56 return false;
57 }
58 if ( empty( $params['chatId'] ) && empty( $params['id'] ) ) {
59 error_log("AI Engine: The query was rejected - no chatId nor id was specified.");
60 return false;
61 }
62 $length = strlen( trim( $params['newMessage'] ) );
63 if ( $length < 1 || $length > ( 4096 - 512 ) ) {
64 error_log("AI Engine: The query was rejected - message was too short or too long.");
65 return false;
66 }
67 return true;
68 }
69
70 public function rest_chat( $request ) {
71 try {
72 $params = $request->get_json_params();
73 if ( !$this->basics_security_check( $params )) {
74 return new WP_REST_Response( [
75 'success' => false,
76 'message' => 'Sorry, your query has been rejected.' ], 403
77 );
78 }
79
80 // Custom Chatbot
81 if ( $params['id'] ) {
82 $chatbot = get_transient( 'mwai_custom_chatbot_' . $params['id'] );
83 }
84 // Registered Chatbot
85 else if ( $params['chatId'] ) {
86 $chatbot = $this->core->getChatbot( $params['chatId'] );
87 }
88
89 if ( !$chatbot ) {
90 error_log("AI Engine: No chatbot was found for this query.");
91 return new WP_REST_Response( [
92 'success' => false,
93 'message' => 'Sorry, your query has been rejected.' ], 403
94 );
95 }
96
97 // Create QueryText
98 $context = null;
99 if ( $chatbot['mode'] === 'images' ) {
100 $query = new Meow_MWAI_QueryImage( $params['newMessage'] );
101
102 // Handle Params
103 $newParams = [];
104 foreach ( $chatbot as $key => $value ) {
105 $newParams[$key] = $value;
106 }
107 foreach ( $params as $key => $value ) {
108 $newParams[$key] = $value;
109 }
110 $params = apply_filters( 'mwai_chatbot_params', $newParams );
111 $params['env'] = empty( $params['env'] ) ? 'chatbot' : $params['env'];
112 $query->injectParams( $params );
113 }
114 else {
115 $query = new Meow_MWAI_QueryText( $params['newMessage'], 1024 );
116 $query->setIsChat( true );
117
118 // Handle Params
119 $newParams = [];
120 foreach ( $chatbot as $key => $value ) {
121 $newParams[$key] = $value;
122 }
123 foreach ( $params as $key => $value ) {
124 $newParams[$key] = $value;
125 }
126 $params = apply_filters( 'mwai_chatbot_params', $newParams );
127 $params['env'] = empty( $params['env'] ) ? 'chatbot' : $params['env'];
128 $query->injectParams( $params );
129
130 // Takeover
131 $takeoverAnswer = apply_filters( 'mwai_chatbot_takeover', null, $query, $params );
132 if ( !empty( $takeoverAnswer ) ) {
133 return new WP_REST_Response( [ 'success' => true, 'reply' => $takeoverAnswer,
134 'html' => $takeoverAnswer, 'usage' => null ], 200 );
135 }
136
137 // Moderation
138 if ( $this->core->get_option( 'shortcode_chat_moderation' ) ) {
139 global $mwai;
140 $isFlagged = $mwai->moderationCheck( $query->prompt );
141 if ( $isFlagged ) {
142 return new WP_REST_Response( [
143 'success' => false,
144 'message' => 'Sorry, your message has been rejected by moderation.' ], 403
145 );
146 }
147 }
148
149 // Awareness & Embeddings
150 $embeddingsIndex = $params['embeddingsIndex'];
151 if ( $query->mode === 'chat' && !empty( $embeddingsIndex ) ) {
152 $context = apply_filters( 'mwai_context_search', $query, $embeddingsIndex );
153 if ( !empty( $context ) ) {
154 $content = $this->core->cleanSentences( $context['content'] );
155 $query->injectContext( $content );
156 }
157 }
158 }
159
160 // Query the AI
161 $reply = $this->core->ai->run( $query );
162 $rawText = $reply->result;
163 $extra = [];
164 if ( $context ) {
165 $extra = [ 'embeddings' => $context['embeddings'] ];
166 }
167 $html = apply_filters( 'mwai_chatbot_reply', $rawText, $query, $params, $extra );
168 if ( $this->core->get_option( 'shortcode_chat_formatting' ) ) {
169 $html = $this->core->markdown_to_html( $html );
170 }
171 return new WP_REST_Response( [
172 'success' => true,
173 'reply' => $rawText,
174 'images' => $chatbot['mode'] === 'images' ? $reply->results : null,
175 'html' => $html,
176 'usage' => $reply->usage
177 ], 200 );
178 }
179 catch ( Exception $e ) {
180 return new WP_REST_Response( [ 'success' => false, 'message' => $e->getMessage() ], 500 );
181 }
182 }
183
184 public function inject_chat() {
185 $params = $this->core->getChatbot( $this->siteWideChatId );
186 $cleanParams = [];
187 if ( !empty( $params ) ) {
188 $cleanParams['window'] = true;
189 $cleanParams['id'] = $this->siteWideChatId;
190 echo $this->chat_shortcode( $cleanParams );
191 }
192 return null;
193 }
194
195 public function chat_shortcode( $atts ) {
196 $chatbot = null;
197 $isCustom = false;
198 $chatId = null; // ID of a registered chatbot.
199 $id = null; // ID of a custom chatbot.
200 $atts = empty( $atts ) ? [] : $atts;
201
202 // If a ChatID is defined, we load it.
203 if ( isset( $atts['chat_id'] ) ) {
204 $chatId = $atts['chat_id'];
205 unset( $atts['chat_id'] );
206 $chatbot = $this->core->getChatbot( $chatId );
207 if ( !$chatbot ) {
208 return "AI Engine: Chatbot not found.";
209 }
210 }
211
212 // If no ChatID, but a ID, let's check it's actually a ChatID.
213 // If there is no ChatID for it, it means it's a custom shortcode.
214 $id = isset( $atts['id'] ) ? $atts['id'] : null;
215 if ( !empty( $id ) ) {
216 unset( $atts['id'] );
217 if ( !$chatbot ) {
218 $chatbot = $this->core->getChatbot( $id );
219 if ( $chatbot ) {
220 $isCustom = false;
221 $chatId = $id;
222 $id = null;
223 }
224 else {
225 $isCustom = true;
226 $chatId = 'default';
227 }
228 }
229 }
230
231 // We need a base chatbot anyway.
232 if ( !$chatbot ) {
233 $chatbot = $this->core->getChatbot( 'default' );
234 $chatId = 'default';
235 }
236
237 // Rename the keys of the atts into camelCase to match the internal params system.
238 $atts = array_map( function( $key, $value ) {
239 $key = str_replace( '_', ' ', $key );
240 $key = ucwords( $key );
241 $key = str_replace( ' ', '', $key );
242 $key = lcfirst( $key );
243 return [ $key => $value ];
244 }, array_keys( $atts ), $atts );
245 $atts = array_merge( ...$atts );
246
247 $frontParams = [];
248 foreach ( MWAI_CHATBOT_FRONT_PARAMS as $param ) {
249 if ( isset( $atts[$param] ) ) {
250 if ( $param === 'localMemory' ) {
251 $frontParams[$param] = $atts[$param] === 'true';
252 continue;
253 }
254 $frontParams[$param] = $atts[$param];
255 }
256 else if ( isset( $chatbot[$param] ) ) {
257 $frontParams[$param] = $chatbot[$param];
258 }
259 }
260
261 // Server Params
262 $serverParams = [];
263 foreach ( MWAI_CHATBOT_SERVER_PARAMS as $param ) {
264 if ( isset( $atts[$param] ) ) {
265 $serverParams[$param] = $atts[$param];
266 }
267 }
268 if ( count( $serverParams ) > 0 ) {
269 if ( !$isCustom ) {
270 $id = md5( json_encode( $serverParams ) );
271 $chatId = null;
272 }
273 set_transient( 'mwai_custom_chatbot_' . $id, $serverParams, 60 * 60 * 24 );
274 }
275
276 // Front Params
277 $frontSystem = [
278 'id' => $id,
279 'chatId' => $chatId,
280 'userData' => $this->core->getUserData(),
281 'sessionId' => $this->core->get_session_id(),
282 'restNonce' => wp_create_nonce( 'wp_rest' ),
283 'contextId' => get_the_ID(),
284 'pluginUrl' => MWAI_URL,
285 'restUrl' => untrailingslashit( rest_url() ),
286 'debugMode' => $this->core->get_option( 'debug_mode' ),
287 'typewriter' => $this->core->get_option( 'shortcode_chat_typewriter' ),
288 'speech_recognition' => $this->core->get_option( 'speech_recognition' ),
289 'speech_synthesis' => $this->core->get_option( 'speech_synthesis' ),
290 ];
291
292 $theme = isset( $frontParams['themeId'] ) ? $this->core->getTheme( $frontParams['themeId'] ) : null;
293 $jsonFrontParams = htmlspecialchars(json_encode($frontParams), ENT_QUOTES, 'UTF-8');
294 $jsonFrontSystem = htmlspecialchars(json_encode($frontSystem), ENT_QUOTES, 'UTF-8');
295 $jsonFrontTheme = htmlspecialchars(json_encode($theme), ENT_QUOTES, 'UTF-8');
296 //$jsonAttributes = htmlspecialchars(json_encode($atts), ENT_QUOTES, 'UTF-8');
297
298 $this->enqueue_scripts();
299 return "<div class='mwai-chatbot-container' data-params='{$jsonFrontParams}' data-system='{$jsonFrontSystem}' data-theme='{$jsonFrontTheme}'></div>";
300 }
301
302 }
303