with one click
add-provider
// Guide for adding a new LLM provider to OhMyCode. Use when user wants to connect a new AI model backend.
// Guide for adding a new LLM provider to OhMyCode. Use when user wants to connect a new AI model backend.
Run OhMyCode benchmarks — score any provider/model with token tracking. Use when user wants to benchmark, evaluate, test performance, or compare models.
Generate high-quality tests for OhMyCode modules. Use when user wants to create, add, or generate tests for a module or file.
Run tests and analyze results for OhMyCode. Use when user wants to run, check, or verify tests — or after any code change.
Guide for debugging OhMyCode issues. Use when user reports errors, unexpected behavior, or connection problems.
Guide for adding a new feature to OhMyCode. Use when user wants to add functionality that goes beyond existing extension points (tools/providers). Always start by reading docs/DEVELOPMENT_GUIDE.md.
Guide for adding a new tool to OhMyCode. Use when user wants to create a custom tool.
| name | add-provider |
| description | Guide for adding a new LLM provider to OhMyCode. Use when user wants to connect a new AI model backend. |
Connect a new LLM backend (e.g., Gemini, Ollama, DeepSeek, local models).
docs/DEVELOPMENT_GUIDE.mdohmycode/providers/base.py to understand Provider Protocol, register_provider()ohmycode/core/messages.py for TextChunk, ToolCallStart, TurnComplete, TokenUsageohmycode/providers/openai.py as referenceEvery provider must implement one method:
async def stream(
self,
messages: list[Message],
tools: list[ToolDef],
system: str,
model: str,
**kwargs,
) -> AsyncIterator[StreamEvent]:
It must yield these events in order:
TextChunk(text="...") — for each streamed text tokenToolCallStart(tool_name="...", tool_use_id="...", params={...}) — for each tool callTurnComplete(finish_reason="stop"|"tool_use", usage=TokenUsage(...)) — always lastCopy templates/provider_template.py to ohmycode/providers/<name>.py.
Fill in:
__init__() — initialize the API clientstream() — handle the streaming response format of the target APIDifferent APIs have different message formats. Key conversions:
UserMessage → the API's user message formatAssistantMessage (with tool_calls) → the API's assistant + tool use formatToolResultMessage → the API's tool result formatsystem parameter → some APIs put it in messages, some as a separate paramCreate tests/providers/test_<name>_provider.py:
import pytest
from ohmycode.providers.base import PROVIDER_REGISTRY
def test_provider_is_registered():
import ohmycode.providers.<name>
assert "<name>" in PROVIDER_REGISTRY
def test_provider_instantiation():
from ohmycode.providers.<name> import <ProviderClass>
provider = <ProviderClass>(api_key="test")
assert provider.name == "<name>"
Add any new config fields to ohmycode/config/config.py OhMyCodeConfig class and DEFAULT_CONFIG dict if needed (e.g., gemini_api_key).
python3 -m pytest tests/ -v # No regressions
ohmycode -p "Hello" --provider <name> --model <model> # End-to-end test
git commit -m "feat(providers): add <name> provider"
ohmycode/providers/ — auto-imported via auto_import_providers()register_provider("<name>", <Class>) at module levelstream() must be an async generator (use yield)TurnComplete as the last eventtools=[] case (no tool use)stream() during normal API errors — the loop handles retriesregister_provider() → provider not found at runtimeTurnComplete → loop hangs waiting for turn endfinish_reason wrong: use "tool_use" when model wants to call tools, "stop" when done