44
55from datetime import UTC , datetime
66from pathlib import Path
7- from typing import TYPE_CHECKING
7+ from typing import TYPE_CHECKING , Any
88
99from fastapi import APIRouter , Form , Request
1010from fastapi .responses import HTMLResponse
1919)
2020from claude_code_proxy .services .model_resolver import get_model_resolver
2121
22+
2223if TYPE_CHECKING :
2324 pass
2425
3132jinja_env = Environment (loader = FileSystemLoader (str (TEMPLATES_DIR )), autoescape = True )
3233
3334
34- def _get_current_settings () -> dict :
35+ def _get_current_settings () -> dict [ str , Any ] :
3536 """Get current model resolution settings."""
3637 settings = get_model_resolution_settings ()
3738 if settings :
@@ -66,7 +67,11 @@ def _get_available_models() -> dict[str, list[str]]:
6667 }
6768 # Fallback defaults
6869 return {
69- "sonnet" : ["claude-sonnet-4-5" , "claude-sonnet-4" , "claude-3-5-sonnet-20241022" ],
70+ "sonnet" : [
71+ "claude-sonnet-4-5" ,
72+ "claude-sonnet-4" ,
73+ "claude-3-5-sonnet-20241022" ,
74+ ],
7075 "opus" : ["claude-opus-4-5" , "claude-opus-4" , "claude-3-opus-20240229" ],
7176 "haiku" : ["claude-haiku-4-5" , "claude-3-5-haiku-20241022" ],
7277 }
@@ -93,7 +98,9 @@ def _get_last_refresh() -> str | None:
9398
9499
95100@router .get ("" , response_class = HTMLResponse )
96- async def settings_page (request : Request , status_message : str | None = None ) -> HTMLResponse :
101+ async def settings_page (
102+ request : Request , status_message : str | None = None
103+ ) -> HTMLResponse :
97104 """Render the settings page."""
98105 template = jinja_env .get_template ("settings.html" )
99106
@@ -118,7 +125,9 @@ async def update_provider(
118125 # Validate provider
119126 if provider not in [p .value for p in ModelProvider ]:
120127 return HTMLResponse (
121- content = _render_status_message (f"Invalid provider: { provider } " , is_error = True )
128+ content = _render_status_message (
129+ f"Invalid provider: { provider } " , is_error = True
130+ )
122131 )
123132
124133 # TODO: Persist settings to file/database
@@ -212,35 +221,37 @@ async def refresh_status(request: Request) -> HTMLResponse:
212221 # Build HTML for status display
213222 html_parts = []
214223 for tier , model in mappings .items ():
215- html_parts .append (f'''
224+ html_parts .append (f"""
216225 <div class="flex items-center justify-between p-3 rounded-lg bg-slate-50">
217226 <code class="text-sm text-slate-600">claude-{ tier } -latest</code>
218227 <code class="text-sm font-medium text-slate-900">{ model } </code>
219228 </div>
220- ''' )
229+ """ )
221230
222231 if last_refresh :
223- html_parts .append (f'<p class="text-xs text-slate-400 mt-3">Last refreshed: { last_refresh } </p>' )
232+ html_parts .append (
233+ f'<p class="text-xs text-slate-400 mt-3">Last refreshed: { last_refresh } </p>'
234+ )
224235
225236 return HTMLResponse (content = "\n " .join (html_parts ))
226237
227238
228239def _render_status_message (message : str , is_error : bool = False ) -> str :
229240 """Render a status message HTML snippet."""
230241 if is_error :
231- return f'''
242+ return f"""
232243 <div class="mb-6 px-4 py-3 rounded-xl text-sm fade-in flex items-start gap-3 bg-red-50 text-red-800 border border-red-100">
233244 <svg class="w-5 h-5 flex-shrink-0 mt-0.5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
234245 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
235246 </svg>
236247 <span>{ message } </span>
237248 </div>
238- '''
239- return f'''
249+ """
250+ return f"""
240251 <div class="mb-6 px-4 py-3 rounded-xl text-sm fade-in flex items-start gap-3 bg-emerald-50 text-emerald-800 border border-emerald-100">
241252 <svg class="w-5 h-5 flex-shrink-0 mt-0.5 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
242253 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
243254 </svg>
244255 <span>{ message } </span>
245256 </div>
246- '''
257+ """
0 commit comments