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