diff --git a/README.md b/README.md index 1374fb8..fc0a1fb 100644 --- a/README.md +++ b/README.md @@ -890,6 +890,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 b75a2bc..b097059 100644 --- a/nanobot/cli/commands.py +++ b/nanobot/cli/commands.py @@ -244,13 +244,15 @@ 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"), + 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.""" 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 @@ -260,16 +262,20 @@ def gateway( import logging logging.basicConfig(level=logging.DEBUG) - console.print(f"{__logo__} Starting nanobot gateway on port {port}...") + config_path = Path(config) if config else None + config = load_config(config_path) + if workspace: + config.agents.defaults.workspace = workspace - config = load_config() + console.print(f"{__logo__} Starting nanobot gateway on port {port}...") sync_workspace_templates(config.workspace_path) bus = MessageBus() provider = _make_provider(config) 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