Add Devin as an ACP-based provider#3654
Conversation
Wires Devin CLI ('devin acp') into the provider stack as a new built-in
driver, modeled on the existing Grok ACP integration:
- DevinSettings contract (binaryPath, apiKey, customModels)
- DevinAcpSupport spawns 'devin acp' and authenticates with the
windsurf-api-key method, passing the API key through authenticate
_meta (Devin's ACP server ignores local CLI credentials by design)
- AcpSessionRuntime gains an optional authenticateMeta passthrough
- Devin adapter/provider/driver/text-generation layers
- Web UI: provider option, settings card, and icon
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…registry tests The periodic provider status probe must never trigger Devin's PKCE browser login, so model discovery is skipped (with an unauthenticated snapshot) until an API key is configured. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The picker requires status 'ready', so an unauthenticated-but-installed Devin CLI now reports ready with auth unauthenticated. Starting a session triggers Devin's PKCE browser login; API key remains the recommended path (skips prompts, enables model discovery). Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Devin's ACP server routes models server-side (Adaptive) and does not implement the unstable session/set_model method; calling it failed session start. Only attempt a model switch when the agent negotiated model support, and tolerate Method-not-found as a safety net. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Mirrors the Grok coverage: ACP support unit tests (spawn input, auth credential resolution, model-selection skip/fallback semantics), provider snapshot/status probes, and the full adapter suite against the shared ACP mock agent (xAI-extension cases dropped; Devin is standards-only ACP). Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| ...(options.authenticateMeta ? { _meta: options.authenticateMeta } : {}), | ||
| } satisfies EffectAcpSchema.AuthenticateRequest; | ||
|
|
||
| yield* runLoggedRequest( |
There was a problem hiding this comment.
🟠 High acp/AcpSessionRuntime.ts:543
The authenticate request payload now includes options.authenticateMeta, which for Devin contains the API key. startOnce() passes this payload through runLoggedRequest("authenticate", authenticatePayload, ...), which logs the full payload on start, success, and failure. Enabling requestLogger writes the secret API key to logs. Consider redacting or omitting the _meta field from the logged payload while still sending it in the actual RPC request.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/acp/AcpSessionRuntime.ts around line 543:
The `authenticate` request payload now includes `options.authenticateMeta`, which for Devin contains the API key. `startOnce()` passes this payload through `runLoggedRequest("authenticate", authenticatePayload, ...)`, which logs the full `payload` on start, success, and failure. Enabling `requestLogger` writes the secret API key to logs. Consider redacting or omitting the `_meta` field from the logged payload while still sending it in the actual RPC request.
| ), | ||
| ); | ||
| const started = yield* Effect.gen(function* () { | ||
| yield* acp.handleRequestPermission((params) => |
There was a problem hiding this comment.
🟡 Medium Layers/DevinAdapter.ts:605
startSession only registers acp.handleRequestPermission(...) and never registers a callback for user-input requests. As a result, when the Devin session sends a structured user-input request, the adapter never records an entry in pendingUserInputs and never emits a user-input.requested runtime event, so the UI is never surfaced the question. A later call to respondToUserInput always fails with Unknown pending user-input request because pendingUserInputs is never populated. Consider registering the corresponding ACP user-input handler (analogous to handleRequestPermission) that creates a Deferred, stores it in pendingUserInputs, and emits the appropriate runtime event.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/DevinAdapter.ts around line 605:
`startSession` only registers `acp.handleRequestPermission(...)` and never registers a callback for user-input requests. As a result, when the Devin session sends a structured user-input request, the adapter never records an entry in `pendingUserInputs` and never emits a `user-input.requested` runtime event, so the UI is never surfaced the question. A later call to `respondToUserInput` always fails with `Unknown pending user-input request` because `pendingUserInputs` is never populated. Consider registering the corresponding ACP user-input handler (analogous to `handleRequestPermission`) that creates a `Deferred`, stores it in `pendingUserInputs`, and emits the appropriate runtime event.
Review feedback: an omitted environment previously spawned the devin child with an empty env (losing PATH and WINDSURF_API_KEY). Fall back to process.env so inherited credentials and binary resolution survive. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Good catch — fixed in b89428d. \makeDevinAcpRuntime\ now defaults an omitted \environment\ to \process.env\ before resolving credentials and building the spawn input, so the child keeps PATH and \WINDSURF_API_KEY. |
A stale or wrong key previously produced a generic 'ACP startup failed' error state. Detect credential rejection during model discovery and report warning/unauthenticated with guidance to clear the key and use the browser login flow. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Summary
Adds Devin CLI as a built-in provider, modeled on the existing Grok ACP integration. Devin ships a full ACP server (
devin acp), so the integration is standards-only ACP — no private protocol extensions.DevinSettings(binaryPath, apiKey, customModels), driver kind, model defaultsDevinAcpSupport(spawn + auth),DevinAdapter(sessions/streaming/tool calls/plans/approvals),DevinProvider(health probe + ACP model discovery),DevinDriverregistered inBUILT_IN_DRIVERS,DevinTextGenerationAcpSessionRuntimegains an optionalauthenticateMetapassthrough — Devin's ACP server takes credentials viaauthenticate_meta(API key) with a PKCE browser-login fallback, and intentionally ignores local CLI credentialsDevin-specific behaviors handled:
ready/unauthenticated, discovery skipped)session/set_modelis not implemented by Devin (server-side Adaptive routing) — only called when the agent negotiates model stateTests
Devin suites mirroring Grok's:
DevinAcpSupport.test.ts,DevinProvider.test.ts,DevinAdapter.test.ts(against the shared ACP mock agent), plus devin coverage in the registry tests.vp checkandvp run typecheckpass.Note
I know contributions aren't open yet — this is a draft to have the work reviewable whenever you are. Happy to adjust to any conventions. Tested end-to-end on Windows with real
devin acpsessions streaming in the UI.This integration was written by Devin CLI itself.
Generated with Devin
Note
Add Devin as an ACP-based provider with full session, adapter, and text generation support
DevinDriverandDevinAdapteras a new built-in provider, wiring ACP session lifecycle (start/stop/interrupt/resume), turn sending with text and image attachments, permission and user-input request handling, and event streaming via PubSub.checkDevinProviderStatusto probe CLI availability viadevin --version, detect credentials, and discover available models via ACP startup; surfaces distinct states for missing binary, unauthenticated, and ACP failure.makeDevinTextGenerationto back commit message, PR content, branch name, and thread title generation through Devin ACP with a 180s timeout, streaming accumulation, and JSON schema decoding.DEVIN_DRIVER_KIND,DevinSettings), the built-in driver registry, the settings UI (PROVIDER_CLIENT_DEFINITIONS), the provider picker (PROVIDER_OPTIONSwith a "new" badge), and the provider icon map.📊 Macroscope summarized 39001d2. 15 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted
🗂️ Filtered Issues
No issues evaluated.