feat: model hub visibility & features + review fixes#15
Conversation
… Table
- ci: add httpx to test workflow pip install for test_a2_verify.py
- config: add public_model_groups list to litellm_settings so all agent-*,
openrouter-auto, llm-routing-ollama, and ollama-deepseek-* groups appear
in the LiteLLM Model Hub Table UI
- config: add full model_info to all model_list entries (supports_vision,
supports_reasoning, supports_function_calling, mode, max_tokens,
max_input_tokens, is_public_model_group)
- config: set llm-routing-ollama and ollama-deepseek-v4-{pro,flash} context
windows to 512K (524288 tokens), up from 131K/262K
- config: add DeepSeek API equivalent per-token costs to ollama models for
Langfuse cost tracking:
ollama-deepseek-v4-pro: $1.74/1M input, $3.48/1M output
ollama-deepseek-v4-flash: $0.14/1M input, $0.28/1M output
- router: enrich /model/new roster sync payload with model_info (features,
context length from OpenRouter API, is_public_model_group) for all
dynamically registered agent-* tiers
- router: add _register_ollama_models_in_db() — registers ollama-deepseek
models via /model/new at startup so their model_info wins over LiteLLM's
internal ollama_chat provider lookup (which returns null/false for unknown
models in /model_group/info aggregation)
…t capabilities, align returned context lengths, and refactor verify scripts to httpx)
Reviewer's GuideImplements full Model Hub visibility and feature metadata for routing and agent models, including DB-backed registration for Ollama deployments, explicit model_info for key LiteLLM model groups, updated context lengths/documentation, and modernized verification scripts using httpx, plus CI wiring for their dependencies. Sequence diagram for Ollama model DB registration during router startupsequenceDiagram
participant FastAPIApp
participant lifespan
participant _register_ollama_models_in_db
participant _purge_stale_deployments
participant Postgres
participant LiteLLMGateway
FastAPIApp->>lifespan: start
lifespan->>_register_ollama_models_in_db: await _register_ollama_models_in_db(litellm_master_key)
_register_ollama_models_in_db->>_purge_stale_deployments: _purge_stale_deployments(db_url, ollama-deepseek-%)
_purge_stale_deployments->>Postgres: DELETE FROM LiteLLM_ProxyModelTable WHERE model_name LIKE ollama-deepseek-%
Postgres-->>_purge_stale_deployments: rows deleted
loop for payload in ollama_models
_register_ollama_models_in_db->>LiteLLMGateway: POST /model/new (payload with model_info)
LiteLLMGateway-->>_register_ollama_models_in_db: 200/201 Created
end
_register_ollama_models_in_db-->>lifespan: registration summary
lifespan-->>FastAPIApp: startup complete
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request updates model context lengths, adds detailed model capabilities and token limits to LiteLLM configurations, and introduces automatic database registration for static Ollama models. Additionally, verification scripts are refactored to use httpx instead of urllib.request. The review feedback identifies a critical NameError in router/main.py where supported_params is referenced instead of supported_parameters, which will crash the application on startup. It also recommends dynamically loading Ollama model configurations from config.yaml to avoid code duplication and adhere to DRY principles.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| model_contexts[mid] = m.get("context_length") or 262144 | ||
| model_supported_params[mid] = supported_params |
There was a problem hiding this comment.
Critical Bug: NameError on Startup
The variable supported_params is not defined in this scope. The actual variable defined at line 393 is supported_parameters.
Using supported_params here will raise a NameError at runtime during the roster sync on startup, crashing the application. Please update it to reference supported_parameters instead.
| model_contexts[mid] = m.get("context_length") or 262144 | |
| model_supported_params[mid] = supported_params | |
| model_contexts[mid] = m.get("context_length") or 262144 | |
| model_supported_params[mid] = supported_parameters |
| ollama_models = [ | ||
| { | ||
| "model_name": "ollama-deepseek-v4-pro", | ||
| "litellm_params": { | ||
| "model": "ollama_chat/deepseek-v4-pro", | ||
| "api_base": "https://api.ollama.com", | ||
| "api_key": "os.environ/OLLAMA_API_KEY", | ||
| "request_timeout": 120, | ||
| }, | ||
| "model_info": { | ||
| "supports_vision": True, | ||
| "supports_reasoning": True, | ||
| "supports_function_calling": True, | ||
| "mode": "chat", | ||
| "max_tokens": 524288, | ||
| "max_input_tokens": 524288, | ||
| "input_cost_per_token": 0.00000174, | ||
| "output_cost_per_token": 0.00000348, | ||
| "is_public_model_group": True, | ||
| }, | ||
| }, | ||
| { | ||
| "model_name": "ollama-deepseek-v4-flash", | ||
| "litellm_params": { | ||
| "model": "ollama_chat/deepseek-v4-flash", | ||
| "api_base": "https://api.ollama.com", | ||
| "api_key": "os.environ/OLLAMA_API_KEY", | ||
| "request_timeout": 120, | ||
| }, | ||
| "model_info": { | ||
| "supports_vision": True, | ||
| "supports_reasoning": True, | ||
| "supports_function_calling": True, | ||
| "mode": "chat", | ||
| "max_tokens": 524288, | ||
| "max_input_tokens": 524288, | ||
| "input_cost_per_token": 0.00000014, | ||
| "output_cost_per_token": 0.00000028, | ||
| "is_public_model_group": True, | ||
| }, | ||
| }, | ||
| ] |
There was a problem hiding this comment.
Maintainability: Avoid Configuration Duplication (DRY)
The static configurations for ollama-deepseek-v4-pro and ollama-deepseek-v4-flash are completely duplicated here in Python code, matching the definitions in litellm/config.yaml exactly. This is highly error-prone and violates the DRY (Don't Repeat Yourself) principle.
Since the LiteLLM configuration is already loaded into the global config variable at startup, you can dynamically extract these models using a list comprehension. This ensures that any future updates to model parameters, costs, or timeouts in config.yaml are automatically reflected in the database registration without requiring duplicate updates.
ollama_models = [
m for m in config.get("model_list", [])
if isinstance(m, dict) and m.get("model_name", "").startswith("ollama-deepseek-")
]There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The new
_register_ollama_models_in_dbhelper hardcodesadmin_url(127.0.0.1:4000) and the Ollama model definitions; consider moving these into configuration/env so they can be reused and adjusted without code changes and stay in sync withlitellm/config.yaml. - In
lifespan,_register_ollama_models_in_dbis always called regardless of whetherlitellm_master_keyis set; adding an early return/log when the master key is missing would avoid unnecessary HTTP attempts and clearer behavior in misconfigured environments.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new `_register_ollama_models_in_db` helper hardcodes `admin_url` (127.0.0.1:4000) and the Ollama model definitions; consider moving these into configuration/env so they can be reused and adjusted without code changes and stay in sync with `litellm/config.yaml`.
- In `lifespan`, `_register_ollama_models_in_db` is always called regardless of whether `litellm_master_key` is set; adding an early return/log when the master key is missing would avoid unnecessary HTTP attempts and clearer behavior in misconfigured environments.
## Individual Comments
### Comment 1
<location path="scripts/verification/verify_ollama_cooldown.py" line_range="26-35" />
<code_context>
- for line in lines:
- if line.startswith("triage_requests_total"):
- return int(float(line.split()[1]))
+ response = httpx.get(METRICS_URL, timeout=5.0)
+ lines = response.text.splitlines()
+ for line in lines:
+ if line.startswith("triage_requests_total"):
+ return int(float(line.split()[1]))
except Exception as e:
print(f"Error fetching metrics: {e}")
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Add response status checking when fetching metrics to avoid parsing error pages.
Because the code parses `response.text` for any status, a 4xx/5xx HTML/error body will cause the `triage_requests_total` parsing to fail and fall back to 0, masking real issues with the metrics endpoint. Consider calling `response.raise_for_status()` after the GET (inside the try) so failures surface explicitly while keeping the control flow the same.
```suggestion
def get_triage_request_count():
try:
response = httpx.get(METRICS_URL, timeout=5.0)
response.raise_for_status()
lines = response.text.splitlines()
for line in lines:
if line.startswith("triage_requests_total"):
return int(float(line.split()[1]))
except Exception as e:
print(f"Error fetching metrics: {e}")
return 0
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
* Configure gated Ollama routing and set llm-routing-ollama as free tier fallback * Address code review comments: Fix annotations race condition and handle null content safely * Address new code reviews: Break Ollama fallback loop, use env key, and fix SAST/lint comments * fix: sanitize triage router 429 detail and force immediate LiteLLM cooldown for llm-routing-ollama on rate limit * docs: update fallback diagrams and cooldown behavior for Ollama models * fix: implement router-side Ollama cooldown to prevent crashloop LiteLLM Community Edition's deployment cooldown is unreliable for single-deployment model groups and fallback-target groups. The previous approach (multi-deployment replicas, allowed_fails_policy) did not reliably cool down llm-routing-ollama, causing crashloops when Ollama was rate-limited. New approach: the triage router manages Ollama cooldowns internally. When Ollama fails (429/502/503), the router activates a 5-minute cooldown (configurable via OLLAMA_COOLDOWN_SECONDS env var). During cooldown, all Ollama requests are immediately rejected: - Auto modes: silently fall back to the free tier - Direct/fallback mode: return 429 so LiteLLM skips to openrouter-auto Changes: - router/main.py: Add _ollama_cooldown_until state, cooldown check before Ollama proxy call, and activation on failure. Add Prometheus metrics (ollama_cooldown_active, ollama_cooldown_remaining_seconds). - litellm/config.yaml: Remove test-fallback-model, remove duplicate llm-routing-ollama deployment (127.0.0.2), restore Ollama api_base to production (api.ollama.com), remove enterprise-only allowed_fails_policy. - README.md: Update sequence diagrams, Fallback and Cooldown Behavior section, and metrics table to document router-side cooldown. * chore: tidy up repository, remove hello world dummies, move and document verification scripts * fix: resolve hardcoded worktree leaks and LiteLLM auth errors * Address PR comments: robust httpx client teardown, dynamic path escaping in sed, expected model asserts in tests, synced metrics documentation * Implement Valkey global cooldown cache sync, standard HTTPX client lifecycles, and handle transient exception status codes * Address PR#11 code reviews: multimodal message extraction, concurrent breaker Valkey calls, generic error detail messages, SSE stream token counting, secure YAML rendering, and robust verification script exit codes * Address PR #12 code review comments - Decouple agy_proxy from main by introducing CooldownPersistence protocol and passing client/cooldown_persistence parameters. - Manage http client lifetime cleanly in agy_proxy. - Reset Valkey client state and cache last init attempt on exceptions to enforce the 5s retry cooldown. - Add isinstance(msg, dict) guards to prevent crashes on malformed payloads. - Use incremental UTF-8 decoder in stream generator to prevent character corruption. - Remove dead should_close_client variables and conditions. - Guard test_antigravity_connection when agentapi is missing. - Fix typo in README. * feat: expose model capabilities, token limits, and costs in Model Hub Table - ci: add httpx to test workflow pip install for test_a2_verify.py - config: add public_model_groups list to litellm_settings so all agent-*, openrouter-auto, llm-routing-ollama, and ollama-deepseek-* groups appear in the LiteLLM Model Hub Table UI - config: add full model_info to all model_list entries (supports_vision, supports_reasoning, supports_function_calling, mode, max_tokens, max_input_tokens, is_public_model_group) - config: set llm-routing-ollama and ollama-deepseek-v4-{pro,flash} context windows to 512K (524288 tokens), up from 131K/262K - config: add DeepSeek API equivalent per-token costs to ollama models for Langfuse cost tracking: ollama-deepseek-v4-pro: $1.74/1M input, $3.48/1M output ollama-deepseek-v4-flash: $0.14/1M input, $0.28/1M output - router: enrich /model/new roster sync payload with model_info (features, context length from OpenRouter API, is_public_model_group) for all dynamically registered agent-* tiers - router: add _register_ollama_models_in_db() — registers ollama-deepseek models via /model/new at startup so their model_info wins over LiteLLM's internal ollama_chat provider lookup (which returns null/false for unknown models in /model_group/info aggregation) * chore: address review feedback on PR #14 (DRY purge helper, safety-net capabilities, align returned context lengths, and refactor verify scripts to httpx) * chore: address PR #15 code review fixes and fix CI workflow triggers * chore(deps): adjust dependabot root docker update time to 02:55 UTC (04:55 local) * chore: address code review feedback (YAML list indentation, raise_for_status in metrics fetch, detailed HTTP routing diagnostics, and defensive config type checking) * chore: trigger CI * Address code reviews for PR #25 * Address new PR reviews and CodeRabbit feedback * Address Gemini Code Assist review feedback on null text handling and empty choices fallback * chore: address PR review feedback on DATABASE_URL, fallback password, and max_tokens clamping * chore: address CodeRabbit and PR #27 review feedback * chore: address Gemini Code Assist review feedback on PR #28 * fix: change session fingerprint hash to SHA-256 to satisfy CodeQL * perf: upgrade session fingerprint hash function to SOTA blake2b * fix: safely handle usage returned as null in api response * fix: resolve missing LiteLLM request logs on Admin UI and fix Langfuse bad requests * fix: address PR 30 review feedback including postgres password and circuit breaker fixes * fix: address PR 31 review feedback
This PR contains the complete implementation for Model Hub visibility and features, incorporating all fixes and feedback from the review of PR #14.
Summary by Sourcery
Enhance model visibility and capabilities metadata across LiteLLM's Model Hub and routing stack, including OpenRouter and Ollama models, while aligning docs, verification scripts, and CI dependencies with the new behavior.
New Features:
Enhancements:
CI:
Documentation: