From fad585c0ccb55fc901061d80a64b7fa98ef995fc Mon Sep 17 00:00:00 2001 From: peptiderepo Date: Sat, 25 Apr 2026 20:41:49 +0000 Subject: [PATCH] feat: expand image model registry to 21 models (v0.13.8) --- CHANGELOG.md | 16 ++ includes/admin/class-image-model-registry.php | 148 ++++++++++++++++-- prautoblogger.php | 4 +- .../unit/Services/ImageModelRegistryTest.php | 52 ++++++ 4 files changed, 204 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53b3cdc..57a0f54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +All notable changes to PRAutoBlogger will be documented in this file. + +Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project uses [Semantic Versioning](https://semver.org/). + +## [0.13.8] - 2026-04-26 + +### Added +- Image model picker expanded from 7 to 21 models +- New Runware text-to-image models: Stable Diffusion 3, HiDream-I1 Full/Dev/Fast, + FLUX.1 Krea [dev], Qwen-Image, FLUX.2 [dev], FLUX.2 [klein] 9B, FLUX.2 [klein] 4B, + GLM-Image, Z-Image, Z-Image-Turbo, TwinFlow Z-Image-Turbo +- New OpenRouter model: openai/gpt-5.4-image-2 +- Registry now includes last-verified date and update instructions in source comment + + All notable changes to PRAutoBlogger will be documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), diff --git a/includes/admin/class-image-model-registry.php b/includes/admin/class-image-model-registry.php index 241c986..ae8e70b 100644 --- a/includes/admin/class-image-model-registry.php +++ b/includes/admin/class-image-model-registry.php @@ -8,6 +8,8 @@ declare(strict_types=1); * * What: Returns a hardcoded list of image models for the admin model picker. * No API discovery — updated manually when providers add/remove models. + * As of 2026-04-26, registry includes 21 models across Runware (15) and + * OpenRouter (6), ordered cheapest-to-most-expensive within each provider. * Who calls it: PRAutoBlogger_Admin_Page (model picker UI + save-time provider * derivation) and PRAutoBlogger_Image_Pipeline (provider lookup). * Dependencies: None. @@ -32,10 +34,15 @@ class PRAutoBlogger_Image_Model_Registry { * Ordered cheapest-to-most-expensive within each provider, with the * recommended default (Runware schnell) at the top. * + * Last verified: 2026-04-26. To update: check https://runware.ai/models (text-to-image section) + * and https://openrouter.ai/api/v1/models filtering output_modalities containing 'image'. + * Exclude: inpainting (needs mask), img2img (needs seedImage), video, upscalers, background removal. + * * @return array> */ public static function get_models(): array { return array( + // RUNWARE MODELS array( 'id' => 'runware:100@1', 'name' => 'FLUX.1 schnell (Runware)', @@ -44,17 +51,122 @@ class PRAutoBlogger_Image_Model_Registry { 'capabilities' => array( 'image_generation' ), 'description' => __( 'Default. Fast, very cheap, comic-friendly fidelity.', 'prautoblogger' ), ), + array( + 'id' => 'runware:twinflow-z-image-turbo@0', + 'name' => 'TwinFlow Z-Image-Turbo (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0006, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'Fast text-to-image, same cost as schnell.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:400@2', + 'name' => 'FLUX.2 klein 9B (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.00078, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'FLUX.2 compact 9B. Stronger than schnell at similar cost.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:400@4', + 'name' => 'FLUX.2 klein 4B (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0006, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'FLUX.2 compact 4B. Newer architecture at schnell price.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:5@1', + 'name' => 'Stable Diffusion 3 (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0013, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'Stable Diffusion 3. Sharp text, complex scenes.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:z-image@turbo', + 'name' => 'Z-Image Turbo (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0013, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'Fast photorealistic generation.', 'prautoblogger' ), + ), array( 'id' => 'runware:101@1', 'name' => 'FLUX.1 dev (Runware)', 'provider' => 'runware', 'cost_per_image' => 0.02, 'capabilities' => array( 'image_generation' ), - 'description' => __( 'Higher fidelity FLUX. ~30x schnell cost.', 'prautoblogger' ), + 'description' => __( 'Higher fidelity FLUX.1. ~30x schnell cost.', 'prautoblogger' ), ), + array( + 'id' => 'runware:97@3', + 'name' => 'HiDream-I1 Fast (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0038, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'HiDream-I1 Fast. Low latency, 17B quality.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:97@2', + 'name' => 'HiDream-I1 Dev (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0045, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'HiDream-I1 Dev. Strong prompt alignment.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:z-image@0', + 'name' => 'Z-Image (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0045, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'High-quality Z-Image foundation model.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:400@1', + 'name' => 'FLUX.2 dev (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0051, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'FLUX.2 dev. Controllable open text-to-image. From $0.0051.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:108@1', + 'name' => 'Qwen-Image (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0058, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'Alibaba Qwen-Image. Strong text rendering in generated images.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:97@1', + 'name' => 'HiDream-I1 Full (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.009, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'HiDream-I1 Full. 17B high-fidelity, LoRA support.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:107@1', + 'name' => 'FLUX.1 Krea dev (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0098, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'FLUX.1 Krea Dev. Photorealistic open-weight generation.', 'prautoblogger' ), + ), + array( + 'id' => 'runware:glm-image@0', + 'name' => 'GLM-Image (Runware)', + 'provider' => 'runware', + 'cost_per_image' => 0.0225, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'GLM-Image. Hybrid autoregressive+diffusion, excellent text rendering.', 'prautoblogger' ), + ), + // OPENROUTER MODELS array( 'id' => 'google/gemini-2.5-flash-image', - 'name' => 'Gemini 2.5 Flash Image (Nano Banana)', + 'name' => 'Gemini 2.5 Flash Image (OpenRouter)', 'provider' => 'openrouter', 'cost_per_image' => 0.005, 'capabilities' => array( 'image_generation' ), @@ -62,31 +174,39 @@ class PRAutoBlogger_Image_Model_Registry { ), array( 'id' => 'google/gemini-3.1-flash-image-preview', - 'name' => 'Gemini 3.1 Flash Image (Nano Banana 2)', + 'name' => 'Gemini 3.1 Flash Image (OpenRouter)', 'provider' => 'openrouter', 'cost_per_image' => 0.008, 'capabilities' => array( 'image_generation' ), - 'description' => __( 'Latest Google. Better quality.', 'prautoblogger' ), - ), - array( - 'id' => 'google/gemini-3-pro-image-preview', - 'name' => 'Gemini 3 Pro Image (Nano Banana Pro)', - 'provider' => 'openrouter', - 'cost_per_image' => 0.03, - 'capabilities' => array( 'image_generation' ), - 'description' => __( 'Highest quality Google. Premium.', 'prautoblogger' ), + 'description' => __( 'Latest Google Flash image. Better quality.', 'prautoblogger' ), ), array( 'id' => 'openai/gpt-5-image-mini', - 'name' => 'GPT-5 Image Mini', + 'name' => 'GPT-5 Image Mini (OpenRouter)', 'provider' => 'openrouter', 'cost_per_image' => 0.02, 'capabilities' => array( 'image_generation' ), 'description' => __( 'OpenAI budget image model.', 'prautoblogger' ), ), + array( + 'id' => 'openai/gpt-5.4-image-2', + 'name' => 'GPT-5.4 Image 2 (OpenRouter)', + 'provider' => 'openrouter', + 'cost_per_image' => 0.02, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'OpenAI GPT-5.4 image generation.', 'prautoblogger' ), + ), + array( + 'id' => 'google/gemini-3-pro-image-preview', + 'name' => 'Gemini 3 Pro Image (OpenRouter)', + 'provider' => 'openrouter', + 'cost_per_image' => 0.03, + 'capabilities' => array( 'image_generation' ), + 'description' => __( 'Highest quality Google image. Premium.', 'prautoblogger' ), + ), array( 'id' => 'openai/gpt-5-image', - 'name' => 'GPT-5 Image', + 'name' => 'GPT-5 Image (OpenRouter)', 'provider' => 'openrouter', 'cost_per_image' => 0.08, 'capabilities' => array( 'image_generation' ), diff --git a/prautoblogger.php b/prautoblogger.php index 18d85fd..0647c1e 100644 --- a/prautoblogger.php +++ b/prautoblogger.php @@ -9,7 +9,7 @@ * Plugin Name: PRAutoBlogger * Plugin URI: https://peptiderepo.com/prautoblogger * Description: Monitors social media for trending topics, generates SEO-friendly blog posts using AI, and publishes them on a daily schedule with full cost tracking and self-improvement metrics. - * Version: 0.13.7 + * Version: 0.13.8 * Requires at least: 6.0 * Requires PHP: 7.4 * Author: PeptideRepo @@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) { | Defined here so every file in the plugin can reference paths, versions, | and limits without magic strings. */ -define( 'PRAUTOBLOGGER_VERSION', '0.13.7' ); +define( 'PRAUTOBLOGGER_VERSION', '0.13.8' ); define( 'PRAUTOBLOGGER_DB_VERSION', '1.1.0' ); define( 'PRAUTOBLOGGER_PLUGIN_FILE', __FILE__ ); define( 'PRAUTOBLOGGER_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); diff --git a/tests/unit/Services/ImageModelRegistryTest.php b/tests/unit/Services/ImageModelRegistryTest.php index 73590b9..77359e3 100644 --- a/tests/unit/Services/ImageModelRegistryTest.php +++ b/tests/unit/Services/ImageModelRegistryTest.php @@ -99,4 +99,56 @@ class ImageModelRegistryTest extends BaseTestCase { \PRAutoBlogger_Image_Model_Registry::provider_for( '' ) ); } + + /** + * Test that runware:400@4 resolves to runware provider. + */ + public function test_provider_for_runware_400_at_4(): void { + $this->assertSame( + 'runware', + \PRAutoBlogger_Image_Model_Registry::provider_for( 'runware:400@4' ) + ); + } + + /** + * Test that runware:glm-image@0 resolves to runware provider. + */ + public function test_provider_for_runware_glm_image(): void { + $this->assertSame( + 'runware', + \PRAutoBlogger_Image_Model_Registry::provider_for( 'runware:glm-image@0' ) + ); + } + + /** + * Test that openai/gpt-5.4-image-2 resolves to openrouter provider. + */ + public function test_provider_for_gpt_5_4_image_2(): void { + $this->assertSame( + 'openrouter', + \PRAutoBlogger_Image_Model_Registry::provider_for( 'openai/gpt-5.4-image-2' ) + ); + } + + /** + * Test that get_models() returns 21 models. + */ + public function test_get_models_returns_21_models(): void { + $models = \PRAutoBlogger_Image_Model_Registry::get_models(); + $this->assertCount( 21, $models ); + } + + /** + * Test that every model has required non-empty fields. + */ + public function test_every_model_has_required_fields(): void { + $models = \PRAutoBlogger_Image_Model_Registry::get_models(); + foreach ( $models as $model ) { + $this->assertNotEmpty( $model['id'] ?? '', 'Model missing id' ); + $this->assertNotEmpty( $model['name'] ?? '', 'Model missing name' ); + $this->assertNotEmpty( $model['provider'] ?? '', 'Model missing provider' ); + $this->assertTrue( isset( $model['cost_per_image'] ), 'Model missing cost_per_image' ); + $this->assertIsNumeric( $model['cost_per_image'], 'cost_per_image is not numeric' ); + } + } }