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:
@@ -122,6 +122,34 @@ interface PRAutoBlogger_Source_Provider_Interface {
|
||||
|
||||
---
|
||||
|
||||
## How To: Add a New Image Provider
|
||||
|
||||
1. Create `includes/providers/class-{name}-image-provider.php`
|
||||
2. Implement `PRAutoBlogger_Image_Provider_Interface` (see `interface-image-provider.php`)
|
||||
3. Required methods: `generate_image()`, `estimate_cost()`, `get_provider_name()`, `validate_credentials_detailed()`
|
||||
4. Split helpers into companions if you'd exceed the 300-line cap. The Cloudflare provider splits into provider + pricing + validator — mirror that shape.
|
||||
5. Add API credentials fields to `admin/class-settings-fields.php` under the `prautoblogger_images` section
|
||||
6. Register the provider in `class-prautoblogger.php` loader once the image pipeline lands (commit 1b of the image workstream)
|
||||
7. Update `ARCHITECTURE.md` file tree, external API integrations table, and the options table
|
||||
|
||||
### Interface contract:
|
||||
```php
|
||||
interface PRAutoBlogger_Image_Provider_Interface {
|
||||
public function generate_image( string $prompt, int $width, int $height, array $options = [] ): array; // {bytes, mime_type, width, height, model, seed, cost_usd, latency_ms}
|
||||
public function estimate_cost( int $width, int $height, array $options = [] ): float;
|
||||
public function get_provider_name(): string; // e.g., 'cloudflare_workers_ai'
|
||||
public function validate_credentials_detailed(): array; // {status, message, debug?}
|
||||
}
|
||||
```
|
||||
|
||||
### Retry + cost rules (non-negotiable)
|
||||
- 5xx / 429 / network errors: retry with exponential backoff up to `PRAUTOBLOGGER_MAX_RETRIES`, respect `Retry-After` when present.
|
||||
- 4xx other than 429: fail loudly on the first response — never retry a deterministic bad request.
|
||||
- Validation check must be non-destructive (no image generation).
|
||||
- Every attempt logs via `PRAutoBlogger_Logger` with context `{provider-slug}-image`.
|
||||
|
||||
---
|
||||
|
||||
## How To: Add a New Admin Setting
|
||||
|
||||
1. Define the option key in the settings array in `admin/class-admin-page.php` → `get_settings_fields()` method
|
||||
|
||||
Reference in New Issue
Block a user