PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.6.65
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.6.65
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
304 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
172 return new WP_REST_Response( [
173 'success' => true,
174 'reply' => $rawText,
175 'images' => $reply->getType() === 'images' ? $reply->results : null,
176 'html' => $html,
177 'usage' => $reply->usage
178 ], 200 );
179 }
180 catch ( Exception $e ) {
181 return new WP_REST_Response( [ 'success' => false, 'message' => $e->getMessage() ], 500 );
182 }
183 }
184
185 public function inject_chat() {
186 $params = $this->core->getChatbot( $this->siteWideChatId );
187 $cleanParams = [];
188 if ( !empty( $params ) ) {
189 $cleanParams['window'] = true;
190 $cleanParams['id'] = $this->siteWideChatId;
191 echo $this->chat_shortcode( $cleanParams );
192 }
193 return null;
194 }
195
196 public function chat_shortcode( $atts ) {
197 $chatbot = null;
198 $isCustom = false;
199 $chatId = null; // ID of a registered chatbot.
200 $id = null; // ID of a custom chatbot.
201 $atts = empty( $atts ) ? [] : $atts;
202
203 // If a ChatID is defined, we load it.
204 if ( isset( $atts['chat_id'] ) ) {
205 $chatId = $atts['chat_id'];
206 unset( $atts['chat_id'] );
207 $chatbot = $this->core->getChatbot( $chatId );
208 if ( !$chatbot ) {
209 return "AI Engine: Chatbot not found.";
210 }
211 }
212
213 // If no ChatID, but a ID, let's check it's actually a ChatID.
214 // If there is no ChatID for it, it means it's a custom shortcode.
215 $id = isset( $atts['id'] ) ? $atts['id'] : null;
216 if ( !empty( $id ) ) {
217 unset( $atts['id'] );
218 if ( !$chatbot ) {
219 $chatbot = $this->core->getChatbot( $id );
220 if ( $chatbot ) {
221 $isCustom = false;
222 $chatId = $id;
223 $id = null;
224 }
225 else {
226 $isCustom = true;
227 $chatId = 'default';
228 }
229 }
230 }
231
232 // We need a base chatbot anyway.
233 if ( !$chatbot ) {
234 $chatbot = $this->core->getChatbot( 'default' );
235 $chatId = 'default';
236 }
237
238 // Rename the keys of the atts into camelCase to match the internal params system.
239 $atts = array_map( function( $key, $value ) {
240 $key = str_replace( '_', ' ', $key );
241 $key = ucwords( $key );
242 $key = str_replace( ' ', '', $key );
243 $key = lcfirst( $key );
244 return [ $key => $value ];
245 }, array_keys( $atts ), $atts );
246 $atts = array_merge( ...$atts );
247
248 $frontParams = [];
249 foreach ( MWAI_CHATBOT_FRONT_PARAMS as $param ) {
250 if ( isset( $atts[$param] ) ) {
251 if ( $param === 'localMemory' ) {
252 $frontParams[$param] = $atts[$param] === 'true';
253 continue;
254 }
255 $frontParams[$param] = $atts[$param];
256 }
257 else if ( isset( $chatbot[$param] ) ) {
258 $frontParams[$param] = $chatbot[$param];
259 }
260 }
261
262 // Server Params
263 $serverParams = [];
264 foreach ( MWAI_CHATBOT_SERVER_PARAMS as $param ) {
265 if ( isset( $atts[$param] ) ) {
266 $serverParams[$param] = $atts[$param];
267 }
268 }
269 if ( count( $serverParams ) > 0 ) {
270 if ( !$isCustom ) {
271 $id = md5( json_encode( $serverParams ) );
272 $chatId = null;
273 }
274 set_transient( 'mwai_custom_chatbot_' . $id, $serverParams, 60 * 60 * 24 );
275 }
276
277 // Front Params
278 $frontSystem = [
279 'id' => $id,
280 'chatId' => $chatId,
281 'userData' => $this->core->getUserData(),
282 'sessionId' => $this->core->get_session_id(),
283 'restNonce' => wp_create_nonce( 'wp_rest' ),
284 'contextId' => get_the_ID(),
285 'pluginUrl' => MWAI_URL,
286 'restUrl' => untrailingslashit( rest_url() ),
287 'debugMode' => $this->core->get_option( 'debug_mode' ),
288 'typewriter' => $this->core->get_option( 'shortcode_chat_typewriter' ),
289 'speech_recognition' => $this->core->get_option( 'speech_recognition' ),
290 'speech_synthesis' => $this->core->get_option( 'speech_synthesis' ),
291 ];
292
293 $theme = isset( $frontParams['themeId'] ) ? $this->core->getTheme( $frontParams['themeId'] ) : null;
294 $jsonFrontParams = htmlspecialchars(json_encode($frontParams), ENT_QUOTES, 'UTF-8');
295 $jsonFrontSystem = htmlspecialchars(json_encode($frontSystem), ENT_QUOTES, 'UTF-8');
296 $jsonFrontTheme = htmlspecialchars(json_encode($theme), ENT_QUOTES, 'UTF-8');
297 //$jsonAttributes = htmlspecialchars(json_encode($atts), ENT_QUOTES, 'UTF-8');
298
299 $this->enqueue_scripts();
300 return "<div class='mwai-chatbot-container' data-params='{$jsonFrontParams}' data-system='{$jsonFrontSystem}' data-theme='{$jsonFrontTheme}'></div>";
301 }
302
303 }
304