def test_create_cli_agent_accepts_host_backend_and_memory_options( monkeypatch, tmp_path ): import EvoScientist.EvoScientist as agent_module from EvoScientist.config.settings import EvoScientistConfig calls = {} workspace_backend = object() chat_model = object() class _CompositeBackend: def __init__(self, *, default, routes, artifacts_root=None): calls["default_backend"] = default calls["routes"] = routes calls["artifacts_root"] = artifacts_root class _MemoryBackend: def __init__(self, **kwargs): calls["memory_backend_kwargs"] = kwargs class _SkillsBackend: def __init__(self, **kwargs): calls["skills_backend_kwargs"] = kwargs class _Agent: def with_config(self, config): calls["agent_config"] = config return self cfg = EvoScientistConfig(auto_approve=True, recursion_limit=321) monkeypatch.setattr("deepagents.backends.CompositeBackend", _CompositeBackend) monkeypatch.setattr("deepagents.create_deep_agent", lambda **kwargs: _Agent()) monkeypatch.setattr("EvoScientist.backends.MemoryFilesystemBackend", _MemoryBackend) monkeypatch.setattr("EvoScientist.backends.MergedSkillsBackend", _SkillsBackend) monkeypatch.setattr(agent_module, "set_active_workspace", lambda path: None) monkeypatch.setattr( agent_module, "_get_default_middleware", lambda **kwargs: calls.setdefault("middleware_kwargs", kwargs) or [], ) monkeypatch.setattr( agent_module, "load_mcp_and_build_kwargs", lambda *args, **kwargs: {"subagents": [{"name": "research"}]}, ) memory_dir = tmp_path / "memory" result = agent_module.create_cli_agent( workspace_dir=str(tmp_path / "workspace"), checkpointer=object(), config=cfg, chat_model=chat_model, workspace_backend=workspace_backend, memory_dir=memory_dir, tool_selector_threshold=8, memory_max_inline_profile_chars=1000, enable_subagents=False, enable_background_execution=False, ) assert isinstance(result, _Agent) assert calls["default_backend"] is workspace_backend assert calls["memory_backend_kwargs"] == { "root_dir": str(memory_dir), "virtual_mode": True, } assert calls["middleware_kwargs"]["memory_dir"] == str(memory_dir) assert calls["middleware_kwargs"]["tool_selector_threshold"] == 8 assert calls["middleware_kwargs"]["memory_max_inline_profile_chars"] == 1000 assert calls["middleware_kwargs"]["enable_background_execution"] is False assert calls["middleware_kwargs"]["enable_legacy_model_fallback"] is True assert calls["agent_config"] == {"recursion_limit": 321} def test_create_cli_agent_installs_route_middleware_in_fixed_slot( monkeypatch, tmp_path ): import EvoScientist.EvoScientist as agent_module from EvoScientist.config.settings import EvoScientistConfig calls = {} class _Middleware: def __init__(self, name): self.name = name class _Backend: def __init__(self, **_kwargs): pass class _CompositeBackend: def __init__(self, **_kwargs): pass class _Agent: def with_config(self, _config): return self default_chain = [ _Middleware("error_normalization"), _Middleware("configurable_model"), _Middleware("context_editing"), _Middleware("tool_protocol_guard"), ] route = _Middleware("gateway_route_fallback") monkeypatch.setattr("deepagents.backends.CompositeBackend", _CompositeBackend) monkeypatch.setattr("deepagents.create_deep_agent", lambda **_kwargs: _Agent()) monkeypatch.setattr("EvoScientist.backends.MemoryFilesystemBackend", _Backend) monkeypatch.setattr("EvoScientist.backends.MergedSkillsBackend", _Backend) monkeypatch.setattr(agent_module, "set_active_workspace", lambda _path: None) def fake_default_middleware(**kwargs): calls["middleware_kwargs"] = kwargs return list(default_chain) monkeypatch.setattr( agent_module, "_get_default_middleware", fake_default_middleware ) def fake_load(_backend, middleware, **_kwargs): calls["middleware"] = middleware return {"subagents": []} monkeypatch.setattr(agent_module, "load_mcp_and_build_kwargs", fake_load) agent_module.create_cli_agent( workspace_dir=str(tmp_path), checkpointer=object(), config=EvoScientistConfig(auto_approve=True), chat_model=object(), workspace_backend=object(), main_agent_route_middleware=route, ) assert calls["middleware_kwargs"]["enable_legacy_model_fallback"] is False assert [middleware.name for middleware in calls["middleware"][:6]] == [ "error_normalization", "provider_context_media", "configurable_model", "gateway_route_fallback", "context_editing", "tool_protocol_guard", ] def test_create_cli_agent_replaces_framework_skill_injection(monkeypatch, tmp_path): import EvoScientist.EvoScientist as agent_module from EvoScientist.config.settings import EvoScientistConfig from EvoScientist.middleware import BudgetedSkillsMiddleware calls = {} class _Backend: def __init__(self, **_kwargs): pass class _CompositeBackend: def __init__(self, **_kwargs): pass class _Agent: def with_config(self, _config): return self def _create_deep_agent(**kwargs): calls["kwargs"] = kwargs return _Agent() monkeypatch.setattr("deepagents.backends.CompositeBackend", _CompositeBackend) monkeypatch.setattr("deepagents.create_deep_agent", _create_deep_agent) monkeypatch.setattr("EvoScientist.backends.MemoryFilesystemBackend", _Backend) monkeypatch.setattr("EvoScientist.backends.MergedSkillsBackend", _Backend) monkeypatch.setattr(agent_module, "set_active_workspace", lambda _path: None) monkeypatch.setattr(agent_module, "_get_default_middleware", lambda **_kwargs: []) monkeypatch.setattr( agent_module, "load_mcp_and_build_kwargs", lambda *_args, **_kwargs: { "skills": ["/skills/"], "middleware": [], "subagents": [{"name": "research", "skills": ["/skills/"]}], }, ) agent_module.create_cli_agent( workspace_dir=str(tmp_path), checkpointer=object(), config=EvoScientistConfig(auto_approve=True), chat_model=object(), workspace_backend=object(), ) assert calls["kwargs"]["skills"] is None assert any( isinstance(middleware, BudgetedSkillsMiddleware) for middleware in calls["kwargs"]["middleware"] ) subagent = calls["kwargs"]["subagents"][0] assert subagent["skills"] is None assert isinstance(subagent["middleware"][0], BudgetedSkillsMiddleware)