130 lines
4.8 KiB
Markdown
130 lines
4.8 KiB
Markdown
## 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
|
|
|
|
1. **Fresh Install - No API Keys**: Error message requesting API key for selected provider
|
|
2. **Switch from OpenAI to OpenRouter**: System uses OpenRouter, preserves OpenAI key
|
|
3. **Custom Backend URL**: System uses custom URL instead of default OpenRouter URL
|
|
4. **Invalid OpenRouter Model**: Clear error from OpenRouter API with docs link
|
|
5. **Missing API Key**: Immediate error before any API calls
|
|
6. **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
|