is_activated(); $plugin_url = plugin_dir_url(dirname(__FILE__)); // Check if integrations are active $pinecone_options = get_option('mxchat_pinecone_addon_options', array()); $is_pinecone_active = ($pinecone_options['mxchat_use_pinecone'] ?? '0') === '1'; $vectorstore_options = get_option('mxchat_openai_vectorstore_options', array()); $is_vectorstore_active = ($vectorstore_options['mxchat_use_openai_vectorstore'] ?? '0') === '1'; // Extract page data extract($page_data); ?>
get_available_bots(); ?>

0) : ?>

0) : ?>

mxchat_render_completed_status_cards(); ?>
options ?? get_option('mxchat_options', array()); // Check if user is using WordPress database (not Pinecone or OpenAI Vector Store) $pinecone_options = get_option('mxchat_pinecone_addon_options', array()); $is_pinecone_active = ($pinecone_options['mxchat_use_pinecone'] ?? '0') === '1'; $vectorstore_options = get_option('mxchat_openai_vectorstore_options', array()); $is_vectorstore_active = ($vectorstore_options['mxchat_use_openai_vectorstore'] ?? '0') === '1'; $is_using_wordpress_db = !$is_pinecone_active && !$is_vectorstore_active; // Check embedding API key $embedding_model = isset($options['embedding_model']) ? esc_attr($options['embedding_model']) : 'text-embedding-ada-002'; $has_openai_key = !empty($options['api_key']); $has_voyage_key = !empty($options['voyage_api_key']); $has_gemini_key = !empty($options['gemini_api_key']); $has_required_key = false; $required_key_type = ''; if (strpos($embedding_model, 'text-embedding-') !== false && $has_openai_key) { $has_required_key = true; $required_key_type = 'OpenAI'; } elseif (strpos($embedding_model, 'voyage-') !== false && $has_voyage_key) { $has_required_key = true; $required_key_type = 'Voyage AI'; } elseif (strpos($embedding_model, 'gemini-embedding-') !== false && $has_gemini_key) { $has_required_key = true; $required_key_type = 'Google Gemini'; } elseif (strpos($embedding_model, 'text-embedding-') !== false) { $required_key_type = 'OpenAI'; } elseif (strpos($embedding_model, 'voyage-') !== false) { $required_key_type = 'Voyage AI'; } elseif (strpos($embedding_model, 'gemini-embedding-') !== false) { $required_key_type = 'Google Gemini'; } ?>

Remember to add credits to your %s account before using the knowledgebase.', 'mxchat'), $required_key_type, $required_key_type)); ?>

0) : ?>

0) : ?>

mxchat_render_completed_status_cards(); } /** * Render Knowledge Base Section (table) */ function mxchat_render_knowledge_base_section($admin_instance, $knowledge_manager, $page_data) { extract($page_data); // Group prompts by source_url for chunked content display $grouped_prompts = array(); if ($prompts) { foreach ($prompts as $prompt) { $source_url = $prompt->source_url ?? ''; // Check if chunk metadata exists on the record itself (Pinecone) if (isset($prompt->chunk_index) && $prompt->chunk_index !== null) { // Pinecone: metadata is already on the record object $prompt->chunk_metadata = array( 'chunk_index' => intval($prompt->chunk_index), 'total_chunks' => isset($prompt->total_chunks) ? intval($prompt->total_chunks) : null, 'is_chunked' => isset($prompt->is_chunked) ? (bool) $prompt->is_chunked : true ); $prompt->display_content = $prompt->article_content; // Pinecone content is already clean } else { // WordPress: Parse chunk metadata from JSON prefix in article_content if (class_exists('MxChat_Chunker')) { $chunk_meta = MxChat_Chunker::parse_stored_chunk($prompt->article_content); $prompt->chunk_metadata = $chunk_meta['metadata']; $prompt->display_content = $chunk_meta['text']; // Store clean content without JSON prefix } else { $prompt->chunk_metadata = array(); $prompt->display_content = $prompt->article_content; } } if (!empty($source_url)) { if (!isset($grouped_prompts[$source_url])) { $grouped_prompts[$source_url] = array(); } $grouped_prompts[$source_url][] = $prompt; } else { // Use a unique key for ungrouped prompts $grouped_prompts['_ungrouped_' . $prompt->id] = array($prompt); } } // Sort each group by chunk_index from metadata foreach ($grouped_prompts as $source_url => &$group) { usort($group, function($a, $b) { $index_a = isset($a->chunk_metadata['chunk_index']) ? intval($a->chunk_metadata['chunk_index']) : 0; $index_b = isset($b->chunk_metadata['chunk_index']) ? intval($b->chunk_metadata['chunk_index']) : 0; return $index_a - $index_b; }); } unset($group); // Break reference } $display_index = 0; ?>

-

()

label; } elseif ($content_type_filter === 'pdf') { $filter_display = 'PDFs'; } elseif ($content_type_filter === 'url') { $filter_display = 'URLs'; } /* translators: %s: content type label (e.g. "Pages", "PDFs") */ $delete_all_label = sprintf(__('Delete All %s', 'mxchat'), $filter_display); /* translators: %s: content type label */ $delete_all_confirm = sprintf(__('Are you sure you want to delete all %s from the knowledge base?', 'mxchat'), $filter_display); } ?>
$group) : $chunk_count = count($group); $first_prompt = $group[0]; $display_index++; if ($chunk_count > 1) : // Multiple chunks - show grouped row with expand button $group_id = 'group-' . md5($source_url); ?> $prompt) : $meta_chunk_index = isset($prompt->chunk_metadata['chunk_index']) ? intval($prompt->chunk_metadata['chunk_index']) : $chunk_index; $meta_total_chunks = isset($prompt->chunk_metadata['total_chunks']) ? intval($prompt->chunk_metadata['total_chunks']) : $chunk_count; $content = isset($prompt->display_content) ? $prompt->display_content : $prompt->article_content; $preview_length = 150; $content_preview = mb_strlen($content) > $preview_length ? mb_substr($content, 0, $preview_length) . '...' : $content; ?> display_content) ? $prompt->display_content : $prompt->article_content; $preview_length = 150; $content_preview = mb_strlen($content) > $preview_length ? mb_substr($content, 0, $preview_length) . '...' : $content; ?>
id); ?>
display_content) ? $first_prompt->display_content : $first_prompt->article_content; $content_preview = mb_substr($parent_content, 0, 100); echo esc_html($content_preview . '...'); ?>
id); ?>
$preview_length) : ?>
source_url ?? ''; } if (!empty($actual_source) && strpos($actual_source, 'mxchat://') !== 0) : ?>
1) : ?>
1) : ?> 1) { echo '1 '; if ($start_page > 2) { echo '... '; } } for ($i = $start_page; $i <= $end_page; $i++) { if ($i == $current_page) { echo '' . $i . ' '; } else { echo '' . $i . ' '; } } if ($end_page < $total_pages) { if ($end_page < $total_pages - 1) { echo '... '; } echo '' . $total_pages . ' '; } ?>

_value span on input and autosaves on change (once per // drag release, so no request storm). Range/default/clamp // unchanged — presentation only. ?>

__('Public (Everyone)', 'mxchat'), 'logged_in' => __('Logged In Users', 'mxchat'), 'subscriber' => __('Subscribers & Above', 'mxchat'), 'contributor' => __('Contributors & Above', 'mxchat'), 'author' => __('Authors & Above', 'mxchat'), 'editor' => __('Editors & Above', 'mxchat'), 'administrator' => __('Administrators Only', 'mxchat') ); ?>

mxchat_get_all_acf_fields(); if (empty($all_acf_fields)): ?>
$group): $fields = $group['fields']; // Group toggle state derives from the per-field state — // never stored on its own (plan bf57e0). $excluded_count = 0; foreach ($fields as $field) { if (in_array($field['key'], $excluded_fields, true) || in_array($field['name'], $excluded_fields, true)) { $excluded_count++; } } $group_all_included = ($excluded_count === 0); $group_partial = ($excluded_count > 0 && $excluded_count < count($fields)); ?>

()

>

'mxch-btn mxch-btn-primary')); ?>
false, 'store_id' => ''); $mapped_count = class_exists('MxChat_Vectorstore_Manager') ? MxChat_Vectorstore_Manager::mapped_file_count() : 0; // Get current chat model to check compatibility $mxchat_options = get_option('mxchat_options', array()); $current_model = $mxchat_options['model'] ?? 'gpt-5.6-sol'; $is_openai_model = preg_match('/^(gpt-|o1-|o3-)/', $current_model); ?>

>

'mxch-btn mxch-btn-primary')); ?>

' . esc_html(number_format_i18n($mapped_count)) . ''); ?>


×
0

×

×