Skip to main content

Composite Variants

Composite variants let you assign different CLIProxy providers to each model tier (opus/sonnet/haiku). For example: Codex for opus, Gemini for sonnet, AGY for haiku — each with its own fallback and thinking budget.

Quick Start

1

Create via wizard

ccs cliproxy create --composite
2

Or via dashboard

Navigate to Dashboard → CLIProxy → Create Variant → Composite
3

Use the variant

ccs <variant-name> "your prompt"

How It Works

  • Each tier (opus/sonnet/haiku) maps independently to a provider + model pair
  • default_tier determines which tier ANTHROPIC_MODEL resolves to when no tier is specified
  • Routing uses the root CLIProxy URL with model-based routing (not provider-specific URLs)
  • Settings written to ~/.ccs/composite-<name>.settings.json

Type Definition

interface CompositeTierConfig {
  provider: CLIProxyProvider;
  model: string;
  account?: string;
  fallback?: { provider: CLIProxyProvider; model: string; account?: string };
  thinking?: string; // 'xhigh' | 'high' | 'medium' | 'off' | numeric string
}

interface CompositeVariantConfig {
  type: 'composite';
  default_tier: 'opus' | 'sonnet' | 'haiku';
  tiers: {
    opus: CompositeTierConfig;
    sonnet: CompositeTierConfig;
    haiku: CompositeTierConfig;
  };
}

CLI Commands

ccs cliproxy create --composite    # Create with interactive wizard
ccs cliproxy edit <name>           # Edit existing variant
ccs cliproxy remove <name>         # Remove variant
ccs cliproxy list                  # List all variants (shows type column)
ccs <variant-name> "prompt"        # Use the variant

Fallback Logic

Each tier supports an optional fallback block. On provider error (4xx/5xx, quota exceeded, rate limit, ECONNREFUSED):
  1. Detect which tier failed via model name in stderr
  2. Apply fallback provider + model for that tier only
  3. Retry the request with the updated config
Circular fallback is blocked — a fallback cannot point to the same provider + model as the primary.
Example tier with fallback:
cliproxy:
  variants:
    my-composite:
      type: composite
      default_tier: sonnet
      tiers:
        opus:
          provider: codex
          model: claude-opus-4-5
          fallback:
            provider: agy
            model: claude-opus-4-5
        sonnet:
          provider: gemini
          model: claude-sonnet-4-5
        haiku:
          provider: agy
          model: claude-haiku-3-5

Per-Tier Thinking

Override the thinking budget independently per tier via thinking in CompositeTierConfig. Priority (highest to lowest):
  1. CLI --thinking flag
  2. Per-tier thinking in composite config
  3. Global thinking config
  4. Provider defaults
Valid values: xhigh, high, medium, off, or a numeric token budget string.

Dashboard CRUD

MethodEndpointNotes
POST/api/cliproxytype: composite, all 3 tiers required
PUT/api/cliproxy/:namePartial tier update supported
DELETE/api/cliproxy/:nameChecks for active sessions before removing
GET/api/cliproxyLists all variants with type, tiers, and port

Validation Rules

  • All 3 tiers required on create; partial updates allowed on edit
  • Each tier must have a valid provider and non-empty model
  • Circular fallback detection enforced at save time
  • kiro and ghcp providers require the Plus backend
Switch to the Plus backend if you need kiro or ghcp in any tier: set cliproxy.backend: plus in ~/.ccs/config.yaml.

Storage

PathPurpose
~/.ccs/config.yamlVariant definition under cliproxy.variants[name]
~/.ccs/composite-<name>.settings.jsonGenerated runtime settings file