Move provider adapters (anthropic, bedrock, azure), platform adapters (telegram, slack, discord, feishu, dingtalk, matrix), and terminal backends (modal, daytona) out of core into plugins/ workspace members. Core references them via the plugin registries (get_provider_namespace / get_provider_service / get_tool_provider / get_credential_pool_hook) instead of direct imports. - Provider/platform/terminal adapters relocated under plugins/; pyproject extras reference workspace members; nix variants aggregate per-platform extras. - Anthropic credential discovery + OAuth-masquerade guard live in the plugin's credential_pool_hook; browser-open guarded by _can_open_graphical_browser. - Vercel AI Gateway + Vercel Sandbox removed (upstream deletion); get_bedrock_model_ids removed (replaced by bedrock_model_ids_or_none + discover_bedrock_models). - Terminal backends resolve ModalEnvironment / DaytonaEnvironment lazily from the plugin registry. - uv.lock regenerated against the pluginified workspace. Plugin test suites updated for the relocation: imports point at hermes_agent_<plat>.adapter, caplog logger-name filters and monkeypatch targets use the new module paths, and credential/rollback tests patch registries.get_provider_service rather than the removed agent.*_adapter modules. Verified: zero dead imports of relocated modules in core (import smoke test + rename-map grep); nix develop succeeds; targeted plugin suites green (bedrock, anthropic-auxiliary, matrix, dingtalk, feishu, credential_pool, switch_model_rollback). Remaining full-suite failures are pre-existing on the pre-merge tree (telegram setUpModule __code__) or environmental (voice/media/ PTY/network-dependent), not introduced here.
48 lines
2.2 KiB
Python
48 lines
2.2 KiB
Python
"""Anthropic-specific ctx halving tests moved from tests/test_ctx_halving_fix.py."""
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# build_anthropic_kwargs — output cap clamping
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestBuildAnthropicKwargsClamping:
|
|
"""The context_length clamp only fires when output ceiling > window.
|
|
For standard Anthropic models (output ceiling < window) it must not fire.
|
|
"""
|
|
|
|
def _build(self, model, max_tokens=None, context_length=None):
|
|
from agent.anthropic_format import build_anthropic_kwargs
|
|
return build_anthropic_kwargs(
|
|
model=model,
|
|
messages=[{"role": "user", "content": "hi"}],
|
|
tools=None,
|
|
max_tokens=max_tokens,
|
|
reasoning_config=None,
|
|
context_length=context_length,
|
|
)
|
|
|
|
def test_no_clamping_when_output_ceiling_fits_in_window(self):
|
|
"""Opus 4.6 native output (128K) < context window (200K) — no clamping."""
|
|
kwargs = self._build("claude-opus-4-6", context_length=200_000)
|
|
assert kwargs["max_tokens"] == 128_000
|
|
|
|
def test_clamping_fires_for_tiny_custom_window(self):
|
|
"""When context_length is 8K (local model), output cap is clamped to 7999."""
|
|
kwargs = self._build("claude-opus-4-6", context_length=8_000)
|
|
assert kwargs["max_tokens"] == 7_999
|
|
|
|
def test_explicit_max_tokens_respected_when_within_window(self):
|
|
"""Explicit max_tokens smaller than window passes through unchanged."""
|
|
kwargs = self._build("claude-opus-4-6", max_tokens=4096, context_length=200_000)
|
|
assert kwargs["max_tokens"] == 4096
|
|
|
|
def test_explicit_max_tokens_clamped_when_exceeds_window(self):
|
|
"""Explicit max_tokens larger than a small window is clamped."""
|
|
kwargs = self._build("claude-opus-4-6", max_tokens=32_768, context_length=16_000)
|
|
assert kwargs["max_tokens"] == 15_999
|
|
|
|
def test_no_context_length_uses_native_ceiling(self):
|
|
"""Without context_length the native output ceiling is used directly."""
|
|
kwargs = self._build("claude-sonnet-4-6")
|
|
assert kwargs["max_tokens"] == 64_000
|