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