Add Devin CLI provider - #6235
Conversation
T3 Code now supports Devin as a first-class provider alongside Codex, Claude, Cursor, Grok, and OpenCode. Server changes add the Devin driver, ACP adapter and runtime, provider snapshot, text generation, and usage transcript support. Web and contract changes add the Devin icon, settings, model selection, and usage attribution. Docs are updated with a Devin provider guide and related internals references. 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 Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
There was a problem hiding this comment.
Reviewed the new Devin service/provider modules against the Effect service conventions. The Devin driver, home/binary helpers, ACP support module, text generation and adapter shape all follow the existing per-provider patterns (namespace subpath imports, make* factories, Foo["Service"] references, tagged errors with structural attributes).
Findings are concentrated in logging safety and probe error modelling:
AcpNativeLogging.tsnow writes raw ACP wire frames (and a new debug log of every payload) instead of the sanitized summaries, which re-exposes secrets carried in ACP params (e.g. the MCPAuthorizationheader this PR sends insession/new).- Leftover debug output (
Console.log,Effect.logInfoof the rawsession/newresponse) in production Devin paths. - Devin's model-discovery probe fails with
ProviderAdapterProcessErrorand a fabricatedthreadId: "probe"instead of a probe-specific error. DevinProvider.test.tsreadsdevin-models-list.txtfromprocess.cwd(), and that fixture is not in the repository.
Posted via Macroscope — Effect Service Conventions
Track both last received ACP usage and last written usage separately to prevent duplicate transcript entries. Add `lastWrittenAcpUsage` to session context and only write deltas when usage increases. Capture usage from `UsageUpdated` events and merge with `PromptResponse` usage. Normalize reasoning variant matching to handle synonyms like "no-thinking"/"none" and "lightning-medium". Add variant expansion logic and tests for
- AcpNativeLogging: never emit raw ACP frames or payload debug logs; always summarize payloads before logging. - DevinAcpSupport: remove leftover Console.log in model selection. - DevinAdapter: remove Effect.logInfo of the raw session/new response. - DevinProvider: introduce ProviderProbeError and use it for devin models list failures instead of ProviderAdapterProcessError with a fabricated 'probe' threadId. - DevinProvider.test: add missing devin-models-list.txt fixture. - mobile: include 'devin' in usage provider labels/colors and model display labels. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Reviewed the Devin provider addition against the Effect service conventions. Five concrete items, mostly in the new Devin modules plus one shared-ACP behavior change that reaches the other ACP providers.
Posted via Macroscope — Effect Service Conventions
- DevinProvider: parse stdout alone, fallback to stderr for text output. - DevinDriver: derive continuation group key from resolved home path. - DevinHome: clear inherited DEVIN_HOME and always set resolved home path. - DevinAdapter: remove Console import/dead locals, fix usage input derivation and equal-total breakdown, validate prompt before model switch, fork ACP drain into sessionScope. - DevinAcpSupport: reuse AcpRuntimeModel config helpers, fail on missing model option, handle default reasoning and reason synonyms. - AcpSessionRuntime: keep auth method authoritative; fail when not advertised. - usageScanCache: accept 'devin' scan-cache entries. - ProviderModelsSection: use orderedModels index for move buttons. - DevinProvider.test: resolve fixture from import.meta.dirname. - Add focused tests for DevinAdapter, DevinHome, usage scan cache, and ACP auth. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The Devin adapter's getThreadSemaphore inserted one Semaphore per threadId into threadLocksRef, but stopSessionInternal and stopAll never removed the entries. This caused unbounded memory growth for long-lived adapters. Remove the threadId from the map when the session stops so the lock table does not accumulate stale entries. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The hasDetails guard in ProviderModelsSection only checked capability labels and whether the model name differs from its slug, so models with only a description never triggered the info tooltip. Include a non-empty model.description in the guard so the tooltip renders. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
deriveProviderSettingsFields now exposes binaryPath, homePath, launchArgs and permissionMode for the Devin provider, matching the schema order. Update the test expectation to match the visible fields. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Add Devin Desktop as an available editor option in the OpenInPicker menu and EDITORS registry. Include DevinIcon import, register "devin-desktop" command with "goto" launch style, and reformat EDITORS array for consistency.
Add Devin logo SVG, display Devin alongside other AI tools in hero section and harness grid, update copy to include Devin in orchestration list. Adjust mobile layout to accommodate six harnesses. Refactor DevinAdapter to use Effect.fn wrapper, replace manual record guard with Schema-based DevinResume decoder, and improve type safety for resume parsing.
Remove unused EffectAcpErrors import, add DEVIN_AUTH_METHOD_ID to imports, and apply consistent formatting across test cases. Wrap long test descriptions and mock function chains to improve readability.
… logic Add comprehensive test coverage for makeDevinTokenUsageSnapshot and makeDevinTokenUsageSnapshotFromUsageUpdate functions. Tests verify token accumulation, context compaction handling, and edge cases like zero-size contexts. Refactor buildThreadTokenUsageSnapshot to simplify token delta calculations, use turn-based token counting when available, and properly track totalProcessedTokens across usage updates. Export snapshot functions for testability.
There was a problem hiding this comment.
One finding on the new provider probe error: its failure modes are distinguished only by prose in detail, so the stage and exit code are not structurally recoverable.
Posted via Macroscope — Effect Service Conventions
- Keep per-thread lock entry while replacing sessions - Advance lastWrittenAcpUsage only after transcript write succeeds - Exclude cached read tokens from totalProcessedTokens - Update snapshot test expectation Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The new provider probe error encoded failure modes only in detail prose, so callers could not recover the probe stage or CLI exit code. Add stage and exitCode fields so the error is structurally recoverable and keep the human-readable detail for messages/logs. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Replace string-based stage and detail fields with typed enums (ProviderProbeStage, ProviderProbeFailureKind). Generate error messages from failureKind instead of storing detail prose. Update Devin adapter to use new typed fields.
There was a problem hiding this comment.
Reviewed the new Devin service/driver code against the Effect service conventions. One finding: the new ProviderDriverError wrapper folds cause.message into its own detail/message. Everything else (namespace imports, Effect.fn requirement types, Schema.TaggedErrorClass usage with structural fields plus preserved cause, Effect.catchTags for known tags, no hidden runtimes) matches the conventions and the sibling ACP provider modules.
Posted via Macroscope — Effect Service Conventions
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a1c6197. Configure here.
| if (written) { | ||
| ctx.lastWrittenAcpUsage = usage; | ||
| } | ||
| } |
There was a problem hiding this comment.
Steered turns undercount usage
Medium Severity
Each successful prompt appends a delta line keyed by sessionId:turnId, but a steer reuses the same turnId. The usage aggregator drops later records with that dedupeKey, so only the first prompt in a steered turn is counted.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit a1c6197. Configure here.
| threadId: input.threadId, | ||
| turnId: prepared.turnId, | ||
| payload: { usage: tokenUsage }, | ||
| }); |
There was a problem hiding this comment.
Prompt usage overwrites live snapshot
Medium Severity
When a prompt response includes usage, the adapter rebuilds the thread snapshot with makeDevinTokenUsageSnapshot and publishes it even after usage_update events already accumulated a snapshot. That helper treats totalTokens as lifetime processed and can set lastUsedTokens to 0 or shrink totalProcessedTokens.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit a1c6197. Configure here.
ApprovabilityVerdict: Needs human review Diff is too large for automated approval analysis. A human reviewer should evaluate this PR. You can customize Macroscope's approvability policy. Learn more. |


Summary
Add Devin as a built-in T3 Code provider, so users with a Devin subscription can drive sessions through the same chat, settings, and usage surfaces as Codex, Claude, Cursor, Grok, and OpenCode.
Closes #3636
What Changed
Server:
DevinDriver,DevinAdapter,DevinProvider, andDevinTextGenerationmodules following the existing per-instance driver pattern.DevinAcpSupport) with model/reasoning variant mapping, permission handling, and real-time token usage collection.t3code-usage.jsonltranscripts.DevinDriverregistered inBUILT_IN_DRIVERS.Contracts:
DevinSettingsschema (binary path, home path, launch args, permission mode, custom models).UsageProviderKindnow includes"devin".DEFAULT_MODEL_BY_PROVIDER, display names, model aliases, and editor registry wired for Devin.Web:
OpenInPickerandEDITORSregistry).description.Mobile:
Marketing:
Docs:
docs/user/providers-devin.mdwith install, binary path, multi-account setup, and usage notes.docs/internals/providers.mdand related docs updated to list the new driver.How to verify
vp test run apps/server/src/provider/Layers/DevinAdapter.test.ts apps/server/src/provider/Layers/DevinProvider.test.ts apps/server/src/provider/acp/DevinAcpSupport.test.tsvp test run apps/web/src/components/settings/ProviderSettingsForm.test.tsNotes / risks
Why
Devin is a coding agent users want to run inside T3 Code alongside Codex, Claude, Cursor, Grok, and OpenCode. Because providers are a cross-surface feature (server runtime, contracts, web settings/chat/usage, docs), adding a new one touches the whole stack.
UI Changes
This PR adds Devin to the provider picker, settings form, model selector, and usage charts. Before/after screenshots and a short settings walkthrough video should be attached below before the PR is opened.
Checklist
Note
Add Devin as a supported CLI provider across server, web, mobile, and marketing
DevinSettings), server-side driver (DevinDriver), ACP session runtime (makeDevinAcpRuntime), and a provider adapter scaffold (DevinAdapter).DEVIN_HOME), binary auto-detection betweendevinanddevin-desktop, and usage transcript parsing (parseDevinLine).makeDevinTextGenerationfor structured JSON text generation via Devin ACP with model selection, streamed text accumulation, and a 180s timeout.permissionModeselect control to provider settings forms, backed by a newselectcontrol type in the settings schema.AcpRequestError-32602) if the requested auth method is not advertised by the agent, which is a behavioral change from the previous flow.Macroscope summarized a1c6197.
Note
Medium Risk
Large new ACP adapter and turn-settlement logic plus a behavioral change to when ACP authenticate runs; mistakes could affect session lifecycle or other ACP-backed providers.
Overview
Adds Devin as a first-class provider so sessions run through the Devin CLI over ACP, with the same settings, chat, and usage surfaces as other harnesses.
On the server, a new driver stack resolves the
devin/devin-desktopbinary andDEVIN_HOME, probes health viadevin --version, discovers model families fromdevin models list, and runs threads through a large ACP adapter (permissions, steering turns, resume cursors, token usage, and append-only usage transcript lines). DevinAcpSupport maps family + reasoning options onto ACP model/effort config. Shared ACP plumbing now handles optional agent-advertised auth (skippingauthenticatewhen none),usage_updatenotifications, and broader model config option matching.Mobile and marketing add Devin to usage charts and hero/harness copy; README and provider docs link Devin install/auth. The mock ACP agent can advertise auth methods for tests.
Reviewed by Cursor Bugbot for commit a1c6197. Bugbot is set up for automated code reviews on this repo. Configure here.