mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-04 08:28:36 +00:00
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:
parent
8c9110fee3
commit
234e895e5a
@ -286,8 +286,8 @@ remain accepted as no-op compatibility aliases.
|
|||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `nanobot provider login openai-codex` | Authenticate OpenAI Codex provider |
|
| `nanobot provider login openai-codex --set-main` | Authenticate Codex and select its current default model |
|
||||||
| `nanobot provider login github-copilot` | Authenticate GitHub Copilot provider |
|
| `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 openai-codex` | Remove OpenAI Codex OAuth state |
|
||||||
| `nanobot provider logout github-copilot` | Remove GitHub Copilot OAuth state |
|
| `nanobot provider logout github-copilot` | Remove GitHub Copilot OAuth state |
|
||||||
|
|
||||||
|
|||||||
@ -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) |
|
| `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) | — |
|
| `vllm` | LLM (local, any OpenAI-compatible server) | — |
|
||||||
| `nvidia` | LLM (NVIDIA NIM) | [build.nvidia.com](https://build.nvidia.com/) |
|
| `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` |
|
| `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) |
|
| `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>
|
<details>
|
||||||
<summary><b>OpenAI Codex (OAuth)</b></summary>
|
<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
|
```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
|
```bash
|
||||||
nanobot agent -m "Hello!"
|
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>
|
</details>
|
||||||
|
|
||||||
|
|||||||
@ -418,38 +418,19 @@ See [`configuration.md#providers`](./configuration.md#providers) for Bedrock-spe
|
|||||||
|
|
||||||
Some providers do not use API keys in `config.json`.
|
Some providers do not use API keys in `config.json`.
|
||||||
|
|
||||||
|
For OpenAI Codex:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nanobot provider login openai-codex
|
nanobot provider login openai-codex --set-main
|
||||||
nanobot provider login github-copilot
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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:
|
```bash
|
||||||
|
nanobot provider login github-copilot --set-main
|
||||||
```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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
## 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`. |
|
| 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. |
|
| 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. |
|
| 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
|
## Langfuse Problems
|
||||||
|
|
||||||
|
|||||||
@ -2646,7 +2646,7 @@ _PROVIDER_DISPLAY: dict[str, str] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_OAUTH_PROVIDER_DEFAULT_MODELS: 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",
|
"github_copilot": "github-copilot/gpt-5.4-mini",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class OpenAICodexProvider(LLMProvider):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
default_model: str = "openai-codex/gpt-5.1-codex",
|
default_model: str = "openai-codex/gpt-5.6-sol",
|
||||||
proxy: str | None = None,
|
proxy: str | None = None,
|
||||||
):
|
):
|
||||||
super().__init__(api_key=None, api_base=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():
|
def test_config_matches_openai_codex_with_hyphen_prefix():
|
||||||
config = Config()
|
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"
|
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():
|
def test_config_dump_excludes_oauth_provider_blocks():
|
||||||
config = Config()
|
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")))
|
saved = Config.model_validate(json.loads(config_path.read_text(encoding="utf-8")))
|
||||||
assert saved.agents.defaults.provider == "openai_codex"
|
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 saved.agents.defaults.model_preset is None
|
||||||
assert make_provider(saved).__class__.__name__ == "OpenAICodexProvider"
|
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():
|
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.6-sol") == "gpt-5.6-sol"
|
||||||
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"
|
||||||
|
|
||||||
|
|
||||||
def test_make_provider_passes_extra_headers_to_custom_provider():
|
def test_make_provider_passes_extra_headers_to_custom_provider():
|
||||||
|
|||||||
@ -18,6 +18,7 @@ from nanobot.providers.openai_codex_provider import (
|
|||||||
_request_codex,
|
_request_codex,
|
||||||
_should_retry_status,
|
_should_retry_status,
|
||||||
)
|
)
|
||||||
|
from nanobot.providers.registry import find_by_name
|
||||||
|
|
||||||
|
|
||||||
def _mock_codex_token(monkeypatch: pytest.MonkeyPatch) -> None:
|
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:
|
class _WarningCaptureLogger:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.calls: list[tuple[str, tuple[Any, ...]]] = []
|
self.calls: list[tuple[str, tuple[Any, ...]]] = []
|
||||||
|
|||||||
@ -1220,7 +1220,7 @@ def test_create_model_configuration_accepts_configured_oauth_provider(
|
|||||||
{
|
{
|
||||||
"label": ["Codex"],
|
"label": ["Codex"],
|
||||||
"provider": ["openai_codex"],
|
"provider": ["openai_codex"],
|
||||||
"model": ["openai-codex/gpt-5.1-codex"],
|
"model": ["openai-codex/gpt-5.6-sol"],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user