You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SSO-issued keys now write the aigw / AIGW provider identity into agent
configs. The pre-rename netgate id joins aigateway as a recognition-only
legacy id: detection, base_url readback, and the credential scrub still
match it, nothing writes it, and installs converge on aigw at their next
config rewrite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: AGENTS.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -132,11 +132,11 @@ When testing the gate, build CoDev-authored fixtures by calling the real writers
132
132
133
133
`src/lib/provider.ts` owns the provider id and display name CoDev writes into the OpenAI-compatible agent configs (Codex `model_provider` + `[model_providers.<id>]`, OpenCode/CoDev Code `provider.<id>` plus the `"<id>/<model>"` reference, Continue's `CoDev (<name>)` title). Claude Code has no provider concept — it only gets env vars.
134
134
135
-
Two built-in identities: **netgate / netGate** for SSO-issued keys (the "Get a new API Key" path, and "Reuse existing API Key" when the saved key carries no provider), and **ai-gateway / AI Gateway** as the manual path's fallback. On "I have my own API Key" the first form field is an optional, ASCII-only **Provider Name**; `providerFromName` slugs it (lowercase, non-alphanumeric runs → `-`, trimmed, capped at 32) and a blank or unusable name falls back to AI Gateway. The slug charset is deliberately `[a-z0-9-]`: TOML bare-key safe so `[model_providers.<id>]` needs no quoting, and slash-free so OpenCode's `"<id>/<model>"` stays parseable.
135
+
Two built-in identities: **aigw / AIGW** for SSO-issued keys (the "Get a new API Key" path, and "Reuse existing API Key" when the saved key carries no provider), and **ai-gateway / AI Gateway** as the manual path's fallback. On "I have my own API Key" the first form field is an optional, ASCII-only **Provider Name**; `providerFromName` slugs it (lowercase, non-alphanumeric runs → `-`, trimmed, capped at 32) and a blank or unusable name falls back to AI Gateway. The slug charset is deliberately `[a-z0-9-]`: TOML bare-key safe so `[model_providers.<id>]` needs no quoting, and slash-free so OpenCode's `"<id>/<model>"` stays parseable.
136
136
137
-
The load-bearing consequence: the provider id **is** CoDev's authorship marker for codex/opencode/codev-code. It gates `detectConfiguredTools` (whose configs `codevhub model` rewrites), `isCodevAuthored` (restore's delete-vs-`kept-live` decision), and `readAgentConfig`'s base_url readback. Since it's no longer a compile-time constant, `codevProviderIds()` returns the candidate set — the id saved in `~/.codev-hub/auth.json`, then `netgate`, `ai-gateway`, and the pre-rename `aigateway` — and `firstNestedKey` resolves the live entry against it. Nothing writes `aigateway`any more; it stays recognized so installs predating the rename keep working, and they converge on the new id at the next config rewrite. Detection is deliberately *saved-id-first*: without auth.json a custom-id config is unattributable and restore keeps it rather than deleting it, matching the module's standing rule that a config we can't attribute is one we don't delete.
137
+
The load-bearing consequence: the provider id **is** CoDev's authorship marker for codex/opencode/codev-code. It gates `detectConfiguredTools` (whose configs `codevhub model` rewrites), `isCodevAuthored` (restore's delete-vs-`kept-live` decision), and `readAgentConfig`'s base_url readback. Since it's no longer a compile-time constant, `codevProviderIds()` returns the candidate set — the id saved in `~/.codev-hub/auth.json`, then `aigw`, `ai-gateway`, and the pre-rename `netgate` and `aigateway` — and `firstNestedKey` resolves the live entry against it. Nothing writes the pre-rename ids any more; they stay recognized so installs predating the renames keep working, and they converge on the new id at the next config rewrite. Detection is deliberately *saved-id-first*: without auth.json a custom-id config is unattributable and restore keeps it rather than deleting it, matching the module's standing rule that a config we can't attribute is one we don't delete.
138
138
139
-
`Credentials`/`ApiKeyCreds` carry `providerId`/`providerName` (persisted as `provider_id`/`provider_name`), and `resolveProvider` supplies the netGate default when they're absent. **`saveApiKey` writes the whole api-key block, so an omitted provider pair clears it** — every re-save site (`ModelApp`'s two re-auth branches and its model switch, `refresh.ts#ensureFreshGatewayKey`, `SetupApp`'s model-choice) must thread it through, or a manually-named provider silently reverts to netGate on the next model switch or launch-time key refresh. `logout()` is the same hazard by a different route: it rebuilds the surviving file field-by-field rather than deleting SSO keys from it, so anything not listed in its `preserved` object is dropped. The provider pair was missing there and had to be added back — a field added to `AuthFileContents` is not automatically a field that survives sign-out.
139
+
`Credentials`/`ApiKeyCreds` carry `providerId`/`providerName` (persisted as `provider_id`/`provider_name`), and `resolveProvider` supplies the AIGW default when they're absent. **`saveApiKey` writes the whole api-key block, so an omitted provider pair clears it** — every re-save site (`ModelApp`'s two re-auth branches and its model switch, `refresh.ts#ensureFreshGatewayKey`, `SetupApp`'s model-choice) must thread it through, or a manually-named provider silently reverts to AIGW on the next model switch or launch-time key refresh. `logout()` is the same hazard by a different route: it rebuilds the surviving file field-by-field rather than deleting SSO keys from it, so anything not listed in its `preserved` object is dropped. The provider pair was missing there and had to be added back — a field added to `AuthFileContents` is not automatically a field that survives sign-out.
0 commit comments