diff --git a/docs/docs.json b/docs/docs.json index d67db901a..87e104ad4 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -570,6 +570,7 @@ "gateway/pairing", "gateway/gateway-lock", "gateway/configuration", + "gateway/configuration-examples", "gateway/background-process", "gateway/health", "gateway/heartbeat", diff --git a/docs/gateway/configuration-examples.md b/docs/gateway/configuration-examples.md new file mode 100644 index 000000000..9ca7d1e78 --- /dev/null +++ b/docs/gateway/configuration-examples.md @@ -0,0 +1,553 @@ +--- +summary: "Schema-accurate configuration examples for common Clawdbot setups" +read_when: + - Learning how to configure clawdbot + - Looking for configuration examples + - Setting up clawdbot for the first time +--- +# Configuration Examples + +Examples below are aligned with the current config schema. For the exhaustive reference and per-field notes, see [Configuration](/gateway/configuration). + +## Quick start + +### Absolute minimum +```json5 +{ + agent: { workspace: "~/clawd" }, + whatsapp: { allowFrom: ["+15555550123"] } +} +``` + +Save to `~/.clawdbot/clawdbot.json` and you can DM the bot from that number. + +### Recommended starter +```json5 +{ + identity: { + name: "Clawd", + theme: "helpful assistant", + emoji: "🦞" + }, + agent: { + workspace: "~/clawd", + model: { primary: "anthropic/claude-sonnet-4-5" } + }, + whatsapp: { + allowFrom: ["+15555550123"], + groups: { "*": { requireMention: true } } + } +} +``` + +## Expanded example (major options) + +> JSON5 lets you use comments and trailing commas. Regular JSON works too. + +```json5 +{ + // Environment + shell + env: { + shellEnv: { + enabled: true, + timeoutMs: 15000 + } + }, + + // Auth profile metadata (secrets live in auth-profiles.json) + auth: { + profiles: { + "anthropic:me@example.com": { provider: "anthropic", mode: "oauth", email: "me@example.com" }, + "anthropic:work": { provider: "anthropic", mode: "api_key" }, + "openai:default": { provider: "openai", mode: "api_key" }, + "openai-codex:default": { provider: "openai-codex", mode: "oauth" } + }, + order: { + anthropic: ["anthropic:me@example.com", "anthropic:work"], + openai: ["openai:default"], + "openai-codex": ["openai-codex:default"] + } + }, + + // Identity + identity: { + name: "Samantha", + theme: "helpful sloth", + emoji: "🦥" + }, + + // Logging + logging: { + level: "info", + file: "/tmp/clawdbot/clawdbot.log", + consoleLevel: "info", + consoleStyle: "pretty", + redactSensitive: "tools" + }, + + // Message formatting + messages: { + messagePrefix: "[clawdbot]", + responsePrefix: ">", + ackReaction: "👀", + ackReactionScope: "group-mentions" + }, + + // Routing + queue + routing: { + groupChat: { + mentionPatterns: ["@clawd", "clawdbot"], + historyLimit: 50 + }, + queue: { + mode: "collect", + debounceMs: 1000, + cap: 20, + drop: "summarize", + byProvider: { + whatsapp: "collect", + telegram: "collect", + discord: "collect", + slack: "collect", + signal: "collect", + imessage: "collect", + webchat: "collect" + } + }, + transcribeAudio: { + command: ["whisper", "--model", "base"], + timeoutSeconds: 120 + } + }, + + // Session behavior + session: { + scope: "per-sender", + idleMinutes: 60, + heartbeatIdleMinutes: 120, + resetTriggers: ["/new", "/reset"], + store: "~/.clawdbot/agents/default/sessions/sessions.json", + typingIntervalSeconds: 5, + sendPolicy: { + default: "allow", + rules: [ + { action: "deny", match: { provider: "discord", chatType: "group" } } + ] + } + }, + + // Providers + whatsapp: { + dmPolicy: "pairing", + allowFrom: ["+15555550123"], + groupPolicy: "open", + groups: { "*": { requireMention: true } } + }, + + telegram: { + enabled: true, + botToken: "YOUR_TELEGRAM_BOT_TOKEN", + allowFrom: ["123456789"], + groupPolicy: "open", + groups: { "*": { requireMention: true } } + }, + + discord: { + enabled: true, + token: "YOUR_DISCORD_BOT_TOKEN", + dm: { enabled: true, allowFrom: ["steipete"] }, + guilds: { + "123456789012345678": { + slug: "friends-of-clawd", + requireMention: false, + channels: { + general: { allow: true }, + help: { allow: true, requireMention: true } + } + } + } + }, + + slack: { + enabled: true, + botToken: "xoxb-REPLACE_ME", + appToken: "xapp-REPLACE_ME", + channels: { + "#general": { allow: true, requireMention: true } + }, + dm: { enabled: true, allowFrom: ["U123"] }, + slashCommand: { + enabled: true, + name: "clawd", + sessionPrefix: "slack:slash", + ephemeral: true + } + }, + + signal: { + enabled: true, + account: "+15555550123", + httpUrl: "http://localhost:8080", + allowFrom: ["+15555550123"] + }, + + imessage: { + enabled: true, + cliPath: "imsg", + dbPath: "~/Library/Messages/chat.db", + service: "auto", + allowFrom: ["+15555550123"], + groups: { "*": { requireMention: true } } + }, + + // Agent runtime + agent: { + workspace: "~/clawd", + userTimezone: "America/Chicago", + model: { + primary: "anthropic/claude-sonnet-4-5", + fallbacks: ["anthropic/claude-opus-4-5", "openai/gpt-5.2"] + }, + imageModel: { + primary: "openrouter/anthropic/claude-sonnet-4-5" + }, + models: { + "anthropic/claude-opus-4-5": { alias: "opus" }, + "anthropic/claude-sonnet-4-5": { alias: "sonnet" }, + "openai/gpt-5.2": { alias: "gpt" } + }, + thinkingDefault: "low", + verboseDefault: "off", + elevatedDefault: "on", + blockStreamingDefault: "on", + blockStreamingBreak: "text_end", + blockStreamingChunk: { + minChars: 800, + maxChars: 1200, + breakPreference: "paragraph" + }, + timeoutSeconds: 600, + mediaMaxMb: 5, + typingIntervalSeconds: 5, + maxConcurrent: 3, + tools: { + allow: ["bash", "process", "read", "write", "edit"], + deny: ["browser", "canvas"] + }, + bash: { + backgroundMs: 10000, + timeoutSec: 1800, + cleanupMs: 1800000 + }, + heartbeat: { + every: "30m", + model: "anthropic/claude-sonnet-4-5", + target: "last", + to: "+15555550123", + prompt: "HEARTBEAT", + ackMaxChars: 30 + }, + elevated: { + enabled: true, + allowFrom: { + whatsapp: ["+15555550123"], + telegram: ["123456789"], + discord: ["steipete"], + slack: ["U123"], + signal: ["+15555550123"], + imessage: ["user@example.com"], + webchat: ["session:demo"] + } + }, + sandbox: { + mode: "non-main", + perSession: true, + workspaceRoot: "~/.clawdbot/sandboxes", + docker: { + image: "clawdbot-sandbox:bookworm-slim", + workdir: "/workspace", + readOnlyRoot: true, + tmpfs: ["/tmp", "/var/tmp", "/run"], + network: "none", + user: "1000:1000" + }, + browser: { + enabled: false + } + } + }, + + // Custom model providers + models: { + mode: "merge", + providers: { + "custom-proxy": { + baseUrl: "http://localhost:4000/v1", + apiKey: "LITELLM_KEY", + api: "openai-responses", + authHeader: true, + headers: { "X-Proxy-Region": "us-west" }, + models: [ + { + id: "llama-3.1-8b", + name: "Llama 3.1 8B", + api: "openai-responses", + reasoning: false, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 128000, + maxTokens: 32000 + } + ] + } + } + }, + + // Cron jobs + cron: { + enabled: true, + store: "~/.clawdbot/cron/cron.json", + maxConcurrentRuns: 2 + }, + + // Webhooks + hooks: { + enabled: true, + path: "/hooks", + token: "shared-secret", + presets: ["gmail"], + transformsDir: "~/.clawdbot/hooks", + mappings: [ + { + id: "gmail-hook", + match: { path: "gmail" }, + action: "agent", + wakeMode: "now", + name: "Gmail", + sessionKey: "hook:gmail:{{messages[0].id}}", + messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}", + textTemplate: "{{messages[0].snippet}}", + deliver: true, + provider: "last", + to: "+15555550123", + thinking: "low", + timeoutSeconds: 300, + transform: { module: "./transforms/gmail.js", export: "transformGmail" } + } + ], + gmail: { + account: "clawdbot@gmail.com", + label: "INBOX", + topic: "projects//topics/gog-gmail-watch", + subscription: "gog-gmail-watch-push", + pushToken: "shared-push-token", + hookUrl: "http://127.0.0.1:18789/hooks/gmail", + includeBody: true, + maxBytes: 20000, + renewEveryMinutes: 720, + serve: { bind: "127.0.0.1", port: 8788, path: "/" }, + tailscale: { mode: "funnel", path: "/gmail-pubsub" } + } + }, + + // Web client + web: { + enabled: true, + heartbeatSeconds: 60, + reconnect: { + initialMs: 2000, + maxMs: 120000, + factor: 1.4, + jitter: 0.2, + maxAttempts: 0 + } + }, + + // Browser automation + browser: { + enabled: true, + controlUrl: "http://127.0.0.1:18791", + cdpUrl: "http://127.0.0.1:9222", + headless: false, + defaultProfile: "clawd", + profiles: { + clawd: { cdpPort: 18800, color: "#FF4500" }, + work: { cdpPort: 18801, color: "#0066CC" } + } + }, + + // UI tweaks + ui: { + seamColor: "#FF4500" + }, + + // Gateway + networking + gateway: { + mode: "local", + port: 18789, + bind: "loopback", + controlUi: { enabled: true, basePath: "/clawdbot" }, + auth: { + mode: "token", + token: "gateway-token", + allowTailscale: true + }, + tailscale: { mode: "serve", resetOnExit: false }, + remote: { url: "ws://gateway.tailnet:18789", token: "remote-token" }, + reload: { mode: "hybrid", debounceMs: 300 } + }, + + bridge: { + enabled: true, + port: 18790, + bind: "tailnet" + }, + + discovery: { + wideArea: { enabled: true } + }, + + canvasHost: { + enabled: true, + root: "~/clawd/canvas", + port: 18793, + liveReload: true + }, + + talk: { + voiceId: "elevenlabs_voice_id", + voiceAliases: { Clawd: "EXAVITQu4vr4xnSDxMaL" }, + modelId: "eleven_v3", + outputFormat: "mp3_44100_128", + apiKey: "ELEVENLABS_API_KEY", + interruptOnSpeech: true + }, + + skills: { + allowBundled: ["brave-search", "gemini"], + load: { + extraDirs: ["~/Projects/agent-scripts/skills"] + }, + install: { + preferBrew: true, + nodeManager: "npm" + }, + entries: { + "nano-banana-pro": { + enabled: true, + apiKey: "GEMINI_KEY_HERE", + env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" } + }, + peekaboo: { enabled: true } + } + } +} +``` + +## Common patterns + +### Multi-platform setup +```json5 +{ + agent: { workspace: "~/clawd" }, + whatsapp: { allowFrom: ["+15555550123"] }, + telegram: { + enabled: true, + botToken: "YOUR_TOKEN", + allowFrom: ["123456789"] + }, + discord: { + enabled: true, + token: "YOUR_TOKEN", + dm: { allowFrom: ["yourname"] } + } +} +``` + +### OAuth with API key failover +```json5 +{ + auth: { + profiles: { + "anthropic:subscription": { + provider: "anthropic", + mode: "oauth", + email: "me@example.com" + }, + "anthropic:api": { + provider: "anthropic", + mode: "api_key" + } + }, + order: { + anthropic: ["anthropic:subscription", "anthropic:api"] + } + }, + agent: { + workspace: "~/clawd", + model: { + primary: "anthropic/claude-sonnet-4-5", + fallbacks: ["anthropic/claude-opus-4-5"] + } + } +} +``` + +### Work bot (restricted access) +```json5 +{ + identity: { + name: "WorkBot", + theme: "professional assistant" + }, + agent: { + workspace: "~/work-clawd", + elevated: { enabled: false } + }, + slack: { + enabled: true, + botToken: "xoxb-...", + channels: { + "#engineering": { allow: true, requireMention: true }, + "#general": { allow: true, requireMention: true } + } + } +} +``` + +### Local models only +```json5 +{ + agent: { + workspace: "~/clawd", + model: { primary: "lmstudio/minimax-m2.1-gs32" } + }, + models: { + mode: "merge", + providers: { + lmstudio: { + baseUrl: "http://127.0.0.1:1234/v1", + apiKey: "lmstudio", + api: "openai-responses", + models: [ + { + id: "minimax-m2.1-gs32", + name: "MiniMax M2.1 GS32", + reasoning: false, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 196608, + maxTokens: 8192 + } + ] + } + } + } +} +``` + +## Tips + +- If you set `dmPolicy: "open"`, the matching `allowFrom` list must include `"*"`. +- Provider IDs differ (phone numbers, user IDs, channel IDs). Use the provider docs to confirm the format. +- See [Providers](/providers/whatsapp) and [Troubleshooting](/gateway/troubleshooting) for deeper setup notes. diff --git a/docs/gateway/configuration.md b/docs/gateway/configuration.md index 29c457c01..86412fcaa 100644 --- a/docs/gateway/configuration.md +++ b/docs/gateway/configuration.md @@ -15,6 +15,8 @@ If the file is missing, CLAWDBOT uses safe-ish defaults (embedded Pi agent + per - tune the embedded agent (`agent`) and session behavior (`session`) - set the agent's identity (`identity`) +> **New to configuration?** Check out the [Configuration Examples](/gateway/configuration-examples) guide for complete examples with detailed explanations! + ## Schema + UI hints The Gateway exposes a JSON Schema representation of the config via `config.schema` for UI editors. diff --git a/docs/index.md b/docs/index.md index 410ff452d..d502eb328 100644 --- a/docs/index.md +++ b/docs/index.md @@ -149,6 +149,7 @@ Example: - [Docs hubs (all pages linked)](https://docs.clawd.bot/start/hubs) - [FAQ](https://docs.clawd.bot/start/faq) ← *common questions answered* - [Configuration](https://docs.clawd.bot/gateway/configuration) + - [Configuration examples](https://docs.clawd.bot/gateway/configuration-examples) - [Slash commands](https://docs.clawd.bot/tools/slash-commands) - [Multi-agent routing](https://docs.clawd.bot/concepts/multi-agent) - [Updating / rollback](https://docs.clawd.bot/install/updating) diff --git a/docs/start/hubs.md b/docs/start/hubs.md index 58b9209b7..bd0af2226 100644 --- a/docs/start/hubs.md +++ b/docs/start/hubs.md @@ -17,6 +17,7 @@ Use these hubs to discover every page, including deep dives and reference docs t - [Dashboard (local Gateway)](http://127.0.0.1:18789/) - [FAQ](https://docs.clawd.bot/start/faq) - [Configuration](https://docs.clawd.bot/gateway/configuration) +- [Configuration examples](https://docs.clawd.bot/gateway/configuration-examples) - [Clawd (personal assistant)](https://docs.clawd.bot/start/clawd) - [Showcase](https://docs.clawd.bot/start/showcase) - [Lore](https://docs.clawd.bot/start/lore)