4.8 KiB
Summary
Add OpenRouter as a third LLM provider option alongside OpenAI and Anthropic, leveraging OpenRouter's OpenAI-compatible API to enable access to multiple model providers through a single endpoint.
What Does NOT Work
Pattern: Direct OpenRouter SDK Integration
- OpenRouter does not have a dedicated SDK
- Attempting to create a separate OpenRouter client class fails because OpenRouter is OpenAI-compatible and should reuse the OpenAI SDK
- Using a custom client breaks LangChain integration patterns
Pattern: Hardcoding Model Names
- Hardcoding specific OpenRouter model names in config files fails because OpenRouter's model catalog changes frequently
- Model names should be configurable via environment variables, not hardcoded defaults
Pattern: Separate API Key Validation
- Creating OpenRouter-specific validation logic fails because OpenRouter uses the same OpenAI SDK authentication pattern
- Validation should reuse existing OpenAI patterns with different base URL
Scenarios
Fresh Install
- User runs Spektiv for the first time
- No .env file exists
- System should:
- Create .env from .env.example with OPENROUTER_API_KEY= template
- Default to openai provider if OPENROUTER_API_KEY not set
- Show clear error message if user selects openrouter without API key
Update/Upgrade - Valid Existing Data
- User has existing .env with OPENAI_API_KEY or ANTHROPIC_API_KEY
- System should:
- Preserve existing configuration
- Add OPENROUTER_API_KEY= to .env.example (user must manually add to .env)
- Not overwrite existing llm_provider setting
- Display info message about new OpenRouter option
Update/Upgrade - User Customizations
- User has custom llm_provider, backend_url, or model settings
- System must:
- Never overwrite user's custom backend_url
- Never change user's selected llm_provider
- Only update .env.example, not .env
Implementation Approach
File 1: spektiv/default_config.py
Add OpenRouter to GENAI_PROVIDERS and genai_config section with llm_provider, backend_url, and model options.
File 2: spektiv/graph/trading_graph.py
Add elif branch for openrouter provider using ChatOpenAI with:
- base_url: https://openrouter.ai/api/v1
- api_key from OPENROUTER_API_KEY env var
- default_headers with HTTP-Referer and X-Title
File 3: .env.example
Add OPENROUTER_API_KEY template and LLM_PROVIDER, LLM_MODEL, BACKEND_URL options.
File 4: main.py
Add OpenRouter configuration example in comments.
File 5: README.md
Update LLM configuration section with all three providers (OpenAI, Anthropic, OpenRouter).
Test Scenarios
- Fresh Install - No API Keys: Error message requesting API key for selected provider
- Switch from OpenAI to OpenRouter: System uses OpenRouter, preserves OpenAI key
- Custom Backend URL: System uses custom URL instead of default OpenRouter URL
- Invalid OpenRouter Model: Clear error from OpenRouter API with docs link
- Missing API Key: Immediate error before any API calls
- Update Preserves Custom Config: .env unchanged, only .env.example updated
Acceptance Criteria
Fresh Install
- .env.example includes OPENROUTER_API_KEY= template
- .env.example includes LLM configuration examples for all three providers
- System defaults to openai if no provider specified
- Error message shown if user selects openrouter without API key
Updates
- Existing .env files are never modified
- Only .env.example is updated with new template
- Existing llm_provider setting is preserved
- Existing backend_url customizations are preserved
- README updated with OpenRouter configuration examples
Functionality
- OpenRouter works with default model
- OpenRouter works with custom LLM_MODEL setting
- OpenRouter works with custom BACKEND_URL setting
- LangChain integration uses ChatOpenAI with custom base_url
- HTTP headers include referer and title for OpenRouter tracking
Validation
- Clear error if OPENROUTER_API_KEY missing
- Clear error if invalid llm_provider specified
- Error messages include documentation links
- Config validation happens before first API call
Security
- API keys never logged or printed
- API keys only read from environment variables
- No hardcoded API keys in any file
- .env file remains in .gitignore
Documentation
- README shows all three provider configurations
- README links to OpenRouter model catalog
- README explains model name format (provider/model-name)
- Comments in code explain OpenRouter OpenAI-compatibility
Environment Requirements
- Python 3.8+
- LangChain 0.1.0+
- OpenAI SDK (already required for OpenAI provider)
Source of Truth
- OpenRouter API documentation: https://openrouter.ai/docs
- Proven implementation pattern from anyclaude
- Verified: 2024-12-25