refactor: remove deprecated memory_window, harden wizard display
This commit is contained in:
@@ -322,9 +322,6 @@ def onboard(
|
||||
console.print(f"[red]✗[/red] Error during configuration: {e}")
|
||||
console.print("[yellow]Please run 'nanobot onboard' again to complete setup.[/yellow]")
|
||||
raise typer.Exit(1)
|
||||
else:
|
||||
console.print("[dim]Config template now uses `maxTokens` + `contextWindowTokens`; `memoryWindow` is no longer a runtime setting.[/dim]")
|
||||
|
||||
_onboard_plugins(config_path)
|
||||
|
||||
# Create workspace, preferring the configured workspace path.
|
||||
@@ -464,21 +461,30 @@ def _load_runtime_config(config: str | None = None, workspace: str | None = None
|
||||
console.print(f"[dim]Using config: {config_path}[/dim]")
|
||||
|
||||
loaded = load_config(config_path)
|
||||
_warn_deprecated_config_keys(config_path)
|
||||
if workspace:
|
||||
loaded.agents.defaults.workspace = workspace
|
||||
return loaded
|
||||
|
||||
|
||||
def _print_deprecated_memory_window_notice(config: Config) -> None:
|
||||
"""Warn when running with old memoryWindow-only config."""
|
||||
if config.agents.defaults.should_warn_deprecated_memory_window:
|
||||
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(
|
||||
"[yellow]Hint:[/yellow] Detected deprecated `memoryWindow` without "
|
||||
"`contextWindowTokens`. `memoryWindow` is ignored; run "
|
||||
"[cyan]nanobot onboard[/cyan] to refresh your config template."
|
||||
"[dim]Hint: `memoryWindow` in your config is no longer used "
|
||||
"and can be safely removed.[/dim]"
|
||||
)
|
||||
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Gateway / Server
|
||||
# ============================================================================
|
||||
@@ -506,7 +512,6 @@ def gateway(
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
config = _load_runtime_config(config, workspace)
|
||||
_print_deprecated_memory_window_notice(config)
|
||||
port = port if port is not None else config.gateway.port
|
||||
|
||||
console.print(f"{__logo__} Starting nanobot gateway version {__version__} on port {port}...")
|
||||
@@ -697,7 +702,6 @@ def agent(
|
||||
from nanobot.cron.service import CronService
|
||||
|
||||
config = _load_runtime_config(config, workspace)
|
||||
_print_deprecated_memory_window_notice(config)
|
||||
sync_workspace_templates(config.workspace_path)
|
||||
|
||||
bus = MessageBus()
|
||||
|
||||
@@ -247,12 +247,20 @@ def _mask_value(value: str) -> str:
|
||||
|
||||
|
||||
def _format_value(value: Any, rich: bool = True, field_name: str = "") -> str:
|
||||
"""Format a value for display, masking sensitive fields."""
|
||||
"""Single recursive entry point for safe value display. Handles any depth."""
|
||||
if value is None or value == "" or value == {} or value == []:
|
||||
return "[dim]not set[/dim]" if rich else "[not set]"
|
||||
if field_name and _is_sensitive_field(field_name) and isinstance(value, str):
|
||||
if _is_sensitive_field(field_name) and isinstance(value, str):
|
||||
masked = _mask_value(value)
|
||||
return f"[dim]{masked}[/dim]" if rich else masked
|
||||
if isinstance(value, BaseModel):
|
||||
parts = []
|
||||
for fname, _finfo in type(value).model_fields.items():
|
||||
fval = getattr(value, fname, None)
|
||||
formatted = _format_value(fval, rich=False, field_name=fname)
|
||||
if formatted != "[not set]":
|
||||
parts.append(f"{fname}={formatted}")
|
||||
return ", ".join(parts) if parts else ("[dim]not set[/dim]" if rich else "[not set]")
|
||||
if isinstance(value, list):
|
||||
return ", ".join(str(v) for v in value)
|
||||
if isinstance(value, dict):
|
||||
@@ -543,6 +551,7 @@ def _configure_pydantic_model(
|
||||
return items + ["[Done]"]
|
||||
|
||||
while True:
|
||||
console.clear()
|
||||
_show_config_panel(display_name, working_model, fields)
|
||||
choices = get_choices()
|
||||
answer = _select_with_back("Select field to configure:", choices)
|
||||
@@ -688,7 +697,6 @@ def _configure_provider(config: Config, provider_name: str) -> None:
|
||||
|
||||
def _configure_providers(config: Config) -> None:
|
||||
"""Configure LLM providers."""
|
||||
_show_section_header("LLM Providers", "Select a provider to configure API key and endpoint")
|
||||
|
||||
def get_provider_choices() -> list[str]:
|
||||
"""Build provider choices with config status indicators."""
|
||||
@@ -703,6 +711,8 @@ def _configure_providers(config: Config) -> None:
|
||||
|
||||
while True:
|
||||
try:
|
||||
console.clear()
|
||||
_show_section_header("LLM Providers", "Select a provider to configure API key and endpoint")
|
||||
choices = get_provider_choices()
|
||||
answer = _select_with_back("Select provider:", choices)
|
||||
|
||||
@@ -738,18 +748,9 @@ def _get_channel_info() -> dict[str, tuple[str, type[BaseModel]]]:
|
||||
for name, channel_cls in discover_all().items():
|
||||
try:
|
||||
mod = importlib.import_module(f"nanobot.channels.{name}")
|
||||
config_cls = next(
|
||||
(
|
||||
attr
|
||||
for attr in vars(mod).values()
|
||||
if isinstance(attr, type)
|
||||
and issubclass(attr, BaseModel)
|
||||
and attr is not BaseModel
|
||||
and attr.__name__.endswith("Config")
|
||||
),
|
||||
None,
|
||||
)
|
||||
if config_cls:
|
||||
config_name = channel_cls.__name__.replace("Channel", "Config")
|
||||
config_cls = getattr(mod, config_name, None)
|
||||
if config_cls and isinstance(config_cls, type) and issubclass(config_cls, BaseModel):
|
||||
display_name = getattr(channel_cls, "display_name", name.capitalize())
|
||||
result[name] = (display_name, config_cls)
|
||||
except Exception:
|
||||
@@ -795,13 +796,13 @@ def _configure_channel(config: Config, channel_name: str) -> None:
|
||||
|
||||
def _configure_channels(config: Config) -> None:
|
||||
"""Configure chat channels."""
|
||||
_show_section_header("Chat Channels", "Select a channel to configure connection settings")
|
||||
|
||||
channel_names = list(_get_channel_names().keys())
|
||||
choices = channel_names + ["<- Back"]
|
||||
|
||||
while True:
|
||||
try:
|
||||
console.clear()
|
||||
_show_section_header("Chat Channels", "Select a channel to configure connection settings")
|
||||
answer = _select_with_back("Select channel:", choices)
|
||||
|
||||
if answer is _BACK_PRESSED or answer is None or answer == "<- Back":
|
||||
@@ -842,8 +843,6 @@ def _configure_general_settings(config: Config, section: str) -> None:
|
||||
if not meta:
|
||||
return
|
||||
display_name, subtitle, skip = meta
|
||||
_show_section_header(section, subtitle)
|
||||
|
||||
model = _SETTINGS_GETTER[section](config)
|
||||
updated = _configure_pydantic_model(model, display_name, skip_fields=skip)
|
||||
if updated is not None:
|
||||
@@ -975,6 +974,7 @@ def run_onboard(initial_config: Config | None = None) -> OnboardResult:
|
||||
config = base_config.model_copy(deep=True)
|
||||
|
||||
while True:
|
||||
console.clear()
|
||||
_show_main_menu_header()
|
||||
|
||||
try:
|
||||
|
||||
@@ -38,14 +38,7 @@ class AgentDefaults(Base):
|
||||
context_window_tokens: int = 65_536
|
||||
temperature: float = 0.1
|
||||
max_tool_iterations: int = 40
|
||||
# Deprecated compatibility field: accepted from old configs but ignored at runtime.
|
||||
memory_window: int | None = Field(default=None, exclude=True)
|
||||
reasoning_effort: str | None = None # low / medium / high — enables LLM thinking mode
|
||||
|
||||
@property
|
||||
def should_warn_deprecated_memory_window(self) -> bool:
|
||||
"""Return True when old memoryWindow is present without contextWindowTokens."""
|
||||
return self.memory_window is not None and "context_window_tokens" not in self.model_fields_set
|
||||
reasoning_effort: str | None = None # low / medium / high - enables LLM thinking mode
|
||||
|
||||
|
||||
class AgentsConfig(Base):
|
||||
|
||||
Reference in New Issue
Block a user