render_header( __('Knowledge Base', 'answerrails'), __('Manage your AI assistant\'s knowledge base and OpenAI vector store.', 'answerrails') ); // Show any settings errors/updates settings_errors(); // Get current values. #92: the key test is OPENAI-SPECIFIC (vector search // runs on OpenAI for every chat provider) — get_api_key() would return the // ACTIVE provider's key and misread a Mistral key as vector-capable. $api_key = AnswerRails_Utils::get_api_key_for('openai'); $vector_store_id = get_option('answerrails_knowledge_vector_store_id', ''); $engine = AnswerRails_Retrieval::engine(); // ⚠ #140 (DD10): the Settings tab is the ONE knowledge-settings surface — // there is no separate config view. First-run config-first semantics (key // present, no store) live in AnswerRails_Knowledge_Admin::current_tab(), // which lands on Settings. ?>
knowledge ? $this->knowledge->get_service() : null; $knowledge_admin = new AnswerRails_Knowledge_Admin($knowledge_service); // Add vector store status to the top ?>

✓ ⚠ ●

get_all_knowledge_items() as $ki) { // #138: a withdrawn item has no file id BY DESIGN (and no // chunks either) — it is withdrawn, not "local-only", and // the offered bulk sync would fail on its missing source. if (!empty($ki['source_error']['withdrawn'])) { continue; } if (empty($ki['openai_file_id'])) { $local_only++; } } if ($local_only > 0) : ?>

render_page(); ?>
render_footer();