RelayPlane Proxy

repository·main·Indexed 41 days ago

https://github.com/relayplane/proxy

An open source cost intelligence proxy for AI agents that monitors, attributes, and controls LLM costs. It acts as a drop-in replacement for Anthropic and OpenAI base URLs to provide real-time cost intelligence, budget caps, and smart model routing based on task complexity. Includes a CLI for managing runs, a local dashboard, and support for 11 providers.

Tokens
33.5K
Snippets
112
Records
154
Agent score
51%

What's inside RelayPlane

  1. Use Complexity-Based Routing

    main

    Complexity-Based Routing automatically classifies incoming requests into simple, moderate, or complex tiers based on prompt length, token patterns, and tool usage. Each tier can be mapped to a specific model to optimize for cost or performance.

    Classification Logic:

    • Simple: Short prompts, basic Q&A, or simple code tasks.
    • Moderate: Multi-step reasoning, code reviews, or analysis with context.
    • Complex: Architecture decisions, large codebases, tasks with many tools, or long prompts containing evaluation/comparison language.

    Classification happens locally; prompt content is never sent to the classifier.

    {
      "routing": {
        "complexity": {
          "enabled": true,
          "simple": "claude-3-5-haiku-latest",
          "moderate": "claude-sonnet-4-20250514",
          "complex": "claude-opus-4-20250514"
        }
      }
    }
  2. Understand the npm publish source of truth for @relayplane/proxy

    main

    The directory packages/proxy within the turleydesigns/relayplane-workflows repository is the single source of truth for both the @relayplane/proxy npm package and the github.com/RelayPlane/proxy GitHub repository.

    Edits made to files within packages/proxy/ (such as README.md) are automatically propagated to both destinations via a CI/CD workflow. There is no requirement for manual copying or syncing between these destinations; the automation handles the build, versioning, npm publishing, and GitHub mirroring.

  3. How the RelayPlane proxy works with Claude Code

    main

    RelayPlane acts as a local HTTP proxy for Claude Code. To use it, point Claude Code to localhost:4100 by setting the ANTHROPIC_BASE_URL environment variable.

    The Proxy Lifecycle:

    1. Intercepts: Captures LLM API requests from Claude Code.
    2. Classifies: Uses heuristics (token count, prompt patterns, keywords) to determine task complexity without making extra LLM calls.
    3. Routes: Sends the request to a configured model based on your routing rules. Note: The default behavior is passthrough; requests go to the model originally requested by the agent unless explicit routing (like cascade or complexity-based routing) is enabled.
    4. Forwards: Sends the request directly to the LLM provider. Your prompts are sent straight to the provider and do not pass through RelayPlane servers.
    5. Records: Logs token counts, latency, and cost locally for viewing in your dashboard.
  4. Proposed header for complexity-based routing

    main

    A proposed mechanism for external clients to influence routing is via the X-RelayPlane-Complexity HTTP header.

    Implementation Details

    • Accepted Values: simple, moderate, or complex.
    • Behavior: If the header is present, the value should be validated and fed into the local complexity variable before tier selection and into resolvePolicy.
    • Caching Warning: Because response cache lookups currently hash the request body and not the headers, any implementation using this header must ensure the override is part of the response cache identity to prevent a complex request from incorrectly reusing a simple-tier cached response.
  5. Configure credential pools for RelayPlane Proxy

    main

    RelayPlane supports a credentialPool to manage multiple accounts (e.g., Account A and Account B) for automatic failover and load balancing.

    Account Priority and Setup

    • Account A (Priority 1): Typically the primary login located at ~/.claude/.credentials.json. It is treated as refresh:false and is not managed by RelayPlane.
    • Account B (Priority 2): A secondary account located in a dedicated file at ~/.relayplane/account-b.credentials.json. It is treated as refresh:true, meaning RelayPlane will manage its OAuth refresh loop.

    Configuration Integration

    To enable pooling, you must merge a credentialPool array into your RelayPlane configuration file. When configuring paths within the JSON, use the absolute path to your $HOME directory.

  6. Handle Anthropic Auth passthrough (Claude Max users)

    main

    RelayPlane supports Anthropic subscription tokens (starting with sk-ant-oat*) via the x-api-key header.

    Key Authentication Details:

    • Header Usage: All Anthropic token types (sk-ant-api* and sk-ant-oat*) must be sent via the x-api-key header. The proxy does not use Authorization: Bearer for Anthropic requests.
    • Subscription Validation: The proxy automatically forwards user-agent and x-app headers required by Anthropic to validate Claude Max subscriptions.
    • Configuration: No special configuration is required for standard passthrough of these tokens. For advanced hybrid authentication (using MAX tokens for expensive models and standard keys for cheap ones), refer to the Configuration reference.
  7. Use Cascade Mode for cost savings

    main

    Cascade Mode starts with the cheapest model in a provided list and escalates to more expensive models only when the response indicates uncertainty, refusal, or an error. This provides a safety net while minimizing costs.

    escalateOn options:

    • uncertainty: Triggers on hedging language (e.g., "I'm not sure").
    • refusal: Triggers when the model refuses to assist.
    • error: Triggers on outright request failure.

    maxEscalations: Caps the number of retries with more expensive models (Default: 1).

    {
      "routing": {
        "mode": "cascade",
        "cascade": {
          "enabled": true,
          "models": [
            "claude-3-5-haiku-latest",
            "claude-sonnet-4-20250514",
            "claude-opus-4-20250514"
          ],
          "escalateOn": "uncertainty",
          "maxEscalations": 2
        }
      }
    }
  8. Stage and run a dev instance with credential pooling

    main

    To test credential pooling without affecting your live production instance (usually running on port 4100), you can spin up a development instance on port 4101 using a scoped configuration file.

    1. Set the RELAYPLANE_CONFIG_PATH environment variable to a new file path.
    2. Copy your existing live config to this new path.
    3. Manually edit the new config to include the credentialPool block (merging it from an example config).
    4. Start the proxy on port 4101.

    On successful boot, the logs should indicate: [RelayPlane] Credential pool: 2 account(s) active (tenant=local), 1 managed w/ OAuth refresh.

    export RELAYPLANE_CONFIG_PATH="$HOME/.relayplane/config.4101.json"
    # start from a copy of the live config, then add the credentialPool block:
    cp "$HOME/.relayplane/config.json" "$RELAYPLANE_CONFIG_PATH"
    
    # (merge the credentialPool array into $RELAYPLANE_CONFIG_PATH, paths = real $HOME)
    RELAYPLANE_PORT=4101 node dist/cli.js start
  9. Apply Configuration Changes via Atomic Merge Script

    main

    To update your RelayPlane configuration with a proposed JSON block (e.g., adding new credentials or budget settings) while preserving existing settings, use the following atomic merge procedure. This script creates a backup, performs a recursive merge using jq, validates the resulting configuration, and replaces the live config.

    Warning: Ensure you have reviewed the proposal.json and that you are running this in the correct directory. This script assumes your config is at /home/coder/.relayplane/config.json.

    cd /home/coder/relayplane-workflows/.phase1-local
    bash <<'APPLY'
    set -euo pipefail
    cfg=/home/coder/.relayplane/config.json
    proposal=packages/proxy/staged/provider-pool-budget-alerts.proposed.json
    backup="$cfg.phase1-backup.$(date -u +%Y%m%dT%H%M%SZ)"
    cp -p -- "$cfg" "$backup"
    merged=$(mktemp /home/coder/.relayplane/config.json.merge.XXXXXX)
    trap 'rm -f -- "$merged"' EXIT
    jq -s '.[0] * .[1]' "$cfg" "$proposal" > "$merged"
    jq -e '.budget.enabled == true and .budget.onBreach == "block" and (.credentialPool | length) == 2' "$merged" >/dev/null
    chmod 600 "$merged"
    mv -- "$merged" "$cfg"
    trap - EXIT
    APPLY
  10. Enable credential pooling for live production sessions

    main

    Once testing is complete, you can enable pooling for your live service and interactive Claude Code sessions.

    1. Update Live Config: Merge the credentialPool block into your production config at $HOME/.relayplane/config.json.
    2. Restart Service: Restart the relayplane-proxy system service.
    3. Route Interactive Sessions: To make your interactive Claude Code sessions use the proxy (enabling pooling and failover), set the ANTHROPIC_BASE_URL environment variable in your shell profile or tmux environment.

    Note: To roll back, remove the credentialPool key from the config and restart the proxy. The proxy will return to single-token behavior.

    # 4b. Restart the live service:
    sudo systemctl restart relayplane-proxy
    
    # 4c. Point interactive Claude Code sessions at the proxy:
    export ANTHROPIC_BASE_URL=http://localhost:4100
  11. Configure Auth for Auto-Routing (Max Plan Users)

    main

    If you are an Anthropic Max plan user using OAuth tokens (sk-ant-oat*), auto-routing to Haiku requires an additional configuration step. Anthropic does not support OAuth for the Haiku model.

    To ensure the proxy can route simple requests to Haiku, you must provide a standard API key (sk-ant-api03-*) via the ANTHROPIC_API_KEY environment variable. Without this, the proxy cannot use Haiku and will fall back to Sonnet for simple tasks.

    Your AuthSimple (Haiku)Moderate (Sonnet)Complex (Opus)
    API key only✅ API key✅ API key✅ API key
    Max/OAuth only❌ Not supported✅ OAuth✅ OAuth
    Max/OAuth + API key✅ API key✅ OAuth✅ OAuth
  12. Configure RelayPlane via config.json

    main

    RelayPlane reads its configuration from ~/.relayplane/config.json. You can override this default location by setting the RELAYPLANE_CONFIG_PATH environment variable.

    All configuration fields are optional and use a deep merge strategy with sensible defaults. A minimal configuration structure looks like this:

    {
      "enabled": true,
      "modelOverrides": {},
      "routing": {
        "mode": "cascade",
        "cascade": { "enabled": true },
        "complexity": { "enabled": true }
      }
    }