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
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ Lines starting with `,` enter internal command mode (`,help`, `,skill name=my-sk
| `BUB_MODEL` | `openrouter:openrouter/free` | Model identifier |
| `BUB_API_KEY` | — | Provider key (optional with `bub login openai`) |
| `BUB_API_BASE` | — | Custom provider endpoint |
| `BUB_API_FORMAT` | `completion` | `completion`, `responses`, or `messages` |
| `BUB_CLIENT_ARGS` | — | JSON object forwarded to the underlying model client |
| `BUB_MAX_STEPS` | `50` | Max tool-use loop iterations |
| `BUB_MAX_TOKENS` | `16384` | Max tokens per model call |
Expand Down
4 changes: 2 additions & 2 deletions website/src/content/docs/docs/getting-started/first-turn.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This tutorial walks through one full turn — the framework's name for one inbou
You should have:

- [Bub installed](/docs/getting-started/install/) and `uv run bub hooks` reporting the `builtin` plugin
- one model access path: an API key exported as `BUB_API_KEY` or a provider-specific `BUB_<PROVIDER>_API_KEY`; alternatively, OpenAI Codex OAuth via `uv run bub login openai` with `BUB_MODEL=openai:gpt-5-codex`
- one model access path: an API key exported as `BUB_API_KEY` or a provider-specific `BUB_<PROVIDER>_API_KEY`; alternatively, OpenAI Codex OAuth via `uv run bub login openai` with `BUB_MODEL=openai:<codex-model>`

## 1. Create a workspace

Expand Down Expand Up @@ -88,7 +88,7 @@ If you want to use the OpenAI Codex OAuth path instead of an API key, log in wit
uv run bub login openai
```

Bub stores the credential locally. Use it by setting `BUB_MODEL=openai:gpt-5-codex` and leaving `BUB_API_KEY` unset.
Bub stores the credential locally. Use it by setting `BUB_MODEL=openai:<codex-model>` for a model available to your Codex account, leaving `BUB_API_KEY` unset, and not setting a custom `BUB_API_BASE`.

## Next steps

Expand Down
2 changes: 1 addition & 1 deletion website/src/content/docs/docs/getting-started/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ You should have:
- [`uv`](https://docs.astral.sh/uv/) on your `PATH`
- one model access path for the model-backed step:
- an API key exported as `BUB_API_KEY` or as a provider-specific `BUB_<PROVIDER>_API_KEY`, or
- OpenAI Codex OAuth via `uv run bub login openai` with `BUB_MODEL=openai:gpt-5-codex`
- OpenAI Codex OAuth via `uv run bub login openai` with `BUB_MODEL=openai:<codex-model>`

If you only want to inspect Bub without running a model turn, the API key is optional — comma commands such as `,help` work without one.

Expand Down
10 changes: 5 additions & 5 deletions website/src/content/docs/docs/operate/configure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ A minimal config looks like this:
# ~/.bub/config.yml
model: openrouter:openrouter/free
api_key: sk-or-v1-...
api_format: completion
telegram:
token: "123456:abcdef..."
allow_users: "123456789,your_username"
Expand All @@ -56,14 +55,15 @@ Every YAML key has a matching environment variable. The pattern is `BUB_<UPPERCA

| Variable | Purpose |
|---|---|
| `BUB_MODEL` | Model identifier, e.g. `openrouter:openrouter/free` or `openai:gpt-5-codex`. |
| `BUB_API_KEY` | API key for the active provider. |
| `BUB_API_BASE` | Override the provider's base URL. |
| `BUB_API_FORMAT` | Request format: `completion` (default), `responses`, or `messages`. |
| `BUB_MODEL` | Model identifier, e.g. `openrouter:openrouter/free` or `openai:<codex-model>`. |
| `BUB_API_KEY` | API key for the active provider. Leave unset when using `bub login openai`. |
| `BUB_API_BASE` | Override the provider's base URL. Leave unset for Codex OAuth so Bub can route through the Codex backend. |
| `BUB_HOME` | Bub's runtime data directory (history, tapes, managed plugin project). Default `~/.bub`; does not move the default config file. |
| `BUB_<PROVIDER>_API_KEY` | Per-provider key, e.g. `BUB_OPENROUTER_API_KEY`. |
| `BUB_<PROVIDER>_API_BASE` | Per-provider base URL. |

When you use `uv run bub login openai`, Bub reads Codex OAuth credentials from `CODEX_HOME` or `~/.codex` and refreshes them automatically. Use a model id under the `openai:` provider and keep both `BUB_API_KEY` and `BUB_API_BASE` unset for that path.

For the full table, including channel debounce knobs and advanced model-client settings, see [Settings reference](/docs/reference/settings/).

## 4. Configure channel credentials
Expand Down
4 changes: 2 additions & 2 deletions website/src/content/docs/docs/reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ bub onboard [OPTIONS]

Behavior notes:

- The builtin onboarding fragment prompts for: provider (one of `openrouter`, `openai`, `anthropic`, `gemini`, `azure`, `bedrock`, `ollama`, `groq`, `mistral`, `deepseek`, plus `custom`), model name, optional API key, optional API base, API format (`completion` / `responses` / `messages`), enabled channels, and stream output.
- The builtin onboarding fragment prompts for: provider (one of `openrouter`, `openai`, `anthropic`, `gemini`, `azure`, `bedrock`, `ollama`, `groq`, `mistral`, `deepseek`, plus `custom`), model name, optional API key, optional API base, enabled channels, and stream output.
- Each plugin's `onboard_config` hook receives the accumulated dict so far; non-dict returns abort with `TypeError`.
- The merged dict is validated through `configure.validate` before being written.

Expand Down Expand Up @@ -185,7 +185,7 @@ bub login openai [OPTIONS]

Behavior notes:

- On success prints `login: ok`, the account id, the auth file path, and a usage hint to set `BUB_MODEL=openai:gpt-5-codex` and omit `BUB_API_KEY`.
- On success prints `login: ok`, the account id, the auth file path, and a usage hint to set `BUB_MODEL=openai:<codex-model>` and omit `BUB_API_KEY`.
- On `CodexOAuthLoginError` exits with code `1`.

## `bub hooks`
Expand Down
14 changes: 7 additions & 7 deletions website/src/content/docs/docs/reference/settings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ class AgentSettings(Settings):
model_config = SettingsConfigDict(env_prefix="BUB_", env_parse_none_str="null", extra="ignore")
model: str = DEFAULT_MODEL # "openrouter:openrouter/free"
fallback_models: list[str] | None = None
api_key: str | dict[str, str] | None = Field(default_factory=provider_specific("api_key"))
api_base: str | dict[str, str] | None = Field(default_factory=provider_specific("api_base"))
api_format: Literal["completion", "responses", "messages"] = "completion"
api_key: str | dict[str, str] | None = None
api_base: str | dict[str, str] | None = None
max_steps: int = 50
max_tokens: int = DEFAULT_MAX_TOKENS # 16384
model_timeout_seconds: int | None = None
client_args: dict[str, Any] | None = None
client_args: dict[str, Any] = Field(default_factory=dict)
verbose: int = Field(default=0, ge=0, le=2)
```

Expand All @@ -60,17 +59,18 @@ Loaded under the YAML root section.
| `BUB_FALLBACK_MODELS` | `null` | `fallback_models` | Optional list of fallback model identifiers. |
| `BUB_API_KEY` | unset | `api_key` | Default API key. May also be a JSON object mapping provider → key. |
| `BUB_API_BASE` | unset | `api_base` | Default API base URL or per-provider mapping. |
| `BUB_<PROVIDER>_API_KEY` | unset | — | Provider-scoped API key, e.g. `BUB_OPENAI_API_KEY`. Collected by the `provider_specific("api_key")` factory. |
| `BUB_<PROVIDER>_API_KEY` | unset | — | Provider-scoped API key, e.g. `BUB_OPENAI_API_KEY`. |
| `BUB_<PROVIDER>_API_BASE` | unset | — | Provider-scoped API base URL, e.g. `BUB_OPENROUTER_API_BASE`. |
| `BUB_API_FORMAT` | `completion` | `api_format` | One of `completion`, `responses`, `messages`. |
| `BUB_MAX_STEPS` | `50` | `max_steps` | Maximum agent loop iterations per turn. |
| `BUB_MAX_TOKENS` | `16384` | `max_tokens` | Maximum tokens per model call. |
| `BUB_MODEL_TIMEOUT_SECONDS` | `null` | `model_timeout_seconds` | Per-call timeout in seconds. |
| `BUB_CLIENT_ARGS` | `null` | `client_args` | Extra kwargs passed to the underlying model client (JSON / dict). |
| `BUB_CLIENT_ARGS` | `{}` | `client_args` | Extra kwargs passed to the underlying model client (JSON / dict). |
| `BUB_VERBOSE` | `0` | `verbose` | Logging verbosity level (`0`–`2`). |

Provider-specific defaults are gathered at startup by scanning `os.environ` for `^BUB_(.+)_(API_KEY|API_BASE)$` and lowercasing the captured provider name.

OpenAI Codex OAuth does not need a separate request-format setting. After `bub login openai`, Bub detects the stored Codex OAuth token when the selected model uses the `openai:` provider and no custom API base is set.

## Channels — `ChannelSettings`

Defined in `src/bub/channels/manager.py`:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ sidebar:
你需要准备:

- 已 [安装 Bub](/zh-cn/docs/getting-started/install/) 且 `uv run bub hooks` 报告 `builtin` 插件
- 一种模型访问方式:通过 `BUB_API_KEY` 或提供商专用 `BUB_<PROVIDER>_API_KEY` 导出的 API key;也可以通过 `uv run bub login openai` 完成 OpenAI Codex OAuth,并设置 `BUB_MODEL=openai:gpt-5-codex`
- 一种模型访问方式:通过 `BUB_API_KEY` 或提供商专用 `BUB_<PROVIDER>_API_KEY` 导出的 API key;也可以通过 `uv run bub login openai` 完成 OpenAI Codex OAuth,并设置 `BUB_MODEL=openai:<codex-model>`

## 1. 创建 workspace

Expand Down Expand Up @@ -88,7 +88,7 @@ uv run bub chat
uv run bub login openai
```

Bub 会在本地保存凭据。使用该路径时,设置 `BUB_MODEL=openai:gpt-5-codex`,并保持 `BUB_API_KEY` 未设置。
Bub 会在本地保存凭据。使用该路径时,选择你的 Codex 账号可用的模型并设置 `BUB_MODEL=openai:<codex-model>`,同时保持 `BUB_API_KEY` 未设置,也不要设置自定义 `BUB_API_BASE`

## 下一步

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Bub 是一个用于在共享环境中构建 agent 的小型 Python 框架。内
- 已加入 `PATH` 的 [`uv`](https://docs.astral.sh/uv/)
- 一种模型访问方式,用于 model-backed 阶段:
- 通过 `BUB_API_KEY` 或提供商专用 `BUB_<PROVIDER>_API_KEY` 导出的 API key,或
- 通过 `uv run bub login openai` 完成 OpenAI Codex OAuth,并设置 `BUB_MODEL=openai:gpt-5-codex`
- 通过 `uv run bub login openai` 完成 OpenAI Codex OAuth,并设置 `BUB_MODEL=openai:<codex-model>`

如果只想检查 Bub 而不实际跑一次 model turn,API key 是可选的——`,help` 等 comma 命令无需它即可使用。

Expand Down
10 changes: 5 additions & 5 deletions website/src/content/docs/zh-cn/docs/operate/configure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ uv run bub onboard
# ~/.bub/config.yml
model: openrouter:openrouter/free
api_key: sk-or-v1-...
api_format: completion
telegram:
token: "123456:abcdef..."
allow_users: "123456789,your_username"
Expand All @@ -56,14 +55,15 @@ telegram:

| 变量 | 用途 |
|---|---|
| `BUB_MODEL` | 模型标识,如 `openrouter:openrouter/free` 或 `openai:gpt-5-codex`。 |
| `BUB_API_KEY` | 当前提供商的 API key。 |
| `BUB_API_BASE` | 覆盖提供商的基础 URL。 |
| `BUB_API_FORMAT` | 请求格式:`completion`(默认)、`responses` 或 `messages`。 |
| `BUB_MODEL` | 模型标识,如 `openrouter:openrouter/free` 或 `openai:<codex-model>`。 |
| `BUB_API_KEY` | 当前提供商的 API key。使用 `bub login openai` 时保持未设置。 |
| `BUB_API_BASE` | 覆盖提供商的基础 URL。使用 Codex OAuth 时保持未设置,以便 Bub 路由到 Codex backend。 |
| `BUB_HOME` | Bub 的运行时数据目录(history、tapes、托管插件项目)。默认 `~/.bub`;不会移动默认配置文件。 |
| `BUB_<PROVIDER>_API_KEY` | 单个提供商的 key,如 `BUB_OPENROUTER_API_KEY`。 |
| `BUB_<PROVIDER>_API_BASE` | 单个提供商的基础 URL。 |

使用 `uv run bub login openai` 时,Bub 会从 `CODEX_HOME` 或 `~/.codex` 读取 Codex OAuth 凭据,并自动 refresh。这个路径下使用 `openai:` provider 的模型标识,同时保持 `BUB_API_KEY` 和 `BUB_API_BASE` 未设置。

完整变量表(包括 channel 防抖参数和高级模型客户端设置)见 [Settings 参考](/zh-cn/docs/reference/settings/)。

## 4. 配置 channel 凭据
Expand Down
4 changes: 2 additions & 2 deletions website/src/content/docs/zh-cn/docs/reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ bub onboard [OPTIONS]

行为说明:

- builtin 的 onboarding fragment 会询问:provider(`openrouter`、`openai`、`anthropic`、`gemini`、`azure`、`bedrock`、`ollama`、`groq`、`mistral`、`deepseek` 之一,或 `custom`)、模型名、可选 API key、可选 API base、API format(`completion` / `responses` / `messages`)、启用的 channel、是否流式输出。
- builtin 的 onboarding fragment 会询问:provider(`openrouter`、`openai`、`anthropic`、`gemini`、`azure`、`bedrock`、`ollama`、`groq`、`mistral`、`deepseek` 之一,或 `custom`)、模型名、可选 API key、可选 API base、启用的 channel、是否流式输出。
- 每个插件的 `onboard_config` 钩子都会拿到当前已累计的 dict;返回值不是 dict 时抛 `TypeError` 并中止。
- 合并后的 dict 会经过 `configure.validate` 验证后才写入。

Expand Down Expand Up @@ -185,7 +185,7 @@ bub login openai [OPTIONS]

行为说明:

- 成功时打印 `login: ok`、account id、auth 文件路径,并提示设置 `BUB_MODEL=openai:gpt-5-codex` 且不再提供 `BUB_API_KEY`。
- 成功时打印 `login: ok`、account id、auth 文件路径,并提示设置 `BUB_MODEL=openai:<codex-model>` 且不再提供 `BUB_API_KEY`。
- 抛出 `CodexOAuthLoginError` 时以退出码 `1` 退出。

## `bub hooks`
Expand Down
16 changes: 8 additions & 8 deletions website/src/content/docs/zh-cn/docs/reference/settings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ class AgentSettings(Settings):
model_config = SettingsConfigDict(env_prefix="BUB_", env_parse_none_str="null", extra="ignore")
model: str = DEFAULT_MODEL # "openrouter:openrouter/free"
fallback_models: list[str] | None = None
api_key: str | dict[str, str] | None = Field(default_factory=provider_specific("api_key"))
api_base: str | dict[str, str] | None = Field(default_factory=provider_specific("api_base"))
api_format: Literal["completion", "responses", "messages"] = "completion"
api_key: str | dict[str, str] | None = None
api_base: str | dict[str, str] | None = None
max_steps: int = 50
max_tokens: int = DEFAULT_MAX_TOKENS # 16384
model_timeout_seconds: int | None = None
client_args: dict[str, Any] | None = None
client_args: dict[str, Any] = Field(default_factory=dict)
verbose: int = Field(default=0, ge=0, le=2)
```

Expand All @@ -60,16 +59,17 @@ class AgentSettings(Settings):
| `BUB_FALLBACK_MODELS` | `null` | `fallback_models` | 可选的回退模型标识列表。 |
| `BUB_API_KEY` | unset | `api_key` | 默认 API key;也可以是按 provider 索引的 JSON object。 |
| `BUB_API_BASE` | unset | `api_base` | 默认 API base URL,或按 provider 索引的映射。 |
| `BUB_<PROVIDER>_API_KEY` | unset | — | 按 provider 划分的 API key,例如 `BUB_OPENAI_API_KEY`。由 `provider_specific("api_key")` 工厂收集。 |
| `BUB_<PROVIDER>_API_KEY` | unset | — | 按 provider 划分的 API key,例如 `BUB_OPENAI_API_KEY`。 |
| `BUB_<PROVIDER>_API_BASE` | unset | — | 按 provider 划分的 API base URL,例如 `BUB_OPENROUTER_API_BASE`。 |
| `BUB_API_FORMAT` | `completion` | `api_format` | `completion`、`responses`、`messages` 之一。 |
| `BUB_MAX_STEPS` | `50` | `max_steps` | 单次 turn 内 agent 循环的最大步数。 |
| `BUB_MAX_TOKENS` | `16384` | `max_tokens` | 单次模型调用的最大 token 数。 |
| `BUB_MODEL_TIMEOUT_SECONDS` | `null` | `model_timeout_seconds` | 单次调用的超时秒数。 |
| `BUB_CLIENT_ARGS` | `null` | `client_args` | 传递给底层模型 client 的额外 kwargs(JSON / dict)。 |
| `BUB_CLIENT_ARGS` | `{}` | `client_args` | 传递给底层模型 client 的额外 kwargs(JSON / dict)。 |
| `BUB_VERBOSE` | `0` | `verbose` | 日志详细级别(`0`–`2`)。 |

启动时 `provider_specific` 工厂会扫描 `os.environ` 中匹配 `^BUB_(.+)_(API_KEY|API_BASE)$` 的变量,把捕获到的 provider 名称小写后作为 key 收集。
启动时 `ProviderSpecificEnvSource` 会扫描 `os.environ` 中匹配 `^BUB_(.+)_(API_KEY|API_BASE)$` 的变量,把捕获到的 provider 名称小写后作为 key 收集。

OpenAI Codex OAuth 不需要单独的请求格式设置。运行 `bub login openai` 后,当模型使用 `openai:` provider 且没有自定义 API base 时,Bub 会检测并使用本地保存的 Codex OAuth token。

## Channels —— `ChannelSettings`

Expand Down
Loading