Commit Graph

6 Commits

Author SHA1 Message Date
peptiderepo
39570e4586 feat: add OpenRouter reasoning mode support (v0.4.9)
Enables reasoning-capable models (Grok 4.1 Fast, DeepSeek-R1, etc.)
via new admin settings: Enable Reasoning toggle and Reasoning Effort
selector. Provider auto-injects reasoning params when enabled; callers
can override per-call via options array. Response parser captures
reasoning_tokens and reasoning_content for visibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 23:54:26 +07:00
peptiderepo
fcc61c0cb8 refactor: Split OpenRouter provider to bring files under 300-line cap
Extracted credential validation, request building, response parsing, and
configuration helpers from the 464-line OpenRouter provider into separate,
focused classes. This follows the pattern established by the Cloudflare
image provider and brings all files under the project's 300-line limit.

Files created:
- class-open-router-validator.php (152 lines): Handles credential validation
  with HTTP probes and diagnostic messaging. Delegates from the provider.
- class-open-router-config.php (84 lines): Centralizes admin config resolution
  for API base URL and cache TTL settings. Used by both provider and validator.
- class-open-router-request-builder.php (79 lines): Encapsulates request header
  building and cURL auth filter registration for hosting environments that
  strip Authorization headers.
- class-open-router-response-parser.php (87 lines): Handles response parsing,
  error classification, and retry-decision logic.
- Tests: OpenRouterValidatorTest.php with comprehensive credential checks.

Provider shrinks from 464 to 278 lines. All classes are under 300 lines.
Dependencies remain clean: validator and config are independent, request-builder
and response-parser have no circular imports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 20:49:54 +07:00
peptiderepo
428a3d5861 feat: optional Cloudflare AI Gateway proxy for OpenRouter calls
Adds two WP options: prautoblogger_ai_gateway_base_url (routes OpenRouter calls through a Cloudflare AI Gateway when set to an https:// URL; empty = direct, the default) and prautoblogger_ai_gateway_cache_ttl (seconds for cf-aig-cache-ttl response caching; 0 = off).

The gateway is a transparent OpenRouter-compatible proxy, so no consuming class, no provider abstraction, and no response-parsing path changes. The http_api_curl belt-and-suspenders Authorization filter is rescoped to the configured upstream host so it still runs under gateway.ai.cloudflare.com.

Rationale: leverages existing Cloudflare infrastructure to satisfy the CTO cost-control rules (caching, cost tracking, rate limiting, fallback) without building equivalent middleware in-plugin. Fully opt-in and reversible from the admin UI.

Docs: ARCHITECTURE.md options + integrations tables updated; key decision #15 added. Uninstall is unaffected (wildcard prautoblogger_% delete).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:41:30 +07:00
Terence Ong
4f704a5dcd fix: add key format validation to validate_credentials_detailed()
Root cause of the 401 was a corrupted API key: the WordPress auth
salt changed after the key was encrypted, so decryption produced
garbage instead of sk-or-... OpenRouter interprets the garbled
Bearer token as "Missing Authentication header."

Adds the same sk-or- prefix check to the credential validation
method so users see a clear "re-enter your key" message instead
of a cryptic 401 error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 08:48:32 +07:00
Terence Ong
98ef81f49a fix: resolve OpenRouter 401 by injecting auth header at cURL level
Hostinger's hosting environment appears to strip the Authorization
header from outgoing wp_remote_post requests before they reach the
cURL transport. This caused OpenRouter to respond with HTTP 401
"Missing Authentication header" even though the header was set in
the wp_remote_post args array.

Fixes:
- Add http_api_curl filter (priority 99) that re-sets the
  Authorization header directly on the cURL handle, bypassing any
  intermediate header stripping. Scoped to openrouter.ai URLs only.
- Applied to all three OpenRouter call sites: send_chat_completion,
  validate_credentials_detailed, and get_available_models.
- Filter is cleaned up in a finally block to avoid leaking.

Also:
- Add pre-flight key format validation (must start with "sk-or-")
  to catch corrupted decryption early with a clear error message.
- Fix retry condition: was `>= 429` (incorrectly retried 430-499),
  now `=== 429` (only retry rate-limit).
- Add detailed diagnostic logging on 401/403 auth failures.
- Add .env.credentials to .gitignore.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 08:30:37 +07:00
peptiderepo
b5cbbef804 feat: v0.2.1 — fix encryption, diverse multi-topic generation, UX fixes
- Rewrite encryption with "enc:" prefix to permanently eliminate
  the double-encryption bug on settings save
- Add one-time migration to clear legacy non-prefixed encrypted values
- Rewrite content analyzer prompts to request N distinct diverse topics
  across 5 categories (question, complaint, comparison, news, guide)
- Pass target_count*2 from pipeline to analyzer for headroom
- Add skip_dedup flag so manual Generate Now always produces content
- Generate Now button now sends force=1 to clear stale locks
- Rename OpenRouter provider files to PSR-4 convention (hyphenated)
- Switch default models to google/gemini-2.5-flash-lite
- Clean up reddit_debug log channel to standard 'reddit'
- Bump version to 0.2.1

Cost: ~$0.003/article with Gemini 2.0 Flash, ~34s pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 13:36:36 +07:00