Openbuff is local-first software focused entirely on local/BYOK operation with no backend fallback, credits, or Openbuff subscription. You provide your own keys for user-configured providers (such as OpenAI, Anthropic/Claude, OpenRouter, or local models). Openbuff does not require hosted authentication, credits, run tracking, or hosted model inference.
There is absolutely no backend fallback. Every LLM request must resolve to either:
- an OpenAI-compatible or Anthropic-compatible provider in
openbuff.json, or - a configured ChatGPT/Codex OAuth provider for supported OpenAI models.
Legacy codebuff.json / manicode config paths and most CODEBUFF_* env-var aliases were removed in the BYOK legacy purge; openbuff.json and OPENBUFF_* are now the primary names. Retained compatibility env names are documented in Environment Variables, including CODEBUFF_API_KEY as a fallback for OPENBUFF_API_KEY. See docs/configuration.md for the full config layering and merge semantics.
openbuff # primary binary
# codebuff --local # retained only where the legacy binary alias is installedOpenbuff is always local/BYOK — there is no cloud-mode toggle.
Openbuff looks for provider config in this order (see docs/configuration.md for full layering details):
OPENBUFF_PROVIDER_CONFIG— explicit env var; when set, only this path is loaded~/.config/openbuff/provider-config.json— user-global config~/.config/openbuff/openbuff.json— user-global config (alternate name)openbuff.jsonin the current directory and each ancestor directory up to (and including) the user's home directory — project-local config
The quickest setup path is the built-in preset command:
/setup opencode-go
/setup openai
/setup anthropic
/setup codex
/setup openrouter
/setup ollama
/setup glm
/setup bedrock
/setup freemodel
Use /provider status to inspect the loaded config and missing environment variables.
Use /models to open the model routing picker.
Durable plan artifacts live under .agents/sessions/<plan>/ and are
attached to a TUI session via PlanLink. The available slash commands are:
/resume-plan— re-attach the current session to an existing plan artifact and rehydrate its working context./update-plan— open the plan artifact for an incremental edit pass./plan-status— print the current task/milestone status fromSTATUS.md./lessons— append or review lesson notes captured during the plan./plans(alias/plan-ls) — list every durable plan session found under.agents/sessions/, one row per session: active marker,[status]badge, slug,N/M doneprogress, and the current task. Only directories holding at least one known plan artifact (SPEC.md,PLAN.md,STATUS.md,LESSONS.md) are listed. It takes no arguments, runs entirely locally, and never sends a prompt to the agent./plan-use <slug>(aliases/plan-active,/use-plan) — point.agents/ACTIVE_SESSIONat a session. Accepts a bare slug or the.agents/sessions/<slug>path form; with no argument it opens the shared plan-session picker like the other plan commands. It fails closed without writing the pointer when the target resolves outside the project root, resolves outside.agents/sessions/, is a nested path under a session directory, is not a valid slug, does not exist on disk, or holds no known plan artifact. The pointer file stores the bare slug.
/plans derives the active session from the rows it scanned, so when
.agents/ACTIVE_SESSION names a slug that /plans does not list (the
directory was deleted, or it has no plan artifacts) it prints a
Stale active session: <slug> ... note pointing at /plan-use <slug>
instead of silently omitting the Active session: line.
For agent-driven updates, prefer update_plan_status for incremental
STATUS.md and lesson-note edits (it preserves user prose), and reserve
create_plan for whole-artifact creation or rewrite. See
Agents and Tools for tool details.
For guided setup/configuration inside the TUI:
/provider
/provider add
/provider status
/provider connect codex
/provider disconnect codex
/models configure
/models set mode plan codex/gpt-5.5
/models set agent code-reviewer openai/gpt-5.5
/models set editor-proposal 2 opencode-go/glm-5.1
/models set editor-selector codex/gpt-5.5
Openbuff supports OpenAI-compatible providers, Anthropic-compatible Claude
Messages API providers, and a first-class chatgpt-oauth provider for a
ChatGPT/Codex subscription:
{
"defaultModel": "openai/gpt-5.5",
"modes": {
"default": "openai/gpt-5.5",
"plan": "openai/gpt-5.5"
},
"agents": {
"base2": "openai/gpt-5.5",
"thinker": "codex/gpt-5.5"
},
"providers": {
"openai": {
"type": "openai-compatible",
"baseURL": "https://api.openai.com/v1",
"apiKeyEnv": "OPENAI_API_KEY",
"supportsStructuredOutputs": true,
"compatibility": {
"stripCacheControl": true,
"stringifyTextContent": true,
"supportsTools": true,
"supportsStopSequences": false,
"stripProviderMetadata": true
},
"models": ["gpt-5.5", "gpt-5.4-mini", "gpt-5.4-nano"]
},
"zai": {
"type": "openai-compatible",
"baseURL": "https://api.z.ai/api/paas/v4",
"apiKeyEnv": "ZAI_API_KEY",
"models": ["glm-4.6"]
},
"anthropic": {
"type": "anthropic-compatible",
"baseURL": "https://api.anthropic.com",
"apiKeyEnv": "ANTHROPIC_API_KEY",
"models": ["claude-sonnet-4-5", "claude-opus-4-5", "claude-haiku-4-5"]
},
"codex": {
"type": "chatgpt-oauth",
"models": ["gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.1-codex"]
},
"local": {
"type": "openai-compatible",
"baseURL": "http://localhost:11434/v1",
"models": ["qwen-coder"]
}
}
}Model routing is driven entirely by openbuff.json / routes.json — there is no
hardcoded per-agent model fallback. For each agent step:
modes.defaultormodes.planoverrides the built-in root agents (base,base2in default mode;base-plan,base2-planin plan mode).agents[agentId]overrides subagents and other non-mode agents when present.defaultModeloverrides every remaining agent when present.- An explicit
modelpassed by the caller is a last-resort fallback. - The resulting requested model is matched against provider
models. - If nothing is configured, Openbuff fails with a hard error:
No model configured for agent '<id>'. Run /setup or set defaultModel (or agents['<id>']) in your openbuff.json.
Failover to backup providers on auth/server errors is a separate layer on top
of routing — see the Failover routing
subsection for the failoverModels field, eligible HTTP status codes
(401/403/5xx), the no-content-yielded gate, and the preferModelParam bypass.
Agent keys may use the exact ID (thinker), a published ID
(publisher/agent@1.2.3), or the unversioned/unpublished short ID.
Model capability metadata may also contain empirical quality.coding
measurements keyed by language, task type, and agent role. These measurements
never silently override explicit routing. Use
/models recommend <language> [task-type] [agent-role] for an opt-in,
transparent recommendation; unmeasured models are excluded.
Provider models can be either a list:
{
"providers": {
"opencode-go": {
"type": "openai-compatible",
"baseURL": "https://opencode.ai/zen/go/v1",
"apiKeyEnv": "OPENCODE_GO_API_KEY",
"models": [
"glm-5.1",
"glm-5",
"kimi-k2.6",
"kimi-k2.5",
"mimo-v2.5-pro",
"mimo-v2.5",
"qwen3.6-plus",
"qwen3.5-plus",
"minimax-m2.7",
"minimax-m2.5",
"deepseek-v4-pro",
"deepseek-v4-flash"
]
}
},
"defaultModel": "opencode-go/kimi-k2.6"
}For chatgpt-oauth, run /provider connect codex before routing traffic to
the provider. Disconnect or rotate the subscription credentials with
/provider disconnect codex and connect again.
or a mapping from Openbuff-requested model to provider model:
{
"providers": {
"openai": {
"type": "openai-compatible",
"baseURL": "https://api.openai.com/v1",
"apiKeyEnv": "OPENAI_API_KEY",
"models": {
"anthropic/claude-opus-4.7": "gpt-5.5",
"anthropic/claude-sonnet-4.6": "gpt-5.5"
}
}
}
}Strict OpenAI-compatible APIs differ on which request fields they accept. Each provider can declare compatibility behavior:
{
"compatibility": {
"stripCacheControl": true,
"stringifyTextContent": true,
"supportsTools": true,
"supportsRequiredToolChoice": true,
"supportsStopSequences": false,
"stripProviderMetadata": true
}
}stripCacheControl: removes Anthropic/OpenRouter prompt-cache metadata.stringifyTextContent: sends text-only user messages as a plain string.supportsTools: setfalsefor chat-only providers that reject tool schemas.supportsRequiredToolChoice: setfalsefor providers that accept tools but rejecttool_choice: "required".supportsStopSequences: settrueonly for OpenAI-compatible providers that accept thestoprequest field; otherwise Openbuff enforces stop sequences locally.stripProviderMetadata: omits Codebuff/OpenRouter-specific provider metadata.
After configuring a provider and exporting its API key:
bun run smoke:openbuff