fix(codex): align OAuth defaults and setup docs (#4910)
* fix(codex): align OAuth defaults and setup docs * docs(codex): clarify provider settings key * docs(codex): simplify OAuth setup guidance
This commit is contained in:
@@ -286,8 +286,8 @@ remain accepted as no-op compatibility aliases.
|
||||
|
||||
| Command | Description |
|
||||
|---|---|
|
||||
| `nanobot provider login openai-codex` | Authenticate OpenAI Codex provider |
|
||||
| `nanobot provider login github-copilot` | Authenticate GitHub Copilot provider |
|
||||
| `nanobot provider login openai-codex --set-main` | Authenticate Codex and select its current default model |
|
||||
| `nanobot provider login github-copilot --set-main` | Authenticate GitHub Copilot and select its current default model |
|
||||
| `nanobot provider logout openai-codex` | Remove OpenAI Codex OAuth state |
|
||||
| `nanobot provider logout github-copilot` | Remove GitHub Copilot OAuth state |
|
||||
|
||||
|
||||
+5
-47
@@ -298,7 +298,7 @@ Tracing covers the providers that go through nanobot's OpenAI-compatible client
|
||||
| `ovms` | LLM (local, OpenVINO Model Server) | [docs.openvino.ai](https://docs.openvino.ai/2026/model-server/ovms_docs_llm_quickstart.html) |
|
||||
| `vllm` | LLM (local, any OpenAI-compatible server) | — |
|
||||
| `nvidia` | LLM (NVIDIA NIM) | [build.nvidia.com](https://build.nvidia.com/) |
|
||||
| `openai_codex` | LLM (Codex, OAuth) | `nanobot provider login openai-codex` |
|
||||
| `openai_codex` | LLM (Codex, OAuth) | `nanobot provider login openai-codex --set-main` |
|
||||
| `github_copilot` | LLM (GitHub Copilot, OAuth) | `nanobot provider login github-copilot` |
|
||||
| `qianfan` | LLM (Baidu Qianfan) | [cloud.baidu.com](https://cloud.baidu.com/doc/qianfan/s/Hmh4suq26) |
|
||||
|
||||
@@ -660,61 +660,19 @@ nanobot agent -m "Reply with one short sentence."
|
||||
<details>
|
||||
<summary><b>OpenAI Codex (OAuth)</b></summary>
|
||||
|
||||
Codex uses OAuth instead of API keys. Requires a ChatGPT Plus or Pro account. `nanobot provider login` stores the OAuth session outside config. A `providers.openai_codex` block is optional and is only needed for provider-specific settings such as a proxy.
|
||||
Codex uses OAuth instead of API keys and requires a ChatGPT Plus or Pro account. Authenticate it and make the current flagship model the active agent model with one command:
|
||||
|
||||
**1. Login:**
|
||||
```bash
|
||||
nanobot provider login openai-codex
|
||||
nanobot provider login openai-codex --set-main
|
||||
```
|
||||
|
||||
If the machine running nanobot cannot open a graphical browser, copy the printed URL into a real browser. For remote SSH login, open the URL locally, then paste the final `http://localhost:1455/auth/callback?...` redirect URL back into the terminal when prompted.
|
||||
Then run:
|
||||
|
||||
**2. Optional proxy** (merge into `~/.nanobot/config.json` if Codex OAuth or Codex API traffic must use a proxy):
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {
|
||||
"openai_codex": {
|
||||
"proxy": "http://127.0.0.1:7890"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The proxy applies to Codex OAuth token refresh, interactive token exchange, and Codex Responses API requests. It does not affect other providers; configure `proxy` separately on each supported provider that needs it.
|
||||
|
||||
**3. Set model** (merge into `~/.nanobot/config.json`):
|
||||
```json
|
||||
{
|
||||
"modelPresets": {
|
||||
"codex": {
|
||||
"provider": "openai_codex",
|
||||
"model": "gpt-5.1-codex",
|
||||
"reasoningEffort": "high"
|
||||
}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"modelPreset": "codex"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use `reasoningEffort` in the preset to send a Codex reasoning effort such as `"low"`, `"medium"`, `"high"`, or another value supported by the selected model. When `provider` is explicitly `openai_codex`, the model name does not need the `openai-codex/` prefix.
|
||||
|
||||
**4. Chat:**
|
||||
```bash
|
||||
nanobot agent -m "Hello!"
|
||||
|
||||
# Target a specific workspace/config locally
|
||||
nanobot agent -c ~/.nanobot-telegram/config.json -m "Hello!"
|
||||
|
||||
# One-off workspace override on top of that config
|
||||
nanobot agent -c ~/.nanobot-telegram/config.json -w /tmp/nanobot-telegram-test -m "Hello!"
|
||||
```
|
||||
|
||||
> Docker users: use `docker run -it` for interactive OAuth login.
|
||||
For proxy, remote/headless login, model-name, or config-key errors, see [`troubleshooting.md`](./troubleshooting.md#provider-and-model-problems).
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
+7
-26
@@ -418,38 +418,19 @@ See [`configuration.md#providers`](./configuration.md#providers) for Bedrock-spe
|
||||
|
||||
Some providers do not use API keys in `config.json`.
|
||||
|
||||
For OpenAI Codex:
|
||||
|
||||
```bash
|
||||
nanobot provider login openai-codex
|
||||
nanobot provider login github-copilot
|
||||
nanobot provider login openai-codex --set-main
|
||||
```
|
||||
|
||||
Then explicitly select the provider and model in a preset. OAuth providers are not valid automatic fallbacks.
|
||||
For GitHub Copilot:
|
||||
|
||||
For OpenAI Codex, add `providers.openai_codex.proxy` only when Codex OAuth/token refresh or Codex API requests must use a proxy:
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {
|
||||
"openai_codex": {
|
||||
"proxy": "http://127.0.0.1:7890"
|
||||
}
|
||||
},
|
||||
"modelPresets": {
|
||||
"codex": {
|
||||
"provider": "openai_codex",
|
||||
"model": "gpt-5.1-codex",
|
||||
"reasoningEffort": "high"
|
||||
}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"modelPreset": "codex"
|
||||
}
|
||||
}
|
||||
}
|
||||
```bash
|
||||
nanobot provider login github-copilot --set-main
|
||||
```
|
||||
|
||||
If you run the login command on a remote/headless machine and open the authorization URL in a local browser, paste the final `http://localhost:1455/auth/callback?...` redirect URL back into the terminal when prompted. See [`configuration.md#providers`](./configuration.md#providers) for the full OAuth provider notes.
|
||||
Each command authenticates the selected provider and makes its current default model active. OAuth providers are not valid automatic fallbacks. See [`troubleshooting.md`](./troubleshooting.md#provider-and-model-problems) for proxy, headless-login, model-name, and config-key errors.
|
||||
|
||||
## Provider Resolution
|
||||
|
||||
|
||||
@@ -135,7 +135,12 @@ If you need a known-good snippet instead of diagnosis, use [`provider-cookbook.m
|
||||
| Provider cannot be inferred | Pin `modelPresets.<name>.provider` in the active preset instead of using `"auto"`. For legacy direct configs, pin `agents.defaults.provider`. |
|
||||
| Local model connection refused | Ollama, vLLM, LM Studio, or another local server is not running, or `apiBase` points to the wrong port. |
|
||||
| Bedrock validation error | Check AWS region, credentials, model access, model ID, and whether the model supports Converse. |
|
||||
| OAuth provider fails | Run `nanobot provider login openai-codex` or `nanobot provider login github-copilot`, then select the provider explicitly. |
|
||||
| OAuth provider fails | Run `nanobot provider login openai-codex --set-main` or `nanobot provider login github-copilot --set-main`. |
|
||||
| Codex OAuth needs a proxy | Set `providers.openaiCodex.proxy` before running the login command. The proxy applies to login, token refresh, and Codex API requests. |
|
||||
| Codex login runs on a remote/headless machine | Open the printed URL in a local browser, then paste the final `http://localhost:1455/auth/callback?...` URL back into the terminal. |
|
||||
| Codex login runs in Docker | Start the container with `docker run -it` so the OAuth flow has an interactive terminal. |
|
||||
| Codex says a model is not supported with a ChatGPT account | Use provider `openai_codex` with a Codex model such as `openai-codex/gpt-5.6-sol`. Do not use the direct-API `openai/...` prefix with Codex OAuth. |
|
||||
| Config says `providers.openai_codex` conflicts with the built-in provider | Under `providers`, keep only the canonical `openaiCodex` settings key and remove a duplicate `openai_codex` key. A model preset's `provider` value remains `openai_codex`. |
|
||||
|
||||
## Langfuse Problems
|
||||
|
||||
|
||||
@@ -2646,7 +2646,7 @@ _PROVIDER_DISPLAY: dict[str, str] = {
|
||||
}
|
||||
|
||||
_OAUTH_PROVIDER_DEFAULT_MODELS: dict[str, str] = {
|
||||
"openai_codex": "openai-codex/gpt-5.4-mini",
|
||||
"openai_codex": "openai-codex/gpt-5.6-sol",
|
||||
"github_copilot": "github-copilot/gpt-5.4-mini",
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class OpenAICodexProvider(LLMProvider):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
default_model: str = "openai-codex/gpt-5.1-codex",
|
||||
default_model: str = "openai-codex/gpt-5.6-sol",
|
||||
proxy: str | None = None,
|
||||
):
|
||||
super().__init__(api_key=None, api_base=None)
|
||||
|
||||
@@ -450,11 +450,21 @@ def test_config_matches_github_copilot_codex_with_hyphen_prefix():
|
||||
|
||||
def test_config_matches_openai_codex_with_hyphen_prefix():
|
||||
config = Config()
|
||||
config.agents.defaults.model = "openai-codex/gpt-5.1-codex"
|
||||
config.agents.defaults.model = "openai-codex/gpt-5.6-sol"
|
||||
|
||||
assert config.get_provider_name() == "openai_codex"
|
||||
|
||||
|
||||
def test_openai_codex_oauth_default_matches_curated_flagship():
|
||||
spec = find_by_name("openai_codex")
|
||||
|
||||
assert spec is not None
|
||||
assert spec.builtin_models
|
||||
assert cli_commands._OAUTH_PROVIDER_DEFAULT_MODELS["openai_codex"] == (
|
||||
spec.builtin_models[0].id
|
||||
)
|
||||
|
||||
|
||||
def test_config_dump_excludes_oauth_provider_blocks():
|
||||
config = Config()
|
||||
|
||||
@@ -605,7 +615,7 @@ def test_provider_login_can_set_openai_codex_as_main_provider(tmp_path):
|
||||
|
||||
saved = Config.model_validate(json.loads(config_path.read_text(encoding="utf-8")))
|
||||
assert saved.agents.defaults.provider == "openai_codex"
|
||||
assert saved.agents.defaults.model == "openai-codex/gpt-5.4-mini"
|
||||
assert saved.agents.defaults.model == "openai-codex/gpt-5.6-sol"
|
||||
assert saved.agents.defaults.model_preset is None
|
||||
assert make_provider(saved).__class__.__name__ == "OpenAICodexProvider"
|
||||
|
||||
@@ -1071,8 +1081,8 @@ async def test_github_copilot_provider_refreshes_client_api_key_before_chat():
|
||||
|
||||
|
||||
def test_openai_codex_strip_prefix_supports_hyphen_and_underscore():
|
||||
assert _strip_model_prefix("openai-codex/gpt-5.1-codex") == "gpt-5.1-codex"
|
||||
assert _strip_model_prefix("openai_codex/gpt-5.1-codex") == "gpt-5.1-codex"
|
||||
assert _strip_model_prefix("openai-codex/gpt-5.6-sol") == "gpt-5.6-sol"
|
||||
assert _strip_model_prefix("openai_codex/gpt-5.6-sol") == "gpt-5.6-sol"
|
||||
|
||||
|
||||
def test_make_provider_passes_extra_headers_to_custom_provider():
|
||||
|
||||
@@ -18,6 +18,7 @@ from nanobot.providers.openai_codex_provider import (
|
||||
_request_codex,
|
||||
_should_retry_status,
|
||||
)
|
||||
from nanobot.providers.registry import find_by_name
|
||||
|
||||
|
||||
def _mock_codex_token(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
@@ -30,6 +31,14 @@ def _mock_codex_token(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
)
|
||||
|
||||
|
||||
def test_codex_default_model_matches_curated_flagship() -> None:
|
||||
spec = find_by_name("openai_codex")
|
||||
|
||||
assert spec is not None
|
||||
assert spec.builtin_models
|
||||
assert OpenAICodexProvider().get_default_model() == spec.builtin_models[0].id
|
||||
|
||||
|
||||
class _WarningCaptureLogger:
|
||||
def __init__(self) -> None:
|
||||
self.calls: list[tuple[str, tuple[Any, ...]]] = []
|
||||
|
||||
@@ -1220,7 +1220,7 @@ def test_create_model_configuration_accepts_configured_oauth_provider(
|
||||
{
|
||||
"label": ["Codex"],
|
||||
"provider": ["openai_codex"],
|
||||
"model": ["openai-codex/gpt-5.1-codex"],
|
||||
"model": ["openai-codex/gpt-5.6-sol"],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user