PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 0.3.6
AI Engine – The Chatbot, AI Framework & MCP for WordPress v0.3.6
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
375 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 $sessionId = $this->core->get_session_id();
135 $rest_nonce = wp_create_nonce( 'wp_rest' );
136 $casuallyFineTuned = boolval( $atts['casually_fined_tuned'] );
137 $promptEnding = addslashes( trim( $atts['prompt_ending'] ) );
138 $completionEnding = addslashes( trim( $atts['completion_ending'] ) );
139 if ( $casuallyFineTuned ) {
140 $promptEnding = "\\n\\n===\\n\\n";
141 $completionEnding = "\\n\\n";
142 }
143
144 // OpenAI Parameters
145 $model = $atts['model'];
146 $temperature = $atts['temperature'];
147 $maxTokens = $atts['max_tokens'];
148 $apiKey = $atts['api_key'];
149
150 // Named functions
151 $onSentClickFn = "mwai_{$id}_onSendClick";
152 $addReplyFn = "mwai_{$id}_addReply";
153 $initChatBotFn = "mwai_{$id}_initChatBot";
154
155 // Variables
156 $onGoingPrompt = "mwai_{$id}_onGoingPrompt";
157 $baseClasses = "mwai-chat";
158 $baseClasses .= ( $window ? " mwai-window" : "" );
159 $baseClasses .= ( !$window && $fullscreen ? " mwai-fullscreen" : "" );
160
161 // Output CSS
162 ob_start();
163 $style_content = "";
164 if ( $style === 'chatgpt' ) {
165 $style_content = $this->chatgpt_style( $id, $style );
166 }
167 echo apply_filters( 'mwai_chatbot_style', $style_content, $id );
168
169 // Output HTML & CSS
170 ?>
171 <div id="mwai-chat-<?= $id ?>" class="<?= $baseClasses ?>">
172 <?php if ( $window ) { ?>
173 <div class="mwai-open-button">
174 <img width="64" height="64" src="<?= plugins_url( '../../images/chat-green.svg', __FILE__ ) ?>" />
175 </div>
176 <div class="mwai-header">
177 <?php if ( $window ) { ?>
178 <div class="mwai-resize-button"></div>
179 <?php } ?>
180 <div class="mwai-close-button"></div>
181 </div>
182 <?php } ?>
183 <div class="mwai-content">
184 <div class="mwai-conversation">
185 </div>
186 <div class="mwai-input">
187 <textarea rows="1" placeholder="<?= $textInputPlaceholder ?>"></textarea>
188 <button><span><?= $textSend ?></span></button>
189 </div>
190 </div>
191 </div>
192
193 <script>
194 var <?= $onGoingPrompt ?> = '<?= $context ?>' + '\n\n';
195 var isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
196 var isWindow = <?= $window ? 'true' : 'false' ?>;
197
198 // Push the reply in the conversation
199 function <?= $addReplyFn ?>(text, type = 'user') {
200 var conversation = document.querySelector('#mwai-chat-<?= $id ?> .mwai-conversation');
201 var mwaiClasses = 'mwai-reply';
202 if (type === 'ai') {
203 mwaiClasses += ' mwai-ai';
204 }
205 else if (type === 'system') {
206 mwaiClasses += ' mwai-system';
207 }
208 else {
209 mwaiClasses += ' mwai-user';
210 }
211 var html = '<div class="' + mwaiClasses + '">';
212 if (type === 'ai') {
213 html += '<span class="mwai-name"><?= $aiName ?></span>';
214 }
215 else if (type === 'system') {
216 html += '<span class="mwai-name"><?= $sysName ?></span>';
217 }
218 else {
219 html += '<span class="mwai-name"><?= $userName ?></span>';
220 }
221 html += '<span class="mwai-text">' + text + '</span>';
222 html += '</div>';
223 conversation.innerHTML += html;
224 conversation.scrollTop = conversation.scrollHeight;
225
226 // Syntax coloring
227 if (typeof hljs !== 'undefined') {
228 document.querySelectorAll('pre code').forEach((el) => {
229 hljs.highlightElement(el);
230 });
231 }
232 }
233
234 // Function to request the completion
235 function <?= $onSentClickFn ?>() {
236 let input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
237 let inputText = input.value.trim();
238
239 if (inputText === '') {
240 return;
241 }
242
243 // Disable the button
244 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
245 button.disabled = true;
246
247 // Add the user reply
248 <?= $addReplyFn ?>(inputText, 'user');
249 <?= $onGoingPrompt ?> += '<?= $userName ?>' + inputText + '\n';
250 input.value = '';
251 input.setAttribute('rows', 1);
252 input.disabled = true;
253
254 // Let's build the prompt depending on the "system"
255 <?= $onGoingPrompt ?> += '<?= $aiName ?>';
256 let prompt = <?= $onGoingPrompt ?>;
257 if (<?= $casuallyFineTuned ? 1 : 0 ?>) {
258 prompt = inputText + '<?= $promptEnding ?>';
259 }
260
261 // Request the completion
262 const data = {
263 env: '<?= $env ?>',
264 session: '<?= $sessionId ?>',
265 prompt: prompt,
266 userName: '<?= $userName ?>',
267 aiName: '<?= $aiName ?>',
268 model: '<?= $model ?>',
269 temperature: '<?= $temperature ?>',
270 maxTokens: '<?= $maxTokens ?>',
271 stop: '<?= $completionEnding ?>',
272 apiKey: '<?= $apiKey ?>',
273 };
274 console.log('[BOT] Sent: ', data);
275 fetch('<?= $apiUrl ?>', { method: 'POST', headers: {
276 'Content-Type': 'application/json',
277 'X-WP-Nonce': '<?= $rest_nonce ?>'
278 },
279 body: JSON.stringify(data)
280 })
281 .then(response => response.json())
282 .then(data => {
283 console.log('[BOT] Recv: ', data);
284 if (!data.success) {
285 <?= $addReplyFn ?>(data.message, 'system');
286 }
287 else {
288 <?= $addReplyFn ?>(data.html, 'ai');
289 <?= $onGoingPrompt ?> += data.answer + '\n';
290 }
291 button.disabled = false;
292 input.disabled = false;
293
294 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
295 if (!isMobile) {
296 input.focus();
297 }
298 })
299 .catch(error => {
300 console.error(error);
301 button.disabled = false;
302 input.disabled = false;
303 });
304 }
305
306 // Keep the textarea height in sync with the content
307 function mwaiSetTextAreaHeight(textarea, lines) {
308 var rows = textarea.getAttribute('rows');
309 if (lines !== rows) {
310 textarea.setAttribute('rows', lines > 5 ? 5 : lines);
311 }
312 }
313
314 // Init the chatbot
315 function <?= $initChatBotFn ?>() {
316 var input = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input textarea');
317 input.addEventListener('keypress', (event) => {
318 if (event.keyCode === 13 && !event.shiftKey) {
319 <?= $onSentClickFn ?>();
320 }
321 });
322 input.addEventListener('keydown', (event) => {
323 var rows = input.getAttribute('rows');
324 if (event.keyCode === 13 && event.shiftKey) {
325 var lines = input.value.split('\n').length + 1;
326 mwaiSetTextAreaHeight(input, lines);
327 }
328 });
329 input.addEventListener('keyup', (event) => {
330 var rows = input.getAttribute('rows');
331 var lines = input.value.split('\n').length ;
332 mwaiSetTextAreaHeight(input, lines);
333 });
334 var button = document.querySelector('#mwai-chat-<?= $id ?> .mwai-input button');
335 button.addEventListener('click', (event) => {
336 <?= $onSentClickFn ?>();
337 });
338
339 // If window, add event listener to mwai-open-button and mwai-close-button
340 if ( isWindow ) {
341 var openButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-open-button');
342 openButton.addEventListener('click', (event) => {
343 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
344 chat.classList.add('mwai-open');
345 // Only focus only on desktop (to avoid the mobile keyboard to kick-in)
346 if (!isMobile) {
347 input.focus();
348 }
349 });
350 var closeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-close-button');
351 closeButton.addEventListener('click', (event) => {
352 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
353 chat.classList.remove('mwai-open');
354 });
355 var resizeButton = document.querySelector('#mwai-chat-<?= $id ?> .mwai-resize-button');
356 resizeButton.addEventListener('click', (event) => {
357 var chat = document.querySelector('#mwai-chat-<?= $id ?>');
358 chat.classList.toggle('mwai-fullscreen');
359 });
360 }
361
362 <?= $addReplyFn ?>('<?= $startSentence ?>', 'ai');
363 }
364
365 // Let's go totally meoooow on this!
366 <?= $initChatBotFn ?>();
367 </script>
368
369 <?php
370 $output = ob_get_contents();
371 ob_end_clean();
372 $output = apply_filters( 'mwai_chatbot', $output, $atts );
373 return $output;
374 }
375 }