Files
Dirigent/README.md
hzhang 32dc9a4233 refactor: new design — sidecar services, moderator Gateway client, tool execute API
- Replace standalone no-reply-api Docker service with unified sidecar (services/main.mjs)
  that routes /no-reply/* and /moderator/* and starts/stops with openclaw-gateway
- Add moderator Discord Gateway client (services/moderator/index.mjs) for real-time
  MESSAGE_CREATE push instead of polling; notifies plugin via HTTP callback
- Add plugin HTTP routes (plugin/web/dirigent-api.ts) for moderator → plugin callbacks
  (wake-from-dormant, interrupt tail-match)
- Fix tool registration format: AgentTool requires execute: not handler:; factory form
  for tools needing ctx
- Rename no-reply-process.ts → sidecar-process.ts, startNoReplyApi → startSideCar
- Remove dead config fields from openclaw.plugin.json (humanList, agentList, listMode,
  channelPoliciesFile, endSymbols, waitIdentifier, multiMessage*, bypassUserIds, etc.)
- Rename noReplyPort → sideCarPort
- Remove docker-compose.yml, dev-up/down scripts, package-plugin.mjs, test-no-reply-api.mjs
- Update install.mjs: clean dist before build, copy services/, drop dead config writes
- Update README, Makefile, smoke script for new architecture

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 08:07:59 +01:00

118 lines
4.2 KiB
Markdown

# Dirigent
Turn-management and moderation plugin for OpenClaw (Discord).
> Formerly known as WhisperGate. Renamed to Dirigent in v0.2.0.
## What it does
Dirigent adds deterministic routing and **turn-based speaking** for multi-agent Discord channels:
- **Rule gate (`before_model_resolve`)**
- Non-speaker agents → routed to no-reply model (silent turn)
- Dormant channels → all agents suppressed until a human message wakes them
- Configurable per-channel mode: `chat`, `work`, `discussion`, `report`, `none`
- **Turn management**
- Only the current speaker responds; others are silenced
- Turn advances when the current speaker ends with a configured symbol or returns `NO_REPLY`
- Full round of silence → channel enters **dormant** state
- Human message → wakes dormant channel, triggers first speaker
- **Moderator bot sidecar**
- Dedicated Discord Gateway connection (separate bot token) for real-time message push
- Sends schedule-trigger messages (`<@USER_ID>➡️`) to signal speaker turns
- Notifies the plugin via HTTP callback on new messages (wake/interrupt)
- **Discussion mode**
- Agents can initiate a structured discussion via `create-discussion-channel` tool
- Initiator calls `discussion-complete` to conclude; summary is posted to the callback channel
- **Channel management tools**
- `create-chat-channel`, `create-work-channel`, `create-report-channel` — create typed channels
- `create-discussion-channel`, `discussion-complete` — discussion lifecycle
- `dirigent-register` — register an agent identity
---
## Repo layout
```
plugin/ OpenClaw plugin (hooks, tools, commands, web UI)
core/ Channel store, identity registry, moderator REST helpers
hooks/ before_model_resolve, agent_end, message_received
tools/ Agent-facing tools
commands/ Slash commands
web/ Control page + Dirigent API (HTTP routes)
services/ Sidecar process — spawned automatically by the plugin
main.mjs Unified entry point, routes /no-reply/* and /moderator/*
no-reply-api/ OpenAI-compatible server that always returns NO_REPLY
moderator/ Discord Gateway client + HTTP control endpoints
scripts/ Dev helpers
docs/ Architecture and integration notes
```
---
## Installation
```bash
node scripts/install.mjs --install
```
This copies `plugin/` and `services/` into the OpenClaw plugin directory and registers skills.
---
## Sidecar
The sidecar (`services/main.mjs`) is spawned automatically when openclaw-gateway starts. It exposes:
| Path prefix | Description |
|---|---|
| `/no-reply/*` | No-reply model API (`/v1/chat/completions`, `/v1/responses`) |
| `/moderator/*` | Moderator bot control (`/send`, `/create-channel`, `/me`, …) |
| `/health` | Combined health check |
Port is configured via `sideCarPort` (default `8787`).
Smoke-test after gateway start:
```bash
make smoke
# or:
./scripts/smoke-no-reply-api.sh
```
---
## Plugin config
Key options (in `openclaw.json` under `plugins.entries.dirigent.config`):
| Key | Default | Description |
|---|---|---|
| `moderatorBotToken` | — | Discord bot token for the moderator/sidecar bot |
| `scheduleIdentifier` | `➡️` | Symbol appended to schedule-trigger mentions |
| `listMode` | `human-list` | `human-list` or `agent-list` |
| `humanList` | `[]` | Discord user IDs treated as humans (bypass turn gate) |
| `agentList` | `[]` | Discord user IDs treated as agents (when `listMode=agent-list`) |
| `noReplyProvider` | `dirigent` | Provider ID for the no-reply model |
| `noReplyModel` | `no-reply` | Model ID for the no-reply model |
| `sideCarPort` | `8787` | Port the sidecar listens on |
| `debugMode` | `false` | Enable verbose debug logging |
| `debugLogChannelIds` | `[]` | Channel IDs that receive debug log messages |
| `channelPoliciesFile` | `~/.openclaw/dirigent-channel-policies.json` | Per-channel policy overrides |
---
## Dev commands
```bash
make check # TypeScript check (plugin/)
make check-rules # Validate rule-case fixtures
make check-files # Verify required files exist
make smoke # Smoke-test no-reply endpoint (sidecar must be running)
make install # Install plugin + sidecar into OpenClaw
```