subscope-ai/laravel-keenable
Subscope AI's Laravel Keenable package integrates Keenable with Laravel for simple feature flag management. Configure the client, check flags through a facade, and enable or roll out features per user, environment, or request with minimal setup and Blade-friendly helpers.
Architecture fit. The package is a thin, well-shaped wrapper rather than a framework: a facade (Keenable), two verbs (search(), fetch()), typed DTOs (SearchResponse, FetchResponse, SearchResult), a SearchMode enum, and a typed exception hierarchy. That is the right shape for a TPM to sign off on — small surface area, few opinions imposed on our code, and the returned DTOs mean our domain layer does not have to defend against loose arrays. The two AI SDK tools (KeenableSearchTool, KeenableFetchTool) implementing Laravel\Ai\Contracts\Tool are the strategic piece: they make web access a two-line configuration change for any Laravel AI SDK agent, which is where most of the near-term business value sits (RAG grounding, freshness, and "read this URL the user pasted" flows).
Integration feasibility. Low friction. composer require subscope-ai/laravel-keenable, a facade call, and Http::fake() works unchanged — that last point matters more than it looks, because it means our existing test suite patterns and CI contract-testing approach carry over without a bespoke fake. Flexible billing (keyed, keyless public endpoints, or x402 pay-per-request) gives us a low-commitment entry path: we can prototype keyless, then move to a key when volume justifies it, without a code change.
Technical risk. Four items, in order of concern:
Laravel\Ai\Contracts\Tool. If that SDK is pre-1.0 or its contract shifts, our agent wiring breaks through no fault of Keenable. Treat the tool classes as convenience, not as the integration contract we design around.x402 pay-per-request billing also introduce procurement and finance questions that a plain seat-licensed SaaS does not.fetch() with a custom prompt sends URLs and prompts to the vendor for LLM extraction. That is a data-processing question (DPA, retention, residency) plus a cost question, since extraction is likely metered differently from raw fetch.Key questions for the vendor/team. What is the published SLA and status-page history? Is laravel/ai GA, and what is its BC policy? How are credits consumed per search vs fetch vs fetch-with-prompt? What are the rate limits by tier, and do the typed exceptions surface them reliably (the retryAfter() and limit metadata suggest yes)? Is there an on-prem or self-hosted path, or is this strictly SaaS? What is the x402 settlement model and does it clear legal/procurement?
Stack fit. Strong, conditional on runtime floor. It is idiomatic Laravel — facade, HTTP client underneath, config-published, container-bound. No queue workers, no migrations, no published service provider side effects that would complicate deployment. It slots into a Laravel 12+ service with essentially zero architectural negotiation.
Migration path. No prior assessment exists, so this is a greenfield adoption rather than a migration. Recommended path: introduce behind our own narrow interface (e.g. WebSearchProvider with search()/fetch()) rather than calling the facade directly from domain code. The package's DTOs are good, but keeping them at the adapter boundary preserves our ability to swap vendors or add a second provider later without touching call sites. This is a half-day of extra work and it is the single highest-value decision in this adoption.
Compatibility. Two compatibility envelopes to track: our Laravel/PHP floor, and the laravel/ai version we standardize on. Pin the package to a caret constraint, pin laravel/ai explicitly, and add a CI job that runs against the lowest supported Laravel. Since Http::fake() works, we can write contract tests that assert request shape and DTO hydration without hitting the network — do that on day one, before we depend on response fields.
Sequencing.
pro vs realtime mode quality and snippet-length tuning. Confirm credit consumption matches the pricing model.Maintenance. Low code-maintenance burden: small API, active release cadence implied, and the facade means upgrades are mostly composer bumps. The real maintenance load is policy maintenance — credit budgets, rate-limit thresholds, prompt templates for extraction, and the adapter mapping. Budget ongoing owner time for those, not for the library.
Support. Vendor support quality is unknown at v1.0.0 — that is the exposure. Mitigate by keeping the blast radius small (adapter boundary), documenting a fallback, and not making web search a hard dependency of any revenue-critical path in the first two quarters. Internally, the typed exceptions are a genuine support win: AuthenticationException, InsufficientCreditsException, ForbiddenKeyException, RateLimitException (with retryAfter()), ValidationException, ServerException map cleanly to distinct runbook entries and distinct alert severities, instead of one opaque 500.
Scaling. Two independent ceilings. Throughput: vendor rate limits by tier — plan for the circuit breaker and a queue-backed retry with retryAfter() respected, not naive exponential backoff. Cost: per-request credit consumption scales linearly with agent usage, and fetch() with a custom prompt will be the expensive call — cache aggressively (search results by normalized query + mode + filters; fetched pages by URL with a TTL) and set per-tenant or per-agent budgets before enabling broadly. Watch for agents in loops calling search() repeatedly; cap tool invocations per agent turn.
Failure modes. Enumerate and handle each explicitly:
retryAfter(); shed load if the window is long.fetch() on unfetchable or paywalled pages → treat as an expected negative result, not an exception path.laravel/ai contract change → tool classes break at upgrade; caught by the pinned-version CI job.Ramp-up. Developer ramp-up is measured in hours — the README example is essentially the whole API. Organizational ramp-up is the longer pole: security review for data egress, finance sign-off on credit/x402 billing, legal review of the DPA, and an ops runbook keyed to the exception hierarchy. Start those in parallel with the week-1 spike, because they, not the code, will set the real go-live date.
How can I help you explore Laravel packages today?