fix: preserve cron reminder context for notifications

This commit is contained in:
MrBob
2026-03-24 15:56:23 -03:00
parent 7b31af2204
commit b26a93c14a
3 changed files with 148 additions and 21 deletions
+29 -11
View File
@@ -1,12 +1,11 @@
"""CLI commands for nanobot."""
import asyncio
from contextlib import contextmanager, nullcontext
import os
import select
import signal
import sys
from contextlib import nullcontext
from pathlib import Path
from typing import Any
@@ -67,6 +66,7 @@ def _flush_pending_tty_input() -> None:
try:
import termios
termios.tcflush(fd, termios.TCIFLUSH)
return
except Exception:
@@ -89,6 +89,7 @@ def _restore_terminal() -> None:
return
try:
import termios
termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, _SAVED_TERM_ATTRS)
except Exception:
pass
@@ -101,6 +102,7 @@ def _init_prompt_session() -> None:
# Save terminal state so we can restore it on exit
try:
import termios
_SAVED_TERM_ATTRS = termios.tcgetattr(sys.stdin.fileno())
except Exception:
pass
@@ -113,7 +115,7 @@ def _init_prompt_session() -> None:
_PROMPT_SESSION = PromptSession(
history=FileHistory(str(history_file)),
enable_open_in_editor=False,
multiline=False, # Enter submits (single line mode)
multiline=False, # Enter submits (single line mode)
)
@@ -225,7 +227,6 @@ async def _read_interactive_input_async() -> str:
raise KeyboardInterrupt from exc
def version_callback(value: bool):
if value:
console.print(f"{__logo__} nanobot v{__version__}")
@@ -275,8 +276,12 @@ def onboard(
config = _apply_workspace_override(load_config(config_path))
else:
console.print(f"[yellow]Config already exists at {config_path}[/yellow]")
console.print(" [bold]y[/bold] = overwrite with defaults (existing values will be lost)")
console.print(" [bold]N[/bold] = refresh config, keeping existing values and adding new fields")
console.print(
" [bold]y[/bold] = overwrite with defaults (existing values will be lost)"
)
console.print(
" [bold]N[/bold] = refresh config, keeping existing values and adding new fields"
)
if typer.confirm("Overwrite?"):
config = _apply_workspace_override(Config())
save_config(config, config_path)
@@ -284,7 +289,9 @@ def onboard(
else:
config = _apply_workspace_override(load_config(config_path))
save_config(config, config_path)
console.print(f"[green]✓[/green] Config refreshed at {config_path} (existing values preserved)")
console.print(
f"[green]✓[/green] Config refreshed at {config_path} (existing values preserved)"
)
else:
config = _apply_workspace_override(Config())
# In wizard mode, don't save yet - the wizard will handle saving if should_save=True
@@ -334,7 +341,9 @@ def onboard(
console.print(f" 1. Add your API key to [cyan]{config_path}[/cyan]")
console.print(" Get one at: https://openrouter.ai/keys")
console.print(f" 2. Chat: [cyan]{agent_cmd}[/cyan]")
console.print("\n[dim]Want Telegram/WhatsApp? See: https://github.com/HKUDS/nanobot#-chat-apps[/dim]")
console.print(
"\n[dim]Want Telegram/WhatsApp? See: https://github.com/HKUDS/nanobot#-chat-apps[/dim]"
)
def _merge_missing_defaults(existing: Any, defaults: Any) -> Any:
@@ -407,9 +416,11 @@ def _make_provider(config: Config):
# --- instantiation by backend ---
if backend == "openai_codex":
from nanobot.providers.openai_codex_provider import OpenAICodexProvider
provider = OpenAICodexProvider(default_model=model)
elif backend == "azure_openai":
from nanobot.providers.azure_openai_provider import AzureOpenAIProvider
provider = AzureOpenAIProvider(
api_key=p.api_key,
api_base=p.api_base,
@@ -417,6 +428,7 @@ def _make_provider(config: Config):
)
elif backend == "anthropic":
from nanobot.providers.anthropic_provider import AnthropicProvider
provider = AnthropicProvider(
api_key=p.api_key if p else None,
api_base=config.get_api_base(model),
@@ -425,6 +437,7 @@ def _make_provider(config: Config):
)
else:
from nanobot.providers.openai_compat_provider import OpenAICompatProvider
provider = OpenAICompatProvider(
api_key=p.api_key if p else None,
api_base=config.get_api_base(model),
@@ -465,6 +478,7 @@ def _load_runtime_config(config: str | None = None, workspace: str | None = None
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()
@@ -488,6 +502,7 @@ def _migrate_cron_store(config: "Config") -> None:
if legacy_path.is_file() and not new_path.exists():
new_path.parent.mkdir(parents=True, exist_ok=True)
import shutil
shutil.move(str(legacy_path), str(new_path))
@@ -514,6 +529,7 @@ def gateway(
if verbose:
import logging
logging.basicConfig(level=logging.DEBUG)
config = _load_runtime_config(config, workspace)
@@ -587,7 +603,7 @@ def gateway(
if job.payload.deliver and job.payload.to and response:
should_notify = await evaluate_response(
response, job.payload.message, provider, agent.model,
response, reminder_note, provider, agent.model,
)
if should_notify:
from nanobot.bus.events import OutboundMessage
@@ -597,6 +613,7 @@ def gateway(
content=response,
))
return response
cron.on_job = on_cron_job
# Create channel manager
@@ -684,6 +701,7 @@ def gateway(
console.print("\nShutting down...")
except Exception:
import traceback
console.print("\n[red]Error: Gateway crashed unexpectedly[/red]")
console.print(traceback.format_exc())
finally:
@@ -696,8 +714,6 @@ def gateway(
asyncio.run(run())
# ============================================================================
# Agent Commands
# ============================================================================
@@ -1149,6 +1165,7 @@ def _register_login(name: str):
def decorator(fn):
_LOGIN_HANDLERS[name] = fn
return fn
return decorator
@@ -1179,6 +1196,7 @@ def provider_login(
def _login_openai_codex() -> None:
try:
from oauth_cli_kit import get_token, login_oauth_interactive
token = None
try:
token = get_token()