revolution/laravel-copilot-sdk
A Laravel SDK that wraps Copilot's API in an expressive, configurable package. Quickly authenticate, send requests, and handle responses using Laravel-friendly classes, facades, and configuration—ideal for adding Copilot-powered workflows to your PHP applications.
Architecture fit. The package remains a conventional Laravel wrapper — service provider, Copilot facade, publishable config/copilot.php, .env overrides, copilot() helper, and Copilot::fake() test double — which is still the right idiom for a Laravel shop. Two architectural facts now dominate, not one. The first is unchanged: it speaks JSON-RPC 2.0 to a locally running copilot --headless process over stdio or TCP, so our application host is a process supervisor for a Node-based third-party CLI. The second is new in 1.0.22 and materially changes the mental model: with "exit-plan and auto-mode reverse-RPC handling," "permission prompt context and user-prompt blocking," and "LLM inference request handling," the integration is no longer a one-way client. The host application must now also serve RPC callbacks the agent makes mid-turn — answering permission prompts, supplying plan decisions, blocking on user input. That is bidirectional control-plane work, and it is the single biggest delta in this release. We are integrating a binary and implementing a small server for it.
Integration feasibility. Code-side friction is still low, and the release meaningfully widens the feature surface a product team can actually use: history compaction controls and handoff summaries (long-session context management), token price unit and runtime image-model catalog metadata (cost and model-selection telemetry), content-exclusion path checks (data governance), folder trust / permission location (permission policy granularity), MCP OAuth discovery and login identity selection (realistic enterprise auth), and session command/skill/shell RPCs (agentic execution). Several of these directly close gaps flagged in the prior assessment. The blockers remain environmental, and 1.0.22 adds two: verified Agent Plugin installation and extension launch provider support mean the package can now install and launch third-party code by design, and shell/skill RPCs mean the agent can execute commands. Both require a trust and sandboxing decision we have not yet made. Nothing here changes the hard prerequisites — CLI in every runtime image, a GitHub identity with a Copilot seat, outbound network, and a process model PHP-FPM handles poorly by default.
Technical risk. Still high, but the composition of the risk has shifted and should be re-scored rather than carried forward. Reduced: protocol drift. The changelog shows a github-actions[bot] "Sync with copilot-sdk" PR and a large batch of upstream-parity ports, which is exactly the automated tracking mechanism the prior assessment said was missing — the wrapper is actively following the upstream SDK rather than drifting from it. Maintenance velocity is also demonstrably not stale (17 PRs in one patch release). Increased: review depth and semver discipline. Most PRs are authored "with @Copilot," only one is explicitly a test addition, and a patch-level bump (1.0.21 → 1.0.22) introduces substantial new public API and at least one item self-labelled experimental. Shipping that much surface in a patch release is a signal to pin exactly and read diffs, not to trust ^1.0. Increased: blast radius. Plugin installation, extension launching, shell/skill RPCs, and auto-mode each widen what a misconfigured or prompt-injected agent can do on our infrastructure. Unchanged: 2 stars, 0 dependents, single maintainer, undocumented PHP/Laravel support matrix, and permission_approve: 'deny-all' remaining the correct but confusing default. Newly relevant: Copilot licensing for programmatic/headless use is still a legal question, but content-exclusion path checks give us a concrete control to point at during that review — a genuine improvement in our ability to get sign-off.
Key questions.
copilot --headless a GA, supported interface, or a preview that can change without notice?PendingCompletions?auto-mode bypass permission_approve entirely?Stance: unchanged at evaluate-and-contain, not adopt. The release improves the drift story and gives us compliance-relevant controls, but simultaneously expands the capability and attack surface and confirms that upstream churn arrives in bulk. The case for a bounded spike is stronger than before; the case for a core-path dependency is not.
Stack fit. Unchanged: Laravel 11/12 on PHP 8.2+, containerized, Copilot CLI baked into the image or run as a sidecar. Best landing zones remain internal engineering tooling and asynchronous jobs. The new features sharpen the fit in two places worth noting — token price and model catalog metadata make cost attribution viable for internal showback, and compaction/handoff summaries make long-lived sessions realistic for multi-turn support triage. It remains a poor fit for synchronous user-facing request paths on PHP-FPM, and the new reverse-RPC callbacks worsen that slightly: a turn may now block waiting on our handler, which extends request duration and widens the orphaned-process window.
Migration path. Unchanged in principle and now more valuable: define a narrow internal port (App\Support\Llm\LlmClient with complete(), stream(), converse()) and implement it once via this package, once via a conventional HTTP provider. Two additions. First, put a second seam around agentic capability — a policy object that declares, per use case, whether tools, MCP, plugins, shell, and auto-mode are enabled — so enabling those features in 1.0.22 is a config decision at one place, not a diff across call sites. Second, treat the reverse-RPC handlers we must implement as first-class application code with their own tests, not as package plumbing.
Compatibility. Pin both sides exactly — the CLI install version in the image (never latest) and an exact Composer constraint. The prior advice to avoid floating minors now applies with more force: a patch bump just added public API and experimental features. Validate the COPILOT_URL TCP sidecar topology before enabling reverse-RPC flows, since a long-lived TCP session holding an open permission prompt behaves very differently from a per-call stdio spawn. Explicitly configure and record the settings for content exclusion, folder trust, and plugin/extension enablement so they are auditable and reviewable in the repo, not left at defaults.
Sequencing.
LlmClient, the capability-policy object, Dockerfile changes, exact version pins, and a Copilot::fake()-based test suite so CI never needs the real binary. Add reverse-RPC handler tests.wire:stream, with explicit timeout and mid-stream failure handling. Note that streaming plus reverse-RPC is the hardest combination to make robust — do it last within this phase.Maintenance. Two moving parts, both owned by others, and the cadence has now been demonstrated to be fast. The automated upstream sync bot is a real operational asset — it means we are not the ones discovering protocol drift — but it also means incompatible changes can arrive in a patch release, so budget a recurring bump-and-smoke cycle on every release rather than a periodic one. Minimum smoke suite: ping(), single run(), one streaming path, one permission-prompt reverse-RPC round-trip, and one compaction/resume cycle. Re-evaluate the surface we actually use each bump and disable the rest via config, so new capabilities are opt-in by default. Single maintainer plus zero dependents remains the stale-or-fork contingency.
Support. No SLA, no vendor path. The runbook grows: CLI missing/wrong version, GitHub token expiry, quota exhaustion, permission-denied responses, timeout tuning, plus new entries for plugin install failure, extension launch failure, MCP OAuth flow failure, and reverse-RPC handler timeout. Ownership of reverse-RPC handlers is ambiguous by default and must be assigned explicitly to the application team — the package author cannot support our handler logic. Legal/procurement sign-off remains the likeliest schedule risk, though content-exclusion path checks give us something concrete to show reviewers.
Scaling. Both regimes are unchanged. Stdio scales by adding workers, each concurrent call costing a spawned process with multi-second cold start and its own memory footprint; throttle deliberately (queue maxTries, backoff, Redis semaphore). TCP with a long-lived copilot --headless --port pools that cost but needs health checks, restart policy, and capacity planning — and now also needs to handle persistent reverse-RPC channels. Throughput remains bounded by seat quota. Two new scaling considerations: plugin/extension launches add per-invocation process cost and install-time I/O, and history compaction runs inline within a turn, so long sessions are not "free" — they trade context quality for latency spikes that must be excluded from timeout budgets.
Failure modes to instrument from day one.
PATH in a container layer.COPILOT_TIMEOUT too low for tool-using, compacting, or reasoning-heavy prompts.copilot processes after PHP-FPM termination or queue worker SIGKILL.deny-all returning denials that read as model failure.sessionId reuse and infiniteSessions — partially mitigated by compaction controls, but only if we configure retention.auto-mode silently bypassing permission_approve, producing an approval-path audit gap.Ramp-up. Still shallow on the API — the facade, helper, array-vs-SessionConfig duality, and Copilot::fake() with assertPrompt/assertPromptCount remain genuinely pleasant. The learning cost has increased on the operational and policy side, not the syntactic side: reverse-RPC handler design, permission policy across the now-finer-grained surface (folder trust, permission location, prompt context, user-prompt blocking), plugin/extension trust, and secret handling for per-user tokens. Budget roughly a day of team onboarding (up from half a day) plus a written, centralized policy covering approveOnce() vs reject(), whether auto-mode is ever permitted, and which capabilities are enabled per use case. That policy should live in code (the capability-policy object), not in a wiki — otherwise a patch release will quietly enable something for us.
How can I help you explore Laravel packages today?