perf: decouple plugin facades from extension types

This commit is contained in:
Peter Steinberger
2026-04-18 22:04:42 +01:00
parent 127bafa0b9
commit e069169765
41 changed files with 1576 additions and 162 deletions

View File

@@ -1,2 +1,2 @@
0a7db1dbcb8d4a58aa9533164929f08e2ed6ee37bb29bf302590a478c55c363a plugin-sdk-api-baseline.json
f1fb149181511750b30d1ee9638d17a0dc6a332db2e32a9a599cb9aeb40b4e1f plugin-sdk-api-baseline.jsonl
20db3f5afb93db334ad7456d26303c81b2a3eeaa5c1f8846a459eec72be20b96 plugin-sdk-api-baseline.json
d02926e9facb3321a1018804d4c0370d9627963bee5e478942dda469e529c20b plugin-sdk-api-baseline.jsonl

View File

@@ -1,7 +1,11 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/anthropic/api.js");
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
CLAUDE_CLI_BACKEND_ID: string;
isClaudeCliProvider: (providerId: string) => boolean;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "anthropic",

View File

@@ -1,6 +1,22 @@
type FacadeModule = typeof import("@openclaw/anthropic-vertex/api.js");
import type { ModelProviderConfig } from "../config/types.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
resolveAnthropicVertexClientRegion: (params?: {
baseUrl?: string;
env?: NodeJS.ProcessEnv;
}) => string;
resolveAnthropicVertexProjectId: (env?: NodeJS.ProcessEnv) => string | undefined;
buildAnthropicVertexProvider: (params?: { env?: NodeJS.ProcessEnv }) => ModelProviderConfig;
resolveImplicitAnthropicVertexProvider: (params?: {
env?: NodeJS.ProcessEnv;
}) => ModelProviderConfig | null;
mergeImplicitAnthropicVertexProvider: (params: {
existing?: ModelProviderConfig;
implicit: ModelProviderConfig;
}) => ModelProviderConfig;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "anthropic-vertex",

View File

@@ -1,7 +1,32 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/bluebubbles/api.js");
import type { OpenClawConfig } from "../config/types.js";
import type { GroupToolPolicyConfig } from "../config/types.tools.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type BlueBubblesGroupContext = {
cfg: OpenClawConfig;
accountId?: string | null;
groupId?: string | null;
senderId?: string | null;
senderName?: string | null;
senderUsername?: string | null;
senderE164?: string | null;
};
type FacadeModule = {
isAllowedBlueBubblesSender: (params: {
allowFrom: Array<string | number>;
sender: string;
chatId?: number | null;
chatGuid?: string | null;
chatIdentifier?: string | null;
}) => boolean;
resolveBlueBubblesGroupRequireMention: (params: BlueBubblesGroupContext) => boolean;
resolveBlueBubblesGroupToolPolicy: (
params: BlueBubblesGroupContext,
) => GroupToolPolicyConfig | undefined;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "bluebubbles",

View File

@@ -1,11 +1,75 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/feishu/contract-api.js");
import type { OpenClawConfig } from "../config/types.js";
import type { BindingTargetKind } from "../infra/outbound/session-binding-service.js";
import {
createLazyFacadeArrayValue,
createLazyFacadeObjectValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
type FeishuGroupSessionScope = "group" | "group_sender" | "group_topic" | "group_topic_sender";
type FeishuThreadBindingRecord = {
accountId: string;
conversationId: string;
parentConversationId?: string;
deliveryTo?: string;
deliveryThreadId?: string;
targetKind: "subagent" | "acp";
targetSessionKey: string;
agentId?: string;
label?: string;
boundBy?: string;
boundAt: number;
lastActivityAt: number;
};
type FeishuThreadBindingManager = {
accountId: string;
getByConversationId: (conversationId: string) => FeishuThreadBindingRecord | undefined;
listBySessionKey: (targetSessionKey: string) => FeishuThreadBindingRecord[];
bindConversation: (params: {
conversationId: string;
parentConversationId?: string;
targetKind: BindingTargetKind;
targetSessionKey: string;
metadata?: Record<string, unknown>;
}) => FeishuThreadBindingRecord | null;
touchConversation: (conversationId: string, at?: number) => FeishuThreadBindingRecord | null;
unbindConversation: (conversationId: string) => FeishuThreadBindingRecord | null;
unbindBySessionKey: (targetSessionKey: string) => FeishuThreadBindingRecord[];
stop: () => void;
};
type FacadeModule = {
buildFeishuConversationId: (params: {
chatId: string;
scope: FeishuGroupSessionScope;
senderOpenId?: string;
topicId?: string;
}) => string;
createFeishuThreadBindingManager: (params: {
accountId?: string;
cfg: OpenClawConfig;
}) => FeishuThreadBindingManager;
feishuSessionBindingAdapterChannels: readonly ["feishu"];
feishuThreadBindingTesting: {
resetFeishuThreadBindingsForTests: () => void;
};
parseFeishuDirectConversationId: (raw: unknown) => string | undefined;
parseFeishuConversationId: (params: {
conversationId: string;
parentConversationId?: string;
}) => {
canonicalConversationId: string;
chatId: string;
topicId?: string;
senderOpenId?: string;
scope: FeishuGroupSessionScope;
} | null;
parseFeishuTargetId: (raw: unknown) => string | undefined;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "feishu",

View File

@@ -1,7 +1,12 @@
// Manual facade. Keep loader boundary explicit.
type SecuritySurface = typeof import("@openclaw/feishu/security-contract-api.js");
import type { OpenClawConfig } from "../config/types.js";
import type { SecurityAuditFinding } from "../security/audit.types.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type SecuritySurface = {
collectFeishuSecurityAuditFindings: (params: { cfg: OpenClawConfig }) => SecurityAuditFinding[];
};
function loadSecuritySurface(): SecuritySurface {
return loadBundledPluginPublicSurfaceModuleSync<SecuritySurface>({
dirName: "feishu",

View File

@@ -1,10 +1,16 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/feishu/setup-api.js");
import type { ChannelSetupWizard } from "../channels/plugins/setup-wizard-types.js";
import type { ChannelSetupAdapter } from "../channels/plugins/types.adapters.js";
import {
createLazyFacadeObjectValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
type FacadeModule = {
feishuSetupAdapter: ChannelSetupAdapter;
feishuSetupWizard: ChannelSetupWizard;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "feishu",

View File

@@ -1,7 +1,14 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/github-copilot/api.js");
import type { RuntimeEnv } from "../runtime.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
githubCopilotLoginCommand: (
opts: { profileId?: string; yes?: boolean },
runtime: RuntimeEnv,
) => Promise<void>;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "github-copilot",

View File

@@ -1,10 +1,54 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/irc/api.js");
import type { ChannelSetupWizard } from "../channels/plugins/setup-wizard-types.js";
import type { ChannelSetupAdapter } from "../channels/plugins/types.adapters.js";
import type { OpenClawConfig } from "../config/types.js";
import {
createLazyFacadeObjectValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
type IrcAccountConfig = {
name?: string;
enabled?: boolean;
host?: string;
port?: number;
tls?: boolean;
nick?: string;
username?: string;
realname?: string;
password?: string;
passwordFile?: string;
channels?: string[];
groups?: Record<string, unknown>;
};
type ResolvedIrcAccount = {
accountId: string;
enabled: boolean;
name?: string;
configured: boolean;
host: string;
port: number;
tls: boolean;
nick: string;
username: string;
realname: string;
password: string;
passwordSource: "env" | "passwordFile" | "config" | "none";
config: IrcAccountConfig;
};
type FacadeModule = {
ircSetupAdapter: ChannelSetupAdapter;
ircSetupWizard: ChannelSetupWizard;
listIrcAccountIds: (cfg: OpenClawConfig) => string[];
resolveDefaultIrcAccountId: (cfg: OpenClawConfig) => string;
resolveIrcAccount: (params: {
cfg: OpenClawConfig;
accountId?: string | null;
}) => ResolvedIrcAccount;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "irc",

View File

@@ -1,7 +1,64 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/line/runtime-api.js");
import type { BaseProbeResult } from "../channels/plugins/types.public.js";
import { loadActivatedBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
type FacadeFunction = (...args: unknown[]) => unknown;
type FacadeModule = Record<
| "buildTemplateMessageFromPayload"
| "cancelDefaultRichMenu"
| "createActionCard"
| "createAgendaCard"
| "createAppleTvRemoteCard"
| "createCarousel"
| "createDefaultMenuConfig"
| "createDeviceControlCard"
| "createEventCard"
| "createGridLayout"
| "createImageCard"
| "createInfoCard"
| "createListCard"
| "createMediaPlayerCard"
| "createNotificationBubble"
| "createQuickReplyItems"
| "createReceiptCard"
| "createRichMenu"
| "createRichMenuAlias"
| "datetimePickerAction"
| "deleteRichMenu"
| "deleteRichMenuAlias"
| "downloadLineMedia"
| "firstDefined"
| "getDefaultRichMenuId"
| "getRichMenu"
| "getRichMenuIdOfUser"
| "getRichMenuList"
| "hasLineDirectives"
| "isSenderAllowed"
| "linkRichMenuToUser"
| "linkRichMenuToUsers"
| "messageAction"
| "monitorLineProvider"
| "normalizeAllowFrom"
| "normalizeDmAllowFromWithStore"
| "parseLineDirectives"
| "postbackAction"
| "probeLineBot"
| "pushFlexMessage"
| "pushLocationMessage"
| "pushMessageLine"
| "pushMessagesLine"
| "pushTemplateMessage"
| "pushTextMessageWithQuickReplies"
| "sendMessageLine"
| "setDefaultRichMenu"
| "toFlexMessage"
| "unlinkRichMenuFromUser"
| "unlinkRichMenuFromUsers"
| "uploadRichMenuImage"
| "uriAction",
FacadeFunction
>;
function loadFacadeModule(): FacadeModule {
return loadActivatedBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "line",
@@ -134,24 +191,123 @@ export const uploadRichMenuImage: FacadeModule["uploadRichMenuImage"] = ((...arg
loadFacadeModule()["uploadRichMenuImage"](...args)) as FacadeModule["uploadRichMenuImage"];
export const uriAction: FacadeModule["uriAction"] = ((...args) =>
loadFacadeModule()["uriAction"](...args)) as FacadeModule["uriAction"];
export type Action = import("@openclaw/line/runtime-api.js").Action;
export type CardAction = import("@openclaw/line/runtime-api.js").CardAction;
export type CreateRichMenuParams = import("@openclaw/line/runtime-api.js").CreateRichMenuParams;
export type FlexBox = import("@openclaw/line/runtime-api.js").FlexBox;
export type FlexBubble = import("@openclaw/line/runtime-api.js").FlexBubble;
export type FlexButton = import("@openclaw/line/runtime-api.js").FlexButton;
export type FlexCarousel = import("@openclaw/line/runtime-api.js").FlexCarousel;
export type FlexComponent = import("@openclaw/line/runtime-api.js").FlexComponent;
export type FlexContainer = import("@openclaw/line/runtime-api.js").FlexContainer;
export type FlexImage = import("@openclaw/line/runtime-api.js").FlexImage;
export type FlexText = import("@openclaw/line/runtime-api.js").FlexText;
export type LineChannelData = import("@openclaw/line/runtime-api.js").LineChannelData;
export type LineConfig = import("@openclaw/line/runtime-api.js").LineConfig;
export type LineProbeResult = import("@openclaw/line/runtime-api.js").LineProbeResult;
export type ListItem = import("@openclaw/line/runtime-api.js").ListItem;
export type ResolvedLineAccount = import("@openclaw/line/runtime-api.js").ResolvedLineAccount;
export type RichMenuArea = import("@openclaw/line/runtime-api.js").RichMenuArea;
export type RichMenuAreaRequest = import("@openclaw/line/runtime-api.js").RichMenuAreaRequest;
export type RichMenuRequest = import("@openclaw/line/runtime-api.js").RichMenuRequest;
export type RichMenuResponse = import("@openclaw/line/runtime-api.js").RichMenuResponse;
export type RichMenuSize = import("@openclaw/line/runtime-api.js").RichMenuSize;
export type Action = Record<string, unknown>;
export type FlexBox = Record<string, unknown>;
export type FlexBubble = Record<string, unknown>;
export type FlexButton = Record<string, unknown>;
export type FlexCarousel = Record<string, unknown>;
export type FlexComponent = Record<string, unknown>;
export type FlexContainer = Record<string, unknown>;
export type FlexImage = Record<string, unknown>;
export type FlexText = Record<string, unknown>;
export interface ListItem {
title: string;
subtitle?: string;
action?: Action;
}
export interface CardAction {
label: string;
action: Action;
}
export interface LineThreadBindingsConfig {
enabled?: boolean;
idleHours?: number;
maxAgeHours?: number;
spawnSubagentSessions?: boolean;
spawnAcpSessions?: boolean;
}
interface LineAccountBaseConfig {
enabled?: boolean;
channelAccessToken?: string;
channelSecret?: string;
tokenFile?: string;
secretFile?: string;
name?: string;
allowFrom?: Array<string | number>;
groupAllowFrom?: Array<string | number>;
dmPolicy?: "open" | "allowlist" | "pairing" | "disabled";
groupPolicy?: "open" | "allowlist" | "disabled";
responsePrefix?: string;
mediaMaxMb?: number;
webhookPath?: string;
threadBindings?: LineThreadBindingsConfig;
groups?: Record<string, LineGroupConfig>;
}
export interface LineConfig extends LineAccountBaseConfig {
accounts?: Record<string, LineAccountBaseConfig>;
defaultAccount?: string;
}
export interface LineGroupConfig {
enabled?: boolean;
allowFrom?: Array<string | number>;
requireMention?: boolean;
systemPrompt?: string;
skills?: string[];
}
export interface ResolvedLineAccount {
accountId: string;
name?: string;
enabled: boolean;
channelAccessToken: string;
channelSecret: string;
tokenSource: "config" | "env" | "file" | "none";
config: LineConfig & LineAccountBaseConfig;
}
export type LineProbeResult = BaseProbeResult<string> & {
bot?: {
displayName?: string;
userId?: string;
basicId?: string;
pictureUrl?: string;
};
};
export type LineChannelData = {
quickReplies?: string[];
location?: {
title: string;
address: string;
latitude: number;
longitude: number;
};
flexMessage?: {
altText: string;
contents: unknown;
};
templateMessage?: unknown;
};
export interface RichMenuSize {
width: 2500;
height: 1686 | 843;
}
export interface RichMenuAreaRequest {
bounds: {
x: number;
y: number;
width: number;
height: number;
};
action: Action;
}
export interface CreateRichMenuParams {
size: RichMenuSize;
selected?: boolean;
name: string;
chatBarText: string;
areas: RichMenuAreaRequest[];
}
export type RichMenuArea = RichMenuAreaRequest;
export type RichMenuRequest = Record<string, unknown>;
export type RichMenuResponse = Record<string, unknown>;

View File

@@ -1,10 +1,33 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/line/runtime-api.js");
import type { BaseProbeResult } from "../channels/plugins/types.public.js";
import {
createLazyFacadeObjectValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
type FacadeFunction = (...args: unknown[]) => unknown;
type FacadeModule = Record<
| "createActionCard"
| "createAgendaCard"
| "createAppleTvRemoteCard"
| "createDeviceControlCard"
| "createEventCard"
| "createImageCard"
| "createInfoCard"
| "createListCard"
| "createMediaPlayerCard"
| "createReceiptCard"
| "listLineAccountIds"
| "normalizeAccountId"
| "processLineMessage"
| "resolveDefaultLineAccountId"
| "resolveExactLineGroupConfigKey"
| "resolveLineAccount",
FacadeFunction
> & {
LineConfigSchema: object;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "line",
@@ -36,8 +59,8 @@ export const createMediaPlayerCard: FacadeModule["createMediaPlayerCard"] = ((..
export const createReceiptCard: FacadeModule["createReceiptCard"] = ((...args) =>
loadFacadeModule()["createReceiptCard"](...args)) as FacadeModule["createReceiptCard"];
export const LineConfigSchema: FacadeModule["LineConfigSchema"] = createLazyFacadeObjectValue(
() => loadFacadeModule()["LineConfigSchema"] as object,
) as FacadeModule["LineConfigSchema"];
() => loadFacadeModule()["LineConfigSchema"],
);
export const listLineAccountIds: FacadeModule["listLineAccountIds"] = ((...args) =>
loadFacadeModule()["listLineAccountIds"](...args)) as FacadeModule["listLineAccountIds"];
export const normalizeAccountId: FacadeModule["normalizeAccountId"] = ((...args) =>
@@ -58,9 +81,88 @@ export const resolveExactLineGroupConfigKey: FacadeModule["resolveExactLineGroup
)) as FacadeModule["resolveExactLineGroupConfigKey"];
export const resolveLineAccount: FacadeModule["resolveLineAccount"] = ((...args) =>
loadFacadeModule()["resolveLineAccount"](...args)) as FacadeModule["resolveLineAccount"];
export type CardAction = import("@openclaw/line/runtime-api.js").CardAction;
export type LineChannelData = import("@openclaw/line/runtime-api.js").LineChannelData;
export type LineConfig = import("@openclaw/line/runtime-api.js").LineConfig;
export type LineProbeResult = import("@openclaw/line/runtime-api.js").LineProbeResult;
export type ListItem = import("@openclaw/line/runtime-api.js").ListItem;
export type ResolvedLineAccount = import("@openclaw/line/runtime-api.js").ResolvedLineAccount;
export type Action = Record<string, unknown>;
export interface ListItem {
title: string;
subtitle?: string;
action?: Action;
}
export interface CardAction {
label: string;
action: Action;
}
export interface LineThreadBindingsConfig {
enabled?: boolean;
idleHours?: number;
maxAgeHours?: number;
spawnSubagentSessions?: boolean;
spawnAcpSessions?: boolean;
}
interface LineAccountBaseConfig {
enabled?: boolean;
channelAccessToken?: string;
channelSecret?: string;
tokenFile?: string;
secretFile?: string;
name?: string;
allowFrom?: Array<string | number>;
groupAllowFrom?: Array<string | number>;
dmPolicy?: "open" | "allowlist" | "pairing" | "disabled";
groupPolicy?: "open" | "allowlist" | "disabled";
responsePrefix?: string;
mediaMaxMb?: number;
webhookPath?: string;
threadBindings?: LineThreadBindingsConfig;
groups?: Record<string, LineGroupConfig>;
}
export interface LineConfig extends LineAccountBaseConfig {
accounts?: Record<string, LineAccountBaseConfig>;
defaultAccount?: string;
}
export interface LineGroupConfig {
enabled?: boolean;
allowFrom?: Array<string | number>;
requireMention?: boolean;
systemPrompt?: string;
skills?: string[];
}
export interface ResolvedLineAccount {
accountId: string;
name?: string;
enabled: boolean;
channelAccessToken: string;
channelSecret: string;
tokenSource: "config" | "env" | "file" | "none";
config: LineConfig & LineAccountBaseConfig;
}
export type LineProbeResult = BaseProbeResult<string> & {
bot?: {
displayName?: string;
userId?: string;
basicId?: string;
pictureUrl?: string;
};
};
export type LineChannelData = {
quickReplies?: string[];
location?: {
title: string;
address: string;
latitude: number;
longitude: number;
};
flexMessage?: {
altText: string;
contents: unknown;
};
templateMessage?: unknown;
};

View File

@@ -1,7 +1,16 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/litellm/api.js");
import type { ModelDefinitionConfig, OpenClawConfig } from "../config/types.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
applyLitellmConfig: (cfg: OpenClawConfig) => OpenClawConfig;
applyLitellmProviderConfig: (cfg: OpenClawConfig) => OpenClawConfig;
buildLitellmModelDefinition: () => ModelDefinitionConfig;
LITELLM_BASE_URL: string;
LITELLM_DEFAULT_MODEL_ID: string;
LITELLM_DEFAULT_MODEL_REF: string;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "litellm",

View File

@@ -1,7 +1,103 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/lmstudio/runtime-api.js");
import type {
ModelDefinitionConfig,
ModelProviderConfig,
OpenClawConfig,
} from "../config/types.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
type LmstudioReasoningCapabilityWire = {
allowed_options?: unknown;
default?: unknown;
};
export type LmstudioModelWire = {
type?: "llm" | "embedding";
key?: string;
display_name?: string;
max_context_length?: number;
format?: "gguf" | "mlx" | null;
capabilities?: {
vision?: boolean;
trained_for_tool_use?: boolean;
reasoning?: LmstudioReasoningCapabilityWire;
};
loaded_instances?: Array<{
id?: string;
config?: {
context_length?: number;
} | null;
} | null>;
};
export type LmstudioModelBase = {
id: string;
displayName: string;
format: "gguf" | "mlx" | null;
vision: boolean;
trainedForToolUse: boolean;
loaded: boolean;
reasoning: boolean;
input: ModelDefinitionConfig["input"];
cost: ModelDefinitionConfig["cost"];
contextWindow: number;
contextTokens: number;
maxTokens: number;
};
type FacadeModule = {
LMSTUDIO_DEFAULT_BASE_URL: string;
LMSTUDIO_DEFAULT_INFERENCE_BASE_URL: string;
LMSTUDIO_DEFAULT_EMBEDDING_MODEL: string;
LMSTUDIO_PROVIDER_LABEL: string;
LMSTUDIO_DEFAULT_API_KEY_ENV_VAR: string;
LMSTUDIO_LOCAL_API_KEY_PLACEHOLDER: string;
LMSTUDIO_MODEL_PLACEHOLDER: string;
LMSTUDIO_DEFAULT_LOAD_CONTEXT_LENGTH: number;
LMSTUDIO_DEFAULT_MODEL_ID: string;
LMSTUDIO_PROVIDER_ID: string;
resolveLmstudioReasoningCapability: (entry: Pick<LmstudioModelWire, "capabilities">) => boolean;
resolveLoadedContextWindow: (entry: Pick<LmstudioModelWire, "loaded_instances">) => number | null;
resolveLmstudioServerBase: (configuredBaseUrl?: string) => string;
resolveLmstudioInferenceBase: (configuredBaseUrl?: string) => string;
normalizeLmstudioProviderConfig: (provider: ModelProviderConfig) => ModelProviderConfig;
fetchLmstudioModels: (params?: {
baseUrl?: string;
apiKey?: string;
headers?: Record<string, string>;
}) => Promise<unknown>;
mapLmstudioWireEntry: (entry: LmstudioModelWire) => LmstudioModelBase | null;
discoverLmstudioModels: (params?: {
config?: OpenClawConfig;
baseUrl?: string;
apiKey?: string;
headers?: Record<string, string>;
}) => Promise<ModelDefinitionConfig[]>;
ensureLmstudioModelLoaded: (params: Record<string, unknown>) => Promise<unknown>;
buildLmstudioAuthHeaders: (params: {
apiKey?: string;
json?: boolean;
headers?: Record<string, string>;
}) => Record<string, string> | undefined;
resolveLmstudioConfiguredApiKey: (params: {
config?: OpenClawConfig;
env?: NodeJS.ProcessEnv;
path?: string;
}) => Promise<string | undefined>;
resolveLmstudioProviderHeaders: (params: {
config?: OpenClawConfig;
env?: NodeJS.ProcessEnv;
headers?: unknown;
path?: string;
}) => Promise<Record<string, string> | undefined>;
resolveLmstudioRuntimeApiKey: (params: {
config?: OpenClawConfig;
agentDir?: string;
env?: NodeJS.ProcessEnv;
headers?: unknown;
}) => Promise<string | undefined>;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "lmstudio",
@@ -9,9 +105,6 @@ function loadFacadeModule(): FacadeModule {
});
}
export type LmstudioModelWire = Parameters<FacadeModule["mapLmstudioWireEntry"]>[0];
export type LmstudioModelBase = Exclude<ReturnType<FacadeModule["mapLmstudioWireEntry"]>, null>;
// Keep defaults inline so importing the runtime facade stays cold until a helper
// is actually used. These values are part of the public LM Studio contract.
export const LMSTUDIO_DEFAULT_BASE_URL: FacadeModule["LMSTUDIO_DEFAULT_BASE_URL"] =

View File

@@ -1,3 +1,13 @@
import type { OpenClawConfig } from "../config/types.js";
import type {
ProviderAuthMethodNonInteractiveContext,
ProviderAuthResult,
ProviderCatalogContext,
ProviderPrepareDynamicModelContext,
ProviderRuntimeModel,
} from "../plugins/types.js";
import type { WizardPrompter } from "../wizard/prompts.js";
export type {
OpenClawPluginApi,
ProviderAuthContext,
@@ -8,7 +18,6 @@ export type {
ProviderPrepareDynamicModelContext,
ProviderRuntimeModel,
} from "../plugins/types.js";
export type { LmstudioModelBase, LmstudioModelWire } from "./lmstudio-runtime.js";
export {
LMSTUDIO_DEFAULT_API_KEY_ENV_VAR,
@@ -36,9 +45,37 @@ export {
resolveLmstudioServerBase,
} from "./lmstudio-runtime.js";
type FacadeModule = typeof import("@openclaw/lmstudio/api.js");
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
type LmstudioInteractiveParams = {
config: OpenClawConfig;
prompter?: WizardPrompter;
secretInputMode?: unknown;
allowSecretRefPrompt?: boolean;
promptText?: (params: {
message: string;
initialValue?: string;
placeholder?: string;
validate?: (value: string | undefined) => string | undefined;
}) => Promise<string | undefined>;
note?: (message: string, title?: string) => Promise<void> | void;
};
type FacadeModule = {
promptAndConfigureLmstudioInteractive: (
params: LmstudioInteractiveParams,
) => Promise<ProviderAuthResult>;
configureLmstudioNonInteractive: (
ctx: ProviderAuthMethodNonInteractiveContext,
) => Promise<OpenClawConfig | null>;
discoverLmstudioProvider: (
ctx: ProviderCatalogContext,
) => Promise<{ provider: import("../config/types.js").ModelProviderConfig } | null>;
prepareLmstudioDynamicModels: (
ctx: ProviderPrepareDynamicModelContext,
) => Promise<ProviderRuntimeModel[]>;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "lmstudio",

View File

@@ -1,7 +1,15 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/matrix/runtime-api.js");
import type { RuntimeEnv } from "../runtime.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
ensureMatrixSdkInstalled: (params: {
runtime: RuntimeEnv;
confirm?: (message: string) => Promise<boolean>;
}) => Promise<void>;
isMatrixSdkAvailable: () => boolean;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "matrix",

View File

@@ -1,7 +1,50 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/matrix/api.js");
import type { OpenClawConfig } from "../config/config.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
export type MatrixScopedEnvVarNames = {
homeserver: string;
userId: string;
accessToken: string;
password: string;
deviceId: string;
deviceName: string;
};
export type MatrixAccountStorageRoot = {
rootDir: string;
accountKey: string;
tokenHash: string;
};
export type MatrixLegacyFlatStoragePaths = {
rootDir: string;
storagePath: string;
cryptoPath: string;
};
type FacadeModule = {
findMatrixAccountEntry: (
cfg: OpenClawConfig,
accountId: string,
) => Record<string, unknown> | null;
getMatrixScopedEnvVarNames: (accountId: string) => MatrixScopedEnvVarNames;
requiresExplicitMatrixDefaultAccount: (cfg: OpenClawConfig, env?: NodeJS.ProcessEnv) => boolean;
resolveConfiguredMatrixAccountIds: (cfg: OpenClawConfig, env?: NodeJS.ProcessEnv) => string[];
resolveMatrixAccountStorageRoot: (params: {
stateDir: string;
homeserver: string;
userId: string;
accessToken: string;
accountId?: string | null;
}) => MatrixAccountStorageRoot;
resolveMatrixChannelConfig: (cfg: OpenClawConfig) => Record<string, unknown> | null;
resolveMatrixCredentialsDir: (stateDir: string) => string;
resolveMatrixCredentialsPath: (params: { stateDir: string; accountId?: string | null }) => string;
resolveMatrixDefaultOrOnlyAccountId: (cfg: OpenClawConfig, env?: NodeJS.ProcessEnv) => string;
resolveMatrixLegacyFlatStoragePaths: (stateDir: string) => MatrixLegacyFlatStoragePaths;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "matrix",

View File

@@ -1,7 +1,30 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/matrix/runtime-api.js");
import type { PluginRuntime } from "../plugins/runtime/types.js";
import { loadActivatedBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
export type MatrixResolvedStringField =
| "homeserver"
| "userId"
| "accessToken"
| "password"
| "deviceId"
| "deviceName";
export type MatrixResolvedStringValues = Record<MatrixResolvedStringField, string>;
type MatrixStringSourceMap = Partial<Record<MatrixResolvedStringField, string>>;
type FacadeModule = {
resolveMatrixAccountStringValues: (params: {
accountId: string;
account?: MatrixStringSourceMap;
scopedEnv?: MatrixStringSourceMap;
channel?: MatrixStringSourceMap;
globalEnv?: MatrixStringSourceMap;
}) => MatrixResolvedStringValues;
setMatrixRuntime: (runtime: PluginRuntime) => void;
};
function loadFacadeModule(): FacadeModule {
return loadActivatedBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "matrix",

View File

@@ -1,10 +1,108 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/matrix/api.js");
import type {
BindingTargetKind,
SessionBindingRecord,
} from "../infra/outbound/session-binding-service.js";
import {
createLazyFacadeArrayValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
export type MatrixFacadeAuth = {
accountId: string;
homeserver: string;
userId: string;
accessToken: string;
password?: string;
deviceId?: string;
deviceName?: string;
initialSyncLimit?: number;
encryption?: boolean;
allowPrivateNetwork?: boolean;
ssrfPolicy?: unknown;
dispatcherPolicy?: unknown;
};
export type MatrixThreadBindingTargetKind = "subagent" | "acp";
export type MatrixThreadBindingRecord = {
accountId: string;
conversationId: string;
parentConversationId?: string;
targetKind: MatrixThreadBindingTargetKind;
targetSessionKey: string;
agentId?: string;
label?: string;
boundBy?: string;
boundAt: number;
lastActivityAt: number;
idleTimeoutMs?: number;
maxAgeMs?: number;
};
export type MatrixThreadBindingManager = {
accountId: string;
getIdleTimeoutMs: () => number;
getMaxAgeMs: () => number;
getByConversation: (params: {
conversationId: string;
parentConversationId?: string;
}) => MatrixThreadBindingRecord | undefined;
listBySessionKey: (targetSessionKey: string) => MatrixThreadBindingRecord[];
listBindings: () => MatrixThreadBindingRecord[];
touchBinding: (bindingId: string, at?: number) => MatrixThreadBindingRecord | null;
setIdleTimeoutBySessionKey: (params: {
targetSessionKey: string;
idleTimeoutMs: number;
}) => MatrixThreadBindingRecord[];
setMaxAgeBySessionKey: (params: {
targetSessionKey: string;
maxAgeMs: number;
}) => MatrixThreadBindingRecord[];
persist: () => Promise<void>;
stop: () => void;
};
type MatrixThreadBindingManagerFactory = (params: {
accountId: string;
auth: MatrixFacadeAuth;
client: unknown;
env?: NodeJS.ProcessEnv;
stateDir?: string;
idleTimeoutMs: number;
maxAgeMs: number;
enableSweeper?: boolean;
logVerboseMessage?: (message: string) => void;
}) => Promise<MatrixThreadBindingManager>;
type FacadeModule = {
createMatrixThreadBindingManager: MatrixThreadBindingManagerFactory;
matrixSessionBindingAdapterChannels: readonly ["matrix"];
resetMatrixThreadBindingsForTests: () => void;
};
export type MatrixSessionBindingTimeoutParams = {
accountId: string;
targetSessionKey: string;
idleTimeoutMs: number;
};
export type MatrixSessionBindingMaxAgeParams = {
accountId: string;
targetSessionKey: string;
maxAgeMs: number;
};
export type MatrixSessionBindingTimeoutSetter = (
params: MatrixSessionBindingTimeoutParams,
) => SessionBindingRecord[];
export type MatrixSessionBindingMaxAgeSetter = (
params: MatrixSessionBindingMaxAgeParams,
) => SessionBindingRecord[];
export type MatrixSessionBindingTargetKind = BindingTargetKind;
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "matrix",

View File

@@ -1,7 +1,20 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/matrix/api.js");
import type { SessionBindingRecord } from "../infra/outbound/session-binding-service.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
setMatrixThreadBindingIdleTimeoutBySessionKey: (params: {
accountId: string;
targetSessionKey: string;
idleTimeoutMs: number;
}) => SessionBindingRecord[];
setMatrixThreadBindingMaxAgeBySessionKey: (params: {
accountId: string;
targetSessionKey: string;
maxAgeMs: number;
}) => SessionBindingRecord[];
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "matrix",

View File

@@ -7,7 +7,11 @@ import {
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
type MatrixFacadeModule = typeof import("@openclaw/matrix/contract-api.js");
type MatrixFacadeModule = {
singleAccountKeysToMove: readonly string[];
namedAccountPromotionKeys: readonly string[];
resolveSingleAccountPromotionTarget: (params: { channel: Record<string, unknown> }) => string;
};
function loadMatrixFacadeModule(): MatrixFacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<MatrixFacadeModule>({

View File

@@ -1,7 +1,96 @@
// Manual facade. Keep loader boundary explicit.
type ApiFacadeModule = typeof import("@openclaw/memory-core/api.js");
type RuntimeFacadeModule = typeof import("@openclaw/memory-core/runtime-api.js");
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
// Manual facade. Keep loader boundary explicit.
import type {
MemoryEmbeddingProvider,
MemoryEmbeddingProviderAdapter,
MemoryEmbeddingProviderCreateOptions,
MemoryEmbeddingProviderRuntime,
} from "./memory-core-host-engine-embeddings.js";
type EmbeddingProviderResult = {
provider: MemoryEmbeddingProvider | null;
requestedProvider: string;
fallbackFrom?: string;
fallbackReason?: string;
providerUnavailableReason?: string;
runtime?: MemoryEmbeddingProviderRuntime;
};
type RuntimeFacadeModule = {
createEmbeddingProvider: (
options: MemoryEmbeddingProviderCreateOptions & {
provider: string;
fallback: string;
},
) => Promise<EmbeddingProviderResult>;
registerBuiltInMemoryEmbeddingProviders: (register: {
registerMemoryEmbeddingProvider: (adapter: MemoryEmbeddingProviderAdapter) => void;
}) => void;
removeGroundedShortTermCandidates: (params: {
workspaceDir: string;
}) => Promise<{ removed: number; storePath: string }>;
repairDreamingArtifacts: (params: {
workspaceDir: string;
archiveDiary?: boolean;
now?: Date;
}) => Promise<RepairDreamingArtifactsResult>;
};
type GroundedRemPreviewItem = {
text: string;
refs: string[];
};
type GroundedRemCandidate = GroundedRemPreviewItem & {
lean: "likely_durable" | "unclear" | "likely_situational";
};
type GroundedRemFilePreview = {
path: string;
facts: GroundedRemPreviewItem[];
reflections: GroundedRemPreviewItem[];
memoryImplications: GroundedRemPreviewItem[];
candidates: GroundedRemCandidate[];
renderedMarkdown: string;
};
type GroundedRemPreviewResult = {
workspaceDir: string;
scannedFiles: number;
files: GroundedRemFilePreview[];
};
type ApiFacadeModule = {
previewGroundedRemMarkdown: (params: {
workspaceDir: string;
inputPaths: string[];
}) => Promise<GroundedRemPreviewResult>;
dedupeDreamDiaryEntries: (params: {
workspaceDir: string;
}) => Promise<{ dreamsPath: string; removed: number; kept: number }>;
writeBackfillDiaryEntries: (params: {
workspaceDir: string;
entries: Array<{
isoDay: string;
bodyLines: string[];
sourcePath?: string;
}>;
timezone?: string;
}) => Promise<{ dreamsPath: string; written: number; replaced: number }>;
removeBackfillDiaryEntries: (params: {
workspaceDir: string;
}) => Promise<{ dreamsPath: string; removed: number }>;
};
type RepairDreamingArtifactsResult = {
changed: boolean;
archiveDir?: string;
archivedDreamsDiary: boolean;
archivedSessionCorpus: boolean;
archivedSessionIngestion: boolean;
archivedPaths: string[];
warnings: string[];
};
function loadApiFacadeModule(): ApiFacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<ApiFacadeModule>({

View File

@@ -1,9 +1,135 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/memory-core/runtime-api.js");
import type { OpenClawConfig } from "../config/types.js";
import {
createLazyFacadeObjectValue,
loadActivatedBundledPluginPublicSurfaceModuleSync,
} from "./facade-runtime.js";
import type { MemorySearchManager } from "./memory-core-host-engine-storage.js";
export type BuiltinMemoryEmbeddingProviderDoctorMetadata = {
providerId: string;
authProviderId: string;
envVars: string[];
transport: "local" | "remote";
autoSelectPriority?: number;
};
export type DreamingArtifactsAuditIssue = {
severity: "warn" | "error";
code:
| "dreaming-session-corpus-unreadable"
| "dreaming-session-corpus-self-ingested"
| "dreaming-session-ingestion-unreadable"
| "dreaming-diary-unreadable";
message: string;
fixable: boolean;
};
export type DreamingArtifactsAuditSummary = {
dreamsPath?: string;
sessionCorpusDir: string;
sessionCorpusFileCount: number;
suspiciousSessionCorpusFileCount: number;
suspiciousSessionCorpusLineCount: number;
sessionIngestionPath: string;
sessionIngestionExists: boolean;
issues: DreamingArtifactsAuditIssue[];
};
export type RepairDreamingArtifactsResult = {
changed: boolean;
archiveDir?: string;
archivedDreamsDiary: boolean;
archivedSessionCorpus: boolean;
archivedSessionIngestion: boolean;
archivedPaths: string[];
warnings: string[];
};
export type ShortTermAuditIssue = {
severity: "warn" | "error";
code:
| "recall-store-unreadable"
| "recall-store-empty"
| "recall-store-invalid"
| "recall-lock-stale"
| "recall-lock-unreadable"
| "qmd-index-missing"
| "qmd-index-empty"
| "qmd-collections-empty";
message: string;
fixable: boolean;
};
export type ShortTermAuditSummary = {
storePath: string;
lockPath: string;
updatedAt?: string;
exists: boolean;
entryCount: number;
promotedCount: number;
spacedEntryCount: number;
conceptTaggedEntryCount: number;
conceptTagScripts?: Record<string, unknown>;
invalidEntryCount: number;
issues: ShortTermAuditIssue[];
qmd?:
| {
dbPath?: string;
collections?: number;
dbBytes?: number;
}
| undefined;
};
export type RepairShortTermPromotionArtifactsResult = {
changed: boolean;
removedInvalidEntries: number;
rewroteStore: boolean;
removedStaleLock: boolean;
};
type MemoryIndexManagerFacade = {
get(params: {
cfg: OpenClawConfig;
agentId: string;
purpose?: "default" | "status";
}): Promise<MemorySearchManager | null>;
};
type FacadeModule = {
auditShortTermPromotionArtifacts: (params: {
workspaceDir: string;
qmd?: {
dbPath?: string;
collections?: number;
};
}) => Promise<ShortTermAuditSummary>;
auditDreamingArtifacts: (params: {
workspaceDir: string;
}) => Promise<DreamingArtifactsAuditSummary>;
getBuiltinMemoryEmbeddingProviderDoctorMetadata: (
providerId: string,
) => BuiltinMemoryEmbeddingProviderDoctorMetadata | null;
getMemorySearchManager: (params: {
cfg: OpenClawConfig;
agentId: string;
purpose?: "default" | "status";
}) => Promise<{
manager: MemorySearchManager | null;
error?: string;
}>;
listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata: () => Array<BuiltinMemoryEmbeddingProviderDoctorMetadata>;
MemoryIndexManager: MemoryIndexManagerFacade;
repairShortTermPromotionArtifacts: (params: {
workspaceDir: string;
}) => Promise<RepairShortTermPromotionArtifactsResult>;
repairDreamingArtifacts: (params: {
workspaceDir: string;
archiveDiary?: boolean;
now?: Date;
}) => Promise<RepairDreamingArtifactsResult>;
};
function loadFacadeModule(): FacadeModule {
return loadActivatedBundledPluginPublicSurfaceModuleSync<FacadeModule>({
@@ -43,13 +169,3 @@ export const repairDreamingArtifacts: FacadeModule["repairDreamingArtifacts"] =
loadFacadeModule()["repairDreamingArtifacts"](
...args,
)) as FacadeModule["repairDreamingArtifacts"];
export type BuiltinMemoryEmbeddingProviderDoctorMetadata =
import("@openclaw/memory-core/runtime-api.js").BuiltinMemoryEmbeddingProviderDoctorMetadata;
export type DreamingArtifactsAuditSummary =
import("@openclaw/memory-core/runtime-api.js").DreamingArtifactsAuditSummary;
export type RepairDreamingArtifactsResult =
import("@openclaw/memory-core/runtime-api.js").RepairDreamingArtifactsResult;
export type RepairShortTermPromotionArtifactsResult =
import("@openclaw/memory-core/runtime-api.js").RepairShortTermPromotionArtifactsResult;
export type ShortTermAuditSummary =
import("@openclaw/memory-core/runtime-api.js").ShortTermAuditSummary;

View File

@@ -1,7 +1,14 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/openrouter/api.js");
import type { ModelProviderConfig, OpenClawConfig } from "../config/types.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
applyOpenrouterConfig: (cfg: OpenClawConfig) => OpenClawConfig;
applyOpenrouterProviderConfig: (cfg: OpenClawConfig) => OpenClawConfig;
buildOpenrouterProvider: () => ModelProviderConfig;
OPENROUTER_DEFAULT_MODEL_REF: string;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "openrouter",

View File

@@ -1,10 +1,256 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/qa-channel/api.js");
import type { ChannelPlugin } from "../channels/plugins/types.plugin.js";
import {
createLazyFacadeObjectValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
export type QaBusConversationKind = "direct" | "channel";
export type QaBusConversation = {
id: string;
kind: QaBusConversationKind;
title?: string;
};
export type QaBusAttachment = {
id: string;
kind: "image" | "video" | "audio" | "file";
mimeType: string;
fileName?: string;
inline?: boolean;
url?: string;
contentBase64?: string;
width?: number;
height?: number;
durationMs?: number;
altText?: string;
transcript?: string;
};
export type QaBusMessage = {
id: string;
accountId: string;
direction: "inbound" | "outbound";
conversation: QaBusConversation;
senderId: string;
senderName?: string;
text: string;
timestamp: number;
threadId?: string;
threadTitle?: string;
replyToId?: string;
deleted?: boolean;
editedAt?: number;
attachments?: QaBusAttachment[];
reactions: Array<{
emoji: string;
senderId: string;
timestamp: number;
}>;
};
export type QaBusThread = {
id: string;
accountId: string;
conversationId: string;
title: string;
createdAt: number;
createdBy: string;
};
export type QaBusEvent =
| { cursor: number; kind: "inbound-message"; accountId: string; message: QaBusMessage }
| { cursor: number; kind: "outbound-message"; accountId: string; message: QaBusMessage }
| { cursor: number; kind: "thread-created"; accountId: string; thread: QaBusThread }
| { cursor: number; kind: "message-edited"; accountId: string; message: QaBusMessage }
| { cursor: number; kind: "message-deleted"; accountId: string; message: QaBusMessage }
| {
cursor: number;
kind: "reaction-added";
accountId: string;
message: QaBusMessage;
emoji: string;
senderId: string;
};
export type QaBusInboundMessageInput = {
accountId?: string;
conversation: QaBusConversation;
senderId: string;
senderName?: string;
text: string;
timestamp?: number;
threadId?: string;
threadTitle?: string;
replyToId?: string;
attachments?: QaBusAttachment[];
};
export type QaBusOutboundMessageInput = {
accountId?: string;
to: string;
senderId?: string;
senderName?: string;
text: string;
timestamp?: number;
threadId?: string;
replyToId?: string;
attachments?: QaBusAttachment[];
};
export type QaBusCreateThreadInput = {
accountId?: string;
conversationId: string;
title: string;
createdBy?: string;
timestamp?: number;
};
export type QaBusReactToMessageInput = {
accountId?: string;
messageId: string;
emoji: string;
senderId?: string;
timestamp?: number;
};
export type QaBusEditMessageInput = {
accountId?: string;
messageId: string;
text: string;
timestamp?: number;
};
export type QaBusDeleteMessageInput = {
accountId?: string;
messageId: string;
timestamp?: number;
};
export type QaBusSearchMessagesInput = {
accountId?: string;
query?: string;
conversationId?: string;
threadId?: string;
limit?: number;
};
export type QaBusReadMessageInput = {
accountId?: string;
messageId: string;
};
export type QaBusPollInput = {
accountId?: string;
cursor?: number;
timeoutMs?: number;
limit?: number;
};
export type QaBusPollResult = {
cursor: number;
events: QaBusEvent[];
};
export type QaBusStateSnapshot = {
cursor: number;
conversations: QaBusConversation[];
threads: QaBusThread[];
messages: QaBusMessage[];
events: QaBusEvent[];
};
export type QaBusWaitForInput =
| {
timeoutMs?: number;
kind: "event-kind";
eventKind: QaBusEvent["kind"];
}
| {
timeoutMs?: number;
kind: "message-text";
textIncludes: string;
direction?: QaBusMessage["direction"];
}
| {
timeoutMs?: number;
kind: "thread-id";
threadId: string;
};
type QaTargetParts = {
chatType: "direct" | "channel";
conversationId: string;
threadId?: string;
};
type FacadeModule = {
buildQaTarget: (params: QaTargetParts & { threadId?: string | null }) => string;
formatQaTarget: (params: QaTargetParts & { threadId?: string | null }) => string;
createQaBusThread: (params: {
baseUrl: string;
accountId: string;
conversationId: string;
title: string;
createdBy?: string;
}) => Promise<{ thread: QaBusThread }>;
deleteQaBusMessage: (params: {
baseUrl: string;
accountId: string;
messageId: string;
}) => Promise<{ message: QaBusMessage }>;
editQaBusMessage: (params: {
baseUrl: string;
accountId: string;
messageId: string;
text: string;
}) => Promise<{ message: QaBusMessage }>;
getQaBusState: (baseUrl: string) => Promise<QaBusStateSnapshot>;
injectQaBusInboundMessage: (params: {
baseUrl: string;
input: QaBusInboundMessageInput;
}) => Promise<{ message: QaBusMessage }>;
normalizeQaTarget: (raw: string) => string | undefined;
parseQaTarget: (raw: string) => QaTargetParts;
pollQaBus: (params: {
baseUrl: string;
accountId: string;
cursor: number;
timeoutMs: number;
signal?: AbortSignal;
}) => Promise<QaBusPollResult>;
qaChannelPlugin: ChannelPlugin;
reactToQaBusMessage: (params: {
baseUrl: string;
accountId: string;
messageId: string;
emoji: string;
senderId?: string;
}) => Promise<{ message: QaBusMessage }>;
readQaBusMessage: (params: {
baseUrl: string;
accountId: string;
messageId: string;
}) => Promise<{ message: QaBusMessage }>;
searchQaBusMessages: (params: {
baseUrl: string;
input: QaBusSearchMessagesInput;
}) => Promise<{ messages: QaBusMessage[] }>;
sendQaBusMessage: (params: {
baseUrl: string;
accountId: string;
to: string;
text: string;
senderId?: string;
senderName?: string;
threadId?: string;
replyToId?: string;
attachments?: QaBusAttachment[];
}) => Promise<{ message: QaBusMessage }>;
setQaChannelRuntime: (runtime: unknown) => void;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "qa-channel",
@@ -62,26 +308,3 @@ export const sendQaBusMessage: FacadeModule["sendQaBusMessage"] = ((...args) =>
export const setQaChannelRuntime: FacadeModule["setQaChannelRuntime"] = ((...args) =>
loadFacadeModule().setQaChannelRuntime(...args)) as FacadeModule["setQaChannelRuntime"];
export type QaBusAttachment = import("@openclaw/qa-channel/api.js").QaBusAttachment;
export type QaBusConversation = import("@openclaw/qa-channel/api.js").QaBusConversation;
export type QaBusConversationKind = import("@openclaw/qa-channel/api.js").QaBusConversationKind;
export type QaBusCreateThreadInput = import("@openclaw/qa-channel/api.js").QaBusCreateThreadInput;
export type QaBusDeleteMessageInput = import("@openclaw/qa-channel/api.js").QaBusDeleteMessageInput;
export type QaBusEditMessageInput = import("@openclaw/qa-channel/api.js").QaBusEditMessageInput;
export type QaBusEvent = import("@openclaw/qa-channel/api.js").QaBusEvent;
export type QaBusInboundMessageInput =
import("@openclaw/qa-channel/api.js").QaBusInboundMessageInput;
export type QaBusMessage = import("@openclaw/qa-channel/api.js").QaBusMessage;
export type QaBusOutboundMessageInput =
import("@openclaw/qa-channel/api.js").QaBusOutboundMessageInput;
export type QaBusPollInput = import("@openclaw/qa-channel/api.js").QaBusPollInput;
export type QaBusPollResult = import("@openclaw/qa-channel/api.js").QaBusPollResult;
export type QaBusReactToMessageInput =
import("@openclaw/qa-channel/api.js").QaBusReactToMessageInput;
export type QaBusReadMessageInput = import("@openclaw/qa-channel/api.js").QaBusReadMessageInput;
export type QaBusSearchMessagesInput =
import("@openclaw/qa-channel/api.js").QaBusSearchMessagesInput;
export type QaBusStateSnapshot = import("@openclaw/qa-channel/api.js").QaBusStateSnapshot;
export type QaBusThread = import("@openclaw/qa-channel/api.js").QaBusThread;
export type QaBusWaitForInput = import("@openclaw/qa-channel/api.js").QaBusWaitForInput;

View File

@@ -1,7 +1,19 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/synology-chat/contract-api.js");
import type { SecurityAuditFinding } from "../security/audit.types.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
collectSynologyChatSecurityAuditFindings: (params: {
accountId?: string | null;
account: {
accountId?: string;
dangerouslyAllowNameMatching?: boolean;
};
orderedAccountIds: string[];
hasExplicitAccountPath: boolean;
}) => SecurityAuditFinding[];
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "synology-chat",

View File

@@ -1,10 +1,25 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/vercel-ai-gateway/api.js");
import type { ModelDefinitionConfig, ModelProviderConfig } from "../config/types.js";
import {
createLazyFacadeObjectValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
type ModelCost = ModelDefinitionConfig["cost"];
type FacadeModule = {
buildVercelAiGatewayProvider: () => Promise<ModelProviderConfig>;
discoverVercelAiGatewayModels: () => Promise<ModelDefinitionConfig[]>;
getStaticVercelAiGatewayModelCatalog: () => ModelDefinitionConfig[];
VERCEL_AI_GATEWAY_BASE_URL: string;
VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW: number;
VERCEL_AI_GATEWAY_DEFAULT_COST: ModelCost;
VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS: number;
VERCEL_AI_GATEWAY_DEFAULT_MODEL_ID: string;
VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF: string;
VERCEL_AI_GATEWAY_PROVIDER_ID: string;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "vercel-ai-gateway",

View File

@@ -1,7 +1,15 @@
// Manual facade. Keep loader boundary explicit.
type FacadeModule = typeof import("@openclaw/xiaomi/api.js");
import type { ModelProviderConfig, OpenClawConfig } from "../config/types.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
applyXiaomiConfig: (cfg: OpenClawConfig) => OpenClawConfig;
applyXiaomiProviderConfig: (cfg: OpenClawConfig) => OpenClawConfig;
buildXiaomiProvider: () => ModelProviderConfig;
XIAOMI_DEFAULT_MODEL_ID: string;
XIAOMI_DEFAULT_MODEL_REF: string;
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "xiaomi",

View File

@@ -1,10 +1,37 @@
// Manual facade. Keep loader boundaries explicit and narrow.
type SetupFacadeModule = typeof import("@openclaw/zalo/setup-api.js");
type GroupAccessFacadeModule = typeof import("@openclaw/zalo/contract-api.js");
import type { ChannelSetupWizard } from "../channels/plugins/setup-wizard-types.js";
import type { ChannelSetupAdapter } from "../channels/plugins/types.adapters.js";
import type { GroupPolicy } from "../config/types.base.js";
import {
createLazyFacadeObjectValue,
loadBundledPluginPublicSurfaceModuleSync,
} from "./facade-loader.js";
import type { SenderGroupAccessDecision } from "./group-access.js";
type ZaloRuntimeGroupPolicyResult = {
groupPolicy: GroupPolicy;
providerMissingFallbackApplied: boolean;
};
type SetupFacadeModule = {
zaloSetupAdapter: ChannelSetupAdapter;
zaloSetupWizard: ChannelSetupWizard;
};
type GroupAccessFacadeModule = {
evaluateZaloGroupAccess: (params: {
providerConfigPresent: boolean;
configuredGroupPolicy?: GroupPolicy;
defaultGroupPolicy?: GroupPolicy;
groupAllowFrom: string[];
senderId: string;
}) => SenderGroupAccessDecision;
resolveZaloRuntimeGroupPolicy: (params: {
providerConfigPresent: boolean;
groupPolicy?: GroupPolicy;
defaultGroupPolicy?: GroupPolicy;
}) => ZaloRuntimeGroupPolicyResult;
};
function loadSetupFacadeModule(): SetupFacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<SetupFacadeModule>({

View File

@@ -82,9 +82,24 @@ export { formatResolvedUnresolvedNote } from "./resolution-notes.js";
export { buildBaseAccountStatusSnapshot } from "./status-helpers.js";
export { chunkTextForOutbound } from "./text-chunking.js";
type FacadeModule = typeof import("@openclaw/zalouser/contract-api.js");
import type { SecurityAuditFinding } from "../security/audit.types.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-loader.js";
type FacadeModule = {
collectZalouserSecurityAuditFindings: (params: {
accountId?: string | null;
account: {
accountId?: string;
config?: {
groups?: Record<string, unknown>;
dangerouslyAllowNameMatching?: boolean;
};
};
orderedAccountIds: string[];
hasExplicitAccountPath: boolean;
}) => SecurityAuditFinding[];
};
function loadFacadeModule(): FacadeModule {
return loadBundledPluginPublicSurfaceModuleSync<FacadeModule>({
dirName: "zalouser",

View File

@@ -8,9 +8,12 @@ export type ProviderContractEntry = {
let providerContractRegistryCache: ProviderContractEntry[] | null = null;
type AnthropicApiSurface = typeof import("../../../extensions/anthropic/api.js");
type GoogleApiSurface = typeof import("../../../extensions/google/api.js");
type OpenAIApiSurface = typeof import("../../../extensions/openai/api.js");
type ProviderApiSurface<TFactoryName extends string> = Record<TFactoryName, () => ProviderPlugin>;
type AnthropicApiSurface = ProviderApiSurface<"buildAnthropicProvider">;
type GoogleApiSurface = ProviderApiSurface<"buildGoogleProvider" | "buildGoogleGeminiCliProvider">;
type OpenAIApiSurface = ProviderApiSurface<
"buildOpenAIProvider" | "buildOpenAICodexProviderPlugin"
>;
export function loadVitestProviderContractRegistry(): ProviderContractEntry[] {
const anthropicApi = loadBundledPluginApiSync<AnthropicApiSurface>("anthropic");

View File

@@ -9,8 +9,9 @@ export type WebSearchProviderContractEntry = {
let webSearchProviderContractRegistryCache: WebSearchProviderContractEntry[] | null = null;
type GoogleWebSearchContractApiSurface =
typeof import("../../../extensions/google/web-search-contract-api.js");
type GoogleWebSearchContractApiSurface = {
createGeminiWebSearchProvider: () => WebSearchProviderPlugin;
};
export function loadVitestWebSearchProviderContractRegistry(): WebSearchProviderContractEntry[] {
const googleWebSearchContractApi =

View File

@@ -53,7 +53,7 @@ describe("security audit discord command findings", () => {
discord: DiscordAccountConfig;
};
},
account: createDiscordAccount(cfg.channels!.discord!),
account: createDiscordAccount(cfg.channels!.discord),
accountId: "default",
orderedAccountIds: ["default"],
hasExplicitAccountPath: false,

View File

@@ -1,6 +1,10 @@
import { resolveRelativeBundledPluginPublicModuleId } from "../../../src/test-utils/bundled-plugin-public-surface.js";
type IMessageContractSurface = typeof import("@openclaw/imessage/contract-api.js");
type IMessageContractSurface = {
DEFAULT_IMESSAGE_ATTACHMENT_ROOTS: string[];
resolveIMessageAttachmentRoots: (params: unknown) => string[];
resolveIMessageRemoteAttachmentRoots: (params: unknown) => string[];
};
const {
DEFAULT_IMESSAGE_ATTACHMENT_ROOTS,

View File

@@ -3,11 +3,14 @@ import {
loadBundledPluginContractApiSync,
} from "../../../src/test-utils/bundled-plugin-public-surface.js";
type TelegramContractSurface = typeof import("@openclaw/telegram/contract-api.js");
type WhatsAppApiSurface = Pick<
typeof import("@openclaw/whatsapp/api.js"),
"isWhatsAppGroupJid" | "normalizeWhatsAppTarget" | "whatsappCommandPolicy"
>;
type TelegramContractSurface = {
buildTelegramModelsProviderChannelData: (...args: unknown[]) => unknown;
};
type WhatsAppApiSurface = {
isWhatsAppGroupJid: (...args: unknown[]) => boolean;
normalizeWhatsAppTarget: (...args: unknown[]) => string | null;
whatsappCommandPolicy: Record<string, unknown>;
};
let telegramContractSurface: TelegramContractSurface | undefined;
let whatsappApiSurface: WhatsAppApiSurface | undefined;

View File

@@ -1,10 +1,16 @@
import type { SignalSender } from "@openclaw/signal/contract-api.js";
import { resolveRelativeBundledPluginPublicModuleId } from "../../../src/test-utils/bundled-plugin-public-surface.js";
type SignalContractApiSurface = Pick<
typeof import("@openclaw/signal/contract-api.js"),
"isSignalSenderAllowed"
>;
export type SignalSender = {
kind: string;
raw: string;
e164?: string;
uuid?: string;
username?: string;
};
type SignalContractApiSurface = {
isSignalSenderAllowed: (...args: unknown[]) => boolean;
};
let signalContractSurface: Promise<SignalContractApiSurface> | undefined;
@@ -18,4 +24,3 @@ export function getSignalContractSurface(): Promise<SignalContractApiSurface> {
) as Promise<SignalContractApiSurface>;
return signalContractSurface;
}
export type { SignalSender };

View File

@@ -5,7 +5,21 @@ import type { OpenClawConfig } from "../../../src/config/config.js";
import { resolveRelativeBundledPluginPublicModuleId } from "../../../src/test-utils/bundled-plugin-public-surface.js";
import { withTempHome } from "../temp-home.js";
type ResolvedSlackAccount = import("@openclaw/slack/api.js").ResolvedSlackAccount;
type ResolvedSlackAccount = {
accountId: string;
enabled: boolean;
botTokenSource: string;
appTokenSource: string;
userTokenSource: string;
config: {
replyToMode?: unknown;
replyToModeByChatType?: unknown;
dm?: unknown;
};
replyToMode?: unknown;
replyToModeByChatType?: unknown;
dm?: unknown;
};
type SlackMessageEvent = {
channel: string;

View File

@@ -1,12 +1,78 @@
export type {
DiscordInteractiveHandlerContext,
DiscordInteractiveHandlerRegistration,
} from "@openclaw/discord/contract-api.js";
export type {
SlackInteractiveHandlerContext,
SlackInteractiveHandlerRegistration,
} from "@openclaw/slack/contract-api.js";
export type {
TelegramInteractiveHandlerContext,
TelegramInteractiveHandlerRegistration,
} from "@openclaw/telegram/contract-api.js";
type ConversationBindingHelpers = {
requestConversationBinding: (...args: unknown[]) => unknown;
detachConversationBinding: (...args: unknown[]) => unknown;
getCurrentConversationBinding: (...args: unknown[]) => unknown;
};
type InteractiveHandlerRegistration<
TChannel extends string,
TContext,
> = ConversationBindingHelpers & {
channel: TChannel;
namespace: string;
handler: (ctx: TContext) => unknown;
};
type BaseInteractiveContext<TChannel extends string> = ConversationBindingHelpers & {
channel: TChannel;
accountId: string;
conversationId: string;
parentConversationId?: string;
senderId: string;
senderUsername?: string;
auth?: unknown;
};
export type TelegramInteractiveHandlerContext = BaseInteractiveContext<"telegram"> & {
callbackId: string;
senderUsername?: string;
threadId?: number;
isGroup?: boolean;
isForum?: boolean;
callback: {
data: string;
namespace: string;
payload: string;
messageId: number;
chatId: string;
messageText?: string;
};
respond: Record<string, (...args: unknown[]) => unknown>;
};
export type DiscordInteractiveHandlerContext = BaseInteractiveContext<"discord"> & {
interactionId: string;
guildId?: string;
interaction: {
data: string;
namespace: string;
payload: string;
[key: string]: unknown;
};
respond: Record<string, (...args: unknown[]) => unknown>;
};
export type SlackInteractiveHandlerContext = BaseInteractiveContext<"slack"> & {
interactionId: string;
threadId?: string;
interaction: {
data: string;
namespace: string;
payload: string;
[key: string]: unknown;
};
respond: Record<string, (...args: unknown[]) => unknown>;
};
export type TelegramInteractiveHandlerRegistration = InteractiveHandlerRegistration<
"telegram",
TelegramInteractiveHandlerContext
>;
export type DiscordInteractiveHandlerRegistration = InteractiveHandlerRegistration<
"discord",
DiscordInteractiveHandlerContext
>;
export type SlackInteractiveHandlerRegistration = InteractiveHandlerRegistration<
"slack",
SlackInteractiveHandlerContext
>;

View File

@@ -1,6 +1,9 @@
import { loadBundledPluginContractApiSync } from "../../../src/test-utils/bundled-plugin-public-surface.js";
type MatrixContractSurface = typeof import("@openclaw/matrix/contract-api.js");
type MatrixContractSurface = {
matrixSetupAdapter: Record<string, unknown>;
matrixSetupWizard: Record<string, unknown>;
};
let matrixContractSurface: MatrixContractSurface | undefined;

View File

@@ -9,29 +9,29 @@ import type { LineProbeResult } from "../../../src/plugin-sdk/line.js";
import { resolveRelativeBundledPluginPublicModuleId } from "../../../src/test-utils/bundled-plugin-public-surface.js";
import { withEnvAsync } from "../../../src/test-utils/env.js";
type DiscordDirectoryContractApiSurface = Pick<
typeof import("@openclaw/discord/directory-contract-api.js"),
"listDiscordDirectoryPeersFromConfig" | "listDiscordDirectoryGroupsFromConfig"
>;
type DiscordProbe = import("@openclaw/discord/api.js").DiscordProbe;
type DiscordTokenResolution = import("@openclaw/discord/api.js").DiscordTokenResolution;
type IMessageProbe = import("@openclaw/imessage/runtime-api.js").IMessageProbe;
type SignalProbe = import("@openclaw/signal/api.js").SignalProbe;
type SlackDirectoryContractApiSurface = Pick<
typeof import("@openclaw/slack/directory-contract-api.js"),
"listSlackDirectoryPeersFromConfig" | "listSlackDirectoryGroupsFromConfig"
>;
type SlackProbe = import("@openclaw/slack/api.js").SlackProbe;
type TelegramDirectoryContractApiSurface = Pick<
typeof import("@openclaw/telegram/directory-contract-api.js"),
"listTelegramDirectoryPeersFromConfig" | "listTelegramDirectoryGroupsFromConfig"
>;
type TelegramProbe = import("@openclaw/telegram/api.js").TelegramProbe;
type TelegramTokenResolution = import("@openclaw/telegram/api.js").TelegramTokenResolution;
type WhatsAppDirectoryContractApiSurface = Pick<
typeof import("@openclaw/whatsapp/directory-contract-api.js"),
"listWhatsAppDirectoryPeersFromConfig" | "listWhatsAppDirectoryGroupsFromConfig"
>;
type DiscordDirectoryContractApiSurface = {
listDiscordDirectoryPeersFromConfig: DirectoryListFn;
listDiscordDirectoryGroupsFromConfig: DirectoryListFn;
};
type DiscordProbe = BaseProbeResult;
type DiscordTokenResolution = BaseTokenResolution;
type IMessageProbe = BaseProbeResult;
type SignalProbe = BaseProbeResult;
type SlackDirectoryContractApiSurface = {
listSlackDirectoryPeersFromConfig: DirectoryListFn;
listSlackDirectoryGroupsFromConfig: DirectoryListFn;
};
type SlackProbe = BaseProbeResult;
type TelegramDirectoryContractApiSurface = {
listTelegramDirectoryPeersFromConfig: DirectoryListFn;
listTelegramDirectoryGroupsFromConfig: DirectoryListFn;
};
type TelegramProbe = BaseProbeResult;
type TelegramTokenResolution = BaseTokenResolution;
type WhatsAppDirectoryContractApiSurface = {
listWhatsAppDirectoryPeersFromConfig: DirectoryListFn;
listWhatsAppDirectoryGroupsFromConfig: DirectoryListFn;
};
let discordDirectoryContractApi: Promise<DiscordDirectoryContractApiSurface> | undefined;
let slackDirectoryContractApi: Promise<SlackDirectoryContractApiSurface> | undefined;

View File

@@ -1,15 +1,54 @@
import type { OpenClawConfig } from "../../../src/config/config.js";
import type { SecurityAuditFinding } from "../../../src/security/audit.types.js";
import {
loadBundledPluginPublicSurfaceSync,
resolveRelativeBundledPluginPublicModuleId,
} from "../../../src/test-utils/bundled-plugin-public-surface.js";
type DiscordSecurityAuditSurface =
typeof import("@openclaw/discord/security-audit-contract-api.js");
type FeishuSecuritySurface = typeof import("@openclaw/feishu/security-contract-api.js");
type SlackSecuritySurface = typeof import("@openclaw/slack/security-contract-api.js");
type SynologyChatSecuritySurface = typeof import("@openclaw/synology-chat/contract-api.js");
type TelegramSecuritySurface = typeof import("@openclaw/telegram/security-audit-contract-api.js");
type ZalouserSecuritySurface = typeof import("@openclaw/zalouser/contract-api.js");
type SecurityAuditAccount = {
accountId: string;
enabled?: boolean;
token?: unknown;
tokenSource?: string;
config?: Record<string, unknown>;
[key: string]: unknown;
};
type FlexibleSecurityAuditParams = {
cfg?: OpenClawConfig;
sourceConfig?: OpenClawConfig;
account: SecurityAuditAccount;
accountId?: string | null;
orderedAccountIds?: string[];
hasExplicitAccountPath?: boolean;
};
type ConfigSecurityAuditParams = {
cfg: OpenClawConfig;
};
type AsyncChannelSecurityAuditCollector = (
params: FlexibleSecurityAuditParams,
) => Promise<SecurityAuditFinding[]>;
type SyncChannelSecurityAuditCollector = (
params: FlexibleSecurityAuditParams,
) => SecurityAuditFinding[];
type ConfigSecurityAuditCollector = (params: ConfigSecurityAuditParams) => SecurityAuditFinding[];
type DiscordSecurityAuditSurface = {
collectDiscordSecurityAuditFindings: AsyncChannelSecurityAuditCollector;
};
type FeishuSecuritySurface = {
collectFeishuSecurityAuditFindings: ConfigSecurityAuditCollector;
};
type SlackSecuritySurface = {
collectSlackSecurityAuditFindings: AsyncChannelSecurityAuditCollector;
};
type SynologyChatSecuritySurface = {
collectSynologyChatSecurityAuditFindings: SyncChannelSecurityAuditCollector;
};
type TelegramSecuritySurface = {
collectTelegramSecurityAuditFindings: AsyncChannelSecurityAuditCollector;
};
type ZalouserSecuritySurface = {
collectZalouserSecurityAuditFindings: SyncChannelSecurityAuditCollector;
};
const discordSecurityAuditModuleId = resolveRelativeBundledPluginPublicModuleId({
fromModuleUrl: import.meta.url,

View File

@@ -1,6 +1,13 @@
import { loadBundledPluginContractApiSync } from "../../../src/test-utils/bundled-plugin-public-surface.js";
type AnthropicContractSurface = typeof import("@openclaw/anthropic/contract-api.js");
type AnthropicContractSurface = {
createAnthropicBetaHeadersWrapper: (...args: unknown[]) => unknown;
createAnthropicFastModeWrapper: (...args: unknown[]) => unknown;
createAnthropicServiceTierWrapper: (...args: unknown[]) => unknown;
resolveAnthropicBetas: (...args: unknown[]) => unknown;
resolveAnthropicFastMode: (...args: unknown[]) => unknown;
resolveAnthropicServiceTier: (...args: unknown[]) => unknown;
};
let anthropicContractSurface: AnthropicContractSurface | undefined;