import json from nanobot.config.loader import load_config, save_config def test_load_config_keeps_max_tokens_and_ignores_legacy_memory_window(tmp_path) -> None: config_path = tmp_path / "config.json" config_path.write_text( json.dumps( { "agents": { "defaults": { "maxTokens": 1234, "memoryWindow": 42, } } } ), encoding="utf-8", ) config = load_config(config_path) assert config.agents.defaults.max_tokens == 1234 assert config.agents.defaults.context_window_tokens == 65_536 assert not hasattr(config.agents.defaults, "memory_window") def test_save_config_writes_context_window_tokens_but_not_memory_window(tmp_path) -> None: config_path = tmp_path / "config.json" config_path.write_text( json.dumps( { "agents": { "defaults": { "maxTokens": 2222, "memoryWindow": 30, } } } ), encoding="utf-8", ) config = load_config(config_path) save_config(config, config_path) saved = json.loads(config_path.read_text(encoding="utf-8")) defaults = saved["agents"]["defaults"] assert defaults["maxTokens"] == 2222 assert defaults["contextWindowTokens"] == 65_536 assert "memoryWindow" not in defaults def test_onboard_does_not_crash_with_legacy_memory_window(tmp_path, monkeypatch) -> None: config_path = tmp_path / "config.json" workspace = tmp_path / "workspace" config_path.write_text( json.dumps( { "agents": { "defaults": { "maxTokens": 3333, "memoryWindow": 50, } } } ), encoding="utf-8", ) monkeypatch.setattr("nanobot.config.loader.get_config_path", lambda: config_path) monkeypatch.setattr("nanobot.cli.commands.get_workspace_path", lambda _workspace=None: workspace) from typer.testing import CliRunner from nanobot.cli.commands import app runner = CliRunner() result = runner.invoke(app, ["onboard"], input="n\n") assert result.exit_code == 0 def test_onboard_refresh_backfills_missing_channel_fields(tmp_path, monkeypatch) -> None: from types import SimpleNamespace config_path = tmp_path / "config.json" workspace = tmp_path / "workspace" config_path.write_text( json.dumps( { "channels": { "qq": { "enabled": False, "appId": "", "secret": "", "allowFrom": [], } } } ), encoding="utf-8", ) monkeypatch.setattr("nanobot.config.loader.get_config_path", lambda: config_path) monkeypatch.setattr("nanobot.cli.commands.get_workspace_path", lambda _workspace=None: workspace) monkeypatch.setattr( "nanobot.channels.registry.discover_all", lambda: { "qq": SimpleNamespace( default_config=lambda: { "enabled": False, "appId": "", "secret": "", "allowFrom": [], "msgFormat": "plain", } ) }, ) from typer.testing import CliRunner from nanobot.cli.commands import app runner = CliRunner() result = runner.invoke(app, ["onboard"], input="n\n") assert result.exit_code == 0 saved = json.loads(config_path.read_text(encoding="utf-8")) assert saved["channels"]["qq"]["msgFormat"] == "plain"