Files

1 line
61 KiB
JSON

{"repo": "anthaathi/anthropic-proxy", "files": {"example.config.yaml": {"72a5e5482844bc64ca62ce9da7b6e835282a0c2e": {"t": 1785746847.0459852, "n": 14974, "h": "e337c35ee943440c", "c": "spec:\n # Provider configurations\n # Each provider needs a type, endpoint, and API key\n providers:\n # === ANTHROPIC PROVIDERS ===\n # Providers using Anthropic API format (/v1/messages)\n\n # Anthropic official API\n anthropic:\n type: anthropic # Optional: defaults to \"anthropic\" if not specified\n endpoint: https://api.anthropic.com\n apiKey: env.ANTHROPIC_API_KEY\n\n # OpenRouter - Multi-model API gateway (Anthropic format)\n openrouter:\n type: anthropic\n endpoint: https://openrouter.ai/api/v1\n apiKey: env.OPENROUTER_API_KEY\n\n # Chutes AI - Claude proxy\n chutes:\n type: anthropic\n endpoint: https://claude.chutes.ai\n apiKey: env.CHUTES_API_KEY\n\n # Z.ai - AI API provider\n zai:\n type: anthropic\n endpoint: https://api.z.ai/api/anthropic\n apiKey: env.ZAI_API_KEY\n\n # DeepSeek - Chinese AI provider with Anthropic-compatible API\n deepseek:\n type: anthropic\n endpoint: https://api.deepseek.com/anthropic\n apiKey: env.DEEPSEEK_API_KEY\n\n # Together AI - Model hosting platform\n together:\n type: anthropic\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Custom self-hosted endpoint\n selfhosted:\n type: anthropic\n endpoint: http://localhost:11434/v1\n apiKey: \"not-needed\" # For local servers that don't require auth\n\n # AWS Bedrock proxy (example)\n bedrock:\n type: anthropic\n endpoint: https://bedrock-runtime.us-east-1.amazonaws.com\n apiKey: env.AWS_ACCESS_KEY\n\n # === OPENAI PROVIDERS ===\n # Providers using OpenAI API format (/v1/chat/completions)\n # The proxy will automatically convert between Anthropic and OpenAI formats\n\n # OpenAI official API\n openai:\n type: openai\n endpoint: https://api.openai.com\n apiKey: env.OPENAI_API_KEY\n\n # Azure OpenAI\n azure_openai:\n type: openai\n endpoint: https://your-resource-name.openai.azure.com\n apiKey: env.AZURE_OPENAI_API_KEY\n\n # OpenRouter with OpenAI format\n openrouter_openai:\n type: openai\n endpoint: https://openrouter.ai/api\n apiKey: env.OPENROUTER_API_KEY\n\n # Together AI with OpenAI format\n together_openai:\n type: openai\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Groq - Ultra-fast inference\n groq:\n type: openai\n endpoint: https://api.groq.com/openai\n apiKey: env.GROQ_API_KEY\n\n # Perplexity AI\n perplexity:\n type: openai\n endpoint: https://api.perplexity.ai\n apiKey: env.PERPLEXITY_API_KEY\n\n # Retry configuration (optional)\n # Controls backoff parameters when same-provider retries are enabled\n retry:\n retrySameProvider: false # false = failover immediately; true = retry the same provider before failing over\n maxRetries: 3 # Number of same-provider retries when retrySameProvider is true\n initialDelay: 100ms # Initial delay before first retry\n maxDelay: 5s # Maximum delay between retries\n backoffMultiplier: 2.0 # Exponential backoff multiplier\n\n # Model configurations\n # Each model maps to a provider and can have an alias\n models:\n # === CLAUDE MODELS (via Anthropic providers) ===\n\n # Claude Opus models\n - name: \"claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: anthropic\n weight: 5\n\n - name: \"anthropic/claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: openrouter\n weight: 4\n\n # Claude Sonnet models\n - name: \"claude-sonnet-4-5-20250929\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: anthropic\n weight: 5\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: chutes\n weight: 3\n\n - name: \"glm-4.6\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: zai\n weight: 3\n\n - name: \"deepseek-chat\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: deepseek\n weight: 2\n\n # Claude Haiku models (fast, lightweight)\n - name: \"claude-haiku-3-5-20250110\"\n context: 200000\n alias: \"claude-haiku*\"\n provider: anthropic\n weight: 5\n\n - name: \"GLM-4.5-Air\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: zai\n weight: 3\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: chutes\n weight: 2\n\n # Exact model name match (no wildcard)\n - name: \"claude-3-opus-20240229\"\n context: 200000\n alias: \"claude-3-opus-20240229\"\n provider: anthropic\n weight: 5\n\n # === OPENAI MODELS (via OpenAI providers) ===\n # Note: Clients still use Anthropic format, proxy converts automatically\n\n # GPT-4 models\n - name: \"gpt-4o\"\n context: 128000\n alias: \"gpt-4o*\"\n provider: openai\n weight: 5\n\n - name: \"gpt-4-turbo\"\n context: 128000\n alias: \"gpt-4-turbo*\"\n provider: openai\n weight: 4\n\n # GPT-3.5 models\n - name: \"gpt-3.5-turbo\"\n context: 16385\n alias: \"gpt-3.5*\"\n provider: openai\n weight: 3\n\n # Groq models (ultra-fast)\n - name: \"llama-3.3-70b-versatile\"\n context: 8192\n alias: \"llama-3.3*\"\n provider: groq\n weight: 5\n\n - name: \"mixtral-8x7b-32768\"\n context: 32768\n alias: \"mixtral*\"\n provider: groq\n weight: 4\n\n # API keys for authenticating incoming requests\n # These are the keys clients will use to access your proxy\n # DEPRECATED: Use auth.staticKeys instead for better organization\n apiKeys:\n - \"$RANDOM_KEY\" # Will auto-generate a random key on startup\n - \"env.PROXY_API_KEY\" # Read from PROXY_API_KEY environment variable\n - \"sk-proxy-example-key-123\" # Static API key example\n\n # Authentication configuration (NEW)\n # Supports both static keys and OpenID Connect with database-backed token management\n auth:\n # Static API keys (backward compatible, optional)\n # If you have keys in 'apiKeys' above, they will still work\n staticKeys:\n - \"sk-static-key-example\"\n - \"env.STATIC_API_KEY\"\n\n # Database configuration\n database:\n driver: sqlite # \"sqlite\" or \"postgres\"\n dsn: ./data/auth.db # SQLite: file path, PostgreSQL: connection string\n maxConns: 10 # Maximum number of database connections\n\n # PostgreSQL example:\n # driver: postgres\n # dsn: \"host=localhost port=5432 user=proxy password=secret dbname=proxy_auth sslmode=disable\"\n # maxConns: 20\n\n # OpenID Connect configuration\n openid:\n enabled: true # Set to false to disable OAuth, use static keys only\n provider: google # \"google\", \"auth0\", \"keycloak\", or \"custom\"\n\n # Option 1: Auto-discovery (recommended)\n # The proxy will automatically fetch configuration from the provider's .well-known/openid-configuration endpoint\n issuer: https://accounts.google.com\n\n # Option 2: Manual configuration (uncomment if your provider doesn't support auto-discovery)\n # authEndpoint: https://your-provider.com/oauth2/authorize\n # tokenEndpoint: https://your-provider.com/oauth2/token\n # userinfoEndpoint: https://your-provider.com/oauth2/userinfo\n # jwksUrl: https://your-provider.com/.well-known/jwks.json\n\n # OAuth2 credentials (get these from your OpenID provider)\n clientId: env.OIDC_CLIENT_ID # Your OAuth2 client ID\n clientSecret: env.OIDC_CLIENT_SECRET # Your OAuth2 client secret\n redirectUrl: http://localhost:8080/auth/callback # Must match your provider's allowed redirect URLs\n\n # Scopes to request (optional, defaults to: openid, email, profile)\n scopes:\n - openid\n - email\n - profile\n\n # Admin UI configuration\n adminUI:\n enabled: true # Enable/disable the admin web interface\n path: /admin # URL path for admin UI (e.g., http://localhost:8080/admin)\n sessionSecret: env.SESSION_SECRET # Secret key for session encryption (generate with: openssl rand -base64 32)\n sessionMaxAge: 86400 # Session duration in seconds (86400 = 24 hours)\n baseUrl: http://localhost:8080 # Base URL for the proxy (used in config display)\n\n # Analytics configuration\n dataRetentionDays: 30 # How many days to keep detailed request logs (default: 30)\n # Older logs are aggregated into monthly summaries and deleted\n\n# Configuration notes:\n#\n# Environment Variables:\n# - Use \"env.VAR_NAME\" to read from environment variable\n# - Use \"$RANDOM_KEY\" to auto-generate a secure random key\n# - Or use static values directly\n#\n# Provider Types:\n# - \"anthropic\": Provider uses Anthropic API format (/v1/messages)\n# - \"openai\": Provider uses OpenAI API format (/v1/chat/completions)\n# - Defaults to \"anthropic\" if not specified\n# - The proxy automatically converts between formats\n#\n# Model Aliases:\n# - Use \"*\" for wildcard matching\n# - \"opus*\" matches any model name starting with \"opus\"\n# - \"*opus\" matches any model name ending with \"opus\"\n# - \"opus\" matches exactly \"opus\" (no wildcard)\n#\n# Provider Endpoints:\n# - Must be valid HTTP/HTTPS URLs\n# - For Anthropic providers: point to endpoints with /v1/messages support\n# - For OpenAI providers: point to endpoints with /v1/chat/completions support\n# - Can be self-hosted or third-party services\n#\n# Retry Configuration:\n# - By default, the proxy fails over to the next provider immediately.\n# - Set retrySameProvider: true to retry the same provider using the settings above.\n# - Retries apply to network errors, rate limits (429), and server errors (5xx).\n# - Client errors (4xx except 429) are NOT retried.\n#\n# Routing Logic:\n# 1. Models with TPS < 40 are excluded\n# 2. Models are sorted by weight (higher first)\n# 3. If weights are equal, higher TPS wins\n# 4. On failure, immediately tries the next provider (unless same-provider retries are enabled)\n# 5. Continues until a provider succeeds or all providers fail\n#\n# Running the proxy:\n# 1. Set environment variables:\n# # Anthropic providers\n# export ANTHROPIC_API_KEY=your-anthropic-key\n# export OPENROUTER_API_KEY=your-openrouter-key\n# export CHUTES_API_KEY=your-chutes-key\n# export ZAI_API_KEY=your-zai-key\n# export DEEPSEEK_API_KEY=your-deepseek-key\n# export TOGETHER_API_KEY=your-together-key\n#\n# # OpenAI providers\n# export OPENAI_API_KEY=your-openai-key\n# export AZURE_OPENAI_API_KEY=your-azure-key\n# export GROQ_API_KEY=your-groq-key\n# export PERPLEXITY_API_KEY=your-perplexity-key\n#\n# # Proxy configuration\n# export PROXY_API_KEY=your-proxy-key\n# export PORT=8080\n# export LOG_LEVEL=INFO # Options: DEBUG, INFO, WARN, ERROR (default: INFO)\n#\n# 2. Start the server:\n# go run main.go\n#\n# 3. Use the proxy:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-sonnet-4-5-20250929\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Hello, how are you?\"}],\n# \"max_tokens\": 1024\n# }'\n#\n# Example with alias matching:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-opus-latest\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Explain quantum computing\"}],\n# \"max_tokens\": 2048\n# }'\n#\n# Tips:\n# - Use weights to prioritize certain providers or models\n# - Higher weight = higher priority in routing decisions\n# - Models with weight 0 or negative are treated as weight 1\n# - Use wildcard aliases for flexible model routing\n# - Monitor TPS (tokens per second) for performance-based routing\n#\n# Authentication Setup:\n# 1. Generate a session secret:\n# export SESSION_SECRET=$(openssl rand -base64 32)\n#\n# 2. Set up OpenID provider (example: Google)\n# - Go to https://console.cloud.google.com/apis/credentials\n# - Create OAuth 2.0 Client ID\n# - Add authorized redirect URI: http://localhost:8080/auth/callback\n# - Copy Client ID and Client Secret\n# export OIDC_CLIENT_ID=your-client-id\n# export OIDC_CLIENT_SECRET=your-client-secret\n#\n# 3. Start the server with auth enabled:\n# go run main.go --tui\n#\n# 4. Access the admin UI:\n# - Open http://localhost:8080/admin\n# - Click \"Sign in with OpenID\"\n# - Authenticate with your provider\n# - Create API tokens for your applications\n#\n# 5. Use generated tokens:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-xxx-yyy\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\"model\": \"claude-sonnet-4-5-20250929\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}], \"max_tokens\": 1024}'\n#\n# Token Management:\n# - Tokens are stored securely in the database (hashed with bcrypt)\n# - Each user can generate multiple tokens with custom names\n# - Tokens can be revoked at any time through the admin UI\n# - Optional expiration dates for tokens (90 days recommended)\n# - Track token usage (last used timestamp)\n#\n# Supported OpenID Providers:\n# - Google: issuer: https://accounts.google.com\n# - Auth0: issuer: https://your-tenant.auth0.com/\n# - Keycloak: issuer: https://your-keycloak.com/realms/your-realm\n# - Okta: issuer: https://your-domain.okta.com\n# - Custom: Use manual endpoint configuration\n#\n# Database Options:\n# - SQLite (default): Great for single-server deployments, no setup required\n# - PostgreSQL: Recommended for production, supports multiple instances\n#\n# Backward Compatibility:\n# - Old 'apiKeys' configuration still works without auth section\n# - Static keys can coexist with database tokens\n# - No breaking changes to existing deployments\n#\n# Admin Features:\n# - First user to authenticate becomes admin automatically\n# - Admins can:\n# * View all users and their usage statistics\n# * Promote other users to admin\n# * View system-wide analytics\n# * Access detailed request logs for all users\n# - Regular users can:\n# * View their own analytics and usage\n# * Create and manage their own API tokens\n# * Access configuration instructions\n#\n# Analytics:\n# - Detailed request logs are kept for the configured retention period\n# - Old logs are automatically aggregated into monthly summaries\n# - Track: tokens used, requests made, models used, providers, timestamps\n# - Per-user and system-wide analytics available\n"}, "4175f401e71bd4de2f7a27cf28f9d670f7862697": {"t": 1785768029.0890338, "n": 14974, "h": "e337c35ee943440c", "c": "spec:\n # Provider configurations\n # Each provider needs a type, endpoint, and API key\n providers:\n # === ANTHROPIC PROVIDERS ===\n # Providers using Anthropic API format (/v1/messages)\n\n # Anthropic official API\n anthropic:\n type: anthropic # Optional: defaults to \"anthropic\" if not specified\n endpoint: https://api.anthropic.com\n apiKey: env.ANTHROPIC_API_KEY\n\n # OpenRouter - Multi-model API gateway (Anthropic format)\n openrouter:\n type: anthropic\n endpoint: https://openrouter.ai/api/v1\n apiKey: env.OPENROUTER_API_KEY\n\n # Chutes AI - Claude proxy\n chutes:\n type: anthropic\n endpoint: https://claude.chutes.ai\n apiKey: env.CHUTES_API_KEY\n\n # Z.ai - AI API provider\n zai:\n type: anthropic\n endpoint: https://api.z.ai/api/anthropic\n apiKey: env.ZAI_API_KEY\n\n # DeepSeek - Chinese AI provider with Anthropic-compatible API\n deepseek:\n type: anthropic\n endpoint: https://api.deepseek.com/anthropic\n apiKey: env.DEEPSEEK_API_KEY\n\n # Together AI - Model hosting platform\n together:\n type: anthropic\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Custom self-hosted endpoint\n selfhosted:\n type: anthropic\n endpoint: http://localhost:11434/v1\n apiKey: \"not-needed\" # For local servers that don't require auth\n\n # AWS Bedrock proxy (example)\n bedrock:\n type: anthropic\n endpoint: https://bedrock-runtime.us-east-1.amazonaws.com\n apiKey: env.AWS_ACCESS_KEY\n\n # === OPENAI PROVIDERS ===\n # Providers using OpenAI API format (/v1/chat/completions)\n # The proxy will automatically convert between Anthropic and OpenAI formats\n\n # OpenAI official API\n openai:\n type: openai\n endpoint: https://api.openai.com\n apiKey: env.OPENAI_API_KEY\n\n # Azure OpenAI\n azure_openai:\n type: openai\n endpoint: https://your-resource-name.openai.azure.com\n apiKey: env.AZURE_OPENAI_API_KEY\n\n # OpenRouter with OpenAI format\n openrouter_openai:\n type: openai\n endpoint: https://openrouter.ai/api\n apiKey: env.OPENROUTER_API_KEY\n\n # Together AI with OpenAI format\n together_openai:\n type: openai\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Groq - Ultra-fast inference\n groq:\n type: openai\n endpoint: https://api.groq.com/openai\n apiKey: env.GROQ_API_KEY\n\n # Perplexity AI\n perplexity:\n type: openai\n endpoint: https://api.perplexity.ai\n apiKey: env.PERPLEXITY_API_KEY\n\n # Retry configuration (optional)\n # Controls backoff parameters when same-provider retries are enabled\n retry:\n retrySameProvider: false # false = failover immediately; true = retry the same provider before failing over\n maxRetries: 3 # Number of same-provider retries when retrySameProvider is true\n initialDelay: 100ms # Initial delay before first retry\n maxDelay: 5s # Maximum delay between retries\n backoffMultiplier: 2.0 # Exponential backoff multiplier\n\n # Model configurations\n # Each model maps to a provider and can have an alias\n models:\n # === CLAUDE MODELS (via Anthropic providers) ===\n\n # Claude Opus models\n - name: \"claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: anthropic\n weight: 5\n\n - name: \"anthropic/claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: openrouter\n weight: 4\n\n # Claude Sonnet models\n - name: \"claude-sonnet-4-5-20250929\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: anthropic\n weight: 5\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: chutes\n weight: 3\n\n - name: \"glm-4.6\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: zai\n weight: 3\n\n - name: \"deepseek-chat\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: deepseek\n weight: 2\n\n # Claude Haiku models (fast, lightweight)\n - name: \"claude-haiku-3-5-20250110\"\n context: 200000\n alias: \"claude-haiku*\"\n provider: anthropic\n weight: 5\n\n - name: \"GLM-4.5-Air\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: zai\n weight: 3\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: chutes\n weight: 2\n\n # Exact model name match (no wildcard)\n - name: \"claude-3-opus-20240229\"\n context: 200000\n alias: \"claude-3-opus-20240229\"\n provider: anthropic\n weight: 5\n\n # === OPENAI MODELS (via OpenAI providers) ===\n # Note: Clients still use Anthropic format, proxy converts automatically\n\n # GPT-4 models\n - name: \"gpt-4o\"\n context: 128000\n alias: \"gpt-4o*\"\n provider: openai\n weight: 5\n\n - name: \"gpt-4-turbo\"\n context: 128000\n alias: \"gpt-4-turbo*\"\n provider: openai\n weight: 4\n\n # GPT-3.5 models\n - name: \"gpt-3.5-turbo\"\n context: 16385\n alias: \"gpt-3.5*\"\n provider: openai\n weight: 3\n\n # Groq models (ultra-fast)\n - name: \"llama-3.3-70b-versatile\"\n context: 8192\n alias: \"llama-3.3*\"\n provider: groq\n weight: 5\n\n - name: \"mixtral-8x7b-32768\"\n context: 32768\n alias: \"mixtral*\"\n provider: groq\n weight: 4\n\n # API keys for authenticating incoming requests\n # These are the keys clients will use to access your proxy\n # DEPRECATED: Use auth.staticKeys instead for better organization\n apiKeys:\n - \"$RANDOM_KEY\" # Will auto-generate a random key on startup\n - \"env.PROXY_API_KEY\" # Read from PROXY_API_KEY environment variable\n - \"sk-proxy-example-key-123\" # Static API key example\n\n # Authentication configuration (NEW)\n # Supports both static keys and OpenID Connect with database-backed token management\n auth:\n # Static API keys (backward compatible, optional)\n # If you have keys in 'apiKeys' above, they will still work\n staticKeys:\n - \"sk-static-key-example\"\n - \"env.STATIC_API_KEY\"\n\n # Database configuration\n database:\n driver: sqlite # \"sqlite\" or \"postgres\"\n dsn: ./data/auth.db # SQLite: file path, PostgreSQL: connection string\n maxConns: 10 # Maximum number of database connections\n\n # PostgreSQL example:\n # driver: postgres\n # dsn: \"host=localhost port=5432 user=proxy password=secret dbname=proxy_auth sslmode=disable\"\n # maxConns: 20\n\n # OpenID Connect configuration\n openid:\n enabled: true # Set to false to disable OAuth, use static keys only\n provider: google # \"google\", \"auth0\", \"keycloak\", or \"custom\"\n\n # Option 1: Auto-discovery (recommended)\n # The proxy will automatically fetch configuration from the provider's .well-known/openid-configuration endpoint\n issuer: https://accounts.google.com\n\n # Option 2: Manual configuration (uncomment if your provider doesn't support auto-discovery)\n # authEndpoint: https://your-provider.com/oauth2/authorize\n # tokenEndpoint: https://your-provider.com/oauth2/token\n # userinfoEndpoint: https://your-provider.com/oauth2/userinfo\n # jwksUrl: https://your-provider.com/.well-known/jwks.json\n\n # OAuth2 credentials (get these from your OpenID provider)\n clientId: env.OIDC_CLIENT_ID # Your OAuth2 client ID\n clientSecret: env.OIDC_CLIENT_SECRET # Your OAuth2 client secret\n redirectUrl: http://localhost:8080/auth/callback # Must match your provider's allowed redirect URLs\n\n # Scopes to request (optional, defaults to: openid, email, profile)\n scopes:\n - openid\n - email\n - profile\n\n # Admin UI configuration\n adminUI:\n enabled: true # Enable/disable the admin web interface\n path: /admin # URL path for admin UI (e.g., http://localhost:8080/admin)\n sessionSecret: env.SESSION_SECRET # Secret key for session encryption (generate with: openssl rand -base64 32)\n sessionMaxAge: 86400 # Session duration in seconds (86400 = 24 hours)\n baseUrl: http://localhost:8080 # Base URL for the proxy (used in config display)\n\n # Analytics configuration\n dataRetentionDays: 30 # How many days to keep detailed request logs (default: 30)\n # Older logs are aggregated into monthly summaries and deleted\n\n# Configuration notes:\n#\n# Environment Variables:\n# - Use \"env.VAR_NAME\" to read from environment variable\n# - Use \"$RANDOM_KEY\" to auto-generate a secure random key\n# - Or use static values directly\n#\n# Provider Types:\n# - \"anthropic\": Provider uses Anthropic API format (/v1/messages)\n# - \"openai\": Provider uses OpenAI API format (/v1/chat/completions)\n# - Defaults to \"anthropic\" if not specified\n# - The proxy automatically converts between formats\n#\n# Model Aliases:\n# - Use \"*\" for wildcard matching\n# - \"opus*\" matches any model name starting with \"opus\"\n# - \"*opus\" matches any model name ending with \"opus\"\n# - \"opus\" matches exactly \"opus\" (no wildcard)\n#\n# Provider Endpoints:\n# - Must be valid HTTP/HTTPS URLs\n# - For Anthropic providers: point to endpoints with /v1/messages support\n# - For OpenAI providers: point to endpoints with /v1/chat/completions support\n# - Can be self-hosted or third-party services\n#\n# Retry Configuration:\n# - By default, the proxy fails over to the next provider immediately.\n# - Set retrySameProvider: true to retry the same provider using the settings above.\n# - Retries apply to network errors, rate limits (429), and server errors (5xx).\n# - Client errors (4xx except 429) are NOT retried.\n#\n# Routing Logic:\n# 1. Models with TPS < 40 are excluded\n# 2. Models are sorted by weight (higher first)\n# 3. If weights are equal, higher TPS wins\n# 4. On failure, immediately tries the next provider (unless same-provider retries are enabled)\n# 5. Continues until a provider succeeds or all providers fail\n#\n# Running the proxy:\n# 1. Set environment variables:\n# # Anthropic providers\n# export ANTHROPIC_API_KEY=your-anthropic-key\n# export OPENROUTER_API_KEY=your-openrouter-key\n# export CHUTES_API_KEY=your-chutes-key\n# export ZAI_API_KEY=your-zai-key\n# export DEEPSEEK_API_KEY=your-deepseek-key\n# export TOGETHER_API_KEY=your-together-key\n#\n# # OpenAI providers\n# export OPENAI_API_KEY=your-openai-key\n# export AZURE_OPENAI_API_KEY=your-azure-key\n# export GROQ_API_KEY=your-groq-key\n# export PERPLEXITY_API_KEY=your-perplexity-key\n#\n# # Proxy configuration\n# export PROXY_API_KEY=your-proxy-key\n# export PORT=8080\n# export LOG_LEVEL=INFO # Options: DEBUG, INFO, WARN, ERROR (default: INFO)\n#\n# 2. Start the server:\n# go run main.go\n#\n# 3. Use the proxy:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-sonnet-4-5-20250929\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Hello, how are you?\"}],\n# \"max_tokens\": 1024\n# }'\n#\n# Example with alias matching:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-opus-latest\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Explain quantum computing\"}],\n# \"max_tokens\": 2048\n# }'\n#\n# Tips:\n# - Use weights to prioritize certain providers or models\n# - Higher weight = higher priority in routing decisions\n# - Models with weight 0 or negative are treated as weight 1\n# - Use wildcard aliases for flexible model routing\n# - Monitor TPS (tokens per second) for performance-based routing\n#\n# Authentication Setup:\n# 1. Generate a session secret:\n# export SESSION_SECRET=$(openssl rand -base64 32)\n#\n# 2. Set up OpenID provider (example: Google)\n# - Go to https://console.cloud.google.com/apis/credentials\n# - Create OAuth 2.0 Client ID\n# - Add authorized redirect URI: http://localhost:8080/auth/callback\n# - Copy Client ID and Client Secret\n# export OIDC_CLIENT_ID=your-client-id\n# export OIDC_CLIENT_SECRET=your-client-secret\n#\n# 3. Start the server with auth enabled:\n# go run main.go --tui\n#\n# 4. Access the admin UI:\n# - Open http://localhost:8080/admin\n# - Click \"Sign in with OpenID\"\n# - Authenticate with your provider\n# - Create API tokens for your applications\n#\n# 5. Use generated tokens:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-xxx-yyy\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\"model\": \"claude-sonnet-4-5-20250929\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}], \"max_tokens\": 1024}'\n#\n# Token Management:\n# - Tokens are stored securely in the database (hashed with bcrypt)\n# - Each user can generate multiple tokens with custom names\n# - Tokens can be revoked at any time through the admin UI\n# - Optional expiration dates for tokens (90 days recommended)\n# - Track token usage (last used timestamp)\n#\n# Supported OpenID Providers:\n# - Google: issuer: https://accounts.google.com\n# - Auth0: issuer: https://your-tenant.auth0.com/\n# - Keycloak: issuer: https://your-keycloak.com/realms/your-realm\n# - Okta: issuer: https://your-domain.okta.com\n# - Custom: Use manual endpoint configuration\n#\n# Database Options:\n# - SQLite (default): Great for single-server deployments, no setup required\n# - PostgreSQL: Recommended for production, supports multiple instances\n#\n# Backward Compatibility:\n# - Old 'apiKeys' configuration still works without auth section\n# - Static keys can coexist with database tokens\n# - No breaking changes to existing deployments\n#\n# Admin Features:\n# - First user to authenticate becomes admin automatically\n# - Admins can:\n# * View all users and their usage statistics\n# * Promote other users to admin\n# * View system-wide analytics\n# * Access detailed request logs for all users\n# - Regular users can:\n# * View their own analytics and usage\n# * Create and manage their own API tokens\n# * Access configuration instructions\n#\n# Analytics:\n# - Detailed request logs are kept for the configured retention period\n# - Old logs are automatically aggregated into monthly summaries\n# - Track: tokens used, requests made, models used, providers, timestamps\n# - Per-user and system-wide analytics available\n"}, "34da64c6adbee2c9fa4b68c3868270b07e12d346": {"t": 1785768030.2671945, "n": 13938, "h": "d74c0d616d9ca356", "c": "spec:\n # Provider configurations\n # Each provider needs a type, endpoint, and API key\n providers:\n # === ANTHROPIC PROVIDERS ===\n # Providers using Anthropic API format (/v1/messages)\n\n # Anthropic official API\n anthropic:\n type: anthropic # Optional: defaults to \"anthropic\" if not specified\n endpoint: https://api.anthropic.com\n apiKey: env.ANTHROPIC_API_KEY\n\n # OpenRouter - Multi-model API gateway (Anthropic format)\n openrouter:\n type: anthropic\n endpoint: https://openrouter.ai/api/v1\n apiKey: env.OPENROUTER_API_KEY\n\n # Chutes AI - Claude proxy\n chutes:\n type: anthropic\n endpoint: https://claude.chutes.ai\n apiKey: env.CHUTES_API_KEY\n\n # Z.ai - AI API provider\n zai:\n type: anthropic\n endpoint: https://api.z.ai/api/anthropic\n apiKey: env.ZAI_API_KEY\n\n # DeepSeek - Chinese AI provider with Anthropic-compatible API\n deepseek:\n type: anthropic\n endpoint: https://api.deepseek.com/anthropic\n apiKey: env.DEEPSEEK_API_KEY\n\n # Together AI - Model hosting platform\n together:\n type: anthropic\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Custom self-hosted endpoint\n selfhosted:\n type: anthropic\n endpoint: http://localhost:11434/v1\n apiKey: \"not-needed\" # For local servers that don't require auth\n\n # AWS Bedrock proxy (example)\n bedrock:\n type: anthropic\n endpoint: https://bedrock-runtime.us-east-1.amazonaws.com\n apiKey: env.AWS_ACCESS_KEY\n\n # === OPENAI PROVIDERS ===\n # Providers using OpenAI API format (/v1/chat/completions)\n # The proxy will automatically convert between Anthropic and OpenAI formats\n\n # OpenAI official API\n openai:\n type: openai\n endpoint: https://api.openai.com\n apiKey: env.OPENAI_API_KEY\n\n # Azure OpenAI\n azure_openai:\n type: openai\n endpoint: https://your-resource-name.openai.azure.com\n apiKey: env.AZURE_OPENAI_API_KEY\n\n # OpenRouter with OpenAI format\n openrouter_openai:\n type: openai\n endpoint: https://openrouter.ai/api\n apiKey: env.OPENROUTER_API_KEY\n\n # Together AI with OpenAI format\n together_openai:\n type: openai\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Groq - Ultra-fast inference\n groq:\n type: openai\n endpoint: https://api.groq.com/openai\n apiKey: env.GROQ_API_KEY\n\n # Perplexity AI\n perplexity:\n type: openai\n endpoint: https://api.perplexity.ai\n apiKey: env.PERPLEXITY_API_KEY\n\n # Retry configuration (optional)\n # Controls backoff parameters when same-provider retries are enabled\n retry:\n retrySameProvider: false # false = failover immediately; true = retry the same provider before failing over\n maxRetries: 3 # Number of same-provider retries when retrySameProvider is true\n initialDelay: 100ms # Initial delay before first retry\n maxDelay: 5s # Maximum delay between retries\n backoffMultiplier: 2.0 # Exponential backoff multiplier\n\n # Model configurations\n # Each model maps to a provider and can have an alias\n models:\n # === CLAUDE MODELS (via Anthropic providers) ===\n\n # Claude Opus models\n - name: \"claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: anthropic\n weight: 5\n\n - name: \"anthropic/claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: openrouter\n weight: 4\n\n # Claude Sonnet models\n - name: \"claude-sonnet-4-5-20250929\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: anthropic\n weight: 5\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: chutes\n weight: 3\n\n - name: \"glm-4.6\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: zai\n weight: 3\n\n - name: \"deepseek-chat\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: deepseek\n weight: 2\n\n # Claude Haiku models (fast, lightweight)\n - name: \"claude-haiku-3-5-20250110\"\n context: 200000\n alias: \"claude-haiku*\"\n provider: anthropic\n weight: 5\n\n - name: \"GLM-4.5-Air\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: zai\n weight: 3\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: chutes\n weight: 2\n\n # Exact model name match (no wildcard)\n - name: \"claude-3-opus-20240229\"\n context: 200000\n alias: \"claude-3-opus-20240229\"\n provider: anthropic\n weight: 5\n\n # === OPENAI MODELS (via OpenAI providers) ===\n # Note: Clients still use Anthropic format, proxy converts automatically\n\n # GPT-4 models\n - name: \"gpt-4o\"\n context: 128000\n alias: \"gpt-4o*\"\n provider: openai\n weight: 5\n\n - name: \"gpt-4-turbo\"\n context: 128000\n alias: \"gpt-4-turbo*\"\n provider: openai\n weight: 4\n\n # GPT-3.5 models\n - name: \"gpt-3.5-turbo\"\n context: 16385\n alias: \"gpt-3.5*\"\n provider: openai\n weight: 3\n\n # Groq models (ultra-fast)\n - name: \"llama-3.3-70b-versatile\"\n context: 8192\n alias: \"llama-3.3*\"\n provider: groq\n weight: 5\n\n - name: \"mixtral-8x7b-32768\"\n context: 32768\n alias: \"mixtral*\"\n provider: groq\n weight: 4\n\n # API keys for authenticating incoming requests\n # These are the keys clients will use to access your proxy\n # DEPRECATED: Use auth.staticKeys instead for better organization\n apiKeys:\n - \"$RANDOM_KEY\" # Will auto-generate a random key on startup\n - \"env.PROXY_API_KEY\" # Read from PROXY_API_KEY environment variable\n - \"sk-proxy-example-key-123\" # Static API key example\n\n # Authentication configuration (NEW)\n # Supports both static keys and OpenID Connect with database-backed token management\n auth:\n # Static API keys (backward compatible, optional)\n # If you have keys in 'apiKeys' above, they will still work\n staticKeys:\n - \"sk-static-key-example\"\n - \"env.STATIC_API_KEY\"\n\n # Database configuration\n database:\n driver: sqlite # \"sqlite\" or \"postgres\"\n dsn: ./data/auth.db # SQLite: file path, PostgreSQL: connection string\n maxConns: 10 # Maximum number of database connections\n\n # PostgreSQL example:\n # driver: postgres\n # dsn: \"host=localhost port=5432 user=proxy password=secret dbname=proxy_auth sslmode=disable\"\n # maxConns: 20\n\n # OpenID Connect configuration\n openid:\n enabled: true # Set to false to disable OAuth, use static keys only\n provider: google # \"google\", \"auth0\", \"keycloak\", or \"custom\"\n\n # Option 1: Auto-discovery (recommended)\n # The proxy will automatically fetch configuration from the provider's .well-known/openid-configuration endpoint\n issuer: https://accounts.google.com\n\n # Option 2: Manual configuration (uncomment if your provider doesn't support auto-discovery)\n # authEndpoint: https://your-provider.com/oauth2/authorize\n # tokenEndpoint: https://your-provider.com/oauth2/token\n # userinfoEndpoint: https://your-provider.com/oauth2/userinfo\n # jwksUrl: https://your-provider.com/.well-known/jwks.json\n\n # OAuth2 credentials (get these from your OpenID provider)\n clientId: env.OIDC_CLIENT_ID # Your OAuth2 client ID\n clientSecret: env.OIDC_CLIENT_SECRET # Your OAuth2 client secret\n redirectUrl: http://localhost:8080/auth/callback # Must match your provider's allowed redirect URLs\n\n # Scopes to request (optional, defaults to: openid, email, profile)\n scopes:\n - openid\n - email\n - profile\n\n # Admin UI configuration\n adminUI:\n enabled: true # Enable/disable the admin web interface\n path: /admin # URL path for admin UI (e.g., http://localhost:8080/admin)\n sessionSecret: env.SESSION_SECRET # Secret key for session encryption (generate with: openssl rand -base64 32)\n sessionMaxAge: 86400 # Session duration in seconds (86400 = 24 hours)\n\n# Configuration notes:\n#\n# Environment Variables:\n# - Use \"env.VAR_NAME\" to read from environment variable\n# - Use \"$RANDOM_KEY\" to auto-generate a secure random key\n# - Or use static values directly\n#\n# Provider Types:\n# - \"anthropic\": Provider uses Anthropic API format (/v1/messages)\n# - \"openai\": Provider uses OpenAI API format (/v1/chat/completions)\n# - Defaults to \"anthropic\" if not specified\n# - The proxy automatically converts between formats\n#\n# Model Aliases:\n# - Use \"*\" for wildcard matching\n# - \"opus*\" matches any model name starting with \"opus\"\n# - \"*opus\" matches any model name ending with \"opus\"\n# - \"opus\" matches exactly \"opus\" (no wildcard)\n#\n# Provider Endpoints:\n# - Must be valid HTTP/HTTPS URLs\n# - For Anthropic providers: point to endpoints with /v1/messages support\n# - For OpenAI providers: point to endpoints with /v1/chat/completions support\n# - Can be self-hosted or third-party services\n#\n# Retry Configuration:\n# - By default, the proxy fails over to the next provider immediately.\n# - Set retrySameProvider: true to retry the same provider using the settings above.\n# - Retries apply to network errors, rate limits (429), and server errors (5xx).\n# - Client errors (4xx except 429) are NOT retried.\n#\n# Routing Logic:\n# 1. Models with TPS < 40 are excluded\n# 2. Models are sorted by weight (higher first)\n# 3. If weights are equal, higher TPS wins\n# 4. On failure, immediately tries the next provider (unless same-provider retries are enabled)\n# 5. Continues until a provider succeeds or all providers fail\n#\n# Running the proxy:\n# 1. Set environment variables:\n# # Anthropic providers\n# export ANTHROPIC_API_KEY=your-anthropic-key\n# export OPENROUTER_API_KEY=your-openrouter-key\n# export CHUTES_API_KEY=your-chutes-key\n# export ZAI_API_KEY=your-zai-key\n# export DEEPSEEK_API_KEY=your-deepseek-key\n# export TOGETHER_API_KEY=your-together-key\n#\n# # OpenAI providers\n# export OPENAI_API_KEY=your-openai-key\n# export AZURE_OPENAI_API_KEY=your-azure-key\n# export GROQ_API_KEY=your-groq-key\n# export PERPLEXITY_API_KEY=your-perplexity-key\n#\n# # Proxy configuration\n# export PROXY_API_KEY=your-proxy-key\n# export PORT=8080\n# export LOG_LEVEL=INFO # Options: DEBUG, INFO, WARN, ERROR (default: INFO)\n#\n# 2. Start the server:\n# go run main.go\n#\n# 3. Use the proxy:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-sonnet-4-5-20250929\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Hello, how are you?\"}],\n# \"max_tokens\": 1024\n# }'\n#\n# Example with alias matching:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-opus-latest\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Explain quantum computing\"}],\n# \"max_tokens\": 2048\n# }'\n#\n# Tips:\n# - Use weights to prioritize certain providers or models\n# - Higher weight = higher priority in routing decisions\n# - Models with weight 0 or negative are treated as weight 1\n# - Use wildcard aliases for flexible model routing\n# - Monitor TPS (tokens per second) for performance-based routing\n#\n# Authentication Setup:\n# 1. Generate a session secret:\n# export SESSION_SECRET=$(openssl rand -base64 32)\n#\n# 2. Set up OpenID provider (example: Google)\n# - Go to https://console.cloud.google.com/apis/credentials\n# - Create OAuth 2.0 Client ID\n# - Add authorized redirect URI: http://localhost:8080/auth/callback\n# - Copy Client ID and Client Secret\n# export OIDC_CLIENT_ID=your-client-id\n# export OIDC_CLIENT_SECRET=your-client-secret\n#\n# 3. Start the server with auth enabled:\n# go run main.go --tui\n#\n# 4. Access the admin UI:\n# - Open http://localhost:8080/admin\n# - Click \"Sign in with OpenID\"\n# - Authenticate with your provider\n# - Create API tokens for your applications\n#\n# 5. Use generated tokens:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-xxx-yyy\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\"model\": \"claude-sonnet-4-5-20250929\", \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}], \"max_tokens\": 1024}'\n#\n# Token Management:\n# - Tokens are stored securely in the database (hashed with bcrypt)\n# - Each user can generate multiple tokens with custom names\n# - Tokens can be revoked at any time through the admin UI\n# - Optional expiration dates for tokens (90 days recommended)\n# - Track token usage (last used timestamp)\n#\n# Supported OpenID Providers:\n# - Google: issuer: https://accounts.google.com\n# - Auth0: issuer: https://your-tenant.auth0.com/\n# - Keycloak: issuer: https://your-keycloak.com/realms/your-realm\n# - Okta: issuer: https://your-domain.okta.com\n# - Custom: Use manual endpoint configuration\n#\n# Database Options:\n# - SQLite (default): Great for single-server deployments, no setup required\n# - PostgreSQL: Recommended for production, supports multiple instances\n#\n# Backward Compatibility:\n# - Old 'apiKeys' configuration still works without auth section\n# - Static keys can coexist with database tokens\n# - No breaking changes to existing deployments\n"}, "6dfda0ef5d4fcbd88a75fd71193dd4efd0a4c1b2": {"t": 1785768031.635539, "n": 9205, "h": "712fa0ba643ae597", "c": "spec:\n # Provider configurations\n # Each provider needs a type, endpoint, and API key\n providers:\n # === ANTHROPIC PROVIDERS ===\n # Providers using Anthropic API format (/v1/messages)\n\n # Anthropic official API\n anthropic:\n type: anthropic # Optional: defaults to \"anthropic\" if not specified\n endpoint: https://api.anthropic.com\n apiKey: env.ANTHROPIC_API_KEY\n\n # OpenRouter - Multi-model API gateway (Anthropic format)\n openrouter:\n type: anthropic\n endpoint: https://openrouter.ai/api/v1\n apiKey: env.OPENROUTER_API_KEY\n\n # Chutes AI - Claude proxy\n chutes:\n type: anthropic\n endpoint: https://claude.chutes.ai\n apiKey: env.CHUTES_API_KEY\n\n # Z.ai - AI API provider\n zai:\n type: anthropic\n endpoint: https://api.z.ai/api/anthropic\n apiKey: env.ZAI_API_KEY\n\n # DeepSeek - Chinese AI provider with Anthropic-compatible API\n deepseek:\n type: anthropic\n endpoint: https://api.deepseek.com/anthropic\n apiKey: env.DEEPSEEK_API_KEY\n\n # Together AI - Model hosting platform\n together:\n type: anthropic\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Custom self-hosted endpoint\n selfhosted:\n type: anthropic\n endpoint: http://localhost:11434/v1\n apiKey: \"not-needed\" # For local servers that don't require auth\n\n # AWS Bedrock proxy (example)\n bedrock:\n type: anthropic\n endpoint: https://bedrock-runtime.us-east-1.amazonaws.com\n apiKey: env.AWS_ACCESS_KEY\n\n # === OPENAI PROVIDERS ===\n # Providers using OpenAI API format (/v1/chat/completions)\n # The proxy will automatically convert between Anthropic and OpenAI formats\n\n # OpenAI official API\n openai:\n type: openai\n endpoint: https://api.openai.com\n apiKey: env.OPENAI_API_KEY\n\n # Azure OpenAI\n azure_openai:\n type: openai\n endpoint: https://your-resource-name.openai.azure.com\n apiKey: env.AZURE_OPENAI_API_KEY\n\n # OpenRouter with OpenAI format\n openrouter_openai:\n type: openai\n endpoint: https://openrouter.ai/api\n apiKey: env.OPENROUTER_API_KEY\n\n # Together AI with OpenAI format\n together_openai:\n type: openai\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Groq - Ultra-fast inference\n groq:\n type: openai\n endpoint: https://api.groq.com/openai\n apiKey: env.GROQ_API_KEY\n\n # Perplexity AI\n perplexity:\n type: openai\n endpoint: https://api.perplexity.ai\n apiKey: env.PERPLEXITY_API_KEY\n\n # Retry configuration (optional)\n # Controls how requests are retried on failure\n retry:\n maxRetries: 3 # Maximum number of retries per provider (default: 3)\n initialDelay: 100ms # Initial delay before first retry (default: 100ms)\n maxDelay: 5s # Maximum delay between retries (default: 5s)\n backoffMultiplier: 2.0 # Exponential backoff multiplier (default: 2.0)\n\n # Model configurations\n # Each model maps to a provider and can have an alias\n models:\n # === CLAUDE MODELS (via Anthropic providers) ===\n\n # Claude Opus models\n - name: \"claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: anthropic\n weight: 5\n\n - name: \"anthropic/claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: openrouter\n weight: 4\n\n # Claude Sonnet models\n - name: \"claude-sonnet-4-5-20250929\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: anthropic\n weight: 5\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: chutes\n weight: 3\n\n - name: \"glm-4.6\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: zai\n weight: 3\n\n - name: \"deepseek-chat\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: deepseek\n weight: 2\n\n # Claude Haiku models (fast, lightweight)\n - name: \"claude-haiku-3-5-20250110\"\n context: 200000\n alias: \"claude-haiku*\"\n provider: anthropic\n weight: 5\n\n - name: \"GLM-4.5-Air\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: zai\n weight: 3\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: chutes\n weight: 2\n\n # Exact model name match (no wildcard)\n - name: \"claude-3-opus-20240229\"\n context: 200000\n alias: \"claude-3-opus-20240229\"\n provider: anthropic\n weight: 5\n\n # === OPENAI MODELS (via OpenAI providers) ===\n # Note: Clients still use Anthropic format, proxy converts automatically\n\n # GPT-4 models\n - name: \"gpt-4o\"\n context: 128000\n alias: \"gpt-4o*\"\n provider: openai\n weight: 5\n\n - name: \"gpt-4-turbo\"\n context: 128000\n alias: \"gpt-4-turbo*\"\n provider: openai\n weight: 4\n\n # GPT-3.5 models\n - name: \"gpt-3.5-turbo\"\n context: 16385\n alias: \"gpt-3.5*\"\n provider: openai\n weight: 3\n\n # Groq models (ultra-fast)\n - name: \"llama-3.3-70b-versatile\"\n context: 8192\n alias: \"llama-3.3*\"\n provider: groq\n weight: 5\n\n - name: \"mixtral-8x7b-32768\"\n context: 32768\n alias: \"mixtral*\"\n provider: groq\n weight: 4\n\n # API keys for authenticating incoming requests\n # These are the keys clients will use to access your proxy\n apiKeys:\n - \"$RANDOM_KEY\" # Will auto-generate a random key on startup\n - \"env.PROXY_API_KEY\" # Read from PROXY_API_KEY environment variable\n - \"sk-proxy-example-key-123\" # Static API key example\n\n# Configuration notes:\n#\n# Environment Variables:\n# - Use \"env.VAR_NAME\" to read from environment variable\n# - Use \"$RANDOM_KEY\" to auto-generate a secure random key\n# - Or use static values directly\n#\n# Provider Types:\n# - \"anthropic\": Provider uses Anthropic API format (/v1/messages)\n# - \"openai\": Provider uses OpenAI API format (/v1/chat/completions)\n# - Defaults to \"anthropic\" if not specified\n# - The proxy automatically converts between formats\n#\n# Model Aliases:\n# - Use \"*\" for wildcard matching\n# - \"opus*\" matches any model name starting with \"opus\"\n# - \"*opus\" matches any model name ending with \"opus\"\n# - \"opus\" matches exactly \"opus\" (no wildcard)\n#\n# Provider Endpoints:\n# - Must be valid HTTP/HTTPS URLs\n# - For Anthropic providers: point to endpoints with /v1/messages support\n# - For OpenAI providers: point to endpoints with /v1/chat/completions support\n# - Can be self-hosted or third-party services\n#\n# Retry Configuration:\n# - Requests are automatically retried on network errors, rate limits (429), and server errors (5xx)\n# - Each provider is retried up to maxRetries times with exponential backoff\n# - After all retries fail, the next provider in the list is tried\n# - Client errors (4xx except 429) are NOT retried\n#\n# Routing Logic:\n# 1. Models with TPS < 40 are excluded\n# 2. Models are sorted by weight (higher first)\n# 3. If weights are equal, higher TPS wins\n# 4. On failure, retries the same provider with backoff\n# 5. After retries exhausted, tries next provider in order\n#\n# Running the proxy:\n# 1. Set environment variables:\n# # Anthropic providers\n# export ANTHROPIC_API_KEY=your-anthropic-key\n# export OPENROUTER_API_KEY=your-openrouter-key\n# export CHUTES_API_KEY=your-chutes-key\n# export ZAI_API_KEY=your-zai-key\n# export DEEPSEEK_API_KEY=your-deepseek-key\n# export TOGETHER_API_KEY=your-together-key\n#\n# # OpenAI providers\n# export OPENAI_API_KEY=your-openai-key\n# export AZURE_OPENAI_API_KEY=your-azure-key\n# export GROQ_API_KEY=your-groq-key\n# export PERPLEXITY_API_KEY=your-perplexity-key\n#\n# # Proxy configuration\n# export PROXY_API_KEY=your-proxy-key\n# export PORT=8080\n# export LOG_LEVEL=INFO # Options: DEBUG, INFO, WARN, ERROR (default: INFO)\n#\n# 2. Start the server:\n# go run main.go\n#\n# 3. Use the proxy:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-sonnet-4-5-20250929\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Hello, how are you?\"}],\n# \"max_tokens\": 1024\n# }'\n#\n# Example with alias matching:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-opus-latest\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Explain quantum computing\"}],\n# \"max_tokens\": 2048\n# }'\n#\n# Tips:\n# - Use weights to prioritize certain providers or models\n# - Higher weight = higher priority in routing decisions\n# - Models with weight 0 or negative are treated as weight 1\n# - Use wildcard aliases for flexible model routing\n# - Monitor TPS (tokens per second) for performance-based routing\n"}, "639e58606b0336dc537a8d2a0b36ac491ff3d6ab": {"t": 1785768032.8869596, "n": 6343, "h": "91e0240bc5e3de32", "c": "spec:\n # Provider configurations\n # Each provider needs an endpoint and API key\n providers:\n # Anthropic official API\n anthropic:\n endpoint: https://api.anthropic.com\n apiKey: env.ANTHROPIC_API_KEY\n\n # OpenRouter - Multi-model API gateway\n openrouter:\n endpoint: https://openrouter.ai/api/v1\n apiKey: env.OPENROUTER_API_KEY\n\n # Chutes AI - Claude proxy\n chutes:\n endpoint: https://claude.chutes.ai\n apiKey: env.CHUTES_API_KEY\n\n # Z.ai - AI API provider\n zai:\n endpoint: https://api.z.ai/api/anthropic\n apiKey: env.ZAI_API_KEY\n\n # DeepSeek - Chinese AI provider with Anthropic-compatible API\n deepseek:\n endpoint: https://api.deepseek.com/anthropic\n apiKey: env.DEEPSEEK_API_KEY\n\n # Together AI - Model hosting platform\n together:\n endpoint: https://api.together.xyz\n apiKey: env.TOGETHER_API_KEY\n\n # Custom self-hosted endpoint\n selfhosted:\n endpoint: http://localhost:11434/v1\n apiKey: \"not-needed\" # For local servers that don't require auth\n\n # AWS Bedrock proxy (example)\n bedrock:\n endpoint: https://bedrock-runtime.us-east-1.amazonaws.com\n apiKey: env.AWS_ACCESS_KEY\n\n # Retry configuration (optional)\n # Controls how requests are retried on failure\n retry:\n maxRetries: 3 # Maximum number of retries per provider (default: 3)\n initialDelay: 100ms # Initial delay before first retry (default: 100ms)\n maxDelay: 5s # Maximum delay between retries (default: 5s)\n backoffMultiplier: 2.0 # Exponential backoff multiplier (default: 2.0)\n\n # Model configurations\n # Each model maps to a provider and can have an alias\n models:\n # Claude Opus models\n - name: \"claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: anthropic\n weight: 5\n\n - name: \"anthropic/claude-opus-4-20250514\"\n context: 200000\n alias: \"claude-opus*\"\n provider: openrouter\n weight: 4\n\n # Claude Sonnet models\n - name: \"claude-sonnet-4-5-20250929\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: anthropic\n weight: 5\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: chutes\n weight: 3\n\n - name: \"glm-4.6\"\n context: 256000\n alias: \"claude-sonnet*\"\n provider: zai\n weight: 3\n\n - name: \"deepseek-chat\"\n context: 200000\n alias: \"claude-sonnet*\"\n provider: deepseek\n weight: 2\n\n # Claude Haiku models (fast, lightweight)\n - name: \"claude-haiku-3-5-20250110\"\n context: 200000\n alias: \"claude-haiku*\"\n provider: anthropic\n weight: 5\n\n - name: \"GLM-4.5-Air\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: zai\n weight: 3\n\n - name: \"moonshotai/Kimi-K2-Thinking\"\n context: 256000\n alias: \"claude-haiku*\"\n provider: chutes\n weight: 2\n\n # Exact model name match (no wildcard)\n - name: \"claude-3-opus-20240229\"\n context: 200000\n alias: \"claude-3-opus-20240229\"\n provider: anthropic\n weight: 5\n\n # API keys for authenticating incoming requests\n # These are the keys clients will use to access your proxy\n apiKeys:\n - \"$RANDOM_KEY\" # Will auto-generate a random key on startup\n - \"env.PROXY_API_KEY\" # Read from PROXY_API_KEY environment variable\n - \"sk-proxy-example-key-123\" # Static API key example\n\n# Configuration notes:\n#\n# Environment Variables:\n# - Use \"env.VAR_NAME\" to read from environment variable\n# - Use \"$RANDOM_KEY\" to auto-generate a secure random key\n# - Or use static values directly\n#\n# Model Aliases:\n# - Use \"*\" for wildcard matching\n# - \"opus*\" matches any model name starting with \"opus\"\n# - \"*opus\" matches any model name ending with \"opus\"\n# - \"opus\" matches exactly \"opus\" (no wildcard)\n#\n# Provider Endpoints:\n# - Must be valid HTTP/HTTPS URLs\n# - Should point to Anthropic-compatible API endpoints\n# - Can be self-hosted or third-party services\n#\n# Retry Configuration:\n# - Requests are automatically retried on network errors, rate limits (429), and server errors (5xx)\n# - Each provider is retried up to maxRetries times with exponential backoff\n# - After all retries fail, the next provider in the list is tried\n# - Client errors (4xx except 429) are NOT retried\n#\n# Routing Logic:\n# 1. Models with TPS < 40 are excluded\n# 2. Models are sorted by weight (higher first)\n# 3. If weights are equal, higher TPS wins\n# 4. On failure, retries the same provider with backoff\n# 5. After retries exhausted, tries next provider in order\n#\n# Running the proxy:\n# 1. Set environment variables:\n# export ANTHROPIC_API_KEY=your-anthropic-key\n# export OPENROUTER_API_KEY=your-openrouter-key\n# export CHUTES_API_KEY=your-chutes-key\n# export ZAI_API_KEY=your-zai-key\n# export DEEPSEEK_API_KEY=your-deepseek-key\n# export TOGETHER_API_KEY=your-together-key\n# export PROXY_API_KEY=your-proxy-key\n# export PORT=8080\n# export LOG_LEVEL=INFO # Options: DEBUG, INFO, WARN, ERROR (default: INFO)\n#\n# 2. Start the server:\n# go run main.go\n#\n# 3. Use the proxy:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-sonnet-4-5-20250929\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Hello, how are you?\"}],\n# \"max_tokens\": 1024\n# }'\n#\n# Example with alias matching:\n# curl -X POST http://localhost:8080/v1/messages \\\n# -H \"Authorization: Bearer sk-proxy-example-key-123\" \\\n# -H \"Content-Type: application/json\" \\\n# -d '{\n# \"model\": \"claude-opus-latest\",\n# \"messages\": [{\"role\": \"user\", \"content\": \"Explain quantum computing\"}],\n# \"max_tokens\": 2048\n# }'\n#\n# Tips:\n# - Use weights to prioritize certain providers or models\n# - Higher weight = higher priority in routing decisions\n# - Models with weight 0 or negative are treated as weight 1\n# - Use wildcard aliases for flexible model routing\n# - Monitor TPS (tokens per second) for performance-based routing\n"}}}}