Files
hermes-agent/tui_gateway/methods_session_model_guard.py
kshitijk4poor 91586d448c refactor(tui_gateway): keep the session.create tier parse out of the oversized handler module
methods_session.py is already past 2000 lines, so the exact-tier parse that
#130990 grew in place moves with the rest of the composer overrides into
methods_session_model_guard.py (the session.create param gate), and the
strict "unknown word is an error, normal words pin ''" rule becomes
agent.fast_mode.parse_exact_service_tier next to the tier word table it
reads. The Daybreak/cyber exclusion folds into _is_openai_fast_model's
single return so hermes_cli/models.py does not grow.

Drops the PR's unused contextlib import in prompt_turn.py (no use was
added with it).

Co-authored-by: FroRaut <79215537+Froraut@users.noreply.github.com>
2026-10-04 02:12:57 +05:30

52 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""``session.create`` composer overrides and the model×provider coherence gate (#96817).
A composer, script or older client can pin a model the selected provider cannot serve
(``gpt-5.5`` on ``anthropic``); the session used to be minted fine and the FIRST turn died with
the provider's 404, leaving a dead chat. The gate is offline (curated catalogs only) and stays
permissive wherever Hermes cannot know better — see ``models_validate.static_model_provider_conflict``.
"""
from __future__ import annotations
import contextlib
def model_override_conflict(params: dict, build_scope) -> dict | None:
"""The conflict record for the create params' model override, or ``None`` when coherent /
undecidable. Without an explicit ``provider`` the pair is judged against the provider the
session would actually build with (profile config, then env) inside ``build_scope`` — the
handler's ``_profile_build_scope(profile_home)`` context manager."""
model = str(params.get("model") or "").strip()
if not model:
return None
from hermes_cli.models_validate import static_model_provider_conflict
from hermes_cli.runtime_provider import resolve_requested_provider
provider = str(params.get("provider") or "").strip()
if not provider:
with build_scope:
provider = resolve_requested_provider()
return static_model_provider_conflict(model, provider)
def create_overrides(params: dict) -> tuple:
"""PER-SESSION (model, reasoning, service_tier) overrides from the composer — never a global config
write. An explicit ``service_tier`` wins over legacy ``fast`` (an unknown word raises ``ValueError``);
``fast`` presence: omitted inherits, true pins priority, false pins normal (\"\")."""
from utils import is_truthy_value
model = str(params.get("model") or "").strip()
model_override = {"model": model, "provider": str(params.get("provider") or "").strip() or None} if model else None
reasoning_override = None
if effort := str(params.get("reasoning_effort") or "").strip():
with contextlib.suppress(Exception):
from hermes_constants import parse_reasoning_effort
reasoning_override = parse_reasoning_effort(effort)
service_tier_override = None
if params.get("service_tier") is not None:
from agent.fast_mode import parse_exact_service_tier
service_tier_override = parse_exact_service_tier(params["service_tier"])
elif "fast" in params:
service_tier_override = "priority" if is_truthy_value(params.get("fast")) else ""
return model_override, reasoning_override, service_tier_override