Skip to content
Merged
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
23 changes: 23 additions & 0 deletions agent/auxiliary_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ def _is_kimi_model(model: Optional[str]) -> bool:
return bare.startswith("kimi-") or bare == "kimi"


def _is_arcee_trinity_thinking(model: Optional[str]) -> bool:
"""True for Arcee Trinity Large Thinking (direct or via OpenRouter)."""
bare = (model or "").strip().lower().rsplit("/", 1)[-1]
return bare == "trinity-large-thinking"


def _fixed_temperature_for_model(
model: Optional[str],
base_url: Optional[str] = None,
Expand All @@ -213,6 +219,23 @@ def _fixed_temperature_for_model(
if _is_kimi_model(model):
logger.debug("Omitting temperature for Kimi model %r (server-managed)", model)
return OMIT_TEMPERATURE
if _is_arcee_trinity_thinking(model):
return 0.5
return None


def _compression_threshold_for_model(model: Optional[str]) -> Optional[float]:
"""Return a context-compression threshold override for specific models.

The threshold is the fraction of the model's context window that must be
consumed before Hermes triggers summarization. Higher values delay
compression and preserve more raw context.

Returns a float in (0, 1] to override the global ``compression.threshold``
config value, or ``None`` to leave the user's config value unchanged.
"""
if _is_arcee_trinity_thinking(model):
return 0.75
return None

# Default auxiliary models for direct API-key providers (cheap/fast for side tasks)
Expand Down
7 changes: 7 additions & 0 deletions run_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,13 @@ def __init__(
if not isinstance(_compression_cfg, dict):
_compression_cfg = {}
compression_threshold = float(_compression_cfg.get("threshold", 0.50))
try:
from agent.auxiliary_client import _compression_threshold_for_model as _cthresh_fn
_model_cthresh = _cthresh_fn(self.model)
if _model_cthresh is not None:
compression_threshold = _model_cthresh
except Exception:
pass
compression_enabled = str(_compression_cfg.get("enabled", True)).lower() in ("true", "1", "yes")
compression_target_ratio = float(_compression_cfg.get("target_ratio", 0.20))
compression_protect_last = int(_compression_cfg.get("protect_last_n", 20))
Expand Down
1 change: 1 addition & 0 deletions scripts/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"50561768+zhanggttry@users.noreply.github.com": "zhanggttry",
"formulahendry@gmail.com": "formulahendry",
"93757150+bogerman1@users.noreply.github.com": "bogerman1",
"132852777+rob-maron@users.noreply.github.com": "rob-maron",
# Matrix parity salvage batch (April 2026)
"sr@samirusani": "samrusani",
"angelclaw@AngelMacBook.local": "angel12",
Expand Down
76 changes: 76 additions & 0 deletions tests/agent/test_arcee_trinity_overrides.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Tests for Arcee Trinity Large Thinking per-model overrides.

Arcee Trinity Large Thinking is a reasoning model that wants:
- Fixed temperature=0.5 (vs the global default)
- Compression threshold=0.75 (delay compression to preserve reasoning context)

The helpers must match the bare model name, including when it arrives via
OpenRouter as ``arcee-ai/trinity-large-thinking``, but must NOT hit sibling
Arcee models like trinity-large-preview or trinity-mini.
"""

from __future__ import annotations

import pytest

from agent.auxiliary_client import (
_compression_threshold_for_model,
_fixed_temperature_for_model,
_is_arcee_trinity_thinking,
)


@pytest.mark.parametrize(
"model",
[
"trinity-large-thinking",
"arcee-ai/trinity-large-thinking",
"Arcee-AI/Trinity-Large-Thinking", # case-insensitive
" trinity-large-thinking ", # whitespace tolerant
],
)
def test_is_arcee_trinity_thinking_matches(model: str) -> None:
assert _is_arcee_trinity_thinking(model) is True


@pytest.mark.parametrize(
"model",
[
None,
"",
"trinity-large-preview",
"arcee-ai/trinity-large-preview:free",
"trinity-mini",
"arcee-ai/trinity-mini",
"trinity-large", # prefix-only must not match
"claude-sonnet-4.6",
"gpt-5.4",
],
)
def test_is_arcee_trinity_thinking_rejects_non_matches(model) -> None:
assert _is_arcee_trinity_thinking(model) is False


def test_fixed_temperature_for_trinity_thinking() -> None:
assert _fixed_temperature_for_model("trinity-large-thinking") == 0.5
assert _fixed_temperature_for_model("arcee-ai/trinity-large-thinking") == 0.5


def test_fixed_temperature_sibling_arcee_models_unaffected() -> None:
# Preview and mini do not pin temperature — caller chooses its default.
assert _fixed_temperature_for_model("trinity-large-preview") is None
assert _fixed_temperature_for_model("trinity-mini") is None


def test_compression_threshold_for_trinity_thinking() -> None:
assert _compression_threshold_for_model("trinity-large-thinking") == 0.75
assert _compression_threshold_for_model("arcee-ai/trinity-large-thinking") == 0.75


def test_compression_threshold_default_none_for_other_models() -> None:
# None means "leave the user's config value unchanged".
assert _compression_threshold_for_model(None) is None
assert _compression_threshold_for_model("") is None
assert _compression_threshold_for_model("trinity-large-preview") is None
assert _compression_threshold_for_model("claude-sonnet-4.6") is None
assert _compression_threshold_for_model("kimi-k2") is None
Loading