refine: cleanup remaining whispergate refs, improve docs and TASKLIST formatting

- Fix enableWhispergatePolicyTool → enableDirigentPolicyTool in config schema and example
- Fix whisper-gateway → dirigentway in install script
- Add v0.2.0 changelog entry
- Improve README with scheduling identifier docs and English text
- Clean up plugin README with moderator handoff format docs
- Reformat TASKLIST with cleaner done markers
This commit is contained in:
zhi
2026-03-03 10:13:39 +00:00
parent af33d747d9
commit fd1bf449a4
7 changed files with 75 additions and 59 deletions

View File

@@ -1,10 +1,21 @@
# Changelog
## 0.2.0
- **Project renamed from WhisperGate to Dirigent**
- All plugin ids, tool names, config keys, file paths, docs updated
- Legacy `whispergate` config key still supported as fallback
- **Identity prompt enhancements**: Discord userId now included in agent identity injection
- **Scheduling identifier**: Added configurable `schedulingIdentifier` (default: `➡️`)
- Moderator handoff now sends `<@USER_ID>➡️` instead of semantic messages
- Agent prompt explains the identifier is meaningless — check chat history and decide
- **All prompts in English**: End-marker instructions, group chat rules, slash command help text
## 0.1.0-mvp
- Added no-reply API service (`/v1/chat/completions`, `/v1/responses`, `/v1/models`)
- Added optional bearer auth (`AUTH_TOKEN`)
- Added Dirigent plugin with deterministic rule gate
- Added plugin with deterministic rule gate
- Added discord-specific 🔚 prompt injection for bypass/end-symbol paths
- Added containerization (`Dockerfile`, `docker-compose.yml`)
- Added helper scripts for smoke/dev lifecycle and rule validation

View File

@@ -2,6 +2,8 @@
Rule-based no-reply gate + turn manager for OpenClaw (Discord).
> Formerly known as WhisperGate. Renamed to Dirigent in v0.2.0.
## What it does
Dirigent adds deterministic logic **before model selection** and **turn-based speaking** for multi-agent Discord channels:
@@ -13,8 +15,13 @@ Dirigent adds deterministic logic **before model selection** and **turn-based sp
4. Otherwise → route to no-reply model/provider
- **End-symbol enforcement**
- Injects instruction like: `你的这次发言必须以🔚作为结尾…`
- In group chats, also injects: “无关/不需要回应就 NO_REPLY
- Injects instruction: `Your response MUST end with 🔚…`
- In group chats, also injects: "If not relevant, reply NO_REPLY"
- **Scheduling identifier (moderator handoff)**
- Configurable identifier (default: `➡️`) used by the moderator bot
- Handoff format: `<@TARGET_USER_ID>➡️` (non-semantic, just a scheduling signal)
- Agent receives instruction explaining the identifier is meaningless — check chat history and decide
- **Turn-based speaking (multi-bot)**
- Only the current speaker is allowed to respond
@@ -22,8 +29,8 @@ Dirigent adds deterministic logic **before model selection** and **turn-based sp
- Turn advances on **end-symbol** or **NO_REPLY**
- If all bots NO_REPLY, channel becomes **dormant** until a new human message
- **Moderator handoff (optional)**
- When the current speaker NO_REPLYs, a moderator bot can post a handoff message to wake the next speaker
- **Agent identity injection**
- Injects agent name, Discord accountId, and Discord userId into group chat prompts
- **Per-channel policy runtime**
- Policies stored in a standalone JSON file
@@ -39,7 +46,7 @@ Dirigent adds deterministic logic **before model selection** and **turn-based sp
- `plugin/` — OpenClaw plugin (gate + turn manager + moderator presence)
- `no-reply-api/` — OpenAI-compatible API that always returns `NO_REPLY`
- `discord-control-api/` — Discord 管理扩展 API私密频道 + 成员列表)
- `discord-control-api/` — Discord admin extension API (private channels + member list)
- `docs/` — rollout, integration, run-mode notes, turn-wakeup analysis
- `scripts/` — smoke/dev/helper checks
- `Makefile` — common dev commands (`make check`, `make check-rules`, `make test-api`, `make smoke-discord-control`, `make up`)
@@ -61,7 +68,7 @@ node scripts/render-openclaw-config.mjs
```
See `docs/RUN_MODES.md` for Docker mode.
Discord 扩展能力见:`docs/DISCORD_CONTROL.md`
Discord extension capabilities: `docs/DISCORD_CONTROL.md`.
---
@@ -92,6 +99,7 @@ Common options (see `docs/INTEGRATION.md`):
- `listMode`: `human-list` or `agent-list`
- `humanList`, `agentList`
- `endSymbols`
- `schedulingIdentifier` (default `➡️`)
- `channelPoliciesFile` (per-channel overrides)
- `moderatorBotToken` (handoff messages)
- `enableDebugLogs`, `debugLogChannelIds`

View File

@@ -2,48 +2,42 @@
> Note: Project rename from WhisperGate → Dirigent implies updating all code/docs references (plugin/tool names, strings, files, configs).
## 1) Identity Prompt Enhancements
- ✅ Added Discord userId to identity injection via `resolveDiscordUserId()`.
- Identity format now: `You are <name> (Discord account: <accountId>, Discord userId: <userId>).`
## 1) Identity Prompt Enhancements
- Current prompt only includes agent-id + discord name.
- **Add Discord userId** to identity injection.
- **Done**: `buildAgentIdentity()` now resolves and includes Discord userId via `resolveDiscordUserId()`.
## 2) Scheduling Identifier (Default: ➡️)
- Added `schedulingIdentifier` config field (default: `➡️`) to `DirigentConfig` and `openclaw.plugin.json`.
- Updated `buildEndMarkerInstruction()` to explain scheduling identifier semantics to agents:
- The identifier itself is meaningless.
- When receiving `<@USER_ID>` + identifier, check chat history and decide whether to reply.
- If nothing to say, reply `NO_REPLY`.
## 2) Scheduling Identifier (Default: ➡️)
- Add a **configurable scheduling identifier** (default: `➡️`).
- Update agent prompt to explain:
- The scheduling identifier itself is meaningless.
- When receiving `<@USER_ID>` + scheduling identifier, the agent should check chat history and decide whether to reply.
- If no reply needed, return `NO_REPLY`.
- **Done**: Added `schedulingIdentifier` config field; `buildSchedulingIdentifierInstruction()` injected for group chats.
## 3) Moderator Handoff Message Format
- Moderator no longer sends semantic messages.
- Handoff format is now: `<@TARGET_USER_ID>` + scheduling identifier (e.g., `<@123>➡️`).
## 3) Moderator Handoff Message Format
- Moderator should **no longer send semantic messages** to activate agents.
- Replace with: `<@TARGET_USER_ID>` + scheduling identifier (e.g., `<@123>➡️`).
- **Done**: Both `before_message_write` and `message_sent` handoff messages now use `<@userId>` + scheduling identifier format.
## 4) Prompt Language
- All prompts converted to English:
- `buildEndMarkerInstruction()` — English with scheduling identifier explanation
- `buildAgentIdentity()` — English format
- Slash command help text — English
- Error messages — English
- Code comments — English
## 4) Prompt Language
- **All prompts must be in English** (including end-marker instructions and group-chat rules).
- **Done**: `buildEndMarkerInstruction()` and `buildSchedulingIdentifierInstruction()` output English. Slash command help text in English.
## 5) Full Project Rename
- ✅ Plugin id: `whispergate``dirigent`
- ✅ Plugin name: `WhisperGate``Dirigent`
- ✅ Tool name: `whispergate_tools``dirigent_tools`
- ✅ Config type: `WhisperGateConfig``DirigentConfig`
- ✅ Config lookup key: `entries.whispergate``entries.dirigent`
- ✅ Channel policies file: `whispergate-channel-policies.json``dirigent-channel-policies.json`
- ✅ Log prefixes: `whispergate:``dirigent:`
- ✅ Slash command: `/whispergate``/dirigent`
- ✅ Gateway browser/device identifier: `whispergate``dirigent`
- ✅ Scripts renamed: `install-whispergate-*` `install-dirigent-*`
- ✅ All docs, configs, examples updated
- ✅ dist/ folder: `dist/whispergate/``dist/dirigent/`
- ✅ package.json names updated
- ✅ README.md, CHANGELOG.md updated
- ✅ Version bumped to 0.2.0
## 5) Full Project Rename
- Project name changed to **Dirigent**.
- Update **all strings** across repo:
- plugin name/id`dirigent`
- tool name`dirigent_tools`
- slash command → `/dirigent`
- docs, config, scripts, examples
- any text mentions
- dist output dir`dist/dirigent`
- docker service → `dirigent-no-reply-api`
- config key fallback: still reads legacy `whispergate` entry if `dirigent` not found
- **Done**: All files updated.
---
## Open Items / Notes
- User requested the previous README commit should have been pushed to `main` directly (was pushed to a branch). Address separately if needed.
- **Migration note**: Existing deployments need to update their `openclaw.json` config from `plugins.entries.whispergate``plugins.entries.dirigent` and rename the channel policies file.

View File

@@ -17,7 +17,7 @@
"noReplyProvider": "dirigentway",
"noReplyModel": "no-reply",
"enableDiscordControlTool": true,
"enableWhispergatePolicyTool": true,
"enableDirigentPolicyTool": true,
"enableDebugLogs": false,
"debugLogChannelIds": [],
"discordControlApiBaseUrl": "http://127.0.0.1:8790",

View File

@@ -4,9 +4,7 @@
- `message:received` caches a per-session decision from deterministic rules.
- `before_model_resolve` applies `providerOverride + modelOverride` when decision says no-reply.
- `before_prompt_build` prepends instruction `你的这次发言必须以🔚作为结尾。` when decision is:
- `bypass_sender`
- `end_symbol:*`
- `before_prompt_build` prepends end-marker instruction + scheduling identifier instruction when decision allows speaking.
## Rules (in order)
@@ -30,12 +28,14 @@ Optional:
- `humanList` (default [])
- `agentList` (default [])
- `channelPoliciesFile` (per-channel overrides in a standalone JSON file)
- `enableWhispergatePolicyTool` (default true)
- `schedulingIdentifier` (default `➡️`) — moderator handoff identifier
- `enableDirigentPolicyTool` (default true)
Unified optional tool:
- `dirigent_tools`
- Discord actions: `channel-private-create`, `channel-private-update`, `member-list`
- Policy actions: `policy-get`, `policy-set-channel`, `policy-delete-channel`
- Turn actions: `turn-status`, `turn-advance`, `turn-reset`
- `bypassUserIds` (deprecated alias of `humanList`)
- `endSymbols` (default ["🔚"])
- `enableDiscordControlTool` (default true)
@@ -53,18 +53,21 @@ Policy file behavior:
- direct file edits do NOT affect memory state
- `dirigent_tools` policy actions update memory first, then persist to file (atomic write)
## Optional tool: `dirigent_tools`
## Moderator handoff format
This plugin registers one unified optional tool: `dirigent_tools`.
To use it, add tool allowlist entry for either:
- tool name: `dirigent_tools`
- plugin id: `dirigent`
When the current speaker NO_REPLYs, the moderator bot sends: `<@NEXT_USER_ID>➡️`
Supported actions:
- Discord: `channel-private-create`, `channel-private-update`, `member-list`
- Policy: `policy-get`, `policy-set-channel`, `policy-delete-channel`
This is a non-semantic scheduling message. The scheduling identifier (`➡️` by default) carries no meaning — it simply signals the next agent to check chat history and decide whether to speak.
## Slash command (Discord)
```
/dirigent status
/dirigent turn-status
/dirigent turn-advance
/dirigent turn-reset
```
Debug logging:
- set `enableDebugLogs: true` to emit detailed hook diagnostics
- optionally set `debugLogChannelIds` to only log selected channel IDs
- logs include key ctx fields + decision status at `message_received`, `before_model_resolve`, `before_prompt_build`

View File

@@ -20,7 +20,7 @@
"noReplyProvider": { "type": "string" },
"noReplyModel": { "type": "string" },
"enableDiscordControlTool": { "type": "boolean", "default": true },
"enableWhispergatePolicyTool": { "type": "boolean", "default": true },
"enableDirigentPolicyTool": { "type": "boolean", "default": true },
"discordControlApiBaseUrl": { "type": "string", "default": "http://127.0.0.1:8790" },
"discordControlApiToken": { "type": "string" },
"discordControlCallerId": { "type": "string" },

View File

@@ -15,7 +15,7 @@ const env = process.env;
const OPENCLAW_CONFIG_PATH = env.OPENCLAW_CONFIG_PATH || path.join(os.homedir(), ".openclaw", "openclaw.json");
const __dirname = path.dirname(new URL(import.meta.url).pathname);
const PLUGIN_PATH = env.PLUGIN_PATH || path.resolve(__dirname, "..", "dist", "dirigent");
const NO_REPLY_PROVIDER_ID = env.NO_REPLY_PROVIDER_ID || "whisper-gateway";
const NO_REPLY_PROVIDER_ID = env.NO_REPLY_PROVIDER_ID || "dirigentway";
const NO_REPLY_MODEL_ID = env.NO_REPLY_MODEL_ID || "no-reply";
const NO_REPLY_BASE_URL = env.NO_REPLY_BASE_URL || "http://127.0.0.1:8787/v1";
const NO_REPLY_API_KEY = env.NO_REPLY_API_KEY || "wg-local-test-token";