v3.1.0 — All major LLM providers (OpenAI, Anthropic, Gemini + custom)
v3.1.0 — all major LLM providers (OpenAI, Anthropic, Gemini + custom)
Slower now works with every major LLM provider through Prism, with fewer config variables than before — provider credentials move out of Slower's config entirely.
Highlights
- Pick a provider with one variable:
SLOWER_AI_SERVICE=openai|anthropic|gemini|ollama|…. Any Prism provider works; a fully custom backend registers viaAiServiceManager::extend(). - Credentials delegated to Prism (
config/prism.php/OPENAI_API_KEY,ANTHROPIC_API_KEY,GEMINI_API_KEY) — Slower's ownopen_aiconfig block is gone. - Sensible low-cost default model per provider (
gpt-5.4-mini,claude-haiku-4-5,gemini-2.5-flash), overridable withSLOWER_AI_RECOMMENDATION_MODEL.
Design
- Replaced
openai-php/laravelwithprism-php/prism— one official package for all providers. The entire integration lives behind a singlePrismDriver; theAiServiceDrivercontract andAiServiceManager::extend()seam are unchanged, so Prism (and its pre-1.0 API) is isolated to one class. AiServiceManagermapsai_service→ any Prism provider (Provider::tryFrom), withextend()taking precedence and unknown names throwing a helpful error.- Provider/transport exceptions propagate (a
nullreturn means only "no usable text"), so failed analyses stay retryable exactly as before.
Backward compatibility
Existing OpenAI users need no changes — Prism reads OPENAI_API_KEY, and a boot-time bridge still honors a legacy slower.open_ai.api_key. Minor release.
Verification
- 126 tests / 268 assertions green on Laravel 11, 12, and 13 (PHP 8.4); PHP 8.5 covered by CI. PHPStan 2 level 5 clean, Pint clean.
PrismDrivertested withPrism::fake()(provider/model/prompt routing, empty→null); manager resolution, customextend(via the real singleton path), thecreate{Name}Driver()BC path, and config all covered.- Architecture selected by a multi-model council (Prism won decisively; per-provider SDKs rejected) plus Fable 5's independent opinion.
- Hardened through four rounds of recursive review, which caught and fixed real bugs a single pass would have missed: a critical
extend()-singleton failure (custom LLMs silently ignored), wrong per-provider model defaults (OpenAI model sent to other providers), a droppedcreate{Name}Driver()extension convention, and misleading error messaging. Two residual items were reasoned design choices, not defects: key validation is deferred to call-time (an eager guard would break keyless providers like Ollama), and the 30s request timeout is a sane default (raisePRISM_REQUEST_TIMEOUTif needed).
Heads-up: GitHub Actions is currently failing to provision runners account-wide (unrelated to this change), so CI hasn't validated the matrix here — it was validated locally across Laravel 11–13.