Conversation
Recognize vertex/gemini- and gemini_cli/gemini- model ids in heuristic reasoning resolution. Deny embedding and image-preview routes before models_dev fallback. Grok uses existing x-ai/ slash-prefix list. Regression tests for custom:newapi; CHANGELOG [Unreleased].
|
| Filename | Overview |
|---|---|
| api/config.py | Adds two new helper functions (_nested_route_reasoning_denied, _nested_gateway_route_reasoning) that handle vertex/ and gemini_cli/ prefixed model IDs; duplication of exclusion criteria between the two is a maintenance risk. |
| tests/test_custom_provider_bare_model_reasoning.py | New parametrized positive and negative test cases for nested Gemini gateway routes; negative cases only cover the vertex/ prefix, leaving the gemini_cli/ branch untested for the deny path. |
| CHANGELOG.md | CHANGELOG entry added under [Unreleased] for the nested Gemini gateway route fix; no issues. |
Reviews (1): Last reviewed commit: "fix(config): reasoning toggle for nested..." | Re-trigger Greptile
| def _nested_route_reasoning_denied(model: str) -> bool: | ||
| """Hard deny for nested Gemini gateway routes that must never show a reasoning toggle.""" | ||
| lower = str(model or "").strip().lower() | ||
| if not lower: | ||
| return False | ||
| for prefix in ("vertex/gemini-", "gemini_cli/gemini-"): | ||
| if lower.startswith(prefix): | ||
| tail = lower[len(prefix) :] | ||
| if tail.startswith("embedding") or "image" in tail or "imagine" in tail: | ||
| return True | ||
| return False | ||
|
|
||
|
|
||
| def _nested_gateway_route_reasoning(model: str) -> bool: | ||
| """Recognize nested ``vertex/gemini-`` and ``gemini_cli/gemini-`` routes on custom providers. | ||
|
|
||
| The slash-prefix heuristic list includes ``google/gemini-2`` but not gateway-prefixed | ||
| Gemini ids, so capable models behind custom aggregators stayed hidden. | ||
| """ | ||
| lower = str(model or "").strip().lower() | ||
| if not lower: | ||
| return False | ||
| for prefix in ("vertex/gemini-", "gemini_cli/gemini-"): | ||
| if lower.startswith(prefix): | ||
| tail = lower[len(prefix) :] | ||
| if tail.startswith("embedding") or "image" in tail or "imagine" in tail: | ||
| return False | ||
| return True | ||
| return False |
There was a problem hiding this comment.
Duplicated exclusion criteria between the two helpers
_nested_route_reasoning_denied and _nested_gateway_route_reasoning each independently define the same embedding/image/imagine exclusion logic. If a new exclusion pattern (e.g. "audio") is added to _nested_gateway_route_reasoning but not to _nested_route_reasoning_denied, the early-deny guard in resolve_model_reasoning_efforts — which exists specifically to override registry false positives from _models_dev_reasoning_efforts — would silently fail to fire for that new pattern. Extracting the exclusion predicate into a single shared helper (e.g. _is_gemini_non_reasoning_tail(tail)) called by both functions would remove the coupling.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| @pytest.mark.parametrize( | ||
| "model_id", | ||
| [ | ||
| "vertex/gemini-embedding-001", | ||
| "vertex/gemini-3-pro-image-preview", | ||
| ], | ||
| ) |
There was a problem hiding this comment.
The negative parametrization only exercises the
vertex/ branch of _nested_route_reasoning_denied; the gemini_cli/ branch is never exercised in the deny path. A regression that accidentally removed "gemini_cli/gemini-" from the deny loop would not be caught by these tests.
| @pytest.mark.parametrize( | |
| "model_id", | |
| [ | |
| "vertex/gemini-embedding-001", | |
| "vertex/gemini-3-pro-image-preview", | |
| ], | |
| ) | |
| @pytest.mark.parametrize( | |
| "model_id", | |
| [ | |
| "vertex/gemini-embedding-001", | |
| "vertex/gemini-3-pro-image-preview", | |
| "gemini_cli/gemini-embedding-001", | |
| "gemini_cli/gemini-3-pro-image-preview", | |
| ], | |
| ) |
Release NU (v0.51.408): reasoning selector for nested Gemini custom-provider routes (#4165)
Release NU (v0.51.408): reasoning selector for nested Gemini custom-provider routes (nesquena#4165)
fix: reasoning toggle for custom provider nested Gemini routes (vertex/, gemini_cli/)
Related context: Follow-up to closed PR #3431 (always-show reasoning chip). Direction in this comment: keep the selector only when the model actually supports reasoning — improve
resolve_model_reasoning_effortsdetection for custom providers and aggregator-shaped ids, not a default-off chip on every model. This PR is scoped to that detection fix for nested Gemini routes (vertex/,gemini_cli/).Thinking Path
vertex/gemini-…,gemini_cli/gemini-…) rather than OpenRouter-stylegoogle/gemini-*.resolve_model_reasoning_efforts()returns a non-empty list; PR fix: generalized reasoning capability heuristics (#3377) #3379 fixed bare and dot-separated ids but not these Gemini route prefixes. That aligns with the feat: always show reasoning effort selector, default off for unrecognized models (#3377) #3431 maintainer feedback: fix false negatives in capability detection, not universal chip visibility.custom:*providers often lack authoritativemodels_devcapability mapping, so the heuristic fallback inapi/config.pymust recognize these gateway shapes.resolve_model_reasoning_effortscovers registry false positives.What Changed
api/config.py_nested_gateway_route_reasoning()forvertex/gemini-andgemini_cli/gemini-, wired into_heuristic_reasoning_efforts()._nested_route_reasoning_denied()and an early return inresolve_model_reasoning_efforts()for embedding / image / imagine Gemini routes.tests/test_custom_provider_bare_model_reasoning.pyvertex/andgemini_cli/viacustom:newapi.Why It Matters
Users on custom gateways lose the reasoning effort control for capable Gemini models when the catalog uses
vertex/orgemini_cli/prefixes. This restores the toggle without affecting embeddings or image-only routes.Verification
vertex/gemini-3.1-pro-preview,gemini_cli/gemini-3-pro-preview→ non-empty efforts;vertex/gemini-embedding-001,vertex/gemini-3-pro-image-preview→[].pytest tests/test_custom_provider_bare_model_reasoning.py -v --timeout=60andpython3 scripts/ruff_lint.py --diff upstream/master(CI runs full matrix).Risks / Follow-ups
google/gemini-3*on custom providers still depends on existinggoogle/gemini-2prefix rules unless ids usevertex//gemini_cli/.Model Used
grok-composer-2.5-fast(Hermes WebUI developer session).gemini-3.5-flash-high