- Add nanobot/utils/evaluator.py: lightweight LLM tool-call to decide notify/silent after background task execution
- Remove magic token injection from heartbeat and cron prompts
- Clean session history (no more <SILENT_OK> pollution)
- Add tests for evaluator and updated heartbeat three-phase flow
Appends a strict instruction to background task prompts (cron and heartbeat)
directing the agent to return a `<SILENT_OK>` token if there is nothing
material to report. Adds conditional logic to intercept this token and
suppress the outbound message to the user, preventing notification spam
from autonomous background checks.
Replace platform-specific shell=True logic with shutil.which('npm') to
resolve the full path to the npm executable. This is cleaner because:
- No shell=True needed (safer, no shell injection risk)
- No platform-specific branching (sys.platform checks removed)
- Works identically on Windows, macOS, and Linux
- shutil.which() resolves npm.cmd on Windows automatically
The npm path check that already existed in _get_bridge_dir() is now
reused as the resolved path for subprocess calls. The same pattern is
applied to channels_login().
On Windows, npm is installed as npm.cmd (a batch script), not a direct
executable. When subprocess.run() is called with a list like
['npm', 'install'] without shell=True, Python's CreateProcess cannot
locate npm.cmd, resulting in:
FileNotFoundError: [WinError 2] The system cannot find the file specified
This fix adds a sys.platform == 'win32' check before each npm subprocess
call. On Windows, it uses shell=True with a string command so the shell
can resolve npm.cmd. On other platforms, the original list-based call is
preserved unchanged.
Affected locations:
- _get_bridge_dir(): npm install, npm run build
- channels_login(): npm start
No behavioral change on Linux/macOS.
Add native Ollama support so local models (e.g. nemotron-3-nano) can be
used without an API key. Adds ProviderSpec with ollama_chat LiteLLM
prefix, ProvidersConfig field, and skips API key validation for local
providers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move consolidation policy into MemoryConsolidator, keep backward compatibility for legacy config, and compress history by token budget instead of message count.
SIGHUP and SIGPIPE are not available on Windows. Add hasattr() checks
before registering these signal handlers to prevent AttributeError on
Windows systems.
Fixes compatibility issue introduced in PR #1400.
Add support for running multiple nanobot instances with complete isolation:
- Add --config parameter to gateway command for custom config file path
- Implement set_config_path() in config/loader.py for dynamic config path
- Derive data directory from config file location (e.g., ~/.nanobot-xxx/)
- Update get_data_path() to use unified data directory from config loader
- Ensure cron jobs use instance-specific data directory
This enables running multiple isolated nanobot instances by specifying
different config files, with each instance maintaining separate:
- Configuration files
- Workspace (memory, sessions, skills)
- Cron jobs
- Logs and media
Example usage:
nanobot gateway --config ~/.nanobot-instance2/config.json --port 18791
When a cron job fires, the agent processes the scheduled message and
has access to the cron tool. If the original message resembles a
scheduling instruction (e.g. "remind me in 10 seconds"), the agent
would call cron.add again, creating an infinite feedback loop.
Add a cron-context flag to CronTool that blocks add operations during
cron job execution. The flag is set before process_direct() and cleared
in a finally block to ensure cleanup even on errors.
Fixes#1441
- Add --workspace/-w flag to specify workspace directory
- Add --config/-c flag to specify config file path
- Move cron store to workspace directory for per-instance isolation
- Enable running multiple nanobot instances simultaneously
- Add handler for SIGTERM to prevent "Terminated" message on Linux
- Add handler for SIGHUP for terminal closure handling
- Ignore SIGPIPE to prevent silent process termination
- Change os._exit(0) to sys.exit(0) for proper cleanup
Fixes issue #1365
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Improve cron job execution context to ensure proper message delivery and
session history recording.
Changes:
- Add [绯荤粺瀹氭椂浠诲姟] prefix to cron reminder messages to clearly mark
them as system-driven, not user queries
- Use user role for cron reminder messages (required by some LLM APIs)
- Properly handle MessageTool to avoid duplicate message delivery
- Correctly save turn history with proper skip count
- Ensure Runtime Context is included in the message list
This ensures that:
1. Cron jobs execute with proper context
2. Messages are correctly delivered to users
3. Session history accurately records cron job interactions
4. The LLM understands these are system-driven reminders, not user queries
- Remove trailing whitespace and normalize blank lines
- Unify string quotes and line breaks for long lines
- Sort imports alphabetically across modules