CliRelay Documentation

repository·main·Indexed 21 days ago

https://github.com/kittors/clirelay

A production-grade unified proxy server for AI CLI tools that consolidates multiple AI subscriptions (OpenAI, Claude, Gemini, etc.) into a single managed API endpoint. It features smart load balancing, auto failover, request logging via PostgreSQL, and a web-based management panel. Supports a wide range of providers including Vertex, Bedrock, and Ollama Cloud, providing OpenAI-compatible endpoints for tools like Claude Code and Gemini CLI.

Tokens
41.3K
Snippets
102
Records
164
Agent score
74%

What's inside CliRelay

  1. What is CliRelay?

    main

    CliRelay is a unified proxy server designed for AI CLI tools. It allows you to use existing AI subscriptions (like Gemini, Claude, OpenAI, etc.) through a single, managed API layer.

    By pointing your AI coding tools (e.g., Claude Code, Gemini CLI, OpenAI Codex, Ollama, etc.) to the CliRelay endpoint, you gain access to advanced features like:

    • Unified Endpoint: Access multiple providers via http://localhost:8317.
    • Smart Load Balancing: Round-robin or fill-first scheduling across multiple API keys.
    • Auto Failover: Automatic switching to backup channels when quotas are hit or errors occur.
    • Request Logging: Full capture of requests, responses, and token usage in PostgreSQL.
    • API Key Management: Create and manage keys with custom quotas and rate limits.
    • Management Panel: A web-based UI at /manage for visual configuration.

    Architecture Overview:

    • Upstream: Connects to providers like Google Gemini, OpenAI, Anthropic, Vertex, Bedrock, etc.
    • Proxy Core: Acts as the intermediary at :8317.
    • Clients: AI tools like Claude Code, Gemini CLI, or any OpenAI-compatible client connect to CliRelay.
    ┌───────────────────────┐         ┌──────────────┐         ┌────────────────────┐
    │   AI Coding Tools     │         │              │         │  Upstream Providers │
    │                       │         │              │ ──────▶ │  Google Gemini      │
    │  Claude Code          │ ──────▶ │   CliRelay   │         │  OpenAI / Codex     │
    │  Gemini CLI           │         │   :8317      │         │  Anthropic Claude   │
    │  OpenAI Codex         │         │              │         │  Qwen / iFlow       │
    │  Amp CLI / IDE        │         └──────────────┘         │  Antigravity/xAI    │
    │  Any OAI-compatible   │                                  │  Vertex / Bedrock   │
    └───────────────────────┘                                  │  OpenCode/Cline     │
                                                               │  Ollama / Amp       │
                                                               └────────────────────┘
  2. Core Features of CliRelay

    main

    CliRelay provides several key capabilities for managing AI traffic:

    Multi-Provider Proxy Engine

    • Unified Endpoint: A single endpoint (default http://localhost:8317) handles multiple providers including Gemini, Claude, Codex, Qwen, Vertex, Bedrock, and more.
    • Smart Load Balancing: Uses polling or priority-based scheduling across multiple API keys.
    • Routing: Supports grouping channels and custom path namespaces for teams or specific business logic.
    • Automatic Failover: Automatically switches to backup channels when a quota is exhausted or an error occurs.
    • Multimodal & Streaming: Supports text, images, function calling, and SSE streaming.
    • OpenAI Compatibility: Works with any upstream service following the OpenAI Chat Completions protocol.

    Request Logging & Monitoring

    • Full Capture: Logs timestamps, models, tokens (input/output/reasoning/cache), latency, status, and source channels to PostgreSQL.
    • Message Storage: Stores compressed request/response bodies with configurable retention policies.
    • Health Scoring: Provides a real-time 0–100 health score based on success rates, latency, and error patterns.
    • Real-time Monitoring: Uses WebSockets to push system stats (CPU, memory, network I/O, etc.).

    API Key & Permission Management

    • CRUD Operations: Create, edit, and delete API keys with custom names and enable/disable toggles.
    • Quota & Rate Limiting: Set maximum token/request quotas and per-key rate limits (RPM/RPH).
    • Access Control: Assign keys to specific users/teams and restrict their access to certain channel groups or models.
    • Self-Service: Provides a public query page for end-users to check their own usage and logs without logging in.

    Channel Management

    • Provider Organization: Manage channels by type (Gemini, Claude, Vertex, etc.).
    • Customization: Set custom names, proxy URLs, headers, and model alias mappings.
    • Latency Tracking: Monitors average latency_ms per channel.
    • Model Control: Exclude specific models from certain channels (e.g., blocking expensive models on backup keys).
  3. Manage credentials and transport

    main

    Injecting custom HTTP Transports

    You can inject a custom *http.Transport (for example, to use a specific proxy) on a per-account basis using Manager.SetRoundTripperProvider.

    core.SetRoundTripperProvider(myProvider) // Returns transport per account

    Injecting credentials into requests

    Credentials can be injected into headers in two ways:

    1. Via Executor: Implement the PrepareRequest method in your ProviderExecutor.
    2. Via Manager: Use Manager.InjectCredentials(req, authID) to manually inject headers for a specific authentication ID.
  4. Database migration rules and constraints

    main

    When performing migrations in CliRelay, the following technical rules and safety constraints apply:

    Data Copying Rules

    • No SELECT *: Every table uses a stable column list.
    • Ordering: Data is sorted by primary key or unique key. Tables without auto-incrementing primary keys are sorted by a combination of primary key columns.
    • Large Objects: Large BLOB tables (like request_log_content) are copied in separate batches.
    • Dependencies: Foreign key tables are copied following dependency order (parent tables before child tables).
    • Dialect Safety: PostgreSQL schema names are quoted safely; MySQL tables and columns use backticks.

    Cutover and Configuration Rules

    • YAML Configuration: If the database is managed via config.yaml, the backend will attempt to write the new configuration directly.
    • Environment Variables: If the database is configured via environment variables, the backend cannot modify them; it will instead provide instructions on how to update the deployment configuration.
    • Service Restarts: If the service does not support hot-swapping connections, the system will mark the migration as "requires restart" and will not restart the service automatically.
    • Safety: Any failed cutover attempt will not delete the source database.
  5. Understand Model ID and Path Terminology

    main

    To correctly interact with CliRelay, distinguish between these key concepts:

    • Upstream Model ID: The original model name used by the provider (e.g., the real name used by an API key or OAuth account).
    • External Model ID: The model value sent in a client request. This is what users see in /models or management tables. It may be the original name, an alias, or a prefixed name.
    • Alias: A mapping (name -> alias) where a user requests an alias and the execution layer maps it back to the original name.
    • Prefix Model: A model ID generated by adding a prefix to the model name (e.g., prefix/model).
    • Default Path: Public API paths without custom prefixes, such as /v1/chat/completions or /v1/images/generations.
    • Custom Path: Paths generated by channel groups or path-routes, such as /{group}/v1/... or multi-segment custom paths.
    • Path Family: A group of interfaces sharing the same protocol (e.g., OpenAI v1, Claude Messages, Gemini v1beta).
  6. Access the Management API when embedded

    main

    When the proxy is embedded, management endpoints are mounted under /v0/management on the configured port. These endpoints are only available if:

    1. remote-management.secret-key is defined in your config.yaml.
    2. remote-management.allow-remote is set to true in your config.yaml.
  7. Manage API Keys and Access

    main

    CliRelay provides robust management for API keys and user access:

    • API Key CRUD: Create, edit, and delete API keys via the Management API. Each key can have a custom name, notes, and an independent enable/disable toggle.
    • Per-Key Quotas: Set maximum token or request quotas per key with automatic enforcement.
    • Rate Limiting: Implement per-key rate limiting (requests per minute/hour).
    • Team Permissions: Assign API keys to users or groups with scoped channel access and model permissions.
    • Key Masking: API keys are masked (e.g., sk-***xxx) in the UI and logs for security.
    • Public Lookup Page: End users can query their own usage stats and request logs via a public self-service page without requiring a login.
  8. Understand the AuthUpdate contract and Watcher behavior

    main

    The watcher.AuthUpdate struct is the data contract used to communicate credential changes.

    Contract Details

    • Action: Can be add, modify, or delete.
    • ID: The unique identifier for the credential.
    • Auth: For add or modify actions, this contains a full clone of the Auth object. For delete actions, this field can be omitted.

    Watcher Logic

    • Snapshot Comparison: The watcher maintains a currentAuths snapshot. When a file or configuration event occurs, it rebuilds the snapshot, compares it to the old one, and generates a minimal list of AuthUpdate objects.
    • Event Merging: Updates are merged based on the credential ID. If a single credential undergoes multiple changes in a short period (e.g., a write followed by a delete), the watcher only emits the final state (e.g., a single delete action).
    • Asynchronous Dispatch: The watcher uses an internal asynchronous loop. Producers append events to an in-memory buffer and wake the dispatch goroutine, ensuring that file event threads are not blocked even if the channel is temporarily full.
  9. CliRelay Architecture and Tech Stack

    main

    CliRelay uses a modern stack designed for production-grade reliability:

    LayerTechnology
    RuntimeGo 1.26, Gin, Docker Compose
    Data (Source of Truth)PostgreSQL 15+ with Ent ORM
    Runtime StateRedis 7+ (used for caching, locks, rate limiting, queues, and snapshots)
    Auth/Config StorageLocal files, PostgreSQL, Git, or S3-compatible object storage
    Proxy CoreOpenAI Chat Completions, Anthropic Messages, Gemini, and provider-specific executors
    OperationsBubble Tea / Lipgloss TUI, /manage Web Panel, updater sidecar
    ObservabilityPostgreSQL request logs, compressed message bodies, WebSocket system stats
  10. How quota recovery is probed and reconciled

    main

    CliRelay includes a background mechanism to detect when exhausted quotas become available again.

    The Recovery Workflow:

    1. Background Loop: The auth manager runs an automatic refresh loop that calls checkQuotaRecoveries().
    2. Probing: For auths currently in a cooldown state, the system triggers a probe if the executor supports the QuotaRecoveryProber interface. For example, the Codex executor probes GET https://chatgpt.com/backend-api/wham/usage and parses fields like allowed, limit_reached, and reset_at.
    3. Reconciliation: If the probe indicates the quota has been restored, the system executes ReconcileQuota(), which clears the quota state, updates NextRecoverAt, and restores the registry's quota/suspend status, making the auth available for scheduling again.
  11. Understand model discovery via path scopes

    main

    Model availability is determined by the specific path used to query the /models endpoint. The set of models returned depends on the path scope, your API Key, and your channel group permissions.

    Available Discovery Scopes:

    • GET /v1/models: Models available via the default OpenAI/Claude v1 paths.
    • GET /v1beta/models: Models available via the default Gemini v1beta paths.
    • GET /{group}/v1/models: Models available through a specific channel group path.
    • GET /{custom/path}/v1/models: Models available through a specific custom path-route.
    • GET /{group}/v1beta/models: Gemini v1beta models available through a specific channel group.
    • GET /{custom/path}/v1beta/models: Gemini v1beta models available through a specific custom path.
  12. How high-frequency changes are handled

    main

    The system uses a two-tier buffering strategy to handle high-frequency credential changes and prevent backpressure from blocking the watcher or the service.

    Two-Tier Buffering

    1. Dispatch Buffer (Watcher Side): Uses a combination of a map and an ordered slice to merge duplicate events for the same credential. This continues until the consumer processes the updates.
    2. Service Channel (Service Side): A buffered channel with a capacity of 256. The consumer uses a "drain" logic to actively pull all pending events from the channel, reducing context-switching overhead.

    Resilience

    If the channel remains under high pressure for an extended period, the buffers continue to merge events. Once the consumer recovers, it applies the latest state in a single batch, avoiding the processing of redundant intermediate states.