|
|
@@ -0,0 +1,125 @@
|
|
|
+# Model Selector
|
|
|
+
|
|
|
+A FastAPI dashboard for browsing and editing the model/provider configuration in `~/.openclaw/openclaw.json`.
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+## Features
|
|
|
+
|
|
|
+- **Live provider discovery** — Pull available models from OpenAI, Groq, and OpenRouter APIs
|
|
|
+- **Smart caching** — Provider snapshots saved locally to `.cache/` for offline browsing
|
|
|
+- **Alias management** — Give your models friendly names (e.g., `gpt-4o` → "osiris")
|
|
|
+- **Config sync** — All changes written atomically to your central `openclaw.json`
|
|
|
+- **Auto-refresh** — Periodic provider updates (default: every 30 minutes)
|
|
|
+- **Zero-build UI** — Single-page vanilla JS, no frontend build step
|
|
|
+
|
|
|
+## Quick Start
|
|
|
+
|
|
|
+```bash
|
|
|
+# Copy env template and add your API keys
|
|
|
+cp .env.example .env
|
|
|
+# Edit .env with your OPENAI_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY
|
|
|
+
|
|
|
+# Start the server (defaults to port 3300)
|
|
|
+./run.sh
|
|
|
+
|
|
|
+# Or with custom port
|
|
|
+MODEL_SELECTOR_PORT=8080 ./run.sh
|
|
|
+```
|
|
|
+
|
|
|
+Open <http://localhost:3300> in your browser.
|
|
|
+
|
|
|
+## Configuration
|
|
|
+
|
|
|
+### Environment Variables
|
|
|
+
|
|
|
+| Variable | Default | Description |
|
|
|
+|----------|---------|-------------|
|
|
|
+| `OPENAI_API_KEY` | — | OpenAI API token |
|
|
|
+| `GROQ_API_KEY` | — | Groq API token |
|
|
|
+| `OPENROUTER_API_KEY` | — | OpenRouter API token |
|
|
|
+| `OPENCLAW_CONFIG_PATH` | `~/.openclaw/openclaw.json` | Path to your OpenClaw config |
|
|
|
+| `MODEL_SELECTOR_PORT` | `3300` | Dashboard server port |
|
|
|
+| `MODEL_SELECTOR_REFRESH_INTERVAL` | `1800` | Provider refresh interval (seconds) |
|
|
|
+| `MODEL_SELECTOR_CACHE_DIR` | `data/model-cache` | Cache directory for provider snapshots |
|
|
|
+
|
|
|
+### Canonical Config Path
|
|
|
+
|
|
|
+The dashboard reads from `/home/lucky/.openclaw/openclaw.json` by default. This file uses the OpenClaw schema:
|
|
|
+
|
|
|
+```json
|
|
|
+{
|
|
|
+ "models": {
|
|
|
+ "providers": {
|
|
|
+ "openai": {
|
|
|
+ "models": [
|
|
|
+ {"id": "gpt-4o", "name": "GPT-4o", "reasoning": false, "input": ["text"], "contextWindow": 128000, "maxTokens": 16000}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "agents": {
|
|
|
+ "defaults": {
|
|
|
+ "models": {
|
|
|
+ "openai/gpt-4o": {"alias": "my-favorite"}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## API Endpoints
|
|
|
+
|
|
|
+| Endpoint | Method | Description |
|
|
|
+|----------|--------|-------------|
|
|
|
+| `/` | GET | Dashboard UI |
|
|
|
+| `/api/state` | GET | Full dashboard state (configured + providers) |
|
|
|
+| `/api/config` | GET | Config path and configured models |
|
|
|
+| `/api/alias` | POST | Update model alias (`{full_key, alias}`) |
|
|
|
+| `/api/config/models/add` | POST | Add model to config (`{provider_key, model_id}`) |
|
|
|
+| `/api/config/models/delete` | POST | Remove model from config (`{full_key}`) |
|
|
|
+| `/api/refresh` | POST | Force provider refresh |
|
|
|
+
|
|
|
+## Development
|
|
|
+
|
|
|
+### Running Tests
|
|
|
+
|
|
|
+```bash
|
|
|
+# Uses temp config fixtures; never touches the live file
|
|
|
+python -m pytest tests/ -v
|
|
|
+```
|
|
|
+
|
|
|
+### Project Structure
|
|
|
+
|
|
|
+```
|
|
|
+.
|
|
|
+├── model_selector/
|
|
|
+│ ├── main.py # FastAPI app, routes
|
|
|
+│ ├── config.py # OpenClawConfigRepository
|
|
|
+│ ├── providers.py # ProviderAdapter, feature detection
|
|
|
+│ ├── service.py # ModelDashboardService
|
|
|
+│ ├── cache.py # SnapshotCache
|
|
|
+│ ├── settings.py # AppSettings from env
|
|
|
+│ └── ui.py # Jinja2-style HTML rendering
|
|
|
+├── data/model-cache/ # Provider snapshots (gitignored)
|
|
|
+├── tests/
|
|
|
+├── run.sh # Start server
|
|
|
+├── restart.sh # Kill + start
|
|
|
+└── killserver.sh # Clear port 3300
|
|
|
+```
|
|
|
+
|
|
|
+## Provider Support
|
|
|
+
|
|
|
+| Provider | Key | Features |
|
|
|
+|----------|-----|----------|
|
|
|
+| OpenAI | `openai` | reasoning, context_window, max_tokens |
|
|
|
+| Groq | `groq-cloud` | reasoning, context_window, active status |
|
|
|
+| OpenRouter | `openrouter` | pricing (prompt/completion/request), full metadata |
|
|
|
+
|
|
|
+Missing capabilities display as "—" rather than being invented.
|
|
|
+
|
|
|
+## License
|
|
|
+
|
|
|
+MIT
|