feat(images): Cloudflare Workers AI image provider (commit 1a)
First commit of the image + Instagram A/B pipeline workstream. Ships the Cloudflare Workers AI image provider, its pricing + validator helpers, four new settings fields in a new "Images" admin section, and unit tests with mocked HTTP. Nothing calls the provider yet from the article pipeline — integration lands in commit 1b. Why: CEO-approved on 2026-04-15 (see convo/prautoblogger/threads/2026-04-image-pipeline/01-cto-handoff.md). Style is locked to the 90s infomercial pastiche; default model is FLUX.1 [schnell] at ~$0.0011/MP (~$0.01/article for 8 images across 4 placements x 2 variants). Risk flags: - Direct call to Cloudflare Workers AI bypassing AI Gateway (decision D-001, documented in convo/prautoblogger/decisions/). Gateway route to Workers AI currently 403s; OpenRouter gateway path unaffected. - prab_event_log structured writes deferred to commit 1b when the table lands (decision D-002). Logger-based logging is in place now. - No schema changes. No existing code paths touched outside settings. - Backward compatible: provider is instantiable but not wired to any consumer yet. Test plan: - CI runs PHPUnit including the new CloudflareImageProviderTest. - After merge: verify the new Images section appears on the settings page, the style-suffix textarea pre-fills with the infomercial prompt, and entering the existing CLOUDFLARE_AI_TOKEN + account UUID lets a future "Test Connection" button return OK (button ships in a later commit; the underlying validate_credentials_detailed() works today). Files: - includes/providers/interface-image-provider.php (adopted from CTO draft) - includes/providers/class-cloudflare-image-provider.php (283 lines) - includes/providers/class-cloudflare-image-pricing.php (78 lines) - includes/providers/class-cloudflare-image-validator.php (107 lines) - includes/admin/class-settings-fields.php (+ Images section, 4 fields) - prautoblogger.php (+ PRAUTOBLOGGER_DEFAULT_IMAGE_MODEL, _STYLE_SUFFIX) - tests/unit/Providers/CloudflareImageProviderTest.php - ARCHITECTURE.md (file tree, integrations table, options table, decision #16) - CONVENTIONS.md (How To: Add a New Image Provider) - CHANGELOG.md (Unreleased section) Agent-Session: cowork-2026-04-15-image-pipeline-commit-1a
This commit is contained in:
@@ -57,6 +57,11 @@ class PRAutoBlogger_Settings_Fields {
|
||||
'icon' => 'dashicons-chart-area',
|
||||
'description' => __( 'Connect Google Analytics 4 for post performance scoring.', 'prautoblogger' ),
|
||||
],
|
||||
'prautoblogger_images' => [
|
||||
'title' => __( 'Images', 'prautoblogger' ),
|
||||
'icon' => 'dashicons-format-image',
|
||||
'description' => __( 'Cloudflare Workers AI credentials and image style controls.', 'prautoblogger' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -329,6 +334,45 @@ class PRAutoBlogger_Settings_Fields {
|
||||
'section' => 'prautoblogger_analytics',
|
||||
'description' => __( 'Paste the full JSON key file for a service account with Analytics read access.', 'prautoblogger' ),
|
||||
],
|
||||
|
||||
// ── Images ─────────────────────────────────────────────────
|
||||
[
|
||||
'id' => 'prautoblogger_cloudflare_ai_token',
|
||||
'label' => __( 'Cloudflare API Token', 'prautoblogger' ),
|
||||
'type' => 'password',
|
||||
'section' => 'prautoblogger_images',
|
||||
'description' => __( 'Workers AI token with Read + Edit scope. Create at dash.cloudflare.com → AI → API Tokens.', 'prautoblogger' ),
|
||||
'icon' => '🔑',
|
||||
],
|
||||
[
|
||||
'id' => 'prautoblogger_cloudflare_account_id',
|
||||
'label' => __( 'Cloudflare Account ID', 'prautoblogger' ),
|
||||
'type' => 'text',
|
||||
'section' => 'prautoblogger_images',
|
||||
'default' => '',
|
||||
'description' => __( 'The Account ID shown on your Cloudflare dashboard sidebar. Used to build the Workers AI URL.', 'prautoblogger' ),
|
||||
],
|
||||
[
|
||||
'id' => 'prautoblogger_image_model',
|
||||
'label' => __( 'Image Model', 'prautoblogger' ),
|
||||
'type' => 'select',
|
||||
'section' => 'prautoblogger_images',
|
||||
'default' => PRAUTOBLOGGER_DEFAULT_IMAGE_MODEL,
|
||||
'options' => [
|
||||
'flux-1-schnell' => __( 'FLUX.1 [schnell] — fast + cheap (default)', 'prautoblogger' ),
|
||||
'flux-1-dev' => __( 'FLUX.1 [dev] — higher quality, ~4× cost', 'prautoblogger' ),
|
||||
],
|
||||
'description' => __( 'Schnell is the normal choice. Only switch to [dev] when a specific post needs higher quality.', 'prautoblogger' ),
|
||||
'badge' => __( 'Low cost', 'prautoblogger' ),
|
||||
],
|
||||
[
|
||||
'id' => 'prautoblogger_image_style_suffix',
|
||||
'label' => __( 'Style Suffix', 'prautoblogger' ),
|
||||
'type' => 'textarea',
|
||||
'section' => 'prautoblogger_images',
|
||||
'default' => PRAUTOBLOGGER_DEFAULT_IMAGE_STYLE_SUFFIX,
|
||||
'description' => __( 'Appended to every image prompt. Controls the visual look across all placements. Changing this mid-run will cause visible style drift — prefer changing during quiet periods.', 'prautoblogger' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user