Files
OpenJarvis/tests/test_system.py
T
Jon Saad-FalconandClaude Opus 4.6 852259f18b Restructure codebase into 5-pillar architecture with MCP tool management, composition layer, and structured learning
Phase 1: Move RoutingContext to core/types.py, add RouterPolicy and QueryAnalyzer ABCs to intelligence/_stubs.py
Phase 2: Move memory backends to tools/storage/, convert memory/ to backward-compat shims
Phase 3: Add MCPToolAdapter, storage MCP tools, upgrade MCP server to spec 2025-11-25
Phase 4: Add SystemBuilder + JarvisSystem composition layer (system.py)
Phase 5: Add InstrumentedEngine for opt-in telemetry, simplify all agents
Phase 6: Add LearningPolicy ABC taxonomy with SFTPolicy, AgentAdvisorPolicy, ICLUpdaterPolicy
Phase 7: Update config schema (ToolsConfig, MCPConfig, TracesConfig, per-pillar learning policies)

Also: update all docs, README (DSPy-inspired), CLAUDE.md, and add logo assets.
1391 tests pass, 32 skipped. Zero new lint errors. Full backward compatibility via shims.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 05:57:13 +00:00

301 lines
9.4 KiB
Python

"""Tests for the composition layer."""
from __future__ import annotations
from unittest.mock import MagicMock
import pytest
from openjarvis.core.config import JarvisConfig
from openjarvis.core.events import EventBus
from openjarvis.system import JarvisSystem, SystemBuilder
class TestJarvisSystem:
def test_ask_direct_mode(self):
engine = MagicMock()
engine.generate.return_value = {
"content": "Hello!",
"usage": {"prompt_tokens": 5, "completion_tokens": 3},
}
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test-model",
)
result = system.ask("Hi")
assert result["content"] == "Hello!"
assert result["model"] == "test-model"
assert result["engine"] == "mock"
def test_ask_returns_usage(self):
engine = MagicMock()
engine.generate.return_value = {
"content": "OK",
"usage": {"prompt_tokens": 10, "completion_tokens": 5},
}
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
)
result = system.ask("Hi")
assert result["usage"]["prompt_tokens"] == 10
def test_ask_no_agent_direct_mode(self):
"""When agent_name is empty and no agent param, use direct engine mode."""
engine = MagicMock()
engine.generate.return_value = {
"content": "Direct response",
"usage": {},
}
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
agent_name="",
)
result = system.ask("Hi")
assert result["content"] == "Direct response"
engine.generate.assert_called_once()
def test_ask_with_agent_none_uses_direct(self):
"""Passing agent_name='none' should use direct engine mode."""
engine = MagicMock()
engine.generate.return_value = {
"content": "Direct response",
"usage": {},
}
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
agent_name="none",
)
result = system.ask("Hi")
assert result["content"] == "Direct response"
def test_ask_with_agent_override(self):
"""Passing agent= param should use that agent even if system has a default."""
from openjarvis.agents._stubs import AgentResult
from openjarvis.core.registry import AgentRegistry
class TestAgent:
agent_id = "test-system-agent"
def __init__(self, eng, model, **kwargs):
pass
def run(self, input, context=None, **kwargs):
return AgentResult(content="From test agent", turns=1)
# Register (or re-register) the agent
if not AgentRegistry.contains("test-system-agent"):
AgentRegistry.register_value("test-system-agent", TestAgent)
engine = MagicMock()
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
agent_name="",
)
result = system.ask("Hi", agent="test-system-agent")
assert result["content"] == "From test agent"
def test_ask_unknown_agent(self):
"""Unknown agent should return an error dict."""
engine = MagicMock()
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
)
result = system.ask("Hi", agent="nonexistent-agent-xyz")
assert "Unknown agent" in result["content"]
assert result.get("error") is True
def test_ask_passes_temperature_and_max_tokens(self):
engine = MagicMock()
engine.generate.return_value = {"content": "OK", "usage": {}}
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
)
system.ask("Hi", temperature=0.3, max_tokens=512)
call_kwargs = engine.generate.call_args
assert call_kwargs[1]["temperature"] == 0.3
assert call_kwargs[1]["max_tokens"] == 512
def test_close(self):
engine = MagicMock()
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
)
system.close() # Should not raise
def test_close_with_telemetry(self):
engine = MagicMock()
telem = MagicMock()
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
telemetry_store=telem,
)
system.close()
telem.close.assert_called_once()
def test_close_with_trace_store(self):
engine = MagicMock()
trace = MagicMock()
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
trace_store=trace,
)
system.close()
trace.close.assert_called_once()
def test_build_tools_empty(self):
engine = MagicMock()
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
)
tools = system._build_tools([])
assert tools == []
def test_build_tools_unknown_tool(self):
engine = MagicMock()
system = JarvisSystem(
config=JarvisConfig(),
bus=EventBus(),
engine=engine,
engine_key="mock",
model="test",
)
tools = system._build_tools(["nonexistent_tool_xyz"])
assert tools == []
class TestSystemBuilder:
def test_builder_fluent_api(self):
config = JarvisConfig()
builder = SystemBuilder(config)
result = builder.engine("ollama").model("test").agent("simple")
assert result is builder # fluent
def test_builder_stores_config(self):
config = JarvisConfig()
builder = SystemBuilder(config)
assert builder._config is config
def test_builder_engine_setter(self):
config = JarvisConfig()
builder = SystemBuilder(config)
builder.engine("vllm")
assert builder._engine_key == "vllm"
def test_builder_model_setter(self):
config = JarvisConfig()
builder = SystemBuilder(config)
builder.model("my-model")
assert builder._model == "my-model"
def test_builder_agent_setter(self):
config = JarvisConfig()
builder = SystemBuilder(config)
builder.agent("orchestrator")
assert builder._agent_name == "orchestrator"
def test_builder_tools_setter(self):
config = JarvisConfig()
builder = SystemBuilder(config)
builder.tools(["calculator", "think"])
assert builder._tool_names == ["calculator", "think"]
def test_builder_telemetry_setter(self):
config = JarvisConfig()
builder = SystemBuilder(config)
builder.telemetry(False)
assert builder._telemetry is False
def test_builder_traces_setter(self):
config = JarvisConfig()
builder = SystemBuilder(config)
builder.traces(True)
assert builder._traces is True
def test_builder_event_bus_setter(self):
config = JarvisConfig()
builder = SystemBuilder(config)
bus = EventBus()
builder.event_bus(bus)
assert builder._bus is bus
def test_builder_chaining(self):
config = JarvisConfig()
builder = (
SystemBuilder(config)
.engine("ollama")
.model("test-model")
.agent("simple")
.tools(["calculator"])
.telemetry(True)
.traces(False)
)
assert builder._engine_key == "ollama"
assert builder._model == "test-model"
assert builder._agent_name == "simple"
assert builder._tool_names == ["calculator"]
assert builder._telemetry is True
assert builder._traces is False
def test_import_works(self):
from openjarvis.system import JarvisSystem, SystemBuilder
assert JarvisSystem is not None
assert SystemBuilder is not None
def test_builder_default_config(self):
"""SystemBuilder with no config should load defaults."""
builder = SystemBuilder()
assert builder._config is not None
assert isinstance(builder._config, JarvisConfig)
def test_builder_build_raises_without_engine(self):
"""build() should raise RuntimeError when no engine is available."""
config = JarvisConfig()
# Use a nonsense engine key to ensure no engine is found
builder = SystemBuilder(config).engine("nonexistent_engine_xyz_123")
with pytest.raises(RuntimeError, match="No inference engine"):
builder.build()