refactor: untangle bundled channel sdk bridges
This commit is contained in:
parent
3aa4199ef0
commit
7c2c20a62f
@ -1,13 +1,13 @@
|
||||
import {
|
||||
hasConfiguredSecretInput,
|
||||
normalizeSecretInputString,
|
||||
} from "../../../src/config/types.secrets.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
type OpenClawConfig,
|
||||
type DiscordAccountConfig,
|
||||
} from "openclaw/plugin-sdk/discord";
|
||||
import {
|
||||
hasConfiguredSecretInput,
|
||||
normalizeSecretInputString,
|
||||
} from "../../../src/config/types.secrets.js";
|
||||
} from "../../../src/plugin-sdk-internal/discord.js";
|
||||
import {
|
||||
mergeDiscordAccountConfig,
|
||||
resolveDefaultDiscordAccountId,
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import type {
|
||||
OpenClawConfig,
|
||||
DiscordAccountConfig,
|
||||
DiscordActionConfig,
|
||||
} from "openclaw/plugin-sdk/discord";
|
||||
import {
|
||||
createAccountActionGate,
|
||||
createAccountListHelpers,
|
||||
normalizeAccountId,
|
||||
resolveAccountEntry,
|
||||
} from "../../../src/plugin-sdk-internal/accounts.js";
|
||||
import type {
|
||||
OpenClawConfig,
|
||||
DiscordAccountConfig,
|
||||
DiscordActionConfig,
|
||||
} from "../../../src/plugin-sdk-internal/discord.js";
|
||||
import { resolveDiscordToken } from "./token.js";
|
||||
|
||||
export type ResolvedDiscordAccount = {
|
||||
|
||||
@ -1,46 +1,12 @@
|
||||
import { createScopedChannelConfigBase } from "openclaw/plugin-sdk/compat";
|
||||
import {
|
||||
createScopedAccountConfigAccessors,
|
||||
formatAllowFromLowercase,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
import {
|
||||
buildChannelConfigSchema,
|
||||
DiscordConfigSchema,
|
||||
getChatChannelMeta,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk/discord";
|
||||
import { inspectDiscordAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listDiscordAccountIds,
|
||||
resolveDefaultDiscordAccountId,
|
||||
resolveDiscordAccount,
|
||||
type ResolvedDiscordAccount,
|
||||
} from "./accounts.js";
|
||||
import { createDiscordSetupWizardProxy, discordSetupAdapter } from "./setup-core.js";
|
||||
|
||||
async function loadDiscordChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
const discordConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }) => resolveDiscordAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedDiscordAccount) => account.config.dm?.allowFrom,
|
||||
formatAllowFrom: (allowFrom) => formatAllowFromLowercase({ allowFrom }),
|
||||
resolveDefaultTo: (account: ResolvedDiscordAccount) => account.config.defaultTo,
|
||||
});
|
||||
|
||||
const discordConfigBase = createScopedChannelConfigBase({
|
||||
sectionKey: "discord",
|
||||
listAccountIds: listDiscordAccountIds,
|
||||
resolveAccount: (cfg, accountId) => resolveDiscordAccount({ cfg, accountId }),
|
||||
inspectAccount: (cfg, accountId) => inspectDiscordAccount({ cfg, accountId }),
|
||||
defaultAccountId: resolveDefaultDiscordAccountId,
|
||||
clearBaseFields: ["token", "name"],
|
||||
});
|
||||
|
||||
const discordSetupWizard = createDiscordSetupWizardProxy(async () => ({
|
||||
discordSetupWizard: (await loadDiscordChannelRuntime()).discordSetupWizard,
|
||||
}));
|
||||
} from "../../../src/plugin-sdk-internal/discord.js";
|
||||
import { type ResolvedDiscordAccount } from "./accounts.js";
|
||||
import { discordConfigAccessors, discordConfigBase, discordSetupWizard } from "./plugin-shared.js";
|
||||
import { discordSetupAdapter } from "./setup-core.js";
|
||||
|
||||
export const discordSetupPlugin: ChannelPlugin<ResolvedDiscordAccount> = {
|
||||
id: "discord",
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
import { Separator, TextDisplay } from "@buape/carbon";
|
||||
import { createScopedChannelConfigBase } from "openclaw/plugin-sdk/compat";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import {
|
||||
buildAccountScopedAllowlistConfigEditor,
|
||||
buildAccountScopedDmSecurityPolicy,
|
||||
collectOpenProviderGroupPolicyWarnings,
|
||||
collectOpenGroupPolicyConfiguredRouteWarnings,
|
||||
createScopedAccountConfigAccessors,
|
||||
formatAllowFromLowercase,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
collectOpenProviderGroupPolicyWarnings,
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import {
|
||||
buildAgentSessionKey,
|
||||
resolveThreadSessionKeys,
|
||||
type RoutePeer,
|
||||
} from "openclaw/plugin-sdk/core";
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
import {
|
||||
buildComputedAccountStatusSnapshot,
|
||||
buildChannelConfigSchema,
|
||||
@ -30,14 +28,11 @@ import {
|
||||
type ChannelMessageActionAdapter,
|
||||
type ChannelPlugin,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/discord";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
} from "../../../src/plugin-sdk-internal/discord.js";
|
||||
import { normalizeMessageChannel } from "../../../src/utils/message-channel.js";
|
||||
import { inspectDiscordAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listDiscordAccountIds,
|
||||
resolveDiscordAccount,
|
||||
resolveDefaultDiscordAccountId,
|
||||
type ResolvedDiscordAccount,
|
||||
} from "./accounts.js";
|
||||
import { collectDiscordAuditChannelIds } from "./audit.js";
|
||||
@ -50,11 +45,12 @@ import {
|
||||
normalizeDiscordMessagingTarget,
|
||||
normalizeDiscordOutboundTarget,
|
||||
} from "./normalize.js";
|
||||
import { discordConfigAccessors, discordConfigBase, discordSetupWizard } from "./plugin-shared.js";
|
||||
import type { DiscordProbe } from "./probe.js";
|
||||
import { resolveDiscordUserAllowlist } from "./resolve-users.js";
|
||||
import { getDiscordRuntime } from "./runtime.js";
|
||||
import { fetchChannelPermissionsDiscord } from "./send.js";
|
||||
import { createDiscordSetupWizardProxy, discordSetupAdapter } from "./setup-core.js";
|
||||
import { discordSetupAdapter } from "./setup-core.js";
|
||||
import { collectDiscordStatusIssues } from "./status-issues.js";
|
||||
import { parseDiscordTarget } from "./targets.js";
|
||||
import { DiscordUiContainer } from "./ui.js";
|
||||
@ -66,10 +62,6 @@ type DiscordSendFn = ReturnType<
|
||||
const meta = getChatChannelMeta("discord");
|
||||
const REQUIRED_DISCORD_PERMISSIONS = ["ViewChannel", "SendMessages"] as const;
|
||||
|
||||
async function loadDiscordChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
function formatDiscordIntents(intents?: {
|
||||
messageContent?: string;
|
||||
guildMembers?: string;
|
||||
@ -304,26 +296,6 @@ function resolveDiscordOutboundSessionRoute(params: {
|
||||
};
|
||||
}
|
||||
|
||||
const discordConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }) => resolveDiscordAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedDiscordAccount) => account.config.dm?.allowFrom,
|
||||
formatAllowFrom: (allowFrom) => formatAllowFromLowercase({ allowFrom }),
|
||||
resolveDefaultTo: (account: ResolvedDiscordAccount) => account.config.defaultTo,
|
||||
});
|
||||
|
||||
const discordConfigBase = createScopedChannelConfigBase({
|
||||
sectionKey: "discord",
|
||||
listAccountIds: listDiscordAccountIds,
|
||||
resolveAccount: (cfg, accountId) => resolveDiscordAccount({ cfg, accountId }),
|
||||
inspectAccount: (cfg, accountId) => inspectDiscordAccount({ cfg, accountId }),
|
||||
defaultAccountId: resolveDefaultDiscordAccountId,
|
||||
clearBaseFields: ["token", "name"],
|
||||
});
|
||||
|
||||
const discordSetupWizard = createDiscordSetupWizardProxy(async () => ({
|
||||
discordSetupWizard: (await loadDiscordChannelRuntime()).discordSetupWizard,
|
||||
}));
|
||||
|
||||
export const discordPlugin: ChannelPlugin<ResolvedDiscordAccount> = {
|
||||
id: "discord",
|
||||
meta: {
|
||||
|
||||
39
extensions/discord/src/plugin-shared.ts
Normal file
39
extensions/discord/src/plugin-shared.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import {
|
||||
createScopedAccountConfigAccessors,
|
||||
createScopedChannelConfigBase,
|
||||
formatAllowFromLowercase,
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import { type OpenClawConfig } from "../../../src/plugin-sdk-internal/discord.js";
|
||||
import { inspectDiscordAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listDiscordAccountIds,
|
||||
resolveDefaultDiscordAccountId,
|
||||
resolveDiscordAccount,
|
||||
type ResolvedDiscordAccount,
|
||||
} from "./accounts.js";
|
||||
import { createDiscordSetupWizardProxy } from "./setup-core.js";
|
||||
|
||||
async function loadDiscordChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
export const discordConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }: { cfg: OpenClawConfig; accountId?: string | null }) =>
|
||||
resolveDiscordAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedDiscordAccount) => account.config.dm?.allowFrom,
|
||||
formatAllowFrom: (allowFrom) => formatAllowFromLowercase({ allowFrom }),
|
||||
resolveDefaultTo: (account: ResolvedDiscordAccount) => account.config.defaultTo,
|
||||
});
|
||||
|
||||
export const discordConfigBase = createScopedChannelConfigBase({
|
||||
sectionKey: "discord",
|
||||
listAccountIds: listDiscordAccountIds,
|
||||
resolveAccount: (cfg, accountId) => resolveDiscordAccount({ cfg, accountId }),
|
||||
inspectAccount: (cfg, accountId) => inspectDiscordAccount({ cfg, accountId }),
|
||||
defaultAccountId: resolveDefaultDiscordAccountId,
|
||||
clearBaseFields: ["token", "name"],
|
||||
});
|
||||
|
||||
export const discordSetupWizard = createDiscordSetupWizardProxy(async () => ({
|
||||
discordSetupWizard: (await loadDiscordChannelRuntime()).discordSetupWizard,
|
||||
}));
|
||||
@ -1,5 +1,7 @@
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/compat";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/core";
|
||||
import {
|
||||
createPluginRuntimeStore,
|
||||
type PluginRuntime,
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
|
||||
const { setRuntime: setDiscordRuntime, getRuntime: getDiscordRuntime } =
|
||||
createPluginRuntimeStore<PluginRuntime>("Discord runtime not initialized");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
||||
import type { OpenClawPluginApi } from "../../../src/plugin-sdk-internal/core.js";
|
||||
import { resolveDiscordAccount } from "./accounts.js";
|
||||
import {
|
||||
autoBindSpawnedDiscordSubagent,
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import type { IMessageAccountConfig } from "openclaw/plugin-sdk/imessage";
|
||||
import {
|
||||
type OpenClawConfig,
|
||||
createAccountListHelpers,
|
||||
normalizeAccountId,
|
||||
resolveAccountEntry,
|
||||
} from "../../../src/plugin-sdk-internal/accounts.js";
|
||||
import type { IMessageAccountConfig } from "../../../src/plugin-sdk-internal/imessage.js";
|
||||
|
||||
export type ResolvedIMessageAccount = {
|
||||
accountId: string;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {
|
||||
buildAccountScopedDmSecurityPolicy,
|
||||
collectAllowlistProviderRestrictSendersWarnings,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import {
|
||||
buildChannelConfigSchema,
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
@ -13,22 +13,15 @@ import {
|
||||
resolveIMessageConfigDefaultTo,
|
||||
setAccountEnabledInConfigSection,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk/imessage";
|
||||
} from "../../../src/plugin-sdk-internal/imessage.js";
|
||||
import {
|
||||
listIMessageAccountIds,
|
||||
resolveDefaultIMessageAccountId,
|
||||
resolveIMessageAccount,
|
||||
type ResolvedIMessageAccount,
|
||||
} from "./accounts.js";
|
||||
import { createIMessageSetupWizardProxy, imessageSetupAdapter } from "./setup-core.js";
|
||||
|
||||
async function loadIMessageChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
const imessageSetupWizard = createIMessageSetupWizardProxy(async () => ({
|
||||
imessageSetupWizard: (await loadIMessageChannelRuntime()).imessageSetupWizard,
|
||||
}));
|
||||
import { imessageSetupWizard } from "./plugin-shared.js";
|
||||
import { imessageSetupAdapter } from "./setup-core.js";
|
||||
|
||||
export const imessageSetupPlugin: ChannelPlugin<ResolvedIMessageAccount> = {
|
||||
id: "imessage",
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import {
|
||||
buildAccountScopedAllowlistConfigEditor,
|
||||
buildAccountScopedDmSecurityPolicy,
|
||||
collectAllowlistProviderRestrictSendersWarnings,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
import { buildAgentSessionKey, type RoutePeer } from "openclaw/plugin-sdk/core";
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import { buildAgentSessionKey, type RoutePeer } from "../../../src/plugin-sdk-internal/core.js";
|
||||
import {
|
||||
buildChannelConfigSchema,
|
||||
collectStatusIssuesFromLastError,
|
||||
@ -22,8 +23,7 @@ import {
|
||||
resolveIMessageGroupToolPolicy,
|
||||
setAccountEnabledInConfigSection,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk/imessage";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
} from "../../../src/plugin-sdk-internal/imessage.js";
|
||||
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
|
||||
import {
|
||||
listIMessageAccountIds,
|
||||
@ -31,20 +31,13 @@ import {
|
||||
resolveIMessageAccount,
|
||||
type ResolvedIMessageAccount,
|
||||
} from "./accounts.js";
|
||||
import { imessageSetupWizard } from "./plugin-shared.js";
|
||||
import { getIMessageRuntime } from "./runtime.js";
|
||||
import { createIMessageSetupWizardProxy, imessageSetupAdapter } from "./setup-core.js";
|
||||
import { imessageSetupAdapter } from "./setup-core.js";
|
||||
import { normalizeIMessageHandle, parseIMessageTarget } from "./targets.js";
|
||||
|
||||
const meta = getChatChannelMeta("imessage");
|
||||
|
||||
async function loadIMessageChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
const imessageSetupWizard = createIMessageSetupWizardProxy(async () => ({
|
||||
imessageSetupWizard: (await loadIMessageChannelRuntime()).imessageSetupWizard,
|
||||
}));
|
||||
|
||||
type IMessageSendFn = ReturnType<
|
||||
typeof getIMessageRuntime
|
||||
>["channel"]["imessage"]["sendMessageIMessage"];
|
||||
|
||||
11
extensions/imessage/src/plugin-shared.ts
Normal file
11
extensions/imessage/src/plugin-shared.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { type ChannelPlugin } from "../../../src/plugin-sdk-internal/imessage.js";
|
||||
import { type ResolvedIMessageAccount } from "./accounts.js";
|
||||
import { createIMessageSetupWizardProxy } from "./setup-core.js";
|
||||
|
||||
async function loadIMessageChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
export const imessageSetupWizard = createIMessageSetupWizardProxy(async () => ({
|
||||
imessageSetupWizard: (await loadIMessageChannelRuntime()).imessageSetupWizard,
|
||||
})) satisfies NonNullable<ChannelPlugin<ResolvedIMessageAccount>["setupWizard"]>;
|
||||
@ -1,5 +1,7 @@
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/compat";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/core";
|
||||
import {
|
||||
createPluginRuntimeStore,
|
||||
type PluginRuntime,
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
|
||||
const { setRuntime: setIMessageRuntime, getRuntime: getIMessageRuntime } =
|
||||
createPluginRuntimeStore<PluginRuntime>("iMessage runtime not initialized");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { isAllowedParsedChatSender } from "../../../src/plugin-sdk/allow-from.js";
|
||||
import { isAllowedParsedChatSender } from "../../../src/plugin-sdk-internal/imessage.js";
|
||||
|
||||
export type ServicePrefix<TService extends string> = { prefix: string; service: TService };
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import type { SignalAccountConfig } from "openclaw/plugin-sdk/signal";
|
||||
import {
|
||||
type OpenClawConfig,
|
||||
createAccountListHelpers,
|
||||
normalizeAccountId,
|
||||
resolveAccountEntry,
|
||||
} from "../../../src/plugin-sdk-internal/accounts.js";
|
||||
import type { SignalAccountConfig } from "../../../src/plugin-sdk-internal/signal.js";
|
||||
|
||||
export type ResolvedSignalAccount = {
|
||||
accountId: string;
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import {
|
||||
createScopedAccountConfigAccessors,
|
||||
buildAccountScopedDmSecurityPolicy,
|
||||
collectAllowlistProviderRestrictSendersWarnings,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import {
|
||||
buildChannelConfigSchema,
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
@ -12,34 +11,15 @@ import {
|
||||
setAccountEnabledInConfigSection,
|
||||
SignalConfigSchema,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk/signal";
|
||||
} from "../../../src/plugin-sdk-internal/signal.js";
|
||||
import {
|
||||
listSignalAccountIds,
|
||||
resolveDefaultSignalAccountId,
|
||||
resolveSignalAccount,
|
||||
type ResolvedSignalAccount,
|
||||
} from "./accounts.js";
|
||||
import { createSignalSetupWizardProxy, signalSetupAdapter } from "./setup-core.js";
|
||||
|
||||
async function loadSignalChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
const signalSetupWizard = createSignalSetupWizardProxy(async () => ({
|
||||
signalSetupWizard: (await loadSignalChannelRuntime()).signalSetupWizard,
|
||||
}));
|
||||
|
||||
const signalConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }) => resolveSignalAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedSignalAccount) => account.config.allowFrom,
|
||||
formatAllowFrom: (allowFrom) =>
|
||||
allowFrom
|
||||
.map((entry) => String(entry).trim())
|
||||
.filter(Boolean)
|
||||
.map((entry) => (entry === "*" ? "*" : normalizeE164(entry.replace(/^signal:/i, ""))))
|
||||
.filter(Boolean),
|
||||
resolveDefaultTo: (account: ResolvedSignalAccount) => account.config.defaultTo,
|
||||
});
|
||||
import { signalConfigAccessors, signalSetupWizard } from "./plugin-shared.js";
|
||||
import { signalSetupAdapter } from "./setup-core.js";
|
||||
|
||||
export const signalSetupPlugin: ChannelPlugin<ResolvedSignalAccount> = {
|
||||
id: "signal",
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { resolveTextChunkLimit } from "../../../src/auto-reply/chunk.js";
|
||||
import { resolveMarkdownTableMode } from "../../../src/config/markdown-tables.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import {
|
||||
buildAccountScopedAllowlistConfigEditor,
|
||||
buildAccountScopedDmSecurityPolicy,
|
||||
createScopedAccountConfigAccessors,
|
||||
collectAllowlistProviderRestrictSendersWarnings,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
import { buildAgentSessionKey, type RoutePeer } from "openclaw/plugin-sdk/core";
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import { buildAgentSessionKey, type RoutePeer } from "../../../src/plugin-sdk-internal/core.js";
|
||||
import {
|
||||
buildBaseAccountStatusSnapshot,
|
||||
buildBaseChannelStatusSummary,
|
||||
@ -23,10 +25,7 @@ import {
|
||||
SignalConfigSchema,
|
||||
type ChannelMessageActionAdapter,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk/signal";
|
||||
import { resolveTextChunkLimit } from "../../../src/auto-reply/chunk.js";
|
||||
import { resolveMarkdownTableMode } from "../../../src/config/markdown-tables.js";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
} from "../../../src/plugin-sdk-internal/signal.js";
|
||||
import {
|
||||
listSignalAccountIds,
|
||||
resolveDefaultSignalAccountId,
|
||||
@ -40,17 +39,10 @@ import {
|
||||
resolveSignalRecipient,
|
||||
resolveSignalSender,
|
||||
} from "./identity.js";
|
||||
import { signalConfigAccessors, signalSetupWizard } from "./plugin-shared.js";
|
||||
import type { SignalProbe } from "./probe.js";
|
||||
import { getSignalRuntime } from "./runtime.js";
|
||||
import { createSignalSetupWizardProxy, signalSetupAdapter } from "./setup-core.js";
|
||||
|
||||
async function loadSignalChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
const signalSetupWizard = createSignalSetupWizardProxy(async () => ({
|
||||
signalSetupWizard: (await loadSignalChannelRuntime()).signalSetupWizard,
|
||||
}));
|
||||
import { signalSetupAdapter } from "./setup-core.js";
|
||||
|
||||
const signalMessageActions: ChannelMessageActionAdapter = {
|
||||
listActions: (ctx) => getSignalRuntime().channel.signal.messageActions?.listActions?.(ctx) ?? [],
|
||||
@ -65,18 +57,6 @@ const signalMessageActions: ChannelMessageActionAdapter = {
|
||||
},
|
||||
};
|
||||
|
||||
const signalConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }) => resolveSignalAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedSignalAccount) => account.config.allowFrom,
|
||||
formatAllowFrom: (allowFrom) =>
|
||||
allowFrom
|
||||
.map((entry) => String(entry).trim())
|
||||
.filter(Boolean)
|
||||
.map((entry) => (entry === "*" ? "*" : normalizeE164(entry.replace(/^signal:/i, ""))))
|
||||
.filter(Boolean),
|
||||
resolveDefaultTo: (account: ResolvedSignalAccount) => account.config.defaultTo,
|
||||
});
|
||||
|
||||
type SignalSendFn = ReturnType<typeof getSignalRuntime>["channel"]["signal"]["sendMessageSignal"];
|
||||
|
||||
function resolveSignalSendContext(params: {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { evaluateSenderGroupAccessForPolicy } from "../../../src/plugin-sdk/group-access.js";
|
||||
import { evaluateSenderGroupAccessForPolicy } from "../../../src/plugin-sdk-internal/signal.js";
|
||||
import { normalizeE164 } from "../../../src/utils.js";
|
||||
|
||||
export type SignalSender =
|
||||
|
||||
25
extensions/signal/src/plugin-shared.ts
Normal file
25
extensions/signal/src/plugin-shared.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { createScopedAccountConfigAccessors } from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import { normalizeE164, type OpenClawConfig } from "../../../src/plugin-sdk-internal/signal.js";
|
||||
import { resolveSignalAccount, type ResolvedSignalAccount } from "./accounts.js";
|
||||
import { createSignalSetupWizardProxy } from "./setup-core.js";
|
||||
|
||||
async function loadSignalChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
export const signalSetupWizard = createSignalSetupWizardProxy(async () => ({
|
||||
signalSetupWizard: (await loadSignalChannelRuntime()).signalSetupWizard,
|
||||
}));
|
||||
|
||||
export const signalConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }: { cfg: OpenClawConfig; accountId?: string | null }) =>
|
||||
resolveSignalAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedSignalAccount) => account.config.allowFrom,
|
||||
formatAllowFrom: (allowFrom) =>
|
||||
allowFrom
|
||||
.map((entry) => String(entry).trim())
|
||||
.filter(Boolean)
|
||||
.map((entry) => (entry === "*" ? "*" : normalizeE164(entry.replace(/^signal:/i, ""))))
|
||||
.filter(Boolean),
|
||||
resolveDefaultTo: (account: ResolvedSignalAccount) => account.config.defaultTo,
|
||||
});
|
||||
@ -1,5 +1,7 @@
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/compat";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/core";
|
||||
import {
|
||||
createPluginRuntimeStore,
|
||||
type PluginRuntime,
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
|
||||
const { setRuntime: setSignalRuntime, getRuntime: getSignalRuntime } =
|
||||
createPluginRuntimeStore<PluginRuntime>("Signal runtime not initialized");
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import {
|
||||
hasConfiguredSecretInput,
|
||||
normalizeSecretInputString,
|
||||
} from "../../../src/config/types.secrets.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
type OpenClawConfig,
|
||||
type SlackAccountConfig,
|
||||
} from "openclaw/plugin-sdk/slack";
|
||||
import {
|
||||
hasConfiguredSecretInput,
|
||||
normalizeSecretInputString,
|
||||
} from "../../../src/config/types.secrets.js";
|
||||
} from "../../../src/plugin-sdk-internal/slack.js";
|
||||
import type { SlackAccountSurfaceFields } from "./account-surface-fields.js";
|
||||
import {
|
||||
mergeSlackAccountConfig,
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { SlackAccountConfig } from "openclaw/plugin-sdk/slack";
|
||||
import {
|
||||
type OpenClawConfig,
|
||||
createAccountListHelpers,
|
||||
@ -7,6 +6,7 @@ import {
|
||||
normalizeChatType,
|
||||
resolveAccountEntry,
|
||||
} from "../../../src/plugin-sdk-internal/accounts.js";
|
||||
import type { SlackAccountConfig } from "../../../src/plugin-sdk-internal/slack.js";
|
||||
import type { SlackAccountSurfaceFields } from "./account-surface-fields.js";
|
||||
import { resolveSlackAppToken, resolveSlackBotToken, resolveSlackUserToken } from "./token.js";
|
||||
|
||||
|
||||
@ -3,19 +3,16 @@ import {
|
||||
getChatChannelMeta,
|
||||
SlackConfigSchema,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk/slack";
|
||||
} from "../../../src/plugin-sdk-internal/slack.js";
|
||||
import { type ResolvedSlackAccount } from "./accounts.js";
|
||||
import { isSlackInteractiveRepliesEnabled } from "./interactive-replies.js";
|
||||
import { createSlackSetupWizardProxy, slackSetupAdapter } from "./setup-core.js";
|
||||
import { isSlackPluginAccountConfigured, slackConfigAccessors, slackConfigBase } from "./shared.js";
|
||||
|
||||
async function loadSlackChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
const slackSetupWizard = createSlackSetupWizardProxy(async () => ({
|
||||
slackSetupWizard: (await loadSlackChannelRuntime()).slackSetupWizard,
|
||||
}));
|
||||
import {
|
||||
isSlackPluginAccountConfigured,
|
||||
slackConfigAccessors,
|
||||
slackConfigBase,
|
||||
slackSetupWizard,
|
||||
} from "./plugin-shared.js";
|
||||
import { slackSetupAdapter } from "./setup-core.js";
|
||||
|
||||
export const slackSetupPlugin: ChannelPlugin<ResolvedSlackAccount> = {
|
||||
id: "slack",
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
import {
|
||||
buildAccountScopedAllowlistConfigEditor,
|
||||
buildAccountScopedDmSecurityPolicy,
|
||||
collectOpenProviderGroupPolicyWarnings,
|
||||
collectOpenGroupPolicyConfiguredRouteWarnings,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
collectOpenProviderGroupPolicyWarnings,
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import {
|
||||
buildAgentSessionKey,
|
||||
resolveThreadSessionKeys,
|
||||
type RoutePeer,
|
||||
} from "openclaw/plugin-sdk/core";
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
import {
|
||||
buildComputedAccountStatusSnapshot,
|
||||
buildChannelConfigSchema,
|
||||
@ -26,8 +27,7 @@ import {
|
||||
SlackConfigSchema,
|
||||
type ChannelPlugin,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/slack";
|
||||
import { resolveOutboundSendDep } from "../../../src/infra/outbound/send-deps.js";
|
||||
} from "../../../src/plugin-sdk-internal/slack.js";
|
||||
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
|
||||
import {
|
||||
listEnabledSlackAccounts,
|
||||
@ -41,22 +41,23 @@ import { isSlackInteractiveRepliesEnabled } from "./interactive-replies.js";
|
||||
import { handleSlackMessageAction } from "./message-action-dispatch.js";
|
||||
import { extractSlackToolSend, listSlackMessageActions } from "./message-actions.js";
|
||||
import { normalizeAllowListLower } from "./monitor/allow-list.js";
|
||||
import {
|
||||
isSlackPluginAccountConfigured,
|
||||
slackConfigAccessors,
|
||||
slackConfigBase,
|
||||
slackSetupWizard,
|
||||
} from "./plugin-shared.js";
|
||||
import type { SlackProbe } from "./probe.js";
|
||||
import { resolveSlackUserAllowlist } from "./resolve-users.js";
|
||||
import { getSlackRuntime } from "./runtime.js";
|
||||
import { fetchSlackScopes } from "./scopes.js";
|
||||
import { createSlackSetupWizardProxy, slackSetupAdapter } from "./setup-core.js";
|
||||
import { isSlackPluginAccountConfigured, slackConfigAccessors, slackConfigBase } from "./shared.js";
|
||||
import { slackSetupAdapter } from "./setup-core.js";
|
||||
import { parseSlackTarget } from "./targets.js";
|
||||
import { buildSlackThreadingToolContext } from "./threading-tool-context.js";
|
||||
|
||||
const meta = getChatChannelMeta("slack");
|
||||
const SLACK_CHANNEL_TYPE_CACHE = new Map<string, "channel" | "group" | "dm" | "unknown">();
|
||||
|
||||
async function loadSlackChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
// Select the appropriate Slack token for read/write operations.
|
||||
function getTokenForOperation(
|
||||
account: ResolvedSlackAccount,
|
||||
@ -328,10 +329,6 @@ async function resolveSlackAllowlistNames(params: {
|
||||
return await resolveSlackUserAllowlist({ token, entries: params.entries });
|
||||
}
|
||||
|
||||
const slackSetupWizard = createSlackSetupWizardProxy(async () => ({
|
||||
slackSetupWizard: (await loadSlackChannelRuntime()).slackSetupWizard,
|
||||
}));
|
||||
|
||||
export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
|
||||
id: "slack",
|
||||
meta: {
|
||||
|
||||
@ -1 +1 @@
|
||||
export { handleSlackMessageAction } from "../../../src/plugin-sdk/slack-message-actions.js";
|
||||
export { handleSlackMessageAction } from "../../../src/plugin-sdk-internal/slack.js";
|
||||
|
||||
53
extensions/slack/src/plugin-shared.ts
Normal file
53
extensions/slack/src/plugin-shared.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import {
|
||||
createScopedAccountConfigAccessors,
|
||||
createScopedChannelConfigBase,
|
||||
formatAllowFromLowercase,
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import { type OpenClawConfig } from "../../../src/plugin-sdk-internal/slack.js";
|
||||
import { inspectSlackAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listSlackAccountIds,
|
||||
resolveDefaultSlackAccountId,
|
||||
resolveSlackAccount,
|
||||
type ResolvedSlackAccount,
|
||||
} from "./accounts.js";
|
||||
import { createSlackSetupWizardProxy } from "./setup-core.js";
|
||||
|
||||
async function loadSlackChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
export function isSlackAccountConfigured(account: ResolvedSlackAccount): boolean {
|
||||
const mode = account.config.mode ?? "socket";
|
||||
const hasBotToken = Boolean(account.botToken?.trim());
|
||||
if (!hasBotToken) {
|
||||
return false;
|
||||
}
|
||||
if (mode === "http") {
|
||||
return Boolean(account.config.signingSecret?.trim());
|
||||
}
|
||||
return Boolean(account.appToken?.trim());
|
||||
}
|
||||
|
||||
export const isSlackPluginAccountConfigured = isSlackAccountConfigured;
|
||||
|
||||
export const slackConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }: { cfg: OpenClawConfig; accountId?: string | null }) =>
|
||||
resolveSlackAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedSlackAccount) => account.dm?.allowFrom,
|
||||
formatAllowFrom: (allowFrom) => formatAllowFromLowercase({ allowFrom }),
|
||||
resolveDefaultTo: (account: ResolvedSlackAccount) => account.config.defaultTo,
|
||||
});
|
||||
|
||||
export const slackConfigBase = createScopedChannelConfigBase({
|
||||
sectionKey: "slack",
|
||||
listAccountIds: listSlackAccountIds,
|
||||
resolveAccount: (cfg, accountId) => resolveSlackAccount({ cfg, accountId }),
|
||||
inspectAccount: (cfg, accountId) => inspectSlackAccount({ cfg, accountId }),
|
||||
defaultAccountId: resolveDefaultSlackAccountId,
|
||||
clearBaseFields: ["botToken", "appToken", "name"],
|
||||
});
|
||||
|
||||
export const slackSetupWizard = createSlackSetupWizardProxy(async () => ({
|
||||
slackSetupWizard: (await loadSlackChannelRuntime()).slackSetupWizard,
|
||||
}));
|
||||
@ -1,5 +1,7 @@
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/compat";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/core";
|
||||
import {
|
||||
createPluginRuntimeStore,
|
||||
type PluginRuntime,
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
|
||||
const { setRuntime: setSlackRuntime, getRuntime: getSlackRuntime } =
|
||||
createPluginRuntimeStore<PluginRuntime>("Slack runtime not initialized");
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { TelegramAccountConfig } from "openclaw/plugin-sdk/telegram";
|
||||
import type { OpenClawConfig } from "../../../src/config/config.js";
|
||||
import {
|
||||
coerceSecretRef,
|
||||
@ -6,7 +5,8 @@ import {
|
||||
normalizeSecretInputString,
|
||||
} from "../../../src/config/types.secrets.js";
|
||||
import { tryReadSecretFileSync } from "../../../src/infra/secret-file.js";
|
||||
import { resolveAccountWithDefaultFallback } from "../../../src/plugin-sdk/account-resolution.js";
|
||||
import { resolveAccountWithDefaultFallback } from "../../../src/plugin-sdk-internal/accounts.js";
|
||||
import type { TelegramAccountConfig } from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js";
|
||||
import { resolveDefaultSecretProviderAlias } from "../../../src/secrets/ref-contract.js";
|
||||
import {
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import util from "node:util";
|
||||
import type { TelegramAccountConfig, TelegramActionConfig } from "openclaw/plugin-sdk/telegram";
|
||||
import { createAccountActionGate } from "../../../src/channels/plugins/account-action-gate.js";
|
||||
import type { OpenClawConfig } from "../../../src/config/config.js";
|
||||
import { isTruthyEnvValue } from "../../../src/infra/env.js";
|
||||
@ -7,7 +6,11 @@ import { createSubsystemLogger } from "../../../src/logging/subsystem.js";
|
||||
import {
|
||||
listConfiguredAccountIds as listConfiguredAccountIdsFromSection,
|
||||
resolveAccountWithDefaultFallback,
|
||||
} from "../../../src/plugin-sdk/account-resolution.js";
|
||||
} from "../../../src/plugin-sdk-internal/accounts.js";
|
||||
import type {
|
||||
TelegramAccountConfig,
|
||||
TelegramActionConfig,
|
||||
} from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { resolveAccountEntry } from "../../../src/routing/account-lookup.js";
|
||||
import {
|
||||
listBoundAccountIds,
|
||||
|
||||
@ -15,8 +15,7 @@ import type {
|
||||
ChannelMessageActionName,
|
||||
} from "../../../src/channels/plugins/types.js";
|
||||
import type { TelegramActionConfig } from "../../../src/config/types.telegram.js";
|
||||
import { readBooleanParam } from "../../../src/plugin-sdk/boolean-param.js";
|
||||
import { extractToolSend } from "../../../src/plugin-sdk/tool-send.js";
|
||||
import { extractToolSend, readBooleanParam } from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { resolveTelegramPollVisibility } from "../../../src/poll-params.js";
|
||||
import {
|
||||
createTelegramActionGate,
|
||||
|
||||
@ -1,78 +1,20 @@
|
||||
import { createScopedChannelConfigBase } from "openclaw/plugin-sdk/compat";
|
||||
import {
|
||||
createScopedAccountConfigAccessors,
|
||||
formatAllowFromLowercase,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
import type { ChannelPlugin } from "openclaw/plugin-sdk/core";
|
||||
import {
|
||||
buildChannelConfigSchema,
|
||||
getChatChannelMeta,
|
||||
normalizeAccountId,
|
||||
TelegramConfigSchema,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/telegram";
|
||||
import { inspectTelegramAccount } from "./account-inspect.js";
|
||||
type ChannelPlugin,
|
||||
} from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { type ResolvedTelegramAccount } from "./accounts.js";
|
||||
import {
|
||||
listTelegramAccountIds,
|
||||
resolveDefaultTelegramAccountId,
|
||||
resolveTelegramAccount,
|
||||
type ResolvedTelegramAccount,
|
||||
} from "./accounts.js";
|
||||
findTelegramTokenOwnerAccountId,
|
||||
formatDuplicateTelegramTokenReason,
|
||||
telegramConfigAccessors,
|
||||
telegramConfigBase,
|
||||
} from "./plugin-shared.js";
|
||||
import type { TelegramProbe } from "./probe.js";
|
||||
import { telegramSetupAdapter } from "./setup-core.js";
|
||||
import { telegramSetupWizard } from "./setup-surface.js";
|
||||
|
||||
function findTelegramTokenOwnerAccountId(params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId: string;
|
||||
}): string | null {
|
||||
const normalizedAccountId = normalizeAccountId(params.accountId);
|
||||
const tokenOwners = new Map<string, string>();
|
||||
for (const id of listTelegramAccountIds(params.cfg)) {
|
||||
const account = inspectTelegramAccount({ cfg: params.cfg, accountId: id });
|
||||
const token = (account.token ?? "").trim();
|
||||
if (!token) {
|
||||
continue;
|
||||
}
|
||||
const ownerAccountId = tokenOwners.get(token);
|
||||
if (!ownerAccountId) {
|
||||
tokenOwners.set(token, account.accountId);
|
||||
continue;
|
||||
}
|
||||
if (account.accountId === normalizedAccountId) {
|
||||
return ownerAccountId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function formatDuplicateTelegramTokenReason(params: {
|
||||
accountId: string;
|
||||
ownerAccountId: string;
|
||||
}): string {
|
||||
return (
|
||||
`Duplicate Telegram bot token: account "${params.accountId}" shares a token with ` +
|
||||
`account "${params.ownerAccountId}". Keep one owner account per bot token.`
|
||||
);
|
||||
}
|
||||
|
||||
const telegramConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }) => resolveTelegramAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedTelegramAccount) => account.config.allowFrom,
|
||||
formatAllowFrom: (allowFrom) =>
|
||||
formatAllowFromLowercase({ allowFrom, stripPrefixRe: /^(telegram|tg):/i }),
|
||||
resolveDefaultTo: (account: ResolvedTelegramAccount) => account.config.defaultTo,
|
||||
});
|
||||
|
||||
const telegramConfigBase = createScopedChannelConfigBase<ResolvedTelegramAccount>({
|
||||
sectionKey: "telegram",
|
||||
listAccountIds: listTelegramAccountIds,
|
||||
resolveAccount: (cfg, accountId) => resolveTelegramAccount({ cfg, accountId }),
|
||||
inspectAccount: (cfg, accountId) => inspectTelegramAccount({ cfg, accountId }),
|
||||
defaultAccountId: resolveDefaultTelegramAccountId,
|
||||
clearBaseFields: ["botToken", "tokenFile", "name"],
|
||||
});
|
||||
|
||||
export const telegramSetupPlugin: ChannelPlugin<ResolvedTelegramAccount, TelegramProbe> = {
|
||||
id: "telegram",
|
||||
meta: {
|
||||
|
||||
@ -1,18 +1,22 @@
|
||||
import { createScopedChannelConfigBase } from "openclaw/plugin-sdk/compat";
|
||||
import { parseTelegramTopicConversation } from "../../../src/acp/conversation-id.js";
|
||||
import { resolveExecApprovalCommandDisplay } from "../../../src/infra/exec-approval-command-display.js";
|
||||
import { buildExecApprovalPendingReplyPayload } from "../../../src/infra/exec-approval-reply.js";
|
||||
import {
|
||||
type OutboundSendDeps,
|
||||
resolveOutboundSendDep,
|
||||
} from "../../../src/infra/outbound/send-deps.js";
|
||||
import {
|
||||
buildAccountScopedAllowlistConfigEditor,
|
||||
collectAllowlistProviderGroupPolicyWarnings,
|
||||
collectOpenGroupPolicyRouteAllowlistWarnings,
|
||||
createScopedAccountConfigAccessors,
|
||||
createScopedDmSecurityResolver,
|
||||
formatAllowFromLowercase,
|
||||
} from "openclaw/plugin-sdk/compat";
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import {
|
||||
buildAgentSessionKey,
|
||||
resolveThreadSessionKeys,
|
||||
type ChannelPlugin,
|
||||
type RoutePeer,
|
||||
} from "openclaw/plugin-sdk/core";
|
||||
import type { ChannelPlugin } from "openclaw/plugin-sdk/core";
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
import {
|
||||
buildChannelConfigSchema,
|
||||
buildTokenChannelStatusSummary,
|
||||
@ -21,7 +25,6 @@ import {
|
||||
getChatChannelMeta,
|
||||
listTelegramDirectoryGroupsFromConfig,
|
||||
listTelegramDirectoryPeersFromConfig,
|
||||
normalizeAccountId,
|
||||
PAIRING_APPROVED_MESSAGE,
|
||||
projectCredentialSnapshotFields,
|
||||
resolveConfiguredFromCredentialStatuses,
|
||||
@ -30,19 +33,10 @@ import {
|
||||
TelegramConfigSchema,
|
||||
type ChannelMessageActionAdapter,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/telegram";
|
||||
import { parseTelegramTopicConversation } from "../../../src/acp/conversation-id.js";
|
||||
import { resolveExecApprovalCommandDisplay } from "../../../src/infra/exec-approval-command-display.js";
|
||||
import { buildExecApprovalPendingReplyPayload } from "../../../src/infra/exec-approval-reply.js";
|
||||
import {
|
||||
type OutboundSendDeps,
|
||||
resolveOutboundSendDep,
|
||||
} from "../../../src/infra/outbound/send-deps.js";
|
||||
} from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { normalizeMessageChannel } from "../../../src/utils/message-channel.js";
|
||||
import { inspectTelegramAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listTelegramAccountIds,
|
||||
resolveDefaultTelegramAccountId,
|
||||
resolveTelegramAccount,
|
||||
type ResolvedTelegramAccount,
|
||||
} from "./accounts.js";
|
||||
@ -57,6 +51,12 @@ import { monitorTelegramProvider } from "./monitor.js";
|
||||
import { looksLikeTelegramTargetId, normalizeTelegramMessagingTarget } from "./normalize.js";
|
||||
import { sendTelegramPayloadMessages } from "./outbound-adapter.js";
|
||||
import { parseTelegramReplyToMessageId, parseTelegramThreadId } from "./outbound-params.js";
|
||||
import {
|
||||
findTelegramTokenOwnerAccountId,
|
||||
formatDuplicateTelegramTokenReason,
|
||||
telegramConfigAccessors,
|
||||
telegramConfigBase,
|
||||
} from "./plugin-shared.js";
|
||||
import { probeTelegram, type TelegramProbe } from "./probe.js";
|
||||
import { getTelegramRuntime } from "./runtime.js";
|
||||
import { sendTypingTelegram } from "./send.js";
|
||||
@ -71,40 +71,6 @@ type TelegramSendFn = ReturnType<
|
||||
|
||||
const meta = getChatChannelMeta("telegram");
|
||||
|
||||
function findTelegramTokenOwnerAccountId(params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId: string;
|
||||
}): string | null {
|
||||
const normalizedAccountId = normalizeAccountId(params.accountId);
|
||||
const tokenOwners = new Map<string, string>();
|
||||
for (const id of listTelegramAccountIds(params.cfg)) {
|
||||
const account = inspectTelegramAccount({ cfg: params.cfg, accountId: id });
|
||||
const token = (account.token ?? "").trim();
|
||||
if (!token) {
|
||||
continue;
|
||||
}
|
||||
const ownerAccountId = tokenOwners.get(token);
|
||||
if (!ownerAccountId) {
|
||||
tokenOwners.set(token, account.accountId);
|
||||
continue;
|
||||
}
|
||||
if (account.accountId === normalizedAccountId) {
|
||||
return ownerAccountId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function formatDuplicateTelegramTokenReason(params: {
|
||||
accountId: string;
|
||||
ownerAccountId: string;
|
||||
}): string {
|
||||
return (
|
||||
`Duplicate Telegram bot token: account "${params.accountId}" shares a token with ` +
|
||||
`account "${params.ownerAccountId}". Keep one owner account per bot token.`
|
||||
);
|
||||
}
|
||||
|
||||
type TelegramSendOptions = NonNullable<Parameters<TelegramSendFn>[2]>;
|
||||
|
||||
function buildTelegramSendOptions(params: {
|
||||
@ -329,23 +295,6 @@ const telegramMessageActions: ChannelMessageActionAdapter = {
|
||||
},
|
||||
};
|
||||
|
||||
const telegramConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }) => resolveTelegramAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedTelegramAccount) => account.config.allowFrom,
|
||||
formatAllowFrom: (allowFrom) =>
|
||||
formatAllowFromLowercase({ allowFrom, stripPrefixRe: /^(telegram|tg):/i }),
|
||||
resolveDefaultTo: (account: ResolvedTelegramAccount) => account.config.defaultTo,
|
||||
});
|
||||
|
||||
const telegramConfigBase = createScopedChannelConfigBase<ResolvedTelegramAccount>({
|
||||
sectionKey: "telegram",
|
||||
listAccountIds: listTelegramAccountIds,
|
||||
resolveAccount: (cfg, accountId) => resolveTelegramAccount({ cfg, accountId }),
|
||||
inspectAccount: (cfg, accountId) => inspectTelegramAccount({ cfg, accountId }),
|
||||
defaultAccountId: resolveDefaultTelegramAccountId,
|
||||
clearBaseFields: ["botToken", "tokenFile", "name"],
|
||||
});
|
||||
|
||||
const resolveTelegramDmPolicy = createScopedDmSecurityResolver<ResolvedTelegramAccount>({
|
||||
channelKey: "telegram",
|
||||
resolvePolicy: (account) => account.config.dmPolicy,
|
||||
|
||||
@ -7,7 +7,7 @@ import type {
|
||||
TelegramGroupConfig,
|
||||
TelegramTopicConfig,
|
||||
} from "../../../src/config/types.js";
|
||||
import { evaluateMatchedGroupAccessForPolicy } from "../../../src/plugin-sdk/group-access.js";
|
||||
import { evaluateMatchedGroupAccessForPolicy } from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { isSenderAllowed, type NormalizedAllowFrom } from "./bot-access.js";
|
||||
import { firstDefined } from "./bot-access.js";
|
||||
|
||||
|
||||
68
extensions/telegram/src/plugin-shared.ts
Normal file
68
extensions/telegram/src/plugin-shared.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import {
|
||||
createScopedAccountConfigAccessors,
|
||||
createScopedChannelConfigBase,
|
||||
formatAllowFromLowercase,
|
||||
} from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import {
|
||||
normalizeAccountId,
|
||||
type OpenClawConfig,
|
||||
} from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { inspectTelegramAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listTelegramAccountIds,
|
||||
resolveDefaultTelegramAccountId,
|
||||
resolveTelegramAccount,
|
||||
type ResolvedTelegramAccount,
|
||||
} from "./accounts.js";
|
||||
|
||||
export function findTelegramTokenOwnerAccountId(params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId: string;
|
||||
}): string | null {
|
||||
const normalizedAccountId = normalizeAccountId(params.accountId);
|
||||
const tokenOwners = new Map<string, string>();
|
||||
for (const id of listTelegramAccountIds(params.cfg)) {
|
||||
const account = inspectTelegramAccount({ cfg: params.cfg, accountId: id });
|
||||
const token = (account.token ?? "").trim();
|
||||
if (!token) {
|
||||
continue;
|
||||
}
|
||||
const ownerAccountId = tokenOwners.get(token);
|
||||
if (!ownerAccountId) {
|
||||
tokenOwners.set(token, account.accountId);
|
||||
continue;
|
||||
}
|
||||
if (account.accountId === normalizedAccountId) {
|
||||
return ownerAccountId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function formatDuplicateTelegramTokenReason(params: {
|
||||
accountId: string;
|
||||
ownerAccountId: string;
|
||||
}): string {
|
||||
return (
|
||||
`Duplicate Telegram bot token: account "${params.accountId}" shares a token with ` +
|
||||
`account "${params.ownerAccountId}". Keep one owner account per bot token.`
|
||||
);
|
||||
}
|
||||
|
||||
export const telegramConfigAccessors = createScopedAccountConfigAccessors({
|
||||
resolveAccount: ({ cfg, accountId }: { cfg: OpenClawConfig; accountId?: string | null }) =>
|
||||
resolveTelegramAccount({ cfg, accountId }),
|
||||
resolveAllowFrom: (account: ResolvedTelegramAccount) => account.config.allowFrom,
|
||||
formatAllowFrom: (allowFrom) =>
|
||||
formatAllowFromLowercase({ allowFrom, stripPrefixRe: /^(telegram|tg):/i }),
|
||||
resolveDefaultTo: (account: ResolvedTelegramAccount) => account.config.defaultTo,
|
||||
});
|
||||
|
||||
export const telegramConfigBase = createScopedChannelConfigBase<ResolvedTelegramAccount>({
|
||||
sectionKey: "telegram",
|
||||
listAccountIds: listTelegramAccountIds,
|
||||
resolveAccount: (cfg, accountId) => resolveTelegramAccount({ cfg, accountId }),
|
||||
inspectAccount: (cfg, accountId) => inspectTelegramAccount({ cfg, accountId }),
|
||||
defaultAccountId: resolveDefaultTelegramAccountId,
|
||||
clearBaseFields: ["botToken", "tokenFile", "name"],
|
||||
});
|
||||
@ -1,5 +1,5 @@
|
||||
import type { TelegramNetworkConfig } from "openclaw/plugin-sdk/telegram";
|
||||
import type { BaseProbeResult } from "../../../src/channels/plugins/types.js";
|
||||
import type { TelegramNetworkConfig } from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { fetchWithTimeout } from "../../../src/utils/fetch-timeout.js";
|
||||
import { resolveTelegramFetch } from "./fetch.js";
|
||||
import { makeProxyFetch } from "./proxy.js";
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/compat";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/core";
|
||||
import {
|
||||
createPluginRuntimeStore,
|
||||
type PluginRuntime,
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
|
||||
const { setRuntime: setTelegramRuntime, getRuntime: getTelegramRuntime } =
|
||||
createPluginRuntimeStore<PluginRuntime>("Telegram runtime not initialized");
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import type { TelegramAccountConfig } from "openclaw/plugin-sdk/telegram";
|
||||
import type { BaseTokenResolution } from "../../../src/channels/plugins/types.core.js";
|
||||
import type { OpenClawConfig } from "../../../src/config/config.js";
|
||||
import { normalizeResolvedSecretInputString } from "../../../src/config/types.secrets.js";
|
||||
import { tryReadSecretFileSync } from "../../../src/infra/secret-file.js";
|
||||
import type { TelegramAccountConfig } from "../../../src/plugin-sdk-internal/telegram.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js";
|
||||
|
||||
export type TelegramTokenSource = "env" | "tokenFile" | "config" | "none";
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { DmPolicy, GroupPolicy, WhatsAppAccountConfig } from "openclaw/plugin-sdk/whatsapp";
|
||||
import { resolveOAuthDir } from "../../../src/config/paths.js";
|
||||
import {
|
||||
type OpenClawConfig,
|
||||
@ -10,6 +9,11 @@ import {
|
||||
resolveAccountEntry,
|
||||
resolveUserPath,
|
||||
} from "../../../src/plugin-sdk-internal/accounts.js";
|
||||
import type {
|
||||
DmPolicy,
|
||||
GroupPolicy,
|
||||
WhatsAppAccountConfig,
|
||||
} from "../../../src/plugin-sdk-internal/whatsapp.js";
|
||||
import { hasWebCredsSync } from "./auth-store.js";
|
||||
|
||||
export type ResolvedWhatsAppAccount = {
|
||||
|
||||
@ -14,7 +14,7 @@ import {
|
||||
resolveWhatsAppGroupToolPolicy,
|
||||
WhatsAppConfigSchema,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk/whatsapp";
|
||||
} from "../../../src/plugin-sdk-internal/whatsapp.js";
|
||||
import {
|
||||
listWhatsAppAccountIds,
|
||||
resolveDefaultWhatsAppAccountId,
|
||||
@ -22,57 +22,9 @@ import {
|
||||
type ResolvedWhatsAppAccount,
|
||||
} from "./accounts.js";
|
||||
import { webAuthExists } from "./auth-store.js";
|
||||
import { whatsappSetupWizardProxy } from "./plugin-shared.js";
|
||||
import { whatsappSetupAdapter } from "./setup-core.js";
|
||||
|
||||
async function loadWhatsAppChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
const whatsappSetupWizardProxy = {
|
||||
channel: "whatsapp",
|
||||
status: {
|
||||
configuredLabel: "linked",
|
||||
unconfiguredLabel: "not linked",
|
||||
configuredHint: "linked",
|
||||
unconfiguredHint: "not linked",
|
||||
configuredScore: 5,
|
||||
unconfiguredScore: 4,
|
||||
resolveConfigured: async ({ cfg }) =>
|
||||
await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.status.resolveConfigured({
|
||||
cfg,
|
||||
}),
|
||||
resolveStatusLines: async ({ cfg, configured }) =>
|
||||
(await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.status.resolveStatusLines?.({
|
||||
cfg,
|
||||
configured,
|
||||
})) ?? [],
|
||||
},
|
||||
resolveShouldPromptAccountIds: (params) =>
|
||||
(params.shouldPromptAccountIds || params.options?.promptWhatsAppAccountId) ?? false,
|
||||
credentials: [],
|
||||
finalize: async (params) =>
|
||||
await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.finalize!(params),
|
||||
disable: (cfg) => ({
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
whatsapp: {
|
||||
...cfg.channels?.whatsapp,
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
onAccountRecorded: (accountId, options) => {
|
||||
options?.onWhatsAppAccountId?.(accountId);
|
||||
},
|
||||
} satisfies NonNullable<ChannelPlugin<ResolvedWhatsAppAccount>["setupWizard"]>;
|
||||
|
||||
export const whatsappSetupPlugin: ChannelPlugin<ResolvedWhatsAppAccount> = {
|
||||
id: "whatsapp",
|
||||
meta: {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { buildAccountScopedAllowlistConfigEditor } from "openclaw/plugin-sdk/compat";
|
||||
import { buildAccountScopedAllowlistConfigEditor } from "../../../src/plugin-sdk-internal/channel-config.js";
|
||||
import {
|
||||
buildChannelConfigSchema,
|
||||
buildAccountScopedDmSecurityPolicy,
|
||||
@ -24,7 +24,7 @@ import {
|
||||
WhatsAppConfigSchema,
|
||||
type ChannelMessageActionName,
|
||||
type ChannelPlugin,
|
||||
} from "openclaw/plugin-sdk/whatsapp";
|
||||
} from "../../../src/plugin-sdk-internal/whatsapp.js";
|
||||
import { isWhatsAppGroupJid, normalizeWhatsAppTarget } from "../../../src/whatsapp/normalize.js";
|
||||
// WhatsApp-specific imports from local extension code (moved from src/web/ and src/channels/plugins/)
|
||||
import {
|
||||
@ -34,16 +34,13 @@ import {
|
||||
type ResolvedWhatsAppAccount,
|
||||
} from "./accounts.js";
|
||||
import { looksLikeWhatsAppTargetId, normalizeWhatsAppMessagingTarget } from "./normalize.js";
|
||||
import { whatsappSetupWizardProxy } from "./plugin-shared.js";
|
||||
import { getWhatsAppRuntime } from "./runtime.js";
|
||||
import { whatsappSetupAdapter } from "./setup-core.js";
|
||||
import { collectWhatsAppStatusIssues } from "./status-issues.js";
|
||||
|
||||
const meta = getChatChannelMeta("whatsapp");
|
||||
|
||||
async function loadWhatsAppChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
function normalizeWhatsAppPayloadText(text: string | undefined): string {
|
||||
return (text ?? "").replace(/^(?:[ \t]*\r?\n)+/, "");
|
||||
}
|
||||
@ -59,51 +56,6 @@ function parseWhatsAppExplicitTarget(raw: string) {
|
||||
};
|
||||
}
|
||||
|
||||
const whatsappSetupWizardProxy = {
|
||||
channel: "whatsapp",
|
||||
status: {
|
||||
configuredLabel: "linked",
|
||||
unconfiguredLabel: "not linked",
|
||||
configuredHint: "linked",
|
||||
unconfiguredHint: "not linked",
|
||||
configuredScore: 5,
|
||||
unconfiguredScore: 4,
|
||||
resolveConfigured: async ({ cfg }) =>
|
||||
await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.status.resolveConfigured({
|
||||
cfg,
|
||||
}),
|
||||
resolveStatusLines: async ({ cfg, configured }) =>
|
||||
(await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.status.resolveStatusLines?.({
|
||||
cfg,
|
||||
configured,
|
||||
})) ?? [],
|
||||
},
|
||||
resolveShouldPromptAccountIds: (params) =>
|
||||
(params.shouldPromptAccountIds || params.options?.promptWhatsAppAccountId) ?? false,
|
||||
credentials: [],
|
||||
finalize: async (params) =>
|
||||
await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.finalize!(params),
|
||||
disable: (cfg) => ({
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
whatsapp: {
|
||||
...cfg.channels?.whatsapp,
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
onAccountRecorded: (accountId, options) => {
|
||||
options?.onWhatsAppAccountId?.(accountId);
|
||||
},
|
||||
} satisfies NonNullable<ChannelPlugin<ResolvedWhatsAppAccount>["setupWizard"]>;
|
||||
|
||||
export const whatsappPlugin: ChannelPlugin<ResolvedWhatsAppAccount> = {
|
||||
id: "whatsapp",
|
||||
meta: {
|
||||
|
||||
51
extensions/whatsapp/src/plugin-shared.ts
Normal file
51
extensions/whatsapp/src/plugin-shared.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { type ChannelPlugin } from "../../../src/plugin-sdk-internal/whatsapp.js";
|
||||
import { type ResolvedWhatsAppAccount } from "./accounts.js";
|
||||
|
||||
async function loadWhatsAppChannelRuntime() {
|
||||
return await import("./channel.runtime.js");
|
||||
}
|
||||
|
||||
export const whatsappSetupWizardProxy = {
|
||||
channel: "whatsapp",
|
||||
status: {
|
||||
configuredLabel: "linked",
|
||||
unconfiguredLabel: "not linked",
|
||||
configuredHint: "linked",
|
||||
unconfiguredHint: "not linked",
|
||||
configuredScore: 5,
|
||||
unconfiguredScore: 4,
|
||||
resolveConfigured: async ({ cfg }) =>
|
||||
await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.status.resolveConfigured({
|
||||
cfg,
|
||||
}),
|
||||
resolveStatusLines: async ({ cfg, configured }) =>
|
||||
(await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.status.resolveStatusLines?.({
|
||||
cfg,
|
||||
configured,
|
||||
})) ?? [],
|
||||
},
|
||||
resolveShouldPromptAccountIds: (params) =>
|
||||
(params.shouldPromptAccountIds || params.options?.promptWhatsAppAccountId) ?? false,
|
||||
credentials: [],
|
||||
finalize: async (params) =>
|
||||
await (
|
||||
await loadWhatsAppChannelRuntime()
|
||||
).whatsappSetupWizard.finalize!(params),
|
||||
disable: (cfg) => ({
|
||||
...cfg,
|
||||
channels: {
|
||||
...cfg.channels,
|
||||
whatsapp: {
|
||||
...cfg.channels?.whatsapp,
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
onAccountRecorded: (accountId, options) => {
|
||||
options?.onWhatsAppAccountId?.(accountId);
|
||||
},
|
||||
} satisfies NonNullable<ChannelPlugin<ResolvedWhatsAppAccount>["setupWizard"]>;
|
||||
@ -1,5 +1,7 @@
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/compat";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/core";
|
||||
import {
|
||||
createPluginRuntimeStore,
|
||||
type PluginRuntime,
|
||||
} from "../../../src/plugin-sdk-internal/core.js";
|
||||
|
||||
const { setRuntime: setWhatsAppRuntime, getRuntime: getWhatsAppRuntime } =
|
||||
createPluginRuntimeStore<PluginRuntime>("WhatsApp runtime not initialized");
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
type OpenClawConfig,
|
||||
} from "../../../src/plugin-sdk-internal/setup.js";
|
||||
import type { ChannelSetupWizard } from "../../../src/plugin-sdk-internal/setup.js";
|
||||
import { type DmPolicy } from "../../../src/plugin-sdk-internal/whatsapp.js";
|
||||
import { listWhatsAppAccountIds, resolveWhatsAppAuthDir } from "./accounts.js";
|
||||
import { loginWeb } from "./login.js";
|
||||
import { whatsappSetupAdapter } from "./setup-core.js";
|
||||
|
||||
@ -402,7 +402,6 @@ export function installChannelDirectoryContractSuite(params: {
|
||||
if (params.invokeLookups === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
const self = await directory?.self?.({
|
||||
cfg: {} as OpenClawConfig,
|
||||
accountId: "default",
|
||||
|
||||
@ -3,6 +3,10 @@ export type { OpenClawConfig } from "../config/config.js";
|
||||
export { createAccountActionGate } from "../channels/plugins/account-action-gate.js";
|
||||
export { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
||||
export { normalizeChatType } from "../channels/chat-type.js";
|
||||
export {
|
||||
listConfiguredAccountIds,
|
||||
resolveAccountWithDefaultFallback,
|
||||
} from "../plugin-sdk/account-resolution.js";
|
||||
export { resolveAccountEntry } from "../routing/account-lookup.js";
|
||||
export { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js";
|
||||
export { normalizeE164, pathExists, resolveUserPath } from "../utils.js";
|
||||
|
||||
17
src/plugin-sdk-internal/channel-config.ts
Normal file
17
src/plugin-sdk-internal/channel-config.ts
Normal file
@ -0,0 +1,17 @@
|
||||
// Private bridge for bundled channel plugins. These config helpers are shared
|
||||
// internally, but do not belong on the public compat surface.
|
||||
export { buildAccountScopedAllowlistConfigEditor } from "../plugin-sdk/allowlist-config-edit.js";
|
||||
export { formatAllowFromLowercase } from "../plugin-sdk/allow-from.js";
|
||||
export {
|
||||
createScopedAccountConfigAccessors,
|
||||
createScopedChannelConfigBase,
|
||||
createScopedDmSecurityResolver,
|
||||
} from "../plugin-sdk/channel-config-helpers.js";
|
||||
export {
|
||||
collectAllowlistProviderGroupPolicyWarnings,
|
||||
collectAllowlistProviderRestrictSendersWarnings,
|
||||
collectOpenGroupPolicyConfiguredRouteWarnings,
|
||||
collectOpenGroupPolicyRouteAllowlistWarnings,
|
||||
collectOpenProviderGroupPolicyWarnings,
|
||||
} from "../channels/plugins/group-policy-warnings.js";
|
||||
export { buildAccountScopedDmSecurityPolicy } from "../channels/plugins/helpers.js";
|
||||
14
src/plugin-sdk-internal/core.ts
Normal file
14
src/plugin-sdk-internal/core.ts
Normal file
@ -0,0 +1,14 @@
|
||||
// Private bridge for bundled channel plugins. Keep public sdk/core slim for
|
||||
// third-party plugins; bundled channels can reach shared runtime helpers here.
|
||||
export type {
|
||||
ChannelMessageActionContext,
|
||||
OpenClawPluginApi,
|
||||
PluginRuntime,
|
||||
} from "../plugin-sdk/channel-plugin-common.js";
|
||||
export { createPluginRuntimeStore } from "../plugin-sdk/runtime-store.js";
|
||||
export {
|
||||
buildAgentSessionKey,
|
||||
type RoutePeer,
|
||||
type RoutePeerKind,
|
||||
} from "../routing/resolve-route.js";
|
||||
export { resolveThreadSessionKeys } from "../routing/session-key.js";
|
||||
@ -11,6 +11,7 @@ export {
|
||||
resolveIMessageConfigAllowFrom,
|
||||
resolveIMessageConfigDefaultTo,
|
||||
} from "../plugin-sdk/channel-config-helpers.js";
|
||||
export { isAllowedParsedChatSender } from "../plugin-sdk/allow-from.js";
|
||||
export {
|
||||
looksLikeIMessageTargetId,
|
||||
normalizeIMessageMessagingTarget,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
export type { ChannelMessageActionAdapter } from "../channels/plugins/types.js";
|
||||
export type { OpenClawConfig } from "../config/config.js";
|
||||
export type { ResolvedSignalAccount } from "../../extensions/signal/src/accounts.js";
|
||||
export type { SignalAccountConfig } from "../config/types.js";
|
||||
export * from "../plugin-sdk/channel-plugin-common.js";
|
||||
@ -23,6 +24,7 @@ export {
|
||||
resolveAllowlistProviderRuntimeGroupPolicy,
|
||||
resolveDefaultGroupPolicy,
|
||||
} from "../config/runtime-group-policy.js";
|
||||
export { evaluateSenderGroupAccessForPolicy } from "../plugin-sdk/group-access.js";
|
||||
export { signalSetupWizard } from "../../extensions/signal/src/setup-surface.js";
|
||||
export { signalSetupAdapter } from "../../extensions/signal/src/setup-core.js";
|
||||
export { SignalConfigSchema } from "../config/zod-schema.providers-core.js";
|
||||
|
||||
@ -7,7 +7,11 @@ export type { ChannelPlugin } from "../channels/plugins/types.plugin.js";
|
||||
export type { OpenClawConfig } from "../config/config.js";
|
||||
export type { PluginRuntime } from "../plugins/runtime/types.js";
|
||||
export type { OpenClawPluginApi } from "../plugins/types.js";
|
||||
export type { TelegramAccountConfig, TelegramActionConfig } from "../config/types.js";
|
||||
export type {
|
||||
TelegramAccountConfig,
|
||||
TelegramActionConfig,
|
||||
TelegramNetworkConfig,
|
||||
} from "../config/types.js";
|
||||
export type { InspectedTelegramAccount } from "../../extensions/telegram/src/account-inspect.js";
|
||||
export type { ResolvedTelegramAccount } from "../../extensions/telegram/src/accounts.js";
|
||||
export type { TelegramProbe } from "../../extensions/telegram/src/probe.js";
|
||||
@ -102,6 +106,9 @@ export {
|
||||
resolveAllowlistProviderRuntimeGroupPolicy,
|
||||
resolveDefaultGroupPolicy,
|
||||
} from "../config/runtime-group-policy.js";
|
||||
export { readBooleanParam } from "../plugin-sdk/boolean-param.js";
|
||||
export { evaluateMatchedGroupAccessForPolicy } from "../plugin-sdk/group-access.js";
|
||||
export { extractToolSend } from "../plugin-sdk/tool-send.js";
|
||||
export {
|
||||
resolveTelegramGroupRequireMention,
|
||||
resolveTelegramGroupToolPolicy,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user