# Dirigent Plugin ## Hook strategy - `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 end-marker instruction + scheduling identifier instruction when decision allows speaking. ## Rules (in order) 1. non-discord -> skip 2. bypass sender -> skip 3. end symbol matched -> skip 4. else -> no-reply override ## Config See `docs/CONFIG.example.json`. Required: - `noReplyProvider` - `noReplyModel` Optional: - `enabled` (default true) - `discordOnly` (default true) - `listMode` (`human-list` | `agent-list`, default `human-list`) - `humanList` (default []) - `agentList` (default []) - `channelPoliciesFile` (per-channel overrides in a standalone JSON file) - `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) - Discord control actions are executed in-plugin via Discord REST API (no `discordControlApiBaseUrl` needed) - `discordControlApiToken` - `discordControlCallerId` - `enableDebugLogs` (default false) - `debugLogChannelIds` (default [], empty = all channels when debug enabled) Per-channel policy file example: `docs/channel-policies.example.json`. Policy file behavior: - loaded once on startup into memory - runtime decisions read memory state only - direct file edits do NOT affect memory state - `dirigent_tools` policy actions update memory first, then persist to file (atomic write) ## Moderator handoff format When the current speaker NO_REPLYs, the moderator bot sends: `<@NEXT_USER_ID>➡️` 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