Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions devlog/_plan/260912_devin_acp_removal/000_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# 260912 — Retire the Devin ACP adapter and give Devin the tool-catalog nudge

## Why this unit exists

Two Devin provider rows exist, `devin` and `devin-cli`, and both stream Cognition's
`ApiServerService/GetChatMessage` over Connect-RPC on the `devin` adapter. They differ only in
where the credential came from: a browser sign-in through `RegisterUser`, or the
`devin-session-token` the installed CLI already wrote to its own `credentials.toml`.

A second adapter registered under the id `devin-cli` still existed. It spawned `devin acp` and
drove the child over Agent Client Protocol on stdio. It was unreachable under the `devin-cli`
provider id — `routedProviderConfig` pins the adapter from the registry for any registry id — and
reachable only through a custom-named row such as `"devin-acp"`. Nobody was routed to it.

It is being removed rather than kept, because the premise that justified it turned out to be
false. The design assumed OpenCodex could not hold a credential for the installed CLI, so a child
process was the only way to use it. The CLI's `windsurf_api_key` is an ordinary
`devin-session-token$<JWT>`, the same credential the cloud client already speaks. Importing the
token does everything the child did, without a placeholder `buildRequest`, a disabled
`parseStream`, an identity-only `baseUrl` that no request may connect to, and a subprocess
running in the operator's own tree.

The nudge is the second half. Every non-OpenAI adapter that advertises a client tool catalog
injects `buildNonOpenAIToolCatalogNudgeForTools` into its system prompt — Anthropic, Google,
non-OpenAI `openai-chat` hosts, Kiro, Command Code. The Devin adapter does advertise a real
catalog (proto field #10 via `mapOcxToolsToDevin`) and was the only one left without the
paragraph. Adding it in `mapOcxMessagesToDevin` covers both provider rows at once, because they
share the adapter. The retired ACP wire could never have used it: `session/prompt` carries prompt
text only, with `capabilities: {}` and `mcpServers: []`, so a catalog nudge there would have
described a contract that does not exist on that wire.

## Work phases

### wp1 — land PR #4411

Unrelated in subject, but it is the open PR blocking this branch's base from being clean. Its
`test 3/4`, `gates` and `macos 2/2` failures were one cause: `privacy:scan` flagged a maintainer
email address quoted inside a carried devlog record. The address was incidental to the note.

Done when: exact-head CI is green and the PR is merged into `dev`.

### wp2 — retire ACP, migrate, nudge

Removals:

- `src/adapters/devin-cli/{acp,adapter,binary,models}.ts`
- `tests/providers/devin-cli-adapter.test.ts`, and its rows in `scripts/test-layout/layout.json`
and `tests/fixtures/test-layout-expected.json`
- the `devin-cli` import, `AdapterWire` member and registry entry in `src/adapters/registry.ts`
- the `devin-cli` case in `upstreamProtocolForAdapter`
- the `devin-cli` row in the adapter-registry authority map, and the wire from
`RUN_TURN_ONLY_WIRES`

Migration. `projectDevinCliAuthMode` previously warned and changed nothing when a saved row still
named the ACP adapter, on the reasoning that routing already pinned the transport. That reasoning
held only for the registry id. With the adapter gone, a custom-named row has nothing pinning it
and would throw `Unknown adapter: devin-cli` on every request, so the migration now rewrites
**every** row naming the retired id, whatever the row is called. A row still carrying the
identity-only `cli.devin.ai` host is repointed at the api-server in the same pass, because that
URL was never a destination and leaving it would trade an unconstructible adapter for an
unresolvable host.

Nudge. `mapOcxMessagesToDevin` appends the shared paragraph to the system content. The wire name
callback is `tool => tool.name`, not the default namespaced form, because `mapOcxToolsToDevin`
writes the bare name; a nudge listing names the model is never offered is worse than none.

Done when: no adapter id `devin-cli` remains anywhere, saved rows migrate with regression
coverage, the nudge is covered by a regression test, structure/ and docs-site agree, exact-head CI
is green and the PR is merged.

## Verification policy for this unit

Local product suite runs are prohibited by the maintainer. Local checks are limited to
`bun run structure:check`, `bun run privacy:scan`, and explicitly named focused test files.
Everything else is hosted exact-head CI. Skipped local checks are labelled NOT RUN in the PR.

2 changes: 1 addition & 1 deletion docs-site/src/content/docs/fr/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ ocx logout <provider>
| `google-antigravity` | `google` | `https://daily-cloudcode-pa.googleapis.com` | Google OAuth avec le protocole Cloud Code Assist. La découverte en direct utilise le point de terminaison CCA authentifié `v1internal:fetchAvailableModels` et publie les modèles d'agent accessibles au compte connecté ; le catalogue maintenu reste la solution de repli. |
| `cursor` | `cursor` | `https://api2.cursor.sh` | Connexion PKCE expérimentale, transport HTTP/2 en direct et découverte de modèles filtrés par compte. |
| `devin` | `devin` | `https://server.codeium.com` | Passerelle Cognition/Devin non officielle et expérimentale. La connexion ouvre l'authentification Auth0 dans le navigateur, puis échange le jeton via `RegisterUser` contre une clé d'API durable. Les modèles sont découverts par compte avec `GetCascadeModelConfigs` ; le streaming passe uniquement par `runTurn` sur Connect-RPC. Absente du préréglage du tableau de bord par défaut. |
| `devin-cli` | `devin` | `https://server.codeium.com` | Importe l'identifiant que votre Devin CLI installé détient déjà (`devin auth login` l'écrit dans son propre `credentials.toml`), puis diffuse via l'api-server Connect-RPC de Cognition comme le fournisseur `devin` — sans connexion navigateur ni clé à coller. La liste des modèles et les fenêtres de contexte proviennent du catalogue de votre compte. Pour la boucle d'agent locale du CLI (ACP stdio), utilisez une entrée nommée différemment avec `"adapter": "devin-cli"`. |
| `devin-cli` | `devin` | `https://server.codeium.com` | Importe l'identifiant que votre Devin CLI installé détient déjà (`devin auth login` l'écrit dans son propre `credentials.toml`), puis diffuse via l'api-server Connect-RPC de Cognition comme le fournisseur `devin` — sans connexion navigateur ni clé à coller. La liste des modèles et les fenêtres de contexte proviennent du catalogue de votre compte. |
| `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | Expérimental. Flux d'appareil GitHub et échange `copilot_internal` (client OAuth de VS Code). Nécessite un abonnement Copilot actif ; il ne s'agit pas d'une API tierce officielle. |

Les vérifications de quota Google Antigravity utilisent des points de terminaison Google fixes, y compris le repli vers la liste des modèles. Elles prennent en charge le DNS Fake-IP transparent pour ces destinations en conservant la vérification TLS, le refus des redirections et les contrôles des adresses privées. Une URL de base personnalisée ne modifie que les requêtes de modèles ; `NO_PROXY` conserve la politique de connexion directe.
Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ ocx logout <provider>
| `cursor` | `cursor` | `https://api2.cursor.sh` | Experimental PKCE login, live HTTP/2 transport with an opt-in HTTP/1.1 compatibility path, and account-filtered model discovery. |
| `orcarouter-oauth` | `openai-chat` | `https://api.orcarouter.ai/v1` | Browser consent and key exchange use `https://www.orcarouter.ai` with S256 PKCE. The returned user-owned `sk-orca-…` API key is stored in the existing credential store and reused until revoked. |
| `devin` | `devin` | `https://server.codeium.com` | Experimental unofficial Cognition/Devin bridge. Login opens Auth0 browser sign-in, then exchanges the token via Cognition's `RegisterUser` for a long-lived API key; models are discovered per account with `GetCascadeModelConfigs`. Not shown in the dashboard preset by default. Chat and usage reporting are verified against a live account across three models. |
| `devin-cli` | `devin` | `https://server.codeium.com` | Imports the credential your installed Devin CLI already holds (`devin auth login` writes it to its own `credentials.toml`), then streams over Cognition's Connect-RPC api-server like the `devin` provider — no browser sign-in and no key to paste. Model discovery and context windows come from your account's own catalog. For the CLI's local agent loop over ACP stdio instead, use a custom-named row with `"adapter": "devin-cli"`. |
| `devin-cli` | `devin` | `https://server.codeium.com` | Imports the credential your installed Devin CLI already holds (`devin auth login` writes it to its own `credentials.toml`), then streams over Cognition's Connect-RPC api-server like the `devin` provider — no browser sign-in and no key to paste. Model discovery and context windows come from your account's own catalog. |
| `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | Experimental. GitHub device flow + `copilot_internal` exchange (VS Code OAuth client). Requires an active Copilot subscription; not an official third-party API. |

Google Antigravity account and provider quota probes use fixed Google accounting endpoints, including the models fallback. They support transparent Fake-IP DNS for those destinations while retaining TLS verification, redirect rejection and private-address checks. A custom provider base URL changes model requests, not quota destinations; `NO_PROXY` continues to select the direct-route policy.
Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/ja/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ ocx logout <provider>
| `google-antigravity` | `google` | `https://daily-cloudcode-pa.googleapis.com` | Google OAuth を Cloud Code Assist wire で使用。ライブ探索は認証済みの CCA `v1internal:fetchAvailableModels` エンドポイントを使用し、ログイン中のアカウントで利用可能な agent モデルのみを公開します。管理されたカタログはフォールバックとして残ります。 |
| `cursor` | `cursor` | `https://api2.cursor.sh` | 実験的 PKCE ログイン、HTTP/2 トランスポート、アカウント別モデル探索をサポート。 |
| `devin` | `devin` | `https://server.codeium.com` | 実験的な非公式 Cognition/Devin ブリッジ。ログインは Auth0 のブラウザサインインを開き、取得したトークンを `RegisterUser` で長期 API キーに交換します。モデル一覧は `GetCascadeModelConfigs` でアカウントごとに取得し、ストリーミングは Connect-RPC 上の `runTurn` 経路のみを使います。ダッシュボードのプリセットには既定で含まれません。 |
| `devin-cli` | `devin` | `https://server.codeium.com` | インストール済み Devin CLI がすでに保持している認証情報を取り込みます(`devin auth login` が自身の `credentials.toml` に書き込みます)。以降は `devin` プロバイダと同じく Cognition の Connect-RPC api-server へストリーミングします。ブラウザサインインも貼り付けるキーも不要です。モデル一覧とコンテキストウィンドウはアカウントのカタログから取得します。CLI 自身のローカルエージェントループ(ACP stdio)を使う場合は、別名の行に `"adapter": "devin-cli"` を指定してください。|
| `devin-cli` | `devin` | `https://server.codeium.com` | インストール済み Devin CLI がすでに保持している認証情報を取り込みます(`devin auth login` が自身の `credentials.toml` に書き込みます)。以降は `devin` プロバイダと同じく Cognition の Connect-RPC api-server へストリーミングします。ブラウザサインインも貼り付けるキーも不要です。モデル一覧とコンテキストウィンドウはアカウントのカタログから取得します。 |
| `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | 実験的。GitHub デバイスフロー + `copilot_internal` 交換(VS Code OAuth クライアント)。有効な Copilot サブスクリプションが必要で、公式のサードパーティ API ではありません。 |

Google Antigravity のアカウント・プロバイダーのクォータ確認は、モデル一覧へのフォールバックも含め、固定の Google エンドポイントを使用します。その宛先では透過 Fake-IP DNS に対応し、TLS 検証、リダイレクト拒否、プライベートアドレス検査を維持します。カスタム base URL はモデル要求にのみ適用されます。`NO_PROXY` は直接接続のポリシーを維持します。
Expand Down
2 changes: 1 addition & 1 deletion docs-site/src/content/docs/ko/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ ocx logout <provider>
| `google-antigravity` | `google` | `https://daily-cloudcode-pa.googleapis.com` | Google OAuth를 Cloud Code Assist wire로 사용합니다. 실시간 탐색은 인증된 CCA `v1internal:fetchAvailableModels` 엔드포인트를 사용하며 로그인한 계정에서 사용할 수 있는 agent 모델만 게시합니다. 유지 관리되는 카탈로그는 폴백으로 남습니다. |
| `cursor` | `cursor` | `https://api2.cursor.sh` | 실험적 PKCE 로그인, HTTP/2 전송, 계정별 모델 탐색을 지원합니다. |
| `devin` | `devin` | `https://server.codeium.com` | 실험적인 비공식 Cognition/Devin 브리지. 로그인은 Auth0 브라우저 사인인을 열고, 받은 토큰을 `RegisterUser`로 교환해 장기 API 키를 얻습니다. 모델 목록은 `GetCascadeModelConfigs`로 계정마다 조회하며, 스트리밍은 Connect-RPC 위에서 `runTurn` 경로만 씁니다. 대시보드 프리셋에는 기본으로 없으니 직접 추가하세요. |
| `devin-cli` | `devin` | `https://server.codeium.com` | 설치된 Devin CLI가 이미 들고 있는 자격증명을 가져옵니다(`devin auth login`이 자기 `credentials.toml`에 씁니다). 그다음은 `devin` 프로바이더와 똑같이 Cognition의 Connect-RPC api-server로 스트리밍합니다. 브라우저 로그인도, 붙여넣을 키도 없습니다. 모델 목록과 컨텍스트 윈도우는 계정 카탈로그에서 실시간으로 옵니다. CLI 자체의 로컬 에이전트 루프(ACP stdio)를 쓰려면 이름이 다른 행에 `"adapter": "devin-cli"`를 지정하세요. |
| `devin-cli` | `devin` | `https://server.codeium.com` | 설치된 Devin CLI가 이미 들고 있는 자격증명을 가져옵니다(`devin auth login`이 자기 `credentials.toml`에 씁니다). 그다음은 `devin` 프로바이더와 똑같이 Cognition의 Connect-RPC api-server로 스트리밍합니다. 브라우저 로그인도, 붙여넣을 키도 없습니다. 모델 목록과 컨텍스트 윈도우는 계정 카탈로그에서 실시간으로 옵니다. |
| `github-copilot` | `openai-chat` | `https://api.githubcopilot.com` | 실험적. GitHub 디바이스 플로우 + `copilot_internal` 교환(VS Code OAuth 클라이언트). 활성 Copilot 구독 필요; 공식 서드파티 API가 아닙니다. |

Google Antigravity 계정·제공자 할당량 확인은 모델 목록 폴백을 포함해 고정된 Google 회계 엔드포인트를 사용합니다. 해당 목적지의 투명 Fake-IP DNS를 지원하며 TLS 검증, 리다이렉트 거부, 사설 주소 검사는 유지합니다. 사용자 지정 base URL은 모델 요청에만 적용되며 할당량 목적지는 바꾸지 않습니다. `NO_PROXY`는 기존 직접 연결 정책을 유지합니다.
Expand Down
25 changes: 8 additions & 17 deletions docs-site/src/content/docs/reference/adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,23 +463,14 @@ api-server URL beside it, and never the file's other fields.

- Uses `runTurn` on the shared cloud-direct client, so it inherits that adapter's live catalog,
per-account context windows and tool-description handling.
- For the CLI's own local agent loop over ACP stdio instead, configure a **custom-named** provider
row with `"adapter": "devin-cli"` — for example `"devin-acp"`. A row named `devin-cli` cannot
select it, because the router pins the adapter from the registry for any registry id.
- One turn is one ACP session: `initialize`, `session/new`, `session/prompt`, with `session/update`
notifications streaming in between and a unary reply carrying the stop reason and usage. The
conversation is flattened into the single prompt string a session takes, with role labels fenced
so a message body cannot forge one.
- The CLI's own tool calls stay internal. Devin executes them inside its session, so forwarding
them as client tools would either fail the turn — the bridge rejects a tool Codex never declared —
or ask Codex to run something the agent already ran.
- **Permission requests are refused by default.** This provider runs an agent in the operator's own
tree, so `session/request_permission` is answered with `cancelled` unless
`OPENCODEX_DEVIN_CLI_ALLOW_TOOLS=1` is set. The child also gets a scoped environment rather than
the proxy's, and `OPENCODEX_DEVIN_CLI_CWD` chooses where it runs.
- Binary discovery prefers `OPENCODEX_DEVIN_CLI_BIN`, then the paths the official installer and the
Homebrew cask use, then `PATH`. Install with `curl -fsSL https://cli.devin.ai/install.sh | bash`
or `brew install --cask devin-cli`.
- Only the credential is local. The turn itself goes to Cognition, exactly as `devin` does, so the
two rows differ in nothing but which account signed in. Install the CLI with
`curl -fsSL https://cli.devin.ai/install.sh | bash` or `brew install --cask devin-cli`, run
`devin auth login` once, then add the provider.
- An earlier build shipped a second adapter under the id `devin-cli` that ran the turn as an
Agent Client Protocol session against a local `devin acp` child process. It is gone. A saved
configuration that still names that adapter is rewritten to `devin` at startup, including a
custom-named row such as `"devin-acp"`.

## `azure-openai` (alias: `azure`)

Expand Down
Loading
Loading