PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 0.3.5
AI Engine – The Chatbot, AI Framework & MCP for WordPress v0.3.5
3.5.9 3.5.8 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 contentaware.php 3 years ago imagesbot.php 3 years ago
chatbot.php
374 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_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
14 if ( $this->core->get_option( 'shortcode_chat_inject' ) ) {
15 add_action( 'wp_body_open', array( $this, 'inject_chat' ) );
16 }
17
18 // Only for test now, but later we should probably import the JS/CSS
19 if ( $this->core->get_option( 'shortcode_chat_syntax_highlighting' ) ) {
20 wp_enqueue_script( 'mwai_chatbot',
21 '//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js', [], null, false );
22 wp_enqueue_style( 'mwai_chatbot',
23 '//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/stackoverflow-dark.min.css' );
24 }
25 }
26
27 function rest_api_init() {
28 try {
29 register_rest_route( $this->namespace, '/chat', array(
30 'methods' => 'POST',
31 'callback' => array( $this, 'rest_chat' ),
32 'permission_callback' => '__return_true'
33 ) );
34 }
35 catch ( Exception $e ) {
36 var_dump( $e );
37 }
38 }
39
40 function chatgpt_style( $id ) {
41 $css = file_get_contents( MWAI_PATH . '/classes/modules/chatbot-chatgpt.css' );
42 $css = str_replace( '#mwai-chat-id', "#mwai-chat-{$id}", $css );
43 return "<style>" . $css . "</style>";
44 }
45
46 function rest_chat( $request ) {
47 try {
48 $params = $request->get_json_params();
49 $session = $params['session'];
50 $env = $params['env'];
51 $prompt = $params['prompt'];
52 $model = $params['model'];
53 $temperature = $params['temperature'];
54 $maxTokens = intval( $params['maxTokens'] );
55 $apiKey = $params['apiKey'];
56 $stop = $params['stop'];
57 $query = new Meow_MWAI_QueryText( $prompt, 1024 );
58 if ( $session ) {
59 $query->setSession( $session );
60 }
61 if ( $model ) {
62 $query->setModel( $model );
63 }
64 if ( $temperature ) {
65 $query->setTemperature( $temperature );
66 }
67 if ( $maxTokens ) {
68 $query->setMaxTokens( $maxTokens );
69 }
70 if ( $stop ) {
71 $query->setStop( $stop );
72 }
73 if ( $apiKey ) {
74 $query->setApiKey( $apiKey );
75 }
76 if ( $env ) {
77 $query->setEnv( $env );
78 }
79 $answer = $this->core->ai->run( $query );
80 $rawText = $answer->result;
81 $html = apply_filters( 'mwai_chatbot_answer', $rawText );
82 $html = $this->core->markdown_to_html( $rawText );
83 return new WP_REST_Response([ 'success' => true, 'answer' => $rawText,
84 'html' => $html, 'usage' => $answer->usage ], 200 );
85 }
86 catch ( Exception $e ) {
87 return new WP_REST_Response([ 'success' => false, 'message' => $e->getMessage() ], 500 );
88 }
89 }
90
91 function inject_chat() {
92 $params = $this->core->get_option( 'shortcode_chat_params' );
93 echo $this->chat( $params );
94 }
95
96 function chat( $atts ) {
97 // Use the core default parameters, or the user default parameters
98 $override = $this->core->get_option( 'shortcode_chat_params_override' );
99 $defaults_params = $override ? $this->core->get_option( 'shortcode_chat_params' ) :
100 $this->core->get_option( 'shortcode_chat_default_params' );
101 $defaults_params['id'] = uniqid();
102
103 // Give a chance to modify the default parameters one last time
104 $defaults = apply_filters( 'mwai_chatbot_params_defaults', $defaults_params );
105
106 // Make sure all the mandatory params are set
107 foreach ( $this->core->defaultChatbotParams as $key => $value ) {
108 if ( !isset( $defaults[$key] ) ) {
109 $defaults[$key] = $value;
110 }
111 }
112
113 // Override with the shortcode, and before/after filters
114 $atts = apply_filters( 'mwai_chatbot_params_before', $atts );
115 $atts = shortcode_atts( $defaults, $atts );
116 $atts = apply_filters( 'mwai_chatbot_params', $atts );
117 $apiUrl = get_rest_url( null, 'ai-engine/v1/chat' );
118
119 // UI Parameters
120 $aiName = addslashes( trim($atts['ai_name']) );
121 $userName = addslashes( trim($atts['user_name']) );
122 $sysName = addslashes( trim($atts['sys_name']) );
123 $context = addslashes( $atts['context'] );
124 $textSend = addslashes( trim( $atts['text_send'] ) );
125 $textInputPlaceholder = addslashes( trim( $atts['text_input_placeholder'] ) );
126 $startSentence = addslashes( trim( $atts['start_sentence'] ) );
127 $window = filter_var( $atts['window'], FILTER_VALIDATE_BOOLEAN );
128 $fullscreen = filter_var( $atts['fullscreen'], FILTER_VALIDATE_BOOLEAN );
129 $style = $atts['style'];
130
131 // Chatbot System Parameters
132 $id = $atts['id'];
133 $env = $atts['env'];
134 $rest_nonce = wp_create_nonce( 'wp_rest' );
135 $casuallyFineTuned = boolval( $atts['casually_fined_tuned'] );
136 $promptEnding = addslashes( trim( $atts['prompt_ending'] ) );
137 $completionEnding = addslashes( trim( $atts['completion_ending'] ) );
138 if ( $casuallyFineTuned ) {
139 $promptEnding = "\\n\\n===\\n\\n";
140 $completionEnding = "\\n\\n";
141 }
142
143 // OpenAI Parameters
144 $model = $atts['model'];
145 $temperature = $atts['temperature'];
146 $maxTokens = $atts['max_tokens'];
147 $apiKey = $atts['api_key'];
148
149 // Named functions
150 $onSentClickFn = "mwai_{$id}_onSendClick";
151 $addReplyFn = "mwai_{$id}_addReply";
152 $initChatBotFn = "mwai_{$id}_initChatBot";
153
154 // Variables
155 $onGoingPrompt = "mwai_{$id}_onGoingPrompt";
156 $baseClasses = "mwai-chat";
157 $baseClasses .= ( $window ? " mwai-window" : "" );
158 $baseClasses .= ( !$window && $fullscreen ? " mwai-fullscreen" : "" );
159
160 // Output CSS
161 ob_start();
162 $style_content = "";
163 if ( $style === 'chatgpt' ) {
164 $style_content = $this->chatgpt_style( $id, $style );
165 }
166 echo apply_filters( 'mwai_chatbot_style', $style_content, $id );
167
168 // Output HTML & CSS
169 ?>
170 <div id="mwai-chat-<?= $id ?>" class="<?= $baseClasses ?>">
171 <?php if ( $window ) { ?>
172 <div class="mwai-open-button">
173 <img width="64" height="64" src="<?= plugins_url( '../../images/chat-green.svg', __FILE__ ) ?>" />
174 </div>
175 <div class="mwai-header">
176 <?php if ( $window ) { ?>
177 <div class="mwai-resize-button"></div>
178 <?php } ?>
179 <div class="mwai-close-button"></div>
180 </div>
181 <?php } ?>
182 <div class="mwai-content">
183 <div class="mwai-conversation">
184 </div>
185 <div class="mwai-input">
186 <textarea rows="1" placeholder="<?= $textInputPlaceholder ?>"></textarea>
187 <button><span><?= $textSend ?></span></button>
188 </div>
189 </div>
190 </div>
191
192 <script>
193 var <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
194 var isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
195 var isWindow = <?= $window ? 'true' : 'false' ?>;
196
197 // Push the reply in the conversation
198 function <?= $addReplyFn ?>(text, type = 'user') {
199 var conversation = document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation');
200 var mwaiClasses = 'mwai-reply';
201 if (type === 'ai') {
202 mwaiClasses += ' mwai-ai';
203 }
204 else if (type === 'system') {
205 mwaiClasses += ' mwai-system';
206 }
207 else {
208 mwaiClasses += ' mwai-user';
209 }
210 var html = '<div class="' + mwaiClasses + '">';
211 if (type === 'ai') {
212 html += '<span class="mwai-name"><?= $aiName ?></span>';
213 }
214 else if (type === 'system') {
215 html += '<span class="mwai-name"><?= $sysName ?></span>';
216 }
217 else {
218 html += '<span class="mwai-name"><?= $userName ?></span>';
219 }
220 html += '<span class="mwai-text">' + text + '</span>';
221 html += '</div>';
222 conversation.innerHTML += html;
223 conversation.scrollTop = conversation.scrollHeight;
224
225 // Syntax coloring
226 if (typeof hljs !== 'undefined') {
227 document.querySelectorAll('pre code').forEach((el) => {
228 hljs.highlightElement(el);
229 });
230 }
231 }
232
233 // Function to request the completion
234 function <?= $onSentClickFn ?>() {
235 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
236 let inputText = input.value.trim();
237
238 if (inputText === '') {
239 return;
240 }
241
242 // Disable the button
243 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
244 button.disabled = true;
245
246 // Add the user reply
247 <?= $addReplyFn ?>(inputText, 'user');
248 <?= $onGoingPrompt ?> += '<?= $userName ?>' + inputText + '\n';
249 input.value = '';
250 input.setAttribute('rows', 1);
251 input.disabled = true;
252
253 // Let's build the prompt depending on the "system"
254 <?= $onGoingPrompt ?> += '<?= $aiName ?>';
255 let prompt = <?= $onGoingPrompt ?>;
256 if (<?= $casuallyFineTuned ? 1 : 0 ?>) {
257 prompt = inputText + '<?= $promptEnding ?>';
258 }
259
260 // Request the completion
261 const data = {
262 env: '<?= $env ?>',
263 session: '<?= $id ?>',
264 prompt: prompt,
265 userName: '<?= $userName ?>',
266 aiName: '<?= $aiName ?>',
267 model: '<?= $model ?>',
268 temperature: '<?= $temperature ?>',
269 maxTokens: '<?= $maxTokens ?>',
270 stop: '<?= $completionEnding ?>',
271 apiKey: '<?= $apiKey ?>',
272 };
273 console.log('[BOT] Sent: ', data);
274 fetch('<?= $apiUrl ?>', { method: 'POST', headers: {
275 'Content-Type': 'application/json',
276 'X-WP-Nonce': '<?= $rest_nonce ?>'
277 },
278 body: JSON.stringify(data)
279 })
280 .then(response => response.json())
281 .then(data => {
282 console.log('[BOT] Recv: ', data);
283 if (!data.success) {
284 <?= $addReplyFn ?>(data.message, 'system');
285 }
286 else {
287 <?= $addReplyFn ?>(data.html, 'ai');
288 <?= $onGoingPrompt ?> += data.answer + '\n';
289 }
290 button.disabled = false;
291 input.disabled = false;
292
293 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
294 if (!isMobile) {
295 input.focus();
296 }
297 })
298 .catch(error => {
299 console.error(error);
300 button.disabled = false;
301 input.disabled = false;
302 });
303 }
304
305 // Keep the textarea height in sync with the content
306 function mwaiSetTextAreaHeight(textarea, lines) {
307 var rows = textarea.getAttribute('rows');
308 if (lines !== rows) {
309 textarea.setAttribute('rows', lines > 5 ? 5 : lines);
310 }
311 }
312
313 // Init the chatbot
314 function <?= $initChatBotFn ?>() {
315 var input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
316 input.addEventListener('keypress', (event) => {
317 if (event.keyCode === 13 && !event.shiftKey) {
318 <?= $onSentClickFn ?>();
319 }
320 });
321 input.addEventListener('keydown', (event) => {
322 var rows = input.getAttribute('rows');
323 if (event.keyCode === 13 && event.shiftKey) {
324 var lines = input.value.split('\n').length + 1;
325 mwaiSetTextAreaHeight(input, lines);
326 }
327 });
328 input.addEventListener('keyup', (event) => {
329 var rows = input.getAttribute('rows');
330 var lines = input.value.split('\n').length ;
331 mwaiSetTextAreaHeight(input, lines);
332 });
333 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
334 button.addEventListener('click', (event) => {
335 <?= $onSentClickFn ?>();
336 });
337
338 // If window, add event listener to mwai-open-button and mwai-close-button
339 if ( isWindow ) {
340 var openButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-open-button');
341 openButton.addEventListener('click', (event) => {
342 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
343 chat.classList.add('mwai-open');
344 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
345 if (!isMobile) {
346 input.focus();
347 }
348 });
349 var closeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-close-button');
350 closeButton.addEventListener('click', (event) => {
351 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
352 chat.classList.remove('mwai-open');
353 });
354 var resizeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-resize-button');
355 resizeButton.addEventListener('click', (event) => {
356 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
357 chat.classList.toggle('mwai-fullscreen');
358 });
359 }
360
361 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
362 }
363
364 // Let's go totally meoooow on this!
365 <?= $initChatBotFn ?>();
366 </script>
367
368 <?php
369 $output = ob_get_contents();
370 ob_end_clean();
371 $output = apply_filters( 'mwai_chatbot', $output, $atts );
372 return $output;
373 }
374 }