diff --git a/docs/memory.md b/docs/memory.md index a8d43d81..acb67b46 100644 --- a/docs/memory.md +++ b/docs/memory.md @@ -186,9 +186,7 @@ Dream is configured under `agents.defaults.dream`: "defaults": { "dream": { "intervalH": 2, - "modelOverride": null, - "maxBatchSize": 20, - "maxIterations": 10 + "modelOverride": null } } } @@ -200,15 +198,12 @@ Dream is configured under `agents.defaults.dream`: | `intervalH` | How often Dream runs, in hours | | `cron` | Cron expression override (takes precedence over `intervalH`) | | `modelOverride` | Optional Dream-specific model override *(pending implementation)* | -| `maxBatchSize` | *(Deprecated — not used)* | -| `maxIterations` | *(Deprecated — not used)* | In practical terms: - `intervalH` is the normal way to configure Dream frequency. Internally it runs as an `every` schedule. - `cron` overrides `intervalH` when set, allowing precise cron expressions (e.g. `0 */4 * * *`). - `modelOverride` is reserved for a future release. Currently Dream uses the same model as the main agent. -- `maxBatchSize` and `maxIterations` are preserved for config compatibility but no longer affect behavior. ## In Practice diff --git a/nanobot/channels/registry.py b/nanobot/channels/registry.py index 2958afee..c6f81c20 100644 --- a/nanobot/channels/registry.py +++ b/nanobot/channels/registry.py @@ -3,8 +3,6 @@ from __future__ import annotations import pkgutil -from functools import cache -from importlib.metadata import entry_points from typing import TYPE_CHECKING from loguru import logger @@ -19,22 +17,6 @@ if TYPE_CHECKING: from nanobot.channels.base import BaseChannel -@cache -def _warn_legacy_channel_entry_points() -> None: - # TODO(v0.3.1): Remove this detection and warning. v0.3.0 is the final - # migration window for installed legacy channel entry points. - names = sorted({entry_point.name for entry_point in entry_points(group="nanobot.channels")}) - if not names: - return - logger.warning( - "Legacy channel entry points were detected but will not be loaded: {}. " - "The '{}' entry-point group is no longer supported; use a built-in channel or " - "migrate it into nanobot/channels//.", - ", ".join(names), - "nanobot.channels", - ) - - def _channel_package_names() -> list[str]: import nanobot.channels as package @@ -49,7 +31,6 @@ def discover_plugins( enabled_names: set[str] | None = None, ) -> dict[str, ChannelPlugin]: """Load dependency-free descriptors from self-contained channel packages.""" - _warn_legacy_channel_entry_points() plugins: dict[str, ChannelPlugin] = {} for name in _channel_package_names(): if enabled_names is not None and name not in enabled_names: diff --git a/nanobot/cli/commands.py b/nanobot/cli/commands.py index e3db4ee7..67df115e 100644 --- a/nanobot/cli/commands.py +++ b/nanobot/cli/commands.py @@ -815,7 +815,6 @@ def _load_runtime_config(config: str | None = None, workspace: str | None = None except ValueError as e: console.print(f"[red]Error: {e}[/red]") raise typer.Exit(1) - _warn_deprecated_config_keys(config_path) if workspace: loaded.agents.defaults.workspace = workspace return loaded @@ -836,24 +835,6 @@ def _read_trigger_cli_message(message: str | None) -> str: raise typer.Exit(1) -def _warn_deprecated_config_keys(config_path: Path | None) -> None: - """Hint users to remove obsolete keys from their config file.""" - import json - - from nanobot.config.loader import get_config_path - - path = config_path or get_config_path() - try: - raw = json.loads(path.read_text(encoding="utf-8")) - except Exception: - return - if "memoryWindow" in raw.get("agents", {}).get("defaults", {}): - console.print( - "[dim]Hint: `memoryWindow` in your config is no longer used " - "and can be safely removed.[/dim]" - ) - - def _load_inspection_config( config: str | None = None, workspace: str | None = None, @@ -873,7 +854,6 @@ def _load_inspection_config( except ValueError as exc: console.print(f"[red]Error: {exc}[/red]") raise typer.Exit(1) from exc - _warn_deprecated_config_keys(display_path) if workspace: loaded.agents.defaults.workspace = workspace return display_path, loaded diff --git a/nanobot/config/loader.py b/nanobot/config/loader.py index 3af4bde1..f32aab1a 100644 --- a/nanobot/config/loader.py +++ b/nanobot/config/loader.py @@ -7,7 +7,6 @@ from pathlib import Path from typing import Any import pydantic -from loguru import logger from pydantic import BaseModel from nanobot.config.schema import Config, _resolve_tool_config_refs @@ -200,23 +199,6 @@ def _env_replace(match: re.Match[str]) -> str: def _migrate_config(data: dict) -> dict: """Migrate old config formats to current.""" - agents = data.get("agents", {}) - defaults = agents.get("defaults", {}) if isinstance(agents, dict) else {} - if isinstance(defaults, dict): - had_legacy_max_messages = ( - "maxMessages" in defaults or "max_messages" in defaults - ) - defaults.pop("maxMessages", None) - defaults.pop("max_messages", None) - if had_legacy_max_messages: - # TODO(v0.3.1): Remove this legacy cleanup branch. v0.3.0 is the - # final release that warns before the schema silently ignores the field. - logger.warning( - "agents.defaults.maxMessages/max_messages is legacy and ignored; " - "replay max messages is now an internal safety cap. Remove it from " - "config. This compatibility warning will be removed in the next version." - ) - # Move tools.exec.restrictToWorkspace → tools.restrictToWorkspace tools = data.get("tools", {}) exec_cfg = tools.get("exec", {}) diff --git a/nanobot/config/schema.py b/nanobot/config/schema.py index 8b51404e..abfc29c9 100644 --- a/nanobot/config/schema.py +++ b/nanobot/config/schema.py @@ -64,9 +64,6 @@ class DreamConfig(Base): default=None, validation_alias=AliasChoices("modelOverride", "model", "model_override"), ) # Override model for Dream sessions (pending implementation) - max_batch_size: int = Field(default=20, ge=1) # Deprecated: no longer used - max_iterations: int = Field(default=15, ge=1) # Deprecated: no longer used - annotate_line_ages: bool = True # Deprecated: no longer used def build_schedule(self, timezone: str) -> CronSchedule: """Build the runtime schedule, preferring the legacy cron override if present.""" diff --git a/nanobot/session/manager.py b/nanobot/session/manager.py index f67a3a68..21c776eb 100644 --- a/nanobot/session/manager.py +++ b/nanobot/session/manager.py @@ -5,7 +5,6 @@ import errno import json import os import re -import shutil from collections import OrderedDict from contextlib import suppress from copy import deepcopy @@ -477,6 +476,14 @@ class SessionManager: except _SESSION_DATA_ERRORS: return None + @classmethod + def _session_key_from_path(cls, path: Path) -> str | None: + """Decode a session key only from a canonical collision-resistant filename.""" + key = cls._decode_storage_key(path.stem) + if key is None or cls._storage_key(key) != path.stem: + return None + return key + def _get_session_path(self, key: str) -> Path: """Get the collision-resistant workspace path for a session.""" return self.sessions_dir / f"{self._storage_key(key)}.jsonl" @@ -489,61 +496,6 @@ class SessionManager: """Legacy global session path (~/.nanobot/sessions/).""" return self.legacy_sessions_dir / f"{self.safe_key(key)}.jsonl" - @staticmethod - def _stored_key_for_path(path: Path) -> str | None: - """Read the stored session key from a JSONL metadata row, if present.""" - try: - with open(path, encoding="utf-8") as f: - for line in f: - line = line.strip() - if not line: - continue - data = json.loads(line) - if not isinstance(data, dict): - raise ValueError("session records must be JSON objects") - if data.get("_type") == "metadata": - stored_key = data.get("key") - return stored_key if isinstance(stored_key, str) else None - return None - except _SESSION_DATA_ERRORS: - return None - return None - - def _resolve_session_path(self, key: str, *, migrate: bool = False) -> Path | None: - """Resolve a session path, falling back to legacy storage locations.""" - path = self._get_session_path(key) - if path.exists(): - return path - - # TODO(v0.3.1): Remove both legacy fallbacks. v0.3.0 is the final - # compatibility window for reading and lazily migrating legacy session files. - fallback_paths = [ - (self._get_legacy_lossy_path(key), "legacy lossy path"), - (self._get_legacy_session_path(key), "legacy path"), - ] - for fallback_path, description in fallback_paths: - if not fallback_path.exists(): - continue - stored_key = self._stored_key_for_path(fallback_path) - if stored_key and stored_key != key: - logger.info( - "Skipping session {} from {} because it belongs to {}", - key, - description, - stored_key, - ) - continue - if not migrate: - return fallback_path - try: - shutil.move(str(fallback_path), str(path)) - logger.info("Migrated session {} from {}", key, description) - except Exception: - logger.exception("Failed to migrate session {}", key) - return None - return path - return None - def get_or_create(self, key: str) -> Session: """ Get an existing session or create a new one. @@ -567,8 +519,8 @@ class SessionManager: def _load(self, key: str) -> Session | None: """Load a session from disk.""" - path = self._resolve_session_path(key, migrate=True) - if path is None: + path = self._get_session_path(key) + if not path.exists(): return None try: @@ -847,8 +799,8 @@ class SessionManager: Returns ``{"key", "created_at", "updated_at", "metadata", "messages"}`` or ``None`` when the session file does not exist or fails to parse. """ - path = self._resolve_session_path(key) - if path is None: + path = self._get_session_path(key) + if not path.exists(): return None try: messages: list[dict[str, Any]] = [] @@ -890,8 +842,8 @@ class SessionManager: This is used by WebUI routes that need session-level metadata but not the full conversation transcript. """ - path = self._resolve_session_path(key) - if path is None: + path = self._get_session_path(key) + if not path.exists(): return None try: with open(path, encoding="utf-8") as f: @@ -935,8 +887,9 @@ class SessionManager: sessions = [] for path in self.sessions_dir.glob("*.jsonl"): - decoded = self._decode_storage_key(path.stem) - fallback_key = decoded or path.stem.replace("_", ":", 1) + storage_key = self._session_key_from_path(path) + if storage_key is None: + continue try: # Read the metadata line and a small preview for session lists. with open(path, encoding="utf-8") as f: @@ -946,7 +899,7 @@ class SessionManager: if not isinstance(data, dict): raise ValueError("session records must be JSON objects") if data.get("_type") == "metadata": - key = data.get("key") or fallback_key + key = data.get("key") or storage_key metadata = data.get("metadata", {}) title = _metadata_title(metadata) preview = "" @@ -991,7 +944,7 @@ class SessionManager: except FileNotFoundError: continue except _SESSION_DATA_ERRORS: - repaired = self._repair(fallback_key, path=path) + repaired = self._repair(storage_key, path=path) if repaired is not None: sessions.append( { diff --git a/nanobot/webui/session_list_index.py b/nanobot/webui/session_list_index.py index c0689a43..104a8206 100644 --- a/nanobot/webui/session_list_index.py +++ b/nanobot/webui/session_list_index.py @@ -54,7 +54,11 @@ def _reconcile_index(session_manager: SessionManager) -> tuple[list[dict[str, An for row in existing_rows or [] if isinstance(row.get("file"), str) } - paths = sorted(session_manager.sessions_dir.glob("*.jsonl")) + paths = sorted( + path + for path in session_manager.sessions_dir.glob("*.jsonl") + if SessionManager._session_key_from_path(path) is not None + ) rows: list[dict[str, Any]] = [] changed = existing_rows is None @@ -268,8 +272,9 @@ def _indexed_row_for_session(session: Session, path: Path) -> dict[str, Any]: def _scan_session_row(session_manager: SessionManager, path: Path) -> dict[str, Any] | None: - storage_key = SessionManager._decode_storage_key(path.stem) - fallback_key = storage_key or path.stem.replace("_", ":", 1) + storage_key = SessionManager._session_key_from_path(path) + if storage_key is None: + return None try: with open(path, encoding="utf-8") as f: first_line = f.readline().strip() @@ -320,7 +325,7 @@ def _scan_session_row(session_manager: SessionManager, path: Path) -> dict[str, fallback_time = datetime.fromtimestamp(signature["mtime_ns"] / 1e9).isoformat() created_at_s = created_at_s or fallback_time updated_at_s = updated_at_s or fallback_time - key = data.get("key") or fallback_key + key = data.get("key") or storage_key activity_signature = _webui_activity_signature(key) activity_updated_at = _webui_activity_updated_at(activity_signature) return { @@ -340,7 +345,7 @@ def _scan_session_row(session_manager: SessionManager, path: Path) -> dict[str, **activity_signature, } except Exception: - repaired = session_manager._repair(fallback_key) + repaired = session_manager._repair(storage_key) if repaired is None: return None return _indexed_row_for_session(repaired, path) diff --git a/tests/agent/test_session_collision.py b/tests/agent/test_session_collision.py index 0d854335..2942988f 100644 --- a/tests/agent/test_session_collision.py +++ b/tests/agent/test_session_collision.py @@ -65,7 +65,7 @@ def test_save_uses_new_path_not_lossy(tmp_path: Path, monkeypatch) -> None: assert lossy_path.read_text(encoding="utf-8") == stale_lossy -def test_load_falls_back_to_lossy_path(tmp_path: Path, monkeypatch) -> None: +def test_load_ignores_legacy_lossy_path(tmp_path: Path, monkeypatch) -> None: sm = _manager(tmp_path, monkeypatch) key = "telegram:legacy:lossy" lossy_path = sm._get_legacy_lossy_path(key) @@ -73,49 +73,23 @@ def test_load_falls_back_to_lossy_path(tmp_path: Path, monkeypatch) -> None: session = sm._load(key) - assert session is not None - assert session.metadata == {"source": "test"} - assert session.messages[0]["content"] == "loaded from lossy" + assert session is None + assert lossy_path.exists() + assert not sm._get_session_path(key).exists() -def test_load_migrates_lossy_to_new_path(tmp_path: Path, monkeypatch) -> None: +def test_load_ignores_legacy_global_path(tmp_path: Path, monkeypatch) -> None: sm = _manager(tmp_path, monkeypatch) - key = "telegram:migrate:lossy" + key = "telegram:legacy:global" new_path = sm._get_session_path(key) - lossy_path = sm._get_legacy_lossy_path(key) - _write_session_file(lossy_path, key, "migrate me") + legacy_path = sm._get_legacy_session_path(key) + _write_session_file(legacy_path, key, "loaded from global") session = sm._load(key) - assert session is not None - assert session.messages[0]["content"] == "migrate me" - assert new_path.exists() - assert not lossy_path.exists() - - -def test_load_does_not_migrate_lossy_path_for_different_stored_key( - tmp_path: Path, - monkeypatch, -) -> None: - sm = _manager(tmp_path, monkeypatch) - first_key = "telegram:a_b" - second_key = "telegram:a:b" - lossy_path = sm._get_legacy_lossy_path(first_key) - assert lossy_path == sm._get_legacy_lossy_path(second_key) - _write_session_file(lossy_path, first_key, "belongs to first") - - loaded_second = sm._load(second_key) - - assert loaded_second is None - assert lossy_path.exists() - assert not sm._get_session_path(second_key).exists() - - loaded_first = sm._load(first_key) - - assert loaded_first is not None - assert loaded_first.messages[0]["content"] == "belongs to first" - assert sm._get_session_path(first_key).exists() - assert not lossy_path.exists() + assert session is None + assert legacy_path.exists() + assert not new_path.exists() def test_safe_key_is_lossy() -> None: diff --git a/tests/channels/test_channel_plugins.py b/tests/channels/test_channel_plugins.py index 93a8b31d..74cc8f21 100644 --- a/tests/channels/test_channel_plugins.py +++ b/tests/channels/test_channel_plugins.py @@ -788,35 +788,6 @@ def test_discover_plugins_skips_names_outside_enabled_set(): assert loaded == [] -def test_discover_plugins_warns_once_for_legacy_entry_points(): - from nanobot.channels.registry import _warn_legacy_channel_entry_points, discover_plugins - - legacy_entry_points = [SimpleNamespace(name="z-old"), SimpleNamespace(name="a-old")] - _warn_legacy_channel_entry_points.cache_clear() - try: - with ( - patch( - "nanobot.channels.registry.entry_points", - return_value=legacy_entry_points, - ) as metadata_entry_points, - patch("nanobot.channels.registry._channel_package_names", return_value=[]), - patch("nanobot.channels.registry.logger.warning") as warning, - ): - discover_plugins() - discover_plugins() - finally: - _warn_legacy_channel_entry_points.cache_clear() - - metadata_entry_points.assert_called_once_with(group="nanobot.channels") - warning.assert_called_once_with( - "Legacy channel entry points were detected but will not be loaded: {}. " - "The '{}' entry-point group is no longer supported; use a built-in channel or " - "migrate it into nanobot/channels//.", - "a-old, z-old", - "nanobot.channels", - ) - - def test_channel_manifest_rejects_invalid_dependency_metadata(): with pytest.raises(TypeError, match="tuple of requirements"): ChannelPlugin( diff --git a/tests/cli/test_commands.py b/tests/cli/test_commands.py index 34c9c674..356ef810 100644 --- a/tests/cli/test_commands.py +++ b/tests/cli/test_commands.py @@ -1728,17 +1728,6 @@ def test_agent_workspace_override_wins_over_config_workspace(mock_agent_runtime, assert passed_config.workspace_path == workspace_path -def test_agent_hints_about_deprecated_memory_window(mock_agent_runtime, tmp_path): - config_file = tmp_path / "config.json" - config_file.write_text(json.dumps({"agents": {"defaults": {"memoryWindow": 42}}})) - - result = runner.invoke(app, ["agent", "-m", "hello", "-c", str(config_file)]) - - assert result.exit_code == 0 - assert "memoryWindow" in result.stdout - assert "no longer used" in result.stdout - - def test_heartbeat_retains_recent_messages_by_default(): config = Config() diff --git a/tests/config/test_config_migration.py b/tests/config/test_config_migration.py index 10ba967a..a07300e8 100644 --- a/tests/config/test_config_migration.py +++ b/tests/config/test_config_migration.py @@ -96,22 +96,17 @@ def test_onboard_does_not_crash_with_legacy_memory_window(tmp_path, monkeypatch) @pytest.mark.parametrize("field_name", ["maxMessages", "max_messages"]) -def test_load_config_warns_and_ignores_legacy_max_messages(tmp_path, field_name) -> None: +def test_load_config_ignores_legacy_max_messages(tmp_path, field_name) -> None: config_path = tmp_path / "config.json" config_path.write_text( json.dumps({"agents": {"defaults": {field_name: 25, "maxTokens": 1234}}}), encoding="utf-8", ) - with patch("nanobot.config.loader.logger.warning") as warning: - config = load_config(config_path) + config = load_config(config_path) assert config.agents.defaults.max_tokens == 1234 assert not hasattr(config.agents.defaults, "max_messages") - warning.assert_called_once() - message = warning.call_args.args[0] - assert "legacy and ignored" in message - assert "next version" in message def test_save_config_drops_legacy_max_messages(tmp_path) -> None: @@ -121,8 +116,7 @@ def test_save_config_drops_legacy_max_messages(tmp_path) -> None: encoding="utf-8", ) - with patch("nanobot.config.loader.logger.warning"): - config = load_config(config_path) + config = load_config(config_path) save_config(config, config_path) saved = json.loads(config_path.read_text(encoding="utf-8")) diff --git a/tests/config/test_dream_config.py b/tests/config/test_dream_config.py index feff587a..a40eb1cc 100644 --- a/tests/config/test_dream_config.py +++ b/tests/config/test_dream_config.py @@ -52,3 +52,22 @@ def test_dream_config_uses_model_override_name_and_accepts_legacy_model() -> Non assert cfg.model_override == "openrouter/sonnet" assert dumped["modelOverride"] == "openrouter/sonnet" assert "model" not in dumped + + +def test_dream_config_ignores_retired_noop_fields() -> None: + cfg = DreamConfig.model_validate( + { + "maxBatchSize": 99, + "maxIterations": 99, + "annotateLineAges": False, + } + ) + + dumped = cfg.model_dump(by_alias=True) + + assert not hasattr(cfg, "max_batch_size") + assert not hasattr(cfg, "max_iterations") + assert not hasattr(cfg, "annotate_line_ages") + assert "maxBatchSize" not in dumped + assert "maxIterations" not in dumped + assert "annotateLineAges" not in dumped diff --git a/tests/session/test_session_list_repair_legacy.py b/tests/session/test_session_list_repair_legacy.py index 0c590f24..6fb37cb6 100644 --- a/tests/session/test_session_list_repair_legacy.py +++ b/tests/session/test_session_list_repair_legacy.py @@ -1,4 +1,5 @@ -"""Regression tests for legacy-stem session handling.""" +"""Tests for retired legacy session storage paths.""" + import json from datetime import datetime from pathlib import Path @@ -6,15 +7,11 @@ from pathlib import Path from nanobot.session.manager import SessionManager -def test_list_sessions_repairs_corrupt_legacy_stem(tmp_path: Path, monkeypatch) -> None: - monkeypatch.setattr( - "nanobot.session.manager.get_legacy_sessions_dir", - lambda: tmp_path / "legacy_sessions", - ) +def test_list_sessions_ignores_legacy_stem(tmp_path: Path) -> None: manager = SessionManager(tmp_path / "workspace") - # Simulate a legacy lossy-path filename (telegram_12345.jsonl) with a corrupt - # first line that triggers the repair branch in list_sessions. + # A legacy lossy-path filename must not be treated as current session storage, + # even when the file contains otherwise recoverable records. legacy_stem = "telegram_12345" corrupt_path = manager.sessions_dir / f"{legacy_stem}.jsonl" corrupt_path.parent.mkdir(parents=True, exist_ok=True) @@ -24,7 +21,6 @@ def test_list_sessions_repairs_corrupt_legacy_stem(tmp_path: Path, monkeypatch) "created_at": datetime(2025, 1, 1).isoformat(), "updated_at": datetime(2025, 1, 1).isoformat(), }) - # Corrupt line followed by valid message corrupt_path.write_text( metadata + "\n{INVALID JSON LINE\n" + json.dumps({"role": "user", "content": "recoverable message"}) + "\n", @@ -33,14 +29,11 @@ def test_list_sessions_repairs_corrupt_legacy_stem(tmp_path: Path, monkeypatch) sessions = manager.list_sessions() - # BUG: repair fails because _repair re-encodes the fallback_key via - # _get_session_path, producing a base64 stem that doesn't match the - # actual legacy filename. The session is silently dropped. - assert len(sessions) == 1, f"Expected 1 session, got {len(sessions)}" - assert sessions[0]["key"] == "telegram:12345" + assert sessions == [] + assert corrupt_path.exists() -def test_read_session_methods_fall_back_to_legacy_lossy_stem( +def test_read_session_methods_ignore_legacy_lossy_stem( tmp_path: Path, monkeypatch, ) -> None: @@ -69,8 +62,5 @@ def test_read_session_methods_fall_back_to_legacy_lossy_stem( metadata_result = manager.read_session_metadata(key) file_result = manager.read_session_file(key) - assert metadata_result is not None - assert metadata_result["metadata"] == metadata["metadata"] - assert file_result is not None - assert file_result["metadata"] == metadata["metadata"] - assert file_result["messages"] == [] + assert metadata_result is None + assert file_result is None diff --git a/tests/webui/test_session_list_index.py b/tests/webui/test_session_list_index.py index 6712c712..2dafd993 100644 --- a/tests/webui/test_session_list_index.py +++ b/tests/webui/test_session_list_index.py @@ -98,6 +98,20 @@ def test_webui_session_list_drops_deleted_index_rows(tmp_path: Path) -> None: assert list_webui_sessions(manager) == [] +def test_webui_session_list_ignores_legacy_stem(tmp_path: Path) -> None: + manager = SessionManager(tmp_path) + legacy_path = manager.sessions_dir / "websocket_legacy.jsonl" + legacy_path.write_text( + '{"_type":"metadata","key":"websocket:legacy",' + '"created_at":"2025-01-01T00:00:00",' + '"updated_at":"2025-01-01T00:00:00","metadata":{}}\n', + encoding="utf-8", + ) + + assert list_webui_sessions(manager) == [] + assert legacy_path.exists() + + def test_webui_session_list_skips_cron_internal_user_preview(tmp_path: Path) -> None: manager = SessionManager(tmp_path) session = manager.get_or_create("websocket:cron-preview") diff --git a/webui/src/tests/app-layout.test.tsx b/webui/src/tests/app-layout.test.tsx index f6a51356..2bf0c775 100644 --- a/webui/src/tests/app-layout.test.tsx +++ b/webui/src/tests/app-layout.test.tsx @@ -115,9 +115,6 @@ function baseSettingsPayload() { }, dream: { schedule: "every 2h", - max_batch_size: 20, - max_iterations: 15, - annotate_line_ages: true, }, unified_session: false, }, diff --git a/webui/src/tests/thread-shell.test.tsx b/webui/src/tests/thread-shell.test.tsx index eed302dd..3c285286 100644 --- a/webui/src/tests/thread-shell.test.tsx +++ b/webui/src/tests/thread-shell.test.tsx @@ -259,9 +259,6 @@ function modelSettings(model: string, provider: string): SettingsPayload { }, dream: { schedule: "every 2h", - max_batch_size: 20, - max_iterations: 15, - annotate_line_ages: true, }, unified_session: false, },