403 ) ); } return true; } /** * Initialize the settings page */ public function init() { add_action( 'admin_init', array( $this, 'register_settings' ) ); add_action( 'admin_init', array( $this, 'handle_mcp_actions' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) ); add_action( 'wp_ajax_abilities_bridge_test_openai', array( $this, 'ajax_test_openai_connection' ) ); } /** * Enqueue CSS and JavaScript for settings page * * @param string $hook The current admin page hook. */ public function enqueue_assets( $hook ) { // Only load on settings page. // Hook format: {parent_slug}_page_{menu_slug}. if ( false === strpos( $hook, 'abilities-bridge-settings' ) ) { return; } $settings_css_version = filemtime( ABILITIES_BRIDGE_PLUGIN_DIR . 'admin/css/settings-page.css' ); $settings_js_version = filemtime( ABILITIES_BRIDGE_PLUGIN_DIR . 'admin/js/settings-page.js' ); wp_enqueue_style( 'abilities-bridge-settings-page', ABILITIES_BRIDGE_PLUGIN_URL . 'admin/css/settings-page.css', array(), $settings_css_version ? $settings_css_version : ABILITIES_BRIDGE_VERSION ); wp_enqueue_script( 'abilities-bridge-settings-page', ABILITIES_BRIDGE_PLUGIN_URL . 'admin/js/settings-page.js', array( 'jquery' ), $settings_js_version ? $settings_js_version : ABILITIES_BRIDGE_VERSION, true ); wp_localize_script( 'abilities-bridge-settings-page', 'abilitiesBridgeSettings', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'abilities_bridge_settings' ), 'memoryConsentGiven' => (bool) get_option( 'abilities_bridge_memory_consent', false ), 'i18n' => array( 'copied' => __( 'Copied!', 'abilities-bridge' ), 'copyFailed' => __( 'Failed to copy to clipboard', 'abilities-bridge' ), 'restorePromptConfirm' => __( 'Are you sure you want to restore the default system prompt? Your customizations will be lost.', 'abilities-bridge' ), 'openaiTestRunning' => __( 'Testing OpenAI connection...', 'abilities-bridge' ), 'openaiTestSuccess' => __( 'OpenAI connection successful.', 'abilities-bridge' ), 'openaiTestFailed' => __( 'OpenAI test failed.', 'abilities-bridge' ), 'openaiTestAjaxError' => __( 'OpenAI test could not be completed. Please try again.', 'abilities-bridge' ), ), 'defaultSystemPrompt' => Abilities_Bridge_Claude_API::get_default_system_prompt(), ) ); } /** * Register settings */ public function register_settings() { register_setting( 'abilities_bridge_settings', 'abilities_bridge_api_key', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '', ) ); register_setting( 'abilities_bridge_settings', 'abilities_bridge_openai_api_key', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '', ) ); register_setting( 'abilities_bridge_settings', 'abilities_bridge_enable_memory', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => false, ) ); register_setting( 'abilities_bridge_settings', 'abilities_bridge_memory_consent', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => false, ) ); add_settings_section( 'abilities_bridge_api_section', __( 'AI Provider Configuration', 'abilities-bridge' ), array( $this, 'render_section' ), 'abilities-bridge-settings' ); add_settings_field( 'abilities_bridge_api_key', __( 'Anthropic API Key', 'abilities-bridge' ), array( $this, 'render_api_key_field' ), 'abilities-bridge-settings', 'abilities_bridge_api_section' ); add_settings_field( 'abilities_bridge_openai_api_key', __( 'OpenAI API Key', 'abilities-bridge' ), array( $this, 'render_openai_api_key_field' ), 'abilities-bridge-settings', 'abilities_bridge_api_section' ); // System Prompt setting. register_setting( 'abilities_bridge_settings', 'abilities_bridge_system_prompt', array( 'type' => 'string', 'sanitize_callback' => 'wp_kses_post', 'default' => '', ) ); add_settings_section( 'abilities_bridge_prompt_section', __( 'System Prompt', 'abilities-bridge' ), array( $this, 'render_prompt_section' ), 'abilities-bridge-settings' ); add_settings_field( 'abilities_bridge_system_prompt', __( 'System Prompt', 'abilities-bridge' ), array( $this, 'render_system_prompt_field' ), 'abilities-bridge-settings', 'abilities_bridge_prompt_section' ); // Memory settings (for separate Memory tab). // Memory tool settings. register_setting( 'abilities_bridge_builtin_tools', 'abilities_bridge_enable_memory', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => false, ) ); register_setting( 'abilities_bridge_builtin_tools', 'abilities_bridge_memory_consent', array( 'type' => 'boolean', 'sanitize_callback' => array( $this, 'validate_memory_consent' ), 'default' => false, ) ); } /** * Validate memory consent * * Ensures that if memory is being enabled, consent must be given. * * @param bool $value The consent value being saved. * @return bool The validated consent value. */ public function validate_memory_consent( $value ) { // Sanitize the boolean value first. $value = rest_sanitize_boolean( $value ); // Check if memory is being enabled (from POST data). // Settings API sanitize callbacks are called after nonce verification by options.php. $enable_memory_raw = filter_input( INPUT_POST, 'abilities_bridge_enable_memory', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); $enable_memory = rest_sanitize_boolean( $enable_memory_raw ); // If memory is enabled but consent is not given, show error and prevent enabling. if ( $enable_memory && ! $value ) { add_settings_error( 'abilities_bridge_memory_consent', 'memory_consent_required', __( 'You must check the consent box to enable the Memory Tool.', 'abilities-bridge' ), 'error' ); // Also prevent memory from being enabled by resetting it. update_option( 'abilities_bridge_enable_memory', false ); // Return false to prevent consent from being saved as true. return false; } return $value; } /** * Render section description */ public function render_section() { ?>
Anthropic Console.', 'abilities-bridge' ), array( 'a' => array( 'href' => array(), 'target' => array(), ), ) ), esc_url( 'https://console.anthropic.com/' ) ); ?>
' . esc_html( $model ) . '' ); ?>
__( 'Insufficient permissions.', 'abilities-bridge' ) ) ); } $provider = Abilities_Bridge_AI_Provider::PROVIDER_OPENAI; $model = Abilities_Bridge_AI_Provider::get_selected_model( $provider ); if ( ! Abilities_Bridge_AI_Provider::has_api_key( $provider ) ) { wp_send_json_error( array( 'code' => 'no_api_key', 'message' => __( 'OpenAI API key is not configured.', 'abilities-bridge' ), 'model' => $model, ) ); } $openai_client = Abilities_Bridge_AI_Provider::create_client( $provider ); $result = $openai_client->send_message( array( array( 'role' => 'user', 'content' => 'Return exactly: OK', ), ), array(), 32, $model ); if ( is_wp_error( $result ) ) { $error_data = $result->get_error_data(); wp_send_json_error( array( 'code' => $result->get_error_code(), 'message' => $result->get_error_message(), 'model' => $model, 'provider' => 'openai', 'status' => isset( $error_data['status'] ) ? intval( $error_data['status'] ) : null, 'provider_msg' => isset( $error_data['provider_message'] ) ? sanitize_text_field( $error_data['provider_message'] ) : '', ) ); } wp_send_json_success( array( 'message' => __( 'OpenAI test succeeded.', 'abilities-bridge' ), 'model' => $model, ) ); } /** * Render system prompt section description */ public function render_prompt_section() { ?>
Database (abilities_bridge_memories table)' ); ?>
⚠️ SECURITY NOTICE: ONE-TIME VIEW
|
| ✓ ✗ |