v0.11.0 — OpenRouter model picker (#111)
v0.11.0 — OpenRouter model picker (AJAX refresh + cost preview + Phase-2 asset extract) Replaces the free-text slug inputs for analysis_model, writing_model, and editor_model with a smart picker fed by a daily-refreshed OpenRouter model registry. Picker shows context size + input/output price + provider, filters by per-field capability, previews per-generation cost using existing cost-tracker history, and keeps a custom-slug fallback. Daily registry refresh fires from inside on_daily_generation() before lock acquire — no new top-level cron event. Commit sequence (preserved for review): -353aa4efeat(models): OpenRouter model picker + AJAX refresh + cost preview -283fa55fix(phpcs): resolve 4 PHPCS violations in model-registry-refresh handler -1b1336astyle(phpcs): fix array syntax in model field + cost tracker -283f9f9style(phpcs): fix tabs vs spaces in settings-page.php -aa78591refactor(assets): extract model-picker refresh handler to generic-handle file Verification - PHPCS strict (CI scope): 0 errors / 0 warnings - PHPUnit: 206/206 (555 assertions, 2 pre-existing skips) - All new files under 300-line cap (field renderer 163, AJAX handler 82) - Security: AJAX nonce + manage_options cap; output escaped; input sanitized - Phase 2 ready: zero PRAUTOBLOGGER_* coupling in registry/picker/AJAX classes; generic asset handle peptiderepo-model-picker QA verdict: PASS (qa-reviews/prautoblogger/2026-04-23-aa78591.md) Out of scope (untouched): cto-review.yml, prautoblogger_image_model field (Workers AI FLUX, Phase 3), Peptide Search AI / Peptide News fields (Phase 2). Co-authored-by: Engineer PRAutoBlogger (in-session subagent) <engineer-prautoblogger@peptiderepo.users.noreply.github.com>
This commit is contained in:
54
CONVENTIONS.md
Executable file → Normal file
54
CONVENTIONS.md
Executable file → Normal file
@@ -234,6 +234,60 @@ Frontend components use `wp.element` (WordPress-bundled React) — no JSX, no bu
|
||||
9. **No `echo` of raw data** — always escape with `esc_html()`, `esc_attr()`, etc.
|
||||
10. **Nonce on every form/AJAX** — `wp_nonce_field()` / `check_ajax_referer()`
|
||||
|
||||
|
||||
## How To: Add an OpenRouter model picker field (v0.11.0+)
|
||||
|
||||
Use the `model_select` field type to let admins choose OpenRouter models with a searchable dropdown, capability filtering, and estimated cost preview based on usage history.
|
||||
|
||||
### 1. Declare the field in `class-settings-fields.php`
|
||||
|
||||
```php
|
||||
[
|
||||
'id' => 'my_plugin_model',
|
||||
'label' => __( 'My Model Setting', 'my-plugin' ),
|
||||
'type' => 'model_select',
|
||||
'section' => 'my_plugin_settings',
|
||||
'default' => 'anthropic/claude-3.5-haiku',
|
||||
'capability' => 'text→text', // see ARCHITECTURE.md §18 for all capability strings
|
||||
'description' => __( 'Choose a model...', 'my-plugin' ),
|
||||
'badge' => __( 'Quality', 'my-plugin' ),
|
||||
],
|
||||
```
|
||||
|
||||
### 2. Map the setting to pipeline stages (for cost preview)
|
||||
|
||||
If you want cost preview to work, add your setting ID and stage list to the `get_stages_for_setting()` method in `includes/admin/fields/class-open-router-model-field.php`:
|
||||
|
||||
```php
|
||||
private static function get_stages_for_setting( string $field_id ): array {
|
||||
$map = [
|
||||
'prautoblogger_analysis_model' => [ 'analysis' ],
|
||||
'prautoblogger_writing_model' => [ 'outline', 'draft', 'polish' ],
|
||||
'prautoblogger_editor_model' => [ 'review' ],
|
||||
'my_new_model_setting' => [ 'my_stage' ], // ADD HERE
|
||||
];
|
||||
return $map[ $field_id ] ?? [];
|
||||
}
|
||||
```
|
||||
|
||||
The cost preview queries `get_avg_tokens_for_stages()` on the Cost Tracker to show estimated cost per generation based on the last 30 days of usage.
|
||||
|
||||
### 3. That's it
|
||||
|
||||
The field renderer, AJAX refresh, model picker JS, and capability filtering are already wired. The admin will see a "Refresh Model List" button on the AI Models tab (or whichever tab contains the picker field).
|
||||
|
||||
### Capability strings (locked in v0.11.0)
|
||||
|
||||
- `text→text` — text input, text output (default for analysis/writing/editor)
|
||||
- `text+image→text` — vision models
|
||||
- `text+audio→text` — audio input models
|
||||
- `text→image` — image generation
|
||||
- `text→audio` — voice synthesis
|
||||
- `text→video` — video generation
|
||||
- `text→embedding` — embeddings
|
||||
|
||||
Phase 3 will add provider selection; v0.11.0 is OpenRouter-only.
|
||||
|
||||
## Git Workflow — PR-Gated, Soft-Enforced
|
||||
|
||||
This repo is private on GitHub's free plan, which does not support branch protection or rulesets. The review gate is enforced at the agent layer, not server-side. Every agent and human contributor follows these rules; the `.github/workflows/main-push-audit.yml` tripwire opens an audit issue on any direct push to `main` that did not come from a merged PR.
|
||||
|
||||
Reference in New Issue
Block a user