PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.2.4
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.2.4
8.7.8 8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 All 534 releases
← All changes | includes/admin/templates/rag.php +39 -406 8.7.78.2.4 View file →
@@ -3,13 +3,10 @@
3 3 /**
4 4 * AI Assistant Template - RAG Feature Extended
5 5 * @package Botmaster
6 6 */
7 -if (get_option('wpchatbot_license_valid') == 'master' && get_option('wpchatbot_license_valid') == 'professional') {
8 - update_option('wpchatbot_license_valid', 'starter');
9 -}
10 7
11 -$wpchatbot_license_valid = get_option('wpchatbot_license_valid');
8 +$wpchatbot_license_valid = get_option('wpchatbot_license_valid');
12 9 // $wpchatbot_license_valid = 'starter';
13 10
14 11 ?>
15 12
@@ -18,18 +15,16 @@
18 15
19 16
20 17 <h2 class="nav-tab-wrapper">
21 18 <a href="#qcld-rag-settings-tab" class="nav-tab nav-tab-active"> Setting options</a>
22 - <a href="#qcld-rag-settings-sql" class="nav-tab">RAG from DB Tables</a>
23 19 <a href="#rag-sync" class="nav-tab">Sync and upload options</a>
24 - <a href="#rag-sources" class="nav-tab">Manage Sources</a>
25 20 <a href="#rag-database" class="nav-tab">KnowledgeBase Database</a>
26 21 </h2>
27 22
28 23 <div id="qcld-rag-settings-tab" class="qcld-tab-content active">
29 24 <!-- ===========================
30 - EMBEDDING SOURCE OPTIONS
31 - ============================ -->
25 + EMBEDDING SOURCE OPTIONS
26 + ============================ -->
32 27 <div class="wrap">
33 28 <h3>Choose Data Sources to Embed</h3>
34 29
35 30 <div class="mb-3">
@@ -65,34 +60,12 @@
65 60 <?php endforeach; ?>
66 61 </div>
67 62 <p class="description">Select multiple custom post types to embed.</p>
68 63 </div>
69 - <div class="mb-4" style="background: #f9f9f9; padding: 15px; border-radius: 8px; border-left: 4px solid #007bff;">
70 - <h4 style="margin-top: 0;"><i class="fa fa-tags"></i> Post Meta Data Settings <span class="pro-badge" style="display:inline-block; margin-left:8px; padding:2px 6px; background:#f0b429; color:#fff; border-radius:3px; font-size:11px; font-weight:bold; text-transform:uppercase;">PRO</span></h4>
71 - <div class="mb-3">
72 - <input type="checkbox" id="rag_embed_meta" <?php checked(get_option('rag_embed_meta'), '1'); ?> disabled>
73 - <label for="rag_embed_meta"><strong>Include Post Meta Data</strong></label>
74 - <p class="description">Enable this to include custom fields/meta data in the embeddings.</p>
75 - </div>
76 64
77 - <div class="mb-3">
78 - <label for="rag_embed_meta_keys"><strong>Meta Keys to Include (comma separated):</strong></label><br>
79 - <input type="text" id="rag_embed_meta_keys" value="<?php echo esc_attr(get_option('rag_embed_meta_keys', '')); ?>" placeholder="e.g. _price, _sku, custom_field_key" style="width: 100%; max-width: 400px; margin-top: 5px;" disabled>
80 - <p class="description">Specify the meta keys you want to include in the context. Leave empty to include all meta (not recommended).</p>
81 - </div>
82 - </div>
83 65
84 66 </div>
85 - <div class="wrap">
86 - <h3>Sync Settings</h3>
87 -
88 - <div class="mb-3">
89 - <input type="checkbox" id="rag_auto_sync_enabled" class="rag_auto_sync_enabled" <?php checked(get_option('rag_auto_sync_enabled'), '1'); ?>>
90 - <label for="rag_auto_sync_enabled"><strong>Enable Auto Sync (on Save)</strong></label>
91 - <p class="description">Automatically update embeddings when a post or product is saved/updated.</p>
92 - </div>
93 - </div>
94 - <!-- ===========================
67 + <!-- ===========================
95 68 EXECUTION BUTTON
96 69 ============================ -->
97 70 <div class="wrap my-4">
98 71 <p style="color: red"> <b><?php esc_html_e('Please connect to an AI service like OpenAI or Gemini before embedding. ', 'chatbot'); ?></b><b><a target="_blank" href="https://wpbot.pro/docs/knowledgebase/how-to-use-an-embedded-vector-database-and-rag-to-get-customized-responses-from-ai/"><?php esc_html_e('Check this Tutorial for more details.', 'chatbot'); ?></a></b></p>
@@ -122,154 +95,10 @@
122 95 <div class="wrap">
123 96 <button class="qcld-btn-primary" id="save_rag_setting">Save Settings</button>
124 97 </div>
125 98 </div>
126 - <div id="qcld-rag-settings-sql" class="qcld-tab-content">
127 -
128 - <div class="wrap">
129 - <h3>Choose Data Sources to Embed</h3>
130 - <?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'): ?>
131 - <div class="wrap">
132 - <div style="background-color: #fee; border: 1px solid #c33; padding: 15px; margin: 20px 0; border-radius: 4px;">
133 - <p style="color: #c33; font-weight: bold; margin: 0; font-size: 14px;">
134 - These options are available with the WPBot Pro <a href="https://www.wpbot.pro/pricing/" target="_blank" style="color: #c33; text-decoration: underline;">Professional</a> and <a href="https://www.wpbot.pro/pricing/" target="_blank" style="color: #c33; text-decoration: underline;">Master</a> Licenses
135 - </p>
136 - </div>
137 - </div>
138 - <?php endif; ?>
139 - <div class="mb-3" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
140 - <input type="checkbox" id="rag_embed_sql" checked disabled <?php checked(get_option('rag_embed_sql'), '1'); ?>>
141 - <label for="rag_embed_sql">Database Table (SQL)</label>
142 - <div id="rag_sql_options" style="">
143 - <table id="rag_sql_tables_list" class="wp-list-table widefat striped" style="max-width: 600px; margin-bottom: 10px;">
144 - <thead>
145 - <tr>
146 - <th>Table Name</th>
147 - <th>Table Field(s)</th>
148 - <th>Actions</th>
149 - </tr>
150 - </thead>
151 - <tbody>
152 - <?php
153 - $sql_tables = get_option('rag_sql_tables', []);
154 - if (!is_array($sql_tables) && !empty($sql_tables)) {
155 - $sql_tables = json_decode($sql_tables, true);
156 - }
157 -
158 - if (empty($sql_tables)) {
159 - $table_name = get_option('rag_sql_table_name', '');
160 - $table_field = get_option('rag_sql_table_field', '');
161 - if ($table_name && $table_field) {
162 - $sql_tables[] = ['table_name' => $table_name, 'table_field' => $table_field];
163 - }
164 - }
165 99
166 - if (!empty($sql_tables)) {
167 - foreach ($sql_tables as $table) {
168 - ?>
169 - <tr>
170 - <td><input type="text" name="rag_sql_table_name[]" value="<?php echo esc_attr($table['table_name']); ?>" class="regular-text" style="width:100%;"></td>
171 - <td><input type="text" name="rag_sql_table_field[]" value="<?php echo esc_attr($table['table_field']); ?>" class="regular-text" style="width:100%;"></td>
172 - <td><button type="button" class="button button-link-delete rag_sql_remove_table">Remove</button></td>
173 - </tr>
174 - <?php
175 - }
176 - } else {
177 - ?>
178 - <tr>
179 - <td><input type="text" name="rag_sql_table_name[]" value="" placeholder="e.g. wp_users" class="regular-text" style="width:100%;"></td>
180 - <td><input type="text" name="rag_sql_table_field[]" value="" placeholder="e.g. user_email" class="regular-text" style="width:100%;"></td>
181 - <td><button type="button" class="button button-link-delete rag_sql_remove_table">Remove</button></td>
182 - </tr>
183 - <?php
184 - }
185 - ?>
186 - </tbody>
187 - </table>
188 - <button type="button" class="button button-primary" id="rag_sql_add_table">Add New Table</button>
189 - <button type="button" class="button button-secondary" id="sql_instruction" style="margin-left: 5px;">View Available SQL Tables & Fields</button>
190 - <p class="description">Add multiple tables and fields. Separate multiple fields in the same table with commas. Click "Create Missing Tables" to generate empty tables in the database if they don't exist.</p>
191 - </div>
192 - <!-- New Section for Google Sheets to SQL Sync -->
193 - <div id="rag_sql_sheets_section" style="display:block; margin-top: 20px; margin-left: 20px; padding: 15px; border: 1px solid #ccc; background: #f9f9f9;">
194 - <h4>Google Sheets & CSV Database Sync</h4>
195 - <p class="description">Directly import Google Sheets or upload CSV data into SQL tables for Text-to-SQL querying.</p>
196 -
197 - <div style="margin-bottom: 15px;">
198 - <label style="display:block; font-weight:bold; margin-bottom:5px;">Import via Google Sheet URL:</label>
199 - <input type="text" id="rag_sql_sheet_url_input" placeholder="Enter Google Sheet or CSV URL" class="regular-text" style="width: 60%; margin-right: 5px;">
200 - <button type="button" class="button button-primary" id="rag_sql_import_sheet">Import URL to SQL</button>
201 - </div>
202 100
203 - <div style="margin-bottom: 15px;">
204 - <label style="display:block; font-weight:bold; margin-bottom:5px;">Upload a Local CSV File:</label>
205 - <input type="file" id="rag_sql_csv_file_input" accept=".csv" style="margin-right: 5px;">
206 - <button type="button" class="button button-primary" id="rag_sql_upload_csv">Upload CSV to SQL</button>
207 - </div>
208 -
209 - <hr style="margin: 15px 0;">
210 - <p>Sync all your previously uploaded sheets into SQL tables:</p>
211 - <button type="button" class="button button-secondary" id="rag_sql_sync_existing_sheets">Sync Existing Sheets to SQL</button>
212 -
213 - <div id="rag_sql_sync_status" style="margin-top: 10px; font-weight: bold;"></div>
214 - </div>
215 - </div>
216 - <br><br>
217 - <div class="mb-3" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?> ">
218 - <input type="checkbox" id="rag_sql_auto_sync_enabled" <?php checked(get_option('rag_sql_auto_sync_enabled'), '1'); ?>>
219 - <label for="rag_sql_auto_sync_enabled"><strong>Enable Auto Sync (on Save)</strong></label>
220 - <p class="description">Automatically update embeddings </p>
221 - </div>
222 - <hr>
223 - <?php
224 - $sql_sync_interval = get_option('rag_sql_sync_interval', 'daily');
225 - $sql_interval_labels = [
226 - 'hourly' => '(Hourly)',
227 - 'twicedaily' => '(Twice Daily)',
228 - 'daily' => '(Daily)',
229 - 'weekly' => '(Weekly)',
230 - ];
231 - $sql_interval_desc = [
232 - 'hourly' => 'once per hour',
233 - 'twicedaily' => 'twice per day',
234 - 'daily' => 'once per day',
235 - 'weekly' => 'once per week',
236 - ];
237 - $sql_current_label = $sql_interval_labels[$sql_sync_interval] ?? '(Daily)';
238 - $sql_current_desc = $sql_interval_desc[$sql_sync_interval] ?? 'once per day';
239 - ?>
240 -
241 - <div class="mb-3" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
242 - <label for="rag_sql_sync_interval"><strong>Sync Interval:</strong></label>
243 - <select id="rag_sql_sync_interval">
244 - <option value="five_minutes" <?php selected(get_option('rag_sql_sync_interval'), 'five_minutes'); ?>>Every 5 Minutes</option>
245 - <option value="hourly" <?php selected(get_option('rag_sql_sync_interval'), 'hourly'); ?>>Hourly</option>
246 - <option value="twicedaily" <?php selected(get_option('rag_sql_sync_interval'), 'twicedaily'); ?>>Twice Daily</option>
247 - <option value="daily" <?php selected(get_option('rag_sql_sync_interval', 'daily'), 'daily'); ?>>Once Daily</option>
248 - <option value="weekly" <?php selected(get_option('rag_sql_sync_interval'), 'weekly'); ?>>Weekly</option>
249 - </select>
250 - <p class="description">Choose how often to run the automated synchronization.</p>
251 - </div>
252 -
253 - </div>
254 -
255 - <div class="wrap my-4" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
256 - <button type="button" id="rag_embed_sql_btn" class="button button-primary">Embed Selected Database Data</button>
257 -
258 - <div id="rag_sql_progress_container" style="display:none; margin-top: 20px;">
259 - <div class="progress" style="height: 25px; background-color: #f1f1f1; border-radius: 5px; overflow: hidden;">
260 - <div id="rag_sql_progress_bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%; height: 100%; background-color: #007bff; transition: width 0.3s ease;"></div>
261 - </div>
262 - <p id="rag_sql_progress_status" style="margin-top: 10px; font-weight: bold;"></p>
263 - </div>
264 - </div>
265 -
266 - <!-- SAVE SETTINGS BUTTON -->
267 - <div class="wrap" style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
268 - <button class="qcld-btn-primary" id="save_rag_setting">Save Settings</button>
269 - </div>
270 - </div>
271 -
272 101 <div id="rag-sync" class="qcld-tab-content">
273 102 <?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'): ?>
274 103 <div class="wrap">
275 104 <div style="background-color: #fee; border: 1px solid #c33; padding: 15px; margin: 20px 0; border-radius: 4px;">
@@ -283,83 +112,33 @@
283 112 <div style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
284 113 <!-- ===========================
285 114 SYNC SETTINGS
286 115 ============================ -->
287 - <!-- ===========================
288 - PDF UPLOAD (AJAX)
289 - ============================ -->
290 116 <div class="wrap">
291 117 <h3>Sync Settings</h3>
292 -
118 +
293 119 <div class="mb-3">
294 - <input type="checkbox" id="rag_auto_sync_enabled_tab" class="rag_auto_sync_enabled" <?php checked(get_option('rag_auto_sync_enabled'), '1'); ?>>
295 - <label for="rag_auto_sync_enabled_tab"><strong>Enable Auto Sync (on Save)</strong></label>
120 + <input type="checkbox" id="rag_auto_sync_enabled" <?php checked(get_option('rag_auto_sync_enabled'), '1'); ?>>
121 + <label for="rag_auto_sync_enabled"><strong>Enable Auto Sync (on Save)</strong></label>
296 122 <p class="description">Automatically update embeddings when a post or product is saved/updated.</p>
297 123 </div>
298 - <hr>
299 - <?php
300 - $sync_interval = get_option('rag_sync_interval', 'daily');
301 - $interval_labels = [
302 - 'hourly' => '(Hourly)',
303 - 'twicedaily' => '(Twice Daily)',
304 - 'daily' => '(Daily)',
305 - 'weekly' => '(Weekly)',
306 - ];
307 - $interval_desc = [
308 - 'hourly' => 'once per hour',
309 - 'twicedaily' => 'twice per day',
310 - 'daily' => 'once per day',
311 - 'weekly' => 'once per week',
312 - ];
313 - $current_label = $interval_labels[$sync_interval] ?? '(Daily)';
314 - $current_desc = $interval_desc[$sync_interval] ?? 'once per day';
315 - ?>
316 124
317 - <div class="mb-3">
318 - <input type="checkbox" id="rag_googlesheets_autosync_enabled" <?php checked(get_option('rag_googlesheets_autosync_enabled'), '1'); ?>>
319 - <label for="rag_googlesheets_autosync_enabled"><strong>Enable Google Sheets Auto Sync <span class="rag-sync-label"><?php echo esc_html( $current_label ); ?></span></strong></label>
320 - <p class="description">Automatically re-sync all Google Sheets in the knowledge base <span class="rag-sync-desc"><?php echo esc_html( $current_desc ); ?></span>.</p>
321 - </div>
125 + </div>
322 126
323 - <div class="mb-3">
324 - <input type="checkbox" id="rag_googledocs_autosync_enabled" <?php checked(get_option('rag_googledocs_autosync_enabled'), '1'); ?>>
325 - <label for="rag_googledocs_autosync_enabled"><strong>Enable Google Docs Auto Sync <span class="rag-sync-label"><?php echo esc_html( $current_label ); ?></span></strong></label>
326 - <p class="description">Automatically re-sync all Google Docs in the knowledge base <span class="rag-sync-desc"><?php echo esc_html( $current_desc ); ?></span>.</p>
327 - </div>
328 127
329 - <div class="mb-3">
330 - <label for="rag_sync_interval"><strong>Sync Interval:</strong></label>
331 - <select id="rag_sync_interval">
332 - <option value="daily" <?php selected(get_option('rag_sync_interval', 'daily'), 'daily'); ?>>Once Daily</option>
333 - <option value="twicedaily" <?php selected(get_option('rag_sync_interval'), 'twicedaily'); ?>>Twice Daily</option>
334 - <option value="hourly" <?php selected(get_option('rag_sync_interval'), 'hourly'); ?>>Hourly</option>
335 - <option value="weekly" <?php selected(get_option('rag_sync_interval'), 'weekly'); ?>>Weekly</option>
336 - </select>
337 - <p class="description">Choose how often to run the automated synchronization.</p>
338 - </div>
339 -
340 - </div>
128 + <!-- ===========================
129 + PDF UPLOAD (AJAX)
130 + ============================ -->
341 131 <div class="wrap">
342 132 <h3>Upload PDF for RAG</h3>
343 133
344 134 <form id="rag-pdf-form">
345 135 <input type="file" id="rag-pdf-files" name="rag_pdf[]" multiple accept="application/pdf" />
346 - <br><br>
136 + <br>
347 137 <button type="submit" class="button button-primary" id="rag-pdf-submit">Upload & Embed PDF</button>
348 - <button type="button" class="button" id="rag-media-pdf-btn">Select PDF from Media Library</button>
349 - <button type="button" class="button" id="qcld-rag-list-pdf-btn">List PDF Files from Media Library</button>
350 138 <span id="rag-pdf-status" style="margin-left: 10px;"></span>
351 139 </form>
352 140
353 - <div id="qcld-pdf-list-container" style="display:none; margin-top:20px; border:1px solid #ddd; padding:15px; background:#fff;">
354 - <h4>Available PDF Files in Media Library</h4>
355 - <div id="qcld-pdf-items" style="max-height:300px; overflow-y:auto; margin-bottom:15px;">
356 - <p>Loading files...</p>
357 - </div>
358 - <button type="button" class="button button-primary qcld-rag-index-selected-media" data-type="pdf">Index Selected PDF Files</button>
359 - <button type="button" class="button qcld-rag-close-media-list">Close List</button>
360 - </div>
361 -
362 141 <div id="rag-pdf-output" style="margin-top: 15px;"></div>
363 142 </div>
364 143
365 144 <!-- ===========================
@@ -366,13 +145,13 @@
366 145 CSV UPLOAD (AJAX)
367 146 ============================ -->
368 147 <div class="wrap">
369 148 <h3>Upload CSV Data for RAG</h3>
370 - <p>Upload CSV files with data to be embedded. Each row will be processed as a separate document. <a href="<?php echo esc_url( plugin_dir_url(__FILE__).'download/rag_test_data.csv' ); ?>">Download Test Data</a></p>
149 + <p>Upload CSV files with data to be embedded. Each row will be processed as a separate document. <a href="<?php echo plugin_dir_url(__FILE__).'download/rag_test_data.csv'; ?>">Download Test Data</a></p>
371 150
372 151 <form id="rag-csv-form">
373 152 <input type="file" id="rag-csv-files" name="rag_csv[]" multiple accept=".csv,text/csv" />
374 - <br><br>
153 + <br>
375 154 <button type="submit" class="button button-primary" id="rag-csv-submit">Upload & Embed CSV</button>
376 155 <span id="rag-csv-status" style="margin-left: 10px;"></span>
377 156 </form>
378 157
@@ -379,36 +158,8 @@
379 158 <div id="rag-csv-output" style="margin-top: 15px;"></div>
380 159 </div>
381 160
382 161 <!-- ===========================
383 - DOCX UPLOAD (AJAX)
384 - ============================ -->
385 - <div class="wrap">
386 - <h3>Upload Word (.docx) for RAG</h3>
387 - <p>Upload MS Word files to be indexed in the knowledge base.</p>
388 -
389 - <form id="rag-docx-form">
390 - <input type="file" id="rag-docx-files" name="rag_docx[]" multiple accept=".docx,application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
391 - <br><br>
392 - <button type="submit" class="button button-primary" id="rag-docx-submit">Upload & Embed Word</button>
393 - <button type="button" class="button" id="rag-media-docx-btn">Select Word from Media Library</button>
394 - <button type="button" class="button" id="qcld-rag-list-docx-btn">List Word Files from Media Library</button>
395 - <span id="rag-docx-status" style="margin-left: 10px;"></span>
396 - </form>
397 -
398 - <div id="qcld-docx-list-container" style="display:none; margin-top:20px; border:1px solid #ddd; padding:15px; background:#fff;">
399 - <h4>Available Word Files in Media Library</h4>
400 - <div id="qcld-docx-items" style="max-height:300px; overflow-y:auto; margin-bottom:15px;">
401 - <p>Loading files...</p>
402 - </div>
403 - <button type="button" class="button button-primary qcld-rag-index-selected-media" data-type="docx">Index Selected Word Files</button>
404 - <button type="button" class="button qcld-rag-close-media-list">Close List</button>
405 - </div>
406 -
407 - <div id="rag-docx-output" style="margin-top: 15px;"></div>
408 - </div>
409 -
410 - <!-- ===========================
411 162 XAML UPLOAD (AJAX)
412 163 ============================ -->
413 164 <div class="wrap">
414 165 <h3>Upload XML Data for RAG</h3>
@@ -415,10 +166,10 @@
415 166 <p>Upload XML files with data to be embedded.</p>
416 167
417 168 <form id="rag-xaml-form">
418 169 <input type="file" id="rag-xaml-files" name="rag_xaml[]" multiple accept=".xaml,text/xml,application/xml" />
419 - <br><br>
420 - <button type="submit" class="button button-primary" id="rag-xaml-submit">Upload & Embed XAML</button>
170 + <br>
171 + <button type="submit" class="button button-primary" id="rag-xaml-submit">Upload & Embed XML</button>
421 172 <span id="rag-xaml-status" style="margin-left: 10px;"></span>
422 173 </form>
423 174
424 175 <div id="rag-xaml-output" style="margin-top: 15px;"></div>
@@ -423,9 +174,9 @@
423 174
424 175 <div id="rag-xaml-output" style="margin-top: 15px;"></div>
425 176 </div>
426 177
427 - <!-- ===========================
178 + <!-- ===========================
428 179 SITEMAP SUBMISSION
429 180 ============================ -->
430 181 <div class="wrap">
431 182 <h3>Submit Sitemap for RAG</h3>
@@ -433,49 +184,11 @@
433 184 <input type="url" id="botmaster_sitemap_url" class="regular-text" placeholder="https://example.com/sitemap.xml" style="width: 100%; max-width: 400px;">
434 185 <button type="button" id="botmaster_submit_sitemap_btn" class="button button-primary">Process Sitemap</button>
435 186 <div id="botmaster_sitemap_status" style="margin-top: 10px;"></div>
436 187 </div>
437 -
438 - <!-- ===========================
439 - GOOGLE SHEETS SUBMISSION
440 - ============================ -->
441 - <div class="wrap">
442 - <h3>Submit Google Sheet for RAG</h3>
443 - <p>Enter your publicly published Google Sheet URL (Publish to web -> Web page).</p>
444 - <input type="url" id="botmaster_googlesheet_url" class="regular-text" placeholder="https://docs.google.com/spreadsheets/d/e/.../pubhtml" style="width: 100%; max-width: 400px;">
445 - <button type="button" id="botmaster_submit_googlesheet_btn" class="button button-primary">Process Google Sheet</button>
446 -
447 - <div id="gs_progress_container" style="display:none; margin-top: 20px;">
448 - <div class="progress" style="height: 20px; background-color: #f1f1f1; border-radius: 5px; overflow: hidden; border: 1px solid #ddd;">
449 - <div id="gs_progress_bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%; height: 100%; background-color: #28a745; transition: width 0.3s ease;"></div>
450 - </div>
451 - <p id="gs_progress_status" style="margin-top: 10px; font-weight: bold; font-size: 13px;"></p>
452 - </div>
453 -
454 - <div id="botmaster_googlesheet_status" style="margin-top: 10px;"></div>
455 188 </div>
456 -
457 - <!-- ===========================
458 - GOOGLE DOCS SUBMISSION
459 - ============================ -->
189 +
460 190 <div class="wrap">
461 - <h3>Submit Google Doc for RAG</h3>
462 - <p>Enter your publicly published Google Doc URL (File -> Share -> Publish to web).</p>
463 - <input type="url" id="botmaster_googledoc_url" class="regular-text" placeholder="https://docs.google.com/document/d/.../pub" style="width: 100%; max-width: 400px;">
464 - <button type="button" id="botmaster_submit_googledoc_btn" class="button button-primary">Process Google Doc</button>
465 -
466 - <div id="gd_progress_container" style="display:none; margin-top: 20px;">
467 - <div class="progress" style="height: 20px; background-color: #f1f1f1; border-radius: 5px; overflow: hidden; border: 1px solid #ddd;">
468 - <div id="gd_progress_bar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%; height: 100%; background-color: #007bff; transition: width 0.3s ease;"></div>
469 - </div>
470 - <p id="gd_progress_status" style="margin-top: 10px; font-weight: bold; font-size: 13px;"></p>
471 - </div>
472 -
473 - <div id="botmaster_googledoc_status" style="margin-top: 10px;"></div>
474 - </div>
475 - </div>
476 - <h5 style="color: #c33;">Notes: These are based on AI system, so make sure you have enabled any AI features and set up valid API keys. <b><a href="<?php echo esc_url('https://wpbot.pro/docs/knowledgebase/how-to-use-an-embedded-vector-database-and-rag-to-get-customized-responses-from-ai/'); ?>" target="_blank">Check this Tutorial for more details.</a></b></h5>
477 - <div class="wrap">
478 191 <button class="qcld-btn-primary" id="save_rag_setting">Save Settings</button>
479 192 </div>
480 193 </div>
481 194
@@ -505,9 +218,9 @@
505 218
506 219 $.post(ajaxurl, {
507 220 action: 'botmaster_submit_sitemap',
508 221 sitemap_url: sitemapUrl,
509 - nonce: '<?php echo esc_attr( wp_create_nonce('botmaster_kb_nonce') ); ?>'
222 + nonce: '<?php echo wp_create_nonce("botmaster_kb_nonce"); ?>'
510 223 }, function(response) {
511 224 $('#botmaster_submit_sitemap_btn').prop('disabled', false);
512 225 if (response.success) {
513 226 statusDiv.html('<div class="notice notice-success inline"><p>' + response.data.message + '</p></div>');
@@ -517,91 +230,13 @@
517 230 });
518 231 });
519 232 });
520 233 </script>
521 - <div id="rag-sources" class="qcld-tab-content">
522 - <?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'): ?>
523 - <div class="wrap">
524 - <div style="background-color: #fee; border: 1px solid #c33; padding: 15px; margin: 20px 0; border-radius: 4px;">
525 - <p style="color: #c33; font-weight: bold; margin: 0; font-size: 14px;">
526 - These options are available with the WPBot Pro <a href="<?php echo esc_url('https://www.wpbot.pro/pricing/'); ?>" target="_blank" style="color: #c33; text-decoration: underline;">Professional</a> and <a href="<?php echo esc_url('https://www.wpbot.pro/pricing/'); ?>" target="_blank" style="color: #c33; text-decoration: underline;">Master</a> Licenses
527 - </p>
528 - </div>
529 - </div>
530 - <?php endif; ?>
531 -
532 - <div style="<?php if ( $wpchatbot_license_valid != 'master' && $wpchatbot_license_valid != 'professional'){ echo 'opacity:0.5; pointer-events:none;'; } ?>">
533 - <div class="wrap">
534 - <h3>Manage Knowledge Base Sources</h3>
535 - <p>Manage entire files or spreadsheets instead of individual rows.</p>
536 -
537 - <table class="wp-list-table widefat fixed striped">
538 - <thead>
539 - <tr>
540 - <th class="check-column"><input type="checkbox" id="rag-sources-select-all"></th>
541 - <th>Source Name / URL</th>
542 - <th>Type</th>
543 - <th>Documents</th>
544 - <th>Actions</th>
545 - </tr>
546 - </thead>
547 - <tbody id="rag-sources-list">
548 - <?php
549 - global $wpdb;
550 - $table = $wpdb->prefix . 'rag_documents';
551 - $sources = $wpdb->get_results("SELECT source_url, source_type, COUNT(*) as count, MAX(title) as display_name FROM {$table} GROUP BY source_url, source_type ORDER BY count DESC"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
552 -
553 - if ($sources) {
554 - foreach ($sources as $source) {
555 - $display_url = $source->source_url ?: "Manual Upload";
556 - ?>
557 - <tr data-source-url="<?php echo esc_attr($source->source_url); ?>">
558 - <th scope="row" class="check-column"><input type="checkbox" class="rag-source-checkbox" value="<?php echo esc_attr($source->source_url); ?>"></th>
559 - <td>
560 - <strong><?php echo esc_html($source->display_name); ?></strong><br>
561 - <small style="color:#888;"><?php echo esc_html($display_url); ?></small>
562 - </td>
563 - <td><span class="badge" style="background:#eee; padding:2px 5px; border-radius:3px;"><?php echo esc_html($source->source_type); ?></span></td>
564 - <td><?php echo esc_html($source->count); ?> chunks</td>
565 - <td>
566 - <button class="button rag-source-sync" data-url="<?php echo esc_attr($source->source_url); ?>" data-type="<?php echo esc_attr($source->source_type); ?>">Sync Now</button>
567 - <button class="button button-link-delete rag-source-delete" data-url="<?php echo esc_attr($source->source_url); ?>">Delete All</button>
568 - </td>
569 - </tr>
570 - <?php
571 - }
572 - } else {
573 - echo '<tr><td colspan="5">No sources found.</td></tr>';
574 - }
575 - ?>
576 - </tbody>
577 - </table>
578 234
579 - <div class="tablenav bottom">
580 - <div class="alignleft actions bulkactions">
581 - <select id="rag-sources-bulk-action">
582 - <option value="-1">Bulk Actions</option>
583 - <option value="delete">Delete Selected Sources</option>
584 - </select>
585 - <button type="button" id="rag-sources-apply-bulk" class="button action">Apply</button>
586 - </div>
587 - </div>
588 - </div>
589 235
590 - <div class="wrap" style="margin-top: 40px; border-top: 1px solid #ddd; padding-top: 20px;">
591 - <h3>Database Utilities</h3>
592 - <div class="notice notice-info inline">
593 - <p>Upgrade your database to the new **High-Speed Binary Format**. This makes similarity searches significantly faster (10x+ speed improvement).</p>
594 - </div>
595 - <button type="button" id="rag-migrate-btn" class="button button-primary">Run High-Speed Migration</button>
596 - <span id="rag-migrate-status" style="margin-left: 10px;"></span>
597 - </div>
598 - </div>
599 - </div>
600 236
601 237
602 238
603 -
604 239 <div id="rag-database" class="qcld-tab-content">
605 240 <!-- ===========================
606 241 KNOWLEDGE BASE MANAGEMENT
607 242 ============================ -->
@@ -661,9 +296,9 @@
661 296 echo '<div class="notice notice-success inline"><p>Database table created successfully.</p></div>';
662 297 }
663 298
664 299 // Check if table exists
665 - $table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $wpdb->esc_like($table_rag_documents))) === $table_rag_documents; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
300 + $table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $wpdb->esc_like($table_rag_documents))) === $table_rag_documents;
666 301
667 302 if (!$table_exists) {
668 303 ?>
669 304 <div class="wrap">
@@ -686,11 +321,11 @@
686 321 $search_query = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
687 322
688 323 if ($search_query) {
689 324 $like = '%' . $wpdb->esc_like($search_query) . '%';
690 - $total_items = $wpdb->get_var($wpdb->prepare("SELECT COUNT(id) FROM {$table_name} WHERE title LIKE %s OR content LIKE %s", $like, $like)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
325 + $total_items = $wpdb->get_var($wpdb->prepare("SELECT COUNT(id) FROM {$table_name} WHERE title LIKE %s OR content LIKE %s", $like, $like));
691 326 } else {
692 - $total_items = $wpdb->get_var("SELECT COUNT(id) FROM {$table_name}"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
327 + $total_items = $wpdb->get_var("SELECT COUNT(id) FROM {$table_name}");
693 328 }
694 329 $items_per_page = 50;
695 330 $page = isset($_GET['paged']) ? absint(wp_unslash($_GET['paged'])) : 1;
696 331 $offset = ($page - 1) * $items_per_page;
@@ -698,10 +333,10 @@
698 333
699 334 $pagination_args = array(
700 335 'base' => add_query_arg(array('paged' => '%#%', 's' => $search_query), '?page=wpbot_openAi') . '#ai-knowledge-base-tab#rag-database',
701 336 'format' => '',
702 - 'prev_text' => __( '&laquo;', 'chatbot' ),
703 - 'next_text' => __( '&raquo;', 'chatbot' ),
337 + 'prev_text' => __('&laquo;'),
338 + 'next_text' => __('&raquo;'),
704 339 'total' => $total_pages,
705 340 'current' => $page,
706 341 'type' => 'plain',
707 342 );
@@ -706,11 +341,10 @@
706 341 'type' => 'plain',
707 342 );
708 343
709 344 if ($total_pages > 1) {
710 - // translators: %s: number of items.
711 - echo '<div class="tablenav-pages"><span class="displaying-num">' . sprintf( esc_html( _n( '%s item', '%s items', $total_items, 'chatbot' ) ), esc_html( number_format_i18n($total_items) ) ) . '</span>';
712 - echo wp_kses_post( paginate_links($pagination_args) );
345 + echo '<div class="tablenav-pages"><span class="displaying-num">' . sprintf(_n('%s item', '%s items', $total_items), number_format_i18n($total_items)) . '</span>';
346 + echo paginate_links($pagination_args);
713 347 echo '</div>';
714 348 }
715 349 ?>
716 350
@@ -731,19 +365,19 @@
731 365 <tbody id="rag-knowledge-base-list">
732 366 <?php
733 367 if ($search_query) {
734 368 $like = '%' . $wpdb->esc_like($search_query) . '%';
735 - $documents = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} WHERE title LIKE %s OR content LIKE %s ORDER BY created_at DESC LIMIT %d OFFSET %d", $like, $like, $items_per_page, $offset)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
369 + $documents = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} WHERE title LIKE %s OR content LIKE %s ORDER BY created_at DESC LIMIT %d OFFSET %d", $like, $like, $items_per_page, $offset));
736 370 } else {
737 - $documents = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} ORDER BY created_at DESC LIMIT %d OFFSET %d", $items_per_page, $offset)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
371 + $documents = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} ORDER BY created_at DESC LIMIT %d OFFSET %d", $items_per_page, $offset));
738 372 }
739 373
740 374 if ($documents) {
741 375 foreach ($documents as $doc) {
742 376 ?>
743 - <tr id="rag-doc-<?php echo esc_attr( $doc->id ); ?>">
377 + <tr id="rag-doc-<?php echo $doc->id; ?>">
744 378 <th scope="qcld-row" class="check-column">
745 - <input type="checkbox" class="rag-doc-checkbox" value="<?php echo esc_attr( $doc->id ); ?>">
379 + <input type="checkbox" class="rag-doc-checkbox" value="<?php echo $doc->id; ?>">
746 380 </th>
747 381 <td><?php echo esc_html($doc->title); ?></td>
748 382 <td>
749 383 <div style="max-height: 4.5em; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; line-height: 1.5em; font-size: 13px; color: #666;">
@@ -754,12 +388,12 @@
754 388 <td><?php echo esc_html($doc->source_url ?: $doc->file_url); ?></td>
755 389 <td><?php echo esc_html($doc->status); ?></td>
756 390 <td>
757 391 <?php if (!in_array($doc->source_type, ['csv', 'xml', 'xaml','sitemap'])): ?>
758 - <button class="button button-small rag-sync-doc" data-id="<?php echo esc_attr( $doc->id ); ?>" title="Re-sync data from source">Sync</button>
392 + <button class="button button-small rag-sync-doc" data-id="<?php echo $doc->id; ?>" title="Re-sync data from source">Sync</button>
759 393 <?php endif; ?>
760 - <button class="button button-small rag-edit-doc" data-id="<?php echo esc_attr( $doc->id ); ?>">Edit</button>
761 - <button class="button button-small button-link-delete rag-delete-doc" data-id="<?php echo esc_attr( $doc->id ); ?>">Delete</button>
394 + <button class="button button-small rag-edit-doc" data-id="<?php echo $doc->id; ?>">Edit</button>
395 + <button class="button button-small button-link-delete rag-delete-doc" data-id="<?php echo $doc->id; ?>">Delete</button>
762 396 </td>
763 397 </tr>
764 398 <?php
765 399 }
@@ -772,11 +406,10 @@
772 406
773 407 <div class="tablenav bottom">
774 408 <?php
775 409 if ($total_pages > 1) {
776 - // translators: %s: number of items.
777 - echo '<div class="tablenav-pages"><span class="displaying-num">' . sprintf( esc_html( _n( '%s item', '%s items', $total_items, 'chatbot' ) ), esc_html( number_format_i18n($total_items) ) ) . '</span>';
778 - echo wp_kses_post( paginate_links($pagination_args) );
410 + echo '<div class="tablenav-pages"><span class="displaying-num">' . sprintf(_n('%s item', '%s items', $total_items), number_format_i18n($total_items)) . '</span>';
411 + echo paginate_links($pagination_args);
779 412 echo '</div>';
780 413 }
781 414 ?>
782 415 <br class="clear">
@@ -825,9 +458,9 @@
825 458 for (var i = 0; i < fileInput.files.length; i++) {
826 459 formData.append('rag_pdf[]', fileInput.files[i]);
827 460 }
828 461 formData.append('action', 'rag_upload_pdf');
829 - formData.append('nonce', '<?php echo esc_js( wp_create_nonce('rag_upload_nonce') ); ?>');
462 + formData.append('nonce', '<?php echo wp_create_nonce('rag_upload_nonce'); ?>');
830 463
831 464 $('#rag-pdf-submit').prop('disabled', true);
832 465 $('#rag-pdf-status').html('<span class="spinner is-active" style="float:none;"></span> Uploading and processing...');
833 466 $('#rag-pdf-output').html('');
@@ -871,9 +504,9 @@
871 504 for (var i = 0; i < fileInput.files.length; i++) {
872 505 formData.append('rag_csv[]', fileInput.files[i]);
873 506 }
874 507 formData.append('action', 'rag_upload_csv');
875 - formData.append('nonce', '<?php echo esc_js( wp_create_nonce('rag_upload_nonce') ); ?>');
508 + formData.append('nonce', '<?php echo wp_create_nonce('rag_upload_nonce'); ?>');
876 509
877 510 $('#rag-csv-submit').prop('disabled', true);
878 511 $('#rag-csv-status').html('<span class="spinner is-active" style="float:none;"></span> Uploading and processing...');
879 512 $('#rag-csv-output').html('');
@@ -917,9 +550,9 @@
917 550 for (var i = 0; i < fileInput.files.length; i++) {
918 551 formData.append('rag_xaml[]', fileInput.files[i]);
919 552 }
920 553 formData.append('action', 'rag_upload_xaml');
921 - formData.append('nonce', '<?php echo esc_js( wp_create_nonce('rag_upload_nonce') ); ?>');
554 + formData.append('nonce', '<?php echo wp_create_nonce('rag_upload_nonce'); ?>');
922 555
923 556 $('#rag-xaml-submit').prop('disabled', true);
924 557 $('#rag-xaml-status').html('<span class="spinner is-active" style="float:none;"></span> Uploading and processing...');
925 558 $('#rag-xaml-output').html('');
@@ -995,5 +628,5 @@
995 628 // Default to first tab if no sub-tab specified
996 629 $('.nav-tab-wrapper a').first().trigger('click');
997 630 }
998 631 });
999 -</script>
632 +</script>