Commit Graph

10 Commits

Author SHA1 Message Date
peptiderepo
c79fbb570e feat: wave 2 eval harness with lm-as-judge and cli command
New eval framework:
- eval/dataset.json: 20 frozen peptide topic eval items
- class-opik-eval-scorer.php: LLM-as-judge using Gemini Flash 1.5
  Scores on: scientific_signal, readability, style_adherence (0-10)
- class-opik-eval-runner.php: orchestrator for full eval pass
  Loads dataset, runs generation (no publish/images), scores, pushes to Opik
  run(int $limit = 0, bool $dry_run = false): array
- class-wp-cli-commands.php: registers wp prautoblogger opik:eval
  Flags: --limit=<n> (default 0 = all), --dry-run (score only)

Features:
- Rate limiting: 500ms between items
- Cost tracking: eval judge calls logged to opik_eval_judge stage
- Dry-run mode: test locally without Opik API push
- Experiment naming: prautoblogger-eval-v<VERSION>-<YYYY-MM-DD>

All files <= 300 lines. Version 0.13.0. Ready for PR.
2026-04-24 04:25:41 +00:00
peptiderepo
58710a0263 fix: use UUID v7 for Opik trace and span IDs (v0.12.1)
Opik requires version 7 UUIDs. wp_generate_uuid4() was producing v4
which the API rejected with 422. Replaced both call sites in
class-opik-trace-context.php with generate_uuid7(), a private static
method implementing RFC 9562 §5.7.

Fixes: smoke test 422 {"errors":["Trace id must be a version 7 UUID"]}
2026-04-23 22:57:28 +07:00
peptiderepo
fbbb387311 feat: Opik LLM observability tracing skeleton (Wave 1) — v0.12.0
Wires PRAutoblogger into Comet Opik cloud for per-call tracing.

- Thin PHP REST client (class-opik-client.php, 276 LOC)
- Async fire-and-forget dispatch via wp_schedule_single_event
- Feature flag PRAUTOBLOGGER_OPIK_ENABLED defaults OFF
- One trace per article, 5 spans across content-generator + chief-editor
- Exponential backoff 2s/4s/8s, max 3 retries, drops on failure
- Admin settings page (api-key configured indicator only, never rendered)
- ARCHITECTURE.md + CONVENTIONS.md updated

PR #113 — QA gate: PASS (qa-reviews/prautoblogger/2026-04-23-0d8dc67.md)
2026-04-23 22:36:24 +07:00
peptiderepo
0e1551be42 fix(phpcs): move ignore pragmas into file-level docblocks
File-level sniffs like WordPress.Files.FileName are evaluated at the file level,
not at code level. They require phpcs:ignore directives to be placed within the
file-level docblock (/** ... */), not in code comments.

Moved all 81 phpcs:ignore pragmas from code comments to the file-level docblocks.
This applies to:
- 79 class files with class-naming convention ignores
- prautoblogger.php with strict-types docblock ignore
- uninstall.php with strict-types docblock ignore
2026-04-23 03:26:50 +00:00
peptiderepo
dc86376e8b style(phpcs): resolve 137 residual WordPress-Core violations
- Added phpcs:ignore for class file naming convention (79 violations)
  WordPress.Files.FileName.InvalidClassFileName is a known architectural
  issue — class files use short names without prautoblogger- prefix

- Added phpcs:ignore for ->prepare() table interpolation (56 violations)
  WordPress.DB.PreparedSQL.InterpolatedNotPrepared: dynamic table names
  (prab_generation_logs, prab_cost_logs) require interpolation; ->prepare()
  does not support table name placeholders, only column values

- Fixed file-level docblock positioning (2 violations)
  prautoblogger.php and uninstall.php: moved declare(strict_types=1) before
  file docblock per PHP best practices
2026-04-23 03:23:52 +00:00
peptiderepo
f3eacd0d8d style(phpcs): autofix WordPress-Core violations via phpcbf
Run phpcbf --standard=WordPress-Core across includes/, prautoblogger.php,
and uninstall.php. Fixed 1,362 formatting violations in 75 files:
  - Short array syntax: [] → array()
  - Line breaking for long function calls
  - Consistent indentation
  - Function call parameter alignment

No logic changes; purely mechanical formatting.
2026-04-23 02:42:48 +00:00
peptiderepo
21430ce3bf cf-removal: patch registry, pipeline, settings, admin-page, interface
Wires out the Cloudflare Workers AI image provider across the plugin:

- class-image-pipeline.php: drop 'cloudflare' dispatch branch; Runware
  becomes the unrecognised-provider fallback
- class-image-model-registry.php: remove flux-1-schnell/cloudflare row;
  update provider-enum docblocks (runware|openrouter only)
- class-settings-fields-extended.php: remove three CF fields
  (cloudflare_ai_token, cloudflare_account_id, cf_image_via_gateway);
  drop Cloudflare mention from model-picker + NSFW retry descriptions
- class-admin-page.php: remove prautoblogger_cloudflare_ai_token from
  the encrypted-options list
- interface-image-provider.php: retarget preamble @see at Runware +
  OpenRouter; update get_provider_name() example
- class-image-nsfw-blocked.php: generalise preamble (Runware +
  OpenRouter can raise this)

Also cleans stale CF Workers AI mentions in:
class-ajax-handlers.php, interface-model-registry.php,
class-image-nsfw-retry.php, class-open-router-image-pricing.php,
prautoblogger.php.

The Cloudflare AI Gateway path (in class-open-router-config.php,
class-settings-fields.php 'prautoblogger_ai_gateway_base_url',
class-open-router-request-builder.php cache headers) is intentionally
untouched — it fronts OpenRouter and is unrelated to the CF Workers AI
image provider.
2026-04-21 16:48:04 +00:00
peptiderepo
c8595e05de Fix duplicate image, remove hardcoded model references
Three fixes in one:

1. Duplicate image: prepend_caption_to_post() was embedding the full
   image + caption as a <figure> block, but the theme already displays
   the featured image. Now only the caption text is prepended — no
   second copy of the image.

2. Hardcoded model names: removed all FLUX.1/FLUX.2 references from
   model-agnostic code (pipeline, prompt builder, sideloader, OpenRouter
   provider, interface, admin labels). The Cloudflare provider still
   references FLUX since it specifically wraps that model family.

3. Test alignment: OpenRouterImagePricingTest was asserting against
   removed models (flux-2-pro, seedream). Updated to match current
   COST_PER_IMAGE entries (Gemini Flash, GPT-5 Image).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 16:08:36 +07:00
peptiderepo
7ef1a917e9 fix: rename model registry files to match autoloader convention
The custom autoloader converts PRAutoBlogger_OpenRouter_Model_Registry
to class-open-router-model-registry.php (hyphen between Open and Router),
but the files were named class-openrouter-model-registry.php. This caused
a fatal "Class not found" error on every uncached page load.

Renames:
- class-openrouter-model-registry.php → class-open-router-model-registry.php
- class-openrouter-model-normalizer.php → class-open-router-model-normalizer.php

Updates @see references in interface, ARCHITECTURE.md, and CHANGELOG.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 21:05:38 +07:00
peptiderepo
be5c659999 feat(models): OpenRouter model registry + interface + cron wiring (model-picker commit 1) (#13)
Foundation for the smart model picker. Fetches, normalizes, and caches
the OpenRouter model list (/api/v1/models — free, unauthenticated).
Daily refresh via the existing prautoblogger_daily_generation cron with
12h idempotency. 3-retry exponential backoff on transient failures;
serves last-good option payload when stale-and-fetch-fails.

New files:
- interface-model-registry.php — Phase 3-aware contract (94 lines)
- class-openrouter-model-registry.php — fetch + cache + query (226 lines)
- class-openrouter-model-normalizer.php — raw → standardized (114 lines)

Zero-coupling: no PRAUTOBLOGGER_* constants inside the service classes.
Config injected via constructor. Phase 2 lift into a shared Composer
package requires only namespace rename, zero internal edits.

Cost impact: $0/month (free endpoint, no LLM tokens).

Agent-Session: cowork-2026-04-16-model-picker-commit1

Co-authored-by: peptiderepo <peptiderepo@users.noreply.github.com>
2026-04-16 16:50:12 +07:00