## ✨ Features - 🔀 **Multi-Channel Aggregation** - Connect multiple LLM provider channels with unified management - 🔄 **Protocol Conversion** - Seamless conversion between OpenAI Chat / OpenAI Responses / Anthropic API formats - 💰 **Price Sync** - Automatic model pricing updates - 🔃 **Model Sync** - Automatic synchronization of available model lists with channels - 📊 **Analytics** - Comprehensive request statistics, token consumption, and cost tracking - 🎨 **Elegant UI** - Clean and beautiful web management panel - 🗄️ **Multi-Database Support** - Support for SQLite, MySQL, PostgreSQL ## 🚀 Quick Start ### 🐳 Docker Run directly: ```bash docker run -d --name octopus -v /path/to/data:/app/data -p 8080:8080 bestrui/octopus ``` Or use docker compose: ```bash wget https://raw.githubusercontent.com/bestruirui/octopus/refs/heads/master/docker-compose.yml docker compose up -d ``` ### 📦 Download from Release Download the binary for your platform from [Releases](https://github.com/bestruirui/octopus/releases), then run: ```bash ./octopus start ``` ### 🛠️ Build from Source **Requirements:** - Go 1.24.4 - Node.js 18+ - pnpm ```bash # Clone the repository git clone https://github.com/bestruirui/octopus.git cd octopus # Build frontend cd web && pnpm install && pnpm run build && cd .. # Move frontend assets to static directory mv web/out static/ # Start the backend service go run main.go start ``` > 💡 **Tip**: The frontend build artifacts are embedded into the Go binary, so you must build the frontend before starting the backend. **Development Mode** ```bash cd web && pnpm install && NEXT_PUBLIC_API_BASE_URL="http://127.0.0.1:8080" pnpm run dev ## Open a new terminal, start the backend service go run main.go start ## Access the frontend at http://localhost:3000 ``` ### 🔐 Default Credentials After first launch, visit http://localhost:8080 and log in to the management panel with: - **Username**: `admin` - **Password**: `admin` > ⚠️ **Security Notice**: Please change the default password immediately after first login. ### 📝 Configuration File The configuration file is located at `data/config.json` by default and is automatically generated on first startup. **Complete Configuration Example:** ```json { "server": { "host": "0.0.0.0", "port": 8080 }, "database": { "type": "sqlite", "path": "data/data.db" }, "log": { "level": "info" } } ``` **Configuration Options:** | Option | Description | Default | |--------|-------------|---------| | `server.host` | Listen address | `0.0.0.0` | | `server.port` | Server port | `8080` | | `database.type` | Database type | `sqlite` | | `database.path` | Database connection string | `data/data.db` | | `log.level` | Log level | `info` | **Database Configuration:** Three database types are supported: | Type | `database.type` | `database.path` Format | |------|-----------------|-----------------------| | SQLite | `sqlite` | `data/data.db` | | MySQL | `mysql` | `user:password@tcp(host:port)/dbname` | | PostgreSQL | `postgres` | `postgresql://user:password@host:port/dbname?sslmode=disable` | **MySQL Configuration Example:** ```json { "database": { "type": "mysql", "path": "root:password@tcp(127.0.0.1:3306)/octopus" } } ``` **PostgreSQL Configuration Example:** ```json { "database": { "type": "postgres", "path": "postgresql://user:password@localhost:5432/octopus?sslmode=disable" } } ``` > 💡 **Tip**: MySQL and PostgreSQL require manual database creation. The application will automatically create the table structure. ### 🌐 Environment Variables All configuration options can be overridden via environment variables using the format `OCTOPUS_` + configuration path (joined with `_`): | Environment Variable | Configuration Option | |---------------------|---------------------| | `OCTOPUS_SERVER_PORT` | `server.port` | | `OCTOPUS_SERVER_HOST` | `server.host` | | `OCTOPUS_DATABASE_TYPE` | `database.type` | | `OCTOPUS_DATABASE_PATH` | `database.path` | | `OCTOPUS_LOG_LEVEL` | `log.level` | | `OCTOPUS_GITHUB_PAT` | For rate limiting when getting the latest version (optional) | ## 📸 Screenshots ### 🖥️ Desktop ### 📱 Mobile ## 📖 Documentation ### 📡 Channel Management Channels are the basic configuration units for connecting to LLM providers. **Base URL Guide:** The program automatically appends API paths based on channel type. You only need to provide the base URL: | Channel Type | Auto-appended Path | Base URL | Full Request URL Example | |--------------|-------------------|----------|--------------------------| | OpenAI Chat | `/chat/completions` | `https://api.openai.com/v1` | `https://api.openai.com/v1/chat/completions` | | OpenAI Responses | `/responses` | `https://api.openai.com/v1` | `https://api.openai.com/v1/responses` | | Anthropic | `/messages` | `https://api.anthropic.com/v1` | `https://api.anthropic.com/v1/messages` | | Gemini | `/models/:model:generateContent` | `https://generativelanguage.googleapis.com/v1beta` | `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent` | > 💡 **Tip**: No need to include specific API endpoint paths in the Base URL - the program handles this automatically. --- ### 📁 Group Management Groups aggregate multiple channels into a unified external model name. **Core Concepts:** - **Group name** is the model name exposed by the program - When calling the API, set the `model` parameter to the group name > 💡 **Example**: Create a group named `gpt-4o`, add multiple providers' GPT-4o channels to it, then access all channels via a unified `model: gpt-4o`. --- ### 💰 Price Management Manage model pricing information in the system. **Data Sources:** - The system periodically syncs model pricing data from [models.dev](https://github.com/sst/models.dev) - When creating a channel, if the channel contains models not in models.dev, the system automatically creates pricing information for those models on this page, so this page displays models that haven't had their prices fetched from upstream, allowing users to set prices manually - Manual creation of models that exist in models.dev is also supported for custom pricing **Price Priority:** | Priority | Source | Description | |:--------:|--------|-------------| | 🥇 High | This Page | Prices set by user in price management page | | 🥈 Low | models.dev | Auto-synced default prices | > 💡 **Tip**: To override a model's default price, simply set a custom price for it in the price management page. --- ### ⚙️ Settings Global system configuration. **Statistics Save Interval (minutes):** Since the program handles numerous statistics, writing to the database on every request would impact read/write performance. The program uses this strategy: - Statistics are first stored in **memory** - Periodically **batch-written** to the database at the configured interval > ⚠️ **Important**: When exiting the program, use proper shutdown methods (like `Ctrl+C` or sending `SIGTERM` signal) to ensure in-memory statistics are correctly written to the database. **Do NOT use `kill -9` or other forced termination methods**, as this may result in statistics data loss. --- ## 🔌 Client Integration ### OpenAI SDK ```python from openai import OpenAI import os client = OpenAI( base_url="http://127.0.0.1:8080/v1", api_key="sk-octopus-P48ROljwJmWBYVARjwQM8Nkiezlg7WOrXXOWDYY8TI5p9Mzg", ) completion = client.chat.completions.create( model="octopus-openai", # Use the correct group name messages = [ {"role": "user", "content": "Hello"}, ], ) print(completion.choices[0].message.content) ``` ### Claude Code Edit `~/.claude/settings.json` ```json { "env": { "ANTHROPIC_BASE_URL": "http://127.0.0.1:8080", "ANTHROPIC_AUTH_TOKEN": "sk-octopus-P48ROljwJmWBYVARjwQM8Nkiezlg7WOrXXOWDYY8TI5p9Mzg", "API_TIMEOUT_MS": "3000000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1", "ANTHROPIC_MODEL": "octopus-sonnet-4-5", "ANTHROPIC_SMALL_FAST_MODEL": "octopus-haiku-4-5", "ANTHROPIC_DEFAULT_SONNET_MODEL": "octopus-sonnet-4-5", "ANTHROPIC_DEFAULT_OPUS_MODEL": "octopus-sonnet-4-5", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "octopus-haiku-4-5" } } ``` ### Codex Edit `~/.codex/config.toml` ```toml model = "gpt-5.6-sol" model_reasoning_effort = "xhigh" model_provider = "octopus" preferred_auth_method = "apikey" [model_providers.octopus] base_url = "http://127.0.0.1:8080/v1" name = "octopus" supports_websockets = false requires_openai_auth = true wire_api = "responses" experimental_bearer_token = "sk-octopus-" ``` Edit `~/.codex/auth.json` ```json { "OPENAI_API_KEY": "" } ``` --- ## 🤝 Acknowledgments - 🙏 [looplj/axonhub](https://github.com/looplj/axonhub) - The LLM API adaptation module in this project is directly derived from this repository - 📊 [sst/models.dev](https://github.com/sst/models.dev) - AI model database providing model pricing data - 🇨🇳 [AtomGit](https://atomgit.com/bestruirui/octopus) - China-based code hosting - 💬 [Linux.do](https://linux.do/)