Command-line chat interface for multiple LLM providers, with streaming output, persistent chats, and YAML-based model aliases.
- One CLI for multiple providers through
pydantic-ai(openai,openai-responses,anthropic,google,openrouter,moonshotai, and others you add in YAML). - Fast model switching via aliases like
sonnet,gpt,gemini-pro. - Chat history with resume/continue flows and an interactive selector.
- Chat bookmarks with
/bookmarkin-chat plus bookmark/filter controls in the selector. - Optional search and thinking traces when the selected model supports them.
- Paste images with
Alt+Von vision-capable models. - User config in
~/.config/oi/merges with built-in defaults.
uv tool install git+https://github.com/dansclearov/oi.gitFor local development:
git clone https://github.com/dansclearov/oi.git
cd oi
uv install --group dev
uv run oi --helpSet one or more provider API keys (you only need keys for providers you use):
export ANTHROPIC_API_KEY=...
export OPENAI_API_KEY=...
export GEMINI_API_KEY=...
export OPENROUTER_API_KEY=...Start chatting:
oi
oi -P concise -m sonnet# Pick prompt + model
oi -P concise -m gpt
# Continue or resume chats
oi -c
oi -r
oi -r chat_20240622_143022_a1b2c3d4
# Headless: send one message and exit
oi -p "what's 2+2"
oi -c -p "follow up on the last chat"
oi --ephemeral -p "quick question, don't save it"
oi -c --ephemeral -p "probe an existing chat without dirtying it"
# In-chat local commands
/bookmark
/vim
# Slash commands complete with Tab
# Model features
oi --search -m sonnet
oi --no-thinking -m gpt
oi --hide-thinking -m gpt
# Show config/data paths
oi --user-pathsDefault models and aliases live in src/oi/models.yaml.
User overrides live in ~/.config/oi/models.yaml and are merged on top of defaults.
Example user overrides:
aliases:
default: r1
r1: openrouter/deepseek/deepseek-r1-0528
openrouter:
deepseek/deepseek-r1-0528:
supports_thinking: true
supports_search: trueNotes:
- Top-level keys starting with
_are ignored (useful for YAML anchors/metadata). extra_paramsis passed through for provider-specific model settings.- On first run,
~/.config/oi/models.yamlis auto-created from a template.
Prompts are loaded from:
~/.config/oi/prompts/(user overrides)src/oi/prompts/(built-ins)
Naming format is prompt_<name>.txt, used as oi -P <name>.
Set the default prompt for new chats in ~/.config/oi/config.json:
{
"default_prompt": "concise"
}An explicit -P still wins, for example oi -P general.
uv run pytest
uv run ty checkMIT. See LICENSE.
