From 8f4baaa5ce750fc073921fa29e734a0fe0da2056 Mon Sep 17 00:00:00 2001 From: chengyongru <2755839590@qq.com> Date: Mon, 2 Mar 2026 22:01:02 +0800 Subject: [PATCH 1/2] feat(gateway): support multiple instances with --workspace and --config options - 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 --- README.md | 27 +++++++++++++++++++++++++++ nanobot/cli/commands.py | 13 ++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 01da228..3022708 100644 --- a/README.md +++ b/README.md @@ -884,6 +884,33 @@ MCP tools are automatically discovered and registered on startup. The LLM can us | `channels.*.allowFrom` | `[]` (allow all) | Whitelist of user IDs. Empty = allow everyone; non-empty = only listed users can interact. | +## Multiple Instances + +Run multiple nanobot instances simultaneously, each with its own workspace and configuration. + +```bash +# Instance A - Telegram bot +nanobot gateway -w ~/.nanobot/botA -p 18791 + +# Instance B - Discord bot +nanobot gateway -w ~/.nanobot/botB -p 18792 + +# Instance C - Using custom config file +nanobot gateway -w ~/.nanobot/botC -c ~/.nanobot/botC/config.json -p 18793 +``` + +| Option | Short | Description | +|--------|-------|-------------| +| `--workspace` | `-w` | Workspace directory (default: `~/.nanobot/workspace`) | +| `--config` | `-c` | Config file path (default: `~/.nanobot/config.json`) | +| `--port` | `-p` | Gateway port (default: `18790`) | + +Each instance has its own: +- Workspace directory (MEMORY.md, HEARTBEAT.md, session files) +- Cron jobs storage (`workspace/cron/jobs.json`) +- Configuration (if using `--config`) + + ## CLI Reference | Command | Description | diff --git a/nanobot/cli/commands.py b/nanobot/cli/commands.py index 2662e9f..e599b11 100644 --- a/nanobot/cli/commands.py +++ b/nanobot/cli/commands.py @@ -244,6 +244,8 @@ def _make_provider(config: Config): @app.command() def gateway( port: int = typer.Option(18790, "--port", "-p", help="Gateway port"), + workspace: str | None = typer.Option(None, "--workspace", "-w", help="Workspace directory (default: ~/.nanobot/workspace)"), + config: str | None = typer.Option(None, "--config", "-c", help="Config file path"), verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"), ): """Start the nanobot gateway.""" @@ -260,6 +262,14 @@ def gateway( import logging logging.basicConfig(level=logging.DEBUG) + # Load config from custom path if provided, otherwise use default + config_path = Path(config) if config else None + config = load_config(config_path) + + # Override workspace if specified via command line + if workspace: + config.agents.defaults.workspace = workspace + console.print(f"{__logo__} Starting nanobot gateway on port {port}...") config = load_config() @@ -269,7 +279,8 @@ def gateway( session_manager = SessionManager(config.workspace_path) # Create cron service first (callback set after agent creation) - cron_store_path = get_data_dir() / "cron" / "jobs.json" + # Use workspace path for per-instance cron store + cron_store_path = config.workspace_path / "cron" / "jobs.json" cron = CronService(cron_store_path) # Create agent with cron service From 0343d66224007d6d7964984db7741ae710c81167 Mon Sep 17 00:00:00 2001 From: Re-bin Date: Thu, 5 Mar 2026 14:54:53 +0000 Subject: [PATCH 2/2] fix(gateway): remove duplicate load_config() that overwrote custom workspace/config --- nanobot/cli/commands.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/nanobot/cli/commands.py b/nanobot/cli/commands.py index 05e2cbe..b097059 100644 --- a/nanobot/cli/commands.py +++ b/nanobot/cli/commands.py @@ -244,7 +244,7 @@ def _make_provider(config: Config): @app.command() def gateway( port: int = typer.Option(18790, "--port", "-p", help="Gateway port"), - workspace: str | None = typer.Option(None, "--workspace", "-w", help="Workspace directory (default: ~/.nanobot/workspace)"), + workspace: str | None = typer.Option(None, "--workspace", "-w", help="Workspace directory"), config: str | None = typer.Option(None, "--config", "-c", help="Config file path"), verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"), ): @@ -252,7 +252,7 @@ def gateway( from nanobot.agent.loop import AgentLoop from nanobot.bus.queue import MessageBus from nanobot.channels.manager import ChannelManager - from nanobot.config.loader import get_data_dir, load_config + from nanobot.config.loader import load_config from nanobot.cron.service import CronService from nanobot.cron.types import CronJob from nanobot.heartbeat.service import HeartbeatService @@ -262,17 +262,12 @@ def gateway( import logging logging.basicConfig(level=logging.DEBUG) - # Load config from custom path if provided, otherwise use default config_path = Path(config) if config else None config = load_config(config_path) - - # Override workspace if specified via command line if workspace: config.agents.defaults.workspace = workspace console.print(f"{__logo__} Starting nanobot gateway on port {port}...") - - config = load_config() sync_workspace_templates(config.workspace_path) bus = MessageBus() provider = _make_provider(config)