diff --git a/README.md b/README.md index 70ca70157..4da25759b 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,41 @@ moltbot onboard --install-daemon The wizard installs the Gateway daemon (launchd/systemd user service) so it stays running. Legacy note: `clawdbot` remains available as a compatibility shim. +```mermaid +graph LR + subgraph Channels [Messaging Channels] + WA[WhatsApp] + TG[Telegram] + SL[Slack] + DC[Discord] + SIG[Signal] + IM[iMessage] + WC[WebChat] + MORE[+ more] + end + + GW[Gateway\nWebSocket + HTTP\nControl Plane] + + subgraph Agent [AI Agent] + RT[Runtime\npi-agent-core] + SK[Skills] + MEM[Memory] + end + + subgraph Tools [Agent Tools] + EXEC[Shell / FS] + BR[Browser] + MSG[Messaging] + CRON[Cron / Automation] + end + + Channels -->|inbound| GW + GW -->|route + queue| Agent + Agent -->|tool calls| Tools + Agent -->|reply| GW + GW -->|outbound| Channels +``` + ## Quick start (TL;DR) Runtime: **Node ≥22**. diff --git a/docs/automation/cron-jobs.md b/docs/automation/cron-jobs.md index b117ba827..4924fb7c1 100644 --- a/docs/automation/cron-jobs.md +++ b/docs/automation/cron-jobs.md @@ -15,6 +15,27 @@ the right time, and can optionally deliver output back to a chat. If you want *“run this every morning”* or *“poke the agent in 20 minutes”*, cron is the mechanism. +```mermaid +flowchart TD + subgraph MainSession [Main Session Job] + MS1[Schedule Triggers] --> MS2[Enqueue System Event] + MS2 --> MS3{Wake Mode?} + MS3 -->|next-heartbeat| MS4[Wait for Next Heartbeat] + MS3 -->|now| MS5[Immediate Heartbeat] + MS4 --> MS6[Run in Main Session Context] + MS5 --> MS6 + end + + subgraph IsolatedSession [Isolated Session Job] + IS1[Schedule Triggers] --> IS2[Create Fresh Session\ncron:jobId] + IS2 --> IS3[Run Dedicated Agent Turn] + IS3 --> IS4[Post Summary to Main] + IS4 --> IS5{Deliver?} + IS5 -->|Yes| IS6[Send to Channel Target] + IS5 -->|No| IS7[Internal Only] + end +``` + ## TL;DR - Cron runs **inside the Gateway** (not inside the model). - Jobs persist under `~/.clawdbot/cron/` so restarts don’t lose schedules. diff --git a/docs/automation/webhook.md b/docs/automation/webhook.md index 81565bd41..5ed883976 100644 --- a/docs/automation/webhook.md +++ b/docs/automation/webhook.md @@ -9,6 +9,35 @@ read_when: Gateway can expose a small HTTP webhook endpoint for external triggers. +```mermaid +sequenceDiagram + participant EXT as External System + participant WH as Gateway /hooks + participant AUTH as Auth Check + participant GW as Gateway Core + + EXT->>WH: POST /hooks/wake or /hooks/agent + WH->>AUTH: Verify token (Bearer / header / query) + alt Token valid + AUTH->>WH: OK + alt /hooks/wake + WH->>GW: Enqueue system event + GW->>GW: Trigger heartbeat (if mode=now) + WH-->>EXT: 200 OK + else /hooks/agent + WH->>GW: Start isolated agent run + GW->>GW: Post summary to main session + GW->>GW: Deliver to channel (if configured) + WH-->>EXT: 202 Accepted + else /hooks/ (mapped) + WH->>GW: Resolve mapping → wake or agent + WH-->>EXT: 200/202 + end + else Token invalid + AUTH-->>EXT: 401 Unauthorized + end +``` + ## Enable ```json5 diff --git a/docs/broadcast-groups.md b/docs/broadcast-groups.md index d5e6b3ea0..91ba86c01 100644 --- a/docs/broadcast-groups.md +++ b/docs/broadcast-groups.md @@ -17,6 +17,25 @@ Broadcast Groups enable multiple agents to process and respond to the same messa Current scope: **WhatsApp only** (web channel). +```mermaid +flowchart TD + MSG[Incoming Message] --> ALLOW{Channel Allowlist\n+ Group Activation?} + ALLOW -->|Blocked| DROP[Ignored] + ALLOW -->|Allowed| BC{Peer in\nBroadcast Config?} + BC -->|No| NORMAL[Normal Routing\nSingle agent via bindings] + BC -->|Yes| AGENTS[Get Agent List\nfor this peer] + AGENTS --> STRAT{Strategy?} + STRAT -->|parallel| PAR[Run All Agents\nSimultaneously] + STRAT -->|sequential| SEQ[Run Agents\nIn Order] + PAR --> ISO1[Agent A\nIsolated Session] + PAR --> ISO2[Agent B\nIsolated Session] + PAR --> ISO3[Agent C\nIsolated Session] + SEQ --> ISO1 + ISO1 --> |done| ISO2 + ISO2 --> |done| ISO3 + ISO1 & ISO2 & ISO3 --> DELIVER[Deliver Replies\nto Same Chat] +``` + Broadcast groups are evaluated after channel allowlists and group activation rules. In WhatsApp groups, this means broadcasts happen when Moltbot would normally reply (for example: on mention, depending on your group settings). ## Use Cases diff --git a/docs/concepts/agent-loop.md b/docs/concepts/agent-loop.md index 65572e4ed..70871cc50 100644 --- a/docs/concepts/agent-loop.md +++ b/docs/concepts/agent-loop.md @@ -13,6 +13,22 @@ In Moltbot, a loop is a single, serialized run per session that emits lifecycle as the model thinks, calls tools, and streams output. This doc explains how that authentic loop is wired end-to-end. +```mermaid +stateDiagram-v2 + [*] --> Intake: Inbound message / RPC + Intake --> ContextAssembly: Resolve session + workspace + ContextAssembly --> PromptBuild: Load skills, bootstrap files + PromptBuild --> ModelInference: System prompt + history + ModelInference --> ToolExecution: Tool calls returned + ToolExecution --> ModelInference: Tool results fed back + ModelInference --> Streaming: Assistant text deltas + Streaming --> Persistence: Final reply assembled + Persistence --> [*]: Session updated + reply delivered + + ModelInference --> Compaction: Context limit hit + Compaction --> ModelInference: Retry with compacted context +``` + ## Entry points - Gateway RPC: `agent` and `agent.wait`. - CLI: `agent` command. @@ -80,6 +96,41 @@ These run inside the agent loop or gateway pipeline: See [Plugins](/plugin#plugin-hooks) for the hook API and registration details. +```mermaid +sequenceDiagram + participant GW as Gateway + participant HOOK as Plugin Hooks + participant AGENT as Agent Runtime + participant MODEL as Model API + participant TOOL as Tool Execution + + GW->>HOOK: gateway_start + Note over GW: Gateway initializes + + GW->>HOOK: message_received + GW->>HOOK: session_start + GW->>HOOK: before_agent_start + GW->>AGENT: Start agent run + AGENT->>MODEL: Send prompt + context + + loop Tool Loop + MODEL->>AGENT: Tool call request + AGENT->>HOOK: before_tool_call + AGENT->>TOOL: Execute tool + TOOL->>AGENT: Tool result + AGENT->>HOOK: after_tool_call + AGENT->>HOOK: tool_result_persist + AGENT->>MODEL: Feed result back + end + + MODEL->>AGENT: Final assistant reply + AGENT->>HOOK: agent_end + GW->>HOOK: message_sending + Note over GW: Deliver reply + GW->>HOOK: message_sent + GW->>HOOK: session_end +``` + ## Streaming + partial replies - Assistant deltas are streamed from pi-agent-core and emitted as `assistant` events. - Block streaming can emit partial replies either on `text_end` or `message_end`. diff --git a/docs/concepts/agent-workspace.md b/docs/concepts/agent-workspace.md index ace2ad4eb..471cc04d3 100644 --- a/docs/concepts/agent-workspace.md +++ b/docs/concepts/agent-workspace.md @@ -9,6 +9,41 @@ read_when: The workspace is the agent's home. It is the only working directory used for file tools and for workspace context. Keep it private and treat it as memory. +```mermaid +graph TD + subgraph Workspace ["Agent Workspace (~/clawd)"] + AGENTS[AGENTS.md\nOperating instructions] + SOUL[SOUL.md\nPersona + tone] + USER[USER.md\nUser profile] + IDENTITY[IDENTITY.md\nAgent name + emoji] + TOOLS[TOOLS.md\nTool notes] + HEARTBEAT[HEARTBEAT.md\nHeartbeat checklist] + BOOT[BOOT.md\nStartup checklist] + BOOTSTRAP[BOOTSTRAP.md\nFirst-run ritual] + + subgraph MemoryDir [memory/] + DAILY[YYYY-MM-DD.md\nDaily logs] + end + + MEMORY_MD[MEMORY.md\nLong-term memory] + + subgraph SkillsDir [skills/] + SKILL[Custom skills] + end + + subgraph CanvasDir [canvas/] + CANVAS_HTML[index.html\nCanvas UI] + end + end + + subgraph StateDir ["State Directory (~/.clawdbot)"] + CONFIG[moltbot.json\nConfiguration] + CREDS[credentials/\nOAuth, API keys] + SESSIONS[agents/agentId/sessions/\nTranscripts + metadata] + MANAGED_SKILLS[skills/\nManaged skills] + end +``` + This is separate from `~/.clawdbot/`, which stores config, credentials, and sessions. diff --git a/docs/concepts/architecture.md b/docs/concepts/architecture.md index e31becb34..37d3583e2 100644 --- a/docs/concepts/architecture.md +++ b/docs/concepts/architecture.md @@ -21,6 +21,45 @@ Last updated: 2026-01-22 ## Components and flows +```mermaid +graph TD + subgraph Channels + WA[WhatsApp/Baileys] + TG[Telegram/grammY] + SL[Slack] + DC[Discord] + SIG[Signal] + IM[iMessage] + WC[WebChat] + end + + subgraph Clients + CLI[CLI] + MAC[macOS App] + WEB[Web UI] + AUTO[Automations] + end + + subgraph Nodes + MACOS_N[macOS Node] + IOS_N[iOS Node] + AND_N[Android Node] + HEAD_N[Headless Node] + end + + GW[Gateway\nWebSocket Server\n127.0.0.1:18789] + + WA & TG & SL & DC & SIG & IM & WC --> GW + CLI & MAC & WEB & AUTO -->|WS: role=operator| GW + MACOS_N & IOS_N & AND_N & HEAD_N -->|WS: role=node| GW + + GW --> AGENT[Agent Runtime\npi-agent-core] + AGENT --> TOOLS[Tools\nbrowser, exec, canvas,\nmessage, cron, nodes] + + CANVAS[Canvas Host\n:18793] + GW -.-> CANVAS +``` + ### Gateway (daemon) - Maintains provider connections. - Exposes a typed WS API (requests, responses, server‑push events). diff --git a/docs/concepts/channel-routing.md b/docs/concepts/channel-routing.md index a6ecf9465..62ad8af6c 100644 --- a/docs/concepts/channel-routing.md +++ b/docs/concepts/channel-routing.md @@ -51,6 +51,23 @@ Routing picks **one agent** for each inbound message: The matched agent determines which workspace and session store are used. +```mermaid +flowchart TD + MSG[Inbound Message] --> P1{Exact Peer Match?} + P1 -->|Yes| FOUND[Agent Found] + P1 -->|No| P2{Guild Match?\nDiscord guildId} + P2 -->|Yes| FOUND + P2 -->|No| P3{Team Match?\nSlack teamId} + P3 -->|Yes| FOUND + P3 -->|No| P4{Account Match?\naccountId} + P4 -->|Yes| FOUND + P4 -->|No| P5{Channel Match?\nany account} + P5 -->|Yes| FOUND + P5 -->|No| P6[Default Agent\nagents.list default\nor first entry\nor 'main'] + P6 --> FOUND + FOUND --> WS[Workspace + Session Store] +``` + ## Broadcast groups (run multiple agents) Broadcast groups let you run **multiple agents** for the same peer **when Moltbot would normally reply** (for example: in WhatsApp groups, after mention/activation gating). @@ -69,6 +86,19 @@ Config: See: [Broadcast Groups](/broadcast-groups). +```mermaid +flowchart TD + MSG[Inbound Message\nfrom peer] --> BC{Peer in\nBroadcast Config?} + BC -->|Yes| MULTI[Broadcast:\nAll listed agents process\nisolated sessions each] + BC -->|No| BIND{Peer in\nBindings?} + BIND -->|Yes| SINGLE[Normal Routing:\nOne matched agent] + BIND -->|No| DEFAULT[Default Agent\nfallback routing] + + MULTI --> REPLY_M[Multiple Replies\nfrom each agent] + SINGLE --> REPLY_S[Single Reply] + DEFAULT --> REPLY_S +``` + ## Config overview - `agents.list`: named agent definitions (workspace, model, etc.). diff --git a/docs/concepts/compaction.md b/docs/concepts/compaction.md index a01d35991..ef2539228 100644 --- a/docs/concepts/compaction.md +++ b/docs/concepts/compaction.md @@ -8,6 +8,22 @@ read_when: Every model has a **context window** (max tokens it can see). Long-running chats accumulate messages and tool results; once the window is tight, Moltbot **compacts** older history to stay within limits. +```mermaid +flowchart TD + A[Session Messages Accumulate] --> B{Near Context Limit?} + B -->|No| C[Continue Normally] + B -->|Yes| D{Memory Flush Enabled?} + D -->|Yes| E[Silent Memory Flush Turn\nWrite durable notes to disk] + D -->|No| F[Skip Flush] + E --> F + F --> G[Auto-Compaction Triggered] + G --> H[Summarize Older Messages] + H --> I[Store Compaction Summary\nin Session JSONL] + I --> J[Keep Recent Messages Intact] + J --> K[Retry Original Request\nwith Compacted Context] + K --> C +``` + ## What compaction is Compaction **summarizes older conversation** into a compact summary entry and keeps recent messages intact. The summary is stored in the session history, so future requests use: - The compaction summary diff --git a/docs/concepts/memory.md b/docs/concepts/memory.md index f2bca461a..44cb91375 100644 --- a/docs/concepts/memory.md +++ b/docs/concepts/memory.md @@ -9,6 +9,34 @@ read_when: Moltbot memory is **plain Markdown in the agent workspace**. The files are the source of truth; the model only "remembers" what gets written to disk. +```mermaid +flowchart TD + subgraph WorkspaceFiles [Workspace Memory Files] + MEM_MD[MEMORY.md\nCurated long-term] + DAILY[memory/YYYY-MM-DD.md\nDaily logs] + end + + subgraph VectorIndex [Vector Memory Search] + EMB[Embedding Provider\nOpenAI / Gemini / Local] + IDX[SQLite Index\n~/.clawdbot/memory/agentId.sqlite] + BM25[BM25 Full-Text\nKeyword matching] + end + + subgraph FlushCycle [Pre-Compaction Flush] + NEAR[Session Nears Limit] --> FLUSH[Silent Memory Flush Turn] + FLUSH --> WRITE[Write Notes to Disk] + WRITE --> COMPACT[Compaction Proceeds] + end + + MEM_MD --> EMB + DAILY --> EMB + EMB --> IDX + IDX --> SEARCH[memory_search Tool] + BM25 --> SEARCH + MEM_MD --> READ[memory_get Tool] + DAILY --> READ +``` + Memory search tools are provided by the active memory plugin (default: `memory-core`). Disable memory plugins with `plugins.slots.memory = "none"`. diff --git a/docs/concepts/messages.md b/docs/concepts/messages.md index 34ecc4c5b..2c66ee63a 100644 --- a/docs/concepts/messages.md +++ b/docs/concepts/messages.md @@ -20,6 +20,30 @@ Inbound message -> outbound replies (channel limits + chunking) ``` +```mermaid +flowchart TD + A[Inbound Message] --> B{Dedupe Cache} + B -->|Duplicate| DROP[Drop] + B -->|New| C{Debounce Window} + C -->|Batched| D[Combined Message] + C -->|Single| D + D --> E[Routing / Bindings] + E --> F[Session Key Resolution] + F --> G{Run Active?} + G -->|No| H[Start Agent Run] + G -->|Yes| I{Queue Mode} + I -->|steer| J[Inject into Current Run] + I -->|followup| K[Queue for Next Turn] + I -->|collect| L[Coalesce into Single Followup] + H --> M[Streaming + Tools] + J --> M + K --> M + L --> M + M --> N[Outbound Reply] + N --> O[Channel Chunking + Limits] + O --> P[Delivered] +``` + Key knobs live in configuration: - `messages.*` for prefixes, queueing, and group behavior. - `agents.defaults.*` for block streaming and chunking defaults. diff --git a/docs/concepts/model-failover.md b/docs/concepts/model-failover.md index 9c2de352c..efcc5aa06 100644 --- a/docs/concepts/model-failover.md +++ b/docs/concepts/model-failover.md @@ -13,6 +13,25 @@ Moltbot handles failures in two stages: This doc explains the runtime rules and the data that backs them. +```mermaid +flowchart TD + REQ[Agent Run Request] --> PROF[Select Auth Profile\nSession-pinned or round-robin] + PROF --> CALL[API Call to Provider] + CALL --> OK{Success?} + OK -->|Yes| DONE[Run Completes] + OK -->|No| ERR{Error Type?} + ERR -->|Rate limit / Auth| CD[Cooldown Profile\nExponential: 1m → 5m → 25m → 1hr] + ERR -->|Billing / Credits| DIS[Disable Profile\n5hr → 24hr backoff] + ERR -->|Format / Invalid| CD + CD --> NEXT{More Profiles\nfor Provider?} + DIS --> NEXT + NEXT -->|Yes| PROF + NEXT -->|No| FB{Model Fallbacks\nConfigured?} + FB -->|Yes| SWITCH[Switch to Next Model\nin fallbacks list] + FB -->|No| FAIL[Run Fails] + SWITCH --> PROF +``` + ## Auth storage (keys + OAuth) Moltbot uses **auth profiles** for both API keys and OAuth tokens. diff --git a/docs/concepts/multi-agent.md b/docs/concepts/multi-agent.md index a36bc3113..3bbda0e47 100644 --- a/docs/concepts/multi-agent.md +++ b/docs/concepts/multi-agent.md @@ -9,7 +9,31 @@ status: active Goal: multiple *isolated* agents (separate workspace + `agentDir` + sessions), plus multiple channel accounts (e.g. two WhatsApps) in one running Gateway. Inbound is routed to an agent via bindings. -## What is “one agent”? +```mermaid +graph TD + GW[Gateway Process] --> A1[Agent: home] + GW --> A2[Agent: work] + + subgraph Agent_home [Agent 'home'] + W1[Workspace\n~/clawd-home] + S1[Sessions\n~/.clawdbot/agents/home/sessions] + AP1[Auth Profiles\n~/.clawdbot/agents/home/agent/auth-profiles.json] + SK1[Skills\n~/clawd-home/skills/] + end + + subgraph Agent_work [Agent 'work'] + W2[Workspace\n~/clawd-work] + S2[Sessions\n~/.clawdbot/agents/work/sessions] + AP2[Auth Profiles\n~/.clawdbot/agents/work/agent/auth-profiles.json] + SK2[Skills\n~/clawd-work/skills/] + end + + B1[Binding: WhatsApp personal] --> A1 + B2[Binding: WhatsApp biz] --> A2 + B3[Binding: Telegram] --> A2 +``` + +## What is "one agent"? An **agent** is a fully scoped brain with its own: diff --git a/docs/concepts/queue.md b/docs/concepts/queue.md index ca498d66b..8c6ff7283 100644 --- a/docs/concepts/queue.md +++ b/docs/concepts/queue.md @@ -7,6 +7,27 @@ read_when: We serialize inbound auto-reply runs (all channels) through a tiny in-process queue to prevent multiple agent runs from colliding, while still allowing safe parallelism across sessions. +```mermaid +flowchart LR + subgraph SessionLanes [Session Lanes\none run per session] + SL1[session:agent:main:main] + SL2[session:agent:main:telegram:group:123] + SL3[session:agent:work:main] + end + + subgraph GlobalLanes [Global Lanes] + ML[Main Lane\nconcurrency: 4] + SAL[Subagent Lane\nconcurrency: 8] + CL[Cron Lane] + end + + SL1 --> ML + SL2 --> ML + SL3 --> ML + SAL -.->|parallel| ML + CL -.->|parallel| ML +``` + ## Why - Auto-reply runs can be expensive (LLM calls) and can collide when multiple inbound messages arrive close together. - Serializing avoids competing for shared resources (session files, logs, CLI stdin) and reduces the chance of upstream rate limits. @@ -27,6 +48,27 @@ Inbound messages can steer the current run, wait for a followup turn, or do both - `interrupt` (legacy): abort the active run for that session, then run the newest message. - `queue` (legacy alias): same as `steer`. +```mermaid +stateDiagram-v2 + [*] --> Idle: No active run + + Idle --> Running: Message arrives + Running --> Steer: steer mode\ninject into run + Running --> Followup: followup mode\nqueue for next turn + Running --> Collect: collect mode\ncoalesce messages + Running --> Interrupt: interrupt mode\nabort + run newest + + Steer --> Running: Tool boundary reached + Followup --> Idle: Current run ends + Followup --> Running: Followup turn starts + Collect --> Idle: Current run ends + Collect --> Running: Single combined turn + Interrupt --> Running: New run starts + + Running --> SteerBacklog: steer-backlog mode + SteerBacklog --> Running: Steer now + preserve for followup +``` + Steer-backlog means you can get a followup response after the steered run, so streaming surfaces can look like duplicates. Prefer `collect`/`steer` if you want one response per inbound message. diff --git a/docs/concepts/session.md b/docs/concepts/session.md index b15b1a1ea..a648ddf91 100644 --- a/docs/concepts/session.md +++ b/docs/concepts/session.md @@ -7,6 +7,21 @@ read_when: Moltbot treats **one direct-chat session per agent** as primary. Direct chats collapse to `agent::` (default `main`), while group/channel chats get their own keys. `session.mainKey` is honored. +```mermaid +flowchart TD + CREATE[Session Created\nNew inbound message] --> LOAD[Load Session\nfrom sessions.json + JSONL] + LOAD --> EXEC[Execute Agent Run\nStreaming + tools] + EXEC --> UPDATE[Update Session\nAppend to JSONL transcript] + UPDATE --> CHECK{Near Context Limit?} + CHECK -->|No| WAIT[Wait for Next Message] + CHECK -->|Yes| COMPACT[Auto-Compaction\nSummarize + retain recent] + COMPACT --> WAIT + WAIT --> RESET{Reset Triggered?} + RESET -->|Daily reset / idle / /new| ARCHIVE[Archive Session\nFresh session ID] + RESET -->|No| LOAD + ARCHIVE --> CREATE +``` + Use `session.dmScope` to control how **direct messages** are grouped: - `main` (default): all DMs share the main session for continuity. - `per-peer`: isolate by sender id across channels. diff --git a/docs/concepts/streaming.md b/docs/concepts/streaming.md index ecb149005..0575229a6 100644 --- a/docs/concepts/streaming.md +++ b/docs/concepts/streaming.md @@ -13,6 +13,29 @@ Moltbot has two separate “streaming” layers: There is **no real token streaming** to external channel messages today. Telegram draft streaming is the only partial-stream surface. +```mermaid +flowchart TD + MODEL[Model Output\ntext_delta events] --> BS{Block Streaming\nEnabled?} + BS -->|Off| FINAL[Wait for Final Reply] + BS -->|On| BREAK{Break Mode?} + BREAK -->|text_end| CHUNK1[Chunker Emits\nas Buffer Grows] + BREAK -->|message_end| CHUNK2[Chunker Flushes\nat message_end] + CHUNK1 --> COAL{Coalesce?} + CHUNK2 --> COAL + COAL -->|Yes| MERGE[Merge Consecutive Chunks\nidle-gap based] + COAL -->|No| SEND[Channel Send] + MERGE --> SEND + FINAL --> SEND + SEND --> LIMIT{Channel Limits} + LIMIT --> SPLIT[Split by textChunkLimit\npreserve code fences] + SPLIT --> DELIVER[Delivered to Channel] + + MODEL --> TG{Telegram?} + TG -->|Yes| DRAFT[Draft Bubble\nsendMessageDraft] + DRAFT --> TGFINAL[Final: Normal Message] + TG -->|No| BS +``` + ## Block streaming (channel messages) Block streaming sends assistant output in coarse chunks as it becomes available. diff --git a/docs/gateway/index.md b/docs/gateway/index.md index 8c5be0fa8..7f9d8bedb 100644 --- a/docs/gateway/index.md +++ b/docs/gateway/index.md @@ -9,6 +9,20 @@ Last updated: 2025-12-09 ## What it is - The always-on process that owns the single Baileys/Telegram connection and the control/event plane. + +```mermaid +stateDiagram-v2 + [*] --> NotInstalled + NotInstalled --> Installing: moltbot gateway install + Installing --> Installed: LaunchAgent / systemd unit created + Installed --> Running: Service starts + Running --> Running: Config hot-reload\nSIGUSR1 in-process restart + Running --> Stopped: moltbot gateway stop\nSIGTERM + Stopped --> Running: moltbot gateway restart\nService supervisor + Running --> Error: Fatal error + Error --> Running: Supervisor auto-restart\nRestartSec=5 +``` + - Replaces the legacy `gateway` command. CLI entry point: `moltbot gateway`. - Runs until stopped; exits non-zero on fatal errors so the supervisor restarts it. @@ -22,6 +36,15 @@ moltbot gateway --force # dev loop (auto-reload on TS changes): pnpm gateway:watch ``` +```mermaid +flowchart LR + WATCH[File Watcher\n~/.clawdbot/moltbot.json] --> DEBOUNCE[Debounce] + DEBOUNCE --> ANALYZE{Analyze Changes} + ANALYZE -->|Safe changes\nthresholds, toggles| HOT[Hot Apply\nNo restart needed] + ANALYZE -->|Critical changes\nport, auth, channels| RESTART[In-Process Restart\nSIGUSR1] + ANALYZE -->|reload.mode=off| IGNORE[Ignored] +``` + - Config hot reload watches `~/.clawdbot/moltbot.json` (or `CLAWDBOT_CONFIG_PATH`). - Default mode: `gateway.reload.mode="hybrid"` (hot-apply safe changes, restart on critical). - Hot reload uses in-process restart via **SIGUSR1** when needed. diff --git a/docs/gateway/protocol.md b/docs/gateway/protocol.md index 66136bd8a..744e0deba 100644 --- a/docs/gateway/protocol.md +++ b/docs/gateway/protocol.md @@ -18,6 +18,31 @@ handshake time. - WebSocket, text frames with JSON payloads. - First frame **must** be a `connect` request. +```mermaid +sequenceDiagram + participant C as Client + participant G as Gateway + + G->>C: event: connect.challenge {nonce, ts} + C->>G: req: connect {protocol, client, role, scopes, auth, device} + alt Valid credentials + device + G->>C: res: hello-ok {protocol, snapshot, policy} + Note over G,C: Includes presence + health snapshot + opt New device + G->>C: hello-ok.auth {deviceToken, role, scopes} + end + else Invalid + G->>C: res: error + G--xC: Socket closed + end + + loop Normal operation + C->>G: req {method, params} + G->>C: res {ok, payload} + G->>C: event {presence, tick, agent, ...} + end +``` + ## Handshake (connect) Gateway → Client (pre-connect challenge): diff --git a/docs/gateway/security/index.md b/docs/gateway/security/index.md index a5d841c18..b6a2daf7f 100644 --- a/docs/gateway/security/index.md +++ b/docs/gateway/security/index.md @@ -35,6 +35,34 @@ Moltbot is both a product and an experiment: you’re wiring frontier-model beha Start with the smallest access that still works, then widen it as you gain confidence. +```mermaid +graph TD + subgraph Layer1 [Layer 1: Inbound Access Control] + DM[DM Policy\npairing / allowlist / open / disabled] + GP[Group Policy\nallowlist + mention gating] + AL[Allowlists\nper-channel sender lists] + end + + subgraph Layer2 [Layer 2: Tool & Execution Scope] + TP[Tool Policy\nallow / deny lists] + SB[Sandboxing\nDocker isolation] + EL[Elevated Mode\nhost exec gating] + BR[Browser Control\nprofile isolation] + end + + subgraph Layer3 [Layer 3: Model & Prompt] + MI[Model Choice\ninstruction-hardened models] + SP[System Prompt\nsafety rules + persona] + PI[Prompt Injection\nresistance varies by model] + end + + INBOUND[Inbound Message] --> Layer1 + Layer1 -->|Authorized| Layer2 + Layer1 -->|Blocked| REJECT[Rejected] + Layer2 -->|Scoped| Layer3 + Layer3 --> AGENT[Agent Executes] +``` + ### What the audit checks (high level) - **Inbound access** (DM policies, group policies, allowlists): can strangers trigger the bot? diff --git a/docs/install/index.md b/docs/install/index.md index 8c6943589..cb845c617 100644 --- a/docs/install/index.md +++ b/docs/install/index.md @@ -9,6 +9,25 @@ read_when: Use the installer unless you have a reason not to. It sets up the CLI and runs onboarding. +```mermaid +flowchart TD + START[Install Moltbot] --> OS{Operating System?} + OS -->|macOS| MAC[macOS] + OS -->|Linux| LINUX[Linux] + OS -->|Windows| WIN[Windows WSL2] + MAC --> METHOD{Install Method?} + LINUX --> METHOD + WIN --> WSL[Install WSL2 First] --> METHOD + METHOD -->|Installer Script| CURL["curl -fsSL https://molt.bot/install.sh | bash"] + METHOD -->|npm Global| NPM[npm install -g moltbot@latest] + METHOD -->|From Source| GIT[git clone + pnpm install + pnpm build] + METHOD -->|Docker| DOCKER[Docker container] + METHOD -->|Nix| NIX[Nix flake] + CURL --> ONBOARD[moltbot onboard --install-daemon] + NPM --> ONBOARD + GIT --> ONBOARD +``` + ## Quick install (recommended) ```bash diff --git a/docs/plugin.md b/docs/plugin.md index 1b5a20608..f1adae913 100644 --- a/docs/plugin.md +++ b/docs/plugin.md @@ -112,6 +112,29 @@ manifest. If multiple plugins resolve to the same id, the first match in the order above wins and lower-precedence copies are ignored. +```mermaid +flowchart TD + A[Plugin Discovery] --> B[1. Config Paths\nplugins.load.paths] + B --> C[2. Workspace Extensions\nworkspace/.clawdbot/extensions/] + C --> D[3. Global Extensions\n~/.clawdbot/extensions/] + D --> E[4. Bundled Extensions\nmoltbot/extensions/\ndisabled by default] + + E --> F{Duplicate ID?} + F -->|Yes| G[First Match Wins\nlower-precedence ignored] + F -->|No| H[Load Plugin] + + H --> I{plugins.allow / deny?} + I -->|Denied| J[Skip Plugin] + I -->|Allowed| K[Register Plugin] + + K --> L[Gateway RPC Methods] + K --> M[Agent Tools] + K --> N[CLI Commands] + K --> O[Background Services] + K --> P[Skills] + K --> Q[Plugin Hooks] +``` + ### Package packs A plugin directory may include a `package.json` with `moltbot.extensions`: diff --git a/docs/start/getting-started.md b/docs/start/getting-started.md index 239b29966..bdda03347 100644 --- a/docs/start/getting-started.md +++ b/docs/start/getting-started.md @@ -9,6 +9,19 @@ read_when: Goal: go from **zero** → **first working chat** (with sane defaults) as quickly as possible. +```mermaid +flowchart TD + A[Install Moltbot\nnpm install -g moltbot] --> B[Run Onboarding Wizard\nmoltbot onboard --install-daemon] + B --> C[Model Auth\nOAuth or API Key] + C --> D[Gateway Settings\nport, bind, token] + D --> E[Channel Setup\nWhatsApp / Telegram / etc.] + E --> F[Pairing Defaults\nSecure DM access] + F --> G[Workspace Bootstrap\nAGENTS.md, SOUL.md, etc.] + G --> H[Install Daemon\nlaunchd / systemd] + H --> I[Gateway Running\nAlways-on service] + I --> J[Send First Message\nmoltbot agent --message 'Hello'] +``` + Fastest chat: open the Control UI (no channel setup needed). Run `moltbot dashboard` and chat in the browser, or open `http://127.0.0.1:18789/` on the gateway host. Docs: [Dashboard](/web/dashboard) and [Control UI](/web/control-ui). diff --git a/docs/start/pairing.md b/docs/start/pairing.md index cb679bfb5..9921e55f0 100644 --- a/docs/start/pairing.md +++ b/docs/start/pairing.md @@ -14,6 +14,29 @@ It is used in two places: 1) **DM pairing** (who is allowed to talk to the bot) 2) **Node pairing** (which devices/nodes are allowed to join the gateway network) +```mermaid +sequenceDiagram + participant S as Sender / Device + participant GW as Gateway + participant O as Owner (CLI) + + Note over S,GW: DM Pairing Flow + S->>GW: Send DM message + GW->>GW: Unknown sender → generate 8-char code + GW->>S: Reply with pairing code (expires 1hr) + O->>GW: moltbot pairing list + O->>GW: moltbot pairing approve + GW->>GW: Add sender to allowlist + S->>GW: Next message → processed normally + + Note over S,GW: Node Device Pairing Flow + S->>GW: WS connect (role: node, device identity) + GW->>GW: New device → create pairing request + O->>GW: moltbot devices approve + GW->>S: Device token issued + S->>GW: Future connects use device token +``` + Security context: [Security](/gateway/security) ## 1) DM pairing (inbound chat access) diff --git a/docs/tools/browser.md b/docs/tools/browser.md index 084c36bf3..6ff0612e6 100644 --- a/docs/tools/browser.md +++ b/docs/tools/browser.md @@ -321,6 +321,24 @@ High-level flow: This design keeps the agent on a stable, deterministic interface while letting you swap local/remote browsers and profiles. +```mermaid +flowchart TD + AGENT[Agent Tool Call\nbrowser action] --> TARGET{Target?} + TARGET -->|sandbox| SB[Sandbox Browser\nDocker container] + TARGET -->|host| LOCAL{Local Browser\nRunning?} + TARGET -->|node| NODE[Node Host\nProxy to remote browser] + LOCAL -->|No| START[Launch Chromium\nvia CDP on loopback] + LOCAL -->|Yes| CDP[Connect via CDP] + START --> CDP + CDP --> PW{Playwright\nAvailable?} + PW -->|Yes| ACTIONS[Full Actions\nclick/type/snapshot/PDF] + PW -->|No| BASIC[Basic Only\nARIA snapshot + screenshot] + ACTIONS --> RESULT[Return to Agent\nsnapshot / screenshot / action result] + BASIC --> RESULT + NODE --> RESULT + SB --> RESULT +``` + ## CLI quick reference All commands accept `--browser-profile ` to target a specific profile. diff --git a/docs/tools/index.md b/docs/tools/index.md index 7c2274fb4..3e886dc06 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -11,6 +11,55 @@ Moltbot exposes **first-class agent tools** for browser, canvas, nodes, and cron These replace the old `moltbot-*` skills: the tools are typed, no shelling, and the agent should rely on them directly. +```mermaid +graph LR + subgraph Runtime [group:runtime] + EXEC[exec] + BASH[bash] + PROC[process] + end + + subgraph FS [group:fs] + READ[read] + WRITE[write] + EDIT[edit] + PATCH[apply_patch] + end + + subgraph Sessions [group:sessions] + SL[sessions_list] + SH[sessions_history] + SS[sessions_send] + SP[sessions_spawn] + SST[session_status] + end + + subgraph Web [group:web] + WS[web_search] + WF[web_fetch] + end + + subgraph UI [group:ui] + BROWSER[browser] + CANVAS[canvas] + end + + subgraph Automation [group:automation] + CRON[cron] + GATEWAY[gateway] + end + + subgraph Messaging [group:messaging] + MSG[message] + end + + subgraph Other + NODES[nodes] + IMAGE[image] + AGENTS_LIST[agents_list] + end +``` + ## Disabling tools You can globally allow/deny tools via `tools.allow` / `tools.deny` in `moltbot.json`