1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# Embedded provider table (arch §4.2). Parsed through the SAME
# `toml::from_str::<PartialConfig>` path as a user config file — the lowest-
# precedence operand of the resolution fold, never a bootstrap special case
# (config §3.5). A unit test parses this file so a malformed edit fails the
# build, not a user run.
# The transport SILENCE budget in whole seconds (config §4.3, architecture §13.15).
# The single home for this number — `bz` reads it off the resolved config and, via
# `timeouts()`, fans it onto ureq's connect + response-header + inter-chunk-idle
# budgets, so the bin holds no magic constant. It abandons an upstream that makes no
# progress (sends no bytes) for this long — applied per phase — WITHOUT capping total
# stream length, so a long-but-live generation is never cut (it is NOT a wall-clock
# total). Override in your config file / env / flag; delete this line to unbound it.
= 120
[[]]
= "anthropic"
= "https://api.anthropic.com"
= "anthropic_messages"
= "api_key"
= { = "x-api-key", = "raw" }
= [["anthropic-version", "2023-06-01"]]
= { = 4096 } # Anthropic requires max_tokens; the row's sane default, overridable via config/flag (config §4.1)
= ["claude-"] # owns the claude- family, so `bz -m claude-… "q"` routes here with no --provider (arch §4.3)
= { = "api_key_env", = "ANTHROPIC_API_KEY" } # vendor-conventional key alias as a ROW-SCOPED, store-miss source — below BRAZEN_API_KEY/--api-key, can't leak cross-vendor or shadow a stored cred (auth §5.5)
[[]]
= "openai"
= "https://api.openai.com/v1"
= "openai_chat"
= "bearer"
= { = "Authorization", = "bearer" }
= ["gpt-", "chatgpt-", "o1", "o3", "o4"] # the OpenAI families; openai-responses (same models, other protocol) ships none, so it stays explicit (arch §4.3)
# Mistral speaks the OpenAI chat dialect verbatim — the severability proof: one
# row, ZERO Rust (providers §2). Reuses the OpenAiChat protocol + bearer auth.
[[]]
= "mistral"
= "https://api.mistral.ai/v1"
= "openai_chat"
= "bearer"
= { = "Authorization", = "bearer" }
= ["mistral-", "ministral-", "magistral-", "codestral-", "pixtral-"]
[[]]
= "openai-responses"
= "https://api.openai.com/v1"
= "openai_responses"
= "bearer"
= { = "Authorization", = "bearer" }
# No model_prefixes: openai-responses serves the SAME OpenAI model ids as `openai`
# over a different protocol. Claiming them would make every gpt-… ambiguous (78),
# so this alternate-protocol row stays opt-in via explicit --provider (arch §4.3).
# Google authenticates with a custom header NAME carrying the raw key — pure row
# DATA read by the shared ApiKeyAuth, no new Auth impl (providers §4.1).
[[]]
= "google"
= "https://generativelanguage.googleapis.com"
= "google_generative_ai"
= "api_key"
= { = "x-goog-api-key", = "raw" }
= ["gemini-"]
# Local Ollama needs no auth: `auth = "none"` reads no credential and writes no
# header, so a keyless row carries no `api_header` (providers §5.1).
[[]]
= "ollama"
= "http://localhost:11434"
= "ollama_chat"
= "none"
# The installed Claude Code CLI as a pure model pass-through (claude-code spec): an
# EXEC-transport row — `exec` substitutes for base_url, `claude` carries its own
# OAuth so auth = "none". The five listed canonical fields have no wire slot on the
# CLI (spec §4.1), so they strip pre-encode. No model_prefixes: `anthropic` owns
# `claude-`; this alternate-transport row stays opt-in via explicit --provider,
# like openai-responses (arch §4.3.1).
[[]]
= "claude-code"
= "claude_code"
= "none"
= "claude"
= ["max_tokens", "temperature", "top_p", "stop", "output"]
# The ONE built-in OAuth row: "Sign in with ChatGPT" (auth §10). It ships so that
# `bz --login --provider openai-chatgpt --browser` works on a bare install — without
# it the binary offers NO reachable browser sign-in and a first-time user's only path
# to a credential is hand-authoring an api key into a config file (operator ruling
# 2026-08-16, reversing §10.5's deferred recommendation; §7's "no built-in OAuth row"
# is now "no built-in row whose vendor restricts third-party use" — see below).
#
# Shipping it compiles in NO vendor login policy: every field is row DATA the
# vendor-blind `OAuth2` impl reads off `AuthCtx` (auth §1.3, §7.1), so this row is
# severable — delete it and the capability goes with it, no Rust changes. The
# `client_id` is Codex's PUBLISHED PUBLIC client, and every value here was validated
# live end to end (auth §10.7).
#
# It is LAST and claims NO model_prefixes, so it moves nothing: `anthropic` stays the
# head row a bare `bz "q"` reaches, and this row — like `openai-responses`, whose
# models it serves over the same protocol — stays opt-in via explicit --provider
# (arch §4.3.1).
#
# NOT shipped, deliberately: an Anthropic subscription-OAuth row. That vendor's terms
# restrict third-party use of its subscription tokens, so neither the row nor a
# turnkey recipe for it is published (bl-a661). The general `oauth2` mechanism stays
# available to an operator who may use it — that is the README's generic block.
[[]]
= "openai-chatgpt"
= "https://chatgpt.com/backend-api/codex"
= "openai_responses"
= "oauth2"
= { = "Authorization", = "bearer" }
= ["max_tokens", "temperature", "top_p"] # the Codex backend 400s on each; stripped pre-encode (config §4.1.1)
[]
= "https://auth.openai.com/oauth/authorize"
= "https://auth.openai.com/oauth/token"
= "app_EMoamEEZ73f0CkXaXp7hrann" # Codex's published public client (auth §10.5)
= "openid profile email offline_access api.connectors.read api.connectors.invoke"
= { = "localhost", = 1455, = "/auth/callback" } # the registered loopback redirect, byte-exact (auth §10.1)
= [["id_token_add_organizations", "true"], ["codex_cli_simplified_flow", "true"], ["originator", "codex_cli_rs"]] # auth §10.2
= "ChatGPT-Account-ID" # name is row data, value is the cred's account_id (auth §10.4)
= [["originator", "codex_cli_rs"]] # static data-plane header (auth §4)
[]
= false # the Codex backend 400s unless store:false; rides the request's passthrough valve (config §4.1)
[]
= "/models"
= [["client_version", "0.0.0"]] # /models 400s without it; the sub-release sentinel returns the FULL catalog (model-discovery §3.2)
= "models" # Codex returns {"models":[…]}, not the protocol-default {"data":[…]}
= "slug" # each entry's id is `slug`, not `id`