docs: document embedded agent runtime

This commit is contained in:
Peter Steinberger
2025-12-17 11:29:12 +01:00
parent fece42ce0a
commit 1cdebb68a0
12 changed files with 143 additions and 252 deletions

View File

@@ -155,7 +155,7 @@ Optional: enable/configure clawds 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:<jid>`.
- Direct chats now share a canonical session key `main` by default (configurable via `inbound.session.mainKey`). Groups stay isolated as `group:<jid>`.
- WebChat attaches to `main` and hydrates history from `~/.clawdis/sessions/<SessionId>.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`:

View File

@@ -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 <text>`
- Session selection:
- If `--session-id` given, use it.
- Else if `--to <e164>` 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 <e164>` 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 <off|minimal|low|medium|high>` and `--verbose <on|off>`.
- Persist into session store (like directive-only flow) and inject into the command invocation.
- Flags `--thinking <off|minimal|low|medium|high>` and `--verbose <on|off>` persist into the session store.
- Output:
- Default: print the agents 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 <text>` (required)
- `--to, -t <e164>` (derive session)
- `--session-id <uuid>` (override)
- `--thinking <off|minimal|low|medium|high>`
- `--verbose <on|off>`
- `--json` (structured output)
- `--timeout <sec>` (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:<url>` lines) to stdout.
- `--json`: prints structured payloads + meta.
- Optional: `--deliver` sends the reply back to the selected provider (requires `--to` for WhatsApp).

48
docs/agent.md Normal file
View File

@@ -0,0 +1,48 @@
---
summary: "Agent runtime (embedded Pi), workspace contract, and session bootstrap"
read_when:
- Changing agent runtime, workspace bootstrap, or session behavior
---
<!-- {% raw %} -->
# 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 agents **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)
Pis 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; its guidance for how *you* want them used.
## Sessions
Session transcripts are stored as JSONL at:
- `~/.clawdis/sessions/<SessionId>.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)* 🦞
<!-- {% endraw %} -->

View File

@@ -1,109 +0,0 @@
---
summary: "Current agent integration: Pi as the sole coding agent with config examples"
read_when:
- Changing agent invocation or defaults
---
<!-- {% raw %} -->
# 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 dont 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 <url>` / `screenshot [targetId]`
- `clawdis browser snapshot --format ai` (returns an AI snapshot with `[ref=…]` ids)
- `clawdis browser click <ref>` (click by ref from an AI snapshot)
This uses a dedicated Chrome/Chromium profile (lobster-orange by default) so it doesnt 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)* 🦞
<!-- {% endraw %} -->

View File

@@ -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 Clawds “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 youll usually want to tune:
- session intro (personality + instructions)
CLAWDIS defaults to a good assistant setup, but youll 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
}
}
}

View File

@@ -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 agents identity (`identity`)
- set the agents workspace (`inbound.workspace`)
- tune the embedded agent (`inbound.agent`) and session behavior (`inbound.session`)
- set the agents 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 havent 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)* 🦞
<!-- {% endraw %} -->

View File

@@ -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`).

View File

@@ -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.

View File

@@ -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 5MB), capped at 6MB.
- **Images:** resize & recompress to JPEG (max side 2048px) targeting `inbound.agent.mediaMaxMb` (default 5MB), capped at 6MB.
- **Audio/Voice/Video:** pass-through up to 16MB; audio is sent as a voice note (`ptt: true`).
- **Documents:** anything else, up to 100MB, with filename preserved when available.
- MIME detection prefers magic bytes, then headers, then file extension.

View File

@@ -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 gateways 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.

View File

@@ -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:<jid>` 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
}
}
}

View File

@@ -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 <level>` (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 `[🛠️ <tool-name> <arg>]` 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.