diff --git a/README.md b/README.md index 3c449958c..300591ff6 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ Optional: enable/configure clawd’s dedicated browser control (defaults are alr - [Configuration Guide](./docs/configuration.md) - [Gateway runbook](./docs/gateway.md) - [Discovery + transports](./docs/discovery.md) -- [Agent Integration](./docs/agents.md) +- [Agent Runtime](./docs/agent.md) - [Group Chats](./docs/group-messages.md) - [Security](./docs/security.md) - [Troubleshooting](./docs/troubleshooting.md) @@ -221,7 +221,7 @@ In chat, send `/status` to see if the agent is reachable, how much context the s ### Sessions, surfaces, and WebChat -- Direct chats now share a canonical session key `main` by default (configurable via `inbound.reply.session.mainKey`). Groups stay isolated as `group:`. +- Direct chats now share a canonical session key `main` by default (configurable via `inbound.session.mainKey`). Groups stay isolated as `group:`. - WebChat attaches to `main` and hydrates history from `~/.clawdis/sessions/.jsonl`, so desktop view mirrors WhatsApp/Telegram turns. - Inbound contexts carry a `Surface` hint (e.g., `whatsapp`, `webchat`, `telegram`) for logging; replies still go back to the originating surface deterministically. - Every inbound message is wrapped for the agent as `[Surface FROM HOST/IP TIMESTAMP] body`: diff --git a/docs/agent-send.md b/docs/agent-send.md index 8a9f0aa04..2ab574942 100644 --- a/docs/agent-send.md +++ b/docs/agent-send.md @@ -3,59 +3,19 @@ summary: "Design notes for a direct `clawdis agent` CLI subcommand without Whats read_when: - Adding or modifying the agent CLI entrypoint --- -# Plan: `clawdis agent` (direct-to-agent invocation) +# `clawdis agent` (direct-to-agent invocation) -Goal: Add a CLI subcommand that talks directly to the configured agent command (no WhatsApp send), while reusing the same session handling and config clawdis already uses for auto-replies. - -## Why -- Sometimes we want to poke the agent directly (same prompt templates/sessions) without sending a WhatsApp message. -- Current flows (`send`, gateway, directives) always route through WhatsApp or add wrapping text; we need a clean “talk to agent now” tool. +`clawdis agent` lets you talk to the **embedded** agent runtime directly (no chat send unless you opt in), while reusing the same session store and thinking/verbose persistence as inbound auto-replies. ## Behavior -- Command: `clawdis agent` - Required: `--message ` - Session selection: - - If `--session-id` given, use it. - - Else if `--to ` given, derive session key like auto-reply (`per-sender`, same normalization) and load/create session id from `session store` path in config. - - Else error (“need --to or --session-id”). -- Runs the same external command as auto-reply: `inbound.reply.command` from config (honors `reply.session` options: sendSystemOnce, sendSystemOnce=false, typing, timeouts, etc.). -- Uses the same templating rules for Body as command mode, but **skips** WhatsApp-specific wrappers (group intro, media hints). Keep session intro/bodyPrefix if sendSystemOnce is false, otherwise follow session config. + - If `--session-id` is given, reuse it. + - Else if `--to ` is given, derive the session key from `inbound.session.scope` (direct chats collapse to `inbound.session.mainKey`). +- Runs the embedded Pi agent (configured via `inbound.agent`). - Thinking/verbose: - - Accept flags `--thinking ` and `--verbose `. - - Persist into session store (like directive-only flow) and inject into the command invocation. + - Flags `--thinking ` and `--verbose ` persist into the session store. - Output: - - Default: print the agent’s text reply to stdout. - - `--json` flag: print full payload (text, any media URL, timing). -- Does **not** send anything to WhatsApp; purely local agent run. - -## Flags (proposed) -- `--message, -m ` (required) -- `--to, -t ` (derive session) -- `--session-id ` (override) -- `--thinking ` -- `--verbose ` -- `--json` (structured output) -- `--timeout ` (override command timeout) - -## Implementation steps -1) CLI: - - Add subcommand in `src/cli/program.ts`. - - Wire options, setVerbose, createDefaultDeps. -2) Command handler (new file `src/commands/agent.ts`): - - Load config. - - Resolve session store + session id (reuse `deriveSessionKey`, `loadSessionStore`, `saveSessionStore`). - - Apply thinking/verbose overrides and persist to session entry. - - Build command body (no WhatsApp wrappers; honor sessionIntro/bodyPrefix as per config). - - Call `runCommandWithTimeout` (same as auto-reply) and parse response (reuse splitter for MEDIA, etc.). - - Return text (and mediaUrl) to stdout / JSON. -3) Share logic: - - Extract helper(s) from `auto-reply/reply.ts` if needed (session + thinking persistence) to avoid duplication. -4) Tests: - - Unit tests for handler: session creation, thinking persistence, resume with `--session-id`, JSON output. - - Snapshot of command args to ensure no WhatsApp wrappers. -5) Docs: - - Add usage examples to CLI help and README. - -## Out of scope (for now) -- Chat directives `/cmd` in WhatsApp. (Can reuse the same handler later.) -- Media input/attachments. Start text-only; extend later if needed. + - Default: prints text (and `MEDIA:` lines) to stdout. + - `--json`: prints structured payloads + meta. +- Optional: `--deliver` sends the reply back to the selected provider (requires `--to` for WhatsApp). diff --git a/docs/agent.md b/docs/agent.md new file mode 100644 index 000000000..cff3f0b4f --- /dev/null +++ b/docs/agent.md @@ -0,0 +1,48 @@ +--- +summary: "Agent runtime (embedded Pi), workspace contract, and session bootstrap" +read_when: + - Changing agent runtime, workspace bootstrap, or session behavior +--- + +# Agent Runtime 🤖 + +CLAWDIS runs a single agent runtime: **Pi (embedded, in-process)**. + +## Workspace (required) + +You must set an agent home directory via `inbound.workspace`. CLAWDIS uses this as the agent’s **only** working directory (`cwd`) for tools and context. + +Recommended: use `clawdis setup` to create `~/.clawdis/clawdis.json` if missing and initialize the workspace files. + +## Bootstrap files (injected) + +Inside `inbound.workspace`, CLAWDIS expects these user-editable files: +- `AGENTS.md` — operating instructions + “memory” +- `SOUL.md` — persona, boundaries, tone +- `TOOLS.md` — user-maintained tool notes (e.g. `imsg`, `sag`, conventions) + +On the first turn of a new session, CLAWDIS injects the contents of these files directly into the agent context. + +If a file is missing, CLAWDIS injects a single “missing file” marker line (and `clawdis setup` will create a safe default template). + +## Built-in tools (internal) + +Pi’s embedded core tools (read/bash/edit/write and related internals) are defined in code and always available. `TOOLS.md` does **not** control which tools exist; it’s guidance for how *you* want them used. + +## Sessions + +Session transcripts are stored as JSONL at: +- `~/.clawdis/sessions/.jsonl` + +The session ID is stable and chosen by CLAWDIS. + +## Configuration (minimal) + +At minimum, set: +- `inbound.workspace` +- `inbound.allowFrom` (strongly recommended) + +--- + +*Next: [Group Chats](./group-messages.md)* 🦞 + diff --git a/docs/agents.md b/docs/agents.md deleted file mode 100644 index d6ba9f3a6..000000000 --- a/docs/agents.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -summary: "Current agent integration: Pi as the sole coding agent with config examples" -read_when: - - Changing agent invocation or defaults ---- - -# Agent Integration 🤖 - -CLAWDIS ships with a single coding-agent path: **Pi** (RPC mode). Legacy Claude/Codex/Gemini/Opencode integrations have been removed. - -## Default behavior - -If you don’t configure `inbound.reply`, CLAWDIS uses the bundled Pi binary in RPC mode: -- command: `pi --mode rpc {{BodyStripped}}` -- per-sender sessions (stored under `~/.clawdis/sessions/*.jsonl`) -- `/new` starts a fresh session - -This is usually enough for a personal assistant setup; add `inbound.allowFrom` to restrict who can trigger it. - -If you keep an `AGENTS.md` (and optional “memory” files) for the agent, set `inbound.workspace` (preferred) or `inbound.reply.cwd` so Pi runs with the right context. - -## Custom agent command (still Pi) - -To override the agent command, configure `inbound.reply.mode: "command"`: - -```json5 -{ - inbound: { - reply: { - mode: "command", - command: ["pi", "--mode", "rpc", "{{BodyStripped}}"], - timeoutSeconds: 1800, - agent: { kind: "pi", format: "json" } - } - } -} -``` - -Notes: -- CLAWDIS forces `--mode rpc` for Pi invocations (even if you pass `--mode json/text`). -- If your `command` array omits `{{Body}}`/`{{BodyStripped}}`, CLAWDIS still synthesizes the prompt body for RPC mode. - -## Sessions - -Session behavior lives under `inbound.reply.session`: - -```json5 -{ - inbound: { - reply: { - session: { - scope: "per-sender", - resetTriggers: ["/new", "/reset"], - idleMinutes: 10080, - sendSystemOnce: true, - sessionIntro: "You are Clawd. Be a good lobster." - } - } - } -} -``` - -Defaults when `session` is enabled: -- Session files are written to `~/.clawdis/sessions/{{SessionId}}.jsonl`. -- Resume adds `--continue` automatically (Pi needs it to load prior messages). - -## Heartbeats - -If you enable `inbound.reply.heartbeatMinutes`, CLAWDIS periodically runs a heartbeat prompt (default: `HEARTBEAT /think:high`). - -- If the agent replies with `HEARTBEAT_OK` (exact token), CLAWDIS suppresses outbound delivery for that heartbeat. -- If you want a different command for heartbeats, set `inbound.reply.heartbeatCommand`. - -```json5 -{ - inbound: { - reply: { - heartbeatMinutes: 30, - heartbeatCommand: ["pi", "--mode", "rpc", "HEARTBEAT /think:high"] - } - } -} -``` - -## Tool streaming (RPC) - -RPC mode emits structured tool lifecycle events (start/result) and assistant output. These are: -- logged to `/tmp/clawdis/…` -- streamed over the Gateway WS to clients like WebChat and the macOS app - -## Browser helpers - -If you enable the clawd-managed browser (default on), the agent can use: -- `clawdis browser status` / `tabs` / `open ` / `screenshot [targetId]` -- `clawdis browser snapshot --format ai` (returns an AI snapshot with `[ref=…]` ids) -- `clawdis browser click ` (click by ref from an AI snapshot) - -This uses a dedicated Chrome/Chromium profile (lobster-orange by default) so it doesn’t interfere with your daily browser. - -## Debugging `clawdis-mac` errors - -When the agent runs `clawdis-mac` (often over SSH), the CLI prints compact, human-readable errors by default. - -- To get the full `NSError` dump (domain/code/userInfo), rerun with `CLAWDIS_MAC_VERBOSE_ERRORS=1` in the environment. - ---- - -*Next: [Group Chats](./group-messages.md)* 🦞 - diff --git a/docs/clawd.md b/docs/clawd.md index a028fd1d0..03b06cfe4 100644 --- a/docs/clawd.md +++ b/docs/clawd.md @@ -90,20 +90,17 @@ Now message the assistant number from your allowlisted phone. ## Give the agent a workspace (AGENTS.md) -Pi (the bundled coding agent) will read operating instructions and “memory” from its current working directory. +Clawd reads operating instructions and “memory” from its workspace directory. -By default, Clawdis uses `~/.clawdis/workspace` as the agent workspace, and will create it (plus a starter `AGENTS.md`) automatically on first agent run. +By default, Clawdis uses `~/clawd` as the agent workspace, and will create it (plus starter `AGENTS.md`, `SOUL.md`, `TOOLS.md`) automatically on setup/first agent run. Tip: treat this folder like Clawd’s “memory” and make it a git repo (ideally private) so your `AGENTS.md` + memory files are backed up. -From the CLAWDIS repo: - ```bash -mkdir -p ~/.clawdis/workspace -cp docs/AGENTS.default.md ~/.clawdis/workspace/AGENTS.md +clawdis setup ``` -Optional: choose a different workspace with `inbound.workspace` (supports `~`). `inbound.reply.cwd` still works and overrides it. +Optional: choose a different workspace with `inbound.workspace` (supports `~`). ```json5 { @@ -115,8 +112,8 @@ Optional: choose a different workspace with `inbound.workspace` (supports `~`). ## The config that turns it into “an assistant” -CLAWDIS defaults to a good Pi setup even without `inbound.reply`, but you’ll usually want to tune: -- session intro (personality + instructions) +CLAWDIS defaults to a good assistant setup, but you’ll usually want to tune: +- persona/instructions in `SOUL.md` - thinking defaults (if desired) - heartbeats (once you trust it) @@ -127,25 +124,24 @@ Example: logging: { level: "info" }, inbound: { allowFrom: ["+15555550123"], + workspace: "~/clawd", groupChat: { requireMention: true, mentionPatterns: ["@clawd", "clawd"] }, - reply: { - mode: "command", - // Pi is bundled; CLAWDIS forces --mode rpc for Pi runs. - command: ["pi", "--mode", "rpc", "{{BodyStripped}}"], + agent: { + provider: "anthropic", + model: "claude-opus-4-5", + thinkingDefault: "high", timeoutSeconds: 1800, - bodyPrefix: "/think:high ", - session: { - scope: "per-sender", - resetTriggers: ["/new"], - idleMinutes: 10080, - sendSystemOnce: true, - sessionIntro: "You are Clawd, a helpful space lobster assistant. Be concise for chat, save long output to files, and be careful with secrets." - }, // Start with 0; enable later. heartbeatMinutes: 0 + }, + session: { + scope: "per-sender", + resetTriggers: ["/new"], + idleMinutes: 10080, + mainKey: "main" } } } @@ -159,17 +155,15 @@ Example: ## Heartbeats (proactive mode) -When `heartbeatMinutes > 0`, CLAWDIS periodically runs a heartbeat prompt (default: `HEARTBEAT /think:high`). +When `inbound.agent.heartbeatMinutes > 0`, CLAWDIS periodically runs a heartbeat prompt (default: `HEARTBEAT`). - If the agent replies with `HEARTBEAT_OK` (exact token), CLAWDIS suppresses outbound delivery for that heartbeat. -- If you want a special command for heartbeats, set `inbound.reply.heartbeatCommand`. ```json5 { inbound: { - reply: { - heartbeatMinutes: 30, - heartbeatCommand: ["pi", "--mode", "rpc", "HEARTBEAT /think:high"] + agent: { + heartbeatMinutes: 30 } } } diff --git a/docs/configuration.md b/docs/configuration.md index 29b078c00..fb51a7d1f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -8,18 +8,20 @@ read_when: CLAWDIS reads an optional **JSON5** config from `~/.clawdis/clawdis.json` (comments + trailing commas allowed). -If the file is missing, CLAWDIS uses safe-ish defaults (bundled Pi in RPC mode + per-sender sessions). 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`) - tune group mention behavior (`inbound.groupChat`) -- customize the agent command (`inbound.reply.command`) - - set the agent’s identity (`identity`) +- set the agent’s workspace (`inbound.workspace`) +- tune the embedded agent (`inbound.agent`) and session behavior (`inbound.session`) +- set the agent’s identity (`identity`) ## Minimal config (recommended starting point) ```json5 { inbound: { - allowFrom: ["+15555550123"] + allowFrom: ["+15555550123"], + workspace: "~/clawd" } } ``` @@ -33,7 +35,6 @@ Optional agent identity used for defaults and UX. This is written by the macOS o If set, CLAWDIS derives defaults (only when you haven’t set them explicitly): - `inbound.responsePrefix` from `identity.emoji` - `inbound.groupChat.mentionPatterns` from `identity.name` (so “@Samantha” works in groups) -- `inbound.reply.session.sessionIntro` when `inbound.reply` is present (and for default Pi runs) ```json5 { @@ -78,58 +79,57 @@ Group messages default to **require mention** (either metadata mention or regex } ``` -### `inbound.reply` +### `inbound.workspace` -Controls how CLAWDIS produces replies. Two modes: -- `mode: "text"` — static reply from config (useful for testing) -- `mode: "command"` — run a local command and use its stdout as the reply (typical) +Sets the **single global workspace directory** used by the agent for file operations. -If you **omit** `inbound.reply`, CLAWDIS defaults to the bundled Pi binary in **RPC** mode: -- command (base): `pi --mode rpc {{BodyStripped}}` -- per-sender sessions + `/new` resets +Default: `~/clawd`. -Safety default: when invoking Pi, CLAWDIS always passes `--provider` and `--model` (unless you already specified them). +```json5 +{ + inbound: { workspace: "~/clawd" } +} +``` -Example command-mode config: +### `inbound.agent` + +Controls the embedded agent runtime (provider/model/thinking/verbose/timeouts). ```json5 { inbound: { - // Preferred: the agent workspace directory (used as default cwd for agent runs; supports ~). - workspace: "~/.clawdis/workspace", - reply: { - mode: "command", - // Example: run the bundled agent (Pi) in RPC mode - command: ["pi", "--mode", "rpc", "{{BodyStripped}}"], - // Optional override: working directory for this reply command (supports ~). - // If omitted, `inbound.workspace` is used. - cwd: "~/.clawdis/workspace", - timeoutSeconds: 1800, + workspace: "~/clawd", + agent: { + provider: "anthropic", + model: "claude-opus-4-5", + thinkingDefault: "low", + verboseDefault: "off", + timeoutSeconds: 600, + mediaMaxMb: 5, heartbeatMinutes: 30, - // Optional: override the command used for heartbeat runs - heartbeatCommand: ["pi", "--mode", "rpc", "HEARTBEAT /think:high"], - session: { - scope: "per-sender", - idleMinutes: 10080, - resetTriggers: ["/new"], - sessionIntro: "You are Clawd. Be a good lobster." - }, - agent: { - kind: "pi", - format: "json", - // Only used for status/usage labeling (Pi may report its own model) - provider: "anthropic", - model: "claude-opus-4-5", - contextTokens: 200000 - } + contextTokens: 200000 } } } ``` -Notes: -- `inbound.workspace` sets the default working directory for agent runs (supports `~` and is resolved to an absolute path). -- `inbound.reply.cwd` overrides the working directory for that specific reply command. +### `inbound.session` + +Controls session scoping, idle expiry, reset triggers, and where the session store is written. + +```json5 +{ + inbound: { + session: { + scope: "per-sender", + idleMinutes: 60, + resetTriggers: ["/new"], + store: "~/.clawdis/sessions/sessions.json", + mainKey: "main" + } + } +} +``` ### `browser` (clawd-managed Chrome) @@ -156,7 +156,7 @@ Defaults: ## Template variables -Template placeholders are expanded in `inbound.reply.command`, `sessionIntro`, `bodyPrefix`, and other templated strings. +Template placeholders are expanded in `inbound.transcribeAudio.command` (and any future templated command fields). | Variable | Description | |----------|-------------| @@ -193,5 +193,5 @@ Cron is a Gateway-owned scheduler for wakeups and scheduled jobs. See [Cron + wa --- -*Next: [Agent Integration](./agents.md)* 🦞 +*Next: [Agent Runtime](./agent.md)* 🦞 diff --git a/docs/cron.md b/docs/cron.md index 1d3b34a1e..5c9b23713 100644 --- a/docs/cron.md +++ b/docs/cron.md @@ -14,7 +14,7 @@ Last updated: 2025-12-13 ## Context Clawdis already has: -- A **periodic reply heartbeat** that runs the agent with `HEARTBEAT /think:high` and suppresses `HEARTBEAT_OK` (`src/web/auto-reply.ts`). +- A **periodic reply heartbeat** that runs the agent with `HEARTBEAT` and suppresses `HEARTBEAT_OK` (`src/web/auto-reply.ts`). - A lightweight, in-memory **system event queue** (`enqueueSystemEvent`) that is injected into the next **main session** turn (`drainSystemEvents` in `src/auto-reply/reply.ts`). - A WebSocket **Gateway** daemon that is intended to be always-on (`docs/gateway.md`). diff --git a/docs/heartbeat.md b/docs/heartbeat.md index 2b97b2e2b..1d37d1346 100644 --- a/docs/heartbeat.md +++ b/docs/heartbeat.md @@ -5,16 +5,16 @@ read_when: --- # Heartbeat polling plan (2025-11-26) -Goal: add a simple heartbeat poll for command-based auto-replies (Pi) that only notifies users when something matters, using the `HEARTBEAT_OK` sentinel. The heartbeat body we send is `HEARTBEAT /think:high` so the model can easily spot it. +Goal: add a simple heartbeat poll for the embedded agent that only notifies users when something matters, using the `HEARTBEAT_OK` sentinel. The heartbeat body we send is `HEARTBEAT` so the model can easily spot it. ## Prompt contract -- Extend the Pi system/identity text to explain: “If this is a heartbeat poll and nothing needs attention, reply exactly `HEARTBEAT_OK` and nothing else. For any alert, do **not** include `HEARTBEAT_OK`; just return the alert text.” Heartbeat prompt body is `HEARTBEAT /think:high`. +- Extend the agent system prompt to explain: “If this is a heartbeat poll and nothing needs attention, reply exactly `HEARTBEAT_OK` and nothing else. For any alert, do **not** include `HEARTBEAT_OK`; just return the alert text.” Heartbeat prompt body is `HEARTBEAT`. - Keep existing WhatsApp length guidance; forbid burying the sentinel inside alerts. ## Config & defaults -- New config key: `inbound.reply.heartbeatMinutes` (number of minutes; `0` or undefined disables). -- Default: 30 minutes when a command-mode reply is configured. -- New optional idle override for heartbeats: `inbound.reply.session.heartbeatIdleMinutes` (defaults to `idleMinutes`). Heartbeat skips do **not** update the session `updatedAt` so idle expiry still works. +- New config key: `inbound.agent.heartbeatMinutes` (number of minutes; `0` disables). +- 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. ## Poller behavior - When gateway runs with command-mode auto-reply, start a timer with the resolved heartbeat interval. diff --git a/docs/images.md b/docs/images.md index 45007ee76..5d37c3fd7 100644 --- a/docs/images.md +++ b/docs/images.md @@ -21,7 +21,7 @@ CLAWDIS is now **web-only** (Baileys). This document captures the current media ## Web Provider Behavior - Input: local file path **or** HTTP(S) URL. - Flow: load into a Buffer, detect media kind, and build the correct payload: - - **Images:** resize & recompress to JPEG (max side 2048px) targeting `inbound.reply.mediaMaxMb` (default 5 MB), capped at 6 MB. + - **Images:** resize & recompress to JPEG (max side 2048px) targeting `inbound.agent.mediaMaxMb` (default 5 MB), capped at 6 MB. - **Audio/Voice/Video:** pass-through up to 16 MB; audio is sent as a voice note (`ptt: true`). - **Documents:** anything else, up to 100 MB, with filename preserved when available. - MIME detection prefers magic bytes, then headers, then file extension. diff --git a/docs/mac/webchat.md b/docs/mac/webchat.md index 78b6b0641..55d93e837 100644 --- a/docs/mac/webchat.md +++ b/docs/mac/webchat.md @@ -5,7 +5,7 @@ read_when: --- # Web Chat (macOS app) -The macOS menu bar app embeds the WebChat UI in a WKWebView and reuses the **primary Clawd session** (`main` by default, configurable via `inbound.reply.session.mainKey`). +The macOS menu bar app embeds the WebChat UI in a WKWebView and reuses the **primary Clawd session** (`main` by default, configurable via `inbound.session.mainKey`). - **Local mode**: loads the gateway’s loopback WebChat HTTP server (default port 18788, see `webchat.port`). - **Remote mode**: serves the WebChat assets locally from the mac app bundle (via `WebChatServer`) and only forwards the gateway WebSocket control port over SSH. diff --git a/docs/session.md b/docs/session.md index d389d1093..9279fa850 100644 --- a/docs/session.md +++ b/docs/session.md @@ -5,7 +5,7 @@ read_when: --- # 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.reply.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 `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. ## 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. @@ -25,7 +25,7 @@ All session state is **owned by the gateway** (the “master” Clawdis). UI cli - Group chats still isolate state with `group:` keys; do not reuse the primary key for groups. ## Lifecyle -- Idle expiry: `inbound.reply.session.idleMinutes` (default 60). After the timeout a new `sessionId` is minted on the next message. +- Idle expiry: `inbound.session.idleMinutes` (default 60). After the timeout a new `sessionId` is minted on the next message. - Reset triggers: exact `/new` (plus any extras in `resetTriggers`) start a fresh session id and pass the remainder of the message through. - 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 // ~/.clawdis/clawdis.json { inbound: { - reply: { - session: { - scope: "per-sender", // keep group keys separate - idleMinutes: 120, - resetTriggers: ["/new"], - store: "~/.clawdis/sessions/sessions.json", - mainKey: "main" // optional rename; still a single primary - } + session: { + scope: "per-sender", // keep group keys separate + idleMinutes: 120, + resetTriggers: ["/new"], + store: "~/.clawdis/sessions/sessions.json", + mainKey: "main" // optional rename; still a single primary } } } diff --git a/docs/thinking.md b/docs/thinking.md index c2a1aefc4..355a97ab3 100644 --- a/docs/thinking.md +++ b/docs/thinking.md @@ -17,7 +17,7 @@ read_when: ## Resolution order 1. Inline directive on the message (applies only to that message). 2. Session override (set by sending a directive-only message). -3. Global default (`inbound.reply.thinkingDefault` in config). +3. Global default (`inbound.agent.thinkingDefault` in config). 4. Fallback: off. ## Setting a session default @@ -26,7 +26,7 @@ read_when: - Confirmation reply is sent (`Thinking level set to high.` / `Thinking disabled.`). If the level is invalid (e.g. `/thinking big`), the command is rejected with a hint and the session state is left unchanged. ## Application by agent -- **Pi**: injects `--thinking ` (skipped for `off`). Other agent paths have been removed. +- **Embedded Pi**: the resolved level is passed to the in-process Pi agent runtime. ## Verbose directives (/verbose or /v) - Levels: `on|full` or `off` (default). @@ -35,7 +35,7 @@ read_when: - When verbose is on, agents that emit structured tool results (Pi, other JSON agents) send each tool result back as its own metadata-only message, prefixed with `[🛠️ ]` when available (path/command); the tool output itself is not forwarded. ## Heartbeats -- Heartbeat probe body is `HEARTBEAT /think:high`, so it always asks for max thinking on the probe. Inline directive wins; session/global defaults are used only when no directive is present. +- Heartbeat probe body is `HEARTBEAT`. Inline directives in a heartbeat message apply as usual (but avoid changing session defaults from heartbeats). ## Web chat UI - The web chat thinking selector mirrors the session's stored level from the inbound session store/config when the page loads.