'string', 'sanitize_callback' => 'sanitize_text_field', ) ); } /** * Renders the settings page. * * @since 1.0.0 * * @return void */ public function render_settings_page(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have sufficient permissions.', 'ai-provider-for-kimi' ) ); } $models = self::fetch_models( self::get_api_key() ); $default_model = get_option( self::OPTION_DEFAULT_MODEL, '' ); ?>

__( 'Context length:', 'ai-provider-for-kimi' ), 'capabilities' => __( 'Capabilities:', 'ai-provider-for-kimi' ), 'pricing' => __( 'Pricing (per 1M tokens):', 'ai-provider-for-kimi' ), 'in' => __( 'In', 'ai-provider-for-kimi' ), 'out' => __( 'Out', 'ai-provider-for-kimi' ), 'cache' => __( 'Cache', 'ai-provider-for-kimi' ), ) ); ?>
invalidateCaches(); delete_transient( self::MODELS_TRANSIENT ); } /** * Enqueues admin assets for the settings page. * * @since 1.0.0 * * @param string $hook_suffix The current admin page hook. * @return void */ public function enqueue_assets( string $hook_suffix ): void { if ( 'settings_page_ai-provider-for-kimi' !== $hook_suffix ) { return; } $plugin_url = plugin_dir_url( dirname( __DIR__, 2 ) . '/ai-provider-for-kimi.php' ); wp_enqueue_style( 'ai-provider-for-kimi-admin', $plugin_url . 'assets/css/admin-settings.css', array(), '1.0.0' ); wp_enqueue_script( 'ai-provider-for-kimi-admin', $plugin_url . 'assets/js/admin-settings.js', array(), '1.0.0', true ); } /** * Fetches the list of available models from the Kimi API. * * @since 1.0.0 * * @param string $api_key The API key to use for the request. * @return array> Associative array of model IDs to model metadata. */ private static function fetch_models( string $api_key ): array { $cached = get_transient( self::MODELS_TRANSIENT ); if ( is_array( $cached ) && ! empty( $cached ) ) { return $cached; } if ( '' !== $api_key ) { $response = wp_remote_get( 'https://api.moonshot.ai/v1/models', array( 'headers' => array( 'Authorization' => 'Bearer ' . $api_key, ), 'timeout' => 10, ) ); if ( ! is_wp_error( $response ) ) { $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( is_array( $data ) && isset( $data['data'] ) && is_array( $data['data'] ) ) { $models = array(); foreach ( $data['data'] as $model ) { if ( ! is_array( $model ) || ! isset( $model['id'] ) || ! is_string( $model['id'] ) ) { continue; } $model_id = $model['id']; $models[ $model_id ] = array( 'id' => $model_id, 'context_length' => isset( $model['context_length'] ) && is_numeric( $model['context_length'] ) ? (int) $model['context_length'] : 0, 'supports_image_in' => ! empty( $model['supports_image_in'] ), 'supports_video_in' => ! empty( $model['supports_video_in'] ), 'supports_reasoning' => ! empty( $model['supports_reasoning'] ), 'pricing' => self::get_model_pricing( $model_id ), 'description' => self::get_model_description( $model_id ), ); } if ( ! empty( $models ) ) { set_transient( self::MODELS_TRANSIENT, $models, HOUR_IN_SECONDS ); return $models; } } } } return self::get_fallback_models(); } /** * Returns the fallback model list when the API is unreachable. * * @since 1.0.0 * * @return array> Fallback model metadata. */ private static function get_fallback_models(): array { return array( 'kimi-k2.6' => array( 'id' => 'kimi-k2.6', 'context_length' => 256000, 'supports_image_in' => true, 'supports_video_in' => true, 'supports_reasoning' => true, 'pricing' => null, 'description' => __( 'Kimi K2.6: Advanced multimodal reasoning model with extended context.', 'ai-provider-for-kimi' ), ), 'kimi-k2.5' => array( 'id' => 'kimi-k2.5', 'context_length' => 256000, 'supports_image_in' => true, 'supports_video_in' => true, 'supports_reasoning' => true, 'pricing' => array( 'input' => 0.60, 'output' => 3.00, 'cache_hit' => 0.10, ), 'description' => __( 'Kimi K2.5: 256K context, supports images, video, and reasoning.', 'ai-provider-for-kimi' ), ), 'moonshot-v1-128k' => array( 'id' => 'moonshot-v1-128k', 'context_length' => 128000, 'supports_image_in' => false, 'supports_video_in' => false, 'supports_reasoning' => false, 'pricing' => array( 'input' => 2.00, 'output' => 5.00, 'cache_hit' => null, ), 'description' => __( 'Moonshot V1 128K: General-purpose model with 128K context.', 'ai-provider-for-kimi' ), ), 'moonshot-v1-32k' => array( 'id' => 'moonshot-v1-32k', 'context_length' => 32000, 'supports_image_in' => false, 'supports_video_in' => false, 'supports_reasoning' => false, 'pricing' => array( 'input' => 1.00, 'output' => 3.00, 'cache_hit' => null, ), 'description' => __( 'Moonshot V1 32K: General-purpose model with 32K context.', 'ai-provider-for-kimi' ), ), 'moonshot-v1-8k' => array( 'id' => 'moonshot-v1-8k', 'context_length' => 8000, 'supports_image_in' => false, 'supports_video_in' => false, 'supports_reasoning' => false, 'pricing' => array( 'input' => 0.20, 'output' => 2.00, 'cache_hit' => null, ), 'description' => __( 'Moonshot V1 8K: General-purpose model with 8K context.', 'ai-provider-for-kimi' ), ), 'moonshot-v1-128k-vision-preview' => array( 'id' => 'moonshot-v1-128k-vision-preview', 'context_length' => 128000, 'supports_image_in' => true, 'supports_video_in' => false, 'supports_reasoning' => false, 'pricing' => array( 'input' => 2.00, 'output' => 5.00, 'cache_hit' => null, ), 'description' => __( 'Moonshot V1 128K Vision: Vision-enabled variant with 128K context.', 'ai-provider-for-kimi' ), ), 'moonshot-v1-32k-vision-preview' => array( 'id' => 'moonshot-v1-32k-vision-preview', 'context_length' => 32000, 'supports_image_in' => true, 'supports_video_in' => false, 'supports_reasoning' => false, 'pricing' => array( 'input' => 1.00, 'output' => 3.00, 'cache_hit' => null, ), 'description' => __( 'Moonshot V1 32K Vision: Vision-enabled variant with 32K context.', 'ai-provider-for-kimi' ), ), 'moonshot-v1-8k-vision-preview' => array( 'id' => 'moonshot-v1-8k-vision-preview', 'context_length' => 8000, 'supports_image_in' => true, 'supports_video_in' => false, 'supports_reasoning' => false, 'pricing' => array( 'input' => 0.20, 'output' => 2.00, 'cache_hit' => null, ), 'description' => __( 'Moonshot V1 8K Vision: Vision-enabled variant with 8K context.', 'ai-provider-for-kimi' ), ), ); } /** * Gets pricing metadata for a model. * * @since 1.0.0 * * @param string $model_id The model identifier. * @return array|null Pricing data or null if unknown. */ private static function get_model_pricing( string $model_id ): ?array { $base_id = str_replace( '-vision-preview', '', $model_id ); $map = array( 'kimi-k2.5' => array( 'input' => 0.60, 'output' => 3.00, 'cache_hit' => 0.10, ), 'moonshot-v1-8k' => array( 'input' => 0.20, 'output' => 2.00, 'cache_hit' => null, ), 'moonshot-v1-32k' => array( 'input' => 1.00, 'output' => 3.00, 'cache_hit' => null, ), 'moonshot-v1-128k' => array( 'input' => 2.00, 'output' => 5.00, 'cache_hit' => null, ), ); return $map[ $base_id ] ?? null; } /** * Generates a human-readable description for a model. * * @since 1.0.0 * * @param string $model_id The model identifier. * @return string The model description. */ private static function get_model_description( string $model_id ): string { if ( str_starts_with( $model_id, 'kimi-k2.6' ) ) { return __( 'Kimi K2.6: Advanced multimodal reasoning model with extended context.', 'ai-provider-for-kimi' ); } if ( str_starts_with( $model_id, 'kimi-k2.5' ) ) { return __( 'Kimi K2.5: 256K context, supports images, video, and reasoning.', 'ai-provider-for-kimi' ); } if ( str_starts_with( $model_id, 'moonshot-v1-128k-vision' ) ) { return __( 'Moonshot V1 128K Vision: Vision-enabled variant with 128K context.', 'ai-provider-for-kimi' ); } if ( str_starts_with( $model_id, 'moonshot-v1-128k' ) ) { return __( 'Moonshot V1 128K: General-purpose model with 128K context.', 'ai-provider-for-kimi' ); } if ( str_starts_with( $model_id, 'moonshot-v1-32k-vision' ) ) { return __( 'Moonshot V1 32K Vision: Vision-enabled variant with 32K context.', 'ai-provider-for-kimi' ); } if ( str_starts_with( $model_id, 'moonshot-v1-32k' ) ) { return __( 'Moonshot V1 32K: General-purpose model with 32K context.', 'ai-provider-for-kimi' ); } if ( str_starts_with( $model_id, 'moonshot-v1-8k-vision' ) ) { return __( 'Moonshot V1 8K Vision: Vision-enabled variant with 8K context.', 'ai-provider-for-kimi' ); } if ( str_starts_with( $model_id, 'moonshot-v1-8k' ) ) { return __( 'Moonshot V1 8K: General-purpose model with 8K context.', 'ai-provider-for-kimi' ); } return __( 'Moonshot AI model.', 'ai-provider-for-kimi' ); } }