Free Claude Code (FCC)

repository·main·Indexed 13 days ago

https://github.com/alishahryar1/free-claude-code

A middleware proxy layer that connects coding agents like Claude Code, Codex, and Pi to OpenAI-compatible AI providers. It supports local providers such as Ollama, LM Studio, and llama.cpp, as well as cloud providers including NVIDIA NIM, OpenRouter, Groq, and Google AI Studio. Version 4.20.0 includes an Admin UI for model routing, reasoning behavior control, and integration wrappers for various IDEs and agents.

Tokens
38K
Snippets
114
Records
173
Agent score
99%

What's inside Free Claude Code

  1. Override model tiers with specific routing

    main

    By default, the MODEL setting is used for every request. However, you can override specific Claude Code tiers by selecting different models for them in the Admin UI. If you select None, the tier will fall back to the global MODEL setting.

    Available tier overrides:

    • MODEL_FABLE
    • MODEL_OPUS
    • MODEL_SONNET
    • MODEL_HAIKU
  2. Understand Smoke Test Failure Classes

    main

    Smoke test results are stored in .smoke-results/. Failures and skips are categorized into the following classes:

    • product_failure: The application accepted the scenario but returned the wrong shape, crashed, leaked state, or violated the product contract. (Failure)
    • harness_bug: The smoke test or driver made an invalid assumption. (Failure)
    • missing_env: Required credentials, binary, provider config, or opt-in flag is absent. (Skip, unless the provider was explicitly selected in FCC_SMOKE_PROVIDER_MATRIX)
    • upstream_unavailable: A real provider or bot API is not reachable. (Skip, unless the provider was explicitly selected in FCC_SMOKE_PROVIDER_MATRIX)
    • probe_timeout: The smoke driver reached the target, but the CLI/probe did not complete within the timeout. (Skip, unless the provider was explicitly selected in FCC_SMOKE_PROVIDER_MATRIX)
    • target_disabled: Skipped because FCC_SMOKE_TARGETS intentionally selected a different target. (Skip)
  3. Understand Protocol Conversion and Streaming Contracts

    main

    The system uses a layered architecture to convert between Anthropic-style protocols and OpenAI-compatible upstreams.

    • Anthropic Protocol Ownership: src/free_claude_code/core/anthropic/ manages Anthropic-side behavior, including models.py (Messages and token-count wire requests), tool schema/result handling, and thinking block handling.
    • Streaming Lifecycle: Managed via src/free_claude_code/core/anthropic/streaming, which handles the neutral stream ledger, SSE emission, and tool repair.
    • Role Mapping: When converting to OpenAI-compatible upstreams, the system maps top-level system content to leading system messages and converts inline system content into ordered user turns. It ensures strict chat templates by coalescing adjacent user content and using whitespace-only assistant boundaries to close tool rounds.
    • Image Conversion: Anthropic base64 and URL image sources are converted to OpenAI image_url content parts. This is a pure protocol operation and does not fetch remote content.
  4. Configure Observability and Safety Settings

    main

    The system uses structured trace events (via src/free_claude_code/core/trace.py) to track activity across ingress, routing, provider, egress, messaging, and CLI execution.

    Logging Behavior:

    • JSON file sink: Defaults to INFO. Detailed request traces require DEBUG level.
    • Log Rotation: The active server log rotates at 50 MB, retaining five files (approx. 300 MB total).
    • Privacy: API payloads and SSE events are not logged raw by default. Trace helpers automatically redact values under keys resembling API keys, authorization tokens, or secrets.

    Security Boundaries:

    • Admin Access: Admin UI and APIs are restricted to loopback-only.
    • Proxy Auth: Controlled via the ANTHROPIC_AUTH_TOKEN environment variable.
    • Web Fetching: web_fetch egress blocks private network targets by default unless explicitly allowed.
  5. How reasoning policy and budget are managed

    main

    Reasoning is managed via a provider-neutral ReasoningPolicy defined in core/reasoning.py. This policy consists of three components:

    1. control: The state of reasoning (provider default, explicitly off, or explicitly on).
    2. effort: The client's requested effort level.
    3. budget_tokens: An exact positive integer budget if supplied.

    The FCC Numeric Scale: When a provider requires a named effort but the client provides a numeric budget, FCC maps the budget to its internal scale:

    • minimal / low: 512 tokens
    • medium: 1024 tokens
    • high: 2048 tokens
    • xhigh: 4096 tokens
    • max: 8192 tokens

    Rules for Implementation:

    • No Model-Name Inspection: Never inspect upstream model names to decide reasoning behavior; use the policy.
    • Single Encoder: Each provider profile must have exactly one reasoning encoder responsible for writing the provider's specific computation and reasoning-output fields.
    • Precedence: Exact client budgets take precedence over named effort scales.
    • Reasoning Replay: Replaying reasoning history is a separate decision from the computation control. Profiles must explicitly choose how to handle prior state (e.g., <think> tags, native reasoning_content, or no replay).
  6. How the Provider Architecture works

    main

    The provider system is split into three distinct layers to separate metadata, runtime lifecycle, and transport implementation:

    1. Metadata Layer (config/provider_catalog.py): A centralized, neutral catalog of ProviderDescriptor objects. It defines provider IDs, display names, authentication types, locality, and configuration requirements (like environment variables or base URLs). It does not select the actual adapter.
    2. Runtime Layer (providers/runtime/): Manages the lifecycle of a provider generation. It handles construction policies, lazy instantiation, admission controllers (rate limiting/concurrency), and cleanup. The ProviderRuntimeManager manages process-lifetime state, while ProviderRuntime manages single-generation resources.
    3. Implementation Layer (providers/): Contains the actual adapters. Most providers use the OpenAIChatProvider (an OpenAI-compatible implementation), while specialized providers are created only for upstreams with unique behaviors (e.g., Groq's reasoning vocabulary or Google's extra_body construction).

    Key Abstractions:

    • ProviderConfig: A frozen internal value containing shared settings like API keys, base URLs, and timeouts.
    • BaseProvider: The abstract base defining the contract for list_model_infos(), preflight_stream(), and stream_response().
    • ProviderModelInfo: An immutable value representing model capabilities, owned by the application layer but populated by provider-specific modules.
  7. Handle Failures and Diagnostics

    main

    The project uses a protocol-neutral error handling system to ensure consistency across different providers.

    • Core Failures: src/free_claude_code/core/failures.py defines FailureKind and ExecutionFailure. ExecutionFailure is the exception propagated through async iterators and contains immutable semantic fields.
    • Diagnostics: src/free_claude_code/core/diagnostics.py handles error body extraction, credential redaction, and safe traceback formatting.
    • Provider Failure Policies: src/free_claude_code/providers/failure_policy.py classifies raw OpenAI SDK and httpx exceptions. While concrete adapters can provide narrow semantic overrides for specific upstream quirks, the shared policy owns the canonical meaning and wording used for retry qualification.
  8. Understand the package architecture and boundaries

    main

    The codebase is organized into specific functional boundaries to maintain a least-privilege dependency policy:

    PackageResponsibility
    applicationDependency-leaf. Owns routing, model metadata, provider execution (ProviderPort), and task control.
    apiHTTP adapter (FastAPI). Owns routes, handlers, and HTTP error mapping.
    cliConsole entrypoints, client launchers, and session management.
    configSettings, provider metadata, filesystem paths, and logging.
    coreProtocol-neutral logic. Owns wire models (Anthropic/OpenAI), SSE construction, and token counting.
    messagingPlatform adapters (Discord/Telegram), message handling, and transcript rendering.
    providersProvider construction, OpenAI-chat shared logic, and concrete provider adapters.
    runtimeThe composition root. Handles startup/shutdown and wires all other packages together.
  9. Manage Stream Recovery and Retries

    main

    Stream recovery is managed by src/free_claude_code/providers/stream_recovery.py using a ProviderRetrySession.

    • Retry Budget: A single five-attempt budget is shared across the entire logical execution (initial opening, request-shape corrections, replay, continuation, and tool repair). There are no nested retry counters.
    • Backoff Strategy: Deterministic corrections retry immediately. Transient failures use exponential backoff with jitter and respect the Retry-After header.
    • Partial Output: If partial output exists, the final attempt is reserved for continuation or tool repair rather than a full replay. Completed tool calls can be salvaged without an upstream attempt.
    • Failure Scopes:
      • Pre-acceptance: Failures before the first chunk are received participate in provider-wide coordinated recovery.
      • Post-acceptance: Failures after the first chunk are request-local to prevent one interrupted connection from affecting parallel streams.
  10. How Model Routing and Gateway IDs work

    main

    The ModelRouter resolves incoming client model names into concrete provider models. It supports two primary formats:

    1. Direct Provider Model Refs: e.g., nvidia_nim/nvidia/model-name. These use the root policy.
    2. Gateway Model IDs: Decoded via core/gateway_model_ids.py. These are mapped by Claude tier (e.g., names containing fable, opus, sonnet, or haiku).

    Key Routing Behaviors:

    • Tier Overrides: If a gateway model name contains a Claude tier keyword, it uses the matching tier override if configured; otherwise, it falls back to the default MODEL.
    • Reasoning Preference: The router selects the applicable reasoning preference (e.g., 'no-thinking' variants force off).
    • Identity Separation: The system maintains a split between the original_model (the stable gateway model exposed in responses/traces) and the provider model sent upstream. Providers and local tools must never publish the private upstream model as the response model.
  11. Understand the Voice-Note Orchestration lifecycle

    main

    Voice-note processing is managed by a shared orchestration layer (voice_flow.py) that handles the transition from audio input to transcription and eventually to an IncomingMessage.

    The Lifecycle:

    1. Validation & Setup: Performs file-size validation and manages temporary file cleanup.
    2. Reservation: Reserves an opaque claim in the PendingVoiceRegistry (owned by messaging/voice.py) before status delivery.
    3. Transcription: Uses a Transcriber protocol. The system supports either a local Whisper TranscriptionService or a provider-owned NvidiaNimTranscriber.
    4. Handoff: Once transcribed, the process hands off to the IncomingMessage flow.
    5. Cancellation: An explicit /stop or /clear atomically removes the claim from the registry and cancels the associated child task. A cancellation that 'wins' turns late status, transcription, or callback completion into cleanup-only work.

    Important: Changing credentials for an active voice backend (via Admin) requires a restart, as the local service retains immutable runtime settings for its pipeline.

  12. How the Codex Model Catalog is managed

    main

    The Codex model picker uses a local JSON catalog to avoid loopback HTTP requests during model selection.

    Workflow:

    1. Generation: The runtime/codex_catalog.py bridge asks the application for its inventory and writes it to ~/.fcc/codex-model-catalog.json.
    2. Updates: The ProviderRuntimeManager triggers a write whenever settings, discovery, provider-tests, or connected accounts change. Writes are atomic.
    3. Consumption: The Codex App reads this file at startup. To see updates to the catalog, the Codex App must be restarted.
    4. Synchronization: The fcc-codex tool can be used as a launch-time synchronizer to fetch the /v1/models response and update the catalog manually.
    # Path to the local Codex model catalog
    ~/.fcc/codex-model-catalog.json