refactor(plugin): extract turn bootstrap/cache helpers into core module
This commit is contained in:
43
plugin/core/turn-bootstrap.ts
Normal file
43
plugin/core/turn-bootstrap.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||
import { initTurnOrder } from "../turn-manager.js";
|
||||
|
||||
const channelSeenAccounts = new Map<string, Set<string>>();
|
||||
|
||||
function getAllBotAccountIds(api: OpenClawPluginApi): string[] {
|
||||
const root = (api.config as Record<string, unknown>) || {};
|
||||
const bindings = root.bindings as Array<Record<string, unknown>> | undefined;
|
||||
if (!Array.isArray(bindings)) return [];
|
||||
const ids: string[] = [];
|
||||
for (const b of bindings) {
|
||||
const match = b.match as Record<string, unknown> | undefined;
|
||||
if (match?.channel === "discord" && typeof match.accountId === "string") {
|
||||
ids.push(match.accountId);
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
function getChannelBotAccountIds(api: OpenClawPluginApi, channelId: string): string[] {
|
||||
const allBots = new Set(getAllBotAccountIds(api));
|
||||
const seen = channelSeenAccounts.get(channelId);
|
||||
if (!seen) return [];
|
||||
return [...seen].filter((id) => allBots.has(id));
|
||||
}
|
||||
|
||||
export function recordChannelAccount(channelId: string, accountId: string): boolean {
|
||||
let seen = channelSeenAccounts.get(channelId);
|
||||
if (!seen) {
|
||||
seen = new Set();
|
||||
channelSeenAccounts.set(channelId, seen);
|
||||
}
|
||||
if (seen.has(accountId)) return false;
|
||||
seen.add(accountId);
|
||||
return true;
|
||||
}
|
||||
|
||||
export function ensureTurnOrder(api: OpenClawPluginApi, channelId: string): void {
|
||||
const botAccounts = getChannelBotAccountIds(api, channelId);
|
||||
if (botAccounts.length > 0) {
|
||||
initTurnOrder(channelId, botAccounts);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ import path from "node:path";
|
||||
import { spawn, type ChildProcess } from "node:child_process";
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
||||
import type { Decision, DirigentConfig } from "./rules.js";
|
||||
import { initTurnOrder } from "./turn-manager.js";
|
||||
import { startModeratorPresence, stopModeratorPresence } from "./moderator-presence.js";
|
||||
import { registerMessageReceivedHook } from "./hooks/message-received.js";
|
||||
import { registerBeforeModelResolveHook } from "./hooks/before-model-resolve.js";
|
||||
@@ -16,6 +15,7 @@ import { getLivePluginConfig } from "./core/live-config.js";
|
||||
import { ensurePolicyStateLoaded, persistPolicies, policyState } from "./policy/store.js";
|
||||
import { buildAgentIdentity, buildUserIdToAccountIdMap, resolveAccountId } from "./core/identity.js";
|
||||
import { extractMentionedUserIds, getModeratorUserId } from "./core/mentions.js";
|
||||
import { ensureTurnOrder, recordChannelAccount } from "./core/turn-bootstrap.js";
|
||||
|
||||
// ── No-Reply API child process lifecycle ──────────────────────────────
|
||||
let noReplyProcess: ChildProcess | null = null;
|
||||
@@ -110,66 +110,6 @@ function pruneDecisionMap(now = Date.now()) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Discord bot accountIds from config bindings.
|
||||
*/
|
||||
function getAllBotAccountIds(api: OpenClawPluginApi): string[] {
|
||||
const root = (api.config as Record<string, unknown>) || {};
|
||||
const bindings = root.bindings as Array<Record<string, unknown>> | undefined;
|
||||
if (!Array.isArray(bindings)) return [];
|
||||
const ids: string[] = [];
|
||||
for (const b of bindings) {
|
||||
const match = b.match as Record<string, unknown> | undefined;
|
||||
if (match?.channel === "discord" && typeof match.accountId === "string") {
|
||||
ids.push(match.accountId);
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Track which bot accountIds have been seen in each channel via message_received.
|
||||
* Key: channelId, Value: Set of accountIds seen.
|
||||
*/
|
||||
const channelSeenAccounts = new Map<string, Set<string>>();
|
||||
|
||||
/**
|
||||
* Record a bot accountId seen in a channel.
|
||||
* Returns true if this is a new account for this channel (turn order should be updated).
|
||||
*/
|
||||
function recordChannelAccount(channelId: string, accountId: string): boolean {
|
||||
let seen = channelSeenAccounts.get(channelId);
|
||||
if (!seen) {
|
||||
seen = new Set();
|
||||
channelSeenAccounts.set(channelId, seen);
|
||||
}
|
||||
if (seen.has(accountId)) return false;
|
||||
seen.add(accountId);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of bot accountIds seen in a channel.
|
||||
* Only returns accounts that are also in the global bindings (actual bots).
|
||||
*/
|
||||
function getChannelBotAccountIds(api: OpenClawPluginApi, channelId: string): string[] {
|
||||
const allBots = new Set(getAllBotAccountIds(api));
|
||||
const seen = channelSeenAccounts.get(channelId);
|
||||
if (!seen) return [];
|
||||
return [...seen].filter(id => allBots.has(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure turn order is initialized for a channel.
|
||||
* Uses only bot accounts that have been seen in this channel.
|
||||
*/
|
||||
function ensureTurnOrder(api: OpenClawPluginApi, channelId: string): void {
|
||||
const botAccounts = getChannelBotAccountIds(api, channelId);
|
||||
if (botAccounts.length > 0) {
|
||||
initTurnOrder(channelId, botAccounts);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Moderator bot helpers ---
|
||||
|
||||
/** Extract Discord user ID from a bot token (base64-encoded in first segment) */
|
||||
|
||||
Reference in New Issue
Block a user