docs: update routing/messages/session config

This commit is contained in:
Peter Steinberger
2025-12-24 00:22:57 +00:00
parent 93af424ce5
commit 0f06e9926b
18 changed files with 109 additions and 105 deletions

View File

@@ -12,7 +12,7 @@
- WhatsApp send now preserves existing JIDs (including group `@g.us`) instead of coercing to `@s.whatsapp.net`. (Thanks @arun-8687.) - WhatsApp send now preserves existing JIDs (including group `@g.us`) instead of coercing to `@s.whatsapp.net`. (Thanks @arun-8687.)
- Telegram/WhatsApp: native replies now target the original inbound message; reply context is appended to `Body` and captured in `ReplyTo*` fields. (Thanks @joshp123 for the PR and follow-up question.) - Telegram/WhatsApp: native replies now target the original inbound message; reply context is appended to `Body` and captured in `ReplyTo*` fields. (Thanks @joshp123 for the PR and follow-up question.)
- WhatsApp web creds persistence hardened; credentials are restored before auth checks and QR login auto-restarts if it stalls. - WhatsApp web creds persistence hardened; credentials are restored before auth checks and QR login auto-restarts if it stalls.
- Group chats now honor `inbound.groupChat.requireMention=false` as the default activation when no per-group override exists. - Group chats now honor `routing.groupChat.requireMention=false` as the default activation when no per-group override exists.
- Gateway auth no longer supports PAM/system mode; use token or shared password. - Gateway auth no longer supports PAM/system mode; use token or shared password.
- Tailscale Funnel now requires password auth (no token-only public exposure). - Tailscale Funnel now requires password auth (no token-only public exposure).
- Group `/new` resets now work with @mentions so activation guidance appears on fresh sessions. - Group `/new` resets now work with @mentions so activation guidance appears on fresh sessions.
@@ -21,6 +21,7 @@
- WhatsApp group typing now starts immediately only when the bot is mentioned; otherwise it waits until real output exists. - WhatsApp group typing now starts immediately only when the bot is mentioned; otherwise it waits until real output exists.
- Streamed `<think>` segments are stripped before partial replies are emitted. - Streamed `<think>` segments are stripped before partial replies are emitted.
- System prompt now tags allowlisted owner numbers as the user identity to avoid mistaken “friend” assumptions. - System prompt now tags allowlisted owner numbers as the user identity to avoid mistaken “friend” assumptions.
- LM Studio/Ollama replies now require <final> tags; streaming ignores content until <final> begins.
- Canvas defaults/A2UI auto-nav aligned; debug status overlay centered; redundant await removed in `CanvasManager`. - Canvas defaults/A2UI auto-nav aligned; debug status overlay centered; redundant await removed in `CanvasManager`.
- Gateway launchd loop fixed by removing redundant `kickstart -k`. - Gateway launchd loop fixed by removing redundant `kickstart -k`.
- CLI now hints when Peekaboo is unauthorized. - CLI now hints when Peekaboo is unauthorized.
@@ -90,7 +91,7 @@ First Clawdis release post rebrand. This is a semver-major because we dropped le
### Breaking ### Breaking
- Renamed to **Clawdis**: defaults now live under `~/.clawdis` (sessions in `~/.clawdis/sessions/`, IPC at `~/.clawdis/clawdis.sock`, logs in `/tmp/clawdis`). Launchd labels and config filenames follow the new name; legacy stores are copied forward on first run. - Renamed to **Clawdis**: defaults now live under `~/.clawdis` (sessions in `~/.clawdis/sessions/`, IPC at `~/.clawdis/clawdis.sock`, logs in `/tmp/clawdis`). Launchd labels and config filenames follow the new name; legacy stores are copied forward on first run.
- Pi only: `inbound.reply.agent.kind` accepts only `"pi"`, and the agent CLI/CLI flags for Claude/Codex/Gemini were removed. The Pi CLI runs in RPC mode with a persistent worker. - Pi only: only the embedded Pi runtime remains, and the agent CLI/CLI flags for Claude/Codex/Gemini were removed. The Pi CLI runs in RPC mode with a persistent worker.
- WhatsApp Web is the only transport; Twilio support and related CLI flags/tests were removed. - WhatsApp Web is the only transport; Twilio support and related CLI flags/tests were removed.
- Direct chats now collapse into a single `main` session by default (no config needed); groups stay isolated as `group:<jid>`. - Direct chats now collapse into a single `main` session by default (no config needed); groups stay isolated as `group:<jid>`.
- Gateway is now a loopback-only WebSocket daemon (`ws://127.0.0.1:18789`) that owns all providers/state; clients (CLI, WebChat, macOS app, nodes) connect to it. Start it explicitly (`clawdis gateway …`) or via Clawdis.app; helper subcommands no longer auto-spawn a gateway. - Gateway is now a loopback-only WebSocket daemon (`ws://127.0.0.1:18789`) that owns all providers/state; clients (CLI, WebChat, macOS app, nodes) connect to it. Start it explicitly (`clawdis gateway …`) or via Clawdis.app; helper subcommands no longer auto-spawn a gateway.
@@ -138,7 +139,7 @@ First Clawdis release post rebrand. This is a semver-major because we dropped le
## 1.5.0 — 2025-12-05 ## 1.5.0 — 2025-12-05
### Breaking ### Breaking
- Dropped all non-Pi agents (Claude, Codex, Gemini, Opencode); `inbound.reply.agent.kind` now only accepts `"pi"` and related CLI helpers have been removed. - Dropped all non-Pi agents (Claude, Codex, Gemini, Opencode); only the embedded Pi runtime remains and related CLI helpers have been removed.
- Removed Twilio support and all related commands/options (webhook/up/provider flags/wait-poll); CLAWDIS is Baileys Web-only. - Removed Twilio support and all related commands/options (webhook/up/provider flags/wait-poll); CLAWDIS is Baileys Web-only.
### Changes ### Changes
@@ -165,7 +166,7 @@ First Clawdis release post rebrand. This is a semver-major because we dropped le
## 1.4.0 — 2025-12-03 ## 1.4.0 — 2025-12-03
### Highlights ### Highlights
- **Thinking directives & state:** `/t|/think|/thinking <level>` (aliases off|minimal|low|medium|high|max/highest). Inline applies to that message; directive-only message pins the level for the session; `/think:off` clears. Resolution: inline > session override > `inbound.reply.thinkingDefault` > off. Pi gets `--thinking <level>` (except off); other agents append cue words (`think``think hard``think harder``ultrathink`). Heartbeat probe uses `HEARTBEAT /think:high`. - **Thinking directives & state:** `/t|/think|/thinking <level>` (aliases off|minimal|low|medium|high|max/highest). Inline applies to that message; directive-only message pins the level for the session; `/think:off` clears. Resolution: inline > session override > `agent.thinkingDefault` > off. Pi gets `--thinking <level>` (except off); other agents append cue words (`think``think hard``think harder``ultrathink`). Heartbeat probe uses `HEARTBEAT /think:high`.
- **Group chats (web provider):** Clawdis now fully supports WhatsApp groups: mention-gated triggers (including image-only @ mentions), recent group history injection, per-group sessions, sender attribution, and a first-turn primer with group subject/member roster; heartbeats are skipped for groups. - **Group chats (web provider):** Clawdis now fully supports WhatsApp groups: mention-gated triggers (including image-only @ mentions), recent group history injection, per-group sessions, sender attribution, and a first-turn primer with group subject/member roster; heartbeats are skipped for groups.
- **Group session primer:** The first turn of a group session now tells the agent it is in a WhatsApp group and lists known members/subject so it can address the right speaker. - **Group session primer:** The first turn of a group session now tells the agent it is in a WhatsApp group and lists known members/subject so it can address the right speaker.
- **Media failures are surfaced:** When a web auto-reply media fetch/send fails (e.g., HTTP 404), we now append a warning to the fallback text so you know the attachment was skipped. - **Media failures are surfaced:** When a web auto-reply media fetch/send fails (e.g., HTTP 404), we now append a warning to the fallback text so you know the attachment was skipped.
@@ -207,7 +208,7 @@ First Clawdis release post rebrand. This is a semver-major because we dropped le
## 1.3.0 — 2025-12-02 ## 1.3.0 — 2025-12-02
### Highlights ### Highlights
- **Pluggable agents (Claude, Pi, Codex, Opencode):** `inbound.reply.agent` selects CLI/parser; per-agent argv builders and NDJSON parsers enable swapping without template changes. - **Pluggable agents (Claude, Pi, Codex, Opencode):** agent selection via config/CLI plus per-agent argv builders and NDJSON parsers enable swapping without template changes.
- **Safety stop words:** `stop|esc|abort|wait|exit` immediately reply “Agent was aborted.” and mark the session so the next prompt is prefixed with an abort reminder. - **Safety stop words:** `stop|esc|abort|wait|exit` immediately reply “Agent was aborted.” and mark the session so the next prompt is prefixed with an abort reminder.
- **Agent session reliability:** Only Claude returns a stable `session_id`; others may reset between runs. - **Agent session reliability:** Only Claude returns a stable `session_id`; others may reset between runs.
@@ -224,7 +225,7 @@ First Clawdis release post rebrand. This is a semver-major because we dropped le
- Batched inbound messages with timestamps; typing indicator after sends. - Batched inbound messages with timestamps; typing indicator after sends.
- Watchdog restarts WhatsApp after long inactivity; heartbeat logging includes minutes since last message. - Watchdog restarts WhatsApp after long inactivity; heartbeat logging includes minutes since last message.
- Early `allowFrom` filtering before decryption. - Early `allowFrom` filtering before decryption.
- Same-phone mode with echo detection and optional `inbound.samePhoneMarker`. - Same-phone mode with echo detection and optional message prefix marker.
## 1.2.2 — 2025-11-28 ## 1.2.2 — 2025-11-28
@@ -254,10 +255,10 @@ First Clawdis release post rebrand. This is a semver-major because we dropped le
## 1.1.0 — 2025-11-26 ## 1.1.0 — 2025-11-26
### Changes ### Changes
- Web auto-replies resize/recompress media and honor `inbound.reply.mediaMaxMb`. - Web auto-replies resize/recompress media and honor `agent.mediaMaxMb`.
- Detect media kind, enforce provider caps (images ≤6MB, audio/video ≤16MB, docs ≤100MB). - Detect media kind, enforce provider caps (images ≤6MB, audio/video ≤16MB, docs ≤100MB).
- `session.sendSystemOnce` and optional `sessionIntro`. - `session.sendSystemOnce` and optional `sessionIntro`.
- Typing indicator refresh during commands; configurable via `inbound.reply.typingIntervalSeconds`. - Typing indicator refresh during commands; configurable via `agent.typingIntervalSeconds`.
- Optional audio transcription via external CLI. - Optional audio transcription via external CLI.
- Command replies return structured payload/meta; respect `mediaMaxMb`; log Claude metadata; include `cwd` in timeout messages. - Command replies return structured payload/meta; respect `mediaMaxMb`; log Claude metadata; include `cwd` in timeout messages.
- Web provider refactor; logout command; web-only gateway start helper. - Web provider refactor; logout command; web-only gateway start helper.

View File

@@ -143,7 +143,7 @@ Minimal `~/.clawdis/clawdis.json`:
```json5 ```json5
{ {
inbound: { routing: {
allowFrom: ["+1234567890"] allowFrom: ["+1234567890"]
} }
} }
@@ -152,7 +152,7 @@ Minimal `~/.clawdis/clawdis.json`:
### WhatsApp ### WhatsApp
- Link the device: `pnpm clawdis login` (stores creds in `~/.clawdis/credentials`). - Link the device: `pnpm clawdis login` (stores creds in `~/.clawdis/credentials`).
- Allowlist who can talk to the assistant via `inbound.allowFrom`. - Allowlist who can talk to the assistant via `routing.allowFrom`.
### Telegram ### Telegram

View File

@@ -11,7 +11,7 @@ read_when:
- Required: `--message <text>` - Required: `--message <text>`
- Session selection: - Session selection:
- If `--session-id` is given, reuse it. - If `--session-id` is given, reuse it.
- Else if `--to <e164>` is given, derive the session key from `inbound.session.scope` (direct chats collapse to `inbound.session.mainKey`). - Else if `--to <e164>` is given, derive the session key from `session.scope` (direct chats collapse to `session.mainKey`).
- Runs the embedded Pi agent (configured via `agent`). - Runs the embedded Pi agent (configured via `agent`).
- Thinking/verbose: - Thinking/verbose:
- Flags `--thinking <off|minimal|low|medium|high>` and `--verbose <on|off>` persist into the session store. - Flags `--thinking <off|minimal|low|medium|high>` and `--verbose <on|off>` persist into the session store.

View File

@@ -76,7 +76,7 @@ Incoming user messages are queued while the agent is streaming. The queue is che
At minimum, set: At minimum, set:
- `agent.workspace` - `agent.workspace`
- `inbound.allowFrom` (strongly recommended) - `routing.allowFrom` (strongly recommended)
--- ---

View File

@@ -7,7 +7,7 @@ read_when:
# Audio / Voice Notes — 2025-12-05 # Audio / Voice Notes — 2025-12-05
## What works ## What works
- **Optional transcription**: If `inbound.transcribeAudio.command` is set in `~/.clawdis/clawdis.json`, CLAWDIS will: - **Optional transcription**: If `routing.transcribeAudio.command` is set in `~/.clawdis/clawdis.json`, CLAWDIS will:
1) Download inbound audio to a temp path when WhatsApp only provides a URL. 1) Download inbound audio to a temp path when WhatsApp only provides a URL.
2) Run the configured CLI (templated with `{{MediaPath}}`), expecting transcript on stdout. 2) Run the configured CLI (templated with `{{MediaPath}}`), expecting transcript on stdout.
3) Replace `Body` with the transcript, set `{{Transcript}}`, and prepend the original media path plus a `Transcript:` section in the command prompt so models see both. 3) Replace `Body` with the transcript, set `{{Transcript}}`, and prepend the original media path plus a `Transcript:` section in the command prompt so models see both.
@@ -18,7 +18,7 @@ read_when:
Requires `OPENAI_API_KEY` in env and `openai` CLI installed: Requires `OPENAI_API_KEY` in env and `openai` CLI installed:
```json5 ```json5
{ {
inbound: { routing: {
transcribeAudio: { transcribeAudio: {
command: [ command: [
"openai", "openai",
@@ -32,11 +32,6 @@ Requires `OPENAI_API_KEY` in env and `openai` CLI installed:
"text" "text"
], ],
timeoutSeconds: 45 timeoutSeconds: 45
},
reply: {
mode: "command",
command: ["pi", "{{Body}}"],
agent: { kind: "pi" }
} }
} }
} }

View File

@@ -17,7 +17,7 @@ Youre putting an agent in a position to:
- send messages back out via WhatsApp/Telegram - send messages back out via WhatsApp/Telegram
Start conservative: Start conservative:
- Always set `inbound.allowFrom` (never run open-to-the-world on your personal Mac). - Always set `routing.allowFrom` (never run open-to-the-world on your personal Mac).
- Use a dedicated WhatsApp number for the assistant. - Use a dedicated WhatsApp number for the assistant.
- Keep heartbeats disabled until you trust the setup (`heartbeatMinutes: 0`). - Keep heartbeats disabled until you trust the setup (`heartbeatMinutes: 0`).
@@ -74,7 +74,7 @@ clawdis gateway --port 18789
```json5 ```json5
{ {
inbound: { routing: {
allowFrom: ["+15555550123"] allowFrom: ["+15555550123"]
} }
} }
@@ -98,7 +98,7 @@ Optional: choose a different workspace with `agent.workspace` (supports `~`).
```json5 ```json5
{ {
inbound: { agent: {
workspace: "~/clawd" workspace: "~/clawd"
} }
} }
@@ -116,27 +116,27 @@ Example:
```json5 ```json5
{ {
logging: { level: "info" }, logging: { level: "info" },
inbound: { agent: {
allowFrom: ["+15555550123"], provider: "anthropic",
model: "claude-opus-4-5",
workspace: "~/clawd", workspace: "~/clawd",
thinkingDefault: "high",
timeoutSeconds: 1800,
// Start with 0; enable later.
heartbeatMinutes: 0
},
routing: {
allowFrom: ["+15555550123"],
groupChat: { groupChat: {
requireMention: true, requireMention: true,
mentionPatterns: ["@clawd", "clawd"] mentionPatterns: ["@clawd", "clawd"]
},
agent: {
provider: "anthropic",
model: "claude-opus-4-5",
thinkingDefault: "high",
timeoutSeconds: 1800,
// Start with 0; enable later.
heartbeatMinutes: 0
},
session: {
scope: "per-sender",
resetTriggers: ["/new", "/reset"],
idleMinutes: 10080,
mainKey: "main"
} }
},
session: {
scope: "per-sender",
resetTriggers: ["/new", "/reset"],
idleMinutes: 10080,
mainKey: "main"
} }
} }
``` ```
@@ -155,10 +155,8 @@ When `agent.heartbeatMinutes > 0`, CLAWDIS periodically runs a heartbeat prompt
```json5 ```json5
{ {
inbound: { agent: {
agent: { heartbeatMinutes: 30
heartbeatMinutes: 30
}
} }
} }
``` ```

View File

@@ -9,10 +9,11 @@ read_when:
CLAWDIS reads an optional **JSON5** config from `~/.clawdis/clawdis.json` (comments + trailing commas allowed). CLAWDIS reads an optional **JSON5** config from `~/.clawdis/clawdis.json` (comments + trailing commas allowed).
If the file is missing, CLAWDIS uses safe-ish defaults (embedded Pi agent + per-sender sessions + workspace `~/clawd`). You usually only need a config to: If the file is missing, CLAWDIS uses safe-ish defaults (embedded Pi agent + per-sender sessions + workspace `~/clawd`). You usually only need a config to:
- restrict who can trigger the bot (`inbound.allowFrom`) - restrict who can trigger the bot (`routing.allowFrom`)
- tune group mention behavior (`inbound.groupChat`) - tune group mention behavior (`routing.groupChat`)
- customize message prefixes (`messages`)
- set the agents workspace (`agent.workspace`) - set the agents workspace (`agent.workspace`)
- tune the embedded agent (`agent`) and session behavior (`inbound.session`) - tune the embedded agent (`agent`) and session behavior (`session`)
- set the agents identity (`identity`) - set the agents identity (`identity`)
## Minimal config (recommended starting point) ## Minimal config (recommended starting point)
@@ -20,7 +21,7 @@ If the file is missing, CLAWDIS uses safe-ish defaults (embedded Pi agent + per-
```json5 ```json5
{ {
agent: { workspace: "~/clawd" }, agent: { workspace: "~/clawd" },
inbound: { allowFrom: ["+15555550123"] } routing: { allowFrom: ["+15555550123"] }
} }
``` ```
@@ -31,8 +32,8 @@ If the file is missing, CLAWDIS uses safe-ish defaults (embedded Pi agent + per-
Optional agent identity used for defaults and UX. This is written by the macOS onboarding assistant. Optional agent identity used for defaults and UX. This is written by the macOS onboarding assistant.
If set, CLAWDIS derives defaults (only when you havent set them explicitly): If set, CLAWDIS derives defaults (only when you havent set them explicitly):
- `inbound.responsePrefix` from `identity.emoji` - `messages.responsePrefix` from `identity.emoji`
- `inbound.groupChat.mentionPatterns` from `identity.name` (so “@Samantha” works in groups) - `routing.groupChat.mentionPatterns` from `identity.name` (so “@Samantha” works in groups)
```json5 ```json5
{ {
@@ -59,23 +60,23 @@ If set, CLAWDIS derives defaults (only when you havent set them explicitly):
} }
``` ```
### `inbound.allowFrom` ### `routing.allowFrom`
Allowlist of E.164 phone numbers that may trigger auto-replies. Allowlist of E.164 phone numbers that may trigger auto-replies.
```json5 ```json5
{ {
inbound: { allowFrom: ["+15555550123", "+447700900123"] } routing: { allowFrom: ["+15555550123", "+447700900123"] }
} }
``` ```
### `inbound.groupChat` ### `routing.groupChat`
Group messages default to **require mention** (either metadata mention or regex patterns). Group messages default to **require mention** (either metadata mention or regex patterns).
```json5 ```json5
{ {
inbound: { routing: {
groupChat: { groupChat: {
mentionPatterns: ["@clawd", "clawdbot", "clawd"], mentionPatterns: ["@clawd", "clawdbot", "clawd"],
historyLimit: 50 historyLimit: 50
@@ -96,6 +97,20 @@ Default: `~/clawd`.
} }
``` ```
### `messages`
Controls inbound/outbound prefixes and timestamps.
```json5
{
messages: {
messagePrefix: "[clawdis]",
responsePrefix: "🦞",
timestampPrefix: "Europe/London"
}
}
```
### `agent` ### `agent`
Controls the embedded agent runtime (provider/model/thinking/verbose/timeouts). Controls the embedded agent runtime (provider/model/thinking/verbose/timeouts).
@@ -117,8 +132,7 @@ Controls the embedded agent runtime (provider/model/thinking/verbose/timeouts).
mediaMaxMb: 5, mediaMaxMb: 5,
heartbeatMinutes: 30, heartbeatMinutes: 30,
contextTokens: 200000 contextTokens: 200000
}, }
inbound: { workspace: "~/clawd" }
} }
``` ```
@@ -138,9 +152,7 @@ Select the model via `agent.provider` + `agent.model`.
```json5 ```json5
{ {
inbound: { agent: { provider: "custom-proxy", model: "llama-3.1-8b" },
agent: { provider: "custom-proxy", model: "llama-3.1-8b" }
},
models: { models: {
mode: "merge", mode: "merge",
providers: { providers: {
@@ -172,20 +184,18 @@ Notes:
- Override the agent config root with `CLAWDIS_AGENT_DIR` (or `PI_CODING_AGENT_DIR`) - Override the agent config root with `CLAWDIS_AGENT_DIR` (or `PI_CODING_AGENT_DIR`)
if you want `models.json` stored elsewhere. if you want `models.json` stored elsewhere.
### `inbound.session` ### `session`
Controls session scoping, idle expiry, reset triggers, and where the session store is written. Controls session scoping, idle expiry, reset triggers, and where the session store is written.
```json5 ```json5
{ {
inbound: { session: {
session: { scope: "per-sender",
scope: "per-sender", idleMinutes: 60,
idleMinutes: 60, resetTriggers: ["/new", "/reset"],
resetTriggers: ["/new", "/reset"], store: "~/.clawdis/sessions/sessions.json",
store: "~/.clawdis/sessions/sessions.json", mainKey: "main"
mainKey: "main"
}
} }
} }
``` ```
@@ -377,7 +387,7 @@ clawdis dns setup --apply
## Template variables ## Template variables
Template placeholders are expanded in `inbound.transcribeAudio.command` (and any future templated command fields). Template placeholders are expanded in `routing.transcribeAudio.command` (and any future templated command fields).
| Variable | Description | | Variable | Description |
|----------|-------------| |----------|-------------|

View File

@@ -9,7 +9,7 @@ Goal: let Clawd sit in WhatsApp groups, wake up only when pinged, and keep that
## Whats implemented (2025-12-03) ## Whats implemented (2025-12-03)
- Activation modes: `mention` (default) or `always`. `mention` requires a ping (real WhatsApp @-mentions via `mentionedJids`, regex patterns, or the bots E.164 anywhere in the text). `always` wakes the agent on every message but it should reply only when it can add meaningful value; otherwise it returns the silent token `NO_REPLY`. Activation is controlled per group (command or UI), not via config. - Activation modes: `mention` (default) or `always`. `mention` requires a ping (real WhatsApp @-mentions via `mentionedJids`, regex patterns, or the bots E.164 anywhere in the text). `always` wakes the agent on every message but it should reply only when it can add meaningful value; otherwise it returns the silent token `NO_REPLY`. Activation is controlled per group (command or UI), not via config.
- Group allowlist bypass: we still enforce `allowFrom` on the participant at inbox ingest, but group JIDs themselves no longer block replies. - Group allowlist bypass: we still enforce `routing.allowFrom` on the participant at inbox ingest, but group JIDs themselves no longer block replies.
- Per-group sessions: session keys look like `group:<jid>` so commands such as `/verbose on` or `/think:high` are scoped to that group; personal DM state is untouched. Heartbeats are skipped for group threads. - Per-group sessions: session keys look like `group:<jid>` so commands such as `/verbose on` or `/think:high` are scoped to that group; personal DM state is untouched. Heartbeats are skipped for group threads.
- Context injection: last N (default 50) group messages are prefixed under `[Chat messages since your last reply - for context]`, with the triggering line under `[Current message - respond to this]`. - Context injection: last N (default 50) group messages are prefixed under `[Chat messages since your last reply - for context]`, with the triggering line under `[Current message - respond to this]`.
- Sender surfacing: every group batch now ends with `[from: Sender Name (+E164)]` so Pi knows who is speaking. - Sender surfacing: every group batch now ends with `[from: Sender Name (+E164)]` so Pi knows who is speaking.
@@ -21,7 +21,7 @@ Add a `groupChat` block to `~/.clawdis/clawdis.json` so display-name pings work
```json5 ```json5
{ {
"inbound": { "routing": {
"groupChat": { "groupChat": {
"historyLimit": 50, "historyLimit": 50,
"mentionPatterns": [ "mentionPatterns": [
@@ -45,7 +45,7 @@ Use the group chat command:
- `/activation mention` - `/activation mention`
- `/activation always` - `/activation always`
Only the owner number (from `allowFrom`, defaulting to the bots own E.164 when unset) can change this. `/status` in the group shows the current activation mode. Only the owner number (from `routing.allowFrom`, defaulting to the bots own E.164 when unset) can change this. `/status` in the group shows the current activation mode.
## How to use ## How to use
1) Add Clawd UK (`+447700900123`) to the group. 1) Add Clawd UK (`+447700900123`) to the group.

View File

@@ -22,7 +22,7 @@ Short guide to verify the WhatsApp Web / Baileys stack without guessing.
## When something fails ## When something fails
- `logged out` or status 409515 → relink with `clawdis logout` then `clawdis login`. - `logged out` or status 409515 → relink with `clawdis logout` then `clawdis login`.
- Gateway unreachable → start it: `clawdis gateway --port 18789` (use `--force` if the port is busy). - Gateway unreachable → start it: `clawdis gateway --port 18789` (use `--force` if the port is busy).
- No inbound messages → confirm linked phone is online and the sender is allowed (`inbound.allowFrom`); for group chats, ensure mention rules match (`inbound.groupChat`). - No inbound messages → confirm linked phone is online and the sender is allowed (`routing.allowFrom`); for group chats, ensure mention rules match (`routing.groupChat`).
## Dedicated "health" command ## Dedicated "health" command
`clawdis health --json` asks the running Gateway for its health snapshot (no direct Baileys socket from the CLI). It reports linked creds, auth age, Baileys connect result/status code, session-store summary, and a probe duration. It exits non-zero if the Gateway is unreachable or the probe fails/timeouts. Use `--timeout <ms>` to override the 10s default. `clawdis health --json` asks the running Gateway for its health snapshot (no direct Baileys socket from the CLI). It reports linked creds, auth age, Baileys connect result/status code, session-store summary, and a probe duration. It exits non-zero if the Gateway is unreachable or the probe fails/timeouts. Use `--timeout <ms>` to override the 10s default.

View File

@@ -14,7 +14,7 @@ Goal: add a simple heartbeat poll for the embedded agent that only notifies user
## Config & defaults ## Config & defaults
- New config key: `agent.heartbeatMinutes` (number of minutes; `0` disables). - New config key: `agent.heartbeatMinutes` (number of minutes; `0` disables).
- Default: 30 minutes. - Default: 30 minutes.
- New optional idle override for heartbeats: `inbound.session.heartbeatIdleMinutes` (defaults to `idleMinutes`). Heartbeat skips do **not** update the session `updatedAt` so idle expiry still works. - New optional idle override for heartbeats: `session.heartbeatIdleMinutes` (defaults to `idleMinutes`). Heartbeat skips do **not** update the session `updatedAt` so idle expiry still works.
## Poller behavior ## Poller behavior
- When gateway runs with command-mode auto-reply, start a timer with the resolved heartbeat interval. - When gateway runs with command-mode auto-reply, start a timer with the resolved heartbeat interval.
@@ -42,8 +42,8 @@ Goal: add a simple heartbeat poll for the embedded agent that only notifies user
## Documentation ## Documentation
- Add a short README snippet under configuration showing `heartbeatMinutes` and the sentinel rule. - Add a short README snippet under configuration showing `heartbeatMinutes` and the sentinel rule.
- Expose CLI triggers: - Expose CLI triggers:
- `clawdis heartbeat` (web provider, defaults to first `allowFrom`; optional `--to` override) - `clawdis heartbeat` (web provider, defaults to first `routing.allowFrom`; optional `--to` override)
- `--session-id <uuid>` forces resuming a specific session for that heartbeat - `--session-id <uuid>` forces resuming a specific session for that heartbeat
- `clawdis gateway --heartbeat-now` to run the gateway loop with an immediate heartbeat - `clawdis gateway --heartbeat-now` to run the gateway loop with an immediate heartbeat
- Gateway supports `--heartbeat-now` to fire once at startup. - Gateway supports `--heartbeat-now` to fire once at startup.
- When multiple sessions are active or `allowFrom` is only `"*"`, require `--to <E.164>` or `--all` for manual heartbeats to avoid ambiguous targets. - When multiple sessions are active or `routing.allowFrom` is only `"*"`, require `--to <E.164>` or `--all` for manual heartbeats to avoid ambiguous targets.

View File

@@ -98,13 +98,13 @@ clawdis send --to +15555550123 --message "Hello from CLAWDIS"
Config lives at `~/.clawdis/clawdis.json`. Config lives at `~/.clawdis/clawdis.json`.
- If you **do nothing**, CLAWDIS uses the bundled Pi binary in RPC mode with per-sender sessions. - If you **do nothing**, CLAWDIS uses the bundled Pi binary in RPC mode with per-sender sessions.
- If you want to lock it down, start with `inbound.allowFrom` and (for groups) mention rules. - If you want to lock it down, start with `routing.allowFrom` and (for groups) mention rules.
Example: Example:
```json5 ```json5
{ {
inbound: { routing: {
allowFrom: ["+15555550123"], allowFrom: ["+15555550123"],
groupChat: { requireMention: true, mentionPatterns: ["@clawd"] } groupChat: { requireMention: true, mentionPatterns: ["@clawd"] }
} }

View File

@@ -5,7 +5,7 @@ read_when:
--- ---
# Web Chat (macOS app) # Web Chat (macOS app)
The macOS menu bar app shows the WebChat UI as a native SwiftUI view and reuses the **primary Clawd session** (`main` by default, configurable via `inbound.session.mainKey`). The macOS menu bar app shows the WebChat UI as a native SwiftUI view and reuses the **primary Clawd session** (`main` by default, configurable via `session.mainKey`).
- **Local mode**: connects directly to the local Gateway WebSocket. - **Local mode**: connects directly to the local Gateway WebSocket.
- **Remote mode**: forwards the Gateway WebSocket control port over SSH and uses that as the data plane. - **Remote mode**: forwards the Gateway WebSocket control port over SSH and uses that as the data plane.

View File

@@ -95,7 +95,7 @@ We no longer collect identity in the onboarding wizard. Instead, the **first age
Identity data still feeds the same defaults as before: Identity data still feeds the same defaults as before:
- outbound prefix emoji (`inbound.responsePrefix`) - outbound prefix emoji (`messages.responsePrefix`)
- group mention patterns / wake words - group mention patterns / wake words
- default session intro (“You are Samantha…”) - default session intro (“You are Samantha…”)
- macOS UI labels - macOS UI labels

View File

@@ -42,7 +42,7 @@ This is social engineering 101. Create distrust, encourage snooping.
```json ```json
{ {
"inbound": { "routing": {
"allowFrom": ["+15555550123"] "allowFrom": ["+15555550123"]
} }
} }
@@ -54,9 +54,11 @@ Only allow specific phone numbers to trigger your AI. Never use `["*"]` in produ
```json ```json
{ {
"groupChat": { "routing": {
"requireMention": true, "groupChat": {
"mentionPatterns": ["@clawd", "@mybot"] "requireMention": true,
"mentionPatterns": ["@clawd", "@mybot"]
}
} }
} }
``` ```

View File

@@ -5,7 +5,7 @@ read_when:
--- ---
# Session Management # Session Management
Clawdis treats **one session as primary**. By default the canonical key is `main` for every direct chat; no configuration is required. You can rename it via `inbound.session.mainKey` if you really want, but there is still only a single primary session. Older/local sessions can stay on disk, but only the primary key is used for desktop/web chat and direct agent calls. Clawdis treats **one session as primary**. By default the canonical key is `main` for every direct chat; no configuration is required. You can rename it via `session.mainKey` if you really want, but there is still only a single primary session. Older/local sessions can stay on disk, but only the primary key is used for desktop/web chat and direct agent calls.
## Gateway is the source of truth ## Gateway is the source of truth
All session state is **owned by the gateway** (the “master” Clawdis). UI clients (macOS app, WebChat, etc.) must query the gateway for session lists and token counts instead of reading local files. All session state is **owned by the gateway** (the “master” Clawdis). UI clients (macOS app, WebChat, etc.) must query the gateway for session lists and token counts instead of reading local files.
@@ -26,7 +26,7 @@ All session state is **owned by the gateway** (the “master” Clawdis). UI cli
- Group chats still isolate state with `group:<jid>` keys; do not reuse the primary key for groups. - Group chats still isolate state with `group:<jid>` keys; do not reuse the primary key for groups.
## Lifecyle ## Lifecyle
- Idle expiry: `inbound.session.idleMinutes` (default 60). After the timeout a new `sessionId` is minted on the next message. - Idle expiry: `session.idleMinutes` (default 60). After the timeout a new `sessionId` is minted on the next message.
- Reset triggers: exact `/new` or `/reset` (plus any extras in `resetTriggers`) start a fresh session id and pass the remainder of the message through. If `/new` or `/reset` is sent alone, Clawdis runs a short “hello” greeting turn to confirm the reset. - Reset triggers: exact `/new` or `/reset` (plus any extras in `resetTriggers`) start a fresh session id and pass the remainder of the message through. If `/new` or `/reset` is sent alone, Clawdis runs a short “hello” greeting turn to confirm the reset.
- Manual reset: delete specific keys from the store or remove the JSONL transcript; the next message recreates them. - Manual reset: delete specific keys from the store or remove the JSONL transcript; the next message recreates them.
@@ -34,14 +34,12 @@ All session state is **owned by the gateway** (the “master” Clawdis). UI cli
```json5 ```json5
// ~/.clawdis/clawdis.json // ~/.clawdis/clawdis.json
{ {
inbound: { session: {
session: { scope: "per-sender", // keep group keys separate
scope: "per-sender", // keep group keys separate idleMinutes: 120,
idleMinutes: 120, resetTriggers: ["/new", "/reset"],
resetTriggers: ["/new", "/reset"], store: "~/.clawdis/sessions/sessions.json",
store: "~/.clawdis/sessions/sessions.json", mainKey: "main" // optional rename; still a single primary
mainKey: "main" // optional rename; still a single primary
}
} }
} }
``` ```

View File

@@ -24,7 +24,7 @@ Status: ready for bot-mode use with grammY (long-polling by default; webhook sup
- If you need a different public port/host, set `telegram.webhookUrl` to the externally reachable URL and use a reverse proxy to forward to `:8787`. - If you need a different public port/host, set `telegram.webhookUrl` to the externally reachable URL and use a reverse proxy to forward to `:8787`.
4) Direct chats: user sends the first message; all subsequent turns land in the shared `main` session (default, no extra config). 4) Direct chats: user sends the first message; all subsequent turns land in the shared `main` session (default, no extra config).
5) Groups: add the bot, disable privacy mode (or make it admin) so it can read messages; group threads stay on `group:<chatId>` and require mention/command to trigger replies. 5) Groups: add the bot, disable privacy mode (or make it admin) so it can read messages; group threads stay on `group:<chatId>` and require mention/command to trigger replies.
6) Optional allowlist: reuse `inbound.allowFrom` for direct chats by chat id (`123456789` or `telegram:123456789`). 6) Optional allowlist: reuse `routing.allowFrom` for direct chats by chat id (`123456789` or `telegram:123456789`).
## Capabilities & limits (Bot API) ## Capabilities & limits (Bot API)
- Sees only messages sent after its added to a chat; no pre-history access. - Sees only messages sent after its added to a chat; no pre-history access.

View File

@@ -22,15 +22,15 @@ The agent was interrupted mid-response.
### Messages Not Triggering ### Messages Not Triggering
**Check 1:** Is the sender in `allowFrom`? **Check 1:** Is the sender in `routing.allowFrom`?
```bash ```bash
cat ~/.clawdis/clawdis.json | jq '.inbound.allowFrom' cat ~/.clawdis/clawdis.json | jq '.routing.allowFrom'
``` ```
**Check 2:** For group chats, is mention required? **Check 2:** For group chats, is mention required?
```bash ```bash
# The message must contain a pattern from mentionPatterns # The message must contain a pattern from mentionPatterns
cat ~/.clawdis/clawdis.json | jq '.inbound.groupChat' cat ~/.clawdis/clawdis.json | jq '.routing.groupChat'
``` ```
**Check 3:** Check the logs **Check 3:** Check the logs

View File

@@ -30,8 +30,8 @@ Status: WhatsApp Web via Baileys only. Gateway owns the single session.
- WhatsApp events come from `messages.upsert` (Baileys). - WhatsApp events come from `messages.upsert` (Baileys).
- Status/broadcast chats are ignored. - Status/broadcast chats are ignored.
- Direct chats use E.164; groups use group JID. - Direct chats use E.164; groups use group JID.
- **Allowlist**: `inbound.allowFrom` enforced for direct chats only. - **Allowlist**: `routing.allowFrom` enforced for direct chats only.
- If allowFrom is empty, default allowlist = self number (self-chat mode). - If `routing.allowFrom` is empty, default allowlist = self number (self-chat mode).
- **Self-chat mode**: avoids auto read receipts and ignores mention JIDs. - **Self-chat mode**: avoids auto read receipts and ignores mention JIDs.
- Read receipts sent for non-self-chat DMs. - Read receipts sent for non-self-chat DMs.
@@ -56,7 +56,7 @@ Status: WhatsApp Web via Baileys only. Gateway owns the single session.
- `mention` (default): requires @mention or regex match. - `mention` (default): requires @mention or regex match.
- `always`: always triggers. - `always`: always triggers.
- `/activation mention|always` is owner-only. - `/activation mention|always` is owner-only.
- Owner = `inbound.allowFrom` (or self E.164 if unset). - Owner = `routing.allowFrom` (or self E.164 if unset).
- **History injection**: - **History injection**:
- Recent messages (default 50) inserted under: - Recent messages (default 50) inserted under:
`[Chat messages since your last reply - for context]` `[Chat messages since your last reply - for context]`
@@ -98,14 +98,14 @@ Status: WhatsApp Web via Baileys only. Gateway owns the single session.
- Logged-out => stop and require re-link. - Logged-out => stop and require re-link.
## Config quick map ## Config quick map
- `inbound.allowFrom` (DM allowlist). - `routing.allowFrom` (DM allowlist).
- `inbound.groupChat.mentionPatterns` - `routing.groupChat.mentionPatterns`
- `inbound.groupChat.historyLimit` - `routing.groupChat.historyLimit`
- `inbound.messagePrefix` (inbound prefix) - `messages.messagePrefix` (inbound prefix)
- `inbound.responsePrefix` (outbound prefix) - `messages.responsePrefix` (outbound prefix)
- `agent.mediaMaxMb` - `agent.mediaMaxMb`
- `agent.heartbeatMinutes` - `agent.heartbeatMinutes`
- `inbound.session.*` (scope, idle, store, mainKey) - `session.*` (scope, idle, store, mainKey)
- `web.heartbeatSeconds` - `web.heartbeatSeconds`
- `web.reconnect.*` - `web.reconnect.*`