diff --git a/FEAT.md b/FEAT.md new file mode 100644 index 0000000..9d4792d --- /dev/null +++ b/FEAT.md @@ -0,0 +1,107 @@ +# Dirigent — Feature List + +All implemented features across all versions. + +--- + +## Core: Rule-Based No-Reply Gate +- Deterministic logic in `before_model_resolve` hook decides whether to route to no-reply model +- **human-list** mode: humanList senders bypass gate; others need end symbol to pass +- **agent-list** mode: agentList senders need end symbol; others bypass +- Non-Discord messages skip entirely +- DM sessions (no metadata) always bypass +- Per-channel policy overrides via JSON file (runtime-updateable) + +## Core: End-Symbol Enforcement +- Injects prompt instruction: "Your response MUST end with 🔚" +- Gateway keywords (NO_REPLY, HEARTBEAT_OK) exempt from end symbol +- Group chats get additional rule: "If not relevant, reply NO_REPLY" +- End symbols configurable per-channel via policy + +## Core: No-Reply API +- OpenAI-compatible API (`/v1/chat/completions`, `/v1/responses`, `/v1/models`) +- Always returns `NO_REPLY` — used as the override model target +- Optional bearer auth (`AUTH_TOKEN`) +- Auto-started/stopped with gateway lifecycle + +## Turn-Based Speaking (Multi-Bot) +- Only the current speaker is allowed to respond; others forced to no-reply model +- Turn order auto-populated from bot accounts seen in each channel +- Turn advances on end-symbol (successful speech) or NO_REPLY +- Successful speech resets NO_REPLY cycle counter +- If all bots NO_REPLY in a cycle → channel goes **dormant** +- Dormant reactivation: human message → first in order; bot message → next after sender +- Turn timeout: auto-advance after 60s of inactivity +- Manual control: `/dirigent turn-status`, `/dirigent turn-advance`, `/dirigent turn-reset` + +## Human @Mention Override *(v0.3.0)* +- When a `humanList` user @mentions specific agents (`<@USER_ID>`): + - Extracts mentioned Discord user IDs from message content + - Maps userIds → accountIds via reverse bot token lookup + - Filters to agents in the current turn order + - Orders by their position in the current turn order + - Temporarily replaces speaking order with only those agents + - Cycle: a → b → c → (back to a) → restore original order, go dormant +- Edge cases: + - All override agents NO_REPLY → restore + dormant + - `resetTurn` clears any active override + - Human message without mentions → restores override, normal flow + - Mentioned users not in turn order → ignored + +## Agent Identity Injection +- Group chat prompts include: agent name, Discord accountId, Discord userId +- userId resolved from bot token (base64 first segment) + +## Scheduling Identifier +- Configurable identifier (default: `➡️`) used for moderator handoff +- Handoff format: `<@TARGET_USER_ID>➡️` (non-semantic scheduling signal) +- Agent prompt explains: identifier is meaningless — check chat history, decide whether to reply +- If nothing to say → NO_REPLY + +## Moderator Bot Presence +- Maintains Discord Gateway WebSocket connection for moderator bot +- Shows "online" status with "Moderating" activity +- Handles reconnect, resume, heartbeat, invalid session recovery +- Singleton guard prevents duplicate connections +- Sends handoff messages to trigger next speaker's turn + +## Individual Tools *(v0.3.0)* +Nine standalone tools (split from former monolithic `dirigent_tools`): + +### Discord Control +- **`dirigent_channel_create`** — Create private Discord channel with user/role permissions +- **`dirigent_channel_update`** — Update permissions on existing private channel +- **`dirigent_member_list`** — List guild members with pagination and field projection + +### Policy Management +- **`dirigent_policy_get`** — Get all channel policies +- **`dirigent_policy_set`** — Set/update a channel policy (listMode, humanList, agentList, endSymbols) +- **`dirigent_policy_delete`** — Delete a channel policy + +### Turn Management +- **`dirigent_turn_status`** — Show turn state (order, current speaker, dormant status, override info) +- **`dirigent_turn_advance`** — Manually advance to next speaker +- **`dirigent_turn_reset`** — Reset turn order (go dormant, clear overrides) + +## Slash Command: `/dirigent` +- `status` — Show all channel policies +- `turn-status` — Show turn state for current channel +- `turn-advance` — Manually advance turn +- `turn-reset` — Reset turn order + +## Project Rename (WhisperGate → Dirigent) *(v0.2.0)* +- All plugin ids, tool names, config keys, file paths, docs updated +- Legacy `whispergate` config key still supported as fallback + +## Installer Script +- `scripts/install-dirigent-openclaw.mjs` +- `--install` / `--uninstall` with delta-tracking +- Auto-reinstall (uninstall + install) if already installed +- Backup before changes, rollback on failure +- Records stored in `~/.openclaw/dirigent-install-records/` + +## Discord Control API (Sidecar) +- Private channel create/update with permission overwrites +- Member list with pagination + field projection +- Guardrails: action validation, id-list limits, response-size limit +- Runs as optional companion service (`discord-control-api/`) diff --git a/NEW_FEAT.md b/NEW_FEAT.md deleted file mode 100644 index bda8407..0000000 --- a/NEW_FEAT.md +++ /dev/null @@ -1,4 +0,0 @@ -# New Features - -1. 拆分 dirigent-tools:不再用一个主工具管理多个小工具。 ✅ -2. 人类@规则:当来自 humanList 的用户消息包含 <@USER_ID> 时,按被 @ 的 agent 顺序临时覆盖 speaking order 循环;回到首个 agent 后恢复原顺序。 ✅ diff --git a/README.md b/README.md index 0a614f6..50796fb 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,17 @@ Dirigent adds deterministic logic **before model selection** and **turn-based sp - **Agent identity injection** - Injects agent name, Discord accountId, and Discord userId into group chat prompts +- **Human @mention override** + - When a `humanList` user @mentions agents, temporarily overrides turn order + - Only mentioned agents cycle; original order restores when cycle completes + - **Per-channel policy runtime** - Policies stored in a standalone JSON file - - Update at runtime via `dirigent_tools` (memory first → persist to file) + - Update at runtime via `dirigent_policy_set` / `dirigent_policy_delete` tools - **Discord control actions (optional)** - Private channel create/update + member list - - Unified via `dirigent_tools` + - Via `dirigent_channel_create`, `dirigent_channel_update`, `dirigent_member_list` tools --- @@ -74,12 +78,24 @@ Discord extension capabilities: `docs/DISCORD_CONTROL.md`. ## Runtime tools & commands -### Tool: `dirigent_tools` +### Tools (9 individual tools) -Actions: -- `policy-get`, `policy-set-channel`, `policy-delete-channel` -- `turn-status`, `turn-advance`, `turn-reset` -- `channel-private-create`, `channel-private-update`, `member-list` +**Discord control:** +- `dirigent_channel_create` — Create private channel +- `dirigent_channel_update` — Update channel permissions +- `dirigent_member_list` — List guild members + +**Policy management:** +- `dirigent_policy_get` — Get all policies +- `dirigent_policy_set` — Set/update channel policy +- `dirigent_policy_delete` — Delete channel policy + +**Turn management:** +- `dirigent_turn_status` — Show turn state +- `dirigent_turn_advance` — Advance turn +- `dirigent_turn_reset` — Reset turn order + +> See `FEAT.md` for full feature documentation. ### Slash command (Discord)