项目文件夹

文件
Ali Khokhar 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 -->
2026-07-15 01:27:36 -07:00

20 行
507 B
Python

"""Application-owned model metadata."""
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class ProviderModelInfo:
"""Provider model metadata used to shape the application model catalog."""
model_id: str
supports_thinking: bool | None = None
@dataclass(frozen=True, slots=True)
class ProviderModelRefreshResult:
"""Per-provider outcome of one model-catalog refresh."""
refreshed_provider_ids: tuple[str, ...] = ()
failed_provider_ids: tuple[str, ...] = ()