mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 15:50:46 +00:00
fix(plugin-sdk): restore discord compatibility facade
This commit is contained in:
@@ -12,6 +12,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Plugin SDK/Discord: restore a deprecated `openclaw/plugin-sdk/discord` compatibility facade and the legacy compat group-policy warning export for the published `@openclaw/discord@2026.3.13` package, covering its config, account, directory, status, and thread-binding imports while keeping new plugins on generic SDK subpaths. Fixes #73685; supersedes #73703. Thanks @rderickson9 and @SymbolStar.
|
||||
- Channels/Discord: suppress duplicate gateway monitors when multiple enabled accounts resolve to the same bot token, preferring config tokens over default env fallback and reporting skipped duplicates as disabled. Supersedes #73608. Thanks @kagura-agent.
|
||||
- Control UI/Talk: decode Google Live binary WebSocket JSON frames and stop queued browser audio on interruption or shutdown, so browser Talk leaves `Connecting Talk...` and barge-in no longer plays stale audio. Fixes #73601 and #73460; supersedes #73466. Thanks @Spolen23 and @WadydX.
|
||||
- Channels/Discord: ignore stale route-shaped conversation bindings after a Discord channel is reconfigured to another agent, while preserving explicit focus and subagent bindings. Fixes #73626. Thanks @ramitrkar-hash.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
7da4f3439785b85e93740640efce5ca2e6eb0024139a6585641fb995f9b3830c plugin-sdk-api-baseline.json
|
||||
91d40edb771792303d91a5d188ec1e6d77647c46866733ad65bf16d6a57348ba plugin-sdk-api-baseline.jsonl
|
||||
46476e7b4fee105ca27aed9c769c507f70f02b8ce8586c135feb18e751db0de1 plugin-sdk-api-baseline.json
|
||||
4bc1c0dc66d910c80694fa1a6b7ba3ab488bf737b3566e53b8a5857c16d2e0b1 plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -545,10 +545,12 @@ surface. The full list of 200+ entrypoints lives in
|
||||
`scripts/lib/plugin-sdk-entrypoints.json`.
|
||||
|
||||
Reserved bundled-plugin helper seams have been retired from the public SDK
|
||||
export map. Owner-specific helpers live inside the owning plugin package; shared
|
||||
host behavior should move through generic SDK contracts such as
|
||||
`plugin-sdk/gateway-runtime`, `plugin-sdk/security-runtime`, and
|
||||
`plugin-sdk/plugin-config-runtime`.
|
||||
export map except for explicitly documented compatibility facades such as the
|
||||
deprecated `plugin-sdk/discord` shim retained for the published
|
||||
`@openclaw/discord@2026.3.13` package. Owner-specific helpers live inside the
|
||||
owning plugin package; shared host behavior should move through generic SDK
|
||||
contracts such as `plugin-sdk/gateway-runtime`, `plugin-sdk/security-runtime`,
|
||||
and `plugin-sdk/plugin-config-runtime`.
|
||||
|
||||
Use the narrowest import that matches the job. If you cannot find an export,
|
||||
check the source at `src/plugin-sdk/` or ask maintainers which generic contract
|
||||
|
||||
@@ -50,6 +50,10 @@ A small set of bundled-plugin helper seams still appear in the generated export
|
||||
map when they have tracked owner usage. They exist for bundled-plugin
|
||||
maintenance only and are not recommended import paths for new third-party
|
||||
plugins.
|
||||
|
||||
`openclaw/plugin-sdk/discord` is also kept as a deprecated compatibility facade
|
||||
for the published `@openclaw/discord@2026.3.13` package. Do not copy that import
|
||||
path into new plugins; use the generic channel SDK subpaths instead.
|
||||
</Warning>
|
||||
|
||||
## Subpath reference
|
||||
|
||||
@@ -84,6 +84,7 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview)
|
||||
| `plugin-sdk/allowlist-config-edit` | Allowlist config edit/read helpers |
|
||||
| `plugin-sdk/group-access` | Shared group-access decision helpers |
|
||||
| `plugin-sdk/direct-dm` | Shared direct-DM auth/guard helpers |
|
||||
| `plugin-sdk/discord` | Deprecated Discord compatibility facade for published `@openclaw/discord@2026.3.13`; new plugins should use generic channel SDK subpaths |
|
||||
| `plugin-sdk/interactive-runtime` | Semantic message presentation, delivery, and legacy interactive reply helpers. See [Message Presentation](/plugins/message-presentation) |
|
||||
| `plugin-sdk/channel-inbound` | Compatibility barrel for inbound debounce, mention matching, mention-policy helpers, and envelope helpers |
|
||||
| `plugin-sdk/channel-inbound-debounce` | Narrow inbound debounce helpers |
|
||||
|
||||
@@ -664,6 +664,10 @@
|
||||
"types": "./dist/plugin-sdk/direct-dm-guard-policy.d.ts",
|
||||
"default": "./dist/plugin-sdk/direct-dm-guard-policy.js"
|
||||
},
|
||||
"./plugin-sdk/discord": {
|
||||
"types": "./dist/plugin-sdk/discord.d.ts",
|
||||
"default": "./dist/plugin-sdk/discord.js"
|
||||
},
|
||||
"./plugin-sdk/device-bootstrap": {
|
||||
"types": "./dist/plugin-sdk/device-bootstrap.d.ts",
|
||||
"default": "./dist/plugin-sdk/device-bootstrap.js"
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
"direct-dm",
|
||||
"direct-dm-access",
|
||||
"direct-dm-guard-policy",
|
||||
"discord",
|
||||
"device-bootstrap",
|
||||
"diagnostic-runtime",
|
||||
"error-runtime",
|
||||
|
||||
@@ -25,6 +25,7 @@ export {
|
||||
buildOpenGroupPolicyWarning,
|
||||
collectAllowlistProviderGroupPolicyWarnings,
|
||||
collectAllowlistProviderRestrictSendersWarnings,
|
||||
collectOpenGroupPolicyConfiguredRouteWarnings,
|
||||
collectOpenGroupPolicyRestrictSendersWarnings,
|
||||
collectOpenGroupPolicyRouteAllowlistWarnings,
|
||||
collectOpenProviderGroupPolicyWarnings,
|
||||
|
||||
@@ -61,6 +61,7 @@ export {
|
||||
export { formatAllowFromLowercase, formatNormalizedAllowFromEntries } from "./allow-from.js";
|
||||
export * from "./channel-config-schema.js";
|
||||
export * from "./channel-policy.js";
|
||||
export { collectOpenGroupPolicyConfiguredRouteWarnings } from "./channel-policy.js";
|
||||
export * from "./reply-history.js";
|
||||
export * from "./directory-runtime.js";
|
||||
export { mapAllowlistResolutionInputs } from "./allow-from.js";
|
||||
|
||||
135
src/plugin-sdk/discord.test.ts
Normal file
135
src/plugin-sdk/discord.test.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const mocks = vi.hoisted(() => {
|
||||
const runtimeConfig = { channels: { discord: { token: "token" } } };
|
||||
const apiModule = {
|
||||
collectDiscordStatusIssues: vi.fn(() => []),
|
||||
discordOnboardingAdapter: { kind: "legacy-onboarding" },
|
||||
inspectDiscordAccount: vi.fn(() => ({ accountId: "default" })),
|
||||
listDiscordAccountIds: vi.fn(() => ["default"]),
|
||||
listDiscordDirectoryGroupsFromConfig: vi.fn(() => []),
|
||||
listDiscordDirectoryPeersFromConfig: vi.fn(() => []),
|
||||
looksLikeDiscordTargetId: vi.fn(() => true),
|
||||
normalizeDiscordMessagingTarget: vi.fn(() => "channel:123"),
|
||||
normalizeDiscordOutboundTarget: vi.fn(() => ({ ok: true, to: "channel:123" })),
|
||||
resolveDefaultDiscordAccountId: vi.fn(() => "default"),
|
||||
resolveDiscordAccount: vi.fn(() => ({
|
||||
accountId: "default",
|
||||
config: {},
|
||||
enabled: true,
|
||||
token: "token",
|
||||
tokenSource: "config",
|
||||
})),
|
||||
resolveDiscordGroupRequireMention: vi.fn(() => true),
|
||||
resolveDiscordGroupToolPolicy: vi.fn(() => undefined),
|
||||
};
|
||||
const runtimeModule = {
|
||||
autoBindSpawnedDiscordSubagent: vi.fn(async (params) => ({
|
||||
accountId: params.accountId ?? "default",
|
||||
channelId: "123",
|
||||
targetKind: "subagent",
|
||||
targetSessionKey: params.childSessionKey,
|
||||
threadId: "456",
|
||||
cfg: params.cfg,
|
||||
})),
|
||||
collectDiscordAuditChannelIds: vi.fn(() => ({ channelIds: [], unresolvedChannels: [] })),
|
||||
listThreadBindingsBySessionKey: vi.fn(() => []),
|
||||
unbindThreadBindingsBySessionKey: vi.fn(() => []),
|
||||
};
|
||||
|
||||
return {
|
||||
apiModule,
|
||||
runtimeModule,
|
||||
runtimeConfig,
|
||||
loadBundledPluginPublicSurfaceModuleSync: vi.fn((params: { artifactBasename: string }) => {
|
||||
if (params.artifactBasename === "runtime-api.js") {
|
||||
return runtimeModule;
|
||||
}
|
||||
return apiModule;
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./facade-loader.js", () => ({
|
||||
createLazyFacadeObjectValue: (load: () => object) =>
|
||||
new Proxy(
|
||||
{},
|
||||
{
|
||||
get(_target, property) {
|
||||
return Reflect.get(load(), property);
|
||||
},
|
||||
},
|
||||
),
|
||||
loadBundledPluginPublicSurfaceModuleSync: mocks.loadBundledPluginPublicSurfaceModuleSync,
|
||||
}));
|
||||
|
||||
vi.mock("./runtime-config-snapshot.js", () => ({
|
||||
getRuntimeConfig: () => mocks.runtimeConfig,
|
||||
getRuntimeConfigSnapshot: () => mocks.runtimeConfig,
|
||||
}));
|
||||
|
||||
describe("discord plugin-sdk compatibility facade", () => {
|
||||
it("exports the @openclaw/discord 2026.3.13 import surface", async () => {
|
||||
const discordSdk = await import("./discord.js");
|
||||
|
||||
for (const exportName of [
|
||||
"DEFAULT_ACCOUNT_ID",
|
||||
"DiscordConfigSchema",
|
||||
"PAIRING_APPROVED_MESSAGE",
|
||||
"applyAccountNameToChannelSection",
|
||||
"autoBindSpawnedDiscordSubagent",
|
||||
"buildChannelConfigSchema",
|
||||
"buildComputedAccountStatusSnapshot",
|
||||
"buildTokenChannelStatusSummary",
|
||||
"collectDiscordAuditChannelIds",
|
||||
"collectDiscordStatusIssues",
|
||||
"discordOnboardingAdapter",
|
||||
"emptyPluginConfigSchema",
|
||||
"getChatChannelMeta",
|
||||
"inspectDiscordAccount",
|
||||
"listDiscordAccountIds",
|
||||
"listDiscordDirectoryGroupsFromConfig",
|
||||
"listDiscordDirectoryPeersFromConfig",
|
||||
"listThreadBindingsBySessionKey",
|
||||
"looksLikeDiscordTargetId",
|
||||
"migrateBaseNameToDefaultAccount",
|
||||
"normalizeAccountId",
|
||||
"normalizeDiscordMessagingTarget",
|
||||
"normalizeDiscordOutboundTarget",
|
||||
"projectCredentialSnapshotFields",
|
||||
"resolveConfiguredFromCredentialStatuses",
|
||||
"resolveDefaultDiscordAccountId",
|
||||
"resolveDiscordAccount",
|
||||
"resolveDiscordGroupRequireMention",
|
||||
"resolveDiscordGroupToolPolicy",
|
||||
"unbindThreadBindingsBySessionKey",
|
||||
]) {
|
||||
expect(discordSdk).toHaveProperty(exportName);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps legacy Discord subagent auto-bind calls working without cfg", async () => {
|
||||
const { autoBindSpawnedDiscordSubagent } = await import("./discord.js");
|
||||
|
||||
const binding = await autoBindSpawnedDiscordSubagent({
|
||||
agentId: "agent",
|
||||
channel: "discord",
|
||||
childSessionKey: "child",
|
||||
});
|
||||
|
||||
expect(mocks.runtimeModule.autoBindSpawnedDiscordSubagent).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
agentId: "agent",
|
||||
cfg: mocks.runtimeConfig,
|
||||
childSessionKey: "child",
|
||||
}),
|
||||
);
|
||||
expect(binding).toEqual(
|
||||
expect.objectContaining({
|
||||
cfg: mocks.runtimeConfig,
|
||||
targetKind: "subagent",
|
||||
targetSessionKey: "child",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
248
src/plugin-sdk/discord.ts
Normal file
248
src/plugin-sdk/discord.ts
Normal file
@@ -0,0 +1,248 @@
|
||||
import type {
|
||||
ChannelAccountSnapshot,
|
||||
ChannelGroupContext,
|
||||
ChannelMessageActionAdapter,
|
||||
ChannelStatusIssue,
|
||||
} from "./channel-contract.js";
|
||||
import type { ChannelPlugin } from "./channel-core.js";
|
||||
import type { OpenClawConfig } from "./config-types.js";
|
||||
import {
|
||||
createLazyFacadeObjectValue,
|
||||
loadBundledPluginPublicSurfaceModuleSync,
|
||||
} from "./facade-loader.js";
|
||||
import { getRuntimeConfig, getRuntimeConfigSnapshot } from "./runtime-config-snapshot.js";
|
||||
|
||||
export type { ChannelMessageActionAdapter, ChannelMessageActionName } from "./channel-contract.js";
|
||||
export type { ChannelPlugin } from "./channel-core.js";
|
||||
export type { OpenClawConfig } from "./config-types.js";
|
||||
export type { OpenClawPluginApi, PluginRuntime } from "./channel-plugin-common.js";
|
||||
|
||||
export {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
applyAccountNameToChannelSection,
|
||||
buildChannelConfigSchema,
|
||||
emptyPluginConfigSchema,
|
||||
getChatChannelMeta,
|
||||
migrateBaseNameToDefaultAccount,
|
||||
normalizeAccountId,
|
||||
PAIRING_APPROVED_MESSAGE,
|
||||
} from "./channel-plugin-common.js";
|
||||
export {
|
||||
buildComputedAccountStatusSnapshot,
|
||||
buildTokenChannelStatusSummary,
|
||||
projectCredentialSnapshotFields,
|
||||
resolveConfiguredFromCredentialStatuses,
|
||||
} from "./channel-status.js";
|
||||
export { DiscordConfigSchema } from "./bundled-channel-config-schema.js";
|
||||
|
||||
export type DiscordAccountConfig = NonNullable<NonNullable<OpenClawConfig["channels"]>["discord"]>;
|
||||
|
||||
export type ResolvedDiscordAccount = {
|
||||
accountId: string;
|
||||
enabled: boolean;
|
||||
name?: string;
|
||||
token: string;
|
||||
tokenSource: "env" | "config" | "none";
|
||||
config: DiscordAccountConfig;
|
||||
};
|
||||
|
||||
export type DiscordOutboundTargetResolution =
|
||||
| { ok: true; to: string }
|
||||
| { ok: false; error: Error };
|
||||
|
||||
export type ThreadBindingTargetKind = "subagent" | "acp";
|
||||
|
||||
export type ThreadBindingRecord = {
|
||||
accountId: string;
|
||||
threadId: string;
|
||||
channelId?: string;
|
||||
targetKind: ThreadBindingTargetKind;
|
||||
targetSessionKey: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
type DirectoryConfigParams = {
|
||||
cfg: OpenClawConfig;
|
||||
accountId?: string | null;
|
||||
};
|
||||
|
||||
type DiscordApiFacadeModule = {
|
||||
collectDiscordStatusIssues: (accounts: ChannelAccountSnapshot[]) => ChannelStatusIssue[];
|
||||
discordOnboardingAdapter?: NonNullable<ChannelPlugin<ResolvedDiscordAccount>["setup"]>;
|
||||
inspectDiscordAccount: (params: { cfg: OpenClawConfig; accountId?: string | null }) => unknown;
|
||||
listDiscordAccountIds: (cfg: OpenClawConfig) => string[];
|
||||
listDiscordDirectoryGroupsFromConfig: (
|
||||
params: DirectoryConfigParams,
|
||||
) => unknown[] | Promise<unknown[]>;
|
||||
listDiscordDirectoryPeersFromConfig: (
|
||||
params: DirectoryConfigParams,
|
||||
) => unknown[] | Promise<unknown[]>;
|
||||
looksLikeDiscordTargetId: (raw: string) => boolean;
|
||||
normalizeDiscordMessagingTarget: (raw: string) => string | undefined;
|
||||
normalizeDiscordOutboundTarget: (to?: string) => DiscordOutboundTargetResolution;
|
||||
resolveDefaultDiscordAccountId: (cfg: OpenClawConfig) => string;
|
||||
resolveDiscordAccount: (params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId?: string | null;
|
||||
}) => ResolvedDiscordAccount;
|
||||
resolveDiscordGroupRequireMention: (params: ChannelGroupContext) => boolean | undefined;
|
||||
resolveDiscordGroupToolPolicy: (params: ChannelGroupContext) => unknown;
|
||||
};
|
||||
|
||||
type DiscordRuntimeFacadeModule = {
|
||||
autoBindSpawnedDiscordSubagent: (params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId?: string;
|
||||
channel?: string;
|
||||
to?: string;
|
||||
threadId?: string | number;
|
||||
childSessionKey: string;
|
||||
agentId: string;
|
||||
label?: string;
|
||||
boundBy?: string;
|
||||
}) => Promise<ThreadBindingRecord | null>;
|
||||
collectDiscordAuditChannelIds: (params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId?: string | null;
|
||||
}) => unknown;
|
||||
listThreadBindingsBySessionKey: (params: {
|
||||
targetSessionKey: string;
|
||||
accountId?: string;
|
||||
targetKind?: ThreadBindingTargetKind;
|
||||
}) => ThreadBindingRecord[];
|
||||
unbindThreadBindingsBySessionKey: (params: {
|
||||
targetSessionKey: string;
|
||||
accountId?: string;
|
||||
targetKind?: ThreadBindingTargetKind;
|
||||
reason?: string;
|
||||
sendFarewell?: boolean;
|
||||
farewellText?: string;
|
||||
}) => ThreadBindingRecord[];
|
||||
};
|
||||
|
||||
function loadDiscordApiFacadeModule(): DiscordApiFacadeModule {
|
||||
return loadBundledPluginPublicSurfaceModuleSync<DiscordApiFacadeModule>({
|
||||
dirName: "discord",
|
||||
artifactBasename: "api.js",
|
||||
});
|
||||
}
|
||||
|
||||
function loadDiscordRuntimeFacadeModule(): DiscordRuntimeFacadeModule {
|
||||
return loadBundledPluginPublicSurfaceModuleSync<DiscordRuntimeFacadeModule>({
|
||||
dirName: "discord",
|
||||
artifactBasename: "runtime-api.js",
|
||||
});
|
||||
}
|
||||
|
||||
function resolveCompatRuntimeConfig(params: { cfg?: OpenClawConfig }): OpenClawConfig {
|
||||
return params.cfg ?? getRuntimeConfigSnapshot() ?? getRuntimeConfig();
|
||||
}
|
||||
|
||||
export const discordOnboardingAdapter = createLazyFacadeObjectValue(
|
||||
() => loadDiscordApiFacadeModule().discordOnboardingAdapter ?? {},
|
||||
);
|
||||
|
||||
export function collectDiscordStatusIssues(
|
||||
accounts: ChannelAccountSnapshot[],
|
||||
): ChannelStatusIssue[] {
|
||||
return loadDiscordApiFacadeModule().collectDiscordStatusIssues(accounts);
|
||||
}
|
||||
|
||||
export function inspectDiscordAccount(params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId?: string | null;
|
||||
}): unknown {
|
||||
return loadDiscordApiFacadeModule().inspectDiscordAccount(params);
|
||||
}
|
||||
|
||||
export function listDiscordAccountIds(cfg: OpenClawConfig): string[] {
|
||||
return loadDiscordApiFacadeModule().listDiscordAccountIds(cfg);
|
||||
}
|
||||
|
||||
export function listDiscordDirectoryGroupsFromConfig(
|
||||
params: DirectoryConfigParams,
|
||||
): unknown[] | Promise<unknown[]> {
|
||||
return loadDiscordApiFacadeModule().listDiscordDirectoryGroupsFromConfig(params);
|
||||
}
|
||||
|
||||
export function listDiscordDirectoryPeersFromConfig(
|
||||
params: DirectoryConfigParams,
|
||||
): unknown[] | Promise<unknown[]> {
|
||||
return loadDiscordApiFacadeModule().listDiscordDirectoryPeersFromConfig(params);
|
||||
}
|
||||
|
||||
export function looksLikeDiscordTargetId(raw: string): boolean {
|
||||
return loadDiscordApiFacadeModule().looksLikeDiscordTargetId(raw);
|
||||
}
|
||||
|
||||
export function normalizeDiscordMessagingTarget(raw: string): string | undefined {
|
||||
return loadDiscordApiFacadeModule().normalizeDiscordMessagingTarget(raw);
|
||||
}
|
||||
|
||||
export function normalizeDiscordOutboundTarget(to?: string): DiscordOutboundTargetResolution {
|
||||
return loadDiscordApiFacadeModule().normalizeDiscordOutboundTarget(to);
|
||||
}
|
||||
|
||||
export function resolveDefaultDiscordAccountId(cfg: OpenClawConfig): string {
|
||||
return loadDiscordApiFacadeModule().resolveDefaultDiscordAccountId(cfg);
|
||||
}
|
||||
|
||||
export function resolveDiscordAccount(params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId?: string | null;
|
||||
}): ResolvedDiscordAccount {
|
||||
return loadDiscordApiFacadeModule().resolveDiscordAccount(params);
|
||||
}
|
||||
|
||||
export function resolveDiscordGroupRequireMention(
|
||||
params: ChannelGroupContext,
|
||||
): boolean | undefined {
|
||||
return loadDiscordApiFacadeModule().resolveDiscordGroupRequireMention(params);
|
||||
}
|
||||
|
||||
export function resolveDiscordGroupToolPolicy(params: ChannelGroupContext): unknown {
|
||||
return loadDiscordApiFacadeModule().resolveDiscordGroupToolPolicy(params);
|
||||
}
|
||||
|
||||
export function collectDiscordAuditChannelIds(params: {
|
||||
cfg: OpenClawConfig;
|
||||
accountId?: string | null;
|
||||
}): unknown {
|
||||
return loadDiscordRuntimeFacadeModule().collectDiscordAuditChannelIds(params);
|
||||
}
|
||||
|
||||
export async function autoBindSpawnedDiscordSubagent(params: {
|
||||
cfg?: OpenClawConfig;
|
||||
accountId?: string;
|
||||
channel?: string;
|
||||
to?: string;
|
||||
threadId?: string | number;
|
||||
childSessionKey: string;
|
||||
agentId: string;
|
||||
label?: string;
|
||||
boundBy?: string;
|
||||
}): Promise<ThreadBindingRecord | null> {
|
||||
return await loadDiscordRuntimeFacadeModule().autoBindSpawnedDiscordSubagent({
|
||||
...params,
|
||||
cfg: resolveCompatRuntimeConfig(params),
|
||||
});
|
||||
}
|
||||
|
||||
export function listThreadBindingsBySessionKey(params: {
|
||||
targetSessionKey: string;
|
||||
accountId?: string;
|
||||
targetKind?: ThreadBindingTargetKind;
|
||||
}): ThreadBindingRecord[] {
|
||||
return loadDiscordRuntimeFacadeModule().listThreadBindingsBySessionKey(params);
|
||||
}
|
||||
|
||||
export function unbindThreadBindingsBySessionKey(params: {
|
||||
targetSessionKey: string;
|
||||
accountId?: string;
|
||||
targetKind?: ThreadBindingTargetKind;
|
||||
reason?: string;
|
||||
sendFarewell?: boolean;
|
||||
farewellText?: string;
|
||||
}): ThreadBindingRecord[] {
|
||||
return loadDiscordRuntimeFacadeModule().unbindThreadBindingsBySessionKey(params);
|
||||
}
|
||||
@@ -11,6 +11,7 @@ export const reservedBundledPluginSdkEntrypoints = [] as const;
|
||||
// Supported SDK facades backed by bundled plugins. These are intentionally public
|
||||
// until they move to generic, plugin-neutral contracts.
|
||||
export const supportedBundledFacadeSdkEntrypoints = [
|
||||
"discord",
|
||||
"lmstudio",
|
||||
"lmstudio-runtime",
|
||||
"memory-core-engine-runtime",
|
||||
|
||||
@@ -462,7 +462,7 @@ describe("plugin-sdk subpath exports", () => {
|
||||
});
|
||||
|
||||
it("keeps removed bundled-channel aliases out of the public sdk list", () => {
|
||||
const removedChannelAliases = new Set(["discord", "signal", "slack", "telegram", "whatsapp"]);
|
||||
const removedChannelAliases = new Set(["signal", "slack", "telegram", "whatsapp"]);
|
||||
const banned = pluginSdkSubpaths.filter((subpath) => removedChannelAliases.has(subpath));
|
||||
expect(banned).toEqual([]);
|
||||
});
|
||||
@@ -640,6 +640,7 @@ describe("plugin-sdk subpath exports", () => {
|
||||
expectSourceMentions("compat", [
|
||||
"createPluginRuntimeStore",
|
||||
"createScopedChannelConfigAdapter",
|
||||
"collectOpenGroupPolicyConfiguredRouteWarnings",
|
||||
"resolveControlCommandGate",
|
||||
"delegateCompactionToRuntime",
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user