diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index da85f03659e8..426479560427 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -536,7 +536,7 @@ def _get_aux_model_for_provider(provider_id: str) -> str: # plus providers we intentionally keep pinned here (e.g. Anthropic predates # profiles). New providers should set default_aux_model on their profile instead. _API_KEY_PROVIDER_AUX_MODELS_FALLBACK: Dict[str, str] = { - "gemini": "gemini-3-flash-preview", + "gemini": "gemini-3.6-flash", "zai": "glm-4.5-flash", "kimi-coding": "kimi-k2-turbo-preview", "stepfun": "step-3.5-flash", @@ -545,7 +545,7 @@ def _get_aux_model_for_provider(provider_id: str) -> str: "anthropic": "claude-haiku-4-5-20251001", "opencode-zen": "gemini-3-flash", "opencode-go": "glm-5", - "kilocode": "google/gemini-3-flash-preview", + "kilocode": "google/gemini-3.6-flash", "ollama-cloud": "nemotron-3-nano:30b", "tencent-tokenhub": "hy3-preview", # NB: no "deepinfra" entry — its aux model lives on the ProviderProfile @@ -760,8 +760,8 @@ def _nous_extra_body() -> dict: auxiliary_is_nous: bool = False # Default auxiliary models per provider -_OPENROUTER_MODEL = "google/gemini-3-flash-preview" -_NOUS_MODEL = "google/gemini-3-flash-preview" +_OPENROUTER_MODEL = "google/gemini-3.6-flash" +_NOUS_MODEL = "google/gemini-3.6-flash" _NOUS_DEFAULT_BASE_URL = "https://inference-api.nousresearch.com/v1" _ANTHROPIC_DEFAULT_BASE_URL = "https://api.anthropic.com" _AUTH_JSON_PATH = get_hermes_home() / "auth.json" diff --git a/agent/gemini_native_adapter.py b/agent/gemini_native_adapter.py index bb53e32b2cec..95c58d72289c 100644 --- a/agent/gemini_native_adapter.py +++ b/agent/gemini_native_adapter.py @@ -73,7 +73,7 @@ def probe_gemini_tier( api_key: str, base_url: str = DEFAULT_GEMINI_BASE_URL, *, - model: str = "gemini-2.5-flash", + model: str = "gemini-3.6-flash", timeout: float = 10.0, ) -> str: """Probe a Google AI Studio API key and return its tier. @@ -154,8 +154,8 @@ def is_free_tier_quota_error(error_message: str) -> bool: _FREE_TIER_GUIDANCE = ( - "\n\nYour Google API key is on the free tier (<= 250 requests/day for " - "gemini-2.5-flash). Hermes typically makes 3-10 API calls per user turn, " + "\n\nYour Google API key is on the free tier (a few hundred requests/day " + "for Gemini Flash models). Hermes typically makes 3-10 API calls per user turn, " "so the free tier is exhausted in a handful of messages and cannot sustain " "an agent session. Enable billing on your Google Cloud project and " "regenerate the key in a billing-enabled project: " @@ -976,7 +976,7 @@ def _advance_stream_iterator(iterator: Iterator[_GeminiStreamChunk]) -> tuple[bo def _create_chat_completion( self, *, - model: str = "gemini-2.5-flash", + model: str = "gemini-3.6-flash", messages: Optional[List[Dict[str, Any]]] = None, stream: bool = False, tools: Any = None, diff --git a/hermes_cli/setup.py b/hermes_cli/setup.py index 53e6136a68a5..58ea510e8db3 100644 --- a/hermes_cli/setup.py +++ b/hermes_cli/setup.py @@ -92,7 +92,7 @@ def _supports_same_provider_pool_setup(provider: str) -> bool: ], "gemini": [ "gemini-3.1-pro-preview", "gemini-3-pro-preview", - "gemini-3-flash-preview", "gemini-3.1-flash-lite-preview", + "gemini-3.6-flash", "gemini-3.1-flash-lite-preview", ], "vertex": [ "google/gemini-3.1-pro-preview", "google/gemini-3-pro-preview", diff --git a/plugins/memory/hindsight/__init__.py b/plugins/memory/hindsight/__init__.py index b5b2aa8cd955..d99e1db4884a 100644 --- a/plugins/memory/hindsight/__init__.py +++ b/plugins/memory/hindsight/__init__.py @@ -66,7 +66,7 @@ _PROVIDER_DEFAULT_MODELS = { "openai": "gpt-4o-mini", "anthropic": "claude-haiku-4-5", - "gemini": "gemini-2.5-flash", + "gemini": "gemini-3.6-flash", "groq": "openai/gpt-oss-120b", "openrouter": "qwen/qwen3.5-9b", "minimax": "MiniMax-M2.7", diff --git a/plugins/model-providers/kilocode/__init__.py b/plugins/model-providers/kilocode/__init__.py index 23123966aaca..f95696acb654 100644 --- a/plugins/model-providers/kilocode/__init__.py +++ b/plugins/model-providers/kilocode/__init__.py @@ -8,7 +8,7 @@ aliases=("kilo-code", "kilo", "kilo-gateway"), env_vars=("KILOCODE_API_KEY",), base_url="https://api.kilo.ai/api/gateway", - default_aux_model="google/gemini-3-flash-preview", + default_aux_model="google/gemini-3.6-flash", ) register_provider(kilocode) diff --git a/plugins/model-providers/openrouter/__init__.py b/plugins/model-providers/openrouter/__init__.py index 3abf291e1446..5e4068c7f5a9 100644 --- a/plugins/model-providers/openrouter/__init__.py +++ b/plugins/model-providers/openrouter/__init__.py @@ -204,7 +204,7 @@ def build_api_kwargs_extras( "anthropic/claude-sonnet-4.6", "openai/gpt-5.4", "deepseek/deepseek-chat", - "google/gemini-3-flash-preview", + "google/gemini-3.6-flash", "qwen/qwen3-plus", ), ) diff --git a/plugins/model-providers/vertex/__init__.py b/plugins/model-providers/vertex/__init__.py index f0d0d4f896b1..a63aa2b68c27 100644 --- a/plugins/model-providers/vertex/__init__.py +++ b/plugins/model-providers/vertex/__init__.py @@ -69,7 +69,7 @@ def fetch_models( env_vars=(), # OAuth2 via service account / ADC — not a static key env var base_url="https://aiplatform.googleapis.com", # real base_url computed at runtime auth_type="vertex", - default_aux_model="google/gemini-3-flash-preview", + default_aux_model="google/gemini-3.6-flash", ) register_provider(vertex) diff --git a/tests/agent/test_auxiliary_client.py b/tests/agent/test_auxiliary_client.py index 8da9bd1edf5f..58d615e5c859 100644 --- a/tests/agent/test_auxiliary_client.py +++ b/tests/agent/test_auxiliary_client.py @@ -10,6 +10,7 @@ import pytest from agent.auxiliary_client import ( + _NOUS_MODEL, get_text_auxiliary_client, get_available_vision_backends, resolve_vision_provider_client, @@ -1804,7 +1805,7 @@ def select(self): client, model = _try_nous() assert client is not None - assert model == "google/gemini-3-flash-preview" + assert model == _NOUS_MODEL assert mock_openai.call_args.kwargs["api_key"] == pooled_token assert mock_openai.call_args.kwargs["base_url"] == "https://inference.pool.example/v1" @@ -1851,7 +1852,7 @@ def try_refresh_current(self): assert pool.refreshed is True assert client is not None - assert model == "google/gemini-3-flash-preview" + assert model == _NOUS_MODEL assert mock_openai.call_args.kwargs["api_key"] == fresh_token assert mock_openai.call_args.kwargs["base_url"] == "https://inference.pool.example/v1" @@ -1938,7 +1939,7 @@ def test_try_nous_falls_back_when_recommendation_lookup_raises(self): client, model = _try_nous() assert client is not None - assert model == "google/gemini-3-flash-preview" + assert model == _NOUS_MODEL def test_call_llm_retries_nous_after_401(self): class _Auth401(Exception): @@ -2360,7 +2361,7 @@ def test_falls_back_to_default_when_portal_matches_stale(self, monkeypatch): ) out = _refresh_nous_recommended_model( vision=True, stale_model="openai/gpt-5.4-mini") - assert out == "google/gemini-3-flash-preview" + assert out == _NOUS_MODEL def test_falls_back_to_default_when_portal_unavailable(self, monkeypatch): def _boom(**kw): @@ -2369,17 +2370,17 @@ def _boom(**kw): "hermes_cli.models.get_nous_recommended_aux_model", _boom) out = _refresh_nous_recommended_model( vision=False, stale_model="some/dead-model") - assert out == "google/gemini-3-flash-preview" + assert out == _NOUS_MODEL def test_returns_none_when_no_distinct_alternative(self, monkeypatch): """When the failed model IS the default and the Portal has nothing else, there's no usable alternative.""" monkeypatch.setattr( "hermes_cli.models.get_nous_recommended_aux_model", - lambda **kw: "google/gemini-3-flash-preview", + lambda **kw: _NOUS_MODEL, ) out = _refresh_nous_recommended_model( - vision=False, stale_model="google/gemini-3-flash-preview") + vision=False, stale_model=_NOUS_MODEL) assert out is None diff --git a/tests/run_agent/test_provider_parity.py b/tests/run_agent/test_provider_parity.py index 56dbd153ef08..c9a4e1079298 100644 --- a/tests/run_agent/test_provider_parity.py +++ b/tests/run_agent/test_provider_parity.py @@ -1022,15 +1022,15 @@ class TestAuxiliaryClientProviderPriority: def test_openrouter_always_wins(self, monkeypatch): monkeypatch.setenv("OPENROUTER_API_KEY", "or-key") - from agent.auxiliary_client import get_text_auxiliary_client + from agent.auxiliary_client import _OPENROUTER_MODEL, get_text_auxiliary_client with patch("agent.auxiliary_client.OpenAI") as mock: client, model = get_text_auxiliary_client() - assert model == "google/gemini-3-flash-preview" + assert model == _OPENROUTER_MODEL assert "openrouter" in str(mock.call_args.kwargs["base_url"]).lower() def test_nous_when_no_openrouter(self, monkeypatch): monkeypatch.delenv("OPENROUTER_API_KEY", raising=False) - from agent.auxiliary_client import get_text_auxiliary_client + from agent.auxiliary_client import _NOUS_MODEL, get_text_auxiliary_client nous_auth = { "access_token": _fake_invoke_jwt(), "scope": "inference:invoke", @@ -1039,7 +1039,7 @@ def test_nous_when_no_openrouter(self, monkeypatch): patch("agent.auxiliary_client.OpenAI") as mock, \ patch("hermes_cli.models.get_nous_recommended_aux_model", return_value=None): client, model = get_text_auxiliary_client() - assert model == "google/gemini-3-flash-preview" + assert model == _NOUS_MODEL def test_custom_endpoint_when_no_nous(self, monkeypatch): """Custom endpoint is used when no OpenRouter/Nous keys are available.