Repository navigation
Conversation
Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
There was a problem hiding this comment.
🟡 Changes recommended
Routing, system-mode readability, and shared callback-listener coordination need corrections before supported subscription flows work reliably.
3 open issues
1 file not reviewed
frontend/pnpm-lock.yaml: Generated file
What changed in this PR
Adds ChatGPT subscription support to Codex through Agentdesktop’s credential helper and gateway, alongside existing Claude integrations.
Changes:
- Adds OpenAI OAuth, token refresh, composite credentials, and subscription billing classification.
- Updates Codex configuration generation and separates proxy routing, caching, and tests.
- Adds schemas, examples, documentation, and integration coverage.
| File | Description |
|---|---|
| schema/daemon-config.md | Documents Codex subscription authentication. |
| schema/daemon-config.json | Adds the Codex authentication field. |
| README.md | Explains subscription setup and routing. |
| frontend/pnpm-lock.yaml | Updates optional YAML dependency resolution. |
| frontend/controller/src/views/ConfigurationView.stories.tsx | Covers subscription configuration output. |
| examples/codex-subscription/README.md | Documents setup and validation limits. |
| examples/codex-subscription/dex.yaml | Configures demonstration identity authentication. |
| examples/codex-subscription/config.yaml | Provides subscription daemon settings. |
| examples/codex-subscription/compose.yaml | Runs example gateway and identity services. |
| examples/codex-subscription/agentgateway.yaml | Validates identity and restores provider credentials. |
| crates/core/src/config.rs | Adds subscription configuration and shared classification. |
| crates/controller/src/service.rs | Recognizes Codex subscription billing. |
| crates/agent/tests/common/gateway.rs | Extends mock subscription request validation. |
| crates/agent/src/subscription.rs | Composes provider-specific credentials. |
| crates/agent/src/subscription_oauth/openai.rs | Implements ChatGPT OAuth and refresh. |
| crates/agent/src/subscription_oauth/mod.rs | Shares subscription credential lifecycle logic. |
| crates/agent/src/subscription_oauth/anthropic.rs | Adapts Claude to shared OAuth infrastructure. |
| crates/agent/src/provider/codex/reconcile.rs | Generates subscription provider configuration. |
| crates/agent/src/provider/codex/mod.rs | Updates reconciliation wiring and system-mode coverage. |
| crates/agent/src/provider/codex/integration_tests.rs | Adds native Codex subscription lifecycle coverage. |
| crates/agent/src/oidc.rs | Supports a separate provider callback listener. |
| crates/agent/src/llm_proxy/tests.rs | Extracts tests and adds Codex passthrough coverage. |
| crates/agent/src/llm_proxy/routes.rs | Extracts routing and adds the Codex route. |
| crates/agent/src/llm_proxy/cache.rs | Extracts credential caching and its tests. |
| crates/agent/src/lib.rs | Wires shared OAuth modules. |
| crates/agent/src/daemon.rs | Starts authentication for configured subscription providers. |
| crates/agent/src/api.rs | Resolves provider-specific subscription credentials. |
Review effort: Balanced
Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
|
@copilot resolve the merge conflicts in this pull request |
# Conflicts: # frontend/pnpm-lock.yaml Co-authored-by: peterj <11080940+peterj@users.noreply.github.com>
Resolved in 58fdc2c by merging |
ilackarms
left a comment
There was a problem hiding this comment.
The direct credential-helper flow and shared OAuth extraction look consistent with the existing Claude integration. I found one login-recovery defect: a permanent nested refresh-token rejection leaves the helper retrying the unusable token instead of reopening sign-in. Please address that before merging.
| if !status.is_success() { | ||
| let invalid_grant = response.json::<Value>().await.ok().is_some_and(|body| { | ||
| matches!( | ||
| body["error"].as_str(), |
There was a problem hiding this comment.
Could we recognize permanent refresh errors in the nested OpenAI error envelope as well? An HTTP 400 response such as {"error":{"code":"refresh_token_reused"}} currently falls through to the generic error because body["error"].as_str() is None. OpenAi::refresh therefore returns an error instead of Ok(None), and the shared credential path exits before starting browser sign-in. Every subsequent request retries the same stored refresh token, so restarting the daemon cannot recover the subscription. Codex 0.153.4 explicitly covers this response in refresh_token_does_not_retry_after_bad_request_reused_failure. Please classify the nested permanent codes as reauthorization-required and add a regression test, while keeping transient failures non-destructive.

Adds
programs.codex.auth: subscriptionso Codex can retain its ChatGPTlogin while authenticating separately to the organization’s gateway.
Agentdesktop generates the Codex provider and pairing header automatically.
The local proxy forwards the ChatGPT token separately from gateway identity; the gateway validates identity before restoring the provider credential.
llmGateway.proxyUrl.