getParameters(); $type = isset( $params[0] ) ? $params[0]->getType() : null; } catch ( \ReflectionException $e ) { return false; } return $type instanceof \ReflectionNamedType && 'Psr\\SimpleCache\\CacheInterface' === ltrim( $type->getName(), '\\' ); } /** * Registers the ChatGPT provider with the WordPress AI Client. * * Registration happens unconditionally so the connector is discoverable in * the AI picker even before the admin imports an auth bundle. When no tokens * are stored, the availability check will mark the provider as unavailable * and the SettingsPage tells the admin how to connect. * * @since 0.1.0 * * @return void */ function register_provider(): void { if ( ! class_exists( AiClient::class ) ) { return; } // Wire a transient-backed PSR-16 cache so the SDK's `/models` lookup is // persisted across requests. Without this the SDK falls back to a // per-request in-memory array, which means the /models endpoint // is hit on every admin page load. Idempotent if called more than once. if ( null === AiClient::getCache() && can_use_transient_cache() ) { AiClient::setCache( new TransientCache() ); } $registry = AiClient::defaultRegistry(); if ( ! $registry->hasProvider( ChatGptProvider::class ) ) { $registry->registerProvider( ChatGptProvider::class ); } /* * Plant a placeholder ApiKeyRequestAuthentication in the registry when a * token bundle is present. The SDK uses this to flip the provider's * "configured" flag for WP core's AI picker. The placeholder is never * actually used to authenticate requests — our model classes override * getRequestAuthentication() to return ChatGptAccountAuthentication. */ if ( ( new TokenStore() )->get_access_token() !== null ) { try { $registry->setProviderRequestAuthentication( ChatGptProvider::class, new ApiKeyRequestAuthentication( TokenStore::CORE_API_KEY_PLACEHOLDER ) ); } catch ( \Throwable $e ) { // Registry not ready or auth-type mismatch; provider stays usable. if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Diagnostic under WP_DEBUG only. error_log( 'ai-provider-for-chatgpt: registry auth wiring failed: ' . $e->getMessage() ); } } } } add_action( 'init', __NAMESPACE__ . '\\register_provider', 5 ); /** * Registers the REST routes that back the React settings UI. * * @since 0.1.0 * * @return void */ function register_rest_controllers(): void { $store = new TokenStore(); ( new ConnectionController( $store ) )->register_routes(); ( new DiagnosticsController( $store ) )->register_routes(); ( new CacheController() )->register_routes(); ( new SettingsController() )->register_routes(); } add_action( 'rest_api_init', __NAMESPACE__ . '\\register_rest_controllers' ); ModelSettings::register(); add_action( TokenRefresher::CRON_HOOK, array( TokenRefresher::class, 'run_cron' ) ); /** * Schedules the weekly refresh when a live connection already exists. * * @since 1.0.0 * * @return void */ function activate(): void { if ( ( new TokenStore() )->is_connected() ) { TokenRefresher::schedule(); } } /** * Removes the weekly refresh; the connection itself is kept. * * @since 1.0.0 * * @return void */ function deactivate(): void { TokenRefresher::unschedule(); } register_activation_hook( __FILE__, __NAMESPACE__ . '\\activate' ); register_deactivation_hook( __FILE__, __NAMESPACE__ . '\\deactivate' ); if ( is_admin() ) { ( new SettingsPage() )->register(); ( new Assets() )->register(); ( new Upgrade() )->register(); }