Skip to content

Commit bea0f2a

Browse files
committed
Merge PR #1435: feat(gateway): support multiple instances with --workspace and --config options
2 parents cd0bcc1 + 0343d66 commit bea0f2a

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,33 @@ MCP tools are automatically discovered and registered on startup. The LLM can us
890890
| `channels.*.allowFrom` | `[]` (allow all) | Whitelist of user IDs. Empty = allow everyone; non-empty = only listed users can interact. |
891891

892892

893+
## Multiple Instances
894+
895+
Run multiple nanobot instances simultaneously, each with its own workspace and configuration.
896+
897+
```bash
898+
# Instance A - Telegram bot
899+
nanobot gateway -w ~/.nanobot/botA -p 18791
900+
901+
# Instance B - Discord bot
902+
nanobot gateway -w ~/.nanobot/botB -p 18792
903+
904+
# Instance C - Using custom config file
905+
nanobot gateway -w ~/.nanobot/botC -c ~/.nanobot/botC/config.json -p 18793
906+
```
907+
908+
| Option | Short | Description |
909+
|--------|-------|-------------|
910+
| `--workspace` | `-w` | Workspace directory (default: `~/.nanobot/workspace`) |
911+
| `--config` | `-c` | Config file path (default: `~/.nanobot/config.json`) |
912+
| `--port` | `-p` | Gateway port (default: `18790`) |
913+
914+
Each instance has its own:
915+
- Workspace directory (MEMORY.md, HEARTBEAT.md, session files)
916+
- Cron jobs storage (`workspace/cron/jobs.json`)
917+
- Configuration (if using `--config`)
918+
919+
893920
## CLI Reference
894921

895922
| Command | Description |

nanobot/cli/commands.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,15 @@ def _make_provider(config: Config):
244244
@app.command()
245245
def gateway(
246246
port: int = typer.Option(18790, "--port", "-p", help="Gateway port"),
247+
workspace: str | None = typer.Option(None, "--workspace", "-w", help="Workspace directory"),
248+
config: str | None = typer.Option(None, "--config", "-c", help="Config file path"),
247249
verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
248250
):
249251
"""Start the nanobot gateway."""
250252
from nanobot.agent.loop import AgentLoop
251253
from nanobot.bus.queue import MessageBus
252254
from nanobot.channels.manager import ChannelManager
253-
from nanobot.config.loader import get_data_dir, load_config
255+
from nanobot.config.loader import load_config
254256
from nanobot.cron.service import CronService
255257
from nanobot.cron.types import CronJob
256258
from nanobot.heartbeat.service import HeartbeatService
@@ -260,16 +262,20 @@ def gateway(
260262
import logging
261263
logging.basicConfig(level=logging.DEBUG)
262264

263-
console.print(f"{__logo__} Starting nanobot gateway on port {port}...")
265+
config_path = Path(config) if config else None
266+
config = load_config(config_path)
267+
if workspace:
268+
config.agents.defaults.workspace = workspace
264269

265-
config = load_config()
270+
console.print(f"{__logo__} Starting nanobot gateway on port {port}...")
266271
sync_workspace_templates(config.workspace_path)
267272
bus = MessageBus()
268273
provider = _make_provider(config)
269274
session_manager = SessionManager(config.workspace_path)
270275

271276
# Create cron service first (callback set after agent creation)
272-
cron_store_path = get_data_dir() / "cron" / "jobs.json"
277+
# Use workspace path for per-instance cron store
278+
cron_store_path = config.workspace_path / "cron" / "jobs.json"
273279
cron = CronService(cron_store_path)
274280

275281
# Create agent with cron service

0 commit comments

Comments
 (0)