PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 0.5.0
AI Engine – The Chatbot, AI Framework & MCP for WordPress v0.5.0
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
chatbot-chatgpt.css 3 years ago chatbot-chatgpt.scss 3 years ago chatbot.php 3 years ago
chatbot.php
534 lines
1 <?php
2
3 class Meow_MWAI_Modules_Chatbot {
4 private $core = null;
5 private $namespace = 'ai-engine/v1';
6
7 public function __construct() {
8 global $mwai_core;
9 $this->core = $mwai_core;
10 if ( is_admin() ) { return; }
11 add_shortcode( 'mwai_chat', array( $this, 'chat' ) );
12 add_shortcode( 'mwai_chatbot', array( $this, 'chat' ) );
13 add_shortcode( 'mwai_imagesbot', array( $this, 'imageschat' ) );
14 add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
15 if ( $this->core->get_option( 'shortcode_chat_inject' ) ) {
16 add_action( 'wp_body_open', array( $this, 'inject_chat' ) );
17 }
18
19 // Only for test now, but later we should probably import the JS/CSS
20 if ( $this->core->get_option( 'shortcode_chat_syntax_highlighting' ) ) {
21 wp_enqueue_script( 'mwai_chatbot',
22 '//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js', [], null, false );
23 wp_enqueue_style( 'mwai_chatbot',
24 '//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/stackoverflow-dark.min.css' );
25 }
26
27 if ( $this->core->get_option( 'shortcode_chat_styles' ) ) {
28 add_filter( 'mwai_chatbot_style', [ $this, 'apply_chat_styles' ], 10, 2 );
29 }
30
31 }
32
33 function rest_api_init() {
34 try {
35 register_rest_route( $this->namespace, '/chat', array(
36 'methods' => 'POST',
37 'callback' => array( $this, 'rest_chat' ),
38 'permission_callback' => '__return_true'
39 ) );
40 register_rest_route( $this->namespace, '/imagesbot', array(
41 'methods' => 'POST',
42 'callback' => array( $this, 'rest_imagesbot' ),
43 'permission_callback' => '__return_true'
44 ) );
45 }
46 catch ( Exception $e ) {
47 var_dump( $e );
48 }
49 }
50
51 function chatgpt_style( $id ) {
52 $css = file_get_contents( MWAI_PATH . '/classes/modules/chatbot-chatgpt.css' );
53 $css = str_replace( '#mwai-chat-id', "#mwai-chat-{$id}", $css );
54 return "<style>" . $css . "</style>";
55 }
56
57 function rest_chat( $request ) {
58 try {
59 $params = $request->get_json_params();
60 $session = $params['session'];
61 $env = $params['env'];
62 $prompt = $params['prompt'];
63 $model = $params['model'];
64 $temperature = $params['temperature'];
65 $maxTokens = intval( $params['maxTokens'] );
66 $apiKey = $params['apiKey'];
67 $stop = $params['stop'];
68 $query = new Meow_MWAI_QueryText( $prompt, 1024 );
69 if ( $model ) {
70 $query->setModel( $model );
71 }
72 if ( $temperature ) {
73 $query->setTemperature( $temperature );
74 }
75 if ( $maxTokens ) {
76 $query->setMaxTokens( $maxTokens );
77 }
78 if ( $stop ) {
79 $query->setStop( $stop );
80 }
81 if ( $apiKey ) {
82 $query->setApiKey( $apiKey );
83 }
84 if ( $env ) {
85 $query->setEnv( $env );
86 }
87 if ( $session ) {
88 $query->setSession( $session );
89 }
90 $answer = $this->core->ai->run( $query );
91 $rawText = $answer->result;
92 $html = apply_filters( 'mwai_chatbot_answer', $rawText );
93 $html = $this->core->markdown_to_html( $rawText );
94 return new WP_REST_Response([ 'success' => true, 'answer' => $rawText,
95 'html' => $html, 'usage' => $answer->usage ], 200 );
96 }
97 catch ( Exception $e ) {
98 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
99 }
100 }
101
102 function rest_imagesbot( $request ) {
103 try {
104 $params = $request->get_json_params();
105 $session = $params['session'];
106 $env = $params['env'];
107 $prompt = $params['prompt'];
108 $maxResults = $params['maxResults'];
109 $apiKey = $params['apiKey'];
110 $query = new Meow_MWAI_QueryImage( $prompt );
111 if ( $maxResults ) {
112 $query->setMaxResults( $maxResults );
113 }
114 if ( $apiKey ) {
115 $query->setApiKey( $apiKey );
116 }
117 if ( $env ) {
118 $query->setEnv( $env );
119 }
120 if ( $session ) {
121 $query->setSession( $session );
122 }
123 $answer = $this->core->ai->run( $query );
124 return new WP_REST_Response([ 'success' => true, 'images' => $answer->results, 'usage' => $answer->usage ], 200 );
125 }
126 catch ( Exception $e ) {
127 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
128 }
129 }
130
131 function apply_chat_styles( $css, $chatbotId ) {
132 $chatStyles = $this->core->get_option( 'shortcode_chat_styles' );
133 return preg_replace_callback( '/--mwai-(\w+):\s*([^;]+);/', function ( $matches ) use ($chatStyles ) {
134 if( isset( $chatStyles[$matches[1]] ) ) {
135 return "--mwai-" . $matches[1] . ": " . $chatStyles[$matches[1]] . ";";
136 }
137 return $matches[0];
138 }, $css );
139 }
140
141 function inject_chat() {
142 $params = $this->core->get_option( 'shortcode_chat_params' );
143 echo $this->chat( $params );
144 }
145
146 function imageschat( $atts ) {
147 $atts['mode'] = 'images';
148 return $this->chat( $atts );
149 }
150
151 function chat( $atts ) {
152 // Use the core default parameters, or the user default parameters
153 $override = $this->core->get_option( 'shortcode_chat_params_override' );
154 $defaults_params = $override ? $this->core->get_option( 'shortcode_chat_params' ) :
155 $this->core->get_option( 'shortcode_chat_default_params' );
156
157 // Give a chance to modify the default parameters one last time
158 $defaults = apply_filters( 'mwai_chatbot_params_defaults', $defaults_params );
159
160 // Make sure all the mandatory params are set
161 foreach ( $this->core->defaultChatbotParams as $key => $value ) {
162 if ( !isset( $defaults[$key] ) ) {
163 $defaults[$key] = $value;
164 }
165 }
166
167 // Override with the shortcode, and before/after filters
168 $atts = apply_filters( 'mwai_chatbot_params_before', $atts );
169 $atts = shortcode_atts( $defaults, $atts );
170 $atts = apply_filters( 'mwai_chatbot_params', $atts );
171
172 // UI Parameters
173 $aiName = addslashes( trim($atts['ai_name']) );
174 $userName = addslashes( trim($atts['user_name']) );
175 $sysName = addslashes( trim($atts['sys_name']) );
176 $context = addslashes( $atts['context'] );
177 $context = preg_replace( '/\v+/', "\\n", $context );
178 $textSend = addslashes( trim( $atts['text_send'] ) );
179 $textClear = addslashes( trim( $atts['text_clear'] ) );
180 $textInputPlaceholder = addslashes( trim( $atts['text_input_placeholder'] ) );
181 $startSentence = addslashes( trim( $atts['start_sentence'] ) );
182 $window = filter_var( $atts['window'], FILTER_VALIDATE_BOOLEAN );
183 $fullscreen = filter_var( $atts['fullscreen'], FILTER_VALIDATE_BOOLEAN );
184 $style = $atts['style'];
185
186 // Validade & Enhance UI Parameters
187 if ( empty( $aiName ) ) {
188 $aiName = '<div class="mwai-avatar mwai-svg"><img src="' .
189 MWAI_URL . '/images/avatar-ai.svg" /></div>';
190 }
191 if ( empty( $userName ) ) {
192 // if is connected, get gravatar from user
193 if ( is_user_logged_in() ) {
194 $user = wp_get_current_user();
195 $userName = '<div class="mwai-avatar"><img src="' .
196 get_avatar_url( $user->user_email ) . '" /></div>';
197 }
198 else {
199 $userName = '<div class="mwai-avatar mwai-svg"><img src="' .
200 MWAI_URL . '/images/avatar-user.svg" /></div>';
201 }
202 }
203
204 // Chatbot System Parameters
205 $id = empty( $atts['id'] ) ? 'mwai2' . uniqid() : $atts['id'];
206 $memorizeChat = !empty( $atts['id'] );
207 $id = preg_replace( '/[^a-zA-Z0-9]/', '', $id );
208 $env = $atts['env'];
209 $mode = $atts['mode'];
210 $maxResults = $atts['max_results'];
211 $sessionId = $this->core->get_session_id();
212 $rest_nonce = wp_create_nonce( 'wp_rest' );
213 $casuallyFineTuned = boolval( $atts['casually_fined_tuned'] );
214 $promptEnding = addslashes( trim( $atts['prompt_ending'] ) );
215 $completionEnding = addslashes( trim( $atts['completion_ending'] ) );
216 if ( $casuallyFineTuned ) {
217 $promptEnding = "\\n\\n===\\n\\n";
218 $completionEnding = "\\n\\n";
219 }
220
221 // OpenAI Parameters
222 $model = $atts['model'];
223 $temperature = $atts['temperature'];
224 $maxTokens = $atts['max_tokens'];
225 $apiKey = $atts['api_key'];
226
227 // Named functions
228 $onSentClickFn = "mwai_{$id}_onSendClick";
229 $addReplyFn = "mwai_{$id}_addReply";
230 $initChatBotFn = "mwai_{$id}_initChatBot";
231 $setButtonTextFn = "mwai_{$id}_setButtonText";
232
233 // Variables
234 $apiUrl = get_rest_url( null, $mode === 'images' ? 'ai-engine/v1/imagesbot' : 'ai-engine/v1/chat' );
235 $onGoingPrompt = "mwai_{$id}_onGoingPrompt";
236 $memorizedChat = "mwai_{$id}_memorizedChat";
237 $baseClasses = "mwai-chat";
238 $baseClasses .= ( $window ? " mwai-window" : "" );
239 $baseClasses .= ( !$window && $fullscreen ? " mwai-fullscreen" : "" );
240
241 // Output CSS
242 ob_start();
243 $style_content = "";
244 if ( $style === 'chatgpt' ) {
245 $style_content = $this->chatgpt_style( $id, $style );
246 }
247 echo apply_filters( 'mwai_chatbot_style', $style_content, $id );
248
249 // Output HTML & CSS
250 $chatStyles = $this->core->get_option( 'shortcode_chat_styles' );
251 $avatar = MWAI_URL . '/images/chat-green.svg';
252 if ( !empty( $chatStyles ) && isset( $chatStyles['avatar'] ) ) {
253 $avatar = MWAI_URL . 'images/' . $chatStyles['avatar'];
254 }
255 ?>
256 <div id="mwai-chat-<?= $id ?>" class="<?= $baseClasses ?>">
257 <?php if ( $window ) { ?>
258 <div class="mwai-open-button">
259 <img width="64" height="64" src="<?= $avatar ?>" />
260 </div>
261 <div class="mwai-header">
262 <?php if ( $window ) { ?>
263 <div class="mwai-resize-button"></div>
264 <?php } ?>
265 <div class="mwai-close-button"></div>
266 </div>
267 <?php } ?>
268 <div class="mwai-content">
269 <div class="mwai-conversation">
270 </div>
271 <div class="mwai-input">
272 <textarea rows="1" placeholder="<?= $textInputPlaceholder ?>"></textarea>
273 <button><span><?= $textSend ?></span></button>
274 </div>
275 </div>
276 </div>
277
278 <script>
279 (function () {
280 let <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
281 let isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
282 let isWindow = <?= $window ? 'true' : 'false' ?>;
283 let mode = '<?= $mode ?>';
284 let memorizeChat = <?= $memorizeChat ? 'true' : 'false' ?>;
285 let <?= $memorizedChat ?> = [];
286
287 // Set button text
288 function <?= $setButtonTextFn ?>() {
289 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
290 let button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
291 if (<?= $memorizedChat ?>.length < 2) {
292 button.innerHTML = '<span><?= $textSend ?></span>';
293 }
294 else if (!input.value.length) {
295 button.innerHTML = '<span><?= $textClear ?></span>';
296 }
297 else {
298 button.innerHTML = '<span><?= $textSend ?></span>';
299 }
300 }
301
302 // Push the reply in the conversation
303 function <?= $addReplyFn ?>(text, type = 'user') {
304 var conversation = document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation');
305
306 if (memorizeChat) {
307 <?= $memorizedChat ?>.push({ text, type });
308 localStorage.setItem('mwai-chat-<?= $id ?>', JSON.stringify(<?= $memorizedChat ?>));
309 }
310
311 // If text is array, then it's image URLs. Let's create a simple gallery in HTML in $text.
312 if (Array.isArray(text)) {
313 var newText = '<div class="mwai-gallery">';
314 for (var i = 0; i < text.length; i++) {
315 newText += '<a href="' + text[i] + '" target="_blank"><img src="' + text[i] + '" />';
316 }
317 text = newText + '</div>';
318 }
319
320 var mwaiClasses = 'mwai-reply';
321 if (type === 'ai') {
322 mwaiClasses += ' mwai-ai';
323 }
324 else if (type === 'system') {
325 mwaiClasses += ' mwai-system';
326 }
327 else {
328 mwaiClasses += ' mwai-user';
329 }
330 var html = '<div class="' + mwaiClasses + '">';
331 if (type === 'ai') {
332 html += '<span class="mwai-name"><?= $aiName ?></span>';
333 }
334 else if (type === 'system') {
335 html += '<span class="mwai-name"><?= $sysName ?></span>';
336 }
337 else {
338 html += '<span class="mwai-name"><?= $userName ?></span>';
339 }
340 html += '<span class="mwai-text">' + text + '</span>';
341 html += '</div>';
342 conversation.innerHTML += html;
343 conversation.scrollTop = conversation.scrollHeight;
344 <?= $setButtonTextFn ?>();
345
346 // Syntax coloring
347 if (typeof hljs !== 'undefined') {
348 document.querySelectorAll('pre code').forEach((el) => {
349 hljs.highlightElement(el);
350 });
351 }
352 }
353
354 // Function to request the completion
355 function <?= $onSentClickFn ?>() {
356 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
357 let inputText = input.value.trim();
358
359 // Reset the conversation if empty
360 if (inputText === '') {
361 <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
362 document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation').innerHTML = '';
363 localStorage.removeItem('mwai-chat-<?= $id ?>');
364 <?= $memorizedChat ?> = [];
365 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
366 return;
367 }
368
369 // Disable the button
370 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
371 button.disabled = true;
372
373 // Add the user reply
374 <?= $addReplyFn ?>(inputText, 'user');
375 <?= $onGoingPrompt ?> += '<?= $userName ?>' + inputText + '\n';
376 input.value = '';
377 input.setAttribute('rows', 1);
378 input.disabled = true;
379
380 // Let's build the prompt depending on the "system"
381 <?= $onGoingPrompt ?> += '<?= $aiName ?>';
382 let prompt = <?= $onGoingPrompt ?>;
383 if (<?= $casuallyFineTuned ? 1 : 0 ?>) {
384 prompt = inputText + '<?= $promptEnding ?>';
385 }
386
387 // Prompt for the images
388 const data = mode === 'images' ? {
389 env: '<?= $env ?>',
390 session: '<?= $sessionId ?>',
391 prompt: inputText,
392 maxResults: <?= $maxResults ?>,
393 model: '<?= $atts['model'] ?>',
394 apiKey: '<?= $atts['api_key'] ?>',
395 // Prompt for the chat
396 } : {
397 env: '<?= $env ?>',
398 session: '<?= $sessionId ?>',
399 prompt: prompt,
400 userName: '<?= $userName ?>',
401 aiName: '<?= $aiName ?>',
402 model: '<?= $model ?>',
403 temperature: '<?= $temperature ?>',
404 maxTokens: '<?= $maxTokens ?>',
405 stop: '<?= $completionEnding ?>',
406 maxResults: '<?= $maxResults ?>',
407 apiKey: '<?= $apiKey ?>',
408 };
409 console.log('[BOT] Sent: ', data);
410 fetch('<?= $apiUrl ?>', { method: 'POST', headers: {
411 'Content-Type': 'application/json',
412 'X-WP-Nonce': '<?= $rest_nonce ?>'
413 },
414 body: JSON.stringify(data)
415 })
416 .then(response => response.json())
417 .then(data => {
418 console.log('[BOT] Recv: ', data);
419 if (!data.success) {
420 <?= $addReplyFn ?>(data.message, 'system');
421 }
422 else {
423 <?= $addReplyFn ?>(data.images ? data.images : data.html, 'ai');
424 <?= $onGoingPrompt ?> += data.answer + '\n';
425 }
426 button.disabled = false;
427 input.disabled = false;
428
429 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
430 if (!isMobile) {
431 input.focus();
432 }
433 })
434 .catch(error => {
435 console.error(error);
436 button.disabled = false;
437 input.disabled = false;
438 });
439 }
440
441 // Keep the textarea height in sync with the content
442 function mwaiSetTextAreaHeight(textarea, lines) {
443 var rows = textarea.getAttribute('rows');
444 if (lines !== rows) {
445 textarea.setAttribute('rows', lines > 5 ? 5 : lines);
446 }
447 }
448
449 // Init the chatbot
450 function <?= $initChatBotFn ?>() {
451 var input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
452 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
453
454 input.addEventListener('keypress', (event) => {
455 let text = event.target.value;
456 if (event.keyCode === 13 && !text.length && !event.shiftKey) {
457 event.preventDefault();
458 return;
459 }
460 if (event.keyCode === 13 && text.length && !event.shiftKey) {
461 <?= $onSentClickFn ?>();
462 }
463 });
464 input.addEventListener('keydown', (event) => {
465 var rows = input.getAttribute('rows');
466 if (event.keyCode === 13 && event.shiftKey) {
467 var lines = input.value.split('\n').length + 1;
468 mwaiSetTextAreaHeight(input, lines);
469 }
470 });
471 input.addEventListener('keyup', (event) => {
472 var rows = input.getAttribute('rows');
473 var lines = input.value.split('\n').length ;
474 mwaiSetTextAreaHeight(input, lines);
475 <?= $setButtonTextFn ?>();
476 });
477
478 button.addEventListener('click', (event) => {
479 <?= $onSentClickFn ?>();
480 });
481
482 // If window, add event listener to mwai-open-button and mwai-close-button
483 if ( isWindow ) {
484 var openButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-open-button');
485 openButton.addEventListener('click', (event) => {
486 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
487 chat.classList.add('mwai-open');
488 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
489 if (!isMobile) {
490 input.focus();
491 }
492 });
493 var closeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-close-button');
494 closeButton.addEventListener('click', (event) => {
495 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
496 chat.classList.remove('mwai-open');
497 });
498 var resizeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-resize-button');
499 resizeButton.addEventListener('click', (event) => {
500 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
501 chat.classList.toggle('mwai-fullscreen');
502 });
503 }
504
505 // Get back the previous chat if any for the same ID
506 var chatHistory = [];
507 if (memorizeChat) {
508 chatHistory = localStorage.getItem('mwai-chat-<?= $id ?>');
509 if (chatHistory) {
510 chatHistory = JSON.parse(chatHistory);
511 chatHistory = chatHistory.filter(x => x && x.text && x.type);
512 chatHistory.forEach(x => { <?= $addReplyFn ?>(x.text, x.type) });
513 }
514 else {
515 chatHistory = [];
516 }
517 }
518 if (chatHistory.length === 0) {
519 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
520 }
521 }
522
523 // Let's go totally meoooow on this!
524 <?= $initChatBotFn ?>();
525 })();
526 </script>
527
528 <?php
529 $output = ob_get_contents();
530 ob_end_clean();
531 $output = apply_filters( 'mwai_chatbot', $output, $atts );
532 return $output;
533 }
534 }