PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 0.9.2
AI Engine – The Chatbot, AI Framework & MCP for WordPress v0.9.2
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
627 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 $debugMode = $chatStyles = $this->core->get_option( 'debug_mode' );
282
283 // OpenAI Parameters
284 $model = $atts['model'];
285 $temperature = $atts['temperature'];
286 $maxTokens = $atts['max_tokens'];
287 $apiKey = $atts['api_key'];
288
289 // Named functions
290 $onSentClickFn = "mwai_{$id}_onSendClick";
291 $addReplyFn = "mwai_{$id}_addReply";
292 $initChatBotFn = "mwai_{$id}_initChatBot";
293 $setButtonTextFn = "mwai_{$id}_setButtonText";
294
295 // Variables
296 $apiUrl = get_rest_url( null, $mode === 'images' ? 'ai-chatbot/v1/imagesbot' : 'ai-chatbot/v1/chat' );
297 $onGoingPrompt = "mwai_{$id}_onGoingPrompt";
298 $memorizedChat = "mwai_{$id}_memorizedChat";
299 $baseClasses = "mwai-chat";
300 $baseClasses .= ( $window ? " mwai-window" : "" );
301 $baseClasses .= ( !$window && $fullscreen ? " mwai-fullscreen" : "" );
302 $baseClasses .= ( $style === 'chatgpt' ? " mwai-chatgpt" : "" );
303 $baseClasses .= ( $window && !empty( $iconPosition ) ? (" mwai-" . $iconPosition) : "" );
304
305 // Output CSS
306 ob_start();
307 $style_content = "";
308 if ( $style === 'chatgpt' ) {
309 $style_content = $this->chatgpt_style( $id, $style );
310 }
311 echo apply_filters( 'mwai_chatbot_style', $style_content, $id );
312
313 // Output HTML & CSS
314 $chatStyles = $this->core->get_option( 'shortcode_chat_styles' );
315 $iconUrl = MWAI_URL . '/images/chat-green.svg';
316 if ( !empty( $icon ) ) {
317 $iconUrl = $icon;
318 }
319 else if ( !empty( $chatStyles ) && isset( $chatStyles['icon'] ) ) {
320 $url = $chatStyles['icon'];
321 $iconUrl = $this->core->isUrl( $url ) ? $url : (MWAI_URL . 'images/' . $chatStyles['icon']);
322 }
323 ?>
324 <div id="mwai-chat-<?= $id ?>" class="<?= $baseClasses ?>">
325 <?php if ( $window ) { ?>
326 <div class="mwai-open-button">
327 <?php if ( !empty( $iconText ) ) { ?>
328 <div class="mwai-icon-text"><?= $iconText ?></div>
329 <?php } ?>
330 <img width="64" height="64" src="<?= $iconUrl ?>" />
331 </div>
332 <div class="mwai-header">
333 <?php if ( $fullscreen ) { ?>
334 <div class="mwai-resize-button"></div>
335 <?php } ?>
336 <div class="mwai-close-button"></div>
337 </div>
338 <?php } ?>
339 <div class="mwai-content">
340 <div class="mwai-conversation">
341 </div>
342 <div class="mwai-input">
343 <textarea rows="1" placeholder="<?= $textInputPlaceholder ?>"></textarea>
344 <button><span><?= $textSend ?></span></button>
345 </div>
346 </div>
347 </div>
348
349 <script>
350 (function () {
351 let <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
352 let isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
353 let isWindow = <?= $window ? 'true' : 'false' ?>;
354 let isDebugMode = <?= $debugMode ? 'true' : 'false' ?>;
355 let isFullscreen = <?= $fullscreen ? 'true' : 'false' ?>;
356 let mode = '<?= $mode ?>';
357 let memorizeChat = <?= $memorizeChat ? 'true' : 'false' ?>;
358 let <?= $memorizedChat ?> = [];
359
360 if (isDebugMode) {
361 window.mwai_<?= $id ?> = {
362 onGoingPrompt: <?= $onGoingPrompt ?>,
363 memorizedChat: <?= $memorizedChat ?>,
364 parameters: {
365 mode: mode,
366 context: '<?= $context ?>',
367 isMobile: isMobile,
368 isWindow: isWindow,
369 isFullscreen: isFullscreen,
370 }
371 };
372 }
373
374 // Set button text
375 function <?= $setButtonTextFn ?>() {
376 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
377 let button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
378 if (<?= $memorizedChat ?>.length < 2) {
379 button.innerHTML = '<span><?= $textSend ?></span>';
380 }
381 else if (!input.value.length) {
382 button.innerHTML = '<span><?= $textClear ?></span>';
383 }
384 else {
385 button.innerHTML = '<span><?= $textSend ?></span>';
386 }
387 }
388
389 // Push the reply in the conversation
390 function <?= $addReplyFn ?>(text, type = 'user') {
391 var conversation = document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation');
392
393 if (memorizeChat) {
394 <?= $memorizedChat ?>.push({ text, type });
395 localStorage.setItem('mwai-chat-<?= $id ?>', JSON.stringify(<?= $memorizedChat ?>));
396 }
397
398 // If text is array, then it's image URLs. Let's create a simple gallery in HTML in $text.
399 if (Array.isArray(text)) {
400 var newText = '<div class="mwai-gallery">';
401 for (var i = 0; i < text.length; i++) {
402 newText += '<a href="' + text[i] + '" target="_blank"><img src="' + text[i] + '" />';
403 }
404 text = newText + '</div>';
405 }
406
407 var mwaiClasses = 'mwai-reply';
408 if (type === 'ai') {
409 mwaiClasses += ' mwai-ai';
410 }
411 else if (type === 'system') {
412 mwaiClasses += ' mwai-system';
413 }
414 else {
415 mwaiClasses += ' mwai-user';
416 }
417 var html = '<div class="' + mwaiClasses + '">';
418 if (type === 'ai') {
419 html += '<span class="mwai-name"><?= $aiName ?></span>';
420 }
421 else if (type === 'system') {
422 html += '<span class="mwai-name"><?= $sysName ?></span>';
423 }
424 else {
425 html += '<span class="mwai-name"><?= $userName ?></span>';
426 }
427 html += '<span class="mwai-text">' + text + '</span>';
428 html += '</div>';
429 conversation.innerHTML += html;
430 conversation.scrollTop = conversation.scrollHeight;
431 <?= $setButtonTextFn ?>();
432
433 // Syntax coloring
434 if (typeof hljs !== 'undefined') {
435 document.querySelectorAll('pre code').forEach((el) => {
436 hljs.highlightElement(el);
437 });
438 }
439 }
440
441 // Function to request the completion
442 function <?= $onSentClickFn ?>() {
443 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
444 let inputText = input.value.trim();
445
446 // Reset the conversation if empty
447 if (inputText === '') {
448 <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
449 document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation').innerHTML = '';
450 localStorage.removeItem('mwai-chat-<?= $id ?>');
451 <?= $memorizedChat ?> = [];
452 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
453 return;
454 }
455
456 // Disable the button
457 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
458 button.disabled = true;
459
460 // Add the user reply
461 <?= $addReplyFn ?>(inputText, 'user');
462 <?= $onGoingPrompt ?> += '<?= $userName ?>' + inputText + '\n';
463 input.value = '';
464 input.setAttribute('rows', 1);
465 input.disabled = true;
466
467 // Let's build the prompt depending on the "system"
468 <?= $onGoingPrompt ?> += '<?= $aiName ?>';
469 let prompt = <?= $onGoingPrompt ?>;
470 if (<?= $casuallyFineTuned ? 1 : 0 ?>) {
471 prompt = inputText + '<?= $promptEnding ?>';
472 }
473
474 // Prompt for the images
475 const data = mode === 'images' ? {
476 env: '<?= $env ?>',
477 session: '<?= $sessionId ?>',
478 prompt: inputText,
479 maxResults: <?= $maxResults ?>,
480 model: '<?= $atts['model'] ?>',
481 apiKey: '<?= $atts['api_key'] ?>',
482 // Prompt for the chat
483 } : {
484 env: '<?= $env ?>',
485 session: '<?= $sessionId ?>',
486 prompt: prompt,
487 userName: '<?= $userName ?>',
488 aiName: '<?= $aiName ?>',
489 model: '<?= $model ?>',
490 temperature: '<?= $temperature ?>',
491 maxTokens: '<?= $maxTokens ?>',
492 stop: '<?= $completionEnding ?>',
493 maxResults: '<?= $maxResults ?>',
494 apiKey: '<?= $apiKey ?>',
495 };
496 if (isDebugMode) {
497 console.log('[BOT] Sent: ', data);
498 }
499 fetch('<?= $apiUrl ?>', { method: 'POST', headers: {
500 'Content-Type': 'application/json',
501 'X-WP-Nonce': '<?= $rest_nonce ?>'
502 },
503 body: JSON.stringify(data)
504 })
505 .then(response => response.json())
506 .then(data => {
507 if (isDebugMode) {
508 console.log('[BOT] Recv: ', data);
509 }
510 if (!data.success) {
511 <?= $addReplyFn ?>(data.message, 'system');
512 }
513 else {
514 <?= $addReplyFn ?>(data.images ? data.images : data.html, 'ai');
515 <?= $onGoingPrompt ?> += data.answer + '\n';
516 }
517 button.disabled = false;
518 input.disabled = false;
519
520 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
521 if (!isMobile) {
522 input.focus();
523 }
524 })
525 .catch(error => {
526 console.error(error);
527 button.disabled = false;
528 input.disabled = false;
529 });
530 }
531
532 // Keep the textarea height in sync with the content
533 function mwaiSetTextAreaHeight(textarea, lines) {
534 var rows = textarea.getAttribute('rows');
535 if (lines !== rows) {
536 textarea.setAttribute('rows', lines > 5 ? 5 : lines);
537 }
538 }
539
540 // Init the chatbot
541 function <?= $initChatBotFn ?>() {
542 var input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
543 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
544
545 input.addEventListener('keypress', (event) => {
546 let text = event.target.value;
547 if (event.keyCode === 13 && !text.length && !event.shiftKey) {
548 event.preventDefault();
549 return;
550 }
551 if (event.keyCode === 13 && text.length && !event.shiftKey) {
552 <?= $onSentClickFn ?>();
553 }
554 });
555 input.addEventListener('keydown', (event) => {
556 var rows = input.getAttribute('rows');
557 if (event.keyCode === 13 && event.shiftKey) {
558 var lines = input.value.split('\n').length + 1;
559 mwaiSetTextAreaHeight(input, lines);
560 }
561 });
562 input.addEventListener('keyup', (event) => {
563 var rows = input.getAttribute('rows');
564 var lines = input.value.split('\n').length ;
565 mwaiSetTextAreaHeight(input, lines);
566 <?= $setButtonTextFn ?>();
567 });
568
569 button.addEventListener('click', (event) => {
570 <?= $onSentClickFn ?>();
571 });
572
573 // If window, add event listener to mwai-open-button and mwai-close-button
574 if ( isWindow ) {
575 var openButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-open-button');
576 openButton.addEventListener('click', (event) => {
577 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
578 chat.classList.add('mwai-open');
579 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
580 if (!isMobile) {
581 input.focus();
582 }
583 });
584 var closeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-close-button');
585 closeButton.addEventListener('click', (event) => {
586 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
587 chat.classList.remove('mwai-open');
588 });
589 if (isFullscreen) {
590 var resizeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-resize-button');
591 resizeButton.addEventListener('click', (event) => {
592 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
593 chat.classList.toggle('mwai-fullscreen');
594 });
595 }
596 }
597
598 // Get back the previous chat if any for the same ID
599 var chatHistory = [];
600 if (memorizeChat) {
601 chatHistory = localStorage.getItem('mwai-chat-<?= $id ?>');
602 if (chatHistory) {
603 chatHistory = JSON.parse(chatHistory);
604 chatHistory = chatHistory.filter(x => x && x.text && x.type);
605 chatHistory.forEach(x => { <?= $addReplyFn ?>(x.text, x.type) });
606 }
607 else {
608 chatHistory = [];
609 }
610 }
611 if (chatHistory.length === 0) {
612 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
613 }
614 }
615
616 // Let's go totally meoooow on this!
617 <?= $initChatBotFn ?>();
618 })();
619 </script>
620
621 <?php
622 $output = ob_get_contents();
623 ob_end_clean();
624 $output = apply_filters( 'mwai_chatbot', $output, $atts );
625 return $output;
626 }
627 }