Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions agent/agent_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -2756,6 +2756,7 @@ def _parse_prune_int(raw, default):
proactive_prune_min_reclaim_tokens=compression_proactive_prune_min_reclaim,
min_tail_user_messages=compression_min_tail_users,
tail_mode=compression_tail_mode,
custom_providers=_custom_providers,
)
_bind_session_state = getattr(agent.context_compressor, "bind_session_state", None)
if callable(_bind_session_state):
Expand Down
10 changes: 10 additions & 0 deletions agent/auxiliary_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5592,12 +5592,22 @@ def _candidate_context_window(
"""
if not model:
return None
# Load custom_providers from config so per-model context_length
# overrides (custom_providers[].models.<id>.context_length) are
# honored for fallback candidates too — not just the main model.
_custom_providers: list | None = None
try:
from hermes_cli.config import get_compatible_custom_providers, load_config_readonly
_custom_providers = get_compatible_custom_providers(load_config_readonly())
except Exception:
pass
try:
ctx = get_model_context_length(
model,
base_url=base_url,
api_key=api_key,
provider=provider,
custom_providers=_custom_providers,
)
except Exception as exc:
logger.debug(
Expand Down
7 changes: 7 additions & 0 deletions agent/context_compressor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2171,6 +2171,7 @@ def _resolve_context_length(self) -> int:
api_key=self.api_key,
config_context_length=self._config_context_length,
provider=self.provider,
custom_providers=self._custom_providers,
)
# Small-context threshold floor: models under 512K trigger at
# >=75% so compaction doesn't fire with half the window still
Expand Down Expand Up @@ -2996,6 +2997,7 @@ def __init__(
proactive_prune_min_reclaim_tokens: int = 4096,
min_tail_user_messages: int = 1,
tail_mode: str = "legacy",
custom_providers: list | None = None,
):
self.model = model
self.base_url = base_url
Expand All @@ -3006,6 +3008,11 @@ def __init__(
# tail + verbatim-user-message summary section + recovery pointers;
# "legacy" = 0.20*window tail (shipping behavior).
self.tail_mode = tail_mode if tail_mode in ("legacy", "lean") else "legacy"
# Per-model context_length overrides from custom_providers config.
# Threaded to get_model_context_length() in _resolve_context_length()
# so deferred resolution (first context_length property access) honors
# the same per-model overrides that startup resolution does (#15779).
self._custom_providers = custom_providers
# Per-model threshold overrides (longest substring match wins).
# Stored as a plain dict; resolved in _resolve_threshold(), then the
# small-context floor is applied on top.
Expand Down
16 changes: 16 additions & 0 deletions agent/moa_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,21 @@ def _run_reference(
_REFERENCE_TRIM_SAFETY_FRACTION = 0.10


def _load_custom_providers() -> list | None:
"""Best-effort load of custom_providers from config.

Used by _trim_messages_for_reference to honor per-model context_length
overrides (custom_providers[].models.<id>.context_length) when resolving
reference model context windows. Returns None on any failure so the
resolver falls through to probing — never breaks a MoA turn.
"""
try:
from hermes_cli.config import get_compatible_custom_providers, load_config_readonly
return get_compatible_custom_providers(load_config_readonly())
except Exception:
return None


def _trim_messages_for_reference(
messages: list[dict[str, Any]],
slot: dict[str, str],
Expand Down Expand Up @@ -723,6 +738,7 @@ def _trim_messages_for_reference(
base_url=str(runtime.get("base_url") or ""),
api_key=str(runtime.get("api_key") or ""),
provider=provider,
custom_providers=_load_custom_providers(),
)
except Exception:
logger.debug(
Expand Down
29 changes: 28 additions & 1 deletion gateway/slash_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -864,8 +864,35 @@ def _resolve_nonresident_context():
try:
from agent.model_metadata import get_model_context_length

# Inactive-agent fallback: resolve the configured route
# identity + compatible custom_providers so per-model
# context_length overrides (custom_providers[].models.<id>)
# are honored — passing only model_name falls through to
# generic metadata for custom endpoints (#15779).
_provider = ""
_custom_providers = None
try:
from hermes_cli.config import (
get_compatible_custom_providers,
load_config_readonly,
)

_cfg = load_config_readonly() or {}
_model_cfg = _cfg.get("model")
if isinstance(_model_cfg, dict):
_provider = str(_model_cfg.get("provider") or "").strip()
_custom_providers = get_compatible_custom_providers(_cfg)
except Exception:
_provider = ""
_custom_providers = None

context_length = _int_value(
await asyncio.to_thread(get_model_context_length, model_name)
await asyncio.to_thread(
get_model_context_length,
model_name,
provider=_provider,
custom_providers=_custom_providers,
)
)
except Exception:
context_length = 0
Expand Down
3 changes: 3 additions & 0 deletions hermes_cli/web_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6922,11 +6922,14 @@ def get_model_info(profile: Optional[str] = None):
# purely auto-detected value, then separately report the override)
try:
from agent.model_metadata import get_model_context_length
from hermes_cli.config import get_compatible_custom_providers
_cp = get_compatible_custom_providers(cfg)
auto_ctx = get_model_context_length(
model=model_name,
base_url=base_url,
provider=provider,
config_context_length=None, # ignore override — we want auto value
custom_providers=_cp,
)
except Exception:
auto_ctx = 0
Expand Down
17 changes: 17 additions & 0 deletions model_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,12 +720,29 @@ def _resolve_active_context_length() -> int:
return cached_ctx
except Exception:
pass
# Per-model context_length overrides from custom_providers config
# (custom_providers[].models.<id>.context_length) must be honored by
# the tool-search gate too — otherwise the gate sizes against generic
# metadata for custom endpoints (#15779). Best-effort load: config
# failure degrades to None so resolution falls through to probing.
custom_providers = None
try:
from hermes_cli.config import (
get_compatible_custom_providers,
load_config_readonly,
)
custom_providers = get_compatible_custom_providers(
load_config_readonly()
)
except Exception:
custom_providers = None
return int(get_model_context_length(
model_id,
base_url=base_url,
api_key=api_key,
config_context_length=config_ctx,
provider=provider,
custom_providers=custom_providers,
) or 0)
except Exception as e:
logger.debug("Could not resolve active context length: %s", e)
Expand Down
Loading
Loading