mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 10:37:41 +00:00
refactor!: rename chat providers to channels
This commit is contained in:
@@ -16,7 +16,7 @@ export type ResolvedDiscordAccount = {
|
||||
};
|
||||
|
||||
function listConfiguredAccountIds(cfg: ClawdbotConfig): string[] {
|
||||
const accounts = cfg.discord?.accounts;
|
||||
const accounts = cfg.channels?.discord?.accounts;
|
||||
if (!accounts || typeof accounts !== "object") return [];
|
||||
return Object.keys(accounts).filter(Boolean);
|
||||
}
|
||||
@@ -37,7 +37,7 @@ function resolveAccountConfig(
|
||||
cfg: ClawdbotConfig,
|
||||
accountId: string,
|
||||
): DiscordAccountConfig | undefined {
|
||||
const accounts = cfg.discord?.accounts;
|
||||
const accounts = cfg.channels?.discord?.accounts;
|
||||
if (!accounts || typeof accounts !== "object") return undefined;
|
||||
return accounts[accountId] as DiscordAccountConfig | undefined;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ function mergeDiscordAccountConfig(
|
||||
cfg: ClawdbotConfig,
|
||||
accountId: string,
|
||||
): DiscordAccountConfig {
|
||||
const { accounts: _ignored, ...base } = (cfg.discord ??
|
||||
const { accounts: _ignored, ...base } = (cfg.channels?.discord ??
|
||||
{}) as DiscordAccountConfig & { accounts?: unknown };
|
||||
const account = resolveAccountConfig(cfg, accountId) ?? {};
|
||||
return { ...base, ...account };
|
||||
@@ -57,7 +57,7 @@ export function resolveDiscordAccount(params: {
|
||||
accountId?: string | null;
|
||||
}): ResolvedDiscordAccount {
|
||||
const accountId = normalizeAccountId(params.accountId);
|
||||
const baseEnabled = params.cfg.discord?.enabled !== false;
|
||||
const baseEnabled = params.cfg.channels?.discord?.enabled !== false;
|
||||
const merged = mergeDiscordAccountConfig(params.cfg, accountId);
|
||||
const accountEnabled = merged.enabled !== false;
|
||||
const enabled = baseEnabled && accountEnabled;
|
||||
|
||||
@@ -11,16 +11,18 @@ describe("discord audit", () => {
|
||||
const { fetchChannelPermissionsDiscord } = await import("./send.js");
|
||||
|
||||
const cfg = {
|
||||
discord: {
|
||||
enabled: true,
|
||||
token: "t",
|
||||
groupPolicy: "allowlist",
|
||||
guilds: {
|
||||
"123": {
|
||||
channels: {
|
||||
"111": { allow: true },
|
||||
general: { allow: true },
|
||||
"222": { allow: false },
|
||||
channels: {
|
||||
discord: {
|
||||
enabled: true,
|
||||
token: "t",
|
||||
groupPolicy: "allowlist",
|
||||
guilds: {
|
||||
"123": {
|
||||
channels: {
|
||||
"111": { allow: true },
|
||||
general: { allow: true },
|
||||
"222": { allow: false },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -20,9 +20,9 @@ vi.mock("../auto-reply/reply/dispatch-from-config.js", () => ({
|
||||
dispatchReplyFromConfig: (...args: unknown[]) => dispatchMock(...args),
|
||||
}));
|
||||
vi.mock("../pairing/pairing-store.js", () => ({
|
||||
readProviderAllowFromStore: (...args: unknown[]) =>
|
||||
readChannelAllowFromStore: (...args: unknown[]) =>
|
||||
readAllowFromStoreMock(...args),
|
||||
upsertProviderPairingRequest: (...args: unknown[]) =>
|
||||
upsertChannelPairingRequest: (...args: unknown[]) =>
|
||||
upsertPairingRequestMock(...args),
|
||||
}));
|
||||
vi.mock("../config/sessions.js", async (importOriginal) => {
|
||||
@@ -61,13 +61,13 @@ describe("discord tool result dispatch", () => {
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
messages: { responsePrefix: "PFX" },
|
||||
discord: { dm: { enabled: true, policy: "open" } },
|
||||
channels: { discord: { dm: { enabled: true, policy: "open" } } },
|
||||
} as ReturnType<typeof import("../config/config.js").loadConfig>;
|
||||
|
||||
const runtimeError = vi.fn();
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
@@ -130,12 +130,12 @@ describe("discord tool result dispatch", () => {
|
||||
},
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
discord: { dm: { enabled: true, policy: "open" } },
|
||||
channels: { discord: { dm: { enabled: true, policy: "open" } } },
|
||||
} as ReturnType<typeof import("../config/config.js").loadConfig>;
|
||||
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
@@ -210,12 +210,12 @@ describe("discord tool result dispatch", () => {
|
||||
},
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
discord: { dm: { enabled: true, policy: "open" } },
|
||||
channels: { discord: { dm: { enabled: true, policy: "open" } } },
|
||||
} as ReturnType<typeof import("../config/config.js").loadConfig>;
|
||||
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
@@ -300,12 +300,14 @@ describe("discord tool result dispatch", () => {
|
||||
},
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
guilds: {
|
||||
"*": {
|
||||
requireMention: false,
|
||||
channels: { c1: { allow: true } },
|
||||
channels: {
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
guilds: {
|
||||
"*": {
|
||||
requireMention: false,
|
||||
channels: { c1: { allow: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -314,7 +316,7 @@ describe("discord tool result dispatch", () => {
|
||||
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
@@ -382,12 +384,14 @@ describe("discord tool result dispatch", () => {
|
||||
},
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
discord: { dm: { enabled: true, policy: "pairing", allowFrom: [] } },
|
||||
channels: {
|
||||
discord: { dm: { enabled: true, policy: "pairing", allowFrom: [] } },
|
||||
},
|
||||
} as ReturnType<typeof import("../config/config.js").loadConfig>;
|
||||
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
@@ -456,10 +460,12 @@ describe("discord tool result dispatch", () => {
|
||||
},
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
groupPolicy: "open",
|
||||
guilds: { "*": { requireMention: true } },
|
||||
channels: {
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
groupPolicy: "open",
|
||||
guilds: { "*": { requireMention: true } },
|
||||
},
|
||||
},
|
||||
messages: {
|
||||
responsePrefix: "PFX",
|
||||
@@ -469,7 +475,7 @@ describe("discord tool result dispatch", () => {
|
||||
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
@@ -549,16 +555,18 @@ describe("discord tool result dispatch", () => {
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
messages: { responsePrefix: "PFX" },
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
groupPolicy: "open",
|
||||
guilds: { "*": { requireMention: false } },
|
||||
channels: {
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
groupPolicy: "open",
|
||||
guilds: { "*": { requireMention: false } },
|
||||
},
|
||||
},
|
||||
} as ReturnType<typeof import("../config/config.js").loadConfig>;
|
||||
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
@@ -655,17 +663,19 @@ describe("discord tool result dispatch", () => {
|
||||
const cfg = {
|
||||
agent: { model: "anthropic/claude-opus-4-5", workspace: "/tmp/clawd" },
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
groupPolicy: "open",
|
||||
guilds: { "*": { requireMention: false } },
|
||||
channels: {
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
groupPolicy: "open",
|
||||
guilds: { "*": { requireMention: false } },
|
||||
},
|
||||
},
|
||||
routing: { allowFrom: [] },
|
||||
} as ReturnType<typeof import("../config/config.js").loadConfig>;
|
||||
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
@@ -765,19 +775,21 @@ describe("discord tool result dispatch", () => {
|
||||
},
|
||||
session: { store: "/tmp/clawdbot-sessions.json" },
|
||||
messages: { responsePrefix: "PFX" },
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
groupPolicy: "open",
|
||||
guilds: { "*": { requireMention: false } },
|
||||
channels: {
|
||||
discord: {
|
||||
dm: { enabled: true, policy: "open" },
|
||||
groupPolicy: "open",
|
||||
guilds: { "*": { requireMention: false } },
|
||||
},
|
||||
},
|
||||
bindings: [
|
||||
{ agentId: "support", match: { provider: "discord", guildId: "g1" } },
|
||||
{ agentId: "support", match: { channel: "discord", guildId: "g1" } },
|
||||
],
|
||||
} as ReturnType<typeof import("../config/config.js").loadConfig>;
|
||||
|
||||
const handler = createDiscordMessageHandler({
|
||||
cfg,
|
||||
discordConfig: cfg.discord,
|
||||
discordConfig: cfg.channels.discord,
|
||||
accountId: "default",
|
||||
token: "token",
|
||||
runtime: {
|
||||
|
||||
@@ -58,16 +58,16 @@ import type { ClawdbotConfig, ReplyToMode } from "../config/config.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { resolveStorePath, updateLastRoute } from "../config/sessions.js";
|
||||
import { danger, logVerbose, shouldLogVerbose } from "../globals.js";
|
||||
import { recordChannelActivity } from "../infra/channel-activity.js";
|
||||
import { formatDurationSeconds } from "../infra/format-duration.js";
|
||||
import { recordProviderActivity } from "../infra/provider-activity.js";
|
||||
import { enqueueSystemEvent } from "../infra/system-events.js";
|
||||
import { getChildLogger } from "../logging.js";
|
||||
import { fetchRemoteMedia } from "../media/fetch.js";
|
||||
import { saveMediaBuffer } from "../media/store.js";
|
||||
import { buildPairingReply } from "../pairing/pairing-messages.js";
|
||||
import {
|
||||
readProviderAllowFromStore,
|
||||
upsertProviderPairingRequest,
|
||||
readChannelAllowFromStore,
|
||||
upsertChannelPairingRequest,
|
||||
} from "../pairing/pairing-store.js";
|
||||
import {
|
||||
buildAgentSessionKey,
|
||||
@@ -103,6 +103,8 @@ export type MonitorDiscordOpts = {
|
||||
replyToMode?: ReplyToMode;
|
||||
};
|
||||
|
||||
type DiscordConfig = NonNullable<ClawdbotConfig["channels"]>["discord"];
|
||||
|
||||
type DiscordMediaInfo = {
|
||||
path: string;
|
||||
contentType?: string;
|
||||
@@ -721,7 +723,7 @@ async function clearDiscordNativeCommands(params: {
|
||||
|
||||
export function createDiscordMessageHandler(params: {
|
||||
cfg: ReturnType<typeof loadConfig>;
|
||||
discordConfig: ClawdbotConfig["discord"];
|
||||
discordConfig: DiscordConfig;
|
||||
accountId: string;
|
||||
token: string;
|
||||
runtime: RuntimeEnv;
|
||||
@@ -800,7 +802,7 @@ export function createDiscordMessageHandler(params: {
|
||||
return;
|
||||
}
|
||||
if (dmPolicy !== "open") {
|
||||
const storeAllowFrom = await readProviderAllowFromStore(
|
||||
const storeAllowFrom = await readChannelAllowFromStore(
|
||||
"discord",
|
||||
).catch(() => []);
|
||||
const effectiveAllowFrom = [...(allowFrom ?? []), ...storeAllowFrom];
|
||||
@@ -818,8 +820,8 @@ export function createDiscordMessageHandler(params: {
|
||||
if (!permitted) {
|
||||
commandAuthorized = false;
|
||||
if (dmPolicy === "pairing") {
|
||||
const { code, created } = await upsertProviderPairingRequest({
|
||||
provider: "discord",
|
||||
const { code, created } = await upsertChannelPairingRequest({
|
||||
channel: "discord",
|
||||
id: author.id,
|
||||
meta: {
|
||||
tag: formatDiscordUserTag(author),
|
||||
@@ -834,7 +836,7 @@ export function createDiscordMessageHandler(params: {
|
||||
await sendMessageDiscord(
|
||||
`user:${author.id}`,
|
||||
buildPairingReply({
|
||||
provider: "discord",
|
||||
channel: "discord",
|
||||
idLine: `Your Discord user id: ${author.id}`,
|
||||
code,
|
||||
}),
|
||||
@@ -863,14 +865,14 @@ export function createDiscordMessageHandler(params: {
|
||||
const messageText = resolveDiscordMessageText(message, {
|
||||
includeForwarded: true,
|
||||
});
|
||||
recordProviderActivity({
|
||||
provider: "discord",
|
||||
recordChannelActivity({
|
||||
channel: "discord",
|
||||
accountId,
|
||||
direction: "inbound",
|
||||
});
|
||||
const route = resolveAgentRoute({
|
||||
cfg,
|
||||
provider: "discord",
|
||||
channel: "discord",
|
||||
accountId,
|
||||
guildId: data.guild_id ?? undefined,
|
||||
peer: {
|
||||
@@ -1174,7 +1176,7 @@ export function createDiscordMessageHandler(params: {
|
||||
? systemPromptParts.join("\n\n")
|
||||
: undefined;
|
||||
let combinedBody = formatAgentEnvelope({
|
||||
provider: "Discord",
|
||||
channel: "Discord",
|
||||
from: fromLabel,
|
||||
timestamp: resolveTimestampMs(message.timestamp),
|
||||
body: text,
|
||||
@@ -1189,7 +1191,7 @@ export function createDiscordMessageHandler(params: {
|
||||
currentMessage: combinedBody,
|
||||
formatEntry: (entry) =>
|
||||
formatAgentEnvelope({
|
||||
provider: "Discord",
|
||||
channel: "Discord",
|
||||
from: fromLabel,
|
||||
timestamp: entry.timestamp,
|
||||
body: `${entry.sender}: ${entry.body} [id:${entry.messageId ?? "unknown"} channel:${message.channelId}]`,
|
||||
@@ -1217,7 +1219,7 @@ export function createDiscordMessageHandler(params: {
|
||||
});
|
||||
if (starter?.text) {
|
||||
const starterEnvelope = formatThreadStarterEnvelope({
|
||||
provider: "Discord",
|
||||
channel: "Discord",
|
||||
author: starter.author,
|
||||
timestamp: starter.timestamp,
|
||||
body: starter.text,
|
||||
@@ -1231,7 +1233,7 @@ export function createDiscordMessageHandler(params: {
|
||||
if (threadParentId) {
|
||||
parentSessionKey = buildAgentSessionKey({
|
||||
agentId: route.agentId,
|
||||
provider: route.provider,
|
||||
channel: route.channel,
|
||||
peer: { kind: "channel", id: threadParentId },
|
||||
});
|
||||
}
|
||||
@@ -1314,7 +1316,7 @@ export function createDiscordMessageHandler(params: {
|
||||
await updateLastRoute({
|
||||
storePath,
|
||||
sessionKey: route.mainSessionKey,
|
||||
provider: "discord",
|
||||
channel: "discord",
|
||||
to: `user:${author.id}`,
|
||||
accountId: route.accountId,
|
||||
});
|
||||
@@ -1602,7 +1604,7 @@ async function handleDiscordReactionEvent(params: {
|
||||
const text = authorLabel ? `${baseText} from ${authorLabel}` : baseText;
|
||||
const route = resolveAgentRoute({
|
||||
cfg: params.cfg,
|
||||
provider: "discord",
|
||||
channel: "discord",
|
||||
accountId: params.accountId,
|
||||
guildId: data.guild_id ?? undefined,
|
||||
peer: { kind: "channel", id: data.channel_id },
|
||||
@@ -1625,7 +1627,7 @@ export function createDiscordNativeCommand(params: {
|
||||
acceptsArgs: boolean;
|
||||
};
|
||||
cfg: ReturnType<typeof loadConfig>;
|
||||
discordConfig: ClawdbotConfig["discord"];
|
||||
discordConfig: DiscordConfig;
|
||||
accountId: string;
|
||||
sessionPrefix: string;
|
||||
ephemeralDefault: boolean;
|
||||
@@ -1721,7 +1723,7 @@ export function createDiscordNativeCommand(params: {
|
||||
return;
|
||||
}
|
||||
if (dmPolicy !== "open") {
|
||||
const storeAllowFrom = await readProviderAllowFromStore(
|
||||
const storeAllowFrom = await readChannelAllowFromStore(
|
||||
"discord",
|
||||
).catch(() => []);
|
||||
const effectiveAllowFrom = [
|
||||
@@ -1742,8 +1744,8 @@ export function createDiscordNativeCommand(params: {
|
||||
if (!permitted) {
|
||||
commandAuthorized = false;
|
||||
if (dmPolicy === "pairing") {
|
||||
const { code, created } = await upsertProviderPairingRequest({
|
||||
provider: "discord",
|
||||
const { code, created } = await upsertChannelPairingRequest({
|
||||
channel: "discord",
|
||||
id: user.id,
|
||||
meta: {
|
||||
tag: formatDiscordUserTag(user),
|
||||
@@ -1753,7 +1755,7 @@ export function createDiscordNativeCommand(params: {
|
||||
if (created) {
|
||||
await interaction.reply({
|
||||
content: buildPairingReply({
|
||||
provider: "discord",
|
||||
channel: "discord",
|
||||
idLine: `Your Discord user id: ${user.id}`,
|
||||
code,
|
||||
}),
|
||||
@@ -1798,7 +1800,7 @@ export function createDiscordNativeCommand(params: {
|
||||
const interactionId = interaction.rawData.id;
|
||||
const route = resolveAgentRoute({
|
||||
cfg,
|
||||
provider: "discord",
|
||||
channel: "discord",
|
||||
accountId,
|
||||
guildId: interaction.guild?.id ?? undefined,
|
||||
peer: {
|
||||
@@ -2244,7 +2246,7 @@ function resolveReplyContext(message: Message): string | null {
|
||||
: "Unknown";
|
||||
const body = `${referencedText}\n[discord message id: ${referenced.id} channel: ${referenced.channelId} from: ${formatDiscordUserTag(referenced.author)} user id:${referenced.author?.id ?? "unknown"}]`;
|
||||
return formatAgentEnvelope({
|
||||
provider: "Discord",
|
||||
channel: "Discord",
|
||||
from: fromLabel,
|
||||
timestamp: resolveTimestampMs(referenced.timestamp),
|
||||
body,
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
} from "discord-api-types/v10";
|
||||
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { recordProviderActivity } from "../infra/provider-activity.js";
|
||||
import { recordChannelActivity } from "../infra/channel-activity.js";
|
||||
import type { RetryConfig } from "../infra/retry.js";
|
||||
import {
|
||||
createDiscordRetryRunner,
|
||||
@@ -630,8 +630,8 @@ export async function sendMessageDiscord(
|
||||
});
|
||||
}
|
||||
|
||||
recordProviderActivity({
|
||||
provider: "discord",
|
||||
recordChannelActivity({
|
||||
channel: "discord",
|
||||
accountId: accountInfo.accountId,
|
||||
direction: "outbound",
|
||||
});
|
||||
|
||||
@@ -23,10 +23,11 @@ export function resolveDiscordToken(
|
||||
opts: { accountId?: string | null; envToken?: string | null } = {},
|
||||
): DiscordTokenResolution {
|
||||
const accountId = normalizeAccountId(opts.accountId);
|
||||
const discordCfg = cfg?.channels?.discord;
|
||||
const accountCfg =
|
||||
accountId !== DEFAULT_ACCOUNT_ID
|
||||
? cfg?.discord?.accounts?.[accountId]
|
||||
: cfg?.discord?.accounts?.[DEFAULT_ACCOUNT_ID];
|
||||
? discordCfg?.accounts?.[accountId]
|
||||
: discordCfg?.accounts?.[DEFAULT_ACCOUNT_ID];
|
||||
const accountToken = normalizeDiscordToken(accountCfg?.token ?? undefined);
|
||||
if (accountToken) return { token: accountToken, source: "config" };
|
||||
|
||||
@@ -37,7 +38,7 @@ export function resolveDiscordToken(
|
||||
if (envToken) return { token: envToken, source: "env" };
|
||||
|
||||
const configToken = allowEnv
|
||||
? normalizeDiscordToken(cfg?.discord?.token ?? undefined)
|
||||
? normalizeDiscordToken(discordCfg?.token ?? undefined)
|
||||
: undefined;
|
||||
if (configToken) return { token: configToken, source: "config" };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user