PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 0.5.3
AI Engine – The Chatbot, AI Framework & MCP for WordPress v0.5.3
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
537 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 ( $fullscreen ) { ?>
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 isFullscreen = <?= $fullscreen ? 'true' : 'false' ?>;
284 let mode = '<?= $mode ?>';
285 let memorizeChat = <?= $memorizeChat ? 'true' : 'false' ?>;
286 let <?= $memorizedChat ?> = [];
287
288 // Set button text
289 function <?= $setButtonTextFn ?>() {
290 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
291 let button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
292 if (<?= $memorizedChat ?>.length < 2) {
293 button.innerHTML = '<span><?= $textSend ?></span>';
294 }
295 else if (!input.value.length) {
296 button.innerHTML = '<span><?= $textClear ?></span>';
297 }
298 else {
299 button.innerHTML = '<span><?= $textSend ?></span>';
300 }
301 }
302
303 // Push the reply in the conversation
304 function <?= $addReplyFn ?>(text, type = 'user') {
305 var conversation = document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation');
306
307 if (memorizeChat) {
308 <?= $memorizedChat ?>.push({ text, type });
309 localStorage.setItem('mwai-chat-<?= $id ?>', JSON.stringify(<?= $memorizedChat ?>));
310 }
311
312 // If text is array, then it's image URLs. Let's create a simple gallery in HTML in $text.
313 if (Array.isArray(text)) {
314 var newText = '<div class="mwai-gallery">';
315 for (var i = 0; i < text.length; i++) {
316 newText += '<a href="' + text[i] + '" target="_blank"><img src="' + text[i] + '" />';
317 }
318 text = newText + '</div>';
319 }
320
321 var mwaiClasses = 'mwai-reply';
322 if (type === 'ai') {
323 mwaiClasses += ' mwai-ai';
324 }
325 else if (type === 'system') {
326 mwaiClasses += ' mwai-system';
327 }
328 else {
329 mwaiClasses += ' mwai-user';
330 }
331 var html = '<div class="' + mwaiClasses + '">';
332 if (type === 'ai') {
333 html += '<span class="mwai-name"><?= $aiName ?></span>';
334 }
335 else if (type === 'system') {
336 html += '<span class="mwai-name"><?= $sysName ?></span>';
337 }
338 else {
339 html += '<span class="mwai-name"><?= $userName ?></span>';
340 }
341 html += '<span class="mwai-text">' + text + '</span>';
342 html += '</div>';
343 conversation.innerHTML += html;
344 conversation.scrollTop = conversation.scrollHeight;
345 <?= $setButtonTextFn ?>();
346
347 // Syntax coloring
348 if (typeof hljs !== 'undefined') {
349 document.querySelectorAll('pre code').forEach((el) => {
350 hljs.highlightElement(el);
351 });
352 }
353 }
354
355 // Function to request the completion
356 function <?= $onSentClickFn ?>() {
357 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
358 let inputText = input.value.trim();
359
360 // Reset the conversation if empty
361 if (inputText === '') {
362 <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
363 document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation').innerHTML = '';
364 localStorage.removeItem('mwai-chat-<?= $id ?>');
365 <?= $memorizedChat ?> = [];
366 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
367 return;
368 }
369
370 // Disable the button
371 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
372 button.disabled = true;
373
374 // Add the user reply
375 <?= $addReplyFn ?>(inputText, 'user');
376 <?= $onGoingPrompt ?> += '<?= $userName ?>' + inputText + '\n';
377 input.value = '';
378 input.setAttribute('rows', 1);
379 input.disabled = true;
380
381 // Let's build the prompt depending on the "system"
382 <?= $onGoingPrompt ?> += '<?= $aiName ?>';
383 let prompt = <?= $onGoingPrompt ?>;
384 if (<?= $casuallyFineTuned ? 1 : 0 ?>) {
385 prompt = inputText + '<?= $promptEnding ?>';
386 }
387
388 // Prompt for the images
389 const data = mode === 'images' ? {
390 env: '<?= $env ?>',
391 session: '<?= $sessionId ?>',
392 prompt: inputText,
393 maxResults: <?= $maxResults ?>,
394 model: '<?= $atts['model'] ?>',
395 apiKey: '<?= $atts['api_key'] ?>',
396 // Prompt for the chat
397 } : {
398 env: '<?= $env ?>',
399 session: '<?= $sessionId ?>',
400 prompt: prompt,
401 userName: '<?= $userName ?>',
402 aiName: '<?= $aiName ?>',
403 model: '<?= $model ?>',
404 temperature: '<?= $temperature ?>',
405 maxTokens: '<?= $maxTokens ?>',
406 stop: '<?= $completionEnding ?>',
407 maxResults: '<?= $maxResults ?>',
408 apiKey: '<?= $apiKey ?>',
409 };
410 console.log('[BOT] Sent: ', data);
411 fetch('<?= $apiUrl ?>', { method: 'POST', headers: {
412 'Content-Type': 'application/json',
413 'X-WP-Nonce': '<?= $rest_nonce ?>'
414 },
415 body: JSON.stringify(data)
416 })
417 .then(response => response.json())
418 .then(data => {
419 console.log('[BOT] Recv: ', data);
420 if (!data.success) {
421 <?= $addReplyFn ?>(data.message, 'system');
422 }
423 else {
424 <?= $addReplyFn ?>(data.images ? data.images : data.html, 'ai');
425 <?= $onGoingPrompt ?> += data.answer + '\n';
426 }
427 button.disabled = false;
428 input.disabled = false;
429
430 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
431 if (!isMobile) {
432 input.focus();
433 }
434 })
435 .catch(error => {
436 console.error(error);
437 button.disabled = false;
438 input.disabled = false;
439 });
440 }
441
442 // Keep the textarea height in sync with the content
443 function mwaiSetTextAreaHeight(textarea, lines) {
444 var rows = textarea.getAttribute('rows');
445 if (lines !== rows) {
446 textarea.setAttribute('rows', lines > 5 ? 5 : lines);
447 }
448 }
449
450 // Init the chatbot
451 function <?= $initChatBotFn ?>() {
452 var input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
453 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
454
455 input.addEventListener('keypress', (event) => {
456 let text = event.target.value;
457 if (event.keyCode === 13 && !text.length && !event.shiftKey) {
458 event.preventDefault();
459 return;
460 }
461 if (event.keyCode === 13 && text.length && !event.shiftKey) {
462 <?= $onSentClickFn ?>();
463 }
464 });
465 input.addEventListener('keydown', (event) => {
466 var rows = input.getAttribute('rows');
467 if (event.keyCode === 13 && event.shiftKey) {
468 var lines = input.value.split('\n').length + 1;
469 mwaiSetTextAreaHeight(input, lines);
470 }
471 });
472 input.addEventListener('keyup', (event) => {
473 var rows = input.getAttribute('rows');
474 var lines = input.value.split('\n').length ;
475 mwaiSetTextAreaHeight(input, lines);
476 <?= $setButtonTextFn ?>();
477 });
478
479 button.addEventListener('click', (event) => {
480 <?= $onSentClickFn ?>();
481 });
482
483 // If window, add event listener to mwai-open-button and mwai-close-button
484 if ( isWindow ) {
485 var openButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-open-button');
486 openButton.addEventListener('click', (event) => {
487 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
488 chat.classList.add('mwai-open');
489 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
490 if (!isMobile) {
491 input.focus();
492 }
493 });
494 var closeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-close-button');
495 closeButton.addEventListener('click', (event) => {
496 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
497 chat.classList.remove('mwai-open');
498 });
499 if (isFullscreen) {
500 var resizeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-resize-button');
501 resizeButton.addEventListener('click', (event) => {
502 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
503 chat.classList.toggle('mwai-fullscreen');
504 });
505 }
506 }
507
508 // Get back the previous chat if any for the same ID
509 var chatHistory = [];
510 if (memorizeChat) {
511 chatHistory = localStorage.getItem('mwai-chat-<?= $id ?>');
512 if (chatHistory) {
513 chatHistory = JSON.parse(chatHistory);
514 chatHistory = chatHistory.filter(x => x && x.text && x.type);
515 chatHistory.forEach(x => { <?= $addReplyFn ?>(x.text, x.type) });
516 }
517 else {
518 chatHistory = [];
519 }
520 }
521 if (chatHistory.length === 0) {
522 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
523 }
524 }
525
526 // Let's go totally meoooow on this!
527 <?= $initChatBotFn ?>();
528 })();
529 </script>
530
531 <?php
532 $output = ob_get_contents();
533 ob_end_clean();
534 $output = apply_filters( 'mwai_chatbot', $output, $atts );
535 return $output;
536 }
537 }