- Replace blacklisted_tools configuration key and comments in config/artemis.jsonc and README.md with denylisted_tools - Update AgentGlobalConfig and AgentConfig with denylisted_tools and validation aliases - Update AgentConfigBuilder and Explorer agent to use denylist conventions - Update Admin Console replay manager and data engine trace filters - Update all associated test suites and mock configurations - Add license headers and clean up test imports
542 lines
21 KiB
Python
542 lines
21 KiB
Python
# Copyright 2026 Google LLC
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""Unit tests for the unified artemis.config package."""
|
|
|
|
from pathlib import Path
|
|
import tempfile
|
|
from unittest.mock import MagicMock
|
|
import pytest
|
|
from pydantic import SecretStr
|
|
|
|
from artemis.config import (
|
|
CONFIG_DIR,
|
|
ROOT_DIR,
|
|
AgentGlobalConfig,
|
|
LLMConfig,
|
|
OutputConfig,
|
|
Settings,
|
|
cleanup_temp_dir,
|
|
clear_ipc_port,
|
|
clear_ls_address,
|
|
deep_merge_llm_config,
|
|
get_app_dir,
|
|
get_config_path,
|
|
get_data_engine_db_path,
|
|
get_default_llm_config,
|
|
get_default_traces_path,
|
|
get_temp_dir,
|
|
get_traces_dir,
|
|
load_agent_config,
|
|
read_ipc_port,
|
|
read_ls_address,
|
|
record_events,
|
|
write_ipc_port,
|
|
write_ls_address,
|
|
)
|
|
|
|
|
|
def test_paths_and_directories():
|
|
"""Verify central path resolution."""
|
|
assert ROOT_DIR.exists()
|
|
assert (ROOT_DIR / "artemis").exists()
|
|
assert CONFIG_DIR.exists()
|
|
assert (CONFIG_DIR / "artemis.jsonc").exists()
|
|
|
|
app_dir = get_app_dir()
|
|
assert isinstance(app_dir, Path)
|
|
|
|
traces_path = get_default_traces_path()
|
|
assert isinstance(traces_path, Path)
|
|
assert get_traces_dir() == traces_path
|
|
|
|
db_path = get_data_engine_db_path()
|
|
assert db_path.name == "data_engine.db"
|
|
|
|
temp_dir = get_temp_dir("test_subfolder")
|
|
assert temp_dir.exists()
|
|
assert temp_dir.name == "test_subfolder"
|
|
|
|
|
|
def test_config_file_resolver():
|
|
"""Test get_config_path for unified artemis.jsonc."""
|
|
artemis_path = get_config_path("artemis.jsonc")
|
|
assert artemis_path.exists()
|
|
|
|
with pytest.raises(FileNotFoundError):
|
|
get_config_path("non_existent_config_12345.json")
|
|
|
|
|
|
def test_settings_and_api_key_fallbacks(monkeypatch):
|
|
"""Test Settings model, API key fallbacks, and get/set methods."""
|
|
monkeypatch.delenv("GOOGLE_API_KEY", raising=False)
|
|
monkeypatch.delenv("GEMINI_API_KEY", raising=False)
|
|
monkeypatch.delenv("GCP_API_KEY", raising=False)
|
|
monkeypatch.delenv("OPENAI_API_KEY", raising=False)
|
|
|
|
custom_settings = Settings(
|
|
_env_file=None,
|
|
GOOGLE_API_KEY=None,
|
|
GEMINI_API_KEY=SecretStr("gemini_key_123"),
|
|
OPENAI_API_KEY=SecretStr("openai_key_456"),
|
|
OCR_API_KEY=SecretStr("ocr_key_789"),
|
|
)
|
|
# Automatic fallback should populate GOOGLE_API_KEY from GEMINI_API_KEY
|
|
assert custom_settings.GOOGLE_API_KEY is not None
|
|
assert custom_settings.GOOGLE_API_KEY.get_secret_value() == "gemini_key_123"
|
|
assert custom_settings.get_api_key("ocr").get_secret_value() == "ocr_key_789"
|
|
|
|
assert custom_settings.get_api_key("google").get_secret_value() == "gemini_key_123"
|
|
assert custom_settings.get_api_key("gemini").get_secret_value() == "gemini_key_123"
|
|
assert custom_settings.get_api_key("openai").get_secret_value() == "openai_key_456"
|
|
assert custom_settings.get_api_key("nonexistent") is None
|
|
|
|
# Test dynamic set_api_key
|
|
custom_settings.set_api_key("xai", "xai_test_key", persist_to_env=False)
|
|
assert custom_settings.get_api_key("xai").get_secret_value() == "xai_test_key"
|
|
|
|
|
|
def test_llm_config_parsing_and_merging():
|
|
"""Test LLMConfig parsing, agent querying, and deep merging."""
|
|
llm_cfg = get_default_llm_config()
|
|
assert isinstance(llm_cfg, LLMConfig)
|
|
assert llm_cfg.planner.provider in ("google", "openai", "openrouter", "xai", "vertexai")
|
|
assert llm_cfg.get_agent("planner") is not None
|
|
assert llm_cfg.get_utils("hopper") is not None
|
|
|
|
# Deep merge overrides
|
|
overrides = {
|
|
"planner": {
|
|
"model": "custom-model-v1",
|
|
"temperature": 0.7,
|
|
}
|
|
}
|
|
merged = deep_merge_llm_config(llm_cfg, overrides)
|
|
assert merged.planner.model == "custom-model-v1"
|
|
assert merged.planner.temperature == 0.7
|
|
|
|
|
|
def test_agent_config_loading():
|
|
"""Test AgentGlobalConfig parsing from agent_config.json / artemis.jsonc."""
|
|
agent_cfg = load_agent_config()
|
|
assert isinstance(agent_cfg, AgentGlobalConfig)
|
|
assert "operator" in agent_cfg.explorer_versions
|
|
assert agent_cfg.explorer.default_version == "flash"
|
|
assert agent_cfg.explorer.flash_mode == "flash"
|
|
assert agent_cfg.explorer.pro_mode == "flash"
|
|
assert agent_cfg.explorer.caching is True
|
|
assert "explorer" in agent_cfg.denylisted_tools
|
|
assert agent_cfg.video_analyzer.enable_ledger is True
|
|
assert agent_cfg.planner_validation.enabled is False
|
|
assert agent_cfg.planner_validation.similarity_threshold == 0.85
|
|
assert agent_cfg.committee.enabled is False
|
|
assert agent_cfg.committee.debate_rounds == 2
|
|
assert agent_cfg.checker.enabled is False
|
|
assert agent_cfg.checker.max_iterations == 20
|
|
assert agent_cfg.checker.max_chat_rounds == 4
|
|
assert agent_cfg.outputter.enabled is True
|
|
assert agent_cfg.outputter.force_synthesis is False
|
|
assert agent_cfg.flash.max_turns == 30
|
|
assert agent_cfg.flash.explorer_mode == "flash"
|
|
assert agent_cfg.pro.explorer.mode == "flash"
|
|
assert agent_cfg.pro.checker.enabled is False
|
|
assert agent_cfg.pro.committee.enabled is False
|
|
assert agent_cfg.pro.planner_validation.enabled is False
|
|
assert agent_cfg.pro.video_analyzer.enable_ledger is True
|
|
|
|
|
|
def test_output_config_and_recording():
|
|
"""Test OutputConfig behavior and event recording."""
|
|
cfg = OutputConfig(output_description="Output a valid JSON summary")
|
|
assert cfg.needs_structured_format() is True
|
|
|
|
cfg_disabled = OutputConfig(output_description="Output JSON", enable_outputter=False)
|
|
assert cfg_disabled.needs_structured_format() is False
|
|
|
|
cfg_forced = OutputConfig(force_synthesis=True)
|
|
assert cfg_forced.needs_structured_format() is True
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
output_file = Path(tmpdir) / "events.json"
|
|
events_data = [{"event": "test_event", "status": "ok"}]
|
|
record_events(output_file, events_data)
|
|
assert output_file.exists()
|
|
assert "test_event" in output_file.read_text(encoding="utf-8")
|
|
|
|
|
|
def test_runtime_state_and_ipc():
|
|
"""Test IPC port and LS address state helpers."""
|
|
# Test IPC port
|
|
write_ipc_port(49152)
|
|
assert read_ipc_port() == 49152
|
|
clear_ipc_port()
|
|
|
|
# Test LS address
|
|
write_ls_address("localhost:12345")
|
|
assert read_ls_address() == "localhost:12345"
|
|
clear_ls_address()
|
|
|
|
# Test temp dir cleanup
|
|
test_temp_sub = get_temp_dir("test_cleanup_dir")
|
|
test_temp_file = test_temp_sub / "temp_marker.txt"
|
|
test_temp_file.write_text("temporary data")
|
|
assert test_temp_file.exists()
|
|
|
|
deleted = cleanup_temp_dir("test_cleanup_dir")
|
|
assert deleted >= 1
|
|
assert not test_temp_file.exists()
|
|
|
|
|
|
def test_planner_validation_builder_and_milestones():
|
|
"""Test AgentConfigBuilder methods for planner validation and validate_milestones threshold."""
|
|
from artemis.sdk.builders.agent_config_builder import AgentConfigBuilder
|
|
from artemis.graph.graph import validate_milestones
|
|
|
|
# Default builder inherits from artemis.jsonc (enabled=False, similarity_threshold=0.85)
|
|
builder = AgentConfigBuilder()
|
|
cfg = builder.build()
|
|
assert cfg.disable_planner_validation is True
|
|
assert cfg.planner_validation_threshold == 0.85
|
|
|
|
# Fluent enabling
|
|
cfg_enabled = (
|
|
AgentConfigBuilder()
|
|
.with_planner_validation(enabled=True, similarity_threshold=0.90)
|
|
.build()
|
|
)
|
|
assert cfg_enabled.disable_planner_validation is False
|
|
assert cfg_enabled.planner_validation_threshold == 0.90
|
|
|
|
# Fluent disabling
|
|
cfg_disabled = AgentConfigBuilder().with_disable_planner_validation(True).build()
|
|
assert cfg_disabled.disable_planner_validation is True
|
|
|
|
# Test validate_milestones with custom thresholds
|
|
before = "- [ ] Tap Login button\n- [ ] Enter password"
|
|
after_minor = "- [ ] Tap the Login button\n- [ ] Enter password"
|
|
# Minor edit has ~0.94 similarity
|
|
assert validate_milestones(before, after_minor, similarity_threshold=0.85) is False
|
|
assert validate_milestones(before, after_minor, similarity_threshold=0.98) is True
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_committee_builder_and_graph_mounting():
|
|
"""Test AgentConfigBuilder committee methods and graph mounting."""
|
|
from artemis.context import ArtemisContext, DeviceContext, DevicePlatform, ExecutionSetup
|
|
from artemis.graph.graph import get_graph
|
|
from artemis.sdk.builders.agent_config_builder import AgentConfigBuilder
|
|
|
|
# Default: disabled
|
|
cfg_default = AgentConfigBuilder().build()
|
|
assert cfg_default.enable_committee is False
|
|
assert cfg_default.committee_debate_rounds == 2
|
|
|
|
# Enabled via builder
|
|
cfg_enabled = AgentConfigBuilder().with_committee(enabled=True, debate_rounds=3).build()
|
|
assert cfg_enabled.enable_committee is True
|
|
assert cfg_enabled.committee_debate_rounds == 3
|
|
|
|
# Test mounting in graph
|
|
device = DeviceContext(
|
|
host_platform="LINUX",
|
|
mobile_platform=DevicePlatform.ANDROID,
|
|
device_id="dummy",
|
|
device_width=1080,
|
|
device_height=2400,
|
|
)
|
|
ctx_disabled = ArtemisContext(
|
|
device=device,
|
|
execution_setup=ExecutionSetup(enable_committee=False),
|
|
)
|
|
graph_disabled = await get_graph(ctx_disabled)
|
|
op_node_disabled = graph_disabled.nodes.get("operator")
|
|
assert op_node_disabled is not None
|
|
# Verify ask_committee is not mounted when disabled
|
|
op_tools_disabled = [t.name for t in op_node_disabled.bound.afunc.tools]
|
|
assert "ask_committee" not in op_tools_disabled
|
|
|
|
ctx_enabled = ArtemisContext(
|
|
device=device,
|
|
execution_setup=ExecutionSetup(enable_committee=True, committee_debate_rounds=3),
|
|
)
|
|
graph_enabled = await get_graph(ctx_enabled)
|
|
op_node_enabled = graph_enabled.nodes.get("operator")
|
|
assert op_node_enabled is not None
|
|
# Verify ask_committee is mounted when enabled
|
|
op_tools_enabled = [t.name for t in op_node_enabled.bound.afunc.tools]
|
|
assert "ask_committee" in op_tools_enabled
|
|
|
|
|
|
def test_checker_builder_and_context_propagation():
|
|
"""Test AgentConfigBuilder methods and context propagation for checker."""
|
|
from unittest.mock import MagicMock
|
|
from artemis.context import ArtemisContext, DeviceContext, DevicePlatform
|
|
from artemis.sdk.agent import Agent
|
|
from artemis.sdk.builders.agent_config_builder import AgentConfigBuilder
|
|
|
|
# Default builder inherits from artemis.jsonc (enabled=False, max_iterations=20, max_chat_rounds=4)
|
|
builder = AgentConfigBuilder()
|
|
cfg = builder.build()
|
|
assert cfg.disable_checker is True
|
|
assert cfg.checker_max_iterations == 20
|
|
assert cfg.checker_max_chat_rounds == 4
|
|
|
|
# Fluent enabling
|
|
cfg_enabled = (
|
|
AgentConfigBuilder()
|
|
.with_checker(enabled=True, max_iterations=25, max_chat_rounds=5)
|
|
.build()
|
|
)
|
|
assert cfg_enabled.disable_checker is False
|
|
assert cfg_enabled.checker_max_iterations == 25
|
|
assert cfg_enabled.checker_max_chat_rounds == 5
|
|
|
|
# Fluent disabling
|
|
cfg_disabled = AgentConfigBuilder().with_disable_checker(True).build()
|
|
assert cfg_disabled.disable_checker is True
|
|
|
|
# Test propagation to ExecutionSetup via Agent._prepare_tracing
|
|
agent = Agent(config=cfg_enabled)
|
|
device = DeviceContext(
|
|
host_platform="LINUX",
|
|
mobile_platform=DevicePlatform.ANDROID,
|
|
device_id="dummy",
|
|
device_width=1080,
|
|
device_height=2400,
|
|
)
|
|
ctx = ArtemisContext(device=device)
|
|
mock_task = MagicMock()
|
|
mock_task.get_name.return_value = "test_task"
|
|
mock_task.request.record_trace = False
|
|
mock_task.request.name = "test_task"
|
|
mock_task.request.profile = None
|
|
mock_task.request.goal = "Test goal"
|
|
agent._prepare_tracing(mock_task, ctx)
|
|
|
|
assert ctx.execution_setup is not None
|
|
assert ctx.execution_setup.disable_checker is False
|
|
assert ctx.execution_setup.checker_max_iterations == 25
|
|
assert ctx.execution_setup.checker_max_chat_rounds == 5
|
|
|
|
|
|
def test_explorer_builder_and_resolution(monkeypatch):
|
|
"""Test AgentConfigBuilder explorer methods and multi-tier resolution logic."""
|
|
from artemis.context import ArtemisContext, DeviceContext, DevicePlatform
|
|
from artemis.sdk.agent import Agent
|
|
from artemis.sdk.builders.agent_config_builder import AgentConfigBuilder
|
|
from artemis.tools.explorer_tool import resolve_explorer_version
|
|
|
|
# Default builder inherits from artemis.jsonc (default="flash", flash_mode="flash", pro_mode="flash", caching=True)
|
|
builder = AgentConfigBuilder()
|
|
cfg = builder.build()
|
|
assert cfg.explorer.default_version == "flash"
|
|
assert cfg.explorer.flash_mode == "flash"
|
|
assert cfg.explorer.pro_mode == "flash"
|
|
assert cfg.explorer.caching is True
|
|
|
|
# Fluent configuration with with_explorer
|
|
cfg_custom = (
|
|
AgentConfigBuilder()
|
|
.with_explorer(
|
|
version="pro",
|
|
flash_mode="flash",
|
|
pro_mode="ultra",
|
|
caching=False,
|
|
versions={"operator": "ultra", "validator": "pro"},
|
|
)
|
|
.build()
|
|
)
|
|
assert cfg_custom.explorer.default_version == "pro"
|
|
assert cfg_custom.explorer.flash_mode == "flash"
|
|
assert cfg_custom.explorer.pro_mode == "ultra"
|
|
assert cfg_custom.explorer.caching is False
|
|
assert cfg_custom.explorer_versions["operator"] == "ultra"
|
|
assert cfg_custom.explorer_versions["validator"] == "pro"
|
|
|
|
# Fluent configuration with with_explorer_version shorthand
|
|
cfg_shorthand = AgentConfigBuilder().with_explorer_version("ultra").build()
|
|
assert cfg_shorthand.explorer.default_version == "ultra"
|
|
|
|
# Context setup for resolution tests
|
|
device = DeviceContext(
|
|
host_platform="LINUX",
|
|
mobile_platform=DevicePlatform.ANDROID,
|
|
device_id="dummy",
|
|
device_width=1080,
|
|
device_height=2400,
|
|
)
|
|
ctx = ArtemisContext(device=device, agent_config=cfg_custom)
|
|
|
|
# 1. Explicit override takes highest priority
|
|
assert resolve_explorer_version(ctx, explicit_version="flash") == "flash"
|
|
assert resolve_explorer_version(ctx, explicit_version="pro") == "pro"
|
|
assert resolve_explorer_version(ctx, explicit_version="ultra") == "ultra"
|
|
|
|
# 2. Environment variable override
|
|
monkeypatch.setenv("ARTEMIS_EXPLORER_VERSION", "ultra")
|
|
assert resolve_explorer_version(ctx) == "ultra"
|
|
monkeypatch.delenv("ARTEMIS_EXPLORER_VERSION", raising=False)
|
|
|
|
# 3. Per-agent mapping in explorer_versions
|
|
assert resolve_explorer_version(ctx, agent_or_profile_name="operator") == "ultra"
|
|
assert resolve_explorer_version(ctx, agent_or_profile_name="validator") == "pro"
|
|
|
|
# 4. Pro profile vs Flash profile resolution
|
|
cfg_profiled = (
|
|
AgentConfigBuilder()
|
|
.with_explorer(flash_mode="flash", pro_mode="pro", default_version="flash", versions={})
|
|
.build()
|
|
)
|
|
ctx_profiled = ArtemisContext(device=device, agent_config=cfg_profiled)
|
|
assert resolve_explorer_version(ctx_profiled, agent_or_profile_name="flash") == "flash"
|
|
assert resolve_explorer_version(ctx_profiled, agent_or_profile_name="flash_runner") == "flash"
|
|
assert resolve_explorer_version(ctx_profiled, agent_or_profile_name="pro") == "pro"
|
|
assert resolve_explorer_version(ctx_profiled, agent_or_profile_name="operator") == "pro"
|
|
|
|
# 5. Propagation to ExecutionSetup via Agent._prepare_tracing
|
|
agent = Agent(config=cfg_custom)
|
|
mock_task = MagicMock()
|
|
mock_task.get_name.return_value = "explorer_test_task"
|
|
mock_task.request.record_trace = False
|
|
mock_task.request.name = "explorer_test_task"
|
|
mock_task.request.profile = None
|
|
mock_task.request.goal = "Test explorer propagation"
|
|
agent._prepare_tracing(mock_task, ctx)
|
|
|
|
assert ctx.execution_setup is not None
|
|
assert ctx.execution_setup.explorer_version == "pro"
|
|
assert ctx.execution_setup.explorer_flash_mode == "flash"
|
|
assert ctx.execution_setup.explorer_pro_mode == "ultra"
|
|
assert ctx.execution_setup.explorer_caching is False
|
|
|
|
|
|
def test_outputter_builder_and_context_propagation():
|
|
"""Test AgentConfigBuilder outputter methods and propagation to ExecutionSetup."""
|
|
from artemis.context import ArtemisContext, DeviceContext, DevicePlatform
|
|
from artemis.sdk.agent import Agent
|
|
from artemis.sdk.builders.agent_config_builder import AgentConfigBuilder
|
|
|
|
# Default builder inherits from artemis.jsonc (enabled=True, force_synthesis=False)
|
|
builder = AgentConfigBuilder()
|
|
cfg = builder.build()
|
|
assert cfg.disable_outputter is False
|
|
assert cfg.outputter.enabled is True
|
|
assert cfg.outputter.force_synthesis is False
|
|
|
|
# Fluent configuration with with_outputter
|
|
cfg_custom = AgentConfigBuilder().with_outputter(enabled=True, force_synthesis=True).build()
|
|
assert cfg_custom.disable_outputter is False
|
|
assert cfg_custom.outputter.enabled is True
|
|
assert cfg_custom.outputter.force_synthesis is True
|
|
|
|
# Fluent disabling with with_disable_outputter
|
|
cfg_disabled = AgentConfigBuilder().with_disable_outputter(True).build()
|
|
assert cfg_disabled.disable_outputter is True
|
|
assert cfg_disabled.outputter.enabled is False
|
|
|
|
# Test propagation to ExecutionSetup via Agent._prepare_tracing
|
|
device = DeviceContext(
|
|
host_platform="LINUX",
|
|
mobile_platform=DevicePlatform.ANDROID,
|
|
device_id="dummy",
|
|
device_width=1080,
|
|
device_height=2400,
|
|
)
|
|
ctx = ArtemisContext(device=device)
|
|
agent = Agent(config=cfg_custom)
|
|
mock_task = MagicMock()
|
|
mock_task.get_name.return_value = "outputter_test_task"
|
|
mock_task.request.record_trace = False
|
|
mock_task.request.name = "outputter_test_task"
|
|
mock_task.request.profile = None
|
|
mock_task.request.goal = "Test outputter propagation"
|
|
agent._prepare_tracing(mock_task, ctx)
|
|
|
|
assert ctx.execution_setup is not None
|
|
assert ctx.execution_setup.disable_outputter is False
|
|
assert ctx.execution_setup.outputter.enabled is True
|
|
assert ctx.execution_setup.outputter.force_synthesis is True
|
|
|
|
|
|
def test_categorized_flash_and_pro_profile_builders():
|
|
"""Test with_flash_config and with_pro_config fluent builders and bidirectional sync."""
|
|
from artemis.config.agent import AgentGlobalConfig
|
|
from artemis.sdk.builders.agent_config_builder import AgentConfigBuilder
|
|
|
|
# 1. Test with_flash_config
|
|
cfg_flash = AgentConfigBuilder().with_flash_config(max_turns=15, explorer_mode="flash").build()
|
|
assert cfg_flash.flash.max_turns == 15
|
|
assert cfg_flash.flash.explorer_mode == "flash"
|
|
assert cfg_flash.explorer.flash_mode == "flash"
|
|
|
|
# 2. Test with_pro_config
|
|
cfg_pro = (
|
|
AgentConfigBuilder()
|
|
.with_pro_config(
|
|
explorer_mode="ultra",
|
|
planner_validation=True,
|
|
committee=True,
|
|
checker=True,
|
|
video_ledger=False,
|
|
)
|
|
.build()
|
|
)
|
|
assert cfg_pro.pro.explorer.mode == "ultra"
|
|
assert cfg_pro.explorer.pro_mode == "ultra"
|
|
assert cfg_pro.disable_planner_validation is False
|
|
assert cfg_pro.enable_committee is True
|
|
assert cfg_pro.disable_checker is False
|
|
assert cfg_pro.enable_video_ledger is False
|
|
|
|
# 3. Test AgentGlobalConfig bidirectional synchronization
|
|
raw_dict = {
|
|
"flash": {"max_turns": 25, "explorer_mode": "flash"},
|
|
"pro": {
|
|
"explorer": {"mode": "pro", "caching": False},
|
|
"checker": {"enabled": True, "max_iterations": 10},
|
|
"committee": {"enabled": True, "debate_rounds": 4},
|
|
},
|
|
}
|
|
synced = AgentGlobalConfig.model_validate(raw_dict)
|
|
assert synced.flash.max_turns == 25
|
|
assert synced.explorer.flash_mode == "flash"
|
|
assert synced.explorer.pro_mode == "pro"
|
|
assert synced.explorer.caching is False
|
|
assert synced.checker.enabled is True
|
|
assert synced.checker.max_iterations == 10
|
|
assert synced.committee.enabled is True
|
|
assert synced.committee.debate_rounds == 4
|
|
|
|
|
|
def test_agent_config_environment_variable_overrides(monkeypatch):
|
|
"""Test environment variable overrides for AgentGlobalConfig switches."""
|
|
from artemis.config.agent import load_agent_config
|
|
|
|
monkeypatch.setenv("ARTEMIS_CHECKER_ENABLED", "true")
|
|
monkeypatch.setenv("ARTEMIS_COMMITTEE_ENABLED", "1")
|
|
monkeypatch.setenv("ARTEMIS_PLANNER_VALIDATION_ENABLED", "yes")
|
|
monkeypatch.setenv("ARTEMIS_OUTPUTTER_ENABLED", "false")
|
|
monkeypatch.setenv("ARTEMIS_VIDEO_LEDGER_ENABLED", "0")
|
|
|
|
cfg = load_agent_config()
|
|
assert cfg.checker.enabled is True
|
|
assert cfg.pro.checker.enabled is True
|
|
assert cfg.committee.enabled is True
|
|
assert cfg.pro.committee.enabled is True
|
|
assert cfg.planner_validation.enabled is True
|
|
assert cfg.pro.planner_validation.enabled is True
|
|
assert cfg.outputter.enabled is False
|
|
assert cfg.video_analyzer.enable_ledger is False
|
|
assert cfg.pro.video_analyzer.enable_ledger is False
|