Spaces:
Sleeping
Sleeping
File size: 4,340 Bytes
2415446 a1bab2d 2415446 a1bab2d 2415446 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | """Model-list response construction for Claude-compatible clients."""
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel
from free_claude_code.application.ports import RequestRuntimePort
from free_claude_code.config.model_refs import configured_chat_model_refs
from free_claude_code.config.settings import Settings
from free_claude_code.core.gateway_model_ids import (
gateway_model_id,
no_thinking_gateway_model_id,
)
DISCOVERED_MODEL_CREATED_AT = "1970-01-01T00:00:00Z"
class ModelResponse(BaseModel):
object: Literal["model"] = "model"
created: int = 0
owned_by: str = "free-claude-code"
created_at: str
display_name: str
id: str
type: Literal["model"] = "model"
class ModelsListResponse(BaseModel):
object: Literal["list"] = "list"
data: list[ModelResponse]
first_id: str | None
has_more: bool
last_id: str | None
SUPPORTED_CLAUDE_MODELS = [
ModelResponse(
id="claude-fable-5",
display_name="Claude Fable 5",
created_at="2026-06-09T00:00:00Z",
),
ModelResponse(
id="claude-opus-4-20250514",
display_name="Claude Opus 4",
created_at="2025-05-14T00:00:00Z",
),
ModelResponse(
id="claude-sonnet-4-20250514",
display_name="Claude Sonnet 4",
created_at="2025-05-14T00:00:00Z",
),
ModelResponse(
id="claude-haiku-4-20250514",
display_name="Claude Haiku 4",
created_at="2025-05-14T00:00:00Z",
),
ModelResponse(
id="claude-3-opus-20240229",
display_name="Claude 3 Opus",
created_at="2024-02-29T00:00:00Z",
),
ModelResponse(
id="claude-3-5-sonnet-20241022",
display_name="Claude 3.5 Sonnet",
created_at="2024-10-22T00:00:00Z",
),
ModelResponse(
id="claude-3-haiku-20240307",
display_name="Claude 3 Haiku",
created_at="2024-03-07T00:00:00Z",
),
ModelResponse(
id="claude-3-5-haiku-20241022",
display_name="Claude 3.5 Haiku",
created_at="2024-10-22T00:00:00Z",
),
]
def build_models_list_response(
settings: Settings, runtime: RequestRuntimePort
) -> ModelsListResponse:
"""Return configured, cached, and compatibility model ids."""
models: list[ModelResponse] = []
seen: set[str] = set()
for ref in configured_chat_model_refs(settings):
supports_thinking = runtime.cached_model_supports_thinking(
ref.provider_id, ref.model_id
)
_append_provider_model_variants(
models,
seen,
ref.model_ref,
supports_thinking=supports_thinking,
)
for model_info in runtime.cached_prefixed_model_infos():
_append_provider_model_variants(
models,
seen,
model_info.model_id,
supports_thinking=model_info.supports_thinking,
)
for model in SUPPORTED_CLAUDE_MODELS:
_append_unique_model(models, seen, model)
return ModelsListResponse(
data=models,
first_id=models[0].id if models else None,
has_more=False,
last_id=models[-1].id if models else None,
)
def _discovered_model_response(model_id: str, *, display_name: str) -> ModelResponse:
return ModelResponse(
id=model_id,
display_name=display_name,
created_at=DISCOVERED_MODEL_CREATED_AT,
)
def _append_unique_model(
models: list[ModelResponse], seen: set[str], model: ModelResponse
) -> None:
if model.id in seen:
return
seen.add(model.id)
models.append(model)
def _append_provider_model_variants(
models: list[ModelResponse],
seen: set[str],
provider_model_ref: str,
*,
supports_thinking: bool | None = None,
) -> None:
if supports_thinking is not False:
_append_unique_model(
models,
seen,
_discovered_model_response(
gateway_model_id(provider_model_ref),
display_name=provider_model_ref,
),
)
_append_unique_model(
models,
seen,
_discovered_model_response(
no_thinking_gateway_model_id(provider_model_ref),
display_name=f"{provider_model_ref} (no thinking)",
),
)
|