main
33 次代码提交
| 作者 | SHA1 | 备注 | 提交日期 | |
|---|---|---|---|---|
|
|
a0f62c598c |
Add Google Vertex AI with renewable ADC (#1193)
## 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 --> |
||
|
|
af658287bd |
Add Amazon Bedrock Mantle support (#1192)
## Problem FCC cannot route coding-agent requests through Amazon Bedrock even though Bedrock Mantle exposes an OpenAI-compatible streaming Chat Completions API. Users currently need a separate compatibility layer, and FCC has no catalog, Admin UI, model-discovery, or smoke-test contract for Bedrock. Fixes #863. ## Changes | Before | After | | --- | --- | | Amazon Bedrock was absent from provider routing. | `bedrock/` uses the existing OpenAI Chat provider with AWS's [Bedrock Mantle endpoint](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-chat-completions-mantle.html). | | Bedrock integration would have implied a new AWS-native transport. | The ordinary profile owns streaming, tools, retries, and `/models` discovery without boto3, SigV4, Converse, or Invoke machinery. | | FCC had no Bedrock authentication or regional endpoint configuration. | `AWS_BEARER_TOKEN_BEDROCK`, `BEDROCK_BASE_URL`, and `BEDROCK_PROXY` are available through environment and Admin UI configuration, with the current `us-east-1` Mantle URL as the default. | | Heterogeneous Bedrock models had no safe provider-wide reasoning control. | FCC replays prior reasoning through portable think tags and leaves model-specific reasoning parameters upstream-owned. | | Smoke configuration duplicated credential checks for every provider. | Smoke configuration reads primary credentials and configurable endpoints from the provider catalog, retaining only Cloudflare's two-field exception. | | Bedrock behavior had no deterministic coverage or release documentation. | Provider requests, regional URL normalization, model discovery, Admin persistence, smoke selection, README usage, architecture boundaries, and version 4.10.0 cover the new capability. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds Amazon Bedrock Mantle as an OpenAI-compatible provider. The main changes are: - Bedrock catalog, settings, proxy, and regional base-URL configuration. - OpenAI Chat routing with portable reasoning replay and model discovery. - Admin UI fields and configuration persistence. - Catalog-driven smoke configuration and Bedrock smoke coverage. - Provider documentation and a version bump to 4.10.0. </details> <h3>Confidence Score: 5/5</h3> The provider flow looks mergeable after handling an explicitly empty Bedrock base URL. Catalog, runtime, Admin, and smoke wiring are consistent. Regional URLs with or without `/v1` are normalized correctly. src/free_claude_code/config/settings.py: an empty `BEDROCK_BASE_URL` can still create a client with an invalid endpoint. <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** - Before the change, bedrock was rejected as an unknown provider with exit code 1. - After the change, the fake service captured the normalized URL, Bearer trex...oken, portable Chat Completions JSON, one tool, think-tag history, and no reasoning\_effort, reasoning, or thinking fields; exit code 0. - Focused pytest validation completed with 6/6 passing tests. <a href="https://app.greptile.com/trex/runs/14988686/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/config/provider_catalog.py | Adds the Bedrock provider descriptor, regional default endpoint, credential mapping, and proxy metadata. | | src/free_claude_code/config/settings.py | Adds Bedrock settings, but an explicitly empty base URL bypasses the regional default. | | src/free_claude_code/providers/openai_chat/profiles.py | Registers Bedrock with URL normalization, think-tag replay, and no provider-wide reasoning parameter. | | src/free_claude_code/config/admin/provider_manifest.py | Generalizes provider base-URL fields and adds Bedrock-specific labels and help text. | | smoke/lib/config.py | Adds Bedrock smoke defaults and replaces provider-specific checks with catalog-driven configuration checks. | | tests/providers/test_bedrock.py | Covers Bedrock URL normalization, request fields, reasoning replay, tool calls, and model discovery. | </details> <details open><summary><h3>Flowchart</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% flowchart LR Config[Environment or Admin config] --> Settings[Settings] Catalog[Provider catalog] --> Runtime[Provider runtime] Settings --> Runtime Runtime --> Profile[Bedrock OpenAI Chat profile] Profile --> Client[AsyncOpenAI client] Client --> Mantle[Regional Bedrock Mantle endpoint] Catalog --> Admin[Admin manifest] Catalog --> Smoke[Smoke selection] ``` </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"}}}%% flowchart LR Config[Environment or Admin config] --> Settings[Settings] Catalog[Provider catalog] --> Runtime[Provider runtime] Settings --> Runtime Runtime --> Profile[Bedrock OpenAI Chat profile] Profile --> Client[AsyncOpenAI client] Client --> Mantle[Regional Bedrock Mantle endpoint] Catalog --> Admin[Admin manifest] Catalog --> Smoke[Smoke selection] ``` </a> </details> <a href="https://app.greptile.com/api/ide/codex?prompt=IMPORTANT%3A%20Work%20in%20the%20repository%20%22alishahryar1%2Ffree-claude-code%22%20on%20the%20existing%20branch%20%22ali%2Fadd-bedrock-mantle%22.%20Checkout%20that%20branch%20%E2%80%94%20do%20NOT%20create%20a%20new%20branch%20or%20open%20a%20new%20PR.%20Push%20your%20changes%20to%20%22ali%2Fadd-bedrock-mantle%22.%0A%0AFix%20the%20following%201%20code%20review%20issue.%20Work%20through%20them%20one%20at%20a%20time%2C%20proposing%20concise%20fixes.%0A%0A---%0A%0A%23%23%23%20Issue%201%20of%201%0Asrc%2Ffree_claude_code%2Fconfig%2Fsettings.py%3A60-63%0A**Empty%20Override%20Bypasses%20Default%20URL**%0A%0AWhen%20%60BEDROCK_BASE_URL%60%20is%20present%20but%20empty%2C%20settings%20keep%20the%20empty%20string%20instead%20of%20using%20%60BEDROCK_DEFAULT_BASE%60.%20Clearing%20this%20field%20through%20environment%20or%20Admin%20configuration%20therefore%20builds%20the%20Bedrock%20client%20with%20an%20invalid%20base%20URL%2C%20and%20Bedrock%20requests%20and%20model%20discovery%20fail%20instead%20of%20using%20the%20documented%20default.%0A%0A&repo=alishahryar1%2Ffree-claude-code&pr=1192&platform=github"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodexDark.svg?v=6"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"><img alt="Fix All in Codex" src="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"></picture></a> <sub>Reviews (1): Last reviewed commit: ["Add Amazon Bedrock Mantle provider"](https://github.com/alishahryar1/free-claude-code/commit/f40b539c99c9f6a888762b8da69d5a738a4f4d70) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=45400300)</sub> > Greptile also left **1 inline comment** on this PR. <!-- /greptile_comment --> |
||
|
|
e14d8402a1 |
Prevent the admin UI from being served from cache (#1160)
## Problem Browsers could retain the local admin page, assets, or error responses, leaving users on stale UI state after an FCC update. ## Changes | Before | After | | --- | --- | | Admin responses had no complete cache policy, and route-level handling missed exception responses. | A dedicated admin response boundary sends `Cache-Control: no-store` for every `/admin` response, including 403, 404, validation, and unexpected errors. | | Admin API fetches used the browser's default cache mode. | Admin API fetches explicitly use `cache: "no-store"`. | | Cache behavior was untested. | Tests cover HTML, assets, JSON, failure responses, and path scoping. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR prevents browsers from retaining stale admin UI responses. The main changes are: - Adds `Cache-Control: no-store` to successful and error responses under `/admin`. - Sets admin API fetches to use the browser's `no-store` cache mode. - Adds tests for HTML, assets, API responses, errors, and path matching. - Bumps the package patch version and updates the lockfile. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. The middleware covers normal and handled error responses under the admin path. The explicit fallback covers general admin error responses. Tests cover successful responses and the relevant 403, 404, 422, and 500 paths. No blocking issues found in the changed code. <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 runtime probe script admin-cache-runtime-probe.py was executed to exercise the repository's create\_test\_app() application. - The admin-cache-http-01-before.log log captured three endpoint responses without Cache-Control before the change. - The admin-cache-http-02-after.log log captured the same endpoints after applying Cache-Control: no-store. - The focused test evidence in admin-cache-02-after.log recorded the exact command, working directory, exit code, and verbose results. <a href="https://app.greptile.com/trex/runs/14828301/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/api/admin_cache.py | Adds middleware and an error-response fallback that apply `Cache-Control: no-store` to the admin surface. | | src/free_claude_code/api/app.py | Registers the cache middleware and applies the policy to general admin error responses. | | src/free_claude_code/api/admin_static/admin.js | Configures admin API fetches to bypass the browser cache. | | tests/api/test_admin.py | Covers cache headers on successful, missing, denied, invalid, and failed admin requests. | </details> <sub>Reviews (2): Last reviewed commit: ["Cover admin error responses with no-stor..."](https://github.com/alishahryar1/free-claude-code/commit/06c92fc4325ee7bcd96641051d19d5b83462322b) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=45057666)</sub> <!-- /greptile_comment --> |
||
|
|
6455c63e1d |
Make reasoning policy provider-neutral and client-aware (#1148)
## Problem FCC reduced reasoning to global and route booleans, mixing client intent, configuration, provider wire capabilities, output visibility, and history replay. That discarded named client efforts, encouraged model-name checks, and made provider behavior inconsistent. ## Changes | Before | After | | --- | --- | | Admin exposed global and route thinking toggles. | Admin exposes **Off**, **From client**, **Low**, **Medium**, **High**, **X-High**, and **Max**; Fable, Opus, Sonnet, and Haiku also expose **Inherit**. | | Request intent was repeatedly reduced to a boolean across routing and providers. | The application boundary resolves one immutable `ReasoningPolicy` with independent control, named effort, and exact positive token budget. | | Provider adapters could infer reasoning behavior from upstream model names or versions. | Provider profiles translate only documented provider-wide wire capabilities; architecture and contributor rules prohibit model-specific reasoning branches. | | Gateway reasoning controls were ad hoc. | [OpenRouter](https://openrouter.ai/docs/guides/best-practices/reasoning-tokens) and [Vercel AI Gateway](https://vercel.com/docs/ai-gateway/models-and-providers) use documented reasoning objects, including exact budgets where representable. | | Named effort forwarding was inconsistent or absent. | [Gemini](https://ai.google.dev/gemini-api/docs/openai), [Ollama](https://docs.ollama.com/api/openai-compatibility), [LM Studio](https://lmstudio.ai/changelog/lmstudio-v0.4.8), [Fireworks](https://docs.fireworks.ai/guides/querying-text-models/reasoning), [Cohere](https://docs.cohere.com/docs/compatibility-api), [Wafer](https://docs.wafer.ai/serverless/api-reference), [Groq](https://console.groq.com/docs/reasoning), [Cerebras](https://inference-docs.cerebras.ai/capabilities/reasoning), [SambaNova](https://docs.sambanova.ai/docs/api-reference/chat-completions/create-chat-based-completion), and [Mistral](https://docs.mistral.ai/studio-api/conversations/reasoning) receive their documented named vocabularies with explicit provider-owned downgrades. | | Boolean thinking controls were mixed into shared conversion. | [DeepSeek](https://api-docs.deepseek.com/guides/thinking_mode/), [Kimi](https://platform.kimi.ai/docs/guide/use-kimi-k2-thinking-model), [Z.ai](https://docs.z.ai/guides/capabilities/thinking-mode), [Cloudflare Workers AI](https://developers.cloudflare.com/changelog/post/2026-04-20-kimi-k2-6-workers-ai/), and [NVIDIA NIM](https://docs.nvidia.com/nim/large-language-models/1.15.0/thinking-budget-control.html) use provider-owned thinking-object or chat-template controls. | | Effort names and output limits could become fabricated reasoning budgets. | Exact budgets remain exact and are forwarded only through documented fields for OpenRouter, Fireworks, LM Studio, NIM, and [llama.cpp](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md); named efforts and output limits are never converted into token budgets. | | New-turn reasoning and prior-turn replay shared one switch. | Every profile independently declares native reasoning replay, `<think>` tag replay, provider-specific replay, or no replay; **Off** suppresses new reasoning output without corrupting required history. | | Providers without a stable generic compute control received guessed controls. | [MiniMax](https://platform.minimax.io/docs/api-reference/text-openai-api) requests split output only, while [GitHub Models](https://docs.github.com/en/rest/models/inference), [Hugging Face Inference Providers](https://huggingface.co/docs/inference-providers/en/tasks/chat-completion), Codestral, and OpenCode keep provider defaults and use only their explicit replay profile. | | OpenAI Responses effort became a lossy Anthropic thinking boolean. | Responses preserves `reasoning.effort` through `output_config`, then resolves it through the same application policy as Messages without inventing a budget. | | Legacy booleans remained the persisted contract. | FCC-owned dotenv files migrate to typed `REASONING_*` values, explicit env files receive an actionable warning, documentation describes the ownership boundary, and the package advances to 4.8.0. | | Reasoning behavior was covered by scattered boolean assertions. | New policy, routing, encoder, provider, Admin, migration, Responses, and smoke contracts pass all five local CI checks: 2,368 tests passed, 40 skipped; 92 smoke tests collect and both live config migration checks pass. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR makes reasoning policy client-aware and independent of provider model names. The main changes are: - Adds one immutable reasoning policy resolved at the application boundary. - Adds typed root and route reasoning settings with Admin UI support. - Moves wire controls and history replay behavior into provider profiles. - Migrates owned dotenv files from legacy thinking booleans. - Expands provider, routing, migration, API, and smoke coverage. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. No blocking issues found in the changed code. <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** - Ran the contract-validation test suite with the specified test modules, and the tests reported 78 passed in 1.53s with exit code 0. - Reviewed the complete captured output artifact reasoning-contract-02-after.log to verify the final test outcomes and successful contract validation. <a href="https://app.greptile.com/trex/runs/14792858/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/config/env_migrations.py | Migrates legacy reasoning booleans in owned dotenv files and warns for explicit environment files. | | src/free_claude_code/application/reasoning.py | Resolves client controls and configured preferences into one provider-neutral reasoning policy. | | src/free_claude_code/application/routing.py | Carries route-level reasoning preferences into request-scoped policy resolution. | | src/free_claude_code/providers/openai_chat/reasoning.py | Provides shared provider encoders for reasoning controls and replay behavior. | </details> <sub>Reviews (2): Last reviewed commit: ["chore: release reasoning controls as 4.8..."](https://github.com/alishahryar1/free-claude-code/commit/9d4be767f7dbdca5709474012f43dcdc6f4347e3) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=44984039)</sub> <!-- /greptile_comment --> |
||
|
|
d3dde47eaa |
Add an explicit searchable model dropdown (#1133)
## Problem Admin model fields depended on the browser's native datalist. Filtering worked, but browsers did not consistently expose a visible dropdown for browsing the full model catalog. ## Changes | Before | After | | --- | --- | | Model fields relied on browser-native datalist behavior. | Model fields use one FCC-owned searchable combobox with a visible chevron. | | Suggestions became discoverable only through browser-specific interactions. | Clicking the field or chevron opens the full catalog, while typing filters it. | | Keyboard navigation and empty results depended on native picker behavior. | Arrow keys, Enter, Escape, empty-state guidance, custom slugs, and None are handled explicitly. | | Selects and model fields rendered separate dropdown indicators. | Both controls use the same shared chevron asset. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR replaces native model datalists with an explicit searchable combobox. The main changes are: - Adds a visible model dropdown with filtering and empty-state guidance. - Supports keyboard navigation, custom model slugs, and optional `None` values. - Shares one chevron style across model fields and selects. - Updates admin tests and bumps the package version to 4.7.0. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. Closed Arrow-Up activates the last available option. Empty model lists and optional `None` values remain valid. No blocking issues were found in the changed code. <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** - Completed end-to-end validation of the FCC listbox model selection flow, including the discovery of models, opus-based filtering, keyboard selection, preservation of a custom slug, serializing None as empty, final activation with Arrow Up, and display of no-match guidance when needed. - Verified that corresponding admin requests returned HTTP 200 during the interaction, confirming contract-level success. <a href="https://app.greptile.com/trex/runs/14651225/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/api/admin_static/admin.js | Adds the searchable model combobox and correctly activates the last option when Arrow-Up opens a closed list. | | src/free_claude_code/api/admin_static/admin.css | Adds combobox layout, option states, dropdown stacking, and shared chevron styling. | | tests/api/test_admin.py | Updates admin static assertions for combobox behavior, custom slugs, and optional model values. | | pyproject.toml | Bumps the project version from 4.6.4 to 4.7.0. | | uv.lock | Synchronizes the editable package version with the project metadata. | </details> <sub>Reviews (2): Last reviewed commit: ["Fix closed ArrowUp model navigation"](https://github.com/alishahryar1/free-claude-code/commit/846c3423c8734c1b69cc340a3ff0c2031ff8bc48) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=44698382)</sub> <!-- /greptile_comment --> |
||
|
|
a092455b54 |
Add searchable model selection to the Admin UI (#1121)
## Problem Admin model routing fields required users to construct provider-prefixed model slugs. Optional tier overrides represented inheritance as an unexplained blank value. ## Changes | Before | After | | --- | --- | | Model inputs only gained suggestions after an individual provider refresh. | Model inputs load configured and discovered canonical slugs from one Admin catalog. | | Model routing looked like unrestricted text entry. | Model routing uses the browser's searchable model dropdown while retaining manual entry. | | Tier overrides displayed an empty value for fallback routing. | Tier overrides display **None** and persist it as an unset override. | | Model refresh returned provider-shaped cache internals. | Model refresh returns the same canonical catalog consumed by the Admin UI. | | Users inferred the provider/model slug format from examples. | The Admin UI and README define and present complete provider/model slugs. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds searchable model selection to the Admin UI. The main changes are: - Adds a canonical catalog of configured and discovered model slugs. - Adds searchable model inputs while preserving manual entry. - Represents unset tier overrides as **None**. - Reports provider-specific model refresh failures. - Reconciles cached models when provider settings change. - Updates documentation, package metadata, and tests. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. Catalog failures no longer stop the rest of the Admin UI from loading. Partial provider refreshes now produce a visible warning. Removed credential-backed providers are pruned from the shared cache, and later stale writes are rejected. No blocking issues remain in the changed code. <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** - T-Rex ran the requested verification for the pull request checks. - The verification completed, but local artifact references were not uploaded. <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/api/admin_static/admin.js | Adds searchable model fields, optional catalog hydration, refresh warnings, and None-to-unset conversion. | | src/free_claude_code/api/admin_routes.py | Adds canonical model catalog endpoints and provider refresh failure metadata. | | src/free_claude_code/providers/runtime/discovery.py | Tracks provider refresh outcomes and separates cache eligibility from discovery eligibility. | | src/free_claude_code/providers/runtime/model_cache.py | Scopes cached model metadata to currently available providers and removes stale remote entries. | | src/free_claude_code/runtime/provider_manager.py | Reconciles cache scope during runtime replacement and returns explicit refresh results. | </details> <sub>Reviews (2): Last reviewed commit: ["Fix model catalog refresh lifecycle"](https://github.com/alishahryar1/free-claude-code/commit/d16e170055f5389e538e18dece269a5f7a8c599d) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=44373795)</sub> <!-- /greptile_comment --> |
||
|
|
b1877a4b21 |
Add Ollama Cloud as a first-class provider (#1106)
## Problem FCC supports Ollama only through a local daemon, so users cannot authenticate directly to Ollama Cloud or discover its hosted models from the Admin UI. Ollama's OpenAI-compatible API also uses the standard `reasoning` field instead of `reasoning_content`, which would otherwise drop thinking output and tool-history reasoning. ## Changes | Before | After | | --- | --- | | `ollama/...` requires a local Ollama server. | `ollama_cloud/...` connects directly to `https://ollama.com/v1` with `OLLAMA_API_KEY`, while local Ollama remains unchanged. | | OpenAI-chat reasoning was hard-coded to `reasoning_content`. | Provider profiles declare their reasoning field, so Ollama streams and replays `reasoning` without a specialized transport. | | Ollama Cloud was absent from configuration, model discovery, docs, and smoke coverage. | The catalog, Admin UI, proxy setting, model picker, README, smoke matrix, and `4.5.0` release metadata expose the provider consistently. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds Ollama Cloud as a separate OpenAI-compatible provider. The main changes are: - New `ollama_cloud` catalog entry, settings, admin fields, proxy setting, and smoke configuration. - Provider profiles now choose the streamed and replayed reasoning field per provider. - Ollama Cloud uses `reasoning` and `reasoning_effort`, while local Ollama stays on its separate local configuration. - Streaming recovery now respects the resolved thinking setting when collecting reasoning. - Tests, docs, environment examples, and release metadata were updated for the new provider. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. No blocking issues found in the changed code. No files need 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** - Ran the provider/runtime/converter/streaming tests with full verbose pytest output and confirmed EXIT\_CODE: 0. - Ran the config/catalog/contracts/admin tests with full verbose pytest output and confirmed EXIT\_CODE: 0. - Generated and ran an introspection script to verify catalog, profile, settings, and admin manifest values without external API calls, and recorded the local execution output. <a href="https://app.greptile.com/trex/runs/14367965/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/openai_chat/profiles.py | Adds provider-level reasoning field selection and the Ollama Cloud profile. | | src/free_claude_code/providers/openai_chat/provider.py | Uses the profile reasoning field for streaming and passes the thinking setting into recovery. | | src/free_claude_code/providers/openai_chat/request_policy.py | Selects reasoning replay mode from the provider policy only when thinking is enabled. | | src/free_claude_code/core/anthropic/conversion.py | Supports replaying assistant reasoning through either `reasoning_content` or `reasoning`. | | src/free_claude_code/config/provider_catalog.py | Registers Ollama Cloud as a remote provider distinct from local Ollama. | | src/free_claude_code/config/settings.py | Adds the Ollama Cloud API key and proxy settings. | </details> <sub>Reviews (3): Last reviewed commit: ["Keep local Ollama wire behavior unchange..."](https://github.com/alishahryar1/free-claude-code/commit/d6f97cdb0074a4cbda140d484fb6dd679a1406df) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=44089262)</sub> <!-- /greptile_comment --> |
||
|
|
4f56a6aa17 |
Add Fable as a first-class Claude routing tier (#1099)
## Problem Claude Code now sends `claude-fable-5` for the Fable alias, but FCC treated it as an unrecognized model and collapsed it into the global fallback route. Users could not map Fable traffic or reasoning behavior independently. Fixes #1097. ## Changes | Before | After | | --- | --- | | Fable requests inherited `MODEL` and `ENABLE_MODEL_THINKING`. | Fable requests use `MODEL_FABLE` and `ENABLE_FABLE_THINKING` when configured, otherwise inherit the existing defaults. | | `/v1/models` omitted Claude Fable 5. | `/v1/models` advertises the canonical `claude-fable-5` identifier. | | Admin, documentation, validation, and smoke contracts described three Claude tiers. | Admin, documentation, validation, and smoke contracts describe Fable alongside Opus, Sonnet, and Haiku. | | The package version was `4.3.1`. | The package version is `4.4.0`. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds Fable as a Claude routing tier. The main changes are: - `MODEL_FABLE` and `ENABLE_FABLE_THINKING` settings. - Fable routing and thinking resolution in `ModelRouter`. - `claude-fable-5` in the model catalog. - Admin, docs, smoke, and test coverage updates. - Package version bump to `4.4.0`. </details> <h3>Confidence Score: 4/5</h3> The changed routing path needs a fix for direct provider model ids containing `fable`. Fable settings, validation, admin fields, and model listing are consistent with the existing tier patterns. Blank Fable settings inherit the existing defaults. Direct provider model ids can receive the Fable thinking override when their model name contains `fable`. src/free_claude_code/application/routing.py <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** - Reproduced the Fable thinking overmatch by running a focused Python repro that disables global thinking and enables Fable thinking, then resolves sambanova/my-fable-ensemble-v2. - The repro confirmed direct routing preserved provider\_id=sambanova, provider\_model=my-fable-ensemble-v2, and provider\_model\_ref=sambanova/my-fable-ensemble-v2, with resolved\_thinking\_enabled and thinking\_enabled both true. - Ran the fable-tier validation pytest, which finished with exit code 0 and 177 tests passed. - Ran the runtime probe to exercise the API model list, Settings env parsing, and ModelRouter paths, and observed a 200 OK on GET /v1/models, with the catalog item id claude-fable-5 and the expected Fable vs global-default routing behavior. - Generated the probe source file used to exercise the API and Settings paths, enabling repeatable validation without real provider credentials. <a href="https://app.greptile.com/trex/runs/14275379/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/application/routing.py | Adds Fable model and thinking branches; the thinking branch can also match unrelated direct provider model ids containing `fable`. | | src/free_claude_code/config/settings.py | Adds optional Fable model and thinking settings with blank-env inheritance and provider/model validation. | | src/free_claude_code/config/model_refs.py | Includes Fable in configured chat model reference collection and dedupe. | | src/free_claude_code/config/admin/manifest.py | Adds Fable model and thinking controls to the admin manifest. | | src/free_claude_code/api/model_catalog.py | Adds `claude-fable-5` to the advertised Claude model aliases. | | pyproject.toml | Bumps the package version to `4.4.0`. | | uv.lock | Updates the editable package version to match `pyproject.toml`. | </details> <details open><summary><h3>Flowchart</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% flowchart TD A[Incoming model name] --> B{Direct provider or gateway id?} B -- yes --> C[Use provider/model directly] C --> D[Resolve thinking from provider model string] B -- no --> E{Claude tier match} E -- Fable --> F[MODEL_FABLE or MODEL] E -- Opus/Sonnet/Haiku --> G[Tier override or MODEL] E -- None --> H[MODEL] D --> I[Provider request] F --> I G --> I H --> I ``` </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"}}}%% flowchart TD A[Incoming model name] --> B{Direct provider or gateway id?} B -- yes --> C[Use provider/model directly] C --> D[Resolve thinking from provider model string] B -- no --> E{Claude tier match} E -- Fable --> F[MODEL_FABLE or MODEL] E -- Opus/Sonnet/Haiku --> G[Tier override or MODEL] E -- None --> H[MODEL] D --> I[Provider request] F --> I G --> I H --> I ``` </a> </details> <a href="https://app.greptile.com/api/ide/codex?prompt=IMPORTANT%3A%20Work%20in%20the%20repository%20%22alishahryar1%2Ffree-claude-code%22%20on%20the%20existing%20branch%20%22ali%2Fadd-fable-routing-tier%22.%20Checkout%20that%20branch%20%E2%80%94%20do%20NOT%20create%20a%20new%20branch%20or%20open%20a%20new%20PR.%20Push%20your%20changes%20to%20%22ali%2Fadd-fable-routing-tier%22.%0A%0AFix%20the%20following%201%20code%20review%20issue.%20Work%20through%20them%20one%20at%20a%20time%2C%20proposing%20concise%20fixes.%0A%0A---%0A%0A%23%23%23%20Issue%201%20of%201%0Asrc%2Ffree_claude_code%2Fapplication%2Frouting.py%3A134-135%0A**Fable%20Thinking%20Overmatches%20Models**%0A%0AWhen%20a%20direct%20provider%20request%20uses%20a%20model%20id%20like%20%60sambanova%2Fmy-fable-ensemble-v2%60%2C%20the%20direct%20route%20bypasses%20tier%20remapping%20but%20still%20calls%20%60_resolve_thinking%28%29%60%20with%20the%20provider%20model%20string.%20With%20%60ENABLE_FABLE_THINKING%60%20set%2C%20this%20substring%20check%20applies%20Fable%20thinking%20behavior%20to%20an%20unrelated%20provider%20model%2C%20changing%20the%20outgoing%20request%20shape%20just%20because%20the%20model%20id%20contains%20%60fable%60.%0A%0A&repo=alishahryar1%2Ffree-claude-code&pr=1099&platform=github"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodexDark.svg?v=6"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"><img alt="Fix All in Codex" src="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"></picture></a> <sub>Reviews (1): Last reviewed commit: ["Add Fable as a first-class routing tier"](https://github.com/alishahryar1/free-claude-code/commit/0705840c65511fd85c74fd2c62ba8ea97afe7c12) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=43892323)</sub> > Greptile also left **1 inline comment** on this PR. <!-- /greptile_comment --> |
||
|
|
db9bee1712 |
Expose the Admin startup browser preference (#1091)
## Problem The Admin startup browser preference bypassed FCC's settings system. Managed configuration could not control it, and the Admin UI did not expose it. ## Changes | Before | After | | --- | --- | | The launcher read `FCC_OPEN_BROWSER` directly from the process environment. | The launcher reads the typed `open_admin_browser` setting. | | The startup browser preference was absent from the Admin UI. | Runtime settings expose an **Open Admin on Startup** toggle. | | Managed configuration could not disable browser launch. | Admin changes persist for the next server launch without restarting the running proxy. | | Browser launch defaulted on through launcher fallback logic. | Browser launch defaults on through the canonical Settings and template contract. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR exposes the Admin startup browser preference through the normal settings flow. The main changes are: - Added `FCC_OPEN_BROWSER` as a typed setting with a default of enabled. - Added an Admin runtime toggle for opening the Admin UI on startup. - Updated the launcher to use the typed setting instead of reading the environment directly. - Persisted Admin changes to the managed env file for the next launch. - Clarified the README startup wording. - Bumped the package version to `4.1.0` in project metadata and the lockfile. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. No blocking issues found in the changed code. None. <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** - T-Rex captured the before-change UI state in the /admin Runtime, showing Open Admin on Startup enabled. - T-Rex captured the after-change UI state in the /admin Runtime, showing Open Admin on Startup disabled and the change applied. - T-Rex generated the harness and collected the end-to-end run, including a Playwright video and server/run logs. - T-Rex compiled raw Admin API responses and parsed persistence evidence confirming FCC\_OPEN\_BROWSER=false. <a href="https://app.greptile.com/trex/runs/14197066/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 | |----------|----------| | README.md | Clarifies that browser opening is the default startup behavior and that the Admin URL is logged. | | pyproject.toml | Bumps the project version to `4.1.0` for the new Admin settings feature. | | uv.lock | Updates the editable package version to match `pyproject.toml`. | | src/free_claude_code/cli/entrypoints.py | Routes Admin browser launch through the typed setting and keeps the one-open-per-process guard. | | src/free_claude_code/config/settings.py | Adds the `open_admin_browser` setting backed by `FCC_OPEN_BROWSER`. | | src/free_claude_code/config/admin/manifest.py | Adds the Admin manifest entry for the startup browser toggle. | | tests/api/test_admin.py | Adds coverage for Admin exposure and persistence of the browser toggle. | | tests/cli/test_entrypoints.py | Updates launcher tests for the settings-based browser launch path. | | tests/config/test_config.py | Adds coverage for the default and environment-loaded browser setting. | </details> <sub>Reviews (2): Last reviewed commit: ["Address release and documentation review"](https://github.com/alishahryar1/free-claude-code/commit/9e83287f80fc7268ec7255006409e61ca429753a) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=43730287)</sub> <!-- /greptile_comment --> |
||
|
|
4951983b5e |
Replace global runtime resources with explicit ownership (#1042)
## Problem Provider, messaging, and transcription resources relied on process-global state, leaving replacement, cancellation, and shutdown ownership ambiguous. Separate server lifetimes could share event-loop-bound resources or retain failed cleanup work. ## Changes | Before | After | | --- | --- | | Provider clients found limiters through global singleton and scoped registries. | Each provider instance receives and owns one explicitly constructed limiter. | | Messaging queues and voice pipelines relied on singleton or module-global state. | Each platform owns its limiter and outbox, while the application owns one injected transcriber. | | Messaging shutdown mixed ingress, active work, delivery, and SDK cleanup. | Application shutdown quiesces ingress, drains work, closes delivery, then releases transcription and providers. | | Cancelled or failed provider cleanup could be forgotten or treated as complete. | The provider manager retains shielded generation and unpublished-runtime cleanup until it succeeds. | | Discord and Telegram startup tasks could outlive or poison runtime readiness. | Platform runtimes observe long-lived tasks and retry only independently repeatable lifecycle steps. | | Constructor-captured security and diagnostic settings appeared hot-applicable. | Admin marks those settings restart-required so applied policy matches the running resource graph. | | Lifecycle races lacked direct ownership coverage. | Deterministic cancellation, retry, isolation, teardown, and live smoke contracts protect the final ownership model. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR moves runtime resources from global state into explicitly owned application objects. The main changes are: - Provider generations own their rate limiters and cleanup tasks. - Messaging platforms own their limiter, outbox, ingress, and delivery lifecycle. - Application shutdown now runs through ordered cleanup gates. - Voice transcription is injected as an owned runtime resource. - Admin config marks constructor-captured settings as restart-required. </details> <h3>Confidence Score: 4/5</h3> The shutdown path needs a bounded cleanup result before merging. Cleanup steps that hang never reach the retryable incomplete-shutdown path. ASGI shutdown can remain stuck while waiting for an external SDK, transcriber, workflow, or provider cleanup. The retry ownership model works only after cleanup returns or raises. src/free_claude_code/runtime/application.py <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** - T-Rex ran the requested verification, but its local artifact references were not uploaded. - The validation run completed successfully with EXIT\_CODE: 0 and 62 tests passed in 3.91 seconds, using the command uv run pytest -vv tests/runtime/test\_application\_runtime.py tests/runtime/test\_provider\_manager.py tests/providers/test\_provider\_runtime.py. <a href="https://app.greptile.com/trex/runs/14064214/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/runtime/application.py | Refactors shutdown into ordered retryable cleanup gates, but cleanup awaitables can still block shutdown forever. | | src/free_claude_code/runtime/asgi.py | Reports incomplete runtime shutdown when `close()` returns false. | | src/free_claude_code/runtime/provider_manager.py | Adds owned provider cleanup retry state and shielded generation cleanup. | </details> <a href="https://app.greptile.com/api/ide/codex?prompt=IMPORTANT%3A%20Work%20in%20the%20repository%20%22alishahryar1%2Ffree-claude-code%22%20on%20the%20existing%20branch%20%22refactor%2Fruntime-owned-resources%22.%20Checkout%20that%20branch%20%E2%80%94%20do%20NOT%20create%20a%20new%20branch%20or%20open%20a%20new%20PR.%20Push%20your%20changes%20to%20%22refactor%2Fruntime-owned-resources%22.%0A%0AFix%20the%20following%201%20code%20review%20issue.%20Work%20through%20them%20one%20at%20a%20time%2C%20proposing%20concise%20fixes.%0A%0A---%0A%0A%23%23%23%20Issue%201%20of%201%0Asrc%2Ffree_claude_code%2Fruntime%2Fapplication.py%3A59%0A**Cleanup%20Await%20Blocks%20Shutdown**%0A%0AWhen%20a%20platform%20SDK%20stop%2C%20workflow%20drain%2C%20transcriber%20close%2C%20or%20provider%20cleanup%20hangs%2C%20this%20helper%20waits%20forever%20and%20never%20returns%20%60False%60.%20ASGI%20shutdown%20stays%20stuck%20in%20%60runtime.close%28%29%60%20instead%20of%20reporting%20an%20incomplete%20shutdown%2C%20so%20the%20retained%20resource%20graph%20cannot%20be%20retried%20cleanly.%0A%0A&repo=alishahryar1%2Ffree-claude-code&pr=1042&platform=github"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodexDark.svg?v=6"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"><img alt="Fix All in Codex" src="https://greptile-static-assets.s3.amazonaws.com/badges/FixAllInCodex.svg?v=6"></picture></a> <sub>Reviews (2): Last reviewed commit: ["Report incomplete runtime shutdown to AS..."](https://github.com/alishahryar1/free-claude-code/commit/338b2bd179c3875b15bbd52818dd04c780e5d46d) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=43454593)</sub> > Greptile also left **1 inline comment** on this PR. **Context used:** - Context used - CLAUDE.md ([source](https://app.greptile.com/alishahryar1/github/Alishahryar1/free-claude-code/-/custom-context?memory=d2fd24d8-0dec-4faf-8ee4-e085e215a2f8)) <!-- /greptile_comment --> |
||
|
|
160d63370b |
Establish single-owner runtime with stream-safe provider hot swaps (#1036)
## Problem Provider runtime ownership was split between lifecycle code and mutable FastAPI state, so Admin replacements could leak the new runtime, double-close the old runtime, or close providers still serving active streams. The API package also owned concrete process composition, obscuring subsystem boundaries. ## Changes | Before | After | | --- | --- | | FastAPI routes inspected several concrete `app.state` resources. | FastAPI receives one explicit `ApiServices` boundary and stores only `app.state.services`. | | Admin Apply persisted config and directly replaced one runtime reference. | Admin Apply validates a candidate, commits atomically, and publishes it through the single runtime owner. | | Provider replacement could close clients used by active streams. | Generation leases retain old providers until each streaming or non-streaming response finishes. | | Provider generations owned discovery state and model metadata. | `ProviderRuntimeManager` owns one application-lifetime catalog and one discovery task across replacements. | | API modules composed provider, messaging, and managed CLI resources. | `runtime.bootstrap` composes concrete subsystems and `ApplicationRuntime` owns their lifecycle. | | Admin config, server URLs, and gateway model IDs lived under the API package. | Admin config lives under `config`, server URLs live under `config`, and gateway IDs live under `core`. | | Messaging restoration and shutdown persistence were coordinated externally. | `MessagingWorkflow` owns snapshot restoration and final persistence flushing. | | Hot-swap behavior lacked a real process-level race scenario. | Deterministic ownership tests and a credential-free subprocess smoke hold provider A while new requests switch to provider B. | | Package version was `3.4.16`. | Package version is `3.4.17` with an updated lockfile. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR centralizes server runtime ownership and provider hot swaps. The main changes are: - Adds `ApplicationRuntime` and `ProviderRuntimeManager` as the process owners. - Moves FastAPI to an explicit `ApiServices` boundary. - Retains provider generations until request and stream responses finish. - Moves admin config, server URL, and gateway model ID modules to neutral package owners. - Updates admin apply to validate, persist, and publish provider-only changes through the runtime owner. - Adds runtime ownership tests and a credential-free smoke scenario. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. No blocking issues found in the changed code. The provider lease path releases resources on normal completion, stream close, and cancellation. The admin apply path keeps restart-required changes separate from provider-only hot swaps, and repository import paths appear updated for the moved modules. No files need follow-up 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** - Ran the T-Rex smoke test command and confirmed it completed with exit code 0 and pytest passing. - Monitored runtime ownership activity during the run, including a provider A stream request on model-a generation 1, an admin publish to generation 2, a new request on model-b generation 2, and the completion of the original generation 1 stream. - Collected smoke result artifacts from the .smoke-results area for gateway 1, gateway 0, and main, and made them available for review. - Opened the smoke report JSON artifacts to review the summarized outcomes for each target environment. <a href="https://app.greptile.com/trex/runs/14008910/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/runtime/provider_manager.py | Adds provider generation ownership, request leases, replacement, discovery refresh, and shutdown cleanup. | | src/free_claude_code/runtime/application.py | Adds the process-level owner for startup, shutdown, admin operations, messaging, and session control. | | src/free_claude_code/api/routes.py | Routes now acquire provider generation leases and bind them to response lifetime. | | src/free_claude_code/api/response_streams.py | Adds response lifetime binding so retained resources release after stream completion, cancellation, or close. | | src/free_claude_code/config/admin/persistence.py | Moves admin config persistence into `config` and adds prepared validation plus atomic managed-env commits. | | src/free_claude_code/runtime/bootstrap.py | Adds the production composition root for logging, runtime owners, services, and ASGI wiring. | | src/free_claude_code/api/__init__.py | Removes package-level API re-exports as part of the HTTP adapter boundary cleanup. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant Client participant API as FastAPI Route participant Manager as ProviderRuntimeManager participant Lease as Generation Lease participant Runtime as Provider Generation participant Admin as Admin Apply Client->>API: Request /v1/messages or /v1/responses API->>Manager: acquire() Manager-->>API: lease for current generation API->>Lease: resolve_provider() Lease->>Runtime: use provider instance Runtime-->>Client: response body or stream Admin->>Manager: replace(candidate settings) Manager->>Manager: publish new generation Manager->>Manager: retire old generation Client-->>API: response completes or disconnects API->>Lease: release() Lease->>Manager: decrement active leases Manager->>Runtime: cleanup retired generation when drained ``` </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 Client participant API as FastAPI Route participant Manager as ProviderRuntimeManager participant Lease as Generation Lease participant Runtime as Provider Generation participant Admin as Admin Apply Client->>API: Request /v1/messages or /v1/responses API->>Manager: acquire() Manager-->>API: lease for current generation API->>Lease: resolve_provider() Lease->>Runtime: use provider instance Runtime-->>Client: response body or stream Admin->>Manager: replace(candidate settings) Manager->>Manager: publish new generation Manager->>Manager: retire old generation Client-->>API: response completes or disconnects API->>Lease: release() Lease->>Manager: decrement active leases Manager->>Runtime: cleanup retired generation when drained ``` </a> </details> <sub>Reviews (1): Last reviewed commit: ["refactor: establish single-owner applica..."](https://github.com/alishahryar1/free-claude-code/commit/92fc06aa733b7acc34ad6ea50de8b6b4ce5cfac1) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=43349002)</sub> <!-- /greptile_comment --> |
||
|
|
71a78a0c5a |
Move runtime packages under src namespace (#1029)
## Problem Runtime modules were published as generic top-level packages like `api`, `cli`, and `providers`. That shape is fragile for PyPI packaging and weakens explicit ownership boundaries. ## Changes | Before | After | | --- | --- | | Runtime code lived in root-level packages. | Runtime code lives under `src/free_claude_code/`. | | Console scripts targeted top-level modules. | Console scripts target namespaced modules. | | Tests and smoke helpers imported old package roots. | Tests and smoke helpers import `free_claude_code.*`. | | Packaging listed six root packages. | Packaging builds the single namespaced package. | | Contracts allowed old root package directories. | Contracts require the src namespace and reject old root imports. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR moves the runtime packages into the `src/free_claude_code` namespace. The main changes are: - Console scripts now point to `free_claude_code.*` entrypoints. - Runtime imports, tests, and smoke helpers now use the namespaced package. - Packaging now builds the single `src/free_claude_code` package. - Contract tests now reject old top-level runtime package roots and imports. </details> <h3>Confidence Score: 5/5</h3> This PR is safe to merge with minimal risk. The changes are a broad but mostly mechanical namespace and package-layout migration with updated packaging, tests, and contract coverage. 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** - Reviewed the primary contract validation by examining the namespace validation log, which documents the exact commands executed, the working directory, exit codes, pytest output, wheel build output, install output, and import/entrypoint resolution. - Verified the wheel listing by inspecting the wheel listing artifact, confirming the available wheel filenames for the namespace validation. - Ran and inspected the isolated import/entrypoint validation harness saved as package-installed-import-check.py to validate import resolution and entrypoint exposure. - Captured and noted the wheel filename record in package-wheel-filename.txt to enable traceability of the observed artifact. <a href="https://app.greptile.com/trex/runs/13810533/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 | |----------|----------| | pyproject.toml | Updates packaging to build the single `src/free_claude_code` package and retargets console scripts to namespaced modules. | | src/free_claude_code/config/env_template.py | Loads `.env.example` from packaged resources with a source-checkout fallback after the runtime package move. | | src/free_claude_code/cli/entrypoints.py | Updates CLI entrypoint imports to `free_claude_code.*` and continues to use the shared env template loader. | | src/free_claude_code/api/routes.py | Retargets API route dependencies and handlers to the namespaced package without changing route behavior. | | src/free_claude_code/api/app.py | Updates app factory imports to the namespaced package while preserving middleware, routers, and exception handling. | | src/free_claude_code/providers/runtime/factory.py | Updates lazy provider factory imports to `free_claude_code.providers.*` under the new package layout. | | tests/contracts/test_import_boundaries.py | Adds contract coverage requiring runtime packages to live under `src/free_claude_code` and rejecting old top-level imports. | | smoke/lib/child_process.py | Updates smoke child-process helpers to import CLI entrypoints from the namespaced package. | | README.md | Updates the project layout and extension guidance to refer to `src/free_claude_code` and importable `free_claude_code.*` modules. | | uv.lock | Reflects the package version bump associated with the runtime packaging move. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant User as User / CLI participant Script as Console script participant Pkg as free_claude_code package participant API as free_claude_code.api participant Runtime as free_claude_code.providers.runtime participant Provider as Provider adapter User->>Script: run fcc-server / free-claude-code Script->>Pkg: load free_claude_code.cli.entrypoints:serve Pkg->>API: create FastAPI app and routes API->>Runtime: resolve configured provider Runtime->>Provider: instantiate namespaced adapter Provider-->>Runtime: stream/model responses Runtime-->>API: provider result API-->>User: Anthropic/OpenAI-compatible response ``` </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 / CLI participant Script as Console script participant Pkg as free_claude_code package participant API as free_claude_code.api participant Runtime as free_claude_code.providers.runtime participant Provider as Provider adapter User->>Script: run fcc-server / free-claude-code Script->>Pkg: load free_claude_code.cli.entrypoints:serve Pkg->>API: create FastAPI app and routes API->>Runtime: resolve configured provider Runtime->>Provider: instantiate namespaced adapter Provider-->>Runtime: stream/model responses Runtime-->>API: provider result API-->>User: Anthropic/OpenAI-compatible response ``` </a> </details> <sub>Reviews (2): Last reviewed commit: ["Fix documented package import paths"](https://github.com/alishahryar1/free-claude-code/commit/bfa9f2704c45f3684da39657d5e13f3814e5d450) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=42950471)</sub> <!-- /greptile_comment --> |
||
|
|
05dae97248 | add telegram proxy support (#988) | ||
|
|
15cab79a43 | Update GLM 5.2 model references | ||
|
|
770d56708a | Add SambaNova Cloud provider (#990) | ||
|
|
0b86dd4ef8 |
Add GitHub Models provider (#989)
## Problem FCC does not expose GitHub Models, so users with GitHub Models access cannot route Claude, Codex, or messaging prompts through GitHub's hosted model catalog. ## Changes | Before | After | | --- | --- | | Provider catalog did not include GitHub Models. | Provider catalog includes `github_models` with token, proxy, admin, smoke, and model picker wiring. | | Requests could not target GitHub Models inference. | `providers/github_models` routes OpenAI-chat requests to `https://models.github.ai/inference`. | | Model discovery assumed provider `/models` compatibility. | GitHub Models discovery uses the catalog API and advertises stream/tool-capable models. | | OpenAI-chat transport could not set provider default headers. | OpenAI-chat transport accepts provider-owned default headers. | | Docs and templates omitted GitHub Models setup. | README, `.env.example`, and architecture docs document GitHub Models setup and ownership. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds GitHub Models as a new provider. The main changes are: - New `github_models` provider runtime, catalog, settings, and admin wiring. - OpenAI-chat transport support for provider-owned default headers. - GitHub Models catalog discovery filtered to streaming and tool-capable models. - Smoke configuration, environment template, docs, and tests for the new provider. - Package version and lockfile updates for the new feature. </details> <h3>Confidence Score: 5/5</h3> Safe to merge with low risk. The provider is wired through runtime creation, catalog metadata, settings, admin fields, smoke config, docs, version metadata, and focused tests. No blocking correctness or security issues were found in the changed paths. 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** - Before-change focused pytest run against HEAD^ showed no GitHub Models provider tests were collected. - After-change focused pytest run showed all 37 provider/runtime tests passed. - After-change harness output captured structured evidence for catalog discovery and OpenAI-chat request routing, and the harness exited successfully. - A temporary harness Python script was generated to capture the mocked request/response evidence. <a href="https://app.greptile.com/trex/runs/13317138/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 | |----------|----------| | providers/github_models/client.py | Implements GitHub Models OpenAI-chat transport wiring, default GitHub headers, and catalog-based stream/tool-capable model discovery. | | providers/transports/openai_chat/transport.py | Allows OpenAI-chat providers to pass default headers into the shared AsyncOpenAI client. | | config/provider_catalog.py | Registers GitHub Models provider metadata, default inference base URL, credential, proxy, and capabilities. | | config/settings.py | Adds settings bindings for `GITHUB_MODELS_TOKEN` and `GITHUB_MODELS_PROXY`. | | api/admin_config/provider_manifest.py | Adds GitHub Models token labeling and description for generated admin provider fields. | | smoke/lib/config.py | Adds GitHub Models smoke defaults and credential detection. | | tests/providers/test_github_models.py | Adds focused tests for GitHub Models initialization, request conversion, catalog filtering, streaming, tool calls, reasoning, and cleanup. | | tests/providers/test_provider_runtime.py | Covers GitHub Models descriptor, provider config construction, and runtime instantiation. | | README.md | Adds GitHub Models setup documentation and updates provider counts/numbering. | | pyproject.toml | Bumps the package version to `3.2.0` for the new provider feature. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant User as Claude/Codex client participant FCC as FCC proxy/router participant Factory as Provider runtime factory participant GH as GitHubModelsProvider participant OpenAI as Shared OpenAI-chat transport participant API as models.github.ai User->>FCC: Request with model `github_models/...` FCC->>Factory: create_provider(`github_models`, settings) Factory->>GH: ProviderConfig(token, base_url, proxy) GH->>OpenAI: Initialize with GitHub default headers FCC->>GH: stream_response(MessagesRequest) GH->>OpenAI: build OpenAI chat body OpenAI->>API: "POST /inference/chat/completions (stream=true)" API-->>OpenAI: OpenAI-compatible stream chunks OpenAI-->>FCC: Anthropic SSE events FCC-->>User: Streamed Anthropic response FCC->>GH: list_model_infos() GH->>API: GET /catalog/models API-->>GH: Catalog entries with capabilities GH-->>FCC: stream/tool-capable model ids ``` </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 Claude/Codex client participant FCC as FCC proxy/router participant Factory as Provider runtime factory participant GH as GitHubModelsProvider participant OpenAI as Shared OpenAI-chat transport participant API as models.github.ai User->>FCC: Request with model `github_models/...` FCC->>Factory: create_provider(`github_models`, settings) Factory->>GH: ProviderConfig(token, base_url, proxy) GH->>OpenAI: Initialize with GitHub default headers FCC->>GH: stream_response(MessagesRequest) GH->>OpenAI: build OpenAI chat body OpenAI->>API: "POST /inference/chat/completions (stream=true)" API-->>OpenAI: OpenAI-compatible stream chunks OpenAI-->>FCC: Anthropic SSE events FCC-->>User: Streamed Anthropic response FCC->>GH: list_model_infos() GH->>API: GET /catalog/models API-->>GH: Catalog entries with capabilities GH-->>FCC: stream/tool-capable model ids ``` </a> </details> <sub>Reviews (1): Last reviewed commit: ["Add GitHub Models provider"](https://github.com/alishahryar1/free-claude-code/commit/736d3f9213f6a8d243d4001c5135b7fac402f143) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=41901295)</sub> <!-- /greptile_comment --> |
||
|
|
9a17d1ed0a |
Add Cohere provider (#986)
## Problem FCC does not expose Cohere's OpenAI-compatible chat models, so users with Cohere keys cannot route Claude, Codex, or messaging prompts through Cohere. ## Changes | Before | After | | --- | --- | | Provider catalog did not include Cohere. | Provider catalog includes Cohere with `COHERE_API_KEY`, `COHERE_PROXY`, admin status, and smoke model wiring. | | Requests could not target Cohere's compatibility API. | `providers/cohere` routes OpenAI-chat requests to Cohere's compatibility API with Cohere-specific request policy. | | Docs and templates omitted Cohere setup. | README, `.env.example`, and architecture docs document Cohere setup and ownership. | | Cohere behavior had no regression coverage. | Provider, runtime, admin, config, smoke, and catalog tests cover Cohere integration. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds Cohere as a new OpenAI-compatible chat provider. The main changes are: - Cohere provider metadata in the catalog, settings, Admin UI manifest, and runtime factory. - A new `CohereProvider` using the shared OpenAI chat transport with Cohere-specific request shaping. - Cohere API key, proxy, smoke model, README, architecture, and environment template updates. - Tests for Admin config, settings, provider catalog order, smoke config, runtime creation, and Cohere request/stream behavior. - Version and lockfile updates for the new provider feature. </details> <h3>Confidence Score: 5/5</h3> Safe to merge with minimal risk. No functional, security, or contract issues were identified. Cohere is consistently wired through settings, catalog metadata, factory creation, Admin config, smoke defaults, docs, versioning, and targeted tests. The implemented Cohere `reasoning_effort` values match the Compatibility API behavior checked during review. 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** - Validated the provider runtime handling of Cohere requests, including the request body policy, streaming parsing, and default base URL and API key behavior. - Verified that the runtime descriptor wiring and provider config proxy/key behavior pass in the general contract validation. - Confirmed the admin/config smoke contract artifact shows the Cohere environment settings, admin config masking, feature/provider catalog contracts, and smoke configuration passing. - Compared the initial -01-before.log and the clean -02-after.log captures to confirm the same scoped commands are present and both exit with code 0. <a href="https://app.greptile.com/trex/runs/13309850/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 | |----------|----------| | providers/cohere/client.py | Implements Cohere request shaping over shared OpenAI chat transport, including allowed extra body and reasoning mapping; no issues found. | | config/provider_catalog.py | Registers Cohere with credential, proxy, base URL, transport, and capability metadata; no issues found. | | providers/runtime/factory.py | Wires Cohere into runtime provider factory dispatch; no issues found. | | config/settings.py | Adds Cohere API key and proxy settings aliases; no issues found. | | api/admin_config/provider_manifest.py | Adds Cohere API key labeling/description through catalog-derived Admin fields; no issues found. | | smoke/lib/config.py | Adds Cohere default smoke model and credential detection; no issues found. | | tests/providers/test_cohere.py | Adds request-policy and streaming adapter tests for the Cohere provider; no issues found. | | tests/providers/test_provider_runtime.py | Adds Cohere descriptor, config build, and factory instantiation coverage; no issues found. | | README.md | Adds Cohere setup instructions and updates provider counts/order; no issues found. | | pyproject.toml | Bumps package version for the new provider feature; no issues found. | | uv.lock | Updates the lockfile package version to match `pyproject.toml`; no issues found. | </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 config participant Catalog as Provider catalog/settings participant Factory as Runtime factory participant Cohere as CohereProvider participant Transport as OpenAI chat transport participant API as Cohere Compatibility API User->>Catalog: "Configure MODEL=cohere/... and COHERE_API_KEY" Catalog->>Factory: Build ProviderConfig for provider_id cohere Factory->>Cohere: Instantiate CohereProvider(config) Cohere->>Transport: Build chat body with Cohere policy Transport->>API: "POST /chat/completions stream=true" API-->>Transport: Streaming OpenAI-compatible chunks Transport-->>User: Anthropic SSE events ``` </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 config participant Catalog as Provider catalog/settings participant Factory as Runtime factory participant Cohere as CohereProvider participant Transport as OpenAI chat transport participant API as Cohere Compatibility API User->>Catalog: "Configure MODEL=cohere/... and COHERE_API_KEY" Catalog->>Factory: Build ProviderConfig for provider_id cohere Factory->>Cohere: Instantiate CohereProvider(config) Cohere->>Transport: Build chat body with Cohere policy Transport->>API: "POST /chat/completions stream=true" API-->>Transport: Streaming OpenAI-compatible chunks Transport-->>User: Anthropic SSE events ``` </a> </details> <sub>Reviews (1): Last reviewed commit: ["Add Cohere provider"](https://github.com/alishahryar1/free-claude-code/commit/7956802968fc6ce63bb71fe6d7503d484df56b79) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=41887611)</sub> <!-- /greptile_comment --> |
||
|
|
d4683bf3f6 |
Add Hugging Face inference provider (#985)
## Problem FCC did not expose Hugging Face Inference Providers as a selectable backend. Voice transcription also used the legacy `HF_TOKEN` setting instead of the canonical Hugging Face API key. ## Changes | Before | After | | --- | --- | | Hugging Face models could not be selected through provider-prefixed routing. | Hugging Face routes through a thin OpenAI-chat provider using `huggingface/<model>`. | | Provider credentials did not include `HUGGINGFACE_API_KEY`. | Admin config, settings, smoke config, and docs use `HUGGINGFACE_API_KEY`. | | `HF_TOKEN` remained a voice-only config key. | Owned dotenv files migrate `HF_TOKEN` to `HUGGINGFACE_API_KEY`, while explicit `FCC_ENV_FILE` users get a warning. | | Version metadata stayed on `2.6.0`. | Version metadata moves to `3.0.0` with a refreshed lockfile. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds Hugging Face Inference Providers as a selectable backend. The main changes are: - Adds a `huggingface` provider using the shared OpenAI-compatible chat transport. - Wires `HUGGINGFACE_API_KEY` and `HUGGINGFACE_PROXY` through settings, Admin UI, provider catalog, runtime factory, and smoke config. - Migrates owned dotenv files from `HF_TOKEN` to `HUGGINGFACE_API_KEY` and warns for explicit `FCC_ENV_FILE` users. - Updates voice transcription plumbing to use the canonical Hugging Face key. - Updates docs, examples, version metadata, lockfile, and related tests. </details> <h3>Confidence Score: 5/5</h3> Safe to merge with minimal risk. No blocking correctness or security issues were identified. The new provider reuses the existing OpenAI-chat transport pattern. Provider wiring, env migration, Admin UI, smoke config, voice plumbing, and tests are consistent. 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 Pytest suite for providers, runtime, env migrations, config, and contract tests ran and completed with exit code 0 and 198 tests passed. - The HuggingFace runtime validator script ran and completed successfully, printing provider\_class=HuggingFaceProvider, default\_base\_url=https://router.huggingface.co/v1, credential\_env=HUGGINGFACE\_API\_KEY, and admin\_field=HUGGINGFACE\_API\_KEY:\[REDACTED\]. - Logs from both runs were captured as artifacts to aid review. <a href="https://app.greptile.com/trex/runs/13308618/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 | |----------|----------| | providers/huggingface/client.py | Implements Hugging Face via the shared OpenAI-chat transport with `extra_body` passthrough. | | config/provider_catalog.py | Registers Hugging Face metadata, default router URL, credential, proxy, and capabilities. | | providers/runtime/factory.py | Wires Hugging Face into runtime provider construction. | | config/env_migrations.py | Adds safe `HF_TOKEN` to `HUGGINGFACE_API_KEY` dotenv migration helpers for owned env files. | | config/settings.py | Adds Hugging Face API key/proxy settings and removes the legacy `hf_token` setting. | | api/admin_config/manifest.py | Removes the voice-only `HF_TOKEN` field and adds Hugging Face smoke model configuration. | | api/admin_config/provider_manifest.py | Adds Admin UI labeling and description for `HUGGINGFACE_API_KEY`. | | messaging/transcription.py | Renames local Whisper token handling to use the canonical Hugging Face API key. | | smoke/lib/config.py | Adds Hugging Face smoke-test default model and credential detection. | | tests/providers/test_huggingface.py | Adds provider tests for Hugging Face base URL, request body policy, streaming, and cleanup. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant User as Admin/User participant Settings as Settings + dotenv migration participant Catalog as Provider Catalog participant Runtime as Provider Runtime Factory participant HF as HuggingFaceProvider participant Router as router.huggingface.co/v1 User->>Settings: "Configure MODEL=huggingface/<model> and HUGGINGFACE_API_KEY" Settings->>Settings: Rename owned HF_TOKEN to HUGGINGFACE_API_KEY when present Settings->>Catalog: Resolve huggingface descriptor and credential/proxy attrs Catalog->>Runtime: Build ProviderConfig for huggingface Runtime->>HF: Create HuggingFaceProvider HF->>Router: Stream OpenAI-compatible chat completion Router-->>HF: Streaming chunks HF-->>User: Anthropic SSE response ``` </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 Admin/User participant Settings as Settings + dotenv migration participant Catalog as Provider Catalog participant Runtime as Provider Runtime Factory participant HF as HuggingFaceProvider participant Router as router.huggingface.co/v1 User->>Settings: "Configure MODEL=huggingface/<model> and HUGGINGFACE_API_KEY" Settings->>Settings: Rename owned HF_TOKEN to HUGGINGFACE_API_KEY when present Settings->>Catalog: Resolve huggingface descriptor and credential/proxy attrs Catalog->>Runtime: Build ProviderConfig for huggingface Runtime->>HF: Create HuggingFaceProvider HF->>Router: Stream OpenAI-compatible chat completion Router-->>HF: Streaming chunks HF-->>User: Anthropic SSE response ``` </a> </details> <sub>Reviews (1): Last reviewed commit: ["Add Hugging Face inference provider"](https://github.com/alishahryar1/free-claude-code/commit/7341d9a923986ac84d5e4fdf858128f913f3e5d3) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=41885587)</sub> <!-- /greptile_comment --> |
||
|
|
85b601884d |
Remove legacy future annotation imports (#982)
## Problem Python 3.14 provides native lazy annotations, but the codebase still relied on legacy future annotation imports. Those imports also made type-only import cycles easier to hide instead of fixing ownership boundaries. ## Changes | Before | After | | --- | --- | | Python files used `from __future__ import annotations`. | Python files rely on Python 3.14 native lazy annotations. | | Some runtime modules used `TYPE_CHECKING` or local imports for required dependencies. | Runtime modules use top-level owner-module imports with explicit boundaries. | | Local and GitHub guardrails only rejected type ignore suppressions. | Local and GitHub guardrails reject type ignore suppressions and legacy future annotation imports. | | Agent docs only documented the no-type-ignore rule. | Agent docs document the Python 3.14 annotation and import-boundary rules. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR moves the codebase to Python 3.14 native lazy annotations. The main changes are: - Removed legacy `from __future__ import annotations` imports across Python modules. - Promoted selected runtime dependencies from `TYPE_CHECKING` or local imports to explicit owner-module imports. - Added local, GitHub, and contract-test guardrails to reject legacy future annotation imports. - Updated agent docs with the annotation and import-boundary rules. - Bumped the package patch version for production-file changes. </details> <h3>Confidence Score: 5/5</h3> Safe to merge with low risk. The changes are mostly mechanical annotation cleanup with matching CI and contract-test guardrails. Reviewed import-boundary updates did not show a confirmed runtime cycle or dependency break. 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** - Performed an end-to-end validation of the guardrail contract suite: an environment check confirmed uv availability, a guardrail pytest run used CPython 3.14.0 with 5 passing contract tests, 3 focused CI-script tests passed, and the direct CI suppressions guardrail command (including the legacy future-annotations grep) also passed. <a href="https://app.greptile.com/trex/runs/13303335/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 | |----------|----------| | api/runtime.py | Moves messaging, CLI manager, session, limiter, and tree dependencies from local/type-checking imports to explicit top-level owner-module imports. | | messaging/platforms/telegram.py | Removes future annotations and promotes Telegram SDK type imports into the existing availability guard. | | messaging/platforms/telegram_inbound.py | Removes future annotations and imports Telegram SDK types at module scope for inbound normalization. | | tests/contracts/test_import_boundaries.py | Adds an AST contract that rejects legacy future annotation imports across Python files. | | scripts/ci.sh | Extends the local suppression check to reject legacy future annotation imports alongside type-ignore suppressions. | | scripts/ci.ps1 | Mirrors the local PowerShell CI suppression check for legacy future annotations. | | .github/workflows/tests.yml | Renames and broadens the GitHub guardrail job to reject both type suppressions and legacy future annotations. | | pyproject.toml | Bumps the patch version for production-file changes. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant Dev as Developer/CI participant Guard as Suppression guard participant AST as Import-boundary contract test participant Py as Python modules Dev->>Guard: Run local/GitHub suppression check Guard->>Py: "Scan *.py for type ignores and future annotations" Guard-->>Dev: Fail if legacy annotation import remains Dev->>AST: Run pytest contract tests AST->>Py: Parse imports with ast AST-->>Dev: Assert no future annotations/import-boundary violations Py-->>Dev: Use Python 3.14 native lazy annotations ``` </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 Dev as Developer/CI participant Guard as Suppression guard participant AST as Import-boundary contract test participant Py as Python modules Dev->>Guard: Run local/GitHub suppression check Guard->>Py: "Scan *.py for type ignores and future annotations" Guard-->>Dev: Fail if legacy annotation import remains Dev->>AST: Run pytest contract tests AST->>Py: Parse imports with ast AST-->>Dev: Assert no future annotations/import-boundary violations Py-->>Dev: Use Python 3.14 native lazy annotations ``` </a> </details> <sub>Reviews (2): Last reviewed commit: ["Remove legacy future annotations import"](https://github.com/alishahryar1/free-claude-code/commit/6e6cda69da243bbdb92831207aecb3731ad469f8) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=41875785)</sub> <!-- /greptile_comment --> |
||
|
|
bd51575430 | Fix Cloudflare Workers AI transport (#971) | ||
|
|
478e96655c | Add Cloudflare provider (#933) | ||
|
|
51157f91bd |
Refactor admin config into catalog-driven package (#926)
## Problem Admin config was a single responsibility hub with manually duplicated provider metadata. Provider labels, fields, template loading, validation, persistence, and status lived in one place. ## Changes | Before | After | | --- | --- | | Admin config lived in one large `api/admin_config.py` module. | Admin config lives in package modules for manifest, sources, values, validation, persistence, and status. | | Provider admin fields and UI labels were manually duplicated. | Provider admin fields and display names derive from `PROVIDER_CATALOG` with admin-only help overrides. | | `fcc-init` and Admin UI loaded `.env.example` separately. | `fcc-init` and Admin UI use shared `config.env_template` loading. | | Architecture docs pointed to the old admin config module. | Architecture docs describe the package owners and catalog-driven provider manifest. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR refactors admin configuration into a catalog-driven package. The main changes are: - Split the former monolithic `api/admin_config.py` into manifest, source loading, value presentation, validation, persistence, and provider status modules. - Generate provider admin fields and display names from `PROVIDER_CATALOG` with admin-specific help overrides. - Share `.env.example` loading between `fcc-init` and Admin UI defaults through `config.env_template`. - Update admin routes, Admin UI provider labels, architecture docs, version metadata, and contract/API tests for the new module layout. </details> <h3>Confidence Score: 5/5</h3> The refactor appears merge-safe with no code issues identified in the reviewed changes. The package split, catalog-driven provider metadata, shared environment template loading, route updates, and tests/docs changes are cohesive and covered by corresponding contract/API/CLI test updates. <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** - T-Rex ran manifest validation for catalog provider before and after routes, capturing base and head responses and catalog-alignment checks, and confirmed the validation completed successfully. - T-Rex evaluated the shared-env-template scenarios, observing the before run with no config.env\_template module and the after run with the module present, with patched loader values and all consistency checks passing, and the run exited with code 0. - T-Rex executed the package-admin-workflow validation, verifying the base and after import paths, the load/validate/write workflow produced matching outputs, and the run completed with exit code 0. <a href="https://app.greptile.com/trex/runs/12529845/artifacts"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=1"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=1"><img alt="View all artifacts" src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=1" height="32"></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> <sub>Reviews (1): Last reviewed commit: ["Refactor admin config into catalog-drive..."](https://github.com/alishahryar1/free-claude-code/commit/d6239d7953fce75d435b8d6a20536c1aff53aa88) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=40315222)</sub> <!-- /greptile_comment --> |
||
|
|
d501e5223a |
Fix live provider smoke defaults
Update live smoke model defaults for NIM, OpenRouter, and Gemini; normalize tool-call indexes; downgrade DeepSeek forced tool_choice; and add coverage for the provider smoke fixes. |
||
|
|
ab842fd920 | Add Cereberas Provider | ||
|
|
b2f66db0bb | Add Groq Provider | ||
|
|
1324c36da5 | Add Gemini Provider | ||
|
|
fe98abf675 |
feat(admin): add Fireworks API key and proxy to admin manifest
Registers FIREWORKS_API_KEY / FIREWORKS_PROXY in api/admin_config FIELDS so the UI can set credentials and provider status stays accurate. Adds admin apply test and contract guards linking PROVIDER_CATALOG to FIELD_BY_KEY; updates .env.example. |
||
|
|
943c3db61d |
Admin UX refactor, runtime fixes, and startup logging (#472)
## Summary - Refactors the admin interface into focused views and simplifies the header (removes noisy status labels; hides managed-source labels where appropriate). - Fixes Claude runtime settings handling, reduces Z.ai base URL leakage in the admin UI, and streamlines API startup logging. - Updates configuration and catalog behavior (including `.env.example` / README), and expands automated tests around admin, app lifespan, and config/registry behavior. ## Test plan - [ ] `uv run ruff format`, `uv run ruff check`, `uv run ty check`, `uv run pytest` - [ ] Smoke the admin UI: navigation between views, settings save/load, no sensitive URL leakage in the UI - [ ] Confirm API startup logs are readable and not overly verbose in normal operation |
||
|
|
37974db1ab |
Improve admin UX settings (#471)
## Summary - split the admin UI into Providers, Model Config, and Messaging views - remove generated env, diagnostics, smoke, managed-label, and fixed cloud/runtime settings from the visible admin UX - make Z.ai base URL, Claude workspace, and Claude CLI binary fixed app-level behavior instead of managed env fields ## Verification - uv run ruff format - uv run ruff check - uv run ty check - uv run pytest |
||
|
|
ac2c37f613 | Use canonical FCC server log path | ||
|
|
a728994e29 | Update default config and workspace paths | ||
|
|
e386a3c8aa | Improve admin UI setup flow | ||
|
|
8ee72968ed | Initial admin impl |