Files
hkuds--nanobot/tests/agent/conftest.py
T
wehub-resource-sync ba1d0b91a4
Test Suite / webui (push) Failing after 1s
Test Suite / test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:06:36 +08:00

92 lines
2.7 KiB
Python

"""Shared fixtures and helpers for agent tests."""
from __future__ import annotations
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from nanobot.agent.loop import AgentLoop
from nanobot.bus.queue import MessageBus
from nanobot.providers.base import LLMProvider
def make_provider(
default_model: str = "test-model",
*,
max_tokens: int = 4096,
spec: bool = True,
) -> MagicMock:
"""Create a spec-limited LLM provider mock."""
mock_type = MagicMock(spec=LLMProvider) if spec else MagicMock()
provider = mock_type
provider.get_default_model.return_value = default_model
provider.generation = SimpleNamespace(
max_tokens=max_tokens,
temperature=0.1,
reasoning_effort=None,
)
provider.estimate_prompt_tokens.return_value = (10_000, "test")
return provider
def make_loop(
tmp_path: Path,
*,
model: str = "test-model",
context_window_tokens: int = 128_000,
session_ttl_minutes: int = 0,
unified_session: bool = False,
mcp_servers: dict | None = None,
tools_config=None,
model_presets: dict | None = None,
hooks: list | None = None,
provider: MagicMock | None = None,
patch_deps: bool = False,
) -> AgentLoop:
"""Create a real AgentLoop for testing.
Args:
patch_deps: If True, patch ContextBuilder/SessionManager/SubagentManager
during construction (needed when workspace has no real files).
"""
bus = MessageBus()
if provider is None:
provider = make_provider(default_model=model)
kwargs = dict(
bus=bus,
provider=provider,
workspace=tmp_path,
model=model,
context_window_tokens=context_window_tokens,
session_ttl_minutes=session_ttl_minutes,
unified_session=unified_session,
)
if mcp_servers is not None:
kwargs["mcp_servers"] = mcp_servers
if tools_config is not None:
kwargs["tools_config"] = tools_config
if model_presets is not None:
kwargs["model_presets"] = model_presets
if hooks is not None:
kwargs["hooks"] = hooks
if patch_deps:
with patch("nanobot.agent.loop.ContextBuilder"), \
patch("nanobot.agent.loop.SessionManager"), \
patch("nanobot.agent.loop.SubagentManager") as mock_sub_mgr:
mock_sub_mgr.return_value.cancel_by_session = AsyncMock(return_value=0)
return AgentLoop(**kwargs)
return AgentLoop(**kwargs)
@pytest.fixture
def loop_factory(tmp_path):
"""Fixture providing a factory for creating AgentLoop instances."""
def _factory(**kwargs):
return make_loop(tmp_path, **kwargs)
return _factory