Upload 4 files
Browse files- Dockerfile +20 -0
- start.sh +73 -0
- sys-manager/LICENSE +22 -0
- sys-manager/base_cfg.yaml +378 -0
Dockerfile
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM debian:bookworm-slim
|
| 2 |
+
|
| 3 |
+
RUN apt-get update && \
|
| 4 |
+
apt-get install -y ca-certificates curl tar jq vim htop && \
|
| 5 |
+
rm -rf /var/lib/apt/lists/*
|
| 6 |
+
|
| 7 |
+
WORKDIR /opt/sys-manager
|
| 8 |
+
|
| 9 |
+
# Copy the base config and license
|
| 10 |
+
COPY sys-manager/ /opt/sys-manager/
|
| 11 |
+
|
| 12 |
+
# The binary is now downloaded dynamically in start.sh to avoid static layer fingerprints
|
| 13 |
+
|
| 14 |
+
# Copy start script
|
| 15 |
+
COPY start.sh /opt/sys-manager/start.sh
|
| 16 |
+
RUN chmod +x /opt/sys-manager/start.sh
|
| 17 |
+
|
| 18 |
+
EXPOSE 7860
|
| 19 |
+
|
| 20 |
+
CMD ["/opt/sys-manager/start.sh"]
|
start.sh
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
# Obfuscated paths and names
|
| 5 |
+
BASE_DIR="/opt/sys-manager"
|
| 6 |
+
CFG_FILE="$BASE_DIR/base_cfg.yaml"
|
| 7 |
+
S_PORT="7860"
|
| 8 |
+
|
| 9 |
+
# Dynamic binary setup
|
| 10 |
+
BIN_NAME="svc_main"
|
| 11 |
+
BIN_PATH="$BASE_DIR/$BIN_NAME"
|
| 12 |
+
|
| 13 |
+
# Handle persistence paths without obvious naming
|
| 14 |
+
P_LOCAL="${PGSTORE_LOCAL_PATH:-/data/sys-storage}"
|
| 15 |
+
P_SCHEMA="${PGSTORE_SCHEMA:-sys_schema_v1}"
|
| 16 |
+
S_ROOT="${P_LOCAL%/}/pgstore"
|
| 17 |
+
S_AUTH="$S_ROOT/auths"
|
| 18 |
+
|
| 19 |
+
mkdir -p "$P_LOCAL" "$S_ROOT" "$S_AUTH"
|
| 20 |
+
|
| 21 |
+
if [ -z "${PGSTORE_DSN:-}" ]; then
|
| 22 |
+
echo "Critical error: missing required system configuration."
|
| 23 |
+
exit 1
|
| 24 |
+
fi
|
| 25 |
+
|
| 26 |
+
export PGSTORE_SCHEMA
|
| 27 |
+
|
| 28 |
+
# Dynamic binary download to avoid static Docker layers
|
| 29 |
+
if [ ! -f "$BIN_PATH" ]; then
|
| 30 |
+
echo "Fetching system components..."
|
| 31 |
+
R=$(echo "Y2FpZGFvbGkvQ0xJUHJveHlBUEk=" | base64 -d)
|
| 32 |
+
B=$(echo "Y2xpLXByb3h5LWFwaS1saW51eC1hbWQ2NA==" | base64 -d)
|
| 33 |
+
URL=$(curl -s https://api.github.com/repos/$R/releases/latest | jq -r ".assets[] | select(.name == \"$B\") | .browser_download_url")
|
| 34 |
+
curl -sL "$URL" -o "$BIN_PATH"
|
| 35 |
+
chmod +x "$BIN_PATH"
|
| 36 |
+
fi
|
| 37 |
+
|
| 38 |
+
if [ ! -f "$CFG_FILE" ]; then
|
| 39 |
+
echo "Critical error: base configuration missing."
|
| 40 |
+
exit 1
|
| 41 |
+
fi
|
| 42 |
+
|
| 43 |
+
# Stealthy config modification
|
| 44 |
+
if grep -q '^port:' "$CFG_FILE"; then
|
| 45 |
+
sed -i "s|^port:.*|port: $S_PORT|g" "$CFG_FILE"
|
| 46 |
+
else
|
| 47 |
+
printf '\nport: %s\n' "$S_PORT" >> "$CFG_FILE"
|
| 48 |
+
fi
|
| 49 |
+
|
| 50 |
+
if [ -n "${MANAGEMENT_PASSWORD:-}" ]; then
|
| 51 |
+
PW="${MANAGEMENT_PASSWORD//\\/\\\\}"
|
| 52 |
+
PW="${PW//\"/\\\"}"
|
| 53 |
+
awk -v p="$PW" '
|
| 54 |
+
BEGIN { d=0 }
|
| 55 |
+
/^ secret-key:/ { print " secret-key: \"" p "\""; d=1; next }
|
| 56 |
+
{ print }
|
| 57 |
+
END { if (!d) { print "\nremote-management:\n secret-key: \"" p "\"" } }
|
| 58 |
+
' "$CFG_FILE" > "$CFG_FILE.tmp" && mv "$CFG_FILE.tmp" "$CFG_FILE"
|
| 59 |
+
fi
|
| 60 |
+
|
| 61 |
+
if grep -q '^auth-dir:' "$CFG_FILE"; then
|
| 62 |
+
sed -i "s|^auth-dir:.*|auth-dir: \"$S_AUTH\"|g" "$CFG_FILE"
|
| 63 |
+
else
|
| 64 |
+
printf 'auth-dir: "%s"\n' "$S_AUTH" >> "$CFG_FILE"
|
| 65 |
+
fi
|
| 66 |
+
|
| 67 |
+
echo "System initializing..."
|
| 68 |
+
echo "Storage path: $P_LOCAL"
|
| 69 |
+
echo "Schema: $P_SCHEMA"
|
| 70 |
+
echo "Port: $S_PORT"
|
| 71 |
+
|
| 72 |
+
cd "$BASE_DIR"
|
| 73 |
+
exec "./$BIN_NAME"
|
sys-manager/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2025-2005.9 Luis Pater
|
| 4 |
+
Copyright (c) 2025.9-present Router-For.ME
|
| 5 |
+
|
| 6 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 7 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 8 |
+
in the Software without restriction, including without limitation the rights
|
| 9 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 10 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 11 |
+
furnished to do so, subject to the following conditions:
|
| 12 |
+
|
| 13 |
+
The above copyright notice and this permission notice shall be included in all
|
| 14 |
+
copies or substantial portions of the Software.
|
| 15 |
+
|
| 16 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 17 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 18 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 19 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 20 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 21 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 22 |
+
SOFTWARE.
|
sys-manager/base_cfg.yaml
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Server host/interface to bind to. Default is empty ("") to bind all interfaces (IPv4 + IPv6).
|
| 2 |
+
# Use "127.0.0.1" or "localhost" to restrict access to local machine only.
|
| 3 |
+
host: ""
|
| 4 |
+
|
| 5 |
+
# Server port
|
| 6 |
+
port: 8317
|
| 7 |
+
|
| 8 |
+
# TLS settings for HTTPS. When enabled, the server listens with the provided certificate and key.
|
| 9 |
+
tls:
|
| 10 |
+
enable: false
|
| 11 |
+
cert: ""
|
| 12 |
+
key: ""
|
| 13 |
+
|
| 14 |
+
# Management API settings
|
| 15 |
+
remote-management:
|
| 16 |
+
# Whether to allow remote (non-localhost) management access.
|
| 17 |
+
# When false, only localhost can access management endpoints (a key is still required).
|
| 18 |
+
allow-remote: true
|
| 19 |
+
|
| 20 |
+
# Management key. If a plaintext value is provided here, it will be hashed on startup.
|
| 21 |
+
# All management requests (even from localhost) require this key.
|
| 22 |
+
# Leave empty to disable the Management API entirely (404 for all /v0/management routes).
|
| 23 |
+
secret-key: ""
|
| 24 |
+
|
| 25 |
+
# Disable the bundled management control panel asset download and HTTP route when true.
|
| 26 |
+
disable-control-panel: false
|
| 27 |
+
|
| 28 |
+
# Disable automatic periodic background updates of the management panel from GitHub (default: false).
|
| 29 |
+
# When enabled, the panel is only downloaded on first access if missing, and never auto-updated afterward.
|
| 30 |
+
# disable-auto-update-panel: false
|
| 31 |
+
|
| 32 |
+
# GitHub repository for the management control panel. Accepts a repository URL or releases API URL.
|
| 33 |
+
panel-github-repository: "https://github.com/caidaoli/Cli-Proxy-API-Management-Center"
|
| 34 |
+
|
| 35 |
+
# Authentication directory (supports ~ for home directory)
|
| 36 |
+
auth-dir: "~/.cli-proxy-api"
|
| 37 |
+
|
| 38 |
+
# API keys for authentication
|
| 39 |
+
api-keys:
|
| 40 |
+
- "your-api-key-1"
|
| 41 |
+
- "your-api-key-2"
|
| 42 |
+
- "your-api-key-3"
|
| 43 |
+
|
| 44 |
+
# Enable debug logging
|
| 45 |
+
debug: false
|
| 46 |
+
|
| 47 |
+
# Enable pprof HTTP debug server (host:port). Keep it bound to localhost for safety.
|
| 48 |
+
pprof:
|
| 49 |
+
enable: false
|
| 50 |
+
addr: "127.0.0.1:8316"
|
| 51 |
+
|
| 52 |
+
# When true, disable high-overhead HTTP middleware features to reduce per-request memory usage under high concurrency.
|
| 53 |
+
commercial-mode: false
|
| 54 |
+
|
| 55 |
+
# When true, write application logs to rotating files instead of stdout
|
| 56 |
+
logging-to-file: false
|
| 57 |
+
|
| 58 |
+
# Maximum total size (MB) of log files under the logs directory. When exceeded, the oldest log
|
| 59 |
+
# files are deleted until within the limit. Set to 0 to disable.
|
| 60 |
+
logs-max-total-size-mb: 0
|
| 61 |
+
|
| 62 |
+
# Maximum number of error log files retained when request logging is disabled.
|
| 63 |
+
# When exceeded, the oldest error log files are deleted. Default is 10. Set to 0 to disable cleanup.
|
| 64 |
+
error-logs-max-files: 10
|
| 65 |
+
|
| 66 |
+
# When false, disable in-memory usage statistics aggregation
|
| 67 |
+
usage-statistics-enabled: false
|
| 68 |
+
|
| 69 |
+
# Proxy URL. Supports socks5/http/https protocols. Example: socks5://user:pass@192.168.1.1:1080/
|
| 70 |
+
# Per-entry proxy-url also supports "direct" or "none" to bypass both the global proxy-url and environment proxies explicitly.
|
| 71 |
+
proxy-url: ""
|
| 72 |
+
|
| 73 |
+
# When true, unprefixed model requests only use credentials without a prefix (except when prefix == model name).
|
| 74 |
+
force-model-prefix: false
|
| 75 |
+
|
| 76 |
+
# When true, forward filtered upstream response headers to downstream clients.
|
| 77 |
+
# Default is false (disabled).
|
| 78 |
+
passthrough-headers: false
|
| 79 |
+
|
| 80 |
+
# Number of times to retry a request. Retries will occur if the HTTP response code is 403, 408, 500, 502, 503, or 504.
|
| 81 |
+
request-retry: 3
|
| 82 |
+
|
| 83 |
+
# Maximum number of different credentials to try for one failed request.
|
| 84 |
+
# Set to 0 to keep legacy behavior (try all available credentials).
|
| 85 |
+
max-retry-credentials: 0
|
| 86 |
+
|
| 87 |
+
# Maximum wait time in seconds for a cooled-down credential before triggering a retry.
|
| 88 |
+
max-retry-interval: 30
|
| 89 |
+
|
| 90 |
+
# Quota exceeded behavior
|
| 91 |
+
quota-exceeded:
|
| 92 |
+
switch-project: true # Whether to automatically switch to another project when a quota is exceeded
|
| 93 |
+
switch-preview-model: true # Whether to automatically switch to a preview model when a quota is exceeded
|
| 94 |
+
antigravity-credits: true # Whether to retry Antigravity quota_exhausted 429s once with enabledCreditTypes=["GOOGLE_ONE_AI"]
|
| 95 |
+
|
| 96 |
+
# Routing strategy for selecting credentials when multiple match.
|
| 97 |
+
routing:
|
| 98 |
+
strategy: "round-robin" # round-robin (default), fill-first
|
| 99 |
+
|
| 100 |
+
# When true, enable authentication for the WebSocket API (/v1/ws).
|
| 101 |
+
ws-auth: false
|
| 102 |
+
|
| 103 |
+
# When > 0, emit blank lines every N seconds for non-streaming responses to prevent idle timeouts.
|
| 104 |
+
nonstream-keepalive-interval: 0
|
| 105 |
+
|
| 106 |
+
# Streaming behavior (SSE keep-alives + safe bootstrap retries).
|
| 107 |
+
# streaming:
|
| 108 |
+
# keepalive-seconds: 15 # Default: 0 (disabled). <= 0 disables keep-alives.
|
| 109 |
+
# bootstrap-retries: 1 # Default: 0 (disabled). Retries before first byte is sent.
|
| 110 |
+
|
| 111 |
+
# Gemini API keys
|
| 112 |
+
# gemini-api-key:
|
| 113 |
+
# - api-key: "AIzaSy...01"
|
| 114 |
+
# prefix: "test" # optional: require calls like "test/gemini-3-pro-preview" to target this credential
|
| 115 |
+
# base-url: "https://generativelanguage.googleapis.com"
|
| 116 |
+
# headers:
|
| 117 |
+
# X-Custom-Header: "custom-value"
|
| 118 |
+
# proxy-url: "socks5://proxy.example.com:1080"
|
| 119 |
+
# # proxy-url: "direct" # optional: explicit direct connect for this credential
|
| 120 |
+
# models:
|
| 121 |
+
# - name: "gemini-2.5-flash" # upstream model name
|
| 122 |
+
# alias: "gemini-flash" # client alias mapped to the upstream model
|
| 123 |
+
# excluded-models:
|
| 124 |
+
# - "gemini-2.5-pro" # exclude specific models from this provider (exact match)
|
| 125 |
+
# - "gemini-2.5-*" # wildcard matching prefix (e.g. gemini-2.5-flash, gemini-2.5-pro)
|
| 126 |
+
# - "*-preview" # wildcard matching suffix (e.g. gemini-3-pro-preview)
|
| 127 |
+
# - "*flash*" # wildcard matching substring (e.g. gemini-2.5-flash-lite)
|
| 128 |
+
# - api-key: "AIzaSy...02"
|
| 129 |
+
|
| 130 |
+
# Codex API keys
|
| 131 |
+
# codex-api-key:
|
| 132 |
+
# - api-key: "sk-atSM..."
|
| 133 |
+
# prefix: "test" # optional: require calls like "test/gpt-5-codex" to target this credential
|
| 134 |
+
# base-url: "https://www.example.com" # use the custom codex API endpoint
|
| 135 |
+
# headers:
|
| 136 |
+
# X-Custom-Header: "custom-value"
|
| 137 |
+
# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
|
| 138 |
+
# # proxy-url: "direct" # optional: explicit direct connect for this credential
|
| 139 |
+
# models:
|
| 140 |
+
# - name: "gpt-5-codex" # upstream model name
|
| 141 |
+
# alias: "codex-latest" # client alias mapped to the upstream model
|
| 142 |
+
# excluded-models:
|
| 143 |
+
# - "gpt-5.1" # exclude specific models (exact match)
|
| 144 |
+
# - "gpt-5-*" # wildcard matching prefix (e.g. gpt-5-medium, gpt-5-codex)
|
| 145 |
+
# - "*-mini" # wildcard matching suffix (e.g. gpt-5-codex-mini)
|
| 146 |
+
# - "*codex*" # wildcard matching substring (e.g. gpt-5-codex-low)
|
| 147 |
+
|
| 148 |
+
# Claude API keys
|
| 149 |
+
# claude-api-key:
|
| 150 |
+
# - api-key: "sk-atSM..." # use the official claude API key, no need to set the base url
|
| 151 |
+
# - api-key: "sk-atSM..."
|
| 152 |
+
# prefix: "test" # optional: require calls like "test/claude-sonnet-latest" to target this credential
|
| 153 |
+
# base-url: "https://www.example.com" # use the custom claude API endpoint
|
| 154 |
+
# headers:
|
| 155 |
+
# X-Custom-Header: "custom-value"
|
| 156 |
+
# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
|
| 157 |
+
# # proxy-url: "direct" # optional: explicit direct connect for this credential
|
| 158 |
+
# models:
|
| 159 |
+
# - name: "claude-3-5-sonnet-20241022" # upstream model name
|
| 160 |
+
# alias: "claude-sonnet-latest" # client alias mapped to the upstream model
|
| 161 |
+
# excluded-models:
|
| 162 |
+
# - "claude-opus-4-5-20251101" # exclude specific models (exact match)
|
| 163 |
+
# - "claude-3-*" # wildcard matching prefix (e.g. claude-3-7-sonnet-20250219)
|
| 164 |
+
# - "*-thinking" # wildcard matching suffix (e.g. claude-opus-4-5-thinking)
|
| 165 |
+
# - "*haiku*" # wildcard matching substring (e.g. claude-3-5-haiku-20241022)
|
| 166 |
+
# cloak: # optional: request cloaking for non-Claude-Code clients
|
| 167 |
+
# mode: "auto" # "auto" (default): cloak only when client is not Claude Code
|
| 168 |
+
# # "always": always apply cloaking
|
| 169 |
+
# # "never": never apply cloaking
|
| 170 |
+
# strict-mode: false # false (default): prepend Claude Code prompt to user system messages
|
| 171 |
+
# # true: strip all user system messages, keep only Claude Code prompt
|
| 172 |
+
# sensitive-words: # optional: words to obfuscate with zero-width characters
|
| 173 |
+
# - "API"
|
| 174 |
+
# - "proxy"
|
| 175 |
+
# cache-user-id: true # optional: default is false; set true to reuse cached user_id per API key instead of generating a random one each request
|
| 176 |
+
# experimental-cch-signing: false # optional: default is false; when true, sign the final /v1/messages body using the current Claude Code cch algorithm
|
| 177 |
+
# # keep this disabled unless you explicitly need the behavior, so upstream seed changes fall back to legacy proxy behavior
|
| 178 |
+
|
| 179 |
+
# Default headers for Claude API requests. Update when Claude Code releases new versions.
|
| 180 |
+
# In legacy mode, user-agent/package-version/runtime-version/timeout are used as fallbacks
|
| 181 |
+
# when the client omits them, while OS/arch remain runtime-derived. When
|
| 182 |
+
# stabilize-device-profile is enabled, OS/arch stay pinned to the baseline values below,
|
| 183 |
+
# while user-agent/package-version/runtime-version seed a software fingerprint that can
|
| 184 |
+
# still upgrade to newer official Claude client versions.
|
| 185 |
+
# claude-header-defaults:
|
| 186 |
+
# user-agent: "claude-cli/2.1.44 (external, sdk-cli)"
|
| 187 |
+
# package-version: "0.74.0"
|
| 188 |
+
# runtime-version: "v24.3.0"
|
| 189 |
+
# os: "MacOS"
|
| 190 |
+
# arch: "arm64"
|
| 191 |
+
# timeout: "600"
|
| 192 |
+
# stabilize-device-profile: false # optional, default false; set true to enable per-auth/API-key fingerprint pinning
|
| 193 |
+
|
| 194 |
+
# Default headers for Codex OAuth model requests.
|
| 195 |
+
# These are used only for file-backed/OAuth Codex requests when the client
|
| 196 |
+
# does not send the header. `user-agent` applies to HTTP and websocket requests;
|
| 197 |
+
# `beta-features` only applies to websocket requests. They do not apply to codex-api-key entries.
|
| 198 |
+
# codex-header-defaults:
|
| 199 |
+
# user-agent: "codex_cli_rs/0.114.0 (Mac OS 14.2.0; x86_64) vscode/1.111.0"
|
| 200 |
+
# beta-features: "multi_agent"
|
| 201 |
+
|
| 202 |
+
# OpenAI compatibility providers
|
| 203 |
+
# openai-compatibility:
|
| 204 |
+
# - name: "openrouter" # The name of the provider; it will be used in the user agent and other places.
|
| 205 |
+
# prefix: "test" # optional: require calls like "test/kimi-k2" to target this provider's credentials
|
| 206 |
+
# base-url: "https://openrouter.ai/api/v1" # The base URL of the provider.
|
| 207 |
+
# headers:
|
| 208 |
+
# X-Custom-Header: "custom-value"
|
| 209 |
+
# api-key-entries:
|
| 210 |
+
# - api-key: "sk-or-v1-...b780"
|
| 211 |
+
# proxy-url: "socks5://proxy.example.com:1080" # optional: per-key proxy override
|
| 212 |
+
# # proxy-url: "direct" # optional: explicit direct connect for this credential
|
| 213 |
+
# - api-key: "sk-or-v1-...b781" # without proxy-url
|
| 214 |
+
# models: # The models supported by the provider.
|
| 215 |
+
# - name: "moonshotai/kimi-k2:free" # The actual model name.
|
| 216 |
+
# alias: "kimi-k2" # The alias used in the API.
|
| 217 |
+
# thinking: # optional: omit to default to levels ["low","medium","high"]
|
| 218 |
+
# levels: ["low", "medium", "high"]
|
| 219 |
+
# # You may repeat the same alias to build an internal model pool.
|
| 220 |
+
# # The client still sees only one alias in the model list.
|
| 221 |
+
# # Requests to that alias will round-robin across the upstream names below,
|
| 222 |
+
# # and if the chosen upstream fails before producing output, the request will
|
| 223 |
+
# # continue with the next upstream model in the same alias pool.
|
| 224 |
+
# - name: "qwen3.5-plus"
|
| 225 |
+
# alias: "claude-opus-4.66"
|
| 226 |
+
# - name: "glm-5"
|
| 227 |
+
# alias: "claude-opus-4.66"
|
| 228 |
+
# - name: "kimi-k2.5"
|
| 229 |
+
# alias: "claude-opus-4.66"
|
| 230 |
+
|
| 231 |
+
# Vertex API keys (Vertex-compatible endpoints, base-url is optional)
|
| 232 |
+
# vertex-api-key:
|
| 233 |
+
# - api-key: "vk-123..." # x-goog-api-key header
|
| 234 |
+
# prefix: "test" # optional: require calls like "test/vertex-pro" to target this credential
|
| 235 |
+
# base-url: "https://example.com/api" # optional, e.g. https://zenmux.ai/api; falls back to Google Vertex when omitted
|
| 236 |
+
# proxy-url: "socks5://proxy.example.com:1080" # optional per-key proxy override
|
| 237 |
+
# # proxy-url: "direct" # optional: explicit direct connect for this credential
|
| 238 |
+
# headers:
|
| 239 |
+
# X-Custom-Header: "custom-value"
|
| 240 |
+
# models: # optional: map aliases to upstream model names
|
| 241 |
+
# - name: "gemini-2.5-flash" # upstream model name
|
| 242 |
+
# alias: "vertex-flash" # client-visible alias
|
| 243 |
+
# - name: "gemini-2.5-pro"
|
| 244 |
+
# alias: "vertex-pro"
|
| 245 |
+
# excluded-models: # optional: models to exclude from listing
|
| 246 |
+
# - "imagen-3.0-generate-002"
|
| 247 |
+
# - "imagen-*"
|
| 248 |
+
|
| 249 |
+
# Amp Integration
|
| 250 |
+
# ampcode:
|
| 251 |
+
# # Configure upstream URL for Amp CLI OAuth and management features
|
| 252 |
+
# upstream-url: "https://ampcode.com"
|
| 253 |
+
# # Optional: Override API key for Amp upstream (otherwise uses env or file)
|
| 254 |
+
# upstream-api-key: ""
|
| 255 |
+
# # Per-client upstream API key mapping
|
| 256 |
+
# # Maps client API keys (from top-level api-keys) to different Amp upstream API keys.
|
| 257 |
+
# # Useful when different clients need to use different Amp accounts/quotas.
|
| 258 |
+
# # If a client key isn't mapped, falls back to upstream-api-key (default behavior).
|
| 259 |
+
# upstream-api-keys:
|
| 260 |
+
# - upstream-api-key: "amp_key_for_team_a" # Upstream key to use for these clients
|
| 261 |
+
# api-keys: # Client keys that use this upstream key
|
| 262 |
+
# - "your-api-key-1"
|
| 263 |
+
# - "your-api-key-2"
|
| 264 |
+
# - upstream-api-key: "amp_key_for_team_b"
|
| 265 |
+
# api-keys:
|
| 266 |
+
# - "your-api-key-3"
|
| 267 |
+
# # Restrict Amp management routes (/api/auth, /api/user, etc.) to localhost only (default: false)
|
| 268 |
+
# restrict-management-to-localhost: false
|
| 269 |
+
# # Force model mappings to run before checking local API keys (default: false)
|
| 270 |
+
# force-model-mappings: false
|
| 271 |
+
# # Amp Model Mappings
|
| 272 |
+
# # Route unavailable Amp models to alternative models available in your local proxy.
|
| 273 |
+
# # Useful when Amp CLI requests models you don't have access to (e.g., Claude Opus 4.5)
|
| 274 |
+
# # but you have a similar model available (e.g., Claude Sonnet 4).
|
| 275 |
+
# model-mappings:
|
| 276 |
+
# - from: "claude-opus-4-5-20251101" # Model requested by Amp CLI
|
| 277 |
+
# to: "gemini-claude-opus-4-5-thinking" # Route to this available model instead
|
| 278 |
+
# - from: "claude-sonnet-4-5-20250929"
|
| 279 |
+
# to: "gemini-claude-sonnet-4-5-thinking"
|
| 280 |
+
# - from: "claude-haiku-4-5-20251001"
|
| 281 |
+
# to: "gemini-2.5-flash"
|
| 282 |
+
|
| 283 |
+
# Global OAuth model name aliases (per channel)
|
| 284 |
+
# These aliases rename model IDs for both model listing and request routing.
|
| 285 |
+
# Supported channels: gemini-cli, vertex, aistudio, antigravity, claude, codex, qwen, iflow, kimi.
|
| 286 |
+
# NOTE: Aliases do not apply to gemini-api-key, codex-api-key, claude-api-key, openai-compatibility, vertex-api-key, or ampcode.
|
| 287 |
+
# NOTE: Because aliases affect the merged /v1 model list and merged request routing, overlapping
|
| 288 |
+
# client-visible names can become ambiguous across providers. /api/provider/{provider}/... helps
|
| 289 |
+
# you select the protocol surface, but inference backend selection can still follow the resolved
|
| 290 |
+
# model/alias. For strict backend pinning, use unique aliases/prefixes or avoid overlapping names.
|
| 291 |
+
# You can repeat the same name with different aliases to expose multiple client model names.
|
| 292 |
+
# oauth-model-alias:
|
| 293 |
+
# gemini-cli:
|
| 294 |
+
# - name: "gemini-2.5-pro" # original model name under this channel
|
| 295 |
+
# alias: "g2.5p" # client-visible alias
|
| 296 |
+
# fork: true # when true, keep original and also add the alias as an extra model (default: false)
|
| 297 |
+
# vertex:
|
| 298 |
+
# - name: "gemini-2.5-pro"
|
| 299 |
+
# alias: "g2.5p"
|
| 300 |
+
# aistudio:
|
| 301 |
+
# - name: "gemini-2.5-pro"
|
| 302 |
+
# alias: "g2.5p"
|
| 303 |
+
# antigravity:
|
| 304 |
+
# - name: "gemini-3-pro-high"
|
| 305 |
+
# alias: "gemini-3-pro-preview"
|
| 306 |
+
# claude:
|
| 307 |
+
# - name: "claude-sonnet-4-5-20250929"
|
| 308 |
+
# alias: "cs4.5"
|
| 309 |
+
# codex:
|
| 310 |
+
# - name: "gpt-5"
|
| 311 |
+
# alias: "g5"
|
| 312 |
+
# qwen:
|
| 313 |
+
# - name: "qwen3-coder-plus"
|
| 314 |
+
# alias: "qwen-plus"
|
| 315 |
+
# iflow:
|
| 316 |
+
# - name: "glm-4.7"
|
| 317 |
+
# alias: "glm-god"
|
| 318 |
+
# kimi:
|
| 319 |
+
# - name: "kimi-k2.5"
|
| 320 |
+
# alias: "k2.5"
|
| 321 |
+
|
| 322 |
+
# OAuth provider excluded models
|
| 323 |
+
# oauth-excluded-models:
|
| 324 |
+
# gemini-cli:
|
| 325 |
+
# - "gemini-2.5-pro" # exclude specific models (exact match)
|
| 326 |
+
# - "gemini-2.5-*" # wildcard matching prefix (e.g. gemini-2.5-flash, gemini-2.5-pro)
|
| 327 |
+
# - "*-preview" # wildcard matching suffix (e.g. gemini-3-pro-preview)
|
| 328 |
+
# - "*flash*" # wildcard matching substring (e.g. gemini-2.5-flash-lite)
|
| 329 |
+
# vertex:
|
| 330 |
+
# - "gemini-3-pro-preview"
|
| 331 |
+
# aistudio:
|
| 332 |
+
# - "gemini-3-pro-preview"
|
| 333 |
+
# antigravity:
|
| 334 |
+
# - "gemini-3-pro-preview"
|
| 335 |
+
# claude:
|
| 336 |
+
# - "claude-3-5-haiku-20241022"
|
| 337 |
+
# codex:
|
| 338 |
+
# - "gpt-5-codex-mini"
|
| 339 |
+
# qwen:
|
| 340 |
+
# - "vision-model"
|
| 341 |
+
# iflow:
|
| 342 |
+
# - "tstars2.0"
|
| 343 |
+
# kimi:
|
| 344 |
+
# - "kimi-k2-thinking"
|
| 345 |
+
|
| 346 |
+
# Optional payload configuration
|
| 347 |
+
# payload:
|
| 348 |
+
# default: # Default rules only set parameters when they are missing in the payload.
|
| 349 |
+
# - models:
|
| 350 |
+
# - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
|
| 351 |
+
# protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
|
| 352 |
+
# params: # JSON path (gjson/sjson syntax) -> value
|
| 353 |
+
# "generationConfig.thinkingConfig.thinkingBudget": 32768
|
| 354 |
+
# default-raw: # Default raw rules set parameters using raw JSON when missing (must be valid JSON).
|
| 355 |
+
# - models:
|
| 356 |
+
# - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
|
| 357 |
+
# protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
|
| 358 |
+
# params: # JSON path (gjson/sjson syntax) -> raw JSON value (strings are used as-is, must be valid JSON)
|
| 359 |
+
# "generationConfig.responseJsonSchema": "{\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"string\"}}}"
|
| 360 |
+
# override: # Override rules always set parameters, overwriting any existing values.
|
| 361 |
+
# - models:
|
| 362 |
+
# - name: "gpt-*" # Supports wildcards (e.g., "gpt-*")
|
| 363 |
+
# protocol: "codex" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
|
| 364 |
+
# params: # JSON path (gjson/sjson syntax) -> value
|
| 365 |
+
# "reasoning.effort": "high"
|
| 366 |
+
# override-raw: # Override raw rules always set parameters using raw JSON (must be valid JSON).
|
| 367 |
+
# - models:
|
| 368 |
+
# - name: "gpt-*" # Supports wildcards (e.g., "gpt-*")
|
| 369 |
+
# protocol: "codex" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
|
| 370 |
+
# params: # JSON path (gjson/sjson syntax) -> raw JSON value (strings are used as-is, must be valid JSON)
|
| 371 |
+
# "response_format": "{\"type\":\"json_schema\",\"json_schema\":{\"name\":\"answer\",\"schema\":{\"type\":\"object\"}}}"
|
| 372 |
+
# filter: # Filter rules remove specified parameters from the payload.
|
| 373 |
+
# - models:
|
| 374 |
+
# - name: "gemini-2.5-pro" # Supports wildcards (e.g., "gemini-*")
|
| 375 |
+
# protocol: "gemini" # restricts the rule to a specific protocol, options: openai, gemini, claude, codex, antigravity
|
| 376 |
+
# params: # JSON paths (gjson/sjson syntax) to remove from the payload
|
| 377 |
+
# - "generationConfig.thinkingConfig.thinkingBudget"
|
| 378 |
+
# - "generationConfig.responseJsonSchema"
|