alishahryar1--free-claude-code
a0f62c598c
## Problem | Before | After | | --- | --- | | FCC supported Google AI Studio API keys but could not route coding agents through a Google Cloud Vertex AI project. | `vertex/...` routes through Google's [documented OpenAI-compatible Chat Completions endpoint](https://cloud.google.com/vertex-ai/generative-ai/docs/start/openai), using the global endpoint by default or an explicitly configured region. | | A pasted Vertex access token would expire, while Application Default Credentials were not part of provider construction. | FCC loads [Application Default Credentials](https://cloud.google.com/docs/authentication/application-default-credentials), supplies a renewable credential callback to the OpenAI transport, coalesces concurrent refreshes, and returns typed authentication or transient failures. | | Vertex does not expose its model catalog through the compatible OpenAI `/models` route. | FCC translates its generic discovery operation to Google's paginated [publisher-model list API](https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/publishers.models/list) and converts resource names into the model IDs accepted by Chat Completions. | | Google thought signatures were owned by the AI Studio adapter even though Vertex shares the same protocol behavior. | A neutral Google OpenAI family owns shared thought-signature and request behavior; AI Studio and Vertex retain separate endpoint and authentication ownership. | ## Changes - Added the Vertex provider, `VERTEX_PROJECT_ID`, optional `VERTEX_LOCATION` and `VERTEX_PROXY`, Admin UI configuration, model-picker discovery, smoke metadata, and customer setup documentation. - Added renewable ADC access tokens with refresh coalescing, proxy-aware refresh, sanitized failure classification, and project quota headers. - Added global/regional endpoint composition plus native model-catalog pagination, strict response validation, response cleanup, and repeated-page protection. - Generalized provider readiness around declared configuration fields so project-based and multi-field providers no longer pretend every remote provider is configured by one API key. - Moved shared Google request quirks out of the Gemini adapter, preserved AI Studio behavior, and bumped the package to `4.11.0`. <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds Google Vertex AI as a new provider using Application Default Credentials. The main changes are: - New `vertex` provider with project/location endpoint construction. - Renewable ADC access-token loading with refresh coalescing and proxy-aware refresh. - Native Vertex publisher-model discovery with pagination and response validation. - Shared Google OpenAI-compatible request behavior for Gemini and Vertex. - Admin UI, settings, smoke config, docs, version, lockfile, and tests for the new provider. </details> <h3>Confidence Score: 5/5</h3> Safe to merge with low risk. No blocking correctness or security issues were identified. The new provider follows the existing provider-runtime and Admin configuration patterns. Endpoint, auth, model parsing, readiness, docs, version, lockfile, and tests are updated together. No files require special attention. <details><summary><h3><a href="https://www.greptile.com/trex"><img alt="T-Rex" src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg" height="20" align="absmiddle"></a> T-Rex Logs</h3></summary> **What T-Rex did** - The T-Rex test suite was executed to validate the code-execution proof-of-work, generating a full verbose pytest log and recording the run metadata, and the run completed with EXIT\_CODE: 0. <a href="https://app.greptile.com/trex/runs/14991235/artifacts"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=4"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"><img alt="View all artifacts" src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"></picture></a> <sub><a href="https://www.greptile.com/trex"><img alt="T-Rex" src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg" height="14" align="absmiddle"></a> Ran code and verified through T-Rex</sub> </details> <details open><summary><h3>Important Files Changed</h3></summary> | Filename | Overview | |----------|----------| | src/free_claude_code/providers/vertex/client.py | Adds the Vertex provider with OpenAI-compatible chat routing and native paginated model discovery. | | src/free_claude_code/providers/vertex/auth.py | Implements renewable ADC token loading, proxy-aware refresh, coalescing, and sanitized auth failures. | | src/free_claude_code/providers/vertex/endpoint.py | Builds validated Vertex global/regional service, chat, and model-list endpoints. | | src/free_claude_code/providers/vertex/models.py | Parses Vertex publisher-model pages into OpenAI-compatible model IDs with malformed-response checks. | | src/free_claude_code/providers/google_openai/provider.py | Adds shared Google thought-signature caching and thinking-budget request body handling. | | src/free_claude_code/providers/google_openai/quirks.py | Renames Gemini-specific quirks to shared Google quirks and exposes model-neutral thinking config helpers. | | src/free_claude_code/providers/openai_chat/provider.py | Allows OpenAI-chat providers to pass an async API-key callback into the OpenAI SDK. | | src/free_claude_code/providers/runtime/discovery.py | Uses descriptor-defined readiness to choose providers eligible for model cache/discovery. | | src/free_claude_code/config/provider_catalog.py | Adds the Vertex descriptor and required settings metadata, and makes Cloudflare readiness require both token and account ID. | | src/free_claude_code/config/admin/status.py | Generalizes Admin provider readiness status to use each descriptor's configuration attributes. | | src/free_claude_code/config/admin/provider_manifest.py | Adds Admin UI fields for Vertex project and location alongside generated provider fields. | | tests/providers/test_vertex.py | Adds targeted tests for Vertex endpoints, ADC token refresh, reasoning mapping, and model discovery pagination. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant User as User / Admin UI participant Settings as Settings + Provider Catalog participant Runtime as Provider Runtime participant Vertex as VertexProvider participant ADC as Google ADC participant OpenAI as OpenAI-compatible Chat Endpoint participant Models as Vertex Publisher Models API User->>Settings: Set VERTEX_PROJECT_ID / VERTEX_LOCATION / VERTEX_PROXY Settings->>Runtime: Descriptor reports vertex configured by project id Runtime->>Vertex: Construct with project, location, proxy, rate limiter Vertex->>ADC: Load/refresh Application Default Credentials ADC-->>Vertex: Renewable access token Vertex->>OpenAI: Stream chat completion with bearer token + x-goog-user-project OpenAI-->>Vertex: Streaming chat chunks Vertex-->>Runtime: Normalized provider stream Runtime->>Vertex: Refresh model list Vertex->>Models: GET paginated publishers/google/models Models-->>Vertex: publisherModels + nextPageToken Vertex-->>Runtime: Prefixed model IDs for cache/model picker ``` </a> <a href="#gh-dark-mode-only"> ```mermaid %%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant User as User / Admin UI participant Settings as Settings + Provider Catalog participant Runtime as Provider Runtime participant Vertex as VertexProvider participant ADC as Google ADC participant OpenAI as OpenAI-compatible Chat Endpoint participant Models as Vertex Publisher Models API User->>Settings: Set VERTEX_PROJECT_ID / VERTEX_LOCATION / VERTEX_PROXY Settings->>Runtime: Descriptor reports vertex configured by project id Runtime->>Vertex: Construct with project, location, proxy, rate limiter Vertex->>ADC: Load/refresh Application Default Credentials ADC-->>Vertex: Renewable access token Vertex->>OpenAI: Stream chat completion with bearer token + x-goog-user-project OpenAI-->>Vertex: Streaming chat chunks Vertex-->>Runtime: Normalized provider stream Runtime->>Vertex: Refresh model list Vertex->>Models: GET paginated publishers/google/models Models-->>Vertex: publisherModels + nextPageToken Vertex-->>Runtime: Prefixed model IDs for cache/model picker ``` </a> </details> <sub>Reviews (1): Last reviewed commit: ["feat: add Google Vertex AI provider"](https://github.com/alishahryar1/free-claude-code/commit/97e753f0772e60377865876ca59b2fd8888d922e) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=45405432)</sub> <!-- /greptile_comment -->
292 行
8.9 KiB
Bash
292 行
8.9 KiB
Bash
# NVIDIA NIM Config
|
|
NVIDIA_NIM_API_KEY=""
|
|
|
|
|
|
# OpenRouter Config
|
|
OPENROUTER_API_KEY=""
|
|
|
|
|
|
# Mistral La Plateforme Config (Experiment plan free tier – rate limits; OpenAI-compatible at api.mistral.ai/v1)
|
|
MISTRAL_API_KEY=""
|
|
|
|
|
|
# Mistral Codestral (separate key from La Plateforme; OpenAI-compatible at codestral.mistral.ai/v1)
|
|
CODESTRAL_API_KEY=""
|
|
|
|
|
|
# DeepSeek Config (OpenAI-compatible Chat Completions at api.deepseek.com)
|
|
DEEPSEEK_API_KEY=""
|
|
|
|
|
|
# Kimi Config (OpenAI-compatible Chat Completions at api.moonshot.ai/v1)
|
|
KIMI_API_KEY=""
|
|
|
|
|
|
# Kimi Code subscription (OpenAI-compatible Chat Completions at api.kimi.com/coding/v1)
|
|
KIMI_CODE_API_KEY=""
|
|
|
|
|
|
# Wafer Config (OpenAI-compatible Chat Completions at pass.wafer.ai/v1)
|
|
WAFER_API_KEY=""
|
|
|
|
|
|
# MiniMax Config (OpenAI-compatible Chat Completions at api.minimax.io/v1)
|
|
MINIMAX_API_KEY=""
|
|
|
|
|
|
# OpenCode Zen (opencode.ai/zen/v1) and OpenCode Go (opencode.ai/zen/go/v1) share OPENCODE_API_KEY
|
|
OPENCODE_API_KEY=""
|
|
|
|
|
|
# Vercel AI Gateway Config (OpenAI-compatible Chat Completions at ai-gateway.vercel.sh/v1)
|
|
AI_GATEWAY_API_KEY=""
|
|
|
|
|
|
# Amazon Bedrock Mantle (region-specific OpenAI-compatible Chat Completions)
|
|
AWS_BEARER_TOKEN_BEDROCK=""
|
|
BEDROCK_BASE_URL="https://bedrock-mantle.us-east-1.api.aws/v1"
|
|
|
|
|
|
# Hugging Face Inference Providers Config (OpenAI-compatible Chat Completions at router.huggingface.co/v1)
|
|
HUGGINGFACE_API_KEY=""
|
|
|
|
|
|
# Cohere Config (OpenAI-compatible Chat Completions at api.cohere.ai/compatibility/v1)
|
|
COHERE_API_KEY=""
|
|
|
|
|
|
# GitHub Models Config (OpenAI-compatible Chat Completions at models.github.ai/inference)
|
|
GITHUB_MODELS_TOKEN=""
|
|
|
|
|
|
# Z.ai Config (GLM Coding Plan OpenAI-compatible Chat Completions at api.z.ai/api/coding/paas/v4)
|
|
ZAI_API_KEY=""
|
|
|
|
|
|
# Fireworks AI Config (OpenAI-compatible Chat Completions at api.fireworks.ai/inference/v1)
|
|
FIREWORKS_API_KEY=""
|
|
|
|
|
|
# Cloudflare Workers AI Config (OpenAI-compatible Chat Completions at api.cloudflare.com/client/v4/accounts/<id>/ai/v1)
|
|
CLOUDFLARE_API_TOKEN=""
|
|
CLOUDFLARE_ACCOUNT_ID=""
|
|
|
|
|
|
# Gemini / Google AI Studio (OpenAI-compatible Chat Completions; see https://ai.google.dev/gemini-api/docs/openai)
|
|
GEMINI_API_KEY=""
|
|
|
|
|
|
# Google Vertex AI (uses Application Default Credentials; no API key)
|
|
# Local setup: gcloud auth application-default login
|
|
VERTEX_PROJECT_ID=""
|
|
VERTEX_LOCATION="global"
|
|
|
|
|
|
# Groq Cloud (OpenAI-compatible Chat Completions; see https://console.groq.com/docs/openai)
|
|
GROQ_API_KEY=""
|
|
|
|
|
|
# SambaNova Cloud (OpenAI-compatible Chat Completions at api.sambanova.ai/v1)
|
|
SAMBANOVA_API_KEY=""
|
|
|
|
|
|
# Cerebras Inference (OpenAI-compatible Chat Completions; see https://inference-docs.cerebras.ai/resources/openai)
|
|
CEREBRAS_API_KEY=""
|
|
|
|
|
|
# Ollama Cloud (direct OpenAI-compatible API at ollama.com/v1)
|
|
OLLAMA_API_KEY=""
|
|
|
|
|
|
# LM Studio Config (local provider, no API key required)
|
|
LM_STUDIO_BASE_URL="http://localhost:1234/v1"
|
|
|
|
|
|
# Llama.cpp Config (local provider, no API key required)
|
|
LLAMACPP_BASE_URL="http://localhost:8080/v1"
|
|
|
|
|
|
# Ollama Config (local provider, no API key required)
|
|
OLLAMA_BASE_URL="http://localhost:11434"
|
|
|
|
|
|
# All Claude model requests are mapped to these models, plain model is fallback
|
|
# Format: provider_type/model/name
|
|
# Valid providers: "nvidia_nim" | "open_router" | "gemini" | "vertex" | "deepseek" | "mistral" | "mistral_codestral" | "opencode" | "opencode_go" | "vercel" | "bedrock" | "huggingface" | "cohere" | "github_models" | "wafer" | "kimi" | "kimi_code" | "minimax" | "cerebras" | "groq" | "sambanova" | "fireworks" | "cloudflare" | "zai" | "ollama_cloud" | "lmstudio" | "llamacpp" | "ollama"
|
|
MODEL_FABLE=
|
|
MODEL_OPUS=
|
|
MODEL_SONNET=
|
|
MODEL_HAIKU=
|
|
MODEL="nvidia_nim/nvidia/nemotron-3-super-120b-a12b"
|
|
|
|
|
|
# Optional live smoke model overrides. Provider smoke runs once per configured
|
|
# provider even when MODEL/MODEL_* route to a different provider.
|
|
FCC_SMOKE_MODEL_NVIDIA_NIM=
|
|
FCC_SMOKE_MODEL_OPEN_ROUTER=
|
|
FCC_SMOKE_MODEL_MISTRAL=
|
|
FCC_SMOKE_MODEL_MISTRAL_REASONING=
|
|
FCC_SMOKE_MODEL_MISTRAL_CODESTRAL=
|
|
FCC_SMOKE_MODEL_DEEPSEEK=
|
|
FCC_SMOKE_MODEL_OLLAMA_CLOUD=
|
|
FCC_SMOKE_MODEL_LMSTUDIO=
|
|
FCC_SMOKE_MODEL_LLAMACPP=
|
|
FCC_SMOKE_MODEL_OLLAMA=
|
|
FCC_SMOKE_MODEL_KIMI=
|
|
FCC_SMOKE_MODEL_KIMI_CODE=
|
|
FCC_SMOKE_MODEL_WAFER=
|
|
FCC_SMOKE_MODEL_MINIMAX=
|
|
FCC_SMOKE_MODEL_OPENCODE=
|
|
FCC_SMOKE_MODEL_OPENCODE_GO=
|
|
FCC_SMOKE_MODEL_VERCEL=
|
|
FCC_SMOKE_MODEL_BEDROCK=
|
|
FCC_SMOKE_MODEL_HUGGINGFACE=
|
|
FCC_SMOKE_MODEL_COHERE=
|
|
FCC_SMOKE_MODEL_GITHUB_MODELS=
|
|
FCC_SMOKE_MODEL_ZAI=
|
|
FCC_SMOKE_MODEL_FIREWORKS=
|
|
FCC_SMOKE_MODEL_CLOUDFLARE=
|
|
FCC_SMOKE_MODEL_GEMINI=
|
|
FCC_SMOKE_MODEL_VERTEX=
|
|
FCC_SMOKE_MODEL_GROQ=
|
|
FCC_SMOKE_MODEL_SAMBANOVA=
|
|
FCC_SMOKE_MODEL_CEREBRAS=
|
|
FCC_SMOKE_NIM_MODELS=
|
|
FCC_SMOKE_NIM_EXTRA_MODELS=
|
|
FCC_SMOKE_OPENROUTER_FREE_MODELS=
|
|
FCC_SMOKE_OPENROUTER_FREE_EXTRA_MODELS=
|
|
|
|
|
|
# Reasoning policy
|
|
# Root: off | client | low | medium | high | xhigh | max
|
|
# Route overrides additionally accept inherit. "client" preserves the CLI's effort;
|
|
# providers translate only controls documented by their API.
|
|
REASONING_POLICY=client
|
|
REASONING_FABLE=inherit
|
|
REASONING_OPUS=inherit
|
|
REASONING_SONNET=inherit
|
|
REASONING_HAIKU=inherit
|
|
|
|
|
|
# Provider config
|
|
# Per-provider proxy support: http and socks5, example: "http://username:password@host:port"
|
|
NVIDIA_NIM_PROXY=""
|
|
OPENROUTER_PROXY=""
|
|
MISTRAL_PROXY=""
|
|
CODESTRAL_PROXY=""
|
|
LMSTUDIO_PROXY=""
|
|
LLAMACPP_PROXY=""
|
|
KIMI_PROXY=""
|
|
KIMI_CODE_PROXY=""
|
|
WAFER_PROXY=""
|
|
MINIMAX_PROXY=""
|
|
OPENCODE_PROXY=""
|
|
OPENCODE_GO_PROXY=""
|
|
VERCEL_AI_GATEWAY_PROXY=""
|
|
BEDROCK_PROXY=""
|
|
HUGGINGFACE_PROXY=""
|
|
COHERE_PROXY=""
|
|
GITHUB_MODELS_PROXY=""
|
|
ZAI_PROXY=""
|
|
FIREWORKS_PROXY=""
|
|
CLOUDFLARE_PROXY=""
|
|
GEMINI_PROXY=""
|
|
VERTEX_PROXY=""
|
|
GROQ_PROXY=""
|
|
SAMBANOVA_PROXY=""
|
|
CEREBRAS_PROXY=""
|
|
OLLAMA_CLOUD_PROXY=""
|
|
|
|
PROVIDER_RATE_LIMIT=1
|
|
PROVIDER_RATE_WINDOW=3
|
|
PROVIDER_MAX_CONCURRENCY=5
|
|
|
|
|
|
# HTTP client timeouts (seconds) for provider API requests
|
|
HTTP_READ_TIMEOUT=300
|
|
HTTP_WRITE_TIMEOUT=60
|
|
HTTP_CONNECT_TIMEOUT=60
|
|
|
|
|
|
# Optional proxy bearer token
|
|
ANTHROPIC_AUTH_TOKEN="freecc"
|
|
|
|
|
|
# Open /admin in the default browser when fcc-server becomes healthy (set 0/false/no to disable)
|
|
FCC_OPEN_BROWSER=true
|
|
|
|
|
|
# Messaging Platform: "telegram" | "discord" | "none"
|
|
MESSAGING_PLATFORM="discord"
|
|
MESSAGING_RATE_LIMIT=1
|
|
MESSAGING_RATE_WINDOW=1
|
|
|
|
|
|
# Voice Note Transcription
|
|
VOICE_NOTE_ENABLED=false
|
|
# WHISPER_DEVICE: "cpu" | "cuda" | "nvidia_nim"
|
|
# - "cpu"/"cuda": Hugging Face transformers Whisper (offline, free; install with: uv sync --extra voice_local)
|
|
# - "nvidia_nim": NVIDIA NIM Whisper via Riva gRPC (requires NVIDIA_NIM_API_KEY; install with: uv sync --extra voice)
|
|
# (Independent of MODEL=nvidia_nim/...: that selects the *chat* provider; this selects voice STT only.)
|
|
WHISPER_DEVICE="nvidia_nim"
|
|
# WHISPER_MODEL:
|
|
# - For cpu/cuda: Hugging Face ID or short name (tiny, base, small, medium, large-v2, large-v3, large-v3-turbo)
|
|
# - For nvidia_nim: NVIDIA NIM model (e.g., "nvidia/parakeet-ctc-1.1b-asr", "openai/whisper-large-v3")
|
|
# - For nvidia_nim, default to "openai/whisper-large-v3" for best performance
|
|
WHISPER_MODEL="openai/whisper-large-v3"
|
|
|
|
|
|
# Telegram Config
|
|
TELEGRAM_BOT_TOKEN=""
|
|
ALLOWED_TELEGRAM_USER_ID=""
|
|
# Optional Telegram-only proxy.
|
|
# Supported schemes: http, https, socks4, socks5, socks5h.
|
|
# Example: "socks5://127.0.0.1:1080" or "https://user:password@host:port"
|
|
TELEGRAM_PROXY_URL=""
|
|
|
|
|
|
# Discord Config
|
|
DISCORD_BOT_TOKEN=""
|
|
ALLOWED_DISCORD_CHANNELS=""
|
|
|
|
|
|
# Agent Config
|
|
ALLOWED_DIR=""
|
|
FAST_PREFIX_DETECTION=true
|
|
ENABLE_NETWORK_PROBE_MOCK=true
|
|
ENABLE_TITLE_GENERATION_SKIP=true
|
|
ENABLE_SUGGESTION_MODE_SKIP=true
|
|
ENABLE_FILEPATH_EXTRACTION_MOCK=true
|
|
|
|
|
|
# Local Anthropic web_search / web_fetch handling (performs outbound HTTP; on by default)
|
|
ENABLE_WEB_SERVER_TOOLS=true
|
|
WEB_FETCH_ALLOWED_SCHEMES=http,https
|
|
WEB_FETCH_ALLOW_PRIVATE_NETWORKS=false
|
|
|
|
|
|
# Structured traces: DEBUG lines with `"trace": true` merge
|
|
# ingress/routing/cli/provider/egress stages. Conversation text is logged in those payloads
|
|
# (verbatim). Values under keys named like ``api_key`` / ``authorization`` are redacted.
|
|
# Raw transport payloads still require the LOG_RAW_* toggles below.
|
|
#
|
|
# Minimum log level for the JSON file sink: DEBUG, INFO, WARNING, ERROR, CRITICAL.
|
|
# Defaults to INFO. Use DEBUG temporarily for detailed request traces, or WARNING for quieter logs.
|
|
# The file rotates at 50 MB and retains five rotated files (roughly 300 MB including the active file).
|
|
LOG_LEVEL=INFO
|
|
#
|
|
# Verbose diagnostics (avoid logging raw prompts / SSE bodies in production)
|
|
DEBUG_PLATFORM_EDITS=false
|
|
DEBUG_SUBAGENT_STACK=false
|
|
# When true, also allows DEBUG-level httpx/httpcore/telegram log noise (not just payload logging).
|
|
LOG_RAW_API_PAYLOADS=false
|
|
LOG_RAW_SSE_EVENTS=false
|
|
# When true, log full exception text and tracebacks for unhandled errors (may leak request-derived data).
|
|
LOG_API_ERROR_TRACEBACKS=false
|
|
# When true, log message/transcription text previews in messaging adapters only (handler ingress always TRACEs verbatim text separately).
|
|
LOG_RAW_MESSAGING_CONTENT=false
|
|
# When true, log full Claude CLI stderr, non-JSON stdout lines, and parser error text.
|
|
LOG_RAW_CLI_DIAGNOSTICS=false
|
|
# When true, log full exception and CLI error message strings in messaging (may leak user content).
|
|
LOG_MESSAGING_ERROR_DETAILS=false
|