main
3 次代码提交
| 作者 | SHA1 | 备注 | 提交日期 | |
|---|---|---|---|---|
|
|
2a676cc6d9 |
Make ProviderModelInfo the sole model-catalog contract (#1222)
## Problem Provider model discovery consumes metadata, but providers and the cache still expose a parallel IDs-only contract. The duplicate contract adds adapters and lets tests bypass capability metadata. ## Changes | Before | After | | --- | --- | | `BaseProvider` exposed `list_model_ids()` plus a metadata adapter. | `BaseProvider` exposes only abstract `list_model_infos()` returning application-owned metadata. | | Ordinary providers parsed IDs and converted them later. | Ordinary providers parse OpenAI-compatible catalogs directly into `ProviderModelInfo` values. | | OpenRouter, Cloudflare, and GitHub Models maintained redundant IDs-only wrappers. | Provider-specific filters and capability metadata have one return path. | | Vertex returned paginated IDs for the base adapter to wrap. | Vertex returns metadata after completing the same paginated discovery flow. | | The runtime cache exposed test-only raw-ID write and prefixed-ID read helpers. | The runtime cache accepts and returns metadata while retaining its production admin-status ID projection. | | Provider tests asserted the parallel IDs-only API. | Provider tests enforce the metadata-only contract and preserve provider-specific discovery behavior. | | The package version was `4.11.6`. | The package version is `4.11.7` with an updated lockfile. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR makes provider metadata the only model-catalog contract. The main changes are: - Makes `list_model_infos()` the abstract provider discovery API. - Migrates provider parsers and implementations to `ProviderModelInfo`. - Removes IDs-only cache and parser helpers. - Updates provider tests, architecture documentation, and package metadata. </details> <h3>Confidence Score: 4/5</h3> The catalog migration is consistent, but the release version must reflect the incompatible API removal. Repository provider and cache call paths use the new metadata shape consistently. Existing external consumers of the removed contracts can fail after a patch upgrade. The repository rules classify incompatible API removals as a major release. pyproject.toml and the matching package entry in uv.lock <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 external-consumer compatibility probe was run against both revisions, confirming the base still supports the legacy provider contract, while head fails with a TypeError due to the missing list\_model\_infos method, and runtime metadata shows head at version 4.11.7, indicating the removal is a patch transition rather than a major change. - An automated test suite completed successfully with 83 tests passing in 3.31 seconds. <a href="https://app.greptile.com/trex/runs/15207030/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/base.py | Replaces the IDs-only provider API with an abstract metadata-only contract. | | src/free_claude_code/providers/model_listing.py | Consolidates OpenAI-compatible parsing into ProviderModelInfo results and removes IDs-only helpers. | | src/free_claude_code/providers/runtime/model_cache.py | Removes raw-ID helpers while retaining metadata storage and the admin ID projection. | | src/free_claude_code/providers/openai_chat/provider.py | Provides the metadata discovery implementation inherited by ordinary OpenAI-compatible providers. | | src/free_claude_code/providers/vertex/client.py | Preserves paginated discovery while returning metadata values. | | pyproject.toml | Uses a patch bump for a release that removes callable and importable contracts. | </details> <details open><summary><h3>Flowchart</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% flowchart LR A[Provider catalog endpoint] --> B[list_model_infos] B --> C[ProviderModelInfo set] C --> D[Provider model discovery] D --> E[ProviderModelCache] E --> F[Metadata-aware catalog] E --> G[Admin ID projection] ``` </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 A[Provider catalog endpoint] --> B[list_model_infos] B --> C[ProviderModelInfo set] C --> D[Provider model discovery] D --> E[ProviderModelCache] E --> F[Metadata-aware catalog] E --> G[Admin ID projection] ``` </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%2Fprovider-model-info-contract%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%2Fprovider-model-info-contract%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%0Apyproject.toml%3A7%0A**Breaking%20Contract%20Ships%20as%20Patch**%0A%0AThis%20release%20removes%20%60BaseProvider.list_model_ids%28%29%60%20and%20cache%2Fparser%20methods%20that%20existing%20integrations%20can%20import%20or%20call.%20Such%20consumers%20will%20fail%20with%20%60TypeError%60%2C%20%60AttributeError%60%2C%20or%20%60ImportError%60%20after%20a%20patch%20upgrade%2C%20so%20this%20incompatible%20API%20change%20requires%20a%20major%20version%20bump%20under%20the%20repository's%20versioning%20rules.%0A%0A%60%60%60suggestion%0Aversion%20%3D%20%225.0.0%22%0A%60%60%60%0A%0A&repo=alishahryar1%2Ffree-claude-code&pr=1222&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: ["Make ProviderModelInfo the sole catalog ..."](https://github.com/alishahryar1/free-claude-code/commit/5c543eadc114201a4085d38885a27ac49153ca29) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=45869248)</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 --> |
||
|
|
af12e7b2bb |
Coordinate provider recovery under concurrent load (#1205)
## Problem Concurrent transient failures could start independent retry, replay, continuation, and repair loops while holding provider concurrency slots. This multiplied upstream attempts and could delay or strand terminal errors under fan-out. ## Changes | Before | After | | --- | --- | | Retry paths owned separate attempt budgets. | One logical-execution session caps all upstream work at five attempts. | | Concurrent failures backed off independently. | One provider-owned recovery episode elects a single half-open probe while followers coalesce. | | Backoff occupied stream concurrency. | Concurrency is held only while an upstream operation or stream is active. | | Provider catalog calls and stream creation used separate admission paths. | Every upstream operation uses one provider-generation admission controller. | | Cancellation could leave recovery ownership or follower state unresolved. | Cancellation releases permits, transfers probe ownership, and unregisters waiting followers. | | Late in-flight failures could cross an exhausted episode boundary. | Every coalesced execution retains that generation's terminal outcome. | | Replay tests allowed loose lifecycle assertions. | Exact SSE contracts prove retries and continuations emit one unduplicated response. | | Recovery wrappers could mask final diagnostics. | Final responses and traces retain the raw provider failure and request ID. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR coordinates provider recovery and retry work under concurrent load. The main changes are: - One five-attempt budget for each logical execution. - Provider-wide recovery episodes with one elected probe. - Shared admission for streams, catalog calls, rate limits, and concurrency. - Concurrency permits held only during active upstream work. - Cancellation-safe probe ownership and preserved final diagnostics. </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** - Reviewed the coordinated-recovery-01-before.log to understand how the exhausted generation outcome was not preserved in a late in-flight failure. - Reviewed the coordinated-recovery-02-after.log to confirm that the updated implementation preserves the exhausted generation outcome for the same focused contract set. - Validated that the provider-admission-full-current.log shows the complete requested test file passed under Python 3.14 with uv run pytest -n 0. <a href="https://app.greptile.com/trex/runs/15050270/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/admission.py | Adds shared admission, retry budgets, recovery episodes, probe election, and cancellation handling. | | src/free_claude_code/providers/openai_chat/provider.py | Moves stream creation, replay, continuation, and repair onto one admission-owned retry session. | | src/free_claude_code/providers/stream_recovery.py | Selects replay, continuation, repair, or final failure using the remaining shared attempt budget. | | src/free_claude_code/providers/failure_policy.py | Adds recovery exhaustion handling and preserves the underlying provider error for final classification. | | src/free_claude_code/providers/runtime/factory.py | Creates one admission controller per provider generation and passes it through provider factories. | </details> <details open><summary><h3>Sequence Diagram</h3></summary> <a href="#gh-light-mode-only"> ```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant E as Execution participant A as Admission controller participant P as Provider participant F as Concurrent follower E->>A: Open attempt A->>P: Send upstream request P-->>E: Retryable failure E->>A: Open recovery episode F->>A: Request admission A-->>F: Coalesce and wait E->>A: Claim probe A->>P: Send half-open probe alt Probe succeeds P-->>E: Valid response E->>A: Close recovery episode A-->>F: Release waiter else Probe fails P-->>E: Retryable failure E->>A: Schedule next probe or finalize error end ``` </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 E as Execution participant A as Admission controller participant P as Provider participant F as Concurrent follower E->>A: Open attempt A->>P: Send upstream request P-->>E: Retryable failure E->>A: Open recovery episode F->>A: Request admission A-->>F: Coalesce and wait E->>A: Claim probe A->>P: Send half-open probe alt Probe succeeds P-->>E: Valid response E->>A: Close recovery episode A-->>F: Release waiter else Probe fails P-->>E: Retryable failure E->>A: Schedule next probe or finalize error end ``` </a> </details> <sub>Reviews (2): Last reviewed commit: ["Harden coordinated retry lifecycle invar..."](https://github.com/alishahryar1/free-claude-code/commit/2e871c8649d148b5eb71d21f80bf870ae2d11708) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=45554917)</sub> <!-- /greptile_comment --> |
||
|
|
b89e849fff |
Add Kimi Code subscription support (#1183)
## Problem FCC's existing `kimi` provider targets Kimi Open Platform credits. Kimi Code subscription keys use a separate coding-agent endpoint, so subscribers cannot currently use their plan or select its K3 and coding models. Fixes #1161. ## Changes | Before | After | | --- | --- | | `KIMI_API_KEY` was the only Kimi contract and routed to the credit-based API platform. | `KIMI_API_KEY` remains unchanged, while `KIMI_CODE_API_KEY` routes the separate [Kimi Code subscription](https://www.kimi.com/code/docs/en/) through `https://api.kimi.com/coding/v1`. | | OpenAI-chat profiles could not declare an upstream client identity. | The Kimi Code profile sends an honest `free-claude-code` user agent as required by [Kimi's integration policy](https://www.kimi.com/code/docs/en/kimi-code/community-guidelines.html), without adding a specialized provider class. | | FCC's fallback output limit and generic token field would override Kimi's default when the client omitted a limit. | Explicit client limits become `max_completion_tokens`; omitted limits remain upstream-owned, and learned cap recovery still handles model-specific rejections. | | Kimi Code reasoning and history had no provider contract. | The profile maps FCC intent to Kimi's documented `low`, `high`, `max`, and `none` efforts and replays prior thinking through `reasoning_content`, with no model-name branching. | | Admin, model discovery, and smoke coverage knew only the credit-based Kimi provider. | Catalog-derived Admin fields, `/models` discovery, README setup, smoke configuration, and deterministic provider/runtime contracts cover `kimi_code`; the release is bumped to 4.9.0. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR adds Kimi Code subscription support as a separate provider. The main changes are: - Adds dedicated API key, proxy, endpoint, and Admin settings. - Adds Kimi-specific reasoning, token-limit, history, and user-agent behavior. - Extends model discovery and smoke configuration for `kimi_code`. - Adds provider contract tests and updates documentation. - Bumps the package and lockfile version to 4.9.0. </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** - The contract validation compared the Kimi code HTTP flow before and after the change and confirmed the after state exits with code 0 and includes Bearer authentication, User-Agent: free-claude-code, model discovery, max\_completion\_tokens, Kimi reasoning effort max, reasoning\_content replay, and omission of token/reasoning fields when unspecified. - Focused tests for the Kimi code HTTP flow were run, and 88 tests passed with exit code 0. - Artifacts document both the initial failure scenario and the successful post-change state, along with the focused tests results. <a href="https://app.greptile.com/trex/runs/14945625/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 | Registers Kimi Code with its dedicated credential, endpoint, and proxy setting. | | src/free_claude_code/config/settings.py | Adds environment-backed fields for the Kimi Code subscription key and proxy. | | src/free_claude_code/providers/openai_chat/__init__.py | Passes an optional profile user agent into the shared OpenAI-compatible client. | | src/free_claude_code/providers/openai_chat/profiles.py | Defines Kimi Code reasoning, token-limit, history replay, extra-body, and user-agent behavior. | | smoke/lib/config.py | Adds Kimi Code configuration detection and its default smoke model. | | tests/providers/test_kimi_code.py | Covers the new endpoint, headers, request mapping, reasoning behavior, and model discovery. | </details> <sub>Reviews (1): Last reviewed commit: ["Add Kimi Code subscription provider"](https://github.com/alishahryar1/free-claude-code/commit/dfc66f2755e5885775a77f5c91b4b9a82eb8fd1d) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=45309322)</sub> <!-- /greptile_comment --> |