PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 0.9.0
AI Engine – The Chatbot, AI Framework & MCP for WordPress v0.9.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
assistants.php 3 years ago chatbot-chatgpt.css 3 years ago chatbot-chatgpt.scss 3 years ago chatbot.php 3 years ago
chatbot.php
607 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, $guestName = "Guest: " ) {
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 if ( !empty( $data ) ) {
180 return $data;
181 }
182 }
183 return $guestName;
184 }
185
186 function formatUserName( $userName, $guestName = "Guest: " ) {
187 // Default avatar
188 if ( empty( $userName ) ) {
189 $user = $this->getCurrentUser();
190 if ( $user ) {
191 // Gravatar
192 $userName = '<div class="mwai-avatar"><img src="' . get_avatar_url( $user->user_email ) . '" /></div>';
193 }
194 else {
195 // Default avatar
196 $userName = '<div class="mwai-avatar mwai-svg"><img src="' . MWAI_URL . '/images/avatar-user.svg" /></div>';
197 }
198 }
199 // Custom avatar
200 else if ( $this->core->isUrl( $userName ) ) {
201 $userName = '<div class="mwai-avatar"><img src="' . $userName . '" /></div>';
202 }
203 // Placeholders
204 else {
205 $userName = $this->handlePlaceholders( $userName, $guestName );
206 }
207 return $userName;
208 }
209
210 function formatAiName( $aiName ) {
211 // Default avatar
212 if ( empty( $aiName ) ) {
213 $aiName = '<div class="mwai-avatar mwai-svg"><img src="' . MWAI_URL . '/images/avatar-ai.svg" /></div>';
214 }
215 // Custom avatar
216 else if ( $this->core->isUrl( $aiName ) ) {
217 $aiName = '<div class="mwai-avatar"><img src="' . $aiName . '" /></div>';
218 }
219 return $aiName;
220 }
221
222 function chat( $atts ) {
223 // Use the core default parameters, or the user default parameters
224 $override = $this->core->get_option( 'shortcode_chat_params_override' );
225 $defaults_params = $override ? $this->core->get_option( 'shortcode_chat_params' ) :
226 $this->core->get_option( 'shortcode_chat_default_params' );
227
228 // Give a chance to modify the default parameters one last time
229 $defaults = apply_filters( 'mwai_chatbot_params_defaults', $defaults_params );
230
231 // Make sure all the mandatory params are set
232 foreach ( $this->core->defaultChatbotParams as $key => $value ) {
233 if ( !isset( $defaults[$key] ) ) {
234 $defaults[$key] = $value;
235 }
236 }
237
238 // Override with the shortcode, and before/after filters
239 $atts = apply_filters( 'mwai_chatbot_params_before', $atts );
240 $atts = shortcode_atts( $defaults, $atts );
241 $atts = apply_filters( 'mwai_chatbot_params', $atts );
242
243 // UI Parameters
244 $aiName = addslashes( trim($atts['ai_name']) );
245 $userName = addslashes( trim($atts['user_name']) );
246 $guestName = addslashes( trim($atts['guest_name']) );
247 $sysName = addslashes( trim($atts['sys_name']) );
248 $context = addslashes( $atts['context'] );
249 $context = preg_replace( '/\v+/', "\\n", $context );
250 $textSend = addslashes( trim( $atts['text_send'] ) );
251 $textClear = addslashes( trim( $atts['text_clear'] ) );
252 $textInputPlaceholder = addslashes( trim( $atts['text_input_placeholder'] ) );
253 $startSentence = addslashes( trim( $atts['start_sentence'] ) );
254 $window = filter_var( $atts['window'], FILTER_VALIDATE_BOOLEAN );
255 $fullscreen = filter_var( $atts['fullscreen'], FILTER_VALIDATE_BOOLEAN );
256 $icon = addslashes( trim($atts['icon']) );
257 $iconText = trim($atts['icon_text']);
258 $iconPosition = addslashes( trim($atts['icon_position']) );
259 $style = $atts['style'];
260
261 // Validade & Enhance UI Parameters
262 $aiName = $this->formatAiName( $aiName );
263 $userName = $this->formatUserName( $userName, $guestName );
264
265 // Chatbot System Parameters
266 $id = empty( $atts['id'] ) ? uniqid() : $atts['id'];
267 $memorizeChat = !empty( $atts['id'] );
268 $id = preg_replace( '/[^a-zA-Z0-9]/', '', $id );
269 $env = $atts['env'];
270 $mode = $atts['mode'];
271 $maxResults = $atts['max_results'];
272 $sessionId = $this->core->get_session_id();
273 $rest_nonce = wp_create_nonce( 'wp_rest' );
274 $casuallyFineTuned = boolval( $atts['casually_fine_tuned'] );
275 $promptEnding = addslashes( trim( $atts['prompt_ending'] ) );
276 $completionEnding = addslashes( trim( $atts['completion_ending'] ) );
277 if ( $casuallyFineTuned ) {
278 $promptEnding = "\\n\\n===\\n\\n";
279 $completionEnding = "\\n\\n";
280 }
281
282 // OpenAI Parameters
283 $model = $atts['model'];
284 $temperature = $atts['temperature'];
285 $maxTokens = $atts['max_tokens'];
286 $apiKey = $atts['api_key'];
287
288 // Named functions
289 $onSentClickFn = "mwai_{$id}_onSendClick";
290 $addReplyFn = "mwai_{$id}_addReply";
291 $initChatBotFn = "mwai_{$id}_initChatBot";
292 $setButtonTextFn = "mwai_{$id}_setButtonText";
293
294 // Variables
295 $apiUrl = get_rest_url( null, $mode === 'images' ? 'ai-chatbot/v1/imagesbot' : 'ai-chatbot/v1/chat' );
296 $onGoingPrompt = "mwai_{$id}_onGoingPrompt";
297 $memorizedChat = "mwai_{$id}_memorizedChat";
298 $baseClasses = "mwai-chat";
299 $baseClasses .= ( $window ? " mwai-window" : "" );
300 $baseClasses .= ( !$window && $fullscreen ? " mwai-fullscreen" : "" );
301 $baseClasses .= ( $style === 'chatgpt' ? " mwai-chatgpt" : "" );
302 $baseClasses .= ( $window && !empty( $iconPosition ) ? (" mwai-" . $iconPosition) : "" );
303
304 // Output CSS
305 ob_start();
306 $style_content = "";
307 if ( $style === 'chatgpt' ) {
308 $style_content = $this->chatgpt_style( $id, $style );
309 }
310 echo apply_filters( 'mwai_chatbot_style', $style_content, $id );
311
312 // Output HTML & CSS
313 $chatStyles = $this->core->get_option( 'shortcode_chat_styles' );
314 $iconUrl = MWAI_URL . '/images/chat-green.svg';
315 if ( !empty( $icon ) ) {
316 $iconUrl = $icon;
317 }
318 else if ( !empty( $chatStyles ) && isset( $chatStyles['icon'] ) ) {
319 $url = $chatStyles['icon'];
320 $iconUrl = $this->core->isUrl( $url ) ? $url : (MWAI_URL . 'images/' . $chatStyles['icon']);
321 }
322 ?>
323 <div id="mwai-chat-<?= $id ?>" class="<?= $baseClasses ?>">
324 <?php if ( $window ) { ?>
325 <div class="mwai-open-button">
326 <?php if ( !empty( $iconText ) ) { ?>
327 <div class="mwai-icon-text"><?= $iconText ?></div>
328 <?php } ?>
329 <img width="64" height="64" src="<?= $iconUrl ?>" />
330 </div>
331 <div class="mwai-header">
332 <?php if ( $fullscreen ) { ?>
333 <div class="mwai-resize-button"></div>
334 <?php } ?>
335 <div class="mwai-close-button"></div>
336 </div>
337 <?php } ?>
338 <div class="mwai-content">
339 <div class="mwai-conversation">
340 </div>
341 <div class="mwai-input">
342 <textarea rows="1" placeholder="<?= $textInputPlaceholder ?>"></textarea>
343 <button><span><?= $textSend ?></span></button>
344 </div>
345 </div>
346 </div>
347
348 <script>
349 (function () {
350 let <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
351 let isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
352 let isWindow = <?= $window ? 'true' : 'false' ?>;
353 let isFullscreen = <?= $fullscreen ? 'true' : 'false' ?>;
354 let mode = '<?= $mode ?>';
355 let memorizeChat = <?= $memorizeChat ? 'true' : 'false' ?>;
356 let <?= $memorizedChat ?> = [];
357
358 // Set button text
359 function <?= $setButtonTextFn ?>() {
360 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
361 let button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
362 if (<?= $memorizedChat ?>.length < 2) {
363 button.innerHTML = '<span><?= $textSend ?></span>';
364 }
365 else if (!input.value.length) {
366 button.innerHTML = '<span><?= $textClear ?></span>';
367 }
368 else {
369 button.innerHTML = '<span><?= $textSend ?></span>';
370 }
371 }
372
373 // Push the reply in the conversation
374 function <?= $addReplyFn ?>(text, type = 'user') {
375 var conversation = document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation');
376
377 if (memorizeChat) {
378 <?= $memorizedChat ?>.push({ text, type });
379 localStorage.setItem('mwai-chat-<?= $id ?>', JSON.stringify(<?= $memorizedChat ?>));
380 }
381
382 // If text is array, then it's image URLs. Let's create a simple gallery in HTML in $text.
383 if (Array.isArray(text)) {
384 var newText = '<div class="mwai-gallery">';
385 for (var i = 0; i < text.length; i++) {
386 newText += '<a href="' + text[i] + '" target="_blank"><img src="' + text[i] + '" />';
387 }
388 text = newText + '</div>';
389 }
390
391 var mwaiClasses = 'mwai-reply';
392 if (type === 'ai') {
393 mwaiClasses += ' mwai-ai';
394 }
395 else if (type === 'system') {
396 mwaiClasses += ' mwai-system';
397 }
398 else {
399 mwaiClasses += ' mwai-user';
400 }
401 var html = '<div class="' + mwaiClasses + '">';
402 if (type === 'ai') {
403 html += '<span class="mwai-name"><?= $aiName ?></span>';
404 }
405 else if (type === 'system') {
406 html += '<span class="mwai-name"><?= $sysName ?></span>';
407 }
408 else {
409 html += '<span class="mwai-name"><?= $userName ?></span>';
410 }
411 html += '<span class="mwai-text">' + text + '</span>';
412 html += '</div>';
413 conversation.innerHTML += html;
414 conversation.scrollTop = conversation.scrollHeight;
415 <?= $setButtonTextFn ?>();
416
417 // Syntax coloring
418 if (typeof hljs !== 'undefined') {
419 document.querySelectorAll('pre code').forEach((el) => {
420 hljs.highlightElement(el);
421 });
422 }
423 }
424
425 // Function to request the completion
426 function <?= $onSentClickFn ?>() {
427 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
428 let inputText = input.value.trim();
429
430 // Reset the conversation if empty
431 if (inputText === '') {
432 <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
433 document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation').innerHTML = '';
434 localStorage.removeItem('mwai-chat-<?= $id ?>');
435 <?= $memorizedChat ?> = [];
436 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
437 return;
438 }
439
440 // Disable the button
441 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
442 button.disabled = true;
443
444 // Add the user reply
445 <?= $addReplyFn ?>(inputText, 'user');
446 <?= $onGoingPrompt ?> += '<?= $userName ?>' + inputText + '\n';
447 input.value = '';
448 input.setAttribute('rows', 1);
449 input.disabled = true;
450
451 // Let's build the prompt depending on the "system"
452 <?= $onGoingPrompt ?> += '<?= $aiName ?>';
453 let prompt = <?= $onGoingPrompt ?>;
454 if (<?= $casuallyFineTuned ? 1 : 0 ?>) {
455 prompt = inputText + '<?= $promptEnding ?>';
456 }
457
458 // Prompt for the images
459 const data = mode === 'images' ? {
460 env: '<?= $env ?>',
461 session: '<?= $sessionId ?>',
462 prompt: inputText,
463 maxResults: <?= $maxResults ?>,
464 model: '<?= $atts['model'] ?>',
465 apiKey: '<?= $atts['api_key'] ?>',
466 // Prompt for the chat
467 } : {
468 env: '<?= $env ?>',
469 session: '<?= $sessionId ?>',
470 prompt: prompt,
471 userName: '<?= $userName ?>',
472 aiName: '<?= $aiName ?>',
473 model: '<?= $model ?>',
474 temperature: '<?= $temperature ?>',
475 maxTokens: '<?= $maxTokens ?>',
476 stop: '<?= $completionEnding ?>',
477 maxResults: '<?= $maxResults ?>',
478 apiKey: '<?= $apiKey ?>',
479 };
480 console.log('[BOT] Sent: ', data);
481 fetch('<?= $apiUrl ?>', { method: 'POST', headers: {
482 'Content-Type': 'application/json',
483 'X-WP-Nonce': '<?= $rest_nonce ?>'
484 },
485 body: JSON.stringify(data)
486 })
487 .then(response => response.json())
488 .then(data => {
489 console.log('[BOT] Recv: ', data);
490 if (!data.success) {
491 <?= $addReplyFn ?>(data.message, 'system');
492 }
493 else {
494 <?= $addReplyFn ?>(data.images ? data.images : data.html, 'ai');
495 <?= $onGoingPrompt ?> += data.answer + '\n';
496 }
497 button.disabled = false;
498 input.disabled = false;
499
500 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
501 if (!isMobile) {
502 input.focus();
503 }
504 })
505 .catch(error => {
506 console.error(error);
507 button.disabled = false;
508 input.disabled = false;
509 });
510 }
511
512 // Keep the textarea height in sync with the content
513 function mwaiSetTextAreaHeight(textarea, lines) {
514 var rows = textarea.getAttribute('rows');
515 if (lines !== rows) {
516 textarea.setAttribute('rows', lines > 5 ? 5 : lines);
517 }
518 }
519
520 // Init the chatbot
521 function <?= $initChatBotFn ?>() {
522 var input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
523 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
524
525 input.addEventListener('keypress', (event) => {
526 let text = event.target.value;
527 if (event.keyCode === 13 && !text.length && !event.shiftKey) {
528 event.preventDefault();
529 return;
530 }
531 if (event.keyCode === 13 && text.length && !event.shiftKey) {
532 <?= $onSentClickFn ?>();
533 }
534 });
535 input.addEventListener('keydown', (event) => {
536 var rows = input.getAttribute('rows');
537 if (event.keyCode === 13 && event.shiftKey) {
538 var lines = input.value.split('\n').length + 1;
539 mwaiSetTextAreaHeight(input, lines);
540 }
541 });
542 input.addEventListener('keyup', (event) => {
543 var rows = input.getAttribute('rows');
544 var lines = input.value.split('\n').length ;
545 mwaiSetTextAreaHeight(input, lines);
546 <?= $setButtonTextFn ?>();
547 });
548
549 button.addEventListener('click', (event) => {
550 <?= $onSentClickFn ?>();
551 });
552
553 // If window, add event listener to mwai-open-button and mwai-close-button
554 if ( isWindow ) {
555 var openButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-open-button');
556 openButton.addEventListener('click', (event) => {
557 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
558 chat.classList.add('mwai-open');
559 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
560 if (!isMobile) {
561 input.focus();
562 }
563 });
564 var closeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-close-button');
565 closeButton.addEventListener('click', (event) => {
566 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
567 chat.classList.remove('mwai-open');
568 });
569 if (isFullscreen) {
570 var resizeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-resize-button');
571 resizeButton.addEventListener('click', (event) => {
572 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
573 chat.classList.toggle('mwai-fullscreen');
574 });
575 }
576 }
577
578 // Get back the previous chat if any for the same ID
579 var chatHistory = [];
580 if (memorizeChat) {
581 chatHistory = localStorage.getItem('mwai-chat-<?= $id ?>');
582 if (chatHistory) {
583 chatHistory = JSON.parse(chatHistory);
584 chatHistory = chatHistory.filter(x => x && x.text && x.type);
585 chatHistory.forEach(x => { <?= $addReplyFn ?>(x.text, x.type) });
586 }
587 else {
588 chatHistory = [];
589 }
590 }
591 if (chatHistory.length === 0) {
592 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
593 }
594 }
595
596 // Let's go totally meoooow on this!
597 <?= $initChatBotFn ?>();
598 })();
599 </script>
600
601 <?php
602 $output = ob_get_contents();
603 ob_end_clean();
604 $output = apply_filters( 'mwai_chatbot', $output, $atts );
605 return $output;
606 }
607 }