fix(security): report DM isolation from effective routing (#121741)

* fix(security): audit effective DM session ownership

Resolve admitted DM principals through canonical route, account, identity-link, and channel-owned session policy before reporting shared-session risk. Doctor now renders the structured channel security owner instead of duplicating the global-only default-account heuristic.\n\nCloses #121711

* chore(plugin-sdk): refresh API contract baseline

* fix(telegram): preserve direct peer SDK export

* fix(telegram): preserve direct peer resolver signature

* fix(ci): use supported DM audit grouping

* fix(protocol): refresh approval reviewer Swift models
This commit is contained in:
Peter Steinberger
2026-08-10 15:34:37 -07:00
committed by GitHub
parent cf432ec871
commit c39abcecda
23 changed files with 1133 additions and 381 deletions
+65 -65
View File
@@ -53,15 +53,15 @@
{"closureHash":"ff3c4616cd6212a6d698831a8b287ad87e3968c8663f4090d095bb30ec40fc1c","declaration":"export function abortAndDrainAgentHarnessRun(params: { sessionId: string; sessionKey?: string; settleMs?: number; forceClear?: boolean; reason?: string; }): Promise<AbortAndDrainEmbeddedAgentRunResult>;","entrypoint":"agent-harness","exportName":"abortAndDrainAgentHarnessRun","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"58989e3fa91eecf2e05202e36548e6e64a3b9219e83154bd99866c851604e34e","declaration":"export function createAgentToolResultMiddlewareRunner(ctx: AgentToolResultMiddlewareContext, handlers?: AgentToolResultMiddleware[]): { applyToolResultMiddleware(event: AgentToolResultMiddlewareEvent): Promise<OpenClawAgentToolResult>; };","entrypoint":"agent-harness","exportName":"createAgentToolResultMiddlewareRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"b8f6355d7ad1700aceecddaa6e9ccf43091a792d5b481a1ee3f55294a881a67d","declaration":"export function createCodexAppServerToolResultExtensionRunner(ctx: CodexAppServerExtensionContext, factories?: CodexAppServerExtensionFactory[]): { applyToolResultExtensions(event: CodexAppServerToolResultEvent): Promise<AgentToolResult<unknown>>; };","entrypoint":"agent-harness","exportName":"createCodexAppServerToolResultExtensionRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"82a967232dd50d7c7a42d6a576722af500feba6c6170c808a3297ea36f6a9bec","declaration":"export function createOpenClawCodingTools(options?: OpenClawCodingToolsOptions): AnyAgentTool[];","entrypoint":"agent-harness","exportName":"createOpenClawCodingTools","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"fd6548682cda2d069f1a9b6eef190102b4ebcadc20d485d5ee9d2cb6e4419011","declaration":"export function createOpenClawCodingTools(options?: OpenClawCodingToolsOptions): AnyAgentTool[];","entrypoint":"agent-harness","exportName":"createOpenClawCodingTools","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"13649ee853485319e7449fda25c106b3f3f53d3090e53cdbb28e220a8529eb80","declaration":"export function disposeRegisteredAgentHarnesses(): Promise<void>;","entrypoint":"agent-harness","exportName":"disposeRegisteredAgentHarnesses","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"f255a91162ece4c239bb8fa745efa14a1054bc024a291e9954f75f239b2b87c3","declaration":"export function resolveActiveEmbeddedRunSessionId(sessionKey: string): string | undefined;","entrypoint":"agent-harness","exportName":"resolveActiveEmbeddedRunSessionId","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"27d9f61df9ccf68615cb2002a6da891e36ab0c07623bc37c4d07aa980b446881","declaration":"export function resolveWebSearchToolPolicy(params: WebSearchToolPolicyParams): WebSearchToolPolicyResolution;","entrypoint":"agent-harness","exportName":"resolveWebSearchToolPolicy","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"e75e94d131237b4b73c507cad9f2a0940716404531516861497e92ba8d06fb87","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"71e57b87ff6cba595cc4513f2fd68742eb69a234d17e328c6cc6761eec04385e","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"4ad0f830bf11a2db48faefb1439b7fbb08d9f22d22083f5e301327e1696f2310","declaration":"export type AgentToolResultMiddleware = AgentToolResultMiddleware;","entrypoint":"agent-harness","exportName":"AgentToolResultMiddleware","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"008b6c78d5e44a9d1df1d7e32e6015382ee9ba1cb9b10bd4c2b467619d1c89d4","declaration":"export type AgentToolResultMiddlewareEvent = AgentToolResultMiddlewareEvent;","entrypoint":"agent-harness","exportName":"AgentToolResultMiddlewareEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"7414a2a79c2d78c1d52538250c827305bba1a2bb25010448837c8524a9f95b3c","declaration":"export type AnyAgentTool = AnyAgentTool;","entrypoint":"agent-harness","exportName":"AnyAgentTool","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"49c4aa50aa6a16de715caebb9215d233ab86bdc710b457b060c7de3857180b84","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"f975d7a88a7e25914f7a255354a6c2f0ede9281ca793e47ed971450e358dfbb4","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"25c6985c3bef2c6efc6a96e70af6d66fe073be0b0d311681cfc0dfc186528d9a","declaration":"export type OpenClawAgentToolResult<TResult = unknown> = OpenClawAgentToolResult<TResult>;","entrypoint":"agent-harness","exportName":"OpenClawAgentToolResult","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"category":"runtime","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","recordType":"module"}
{"closureHash":"fab99dfcb01d475a1bfdbe7a8fac9be10a93dac5f12ac78c2dea673c8ab86abf","declaration":"export function abortAgentHarnessRun(sessionId: string): boolean;\nexport function abortAgentHarnessRun(sessionId: undefined, opts: { mode: \"all\" | \"compacting\"; reason?: \"restart\"; }): boolean;","entrypoint":"agent-harness-runtime","exportName":"abortAgentHarnessRun","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
@@ -80,8 +80,8 @@
{"closureHash":"593bc2b598c7715ab011aa6ab5659f02262f134b15f218b02921e1c7e33198ba","declaration":"export function buildAgentRuntimePlan(params: BuildAgentRuntimePlanParams): AgentRuntimePlan;","entrypoint":"agent-harness-runtime","exportName":"buildAgentRuntimePlan","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"528d11abf061b0b303722737de5a6406e7e55bffa38c45144c77d896ae1b3b0a","declaration":"export function buildBootstrapContextForFiles(bootstrapFiles: WorkspaceBootstrapFile[], params: { config?: OpenClawConfig; agentId?: string | null; warn?: (message: string) => void; }): EmbeddedContextFile[];","entrypoint":"agent-harness-runtime","exportName":"buildBootstrapContextForFiles","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"44d5a4667d2f3dc3a28e5c9d7b46765b1fb3c62820288e40251f5174911c8a6a","declaration":"export function buildEmbeddedAttemptToolRunContext(params: { trigger?: EmbeddedRunTrigger; jobId?: string; memoryFlushWritePath?: string; toolsAllow?: string[]; conversationToolPolicy?: GroupToolPolicyConfig; trace?: DiagnosticTraceContext; }): { trigger?: EmbeddedRunTrigger; jobId?: string; memoryFlushWritePath?: string; runtimeToolAllowlist?: string[]; conversationToolPolicy?: GroupToolPolicyConfig; trace?: DiagnosticTraceContext; };","entrypoint":"agent-harness-runtime","exportName":"buildEmbeddedAttemptToolRunContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"0044b5f2a53d7378e9e6f7e60303a99af22ba23d124cfdfbc3d87fe33a15b2a5","declaration":"export function buildHarnessContextEngineRuntimeContext(params: Parameters<typeof buildAfterTurnRuntimeContext>[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"3c5037a93268c28d1d0c1855793cd448d7c40d535422e18245d30a61c12a5e02","declaration":"export function buildHarnessContextEngineRuntimeContextFromUsage(params: Parameters<typeof buildAfterTurnRuntimeContextFromUsage>[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContextFromUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"792093d47cf7874e3a30edca5a3f4e2e3b30237c99e4a567adab2ea74ebb9014","declaration":"export function buildHarnessContextEngineRuntimeContext(params: Parameters<typeof buildAfterTurnRuntimeContext>[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"7371785d39b9e470e35b1cb3bfd4e64ab2a71562a4a4411057999b94eba5d812","declaration":"export function buildHarnessContextEngineRuntimeContextFromUsage(params: Parameters<typeof buildAfterTurnRuntimeContextFromUsage>[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContextFromUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"33a7cd8d63d4ef045ee3a42f806026a8b621e7dd32d8d6fbf4e7b44452d5e0ce","declaration":"export function buildNativeHookRelayCommand(params: { provider: NativeHookRelayProvider; relayId: string; generation?: string; event: NativeHookRelayEvent; preToolUseUnavailable?: \"noop\"; timeoutMs?: number; executable?: string; nice?: number | false; nodeExecutable?: string; }): string;","entrypoint":"agent-harness-runtime","exportName":"buildNativeHookRelayCommand","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"3846647c3c2fb0242f70591cf95c2e02f2a5a3c44447efb4cf7a31b2dc2122fd","declaration":"export function buildSkillWorkshopPromptSection(): string[];","entrypoint":"agent-harness-runtime","exportName":"buildSkillWorkshopPromptSection","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"32e977ece65144a83ae1b0a3c8d1b9b00a2a2506ad9ef1db3b2b9770ce762dbe","declaration":"export function buildWatchedSessionsHarnessContext(params: { config?: OpenClawConfig; sessionKey?: string; sandboxed?: boolean; toolNames: Iterable<string>; capabilityToolNames?: Iterable<string>; }): string | undefined;","entrypoint":"agent-harness-runtime","exportName":"buildWatchedSessionsHarnessContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
@@ -98,7 +98,7 @@
{"closureHash":"51f76e9e37b65b358f0313e10152d950b003bc3e50f4bb26fe29a988237772e2","declaration":"export function consumePreExecutionBlockedToolCall(toolCallId: string, runId?: string): boolean;","entrypoint":"agent-harness-runtime","exportName":"consumePreExecutionBlockedToolCall","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"58989e3fa91eecf2e05202e36548e6e64a3b9219e83154bd99866c851604e34e","declaration":"export function createAgentToolResultMiddlewareRunner(ctx: AgentToolResultMiddlewareContext, handlers?: AgentToolResultMiddleware[]): { applyToolResultMiddleware(event: AgentToolResultMiddlewareEvent): Promise<OpenClawAgentToolResult>; };","entrypoint":"agent-harness-runtime","exportName":"createAgentToolResultMiddlewareRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"b8f6355d7ad1700aceecddaa6e9ccf43091a792d5b481a1ee3f55294a881a67d","declaration":"export function createCodexAppServerToolResultExtensionRunner(ctx: CodexAppServerExtensionContext, factories?: CodexAppServerExtensionFactory[]): { applyToolResultExtensions(event: CodexAppServerToolResultEvent): Promise<AgentToolResult<unknown>>; };","entrypoint":"agent-harness-runtime","exportName":"createCodexAppServerToolResultExtensionRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"ceb4f4b948da28b98ff86f7cedfba4e7f17135c7e1321f4b528d8749fa389132","declaration":"export function deliverAgentHarnessUserInputPrompt(params: PromptDeliveryParams, questions: readonly AgentHarnessUserInputQuestion[], options?: AgentHarnessUserInputPromptOptions): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"deliverAgentHarnessUserInputPrompt","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"149e13ab601ed9304f695360d5ffa481e79d8d3a5cc163357d8a7e7a7e66a7d5","declaration":"export function deliverAgentHarnessUserInputPrompt(params: PromptDeliveryParams, questions: readonly AgentHarnessUserInputQuestion[], options?: AgentHarnessUserInputPromptOptions): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"deliverAgentHarnessUserInputPrompt","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"6f436485257f69fa07a18203b91d4341690522f12aff4f25805c7a1e21326ee3","declaration":"export function detectAndLoadAgentHarnessPromptImages(params: { prompt: string; workspaceDir: string; model: { input?: string[]; }; existingImages?: ImageContent[]; imageOrder?: PromptImageOrderEntry[]; media?: MediaFact[]; config?: OpenClawConfig; workspaceOnly?: boolean; localRoots?: readonly string[]; sandbox?: { root: string; bridge: SandboxFsBridge; }; }): Promise<{ images: ImageContent[]; detectedRefs: Array<{ raw: string; resolved: string; type: \"path\" | \"media-uri\"; }>; loadedCount: number; skippedCount: number; }>;","entrypoint":"agent-harness-runtime","exportName":"detectAndLoadAgentHarnessPromptImages","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"13649ee853485319e7449fda25c106b3f3f53d3090e53cdbb28e220a8529eb80","declaration":"export function disposeRegisteredAgentHarnesses(): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"disposeRegisteredAgentHarnesses","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"c38cd390190bb07ddcd247420d6e0b489a0229bd402ddca0440417217a57251a","declaration":"export function emitAgentEvent(event: Omit<AgentEventPayload, \"seq\" | \"ts\">): void;","entrypoint":"agent-harness-runtime","exportName":"emitAgentEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
@@ -195,7 +195,7 @@
{"closureHash":"e4784aeda4c24b60cd49b7f5983e70a380a4759d5176c74d30f2900952ba848f","declaration":"export function runAgentHarnessBeforeAgentFinalizeHook(params: { event: PluginHookBeforeAgentFinalizeEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): Promise<AgentHarnessBeforeAgentFinalizeOutcome>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeAgentFinalizeHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"8fec73ee8c7c9be3335bd6dc1bac9278f0be5beef22a5975eb06e56f504f4bd6","declaration":"export function runAgentHarnessBeforeCompactionHook(params: { sessionFile: string; messages?: AgentMessage[]; ctx: AgentHarnessHookContext; }): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeCompactionHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"021b81820bef2e8d54c50a5fc159d6665b23b50a1f5c40dae76a4833839d89c9","declaration":"export function runAgentHarnessBeforeMessageWriteHook(params: { message: AgentMessage; agentId?: string; sessionKey?: string; }): AgentMessage | null;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeMessageWriteHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"1707257505ae1574ce02a6fb3ea20bb59dbcad1d324e078d778d0407606d95de","declaration":"export function runAgentHarnessGatewayQuestion(params: RunAgentHarnessGatewayQuestionParams): Promise<QuestionWaitAnswerResult>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessGatewayQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"1265cab97fe0a20462087f4fd953b2e97e86fe99e0f2433edd1752e187132fd8","declaration":"export function runAgentHarnessGatewayQuestion(params: RunAgentHarnessGatewayQuestionParams): Promise<QuestionWaitAnswerResult>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessGatewayQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"50a4d7cb20dd8f884abbcb62d77b5b2df183fbfcd058cc7aa76edacd1f7b90d8","declaration":"export function runAgentHarnessLlmInputHook(params: { event: PluginHookLlmInputEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessLlmInputHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"1bd55c141c249b1c04470cafe0cd4d41dce334ea2883ce83235af56d24a15cca","declaration":"export function runAgentHarnessLlmOutputHook(params: { event: PluginHookLlmOutputEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessLlmOutputHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"c4c5131ab7065decd8d8e935ac3779e3baa2c52fbbbd95a6ccb624377db09ca1","declaration":"export function runBeforeToolCallHook(args: { toolName: string; params: unknown; toolKind?: PluginHookToolKind; toolInputKind?: PluginHookToolInputKind; toolCallId?: string; ctx?: HookContext; signal?: AbortSignal; approvalMode?: \"request\" | \"report\" | \"deny\" | \"defer\"; }): Promise<HookOutcome>;","entrypoint":"agent-harness-runtime","exportName":"runBeforeToolCallHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
@@ -221,8 +221,8 @@
{"closureHash":"f237bbc11e1d389679cd4e2ad7aa9055951b3029348e3374b81f769786a51d55","declaration":"export type AbortAndDrainAgentHarnessRunResult = AbortAndDrainEmbeddedAgentRunResult;","entrypoint":"agent-harness-runtime","exportName":"AbortAndDrainAgentHarnessRunResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"6f802f46717d28d260bbcb2cf4790dfed4e9ab28c4fe822d259228189cca4665","declaration":"export type AgentApprovalEventData = AgentApprovalEventData;","entrypoint":"agent-harness-runtime","exportName":"AgentApprovalEventData","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"12aac3a57ce200b0f082002be237625729f84ed7c337f1bac90bcd0688a53319","declaration":"export type AgentEventPayload = AgentEventPayload;","entrypoint":"agent-harness-runtime","exportName":"AgentEventPayload","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"e75e94d131237b4b73c507cad9f2a0940716404531516861497e92ba8d06fb87","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness-runtime","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"e75e94d131237b4b73c507cad9f2a0940716404531516861497e92ba8d06fb87","declaration":"export type AgentHarnessAttemptParams = AgentHarnessAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"71e57b87ff6cba595cc4513f2fd68742eb69a234d17e328c6cc6761eec04385e","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness-runtime","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"71e57b87ff6cba595cc4513f2fd68742eb69a234d17e328c6cc6761eec04385e","declaration":"export type AgentHarnessAttemptParams = AgentHarnessAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"2dc2a62deea63b316142cc28d40afb88fb0d1e5ce3e048f141420726cda38248","declaration":"export type AgentHarnessAttemptResult = AgentHarnessAttemptResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"c7e642234081160830fd9e18a301900f8ee1ea8c88382e5a286f0102de65b714","declaration":"export type AgentHarnessAuthBindingFingerprintParams = AgentHarnessAuthBindingFingerprintParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAuthBindingFingerprintParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"601d68a3c668b18a4009d33b516d577bade06c3f89fafaa19685681c44d801b2","declaration":"export type AgentHarnessCompactParams = CompactEmbeddedAgentSessionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessCompactParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
@@ -271,7 +271,7 @@
{"closureHash":"f30b66fd82f4cd61c60880c42a3b8f152ca64a2216036c99ab4129648ed329e7","declaration":"export type EmbeddedAgentCompactResult = EmbeddedAgentCompactResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedAgentCompactResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"1bbefad0193436f7340f9d0dec50be5d482973325c3c65170b1053dd05566f0a","declaration":"export type EmbeddedContextFile = EmbeddedContextFile;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedContextFile","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"f30b66fd82f4cd61c60880c42a3b8f152ca64a2216036c99ab4129648ed329e7","declaration":"export type EmbeddedPiCompactResult = EmbeddedAgentCompactResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedPiCompactResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"49c4aa50aa6a16de715caebb9215d233ab86bdc710b457b060c7de3857180b84","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"f975d7a88a7e25914f7a255354a6c2f0ede9281ca793e47ed971450e358dfbb4","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"a6cd2eebe0d06e6578ec8438a207c5acda10ddf01041102d84e4c576a0b6a42f","declaration":"export type EmbeddedRunAttemptResult = EmbeddedRunAttemptResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"f6cb2d6411db22cb04220777720d97bcca977351de1cb344ce2ff6ab126a3a08","declaration":"export type ExecApprovalDecision = ExecApprovalDecision;","entrypoint":"agent-harness-runtime","exportName":"ExecApprovalDecision","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"7acb0dffc7bcda6c727e4afc49c955fa8e14f4f8b7b45d197ed794dfa0d73b8e","declaration":"export type ExecAutoReviewDecision = ExecAutoReviewDecision;","entrypoint":"agent-harness-runtime","exportName":"ExecAutoReviewDecision","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
@@ -755,37 +755,37 @@
{"closureHash":"3ec2c091f2139a6c20b090ef4aa8a7e052440040bc620ce6cb7b8fd5ced3efa3","declaration":"export function buildThreadAwareOutboundSessionRoute(params: { route: ChannelOutboundSessionRoute; replyToId?: string | number | null; threadId?: string | number | null; currentSessionKey?: string | null; precedence?: readonly ThreadAwareOutboundSessionRouteThreadSource[]; useSuffix?: boolean; parentSessionKey?: string; normalizeThreadId?: (threadId: string) => string; canRecoverCurrentThread?: (context: ThreadAwareOutboundSessionRouteRecoveryContext) => boolean; }): ChannelOutboundSessionRoute;","entrypoint":"channel-core","exportName":"buildThreadAwareOutboundSessionRoute","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"9fc7e45343d7bfbc6ed56d05c9f824e2f9cf6dafc3ca4b25437d1f65c2200727","declaration":"export function clearAccountEntryFields<TAccountEntry extends object>(params: { accounts?: Record<string, TAccountEntry>; accountId: string; fields: string[]; isValueSet?: (value: unknown) => boolean; markClearedOnFieldPresence?: boolean; }): { nextAccounts?: Record<string, TAccountEntry>; changed: boolean; cleared: boolean; };","entrypoint":"channel-core","exportName":"clearAccountEntryFields","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"f4e084b64b5376268885a73fe507aa5d72bee17a88ec2d7ae1d19b36ea5f1ccb","declaration":"export function createChannelConfigUiHints(params: { channelLabel: string; dmPolicy?: { channelKey: string; includeLegacyNestedPolicy?: boolean; legacyNestedPolicyOrder?: \"before\" | \"after\"; }; configWrites?: boolean; mentionPatterns?: { targetDescription: string; policyTargetDescription?: string; policyNote?: string; denyNote?: string; }; nativeCommands?: boolean; implicitMentions?: boolean; progress?: { includeCommentary?: boolean; commentaryOrder?: \"before-command\" | \"after-command\"; labels?: \"openclaw\"; titleWording?: boolean; }; streaming?: Partial<Record<StreamingHintKey, StreamingHintValue>>; retry?: boolean; }): HintMap;","entrypoint":"channel-core","exportName":"createChannelConfigUiHints","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"c26bfcd8451627b0eb75f7837e281b58dc127d19591d7c030691ca9bbe0edbf4","declaration":"export function createChatChannelPlugin<TResolvedAccount extends { accountId?: string | null; }, Probe = unknown, Audit = unknown>(params: { base: ChatChannelPluginBase<TResolvedAccount, Probe, Audit>; security?: ChannelSecurityAdapter<TResolvedAccount> | ChatChannelSecurityOptions<TResolvedAccount>; pairing?: ChannelPairingAdapter | ChatChannelPairingOptions; threading?: ChannelThreadingAdapter | ChatChannelThreadingOptions<TResolvedAccount>; outbound?: ChannelOutboundAdapter | ChatChannelAttachedOutboundOptions; }): ChannelPlugin<TResolvedAccount, Probe, Audit>;","entrypoint":"channel-core","exportName":"createChatChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"c4b7032c03cf9c056cfab60aeddd037258981854bd1081a4b88ccfed0306317a","declaration":"export function defineChannelPluginEntry<TPlugin>({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin>;","entrypoint":"channel-core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"b8e27bea2add3eaafac7074cbd44fcf2acea30a1ac125c3551925e8cd0b3378d","declaration":"export function createChatChannelPlugin<TResolvedAccount extends { accountId?: string | null; }, Probe = unknown, Audit = unknown>(params: { base: ChatChannelPluginBase<TResolvedAccount, Probe, Audit>; security?: ChannelSecurityAdapter<TResolvedAccount> | ChatChannelSecurityOptions<TResolvedAccount>; pairing?: ChannelPairingAdapter | ChatChannelPairingOptions; threading?: ChannelThreadingAdapter | ChatChannelThreadingOptions<TResolvedAccount>; outbound?: ChannelOutboundAdapter | ChatChannelAttachedOutboundOptions; }): ChannelPlugin<TResolvedAccount, Probe, Audit>;","entrypoint":"channel-core","exportName":"createChatChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"9eec5be09e3eabc56729d2dcf61798420c8b5bd13d732790ab88e951c37156e4","declaration":"export function defineChannelPluginEntry<TPlugin>({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin>;","entrypoint":"channel-core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"0e0a9f6b22c433bdb1165e7707b1f9a1ddac1a544a8add00b503048cf157921f","declaration":"export function defineSetupPluginEntry<TPlugin>(plugin: TPlugin): { plugin: TPlugin; };","entrypoint":"channel-core","exportName":"defineSetupPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"8895f7af11b994dcd383ebc45d8cfb3c3b1e6d88a64a001b04f604a83f77e517","declaration":"export function parseOptionalDelimitedEntries(value?: string): string[] | undefined;","entrypoint":"channel-core","exportName":"parseOptionalDelimitedEntries","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"3f97534b10d08eda6a556044eaba623b3744b200a2033877e48d2f2ca924d298","declaration":"export function recoverCurrentThreadSessionId(params: { route: ChannelOutboundSessionRoute; currentSessionKey?: string | null; canRecover?: (context: ThreadAwareOutboundSessionRouteRecoveryContext) => boolean; }): string | undefined;","entrypoint":"channel-core","exportName":"recoverCurrentThreadSessionId","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"0f0c9fb9b983b0c977229de86091efa1fbb7c8294657bd993ecd5448b351f371","declaration":"export function stripChannelTargetPrefix(raw: string, ...providers: string[]): string;","entrypoint":"channel-core","exportName":"stripChannelTargetPrefix","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"ba015db1f7f7fad580c6bed6d69816f9ba04dea11bb0605cac1f2f2baddb7bca","declaration":"export function stripTargetKindPrefix(raw: string): string;","entrypoint":"channel-core","exportName":"stripTargetKindPrefix","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"2e6ce1f4c1692270a00dc0cf08e2752a26739c3143f8091cb270063c6034605d","declaration":"export function tryReadSecretFileSync(filePath: string | undefined, label: string, options: CredentialFileReadOptions): string | undefined;\nexport function tryReadSecretFileSync(filePath: string | undefined, label: string, options?: FsSafeSecretFileReadOptions): string | undefined;\nexport function tryReadSecretFileSync(filePath: string, label: string, options: FsSafeSecretFileReadOptions | undefined, diagnostic: { configPath: string; }): ConfiguredCredentialResult<string>;\nexport function tryReadSecretFileSync(filePath: string | undefined, label: string, options: FsSafeSecretFileReadOptions | undefined, diagnostic: { configPath: string; }): CredentialResult<string>;","entrypoint":"channel-core","exportName":"tryReadSecretFileSync","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"}
{"closureHash":"a5df78f0e910228e5cdea73e55f0335787437091ea28185ea264724e43b8b167","declaration":"export const createChannelPluginBase: <TResolvedAccount>(params: { id: ChannelPlugin<TResolvedAccount>[\"id\"]; meta?: Partial<NonNullable<ChannelPlugin<TResolvedAccount>[\"meta\"]>>; setupWizard?: NonNullable<ChannelPlugin<TResolvedAccount>[\"setupWizard\"]>; capabilities?: ChannelPlugin<TResolvedAccount>[\"capabilities\"]; commands?: ChannelPlugin<TResolvedAccount>[\"commands\"]; doctor?: ChannelPlugin<TResolvedAccount>[\"doctor\"]; agentPrompt?: ChannelPlugin<TResolvedAccount>[\"agentPrompt\"]; streaming?: ChannelPlugin<TResolvedAccount>[\"streaming\"]; reload?: ChannelPlugin<TResolvedAccount>[\"reload\"]; gatewayMethods?: ChannelPlugin<TResolvedAccount>[\"gatewayMethods\"]; gatewayMethodDescriptors?: ChannelPlugin<TResolvedAccount>[\"gatewayMethodDescriptors\"]; configSchema?: ChannelPlugin<TResolvedAccount>[\"configSchema\"]; config?: ChannelConfigAdapter<TResolvedAccount> | undefined; security?: ChannelSecurityAdapter<TResolvedAccount> | undefined; setup?: NonNullable<ChannelPlugin<TResolvedAccount>[\"setup\"]>; setupContract?: NonNullable<ChannelPlugin<TResolvedAccount>[\"setupContract\"]>; groups?: ChannelPlugin<TResolvedAccount>[\"groups\"];}) => Pick<ChannelPlugin<TResolvedAccount>, \"id\" | \"meta\"> & Partial<Pick<ChannelPlugin<TResolvedAccount>, \"security\" | \"commands\" | \"groups\" | \"capabilities\" | \"streaming\" | \"config\" | \"reload\" | \"configSchema\" | \"setup\" | \"doctor\" | \"gatewayMethodDescriptors\" | \"setupContract\" | \"setupWizard\" | \"gatewayMethods\" | \"agentPrompt\">>;","entrypoint":"channel-core","exportName":"createChannelPluginBase","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"const","recordType":"export"}
{"closureHash":"78d00beda3fcd305326e030090a06b90b5567866e1aef144db85fb6bfa8d0a47","declaration":"export const createChannelPluginBase: <TResolvedAccount>(params: { id: ChannelPlugin<TResolvedAccount>[\"id\"]; meta?: Partial<NonNullable<ChannelPlugin<TResolvedAccount>[\"meta\"]>>; setupWizard?: NonNullable<ChannelPlugin<TResolvedAccount>[\"setupWizard\"]>; capabilities?: ChannelPlugin<TResolvedAccount>[\"capabilities\"]; commands?: ChannelPlugin<TResolvedAccount>[\"commands\"]; doctor?: ChannelPlugin<TResolvedAccount>[\"doctor\"]; agentPrompt?: ChannelPlugin<TResolvedAccount>[\"agentPrompt\"]; streaming?: ChannelPlugin<TResolvedAccount>[\"streaming\"]; reload?: ChannelPlugin<TResolvedAccount>[\"reload\"]; gatewayMethods?: ChannelPlugin<TResolvedAccount>[\"gatewayMethods\"]; gatewayMethodDescriptors?: ChannelPlugin<TResolvedAccount>[\"gatewayMethodDescriptors\"]; configSchema?: ChannelPlugin<TResolvedAccount>[\"configSchema\"]; config?: ChannelConfigAdapter<TResolvedAccount> | undefined; security?: ChannelSecurityAdapter<TResolvedAccount> | undefined; setup?: NonNullable<ChannelPlugin<TResolvedAccount>[\"setup\"]>; setupContract?: NonNullable<ChannelPlugin<TResolvedAccount>[\"setupContract\"]>; groups?: ChannelPlugin<TResolvedAccount>[\"groups\"];}) => Pick<ChannelPlugin<TResolvedAccount>, \"id\" | \"meta\"> & Partial<Pick<ChannelPlugin<TResolvedAccount>, \"security\" | \"commands\" | \"groups\" | \"capabilities\" | \"streaming\" | \"config\" | \"reload\" | \"configSchema\" | \"setup\" | \"doctor\" | \"gatewayMethodDescriptors\" | \"setupContract\" | \"setupWizard\" | \"gatewayMethods\" | \"agentPrompt\">>;","entrypoint":"channel-core","exportName":"createChannelPluginBase","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"const","recordType":"export"}
{"closureHash":"db6db8b2272765050d9dab70b7793f052520d8745923290375a50661f3e33cc8","declaration":"export type ChannelConfigUiHint = ChannelConfigUiHint;","entrypoint":"channel-core","exportName":"ChannelConfigUiHint","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"8126b651a679d5435eaa5d346916792c3600e5f0f75d8492b077dd361854f7dd","declaration":"export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; currentSessionKey?: string; resolvedTarget?: { to: string; kind: ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};","entrypoint":"channel-core","exportName":"ChannelOutboundSessionRouteParams","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"4dd12b961fc300d388143ed5d8dc990e759c382b949c337c8f28ac83ca65aae7","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"channel-core","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"18fcab0d5899575a31205732d2be92597e533ad944c7fe11cac2af6fc718ea34","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"channel-core","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"channel-core","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"fb4fde629072c35c7afe2f3248520c284b439596eb2e25c136b6494b402cee1f","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"b9c63a41b3da754e29aee2040c6b79300801cb59b95dcedf8032f404cd0c9a8d","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"4bf9c20e2a621ecc84998961937887666d84884ef6f8f1993a34c87c11000b60","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"3203c47bc265736977eb102837cf12d2fe8f8dc459389c21f319d9426d83dc8e","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"channel-core","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"category":"channel","entrypoint":"channel-dm-policy","importSpecifier":"openclaw/plugin-sdk/channel-dm-policy","recordType":"module"}
{"closureHash":"821fe6ccd0d9323322bf70c4d1ca5697071a0e32032f44c1e14157162c2c729d","declaration":"export function createChannelDmPolicy<TConfig extends DmPolicyAccountConfig>(params: CreateChannelDmPolicyParams<TConfig>): ChannelSetupDmPolicy & { promptAllowFrom: NonNullable<ChannelSetupDmPolicy[\"promptAllowFrom\"]>; };","entrypoint":"channel-dm-policy","exportName":"createChannelDmPolicy","importSpecifier":"openclaw/plugin-sdk/channel-dm-policy","kind":"function","recordType":"export"}
{"category":null,"entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","recordType":"module"}
{"closureHash":"f926201f9283010418a03fd8ef841fb2616017d05975365dc979bbde0747c7a9","declaration":"export function defineBundledChannelEntry<TPlugin = ChannelPlugin>({ id, name, description, importMetaUrl, plugin, outbound, secrets, configSchema, runtime, accountInspect, features, registerCliMetadata, registerFull, registerCapabilities, }: DefineBundledChannelEntryOptions<TPlugin>): BundledChannelEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
{"closureHash":"4d79a9648b7007df00560ca5a1a33e6fccc2d92cd00a0fea8ca52eada4d326ea","declaration":"export function defineBundledChannelSetupEntry<TPlugin = ChannelPlugin>({ importMetaUrl, plugin, secrets, runtime, legacyStateMigrations, legacySessionSurface, registerSetupRuntime, features, }: DefineBundledChannelSetupEntryOptions): BundledChannelSetupEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelSetupEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
{"closureHash":"77ed16a89093257c19f2f0ec5dc040b684d4c96b3a3afb95b5346123128c5910","declaration":"export function defineBundledChannelEntry<TPlugin = ChannelPlugin>({ id, name, description, importMetaUrl, plugin, outbound, secrets, configSchema, runtime, accountInspect, features, registerCliMetadata, registerFull, registerCapabilities, }: DefineBundledChannelEntryOptions<TPlugin>): BundledChannelEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
{"closureHash":"c223d3c170b0dc6ed877fd13a05341da5ed89f55a9138de5015cdffcef266fdb","declaration":"export function defineBundledChannelSetupEntry<TPlugin = ChannelPlugin>({ importMetaUrl, plugin, secrets, runtime, legacyStateMigrations, legacySessionSurface, registerSetupRuntime, features, }: DefineBundledChannelSetupEntryOptions): BundledChannelSetupEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelSetupEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
{"closureHash":"cd150287d7e286e7a0d7d6caeb05d0a1efa63b5f351f75f69ba932510a108afd","declaration":"export function loadBundledEntryExportSync<T>(importMetaUrl: string, reference: BundledEntryModuleRef, options?: BundledEntryModuleLoadOptions): T;","entrypoint":"channel-entry-contract","exportName":"loadBundledEntryExportSync","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"}
{"closureHash":"7781a3d570d08929af5b3b6cffbb9ef4b9c8e8f1bed55234e0015a681868c812","declaration":"export type AnyAgentTool = AnyAgentTool;","entrypoint":"channel-entry-contract","exportName":"AnyAgentTool","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"12459db2b865a0aea85d69e055538a24c0cc3993a083b0630465d909ff4af7f3","declaration":"export type BundledChannelEntryContract<TPlugin = ChannelPlugin> = BundledChannelEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"e93a25fc5f26079e40a477b03e7b183c95bbca1c780f5fea98710c4a3196179d","declaration":"export type BundledChannelEntryContract<TPlugin = ChannelPlugin> = BundledChannelEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"f4b82dfd995bd6f08b232984743389d1c854866cb845a8dbb3605acb28818688","declaration":"export type BundledChannelEntryFeatures = BundledChannelEntryFeatures;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryFeatures","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"960693591b9bdc974bf3f0097076d90490078db3dceb35349a4f851736cde4fc","declaration":"export type BundledChannelLegacySessionSurface = BundledChannelLegacySessionSurface;","entrypoint":"channel-entry-contract","exportName":"BundledChannelLegacySessionSurface","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"edf79e6a736e5c4977e3b86ef21e7fdf0c0b2bc7deacd8edbee2ca76cb8cef43","declaration":"export type BundledChannelLegacyStateMigrationDetector = BundledChannelLegacyStateMigrationDetector;","entrypoint":"channel-entry-contract","exportName":"BundledChannelLegacyStateMigrationDetector","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"68b7d919c703115b3ab0acb41f6fe59c23e4888de19fc7bb8f73e42f9ae1d253","declaration":"export type BundledChannelSetupEntryContract<TPlugin = ChannelPlugin> = BundledChannelSetupEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"d9419e11e4b295fa773cabd3e62af412fe761b62f841eafb5c9809636a1258b7","declaration":"export type BundledChannelSetupEntryContract<TPlugin = ChannelPlugin> = BundledChannelSetupEntryContract<TPlugin>;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"24679ecdf2ff34157b6345a37b58ec1363ec8cb1969b522599d0d92bb7a113b7","declaration":"export type BundledChannelSetupEntryFeatures = BundledChannelSetupEntryFeatures;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryFeatures","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"367219c821915e5be4d1ba3a86754475a5f8a4194512f0401de3be11cc649c60","declaration":"export type BundledEntryModuleLoadOptions = BundledEntryModuleLoadOptions;","entrypoint":"channel-entry-contract","exportName":"BundledEntryModuleLoadOptions","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"6338ff51830d7387f35c03310d140f89d172f45805deb0b480698b4473ab9ef8","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"e1750a74dc768e6a21ee2eafbf486b817be19485a063e5a7f0f72d24540e73da","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"f22bde542d2dc632b20569c7679ee30a4e88851e0e9dec89350e120f6f456b15","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"a0103d278095a8687e571bcc0917c5c87fc1a1c79f151a07c7225c4d8f54a39d","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-entry-contract","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"channel-feedback","importSpecifier":"openclaw/plugin-sdk/channel-feedback","recordType":"module"}
@@ -1097,7 +1097,7 @@
{"closureHash":"9555a73ba2717bba0bf94888017be4cecef2c51cc3887ed34f8d8ef3c79d6abf","declaration":"export const DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS: number;","entrypoint":"channel-message","exportName":"DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
{"closureHash":"3a2df3ab656149630c004d2d9f71b8ceda99aa81eb6b72b0cc7b3982ed0ce044","declaration":"export const DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS: 8;","entrypoint":"channel-message","exportName":"DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
{"closureHash":"38c735a14c65067aa7825390d1c5c8876c651d0603e84980dfaf947f5235747a","declaration":"export const INGRESS_CLAIM_PROCESS_ID: string;","entrypoint":"channel-message","exportName":"INGRESS_CLAIM_PROCESS_ID","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
{"closureHash":"f5d6c974980d1792af370a89adca4417174efdc8bf3b70e140fdfe21d1692cca","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-message","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
{"closureHash":"16254799487aa48361f99ab341adad98738406e4af686ef50487780450c230fe","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-message","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"}
{"closureHash":"2c52eff200a5b9bd2d93ee72209c2626bbe165f59b538591db661b94773023b0","declaration":"export type AgentPlanStep = AgentPlanStep;","entrypoint":"channel-message","exportName":"AgentPlanStep","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"}
{"closureHash":"1e8bcb2c8d8f5327f5b81b8c217f722f090dccba21ba3943324010f4f80a5a50","declaration":"export type AgentPlanStepStatus = AgentPlanStepStatus;","entrypoint":"channel-message","exportName":"AgentPlanStepStatus","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"}
{"closureHash":"b036fc26e5330dfd7da1af8839bb3c23e85283b9e16e252a659dd4bb0c35cd5e","declaration":"export type ChannelDeliveryStreamingConfig = ChannelDeliveryStreamingConfig;","entrypoint":"channel-message","exportName":"ChannelDeliveryStreamingConfig","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"}
@@ -1226,7 +1226,7 @@
{"closureHash":"9555a73ba2717bba0bf94888017be4cecef2c51cc3887ed34f8d8ef3c79d6abf","declaration":"export const DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS: number;","entrypoint":"channel-outbound","exportName":"DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
{"closureHash":"3a2df3ab656149630c004d2d9f71b8ceda99aa81eb6b72b0cc7b3982ed0ce044","declaration":"export const DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS: 8;","entrypoint":"channel-outbound","exportName":"DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
{"closureHash":"38c735a14c65067aa7825390d1c5c8876c651d0603e84980dfaf947f5235747a","declaration":"export const INGRESS_CLAIM_PROCESS_ID: string;","entrypoint":"channel-outbound","exportName":"INGRESS_CLAIM_PROCESS_ID","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
{"closureHash":"f5d6c974980d1792af370a89adca4417174efdc8bf3b70e140fdfe21d1692cca","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-outbound","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
{"closureHash":"16254799487aa48361f99ab341adad98738406e4af686ef50487780450c230fe","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-outbound","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"}
{"closureHash":"2c52eff200a5b9bd2d93ee72209c2626bbe165f59b538591db661b94773023b0","declaration":"export type AgentPlanStep = AgentPlanStep;","entrypoint":"channel-outbound","exportName":"AgentPlanStep","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"}
{"closureHash":"1e8bcb2c8d8f5327f5b81b8c217f722f090dccba21ba3943324010f4f80a5a50","declaration":"export type AgentPlanStepStatus = AgentPlanStepStatus;","entrypoint":"channel-outbound","exportName":"AgentPlanStepStatus","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"}
{"closureHash":"b036fc26e5330dfd7da1af8839bb3c23e85283b9e16e252a659dd4bb0c35cd5e","declaration":"export type ChannelDeliveryStreamingConfig = ChannelDeliveryStreamingConfig;","entrypoint":"channel-outbound","exportName":"ChannelDeliveryStreamingConfig","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"}
@@ -1291,8 +1291,8 @@
{"closureHash":"b40933a11984425d14a7a479bda0d2cd14cbfa9371164774f39bebbf12861df7","declaration":"export const DEFAULT_ACCOUNT_ID: \"default\";","entrypoint":"channel-plugin-common","exportName":"DEFAULT_ACCOUNT_ID","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"const","recordType":"export"}
{"closureHash":"cd6b0d3f962c8cb40d405e92bb06bb8e9285b386200897f550d21036022262c1","declaration":"export const PAIRING_APPROVED_MESSAGE: \"✅ OpenClaw access approved. Send a message to start chatting.\";","entrypoint":"channel-plugin-common","exportName":"PAIRING_APPROVED_MESSAGE","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"const","recordType":"export"}
{"closureHash":"712435252d2fe5135542ca6b5a4375a6edea24e83829338011dc6ae7e9802fbb","declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"channel-plugin-common","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"closureHash":"4dd12b961fc300d388143ed5d8dc990e759c382b949c337c8f28ac83ca65aae7","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"channel-plugin-common","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"closureHash":"fb4fde629072c35c7afe2f3248520c284b439596eb2e25c136b6494b402cee1f","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-plugin-common","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"closureHash":"18fcab0d5899575a31205732d2be92597e533ad944c7fe11cac2af6fc718ea34","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"channel-plugin-common","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"closureHash":"b9c63a41b3da754e29aee2040c6b79300801cb59b95dcedf8032f404cd0c9a8d","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-plugin-common","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"closureHash":"3203c47bc265736977eb102837cf12d2fe8f8dc459389c21f319d9426d83dc8e","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"channel-plugin-common","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"channel-policy","importSpecifier":"openclaw/plugin-sdk/channel-policy","recordType":"module"}
{"closureHash":"017ab29d16d0f3d02d60f3513e65a373868d26496bc93d020d8fc8c17fd875f4","declaration":"export function buildAccountScopedDmSecurityPolicy(params: { cfg: OpenClawConfig; channelKey: string; accountId?: string | null; fallbackAccountId?: string | null; policy?: string | null; allowFrom?: Array<string | number> | null; defaultPolicy?: string; allowFromPathSuffix?: string; policyPathSuffix?: string; approveChannelId?: string; approveHint?: string; normalizeEntry?: (raw: string) => string; inheritSharedDefaultsFromDefaultAccount?: boolean; }): ChannelSecurityDmPolicy;","entrypoint":"channel-policy","exportName":"buildAccountScopedDmSecurityPolicy","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
@@ -1320,7 +1320,7 @@
{"closureHash":"02363b81b54c30225eb6e3f0519b41cbe7d3138a2f246f98a603edf39f25ed32","declaration":"export function createOpenGroupPolicyRestrictSendersWarningCollector<ResolvedAccount>(params: { resolveGroupPolicy: (account: ResolvedAccount) => GroupPolicy | null | undefined; defaultGroupPolicy?: GroupPolicy; } & Omit<Parameters<typeof collectOpenGroupPolicyRestrictSendersWarnings>[0], \"groupPolicy\">): (account: ResolvedAccount) => string[];","entrypoint":"channel-policy","exportName":"createOpenGroupPolicyRestrictSendersWarningCollector","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
{"closureHash":"cbfd724680731a8586992b442db7c33029ad6eff20785686d5b383223b553e4a","declaration":"export function createOpenProviderConfiguredRouteWarningCollector<ResolvedAccount>(params: { providerConfigPresent: (cfg: OpenClawConfig) => boolean; resolveGroupPolicy: (account: ResolvedAccount) => GroupPolicy | null | undefined; resolveRouteAllowlistConfigured: (account: ResolvedAccount) => boolean; configureRouteAllowlist: Parameters<typeof buildOpenGroupPolicyConfigureRouteAllowlistWarning>[0]; missingRouteAllowlist: Parameters<typeof buildOpenGroupPolicyWarning>[0]; }): AccountGroupPolicyWarningCollector<ResolvedAccount>;","entrypoint":"channel-policy","exportName":"createOpenProviderConfiguredRouteWarningCollector","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
{"closureHash":"92c797e68f69341c7b377821234cd9b27a8be1593249e956c4f1f1fe72bd65d7","declaration":"export function createOpenProviderGroupPolicyWarningCollector<Params extends { cfg: OpenClawConfig; }>(params: { providerConfigPresent: (cfg: OpenClawConfig) => boolean; resolveGroupPolicy: (params: Params) => GroupPolicy | null | undefined; collect: (params: Params & { groupPolicy: GroupPolicy; }) => string[]; }): ConfigGroupPolicyWarningCollector<Params>;","entrypoint":"channel-policy","exportName":"createOpenProviderGroupPolicyWarningCollector","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
{"closureHash":"30a586ad5e032fa84b001e73af62870c9a682e84c0616077a06e24fe9cc09b60","declaration":"export function createRestrictSendersChannelSecurity<ResolvedAccount extends { accountId?: string | null; }>(params: { channelKey: string; resolveDmPolicy: (account: ResolvedAccount) => string | null | undefined; resolveDmAllowFrom: (account: ResolvedAccount) => Array<string | number> | null | undefined; resolveGroupPolicy: (account: ResolvedAccount) => GroupPolicy | null | undefined; surface: string; openScope: string; groupPolicyPath: string; groupAllowFromPath: string; mentionGated?: boolean; providerConfigPresent?: (cfg: OpenClawConfig) => boolean; resolveFallbackAccountId?: (account: ResolvedAccount) => string | null | undefined; defaultDmPolicy?: string; allowFromPathSuffix?: string; policyPathSuffix?: string; approveChannelId?: string; approveHint?: string; normalizeDmEntry?: (raw: string) => string; inheritSharedDefaultsFromDefaultAccount?: boolean; }): ChannelSecurityAdapter<ResolvedAccount>;","entrypoint":"channel-policy","exportName":"createRestrictSendersChannelSecurity","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
{"closureHash":"3498d7988e1de695e02d420fb41202d80418f2758577289ff002332747eb4346","declaration":"export function createRestrictSendersChannelSecurity<ResolvedAccount extends { accountId?: string | null; }>(params: { channelKey: string; resolveDmPolicy: (account: ResolvedAccount) => string | null | undefined; resolveDmAllowFrom: (account: ResolvedAccount) => Array<string | number> | null | undefined; resolveGroupPolicy: (account: ResolvedAccount) => GroupPolicy | null | undefined; surface: string; openScope: string; groupPolicyPath: string; groupAllowFromPath: string; mentionGated?: boolean; providerConfigPresent?: (cfg: OpenClawConfig) => boolean; resolveFallbackAccountId?: (account: ResolvedAccount) => string | null | undefined; defaultDmPolicy?: string; allowFromPathSuffix?: string; policyPathSuffix?: string; approveChannelId?: string; approveHint?: string; normalizeDmEntry?: (raw: string) => string; inheritSharedDefaultsFromDefaultAccount?: boolean; dmRouting?: ChannelSecurityAdapter<ResolvedAccount>[\"dmRouting\"]; }): ChannelSecurityAdapter<ResolvedAccount>;","entrypoint":"channel-policy","exportName":"createRestrictSendersChannelSecurity","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
{"closureHash":"b6b34cd3844debbe7cda17ad7703e4fcffe4489789ae1763df8f8ab027150203","declaration":"export function evaluateGroupRouteAccessForPolicy(params: { groupPolicy: GroupPolicy; routeAllowlistConfigured: boolean; routeMatched: boolean; routeEnabled?: boolean; }): GroupRouteAccessDecision;","entrypoint":"channel-policy","exportName":"evaluateGroupRouteAccessForPolicy","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
{"closureHash":"182fa4fc45ddd20915ce722f255d301180b06a33d25aa2b4d771ced127558035","declaration":"export function evaluateSenderGroupAccessForPolicy(params: { groupPolicy: GroupPolicy; providerMissingFallbackApplied?: boolean; groupAllowFrom: string[]; senderId: string; isSenderAllowed: (senderId: string, allowFrom: string[]) => boolean; }): SenderGroupAccessDecision;","entrypoint":"channel-policy","exportName":"evaluateSenderGroupAccessForPolicy","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
{"closureHash":"cf41bc7efb2e5e5a031c236a14192bedba5a02d93aae3306ae5793d632d93692","declaration":"export function normalizeAllowFromList(list: Array<string | number> | undefined | null): string[];","entrypoint":"channel-policy","exportName":"normalizeAllowFromList","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
@@ -1887,12 +1887,12 @@
{"closureHash":"544219cddcce81cf5c8239f6ea9908fbeb809dba370b34e4928be95ee639057c","declaration":"export function channelTargetsSchema(options?: { description?: string; }): Type.TArray<Type.TString>;","entrypoint":"core","exportName":"channelTargetsSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"9fc7e45343d7bfbc6ed56d05c9f824e2f9cf6dafc3ca4b25437d1f65c2200727","declaration":"export function clearAccountEntryFields<TAccountEntry extends object>(params: { accounts?: Record<string, TAccountEntry>; accountId: string; fields: string[]; isValueSet?: (value: unknown) => boolean; markClearedOnFieldPresence?: boolean; }): { nextAccounts?: Record<string, TAccountEntry>; changed: boolean; cleared: boolean; };","entrypoint":"core","exportName":"clearAccountEntryFields","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"0438c0afd280cc2df90e7ffe221ce3133e6f742e9dc725ff34bbdeb90eeab2c8","declaration":"export function createActionGate<T extends Record<string, boolean | undefined>>(actions: T | undefined): ActionGate<T>;","entrypoint":"core","exportName":"createActionGate","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"7c5b67965c77dc8d16606890f53057c8835c3b502559d2b4c97bb73488f84617","declaration":"export function createChannelPluginBase<TResolvedAccount>(params: CreateChannelPluginBaseOptions<TResolvedAccount>): CreatedChannelPluginBase<TResolvedAccount>;","entrypoint":"core","exportName":"createChannelPluginBase","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"c26bfcd8451627b0eb75f7837e281b58dc127d19591d7c030691ca9bbe0edbf4","declaration":"export function createChatChannelPlugin<TResolvedAccount extends { accountId?: string | null; }, Probe = unknown, Audit = unknown>(params: { base: ChatChannelPluginBase<TResolvedAccount, Probe, Audit>; security?: ChannelSecurityAdapter<TResolvedAccount> | ChatChannelSecurityOptions<TResolvedAccount>; pairing?: ChannelPairingAdapter | ChatChannelPairingOptions; threading?: ChannelThreadingAdapter | ChatChannelThreadingOptions<TResolvedAccount>; outbound?: ChannelOutboundAdapter | ChatChannelAttachedOutboundOptions; }): ChannelPlugin<TResolvedAccount, Probe, Audit>;","entrypoint":"core","exportName":"createChatChannelPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"990d66feef26f2c87a46c85726a0b0eb3c39254e631cbcbb752ec0fe1d363fbf","declaration":"export function createChannelPluginBase<TResolvedAccount>(params: CreateChannelPluginBaseOptions<TResolvedAccount>): CreatedChannelPluginBase<TResolvedAccount>;","entrypoint":"core","exportName":"createChannelPluginBase","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"b8e27bea2add3eaafac7074cbd44fcf2acea30a1ac125c3551925e8cd0b3378d","declaration":"export function createChatChannelPlugin<TResolvedAccount extends { accountId?: string | null; }, Probe = unknown, Audit = unknown>(params: { base: ChatChannelPluginBase<TResolvedAccount, Probe, Audit>; security?: ChannelSecurityAdapter<TResolvedAccount> | ChatChannelSecurityOptions<TResolvedAccount>; pairing?: ChannelPairingAdapter | ChatChannelPairingOptions; threading?: ChannelThreadingAdapter | ChatChannelThreadingOptions<TResolvedAccount>; outbound?: ChannelOutboundAdapter | ChatChannelAttachedOutboundOptions; }): ChannelPlugin<TResolvedAccount, Probe, Audit>;","entrypoint":"core","exportName":"createChatChannelPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"785b0f750c5bd20f9f3ca081886a5af79ee0e4d2c38f78f769bf994b234f5076","declaration":"export function createDedupeCache(options: DedupeCacheOptions): DedupeCache;","entrypoint":"core","exportName":"createDedupeCache","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"e2df8d235401aebf58eb71652fbeaedb42ca00aaa5042a76909ff2c48ba6fd54","declaration":"export function createSubsystemLogger(subsystem: string): SubsystemLogger;","entrypoint":"core","exportName":"createSubsystemLogger","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"c4b7032c03cf9c056cfab60aeddd037258981854bd1081a4b88ccfed0306317a","declaration":"export function defineChannelPluginEntry<TPlugin>({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin>;","entrypoint":"core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"0e3a6175467adf8ff674c52bb0ae1af57d2e52f33448416e5d11b4eca1685baf","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"core","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"9eec5be09e3eabc56729d2dcf61798420c8b5bd13d732790ab88e951c37156e4","declaration":"export function defineChannelPluginEntry<TPlugin>({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin>;","entrypoint":"core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"a4f0792ef70bd2b09bf37e9c37943284c8f93b82bd3864cf6f3739033c2878a6","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"core","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"0e0a9f6b22c433bdb1165e7707b1f9a1ddac1a544a8add00b503048cf157921f","declaration":"export function defineSetupPluginEntry<TPlugin>(plugin: TPlugin): { plugin: TPlugin; };","entrypoint":"core","exportName":"defineSetupPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"3c5ce0c3733cbb038aeb914af1df5d701f362f0521921b8abd0c9214db9cc4b8","declaration":"export function delegateCompactionToRuntime(params: Parameters<ContextEngine[\"compact\"]>[0]): Promise<CompactResult>;","entrypoint":"core","exportName":"delegateCompactionToRuntime","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"2c282e0e308f9442bca7cdeb8e89a097531b1d54a692c9d86e5f39a8db1c2537","declaration":"export function deleteAccountFromConfigSection(params: { cfg: OpenClawConfig; sectionKey: string; accountId: string; clearBaseFields?: string[]; }): OpenClawConfig;","entrypoint":"core","exportName":"deleteAccountFromConfigSection","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
@@ -1939,7 +1939,7 @@
{"closureHash":"2e6ce1f4c1692270a00dc0cf08e2752a26739c3143f8091cb270063c6034605d","declaration":"export function tryReadSecretFileSync(filePath: string | undefined, label: string, options: CredentialFileReadOptions): string | undefined;\nexport function tryReadSecretFileSync(filePath: string | undefined, label: string, options?: FsSafeSecretFileReadOptions): string | undefined;\nexport function tryReadSecretFileSync(filePath: string, label: string, options: FsSafeSecretFileReadOptions | undefined, diagnostic: { configPath: string; }): ConfiguredCredentialResult<string>;\nexport function tryReadSecretFileSync(filePath: string | undefined, label: string, options: FsSafeSecretFileReadOptions | undefined, diagnostic: { configPath: string; }): CredentialResult<string>;","entrypoint":"core","exportName":"tryReadSecretFileSync","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"b40933a11984425d14a7a479bda0d2cd14cbfa9371164774f39bebbf12861df7","declaration":"export const DEFAULT_ACCOUNT_ID: \"default\";","entrypoint":"core","exportName":"DEFAULT_ACCOUNT_ID","importSpecifier":"openclaw/plugin-sdk/core","kind":"const","recordType":"export"}
{"closureHash":null,"declaration":"export const DEFAULT_SECRET_FILE_MAX_BYTES: number;","entrypoint":"core","exportName":"DEFAULT_SECRET_FILE_MAX_BYTES","importSpecifier":"openclaw/plugin-sdk/core","kind":"const","recordType":"export"}
{"closureHash":"e75e94d131237b4b73c507cad9f2a0940716404531516861497e92ba8d06fb87","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"core","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"71e57b87ff6cba595cc4513f2fd68742eb69a234d17e328c6cc6761eec04385e","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"core","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"d2ff4de9ee3fd111c2cc64a3ee7e557d9f161af1b6b437ee7886bcb16e426317","declaration":"export type AgentPromptGuidance = AgentPromptGuidance;","entrypoint":"core","exportName":"AgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"2841127a90e04467adfea8126cbf03655f44ddb089ad9e0d48833c2beea39cbd","declaration":"export type AgentPromptGuidanceEntry = AgentPromptGuidanceEntry;","entrypoint":"core","exportName":"AgentPromptGuidanceEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"aa0412acefe62caff12e5271ead0545504874e824380dc21cfc0566388a05f33","declaration":"export type AgentPromptSurfaceKind = \"openclaw_main\" | \"pi_main\" | \"codex_app_server\" | \"cli_backend\" | \"acp_backend\" | \"subagent\";","entrypoint":"core","exportName":"AgentPromptSurfaceKind","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
@@ -1957,7 +1957,7 @@
{"closureHash":"ec916ca974bd0242329b6532fb8467a63d038f1182ae9b2af3aa3b979b5fa589","declaration":"export type ChannelOutboundAdapter = ChannelOutboundAdapter;","entrypoint":"core","exportName":"ChannelOutboundAdapter","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"7b39a17fc562efc5af466006bcdedc6182567effce66c775b565317fb59b0295","declaration":"export type ChannelOutboundSessionRoute = ChannelOutboundSessionRoute;","entrypoint":"core","exportName":"ChannelOutboundSessionRoute","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"8126b651a679d5435eaa5d346916792c3600e5f0f75d8492b077dd361854f7dd","declaration":"export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; currentSessionKey?: string; resolvedTarget?: { to: string; kind: ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};","entrypoint":"core","exportName":"ChannelOutboundSessionRouteParams","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"4dd12b961fc300d388143ed5d8dc990e759c382b949c337c8f28ac83ca65aae7","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"core","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"18fcab0d5899575a31205732d2be92597e533ad944c7fe11cac2af6fc718ea34","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"core","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"c7f4189c00fda265d2124e4603f9a2936229c7bf5dcc246e5d6f831179d18182","declaration":"export type ChannelSetupInput = ChannelSetupInput;","entrypoint":"core","exportName":"ChannelSetupInput","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"5fd0fa51b352b25b111be12e2fbc79648bb5e9cf5f55cbe7131c8c60e54787b2","declaration":"export type ChatType = ChatType;","entrypoint":"core","exportName":"ChatType","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"e4880dcde69275f17e135c15682e5195e4817e0b0ed06763703145086fc2e721","declaration":"export type ContextEngineSessionTarget = ContextEngineSessionTarget;","entrypoint":"core","exportName":"ContextEngineSessionTarget","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
@@ -1971,10 +1971,10 @@
{"closureHash":"54ea426dde51859b572b4c1079d2b70b412096f73da2b8c265f2749d9f01cbb5","declaration":"export type NormalizedLocation = NormalizedLocation;","entrypoint":"core","exportName":"NormalizedLocation","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"core","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"5189698d102b8b064eefe1442b008312973c3994fd6b203d2205725d7ee9d118","declaration":"export type OpenClawPluginActiveModelContext = OpenClawPluginActiveModelContext;","entrypoint":"core","exportName":"OpenClawPluginActiveModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"fb4fde629072c35c7afe2f3248520c284b439596eb2e25c136b6494b402cee1f","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"b9c63a41b3da754e29aee2040c6b79300801cb59b95dcedf8032f404cd0c9a8d","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"69fefc8092c1cea366c48505c8423ff0f8f995caef3d259d177346b1687541aa","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"core","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"core","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"c8efb9154eafc9061e7b6bf41fd001a4c2b38e0645d6382ad9e493d3f12a3664","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"2614b3215fe42678ee92b6d077aaf2ddea54294b486b5bc3dbffde10cff679ac","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"a7ed83f0924f818b23cecb5a1f3591ff28b9499ccac9667a2b8505c2bc608ea9","declaration":"export type OpenClawPluginGatewayEventScope = OpenClawPluginGatewayEventScope;","entrypoint":"core","exportName":"OpenClawPluginGatewayEventScope","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"f81f224d9b837e6353b7a546c5a76b124bcf568fd1f1fd0c6881fda30c53120a","declaration":"export type OpenClawPluginGatewayEvents = OpenClawPluginGatewayEvents;","entrypoint":"core","exportName":"OpenClawPluginGatewayEvents","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"ddc2738dd0ece94ddde9a7c655f92c15ec6416645ecf932d4aa404c7b7761159","declaration":"export type OpenClawPluginService = OpenClawPluginService;","entrypoint":"core","exportName":"OpenClawPluginService","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
@@ -2195,13 +2195,13 @@
{"closureHash":"4d4a0ece3ccb6d5020047cb2478574e012716748c8849e78b740dfd3bdc588f4","declaration":"export function unbindThreadBindingsBySessionKey(params: { targetSessionKey: string; accountId?: string; targetKind?: ThreadBindingTargetKind; reason?: string; sendFarewell?: boolean; farewellText?: string; }): ThreadBindingRecord[];","entrypoint":"discord","exportName":"unbindThreadBindingsBySessionKey","importSpecifier":"openclaw/plugin-sdk/discord","kind":"function","recordType":"export"}
{"closureHash":"b40933a11984425d14a7a479bda0d2cd14cbfa9371164774f39bebbf12861df7","declaration":"export const DEFAULT_ACCOUNT_ID: \"default\";","entrypoint":"discord","exportName":"DEFAULT_ACCOUNT_ID","importSpecifier":"openclaw/plugin-sdk/discord","kind":"const","recordType":"export"}
{"closureHash":"cd6b0d3f962c8cb40d405e92bb06bb8e9285b386200897f550d21036022262c1","declaration":"export const PAIRING_APPROVED_MESSAGE: \"✅ OpenClaw access approved. Send a message to start chatting.\";","entrypoint":"discord","exportName":"PAIRING_APPROVED_MESSAGE","importSpecifier":"openclaw/plugin-sdk/discord","kind":"const","recordType":"export"}
{"closureHash":"1c7d6b7fb8094571ea44338cc968e915c65ed09ac437780f9fd16c59d731f438","declaration":"export const buildDiscordComponentMessage: BuildDiscordComponentMessage;","entrypoint":"discord","exportName":"buildDiscordComponentMessage","importSpecifier":"openclaw/plugin-sdk/discord","kind":"const","recordType":"export"}
{"closureHash":"83e88b20d1d794e442f7a4c245b9d557b3f95276fad4a0758466c60c9f12997c","declaration":"export const buildDiscordComponentMessage: BuildDiscordComponentMessage;","entrypoint":"discord","exportName":"buildDiscordComponentMessage","importSpecifier":"openclaw/plugin-sdk/discord","kind":"const","recordType":"export"}
{"closureHash":"7ca7125928ab0b6f04d47bfba94b9a50e3dfcc56717a413d24e4794ef91a091e","declaration":"export const discordOnboardingAdapter: {};","entrypoint":"discord","exportName":"discordOnboardingAdapter","importSpecifier":"openclaw/plugin-sdk/discord","kind":"const","recordType":"export"}
{"closureHash":"d619ec239abd45d5be76c3c58acc82f7a25f8f66352d2afc6453e13c4c7a82e7","declaration":"export const editDiscordComponentMessage: EditDiscordComponentMessage;","entrypoint":"discord","exportName":"editDiscordComponentMessage","importSpecifier":"openclaw/plugin-sdk/discord","kind":"const","recordType":"export"}
{"closureHash":"d619ec239abd45d5be76c3c58acc82f7a25f8f66352d2afc6453e13c4c7a82e7","declaration":"export const registerBuiltDiscordComponentMessage: RegisterBuiltDiscordComponentMessage;","entrypoint":"discord","exportName":"registerBuiltDiscordComponentMessage","importSpecifier":"openclaw/plugin-sdk/discord","kind":"const","recordType":"export"}
{"closureHash":"75b9b07bac5eabd3e05c7d3e33b28c53db35410e6ba9b2f8bb5406a3849e2c11","declaration":"export type ChannelMessageActionAdapter = ChannelMessageActionAdapter;","entrypoint":"discord","exportName":"ChannelMessageActionAdapter","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"0a4bc843eaab5feec0a0085b0bc501a0e0b3f4b87b0e05b40c5ea1ce874fad02","declaration":"export type ChannelMessageActionName = \"search\" | \"broadcast\" | \"read\" | \"edit\" | \"delete\" | \"timeout\" | \"send\" | \"poll\" | \"poll-vote\" | \"react\" | \"reactions\" | \"unsend\" | \"reply\" | \"sendWithEffect\" | \"renameGroup\" | \"setGroupIcon\" | \"addParticipant\" | \"removeParticipant\" | \"leaveGroup\" | \"sendAttachment\" | \"pin\" | \"unpin\" | \"list-pins\" | \"permissions\" | \"thread-create\" | \"thread-list\" | \"thread-reply\" | \"sticker\" | \"sticker-search\" | \"member-info\" | \"role-info\" | \"emoji-list\" | \"emoji-upload\" | \"sticker-upload\" | \"role-add\" | \"role-remove\" | \"channel-info\" | \"channel-list\" | \"channel-create\" | \"channel-edit\" | \"channel-delete\" | \"channel-move\" | \"category-create\" | \"category-edit\" | \"category-delete\" | \"topic-create\" | \"topic-edit\" | \"voice-status\" | \"event-list\" | \"event-create\" | \"kick\" | \"ban\" | \"set-profile\" | \"set-presence\" | \"download-file\" | \"upload-file\";","entrypoint":"discord","exportName":"ChannelMessageActionName","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"4dd12b961fc300d388143ed5d8dc990e759c382b949c337c8f28ac83ca65aae7","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"discord","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"18fcab0d5899575a31205732d2be92597e533ad944c7fe11cac2af6fc718ea34","declaration":"export type ChannelPlugin<ResolvedAccount = any, Probe = unknown, Audit = unknown> = ChannelPlugin<ResolvedAccount, Probe, Audit>;","entrypoint":"discord","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"68c829c145de778dc26f5f89ba81aa0087171cf6b8f2bb79530247c14af4ba0e","declaration":"export type DiscordAccountConfig = { accounts?: Record<string, DiscordAccountConfig>; defaultAccount?: string;} & Omit<CommonChannelMessagingConfig<string[], string, string, DiscordChannelStreamingConfig>, \"groupAllowFrom\"> & ChannelBotInteractionConfig & { reactionNotifications?: undefined; reactionLevel?: undefined; ackReaction?: string | undefined;} & Record<never, never> & { commands?: ProviderCommandsConfig; token?: SecretInput; applicationId?: string; activities?: { clientSecret?: string; applicationId?: string; }; proxy?: string; mentionAliases?: DiscordMentionAliasesConfig; suppressEmbeds?: boolean; maxLinesPerMessage?: number; actions?: DiscordActionConfig; thread?: DiscordThreadConfig; dm?: DiscordDmConfig; guilds?: Record<string, DiscordGuildEntry>; execApprovals?: DiscordExecApprovalConfig; agentComponents?: DiscordAgentComponentsConfig; slashCommand?: DiscordSlashCommandConfig; threadBindings?: DiscordThreadBindingsConfig; subagentProgress?: boolean; intents?: DiscordIntentsConfig; voice?: DiscordVoiceConfig; pluralkit?: DiscordPluralKitConfig; ackReactionScope?: \"group-mentions\" | \"group-all\" | \"direct\" | \"all\" | \"off\" | \"none\"; activity?: string; status?: \"online\" | \"dnd\" | \"idle\" | \"invisible\"; autoPresence?: DiscordAutoPresenceConfig; activityType?: 0 | 1 | 2 | 3 | 4 | 5; activityUrl?: string; inboundWorker?: { runTimeoutMs?: number; };};","entrypoint":"discord","exportName":"DiscordAccountConfig","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"ae9fb82eaf8d09709d4f8c26f7419827741faa40a3fae83864863cdae7e86250","declaration":"export type DiscordComponentBuildResult = DiscordComponentBuildResult;","entrypoint":"discord","exportName":"DiscordComponentBuildResult","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"5c5d9351a7f45d03bd5b0f2b116db5484bc5073b02f717b353420369a8f48556","declaration":"export type DiscordComponentMessageSpec = DiscordComponentMessageSpec;","entrypoint":"discord","exportName":"DiscordComponentMessageSpec","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
@@ -2209,7 +2209,7 @@
{"closureHash":"0db968dad99d84ecef5202167daadd092e3b4f456270283d3fd61585ac2bbd5a","declaration":"export type DiscordComponentSendResult = DiscordComponentSendResult;","entrypoint":"discord","exportName":"DiscordComponentSendResult","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"084b46d7dd510eb182a4705559251e824220b57dbfa6dc54392507b72ba1815e","declaration":"export type DiscordOutboundTargetResolution = DiscordOutboundTargetResolution;","entrypoint":"discord","exportName":"DiscordOutboundTargetResolution","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"discord","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"fb4fde629072c35c7afe2f3248520c284b439596eb2e25c136b6494b402cee1f","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"discord","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"b9c63a41b3da754e29aee2040c6b79300801cb59b95dcedf8032f404cd0c9a8d","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"discord","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"3203c47bc265736977eb102837cf12d2fe8f8dc459389c21f319d9426d83dc8e","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"discord","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"6b9967e919c1cd420c8356b4f9d40dbc81932b4b15a733eecdcfb2ad84f8e5d8","declaration":"export type ResolvedDiscordAccount = ResolvedDiscordAccount;","entrypoint":"discord","exportName":"ResolvedDiscordAccount","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"6bed5ca896b7034117e4757e2c6b4111dd5293dbad9416e3828dd6afa4e858ce","declaration":"export type ThreadBindingRecord = ThreadBindingRecord;","entrypoint":"discord","exportName":"ThreadBindingRecord","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
@@ -2354,7 +2354,7 @@
{"closureHash":"98e0cc16352b7dfcceb4957f8cd2acfe3c2b3acb223c42a5cfb885e088fcb04c","declaration":"export function resolveInboundReplyDispatchCounts(result: ChannelTurnDispatchResultLike): Record<ReplyDispatchKind, number>;","entrypoint":"inbound-reply-dispatch","exportName":"resolveInboundReplyDispatchCounts","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"}
{"closureHash":"9d503d05e408ddd1a1c373e3c4485b1f9acff4c240fdc241840a2cfa8b55c3a7","declaration":"export function runChannelInboundEvent<TRaw, TDispatchResult = DispatchFromConfigResult>(params: RunChannelTurnParams<TRaw, TDispatchResult, ChannelProviderOwnedMessageSendingDeliveryAdapter>): Promise<ChannelTurnResult<TDispatchResult>>;\nexport function runChannelInboundEvent<TRaw, TDispatchResult = DispatchFromConfigResult>(params: ChannelInboundEventRunnerParams<TRaw, TDispatchResult>): Promise<ChannelTurnResult<TDispatchResult>>;","entrypoint":"inbound-reply-dispatch","exportName":"runChannelInboundEvent","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"}
{"closureHash":"2c68496a174872b31aaf1ac8fad2789deb79d490c5ffbcb157325f1c95d1b51f","declaration":"export function runPreparedInboundReply<TDispatchResult>(params: PreparedChannelTurn<TDispatchResult>): Promise<ChannelTurnResult<TDispatchResult>>;","entrypoint":"inbound-reply-dispatch","exportName":"runPreparedInboundReply","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"}
{"closureHash":"f5d6c974980d1792af370a89adca4417174efdc8bf3b70e140fdfe21d1692cca","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"inbound-reply-dispatch","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"const","recordType":"export"}
{"closureHash":"16254799487aa48361f99ab341adad98738406e4af686ef50487780450c230fe","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"inbound-reply-dispatch","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"const","recordType":"export"}
{"closureHash":"278dc8a410230012ddbc3552ec621a224e6f7c5dd4cd3904c943ac98dd4259e4","declaration":"export type AssembledInboundReply = AssembledChannelTurn;","entrypoint":"inbound-reply-dispatch","exportName":"AssembledInboundReply","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"}
{"closureHash":"3de0d6d1bb8f9a83bd1c6e57aa8618e3fea71054236cd530c555e348bd0b7702","declaration":"export type ChannelBotLoopProtectionFacts = ChannelBotLoopProtectionFacts;","entrypoint":"inbound-reply-dispatch","exportName":"ChannelBotLoopProtectionFacts","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"}
{"closureHash":"f0da845bbdf49b30f6718a4b7ff012a0536deb98f65418583555dc90825797ca","declaration":"export type ChannelInboundDroppedHistoryOptions = ChannelTurnDroppedHistoryOptions;","entrypoint":"inbound-reply-dispatch","exportName":"ChannelInboundDroppedHistoryOptions","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"}
@@ -3189,19 +3189,19 @@
{"closureHash":"50394942e0a454c742e80a4f3c8739c80258b387ade498eb5aed66df887108be","declaration":"export function callMeetingBrowserProxyOnNode(params: { runtime: PluginRuntime; adapter: NodeAdapter; nodeId: string; } & MeetingBrowserRequestParams): Promise<unknown>;","entrypoint":"meeting-runtime","exportName":"callMeetingBrowserProxyOnNode","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"c5fcd1d157edcb4773235adfaf8051e3ec7ca428cb7916b6d55f2511affab56c","declaration":"export function convertMeetingBridgeAudioForStt(audio: Buffer, audioFormat: MeetingRealtimeAudioFormat): Buffer;","entrypoint":"meeting-runtime","exportName":"convertMeetingBridgeAudioForStt","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"aa9063c27c5ff714d3653571c4a2a71e9d2eea5609b161f03e4738e15411358b","declaration":"export function convertMeetingTtsAudioForBridge(audio: Buffer, sampleRate: number, audioFormat: MeetingRealtimeAudioFormat, outputFormat?: string, platformName?: string): Buffer;","entrypoint":"meeting-runtime","exportName":"convertMeetingTtsAudioForBridge","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"c8f1a9163a69ca61d4f88f8129e5f23719f921e5245e060c7a6c77bfaae8c34a","declaration":"export function createLocalMeetingRealtimeAudioTransport(params: { inputCommand: string[]; outputCommand: string[]; bargeInInputCommand?: string[]; bargeInRmsThreshold: number; bargeInPeakThreshold: number; bargeInCooldownMs: number; logger: RuntimeLogger; logScope: string; audioFormat?: MeetingRealtimeAudioFormat; spawn?: MeetingRealtimeAudioSpawn; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createLocalMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"cc82f299f781157a633a599387ba8190b4f9163b031ea44cb27df50b0aeed48f","declaration":"export function createLocalMeetingRealtimeAudioTransport(params: { inputCommand: string[]; outputCommand: string[]; bargeInInputCommand?: string[]; bargeInRmsThreshold: number; bargeInPeakThreshold: number; bargeInCooldownMs: number; logger: RuntimeLogger; logScope: string; audioFormat?: MeetingRealtimeAudioFormat; spawn?: MeetingRealtimeAudioSpawn; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createLocalMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"9cb63eefd2e5a70aea960bf17fcf570ef02a2d7b5afd5ad9451802964c653fcf","declaration":"export function createMeetingBrowserNodeCaller(params: { runtime: PluginRuntime; adapter: NodeAdapter; nodeId: string; }): MeetingBrowserRequestCaller;","entrypoint":"meeting-runtime","exportName":"createMeetingBrowserNodeCaller","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"f244ca8c47f556c9f388953cf9a7581c7d4d413af93e0dfa1462779e6a687a7c","declaration":"export function createMeetingBrowserNodeInvokePolicy(options: MeetingBrowserNodePolicyOptions): OpenClawPluginNodeInvokePolicy;","entrypoint":"meeting-runtime","exportName":"createMeetingBrowserNodeInvokePolicy","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"1aa4e3ff39a2cbe162421c62b1fa4a362973381d4d9ff15c671249b1ebd566bc","declaration":"export function createMeetingNodeHost(options: MeetingNodeHostOptions): { handleCommand(paramsJSON?: string | null): Promise<string>; };","entrypoint":"meeting-runtime","exportName":"createMeetingNodeHost","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"2493d5d6a3b2128c167ae4c42129ff96b2dddaac7c12c87fc442ff304b01ca3a","declaration":"export function createMeetingRealtimeEngineBindings(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { agentId?: string; toolPolicy: RealtimeVoiceAgentConsultToolPolicy; }; }; fullConfig: OpenClawConfig; runtime: PluginRuntime; logger: RuntimeLogger; }): { platform: MeetingRuntimePlatform; consultAgent: (consult: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (call: MeetingRealtimeToolCallParams) => Promise<void>; };","entrypoint":"meeting-runtime","exportName":"createMeetingRealtimeEngineBindings","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"6030bd4718a6362627f0388a624505ad6680512881e27c42a7792ec0d52f9d58","declaration":"export function createMeetingRealtimeEngineBindings(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { agentId?: string; toolPolicy: RealtimeVoiceAgentConsultToolPolicy; }; }; fullConfig: OpenClawConfig; runtime: PluginRuntime; logger: RuntimeLogger; }): { platform: MeetingRuntimePlatform; consultAgent: (consult: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (call: MeetingRealtimeToolCallParams) => Promise<void>; };","entrypoint":"meeting-runtime","exportName":"createMeetingRealtimeEngineBindings","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"9124db05923060c467edb149bd8abdc8be1d00d00f867cf84600972923a58489","declaration":"export function createMeetingSession<TTransport extends string, TMode extends string, TToolPolicy extends string>(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { provider?: string; voiceProvider?: string; transcriptionProvider?: string; model?: string; toolPolicy: TToolPolicy; }; }; resolved: MeetingResolvedJoin<TTransport, TMode>; createdAt: string; }): MeetingSessionRecord<TTransport, TMode, { enabled: boolean; strategy: string; provider: string | undefined; model: string | undefined; transcriptionProvider: string | undefined; toolPolicy: TToolPolicy; }>;","entrypoint":"meeting-runtime","exportName":"createMeetingSession","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"fb276e07e395ab19177b3d7967fd0a8fcda79130883f15092a4a306b826481b9","declaration":"export function createMeetingSetupStatus(checks: MeetingSetupCheck[]): MeetingSetupStatus;","entrypoint":"meeting-runtime","exportName":"createMeetingSetupStatus","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"93c4bb70429a2739151e6f900e67bed81f3cd8f597811220e790341edb0d6008","declaration":"export function createMeetingVoiceCallGateway(params: { config: MeetingVoiceCallConfig; runtime: PluginRuntime; surface: MeetingVoiceCallSurface; connectClient: (params: { config: MeetingVoiceCallConfig; surface: MeetingVoiceCallSurface; }) => Promise<MeetingVoiceCallGatewayClient>; }): MeetingVoiceCallGateway;","entrypoint":"meeting-runtime","exportName":"createMeetingVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"cdf4e39ad1cf11a2826425997ccaea4ffedb057b543b355c375885891476bf23","declaration":"export function createNodeMeetingRealtimeAudioTransport(params: { runtime: PluginRuntime; nodeId: string; bridgeId: string; logger: RuntimeLogger; commandName: string; logScope: string; logPrefix: string; audioFormat?: MeetingRealtimeAudioFormat; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createNodeMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"e1c082dd9e7ecc190f8cbd1e9706e37a805d64a55ee7256f84f5d39dc2edaaf4","declaration":"export function createNodeMeetingRealtimeAudioTransport(params: { runtime: PluginRuntime; nodeId: string; bridgeId: string; logger: RuntimeLogger; commandName: string; logScope: string; logPrefix: string; audioFormat?: MeetingRealtimeAudioFormat; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createNodeMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"c0987b15a391a92d53d3e4e12b61eb122f9547fcf4f45478cdd3c5a8973a3e52","declaration":"export function endMeetingVoiceCallGatewayCall(params: { gateway: MeetingVoiceCallGateway; callId: string; }): Promise<void>;","entrypoint":"meeting-runtime","exportName":"endMeetingVoiceCallGatewayCall","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"b3ebc10fe7ab372e1317eaa8f78621cf277bba1e33fda57acf2254f6759d1e9d","declaration":"export function getMeetingVoiceCallGatewayCall(params: { gateway: MeetingVoiceCallGateway; callId: string; }): Promise<MeetingVoiceCallStatusResult>;","entrypoint":"meeting-runtime","exportName":"getMeetingVoiceCallGatewayCall","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"aac088df8e80d9ce89c45feccdb04ace3ae4417b3fcdd0f058410ddf25c96b46","declaration":"export function isMeetingVoiceCallMissingError(error: unknown): boolean;","entrypoint":"meeting-runtime","exportName":"isMeetingVoiceCallMissingError","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"337f14177df4f0a622be4d97495e99706782e43917ff560c5fbb439263f89457","declaration":"export function joinMeetingViaVoiceCallGateway(params: { config: MeetingVoiceCallConfig; gateway: MeetingVoiceCallGateway; surface: MeetingVoiceCallSurface; dialInNumber: string; dtmfSequence?: string; logger?: RuntimeLogger; message?: string; requesterSessionKey?: string; agentId?: string; sessionKey?: string; }): Promise<MeetingVoiceCallJoinResult>;","entrypoint":"meeting-runtime","exportName":"joinMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"59bf540846422a2078a247b42ea08bba1bf81b46b732a19180790f2a73568f11","declaration":"export function joinMeetingViaVoiceCallGateway(params: { config: MeetingVoiceCallConfig; gateway: MeetingVoiceCallGateway; surface: MeetingVoiceCallSurface; dialInNumber: string; dtmfSequence?: string; logger?: RuntimeLogger; message?: string; requesterSessionKey?: string; agentId?: string; sessionKey?: string; }): Promise<MeetingVoiceCallJoinResult>;","entrypoint":"meeting-runtime","exportName":"joinMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"bac9621cd025754fbcd4c21409b06eb0503405db81f35cac993aaf0b881ab3e1","declaration":"export function leaveMeetingWithBrowser<Session, Mode extends string, Health extends MeetingBrowserHealth, Transcript extends MeetingTranscriptSnapshot>(params: { adapter: BrowserAdapter<Session, Mode, Health, Transcript>; callBrowser: MeetingBrowserRequestCaller; launch: boolean; meetingSessionId?: string; meetingUrl: string; tab: MeetingBrowserTab; timeoutMs: number; }): Promise<{ left: boolean; note: string; }>;","entrypoint":"meeting-runtime","exportName":"leaveMeetingWithBrowser","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"c7b1aeac134b2070d053adf33026d876998b852ccd65cd2c9667119b1a1abee2","declaration":"export function openMeetingWithBrowser<Session extends MeetingBrowserJoinSession<Mode>, Mode extends string, Health extends MeetingBrowserHealth & { browserTitle?: string; browserUrl?: string; notes?: string[]; }, Transcript extends MeetingTranscriptSnapshot>(params: { adapter: BrowserAdapter<Session, Mode, Health, Transcript>; callBrowser: MeetingBrowserRequestCaller; config: MeetingBrowserControllerConfig; session: Session; }): Promise<{ launched: boolean; browser?: Health; tab?: MeetingBrowserTab; }>;","entrypoint":"meeting-runtime","exportName":"openMeetingWithBrowser","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"34858979bd248799c2215d9c7bdd5d4a6b27660c9173bfca2e50dd4373ac27db","declaration":"export function readMeetingBrowserTab(result: unknown): MeetingBrowserCandidateTab | undefined;","entrypoint":"meeting-runtime","exportName":"readMeetingBrowserTab","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
@@ -3212,8 +3212,8 @@
{"closureHash":"56874c5b2ced5af647b1dff296c931f0d8b85b1318e98c741aa88b58a9c5c606","declaration":"export function resolveMeetingBrowserNodeInfo(params: { runtime: PluginRuntime; adapter: NodeAdapter; requestedNode?: string; }): Promise<MeetingBrowserNodeInfo>;","entrypoint":"meeting-runtime","exportName":"resolveMeetingBrowserNodeInfo","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"f21196c9ea8ab90248ffdcdef3e942f1247ee2b9064ddb9757fffe352362c779","declaration":"export function resolveMeetingRealtimeAudioFormat(audioFormat: MeetingRealtimeAudioFormat): RealtimeVoiceAudioFormat;","entrypoint":"meeting-runtime","exportName":"resolveMeetingRealtimeAudioFormat","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"521dc5c262524a709cdd27cdc88e95004073da8223537bcbc73d5d423172dc2b","declaration":"export function speakMeetingViaVoiceCallGateway(params: { gateway: MeetingVoiceCallGateway; callId: string; message: string; }): Promise<void>;","entrypoint":"meeting-runtime","exportName":"speakMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"318770156465bcaef766d607ed73d3d3ceea9a3d148c80980bed8da4d33ae94e","declaration":"export function startMeetingAgentRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeTranscriptionProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; }): Promise<MeetingRealtimeAudioEngineHandle>;","entrypoint":"meeting-runtime","exportName":"startMeetingAgentRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"90ca9e0ecea498d28aad6e0d5b1a098779002ff2229035ad43e7c6eae9411f23","declaration":"export function startMeetingRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; talkSessionId?: string; talkContext?: { nodeId: string; bridgeId: string; }; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeVoiceProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (params: MeetingRealtimeToolCallParams) => Promise<void>; }): Promise<MeetingRealtimeAudioEngineHandle>;","entrypoint":"meeting-runtime","exportName":"startMeetingRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"3130ab53a021c7e3f2970bf24e318a1f06ca09ea91d3c9bd51581bf39481d229","declaration":"export function startMeetingAgentRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeTranscriptionProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; }): Promise<MeetingRealtimeAudioEngineHandle>;","entrypoint":"meeting-runtime","exportName":"startMeetingAgentRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"b943ecbbcebec424120f28f33fb2f8b382d2ae91adad8fac853496bd2eed1984","declaration":"export function startMeetingRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; talkSessionId?: string; talkContext?: { nodeId: string; bridgeId: string; }; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeVoiceProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (params: MeetingRealtimeToolCallParams) => Promise<void>; }): Promise<MeetingRealtimeAudioEngineHandle>;","entrypoint":"meeting-runtime","exportName":"startMeetingRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"663b9c77231b21af697efd5042e22d1c33e9ee972adeb312ad86d81a2b2e36f7","declaration":"export type MeetingAgentConsultParams = MeetingAgentConsultParams;","entrypoint":"meeting-runtime","exportName":"MeetingAgentConsultParams","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"adf0745c611bf737fc28978d766fc2a25b7104e71b6b2fed4e9b95e519c7b115","declaration":"export type MeetingBrowserCandidateTab = MeetingBrowserCandidateTab;","entrypoint":"meeting-runtime","exportName":"MeetingBrowserCandidateTab","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"59b1526172b7491b85f14f13c1ee26d8d6726f33093770748580c767b1689a17","declaration":"export type MeetingBrowserControllerConfig = MeetingBrowserControllerConfig;","entrypoint":"meeting-runtime","exportName":"MeetingBrowserControllerConfig","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
@@ -3245,7 +3245,7 @@
{"closureHash":"8244b408803f57cf2004157e96f2ce11bb036cdf864123b15ba2fac7f03b5d43","declaration":"export type MeetingSessionRuntimeHandles<THealth extends MeetingBrowserHealth> = MeetingSessionRuntimeHandles<THealth>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeHandles","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"aa8054fc2c442891197e89bdad61e79999ea15d813c4b127fb6150607b9e67e7","declaration":"export type MeetingSessionRuntimeJoinContext<TSession extends MeetingSessionRecord<TTransport, TMode>, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth, TTab extends MeetingBrowserTab> = MeetingSessionRuntimeJoinContext<TSession, TTransport, TMode, THealth, TTab>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeJoinContext","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"325241724edd38da439c5df03d225e2a7cb8e56d817e98ed7c37850656d3744b","declaration":"export type MeetingSessionRuntimeMessages<TSpeechBlockedReason extends string> = MeetingSessionRuntimeMessages<TSpeechBlockedReason>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeMessages","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"bc3ec8d61eeca24b6d2d5d56b91479aed7c4e8bf0b7e86945a1eedc562a9e42e","declaration":"export type MeetingSessionRuntimeOptions<TSession extends MeetingSessionRecord<TTransport, TMode>, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth<TManualReason, TSpeechBlockedReason>, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> = MeetingSessionRuntimeOptions<TSession, TRequest, TTransport, TMode, THealth, TTab, TManualReason, TSpeechBlockedReason>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeOptions","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"8345dc18050019a013d34a7653ed0d12e6178bcc18dfdb52f85a05a46bbd4e22","declaration":"export type MeetingSessionRuntimeOptions<TSession extends MeetingSessionRecord<TTransport, TMode>, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth<TManualReason, TSpeechBlockedReason>, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> = MeetingSessionRuntimeOptions<TSession, TRequest, TTransport, TMode, THealth, TTab, TManualReason, TSpeechBlockedReason>;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeOptions","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"d3c730cba02d30512c4cdae6e2367c662982e2c25671833ecd8701283924c642","declaration":"export type MeetingSessionState = MeetingSessionState;","entrypoint":"meeting-runtime","exportName":"MeetingSessionState","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"2496931157bf64fdb16013172ab9c023e60c5f85b98f46a3ee9532ce58d636d6","declaration":"export type MeetingSetupCheck = MeetingSetupCheck;","entrypoint":"meeting-runtime","exportName":"MeetingSetupCheck","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"f0aed6f7955a43fc387d8bbc072cb6276b0f2d18e7f829441a2ad45974bb3831","declaration":"export type MeetingSetupStatus = MeetingSetupStatus;","entrypoint":"meeting-runtime","exportName":"MeetingSetupStatus","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
@@ -3259,9 +3259,9 @@
{"closureHash":"20c70a94483aeddda4d1500cfcc5e71fab844b474ba4061c55d6c8693d40821b","declaration":"export type MeetingVoiceCallJoinResult = MeetingVoiceCallJoinResult;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallJoinResult","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"4fb2c5928aa6f809dd4c604d71c5c99cdfe3e98b6e9c1662601c9b4ad9738162","declaration":"export type MeetingVoiceCallStatusResult = MeetingVoiceCallStatusResult;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallStatusResult","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"5ef812397b6409a4ca228943dd1080661365959477b42e705a9aaa219757d14f","declaration":"export type MeetingVoiceCallSurface = MeetingVoiceCallSurface;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallSurface","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"}
{"closureHash":"647fd7d11823c5e1228d0cb75a7dfed96c63e16087f74f7dc6c48afaebaf417d","declaration":"export interface MeetingPlatformAdapter<Session, Mode extends string, Health extends MeetingBrowserHealth, Transcript extends MeetingTranscriptSnapshot, CreateParams = never, CreateResult = never, DialInParams = never, DialInPlan = never> extends MeetingPlatformAdapterContract<Session, Mode, Health, Transcript, CreateParams, CreateResult, DialInParams, DialInPlan> {\n}","entrypoint":"meeting-runtime","exportName":"MeetingPlatformAdapter","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"}
{"closureHash":"4eaf1fc1a9108206f22d89e18f61a55a34c7270419bd533692cb6106b0491dff","declaration":"export interface MeetingPlatformAdapter<Session, Mode extends string, Health extends MeetingBrowserHealth, Transcript extends MeetingTranscriptSnapshot, CreateParams = never, CreateResult = never, DialInParams = never, DialInPlan = never> extends MeetingPlatformAdapterContract<Session, Mode, Health, Transcript, CreateParams, CreateResult, DialInParams, DialInPlan> {\n}","entrypoint":"meeting-runtime","exportName":"MeetingPlatformAdapter","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"}
{"closureHash":"79884bd1df1ea0d07d5ceb4c62d93c1ee744b75d31c94c988845869c0f3cbd2d","declaration":"export interface MeetingRealtimeAudioTransport {\n onFatal(handler: () => void): void;\n startInput(onAudio: (audio: Buffer) => void): void;\n beginOutput?(): void;\n stop(): Promise<void>;\n writeOutput(audio: Buffer): Promise<void>;\n clearOutput(): Promise<void>;\n dispose(): Promise<void>;\n getHealth?(): MeetingRealtimeAudioTransportHealth;\n startBargeInMonitor?(onBargeIn: (audio: Buffer) => boolean): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"}
{"closureHash":"d3d839a5d9a3361c282ff6d2713defc867be38fef32cb3e2731fcd4fbf6645a7","declaration":"export class MeetingSessionRuntime<TSession extends MeetingSessionRecord<TTransport, TMode>, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth<TManualReason, TSpeechBlockedReason>, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> {\n readonly #sessions: Map<string, TSession>;\n readonly #sessionLeaves: Map<string, Promise<MeetingSessionLeaveResult<TSession>>>;\n readonly #sessionCleanup: MeetingSessionCleanupTracker;\n readonly #meetingLock: MeetingSessionJoinLock;\n readonly #sessionStops: Map<string, () => Promise<void>>;\n readonly #sessionSpeakers: Map<string, (instructions?: string) => void>;\n readonly #sessionHealth: Map<string, () => Partial<THealth>>;\n readonly #durableTranscripts: MeetingSessionDurableTranscripts<TSession>;\n readonly #transcriptStore: MeetingSessionTranscriptStore<TSession>;\n constructor(private readonly options: MeetingSessionRuntimeOptions<TSession, TRequest, TTransport, TMode, THealth, TTab, TManualReason, TSpeechBlockedReason>);\n list(): TSession[];\n getSession(sessionId: string): TSession | undefined;\n async status(sessionId?: string): Promise<{\n found: boolean;\n session?: TSession;\n sessions?: TSession[];\n }>;\n async transcript(sessionId: string, options: {\n sinceIndex?: number;\n }): Promise<{ found: boolean; sessionId?: string; startIndex?: number; nextIndex?: number; droppedLines?: number; evicted?: boolean; lines?: MeetingTranscriptLine[]; }>;\n async startTranscriptSource(request: TranscriptStartRequest): Promise<TranscriptsStartResult>;\n async stopTranscriptSource(request: TranscriptStopRequest): Promise<TranscriptsStopResult>;\n isReusableSession(session: TSession, resolved: MeetingResolvedJoin<TTransport, TMode>): boolean;\n async join(request: TRequest): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async leave(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n async speak(sessionId: string, instructions?: string): Promise<{\n found: boolean;\n spoken: boolean;\n session?: TSession;\n }>;\n async speakWhenReady(session: TSession, instructions: string): Promise<boolean>;\n hasHealthHandle(sessionId: string): boolean;\n refreshHealth(sessionId?: string): void;\n async refreshBrowserHealth(session: TSession, options: {\n force?: boolean;\n readOnly?: boolean;\n }): Promise<void>;\n async refreshCaptionHealth(session: TSession): Promise<void>;\n refreshSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n markSessionEnded(session: TSession, reason: string): void;\n async #joinUnlocked(request: TRequest, resolved: MeetingResolvedJoin<TTransport, TMode>): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async #leaveUnlocked(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n async #leaveSession(session: TSession, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n #meetingKey(transport: TTransport, url: string): string;\n #inheritBrowserTabOwnership(params: {\n session: TSession;\n transport: TTransport;\n nodeId?: string;\n meetingUrl: string;\n tab?: TTab;\n }): TTab | undefined;\n async #settleRetainedBrowserTabs(retained: Array<{\n session: TSession;\n tab: TTab;\n }>, adopted?: {\n transport: TTransport;\n nodeId?: string;\n tab: TTab;\n }): Promise<boolean>;\n async #rollbackFailedJoinSession(session: TSession): Promise<void>;\n async #settleRetainedBrowserTabsAfterFailure(retained: Array<{\n session: TSession;\n tab: TTab;\n }>): Promise<void>;\n #attachRuntimeHandles(session: TSession, handles: MeetingSessionRuntimeHandles<THealth>): void;\n #dropRuntimeHandles(sessionId: string): void;\n #isManagedBrowserSession(session: TSession): boolean;\n #evaluateSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n #noteSession(session: TSession, note: string): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"class","recordType":"export"}
{"closureHash":"42723d088f7aacd0105697bace2776af0f0b6634c40183ad06a24f563ecca26f","declaration":"export class MeetingSessionRuntime<TSession extends MeetingSessionRecord<TTransport, TMode>, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth<TManualReason, TSpeechBlockedReason>, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> {\n readonly #sessions: Map<string, TSession>;\n readonly #sessionLeaves: Map<string, Promise<MeetingSessionLeaveResult<TSession>>>;\n readonly #sessionCleanup: MeetingSessionCleanupTracker;\n readonly #meetingLock: MeetingSessionJoinLock;\n readonly #sessionStops: Map<string, () => Promise<void>>;\n readonly #sessionSpeakers: Map<string, (instructions?: string) => void>;\n readonly #sessionHealth: Map<string, () => Partial<THealth>>;\n readonly #durableTranscripts: MeetingSessionDurableTranscripts<TSession>;\n readonly #transcriptStore: MeetingSessionTranscriptStore<TSession>;\n constructor(private readonly options: MeetingSessionRuntimeOptions<TSession, TRequest, TTransport, TMode, THealth, TTab, TManualReason, TSpeechBlockedReason>);\n list(): TSession[];\n getSession(sessionId: string): TSession | undefined;\n async status(sessionId?: string): Promise<{\n found: boolean;\n session?: TSession;\n sessions?: TSession[];\n }>;\n async transcript(sessionId: string, options: {\n sinceIndex?: number;\n }): Promise<{ found: boolean; sessionId?: string; startIndex?: number; nextIndex?: number; droppedLines?: number; evicted?: boolean; lines?: MeetingTranscriptLine[]; }>;\n async startTranscriptSource(request: TranscriptStartRequest): Promise<TranscriptsStartResult>;\n async stopTranscriptSource(request: TranscriptStopRequest): Promise<TranscriptsStopResult>;\n isReusableSession(session: TSession, resolved: MeetingResolvedJoin<TTransport, TMode>): boolean;\n async join(request: TRequest): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async leave(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n async speak(sessionId: string, instructions?: string): Promise<{\n found: boolean;\n spoken: boolean;\n session?: TSession;\n }>;\n async speakWhenReady(session: TSession, instructions: string): Promise<boolean>;\n hasHealthHandle(sessionId: string): boolean;\n refreshHealth(sessionId?: string): void;\n async refreshBrowserHealth(session: TSession, options: {\n force?: boolean;\n readOnly?: boolean;\n }): Promise<void>;\n async refreshCaptionHealth(session: TSession): Promise<void>;\n refreshSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n markSessionEnded(session: TSession, reason: string): void;\n async #joinUnlocked(request: TRequest, resolved: MeetingResolvedJoin<TTransport, TMode>): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async #leaveUnlocked(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n async #leaveSession(session: TSession, options?: {\n keepBrowserTab?: boolean;\n }): Promise<MeetingSessionLeaveResult<TSession>>;\n #meetingKey(transport: TTransport, url: string): string;\n #inheritBrowserTabOwnership(params: {\n session: TSession;\n transport: TTransport;\n nodeId?: string;\n meetingUrl: string;\n tab?: TTab;\n }): TTab | undefined;\n async #settleRetainedBrowserTabs(retained: Array<{\n session: TSession;\n tab: TTab;\n }>, adopted?: {\n transport: TTransport;\n nodeId?: string;\n tab: TTab;\n }): Promise<boolean>;\n async #rollbackFailedJoinSession(session: TSession): Promise<void>;\n async #settleRetainedBrowserTabsAfterFailure(retained: Array<{\n session: TSession;\n tab: TTab;\n }>): Promise<void>;\n #attachRuntimeHandles(session: TSession, handles: MeetingSessionRuntimeHandles<THealth>): void;\n #dropRuntimeHandles(sessionId: string): void;\n #isManagedBrowserSession(session: TSession): boolean;\n #evaluateSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n #noteSession(session: TSession, note: string): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"class","recordType":"export"}
{"category":null,"entrypoint":"memory-core-host-engine-foundation","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","recordType":"module"}
{"closureHash":"e2df8d235401aebf58eb71652fbeaedb42ca00aaa5042a76909ff2c48ba6fd54","declaration":"export function createSubsystemLogger(subsystem: string): SubsystemLogger;","entrypoint":"memory-core-host-engine-foundation","exportName":"createSubsystemLogger","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","kind":"function","recordType":"export"}
{"closureHash":null,"declaration":"export function isPathInside(root: string, target: string): boolean;","entrypoint":"memory-core-host-engine-foundation","exportName":"isPathInside","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","kind":"function","recordType":"export"}
@@ -3388,9 +3388,9 @@
{"category":"core","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","recordType":"module"}
{"closureHash":"3d27406644141af2733cfca6e8c1240fc62327910109f585ce9073cafd7fd89c","declaration":"export function buildJsonPluginConfigSchema(schema: JsonSchemaObject, options?: BuildJsonPluginConfigSchemaOptions): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"buildJsonPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
{"closureHash":"aff66c792d532642afb9c6e5a03c8d220f219250c3a8b49733f32058f22f98ca","declaration":"export function buildPluginConfigSchema(schema: ZodTypeAny, options?: BuildPluginConfigSchemaOptions): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"buildPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
{"closureHash":"0e3a6175467adf8ff674c52bb0ae1af57d2e52f33448416e5d11b4eca1685baf","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"plugin-entry","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
{"closureHash":"a4f0792ef70bd2b09bf37e9c37943284c8f93b82bd3864cf6f3739033c2878a6","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"plugin-entry","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
{"closureHash":"0ef1dfa3b5deeb456480e292c0e835c3cd6d13e7bb7059fc735546507da51594","declaration":"export function emptyPluginConfigSchema(): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"emptyPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"}
{"closureHash":"e75e94d131237b4b73c507cad9f2a0940716404531516861497e92ba8d06fb87","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"plugin-entry","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"71e57b87ff6cba595cc4513f2fd68742eb69a234d17e328c6cc6761eec04385e","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"plugin-entry","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"d2ff4de9ee3fd111c2cc64a3ee7e557d9f161af1b6b437ee7886bcb16e426317","declaration":"export type AgentPromptGuidance = AgentPromptGuidance;","entrypoint":"plugin-entry","exportName":"AgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"2841127a90e04467adfea8126cbf03655f44ddb089ad9e0d48833c2beea39cbd","declaration":"export type AgentPromptGuidanceEntry = AgentPromptGuidanceEntry;","entrypoint":"plugin-entry","exportName":"AgentPromptGuidanceEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"aa0412acefe62caff12e5271ead0545504874e824380dc21cfc0566388a05f33","declaration":"export type AgentPromptSurfaceKind = \"openclaw_main\" | \"pi_main\" | \"codex_app_server\" | \"cli_backend\" | \"acp_backend\" | \"subagent\";","entrypoint":"plugin-entry","exportName":"AgentPromptSurfaceKind","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
@@ -3406,10 +3406,10 @@
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"plugin-entry","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"2f6e368fff73e942044cdf95c7c751b46c741e22ac0d2d4d97f45a3158f758ae","declaration":"export type OpenClawGatewayDiscoveryAdvertiseContext = OpenClawGatewayDiscoveryAdvertiseContext;","entrypoint":"plugin-entry","exportName":"OpenClawGatewayDiscoveryAdvertiseContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"b198058e0065e5c60b729a5bdf568f7e2436a006d8c4a7c63de764c7283f96ba","declaration":"export type OpenClawGatewayDiscoveryService = OpenClawGatewayDiscoveryService;","entrypoint":"plugin-entry","exportName":"OpenClawGatewayDiscoveryService","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"fb4fde629072c35c7afe2f3248520c284b439596eb2e25c136b6494b402cee1f","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"b9c63a41b3da754e29aee2040c6b79300801cb59b95dcedf8032f404cd0c9a8d","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"69fefc8092c1cea366c48505c8423ff0f8f995caef3d259d177346b1687541aa","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"c8efb9154eafc9061e7b6bf41fd001a4c2b38e0645d6382ad9e493d3f12a3664","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"2614b3215fe42678ee92b6d077aaf2ddea54294b486b5bc3dbffde10cff679ac","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"a7ed83f0924f818b23cecb5a1f3591ff28b9499ccac9667a2b8505c2bc608ea9","declaration":"export type OpenClawPluginGatewayEventScope = OpenClawPluginGatewayEventScope;","entrypoint":"plugin-entry","exportName":"OpenClawPluginGatewayEventScope","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"f81f224d9b837e6353b7a546c5a76b124bcf568fd1f1fd0c6881fda30c53120a","declaration":"export type OpenClawPluginGatewayEvents = OpenClawPluginGatewayEvents;","entrypoint":"plugin-entry","exportName":"OpenClawPluginGatewayEvents","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"7470b211ac4d3449cd0fc353ee2eb48e9fbc2dbc9259d21c680d0203577aa94f","declaration":"export type OpenClawPluginHttpRouteHandler = OpenClawPluginHttpRouteHandler;","entrypoint":"plugin-entry","exportName":"OpenClawPluginHttpRouteHandler","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
@@ -3558,14 +3558,14 @@
{"closureHash":"5e57188ea41861c5108f8a07d6a2a1902ced52b5f1708a70d702dc4ba3ce5e0b","declaration":"export function executePluginCommand(params: { command: RegisteredPluginCommand; args?: string; senderId?: string; channel: string; channelId?: PluginCommandContext[\"channelId\"]; isAuthorizedSender: boolean; senderIsOwner?: boolean; gatewayClientScopes?: PluginCommandContext[\"gatewayClientScopes\"]; agentId?: string; sessionKey?: PluginCommandContext[\"sessionKey\"]; sessionId?: PluginCommandContext[\"sessionId\"]; sessionTarget?: PluginCommandContext[\"sessionTarget\"]; sessionFile?: PluginCommandContext[\"sessionFile\"]; authProfileId?: string; commandBody: string; config: OpenClawConfig; from?: PluginCommandContext[\"from\"]; to?: PluginCommandContext[\"to\"]; originatingTo?: string; accountId?: PluginCommandContext[\"accountId\"]; messageThreadId?: PluginCommandContext[\"messageThreadId\"]; threadParentId?: PluginCommandContext[\"threadParentId\"]; diagnosticsSessions?: PluginCommandContext[\"diagnosticsSessions\"]; diagnosticsUploadApproved?: PluginCommandContext[\"diagnosticsUploadApproved\"]; diagnosticsPreviewOnly?: PluginCommandContext[\"diagnosticsPreviewOnly\"]; diagnosticsPrivateRouted?: PluginCommandContext[\"diagnosticsPrivateRouted\"]; }): Promise<PluginCommandResult>;","entrypoint":"plugin-runtime","exportName":"executePluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"7e75fc04d621dc8d12f459d5b5b0c039a39b77c30c2b51af481e123c352f57b8","declaration":"export function getGlobalHookRunner(): HookRunner | null;","entrypoint":"plugin-runtime","exportName":"getGlobalHookRunner","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"db6583607237e4081814e2c5d4f8fb6f216ad3bbfe623bf16fc1a9c09c15f64b","declaration":"export function getPluginCommandSpecs(provider?: string, options?: PluginCommandSpecOptions): Array<{ name: string; description: string; descriptionLocalizations?: Record<string, string>; acceptsArgs: boolean; }>;","entrypoint":"plugin-runtime","exportName":"getPluginCommandSpecs","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"e9dd89081dbc3593fa3f2db4c3aa9b09a87f04b30f77e5e9f9ea85e6338a6af9","declaration":"export function getPluginRuntimeGatewayRequestScope(): PluginRuntimeGatewayRequestScope | undefined;","entrypoint":"plugin-runtime","exportName":"getPluginRuntimeGatewayRequestScope","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"6ac38086644eb07b191025bb303de3621cb9f801ecc1a11dd06a9896c0c9815d","declaration":"export function getPluginRuntimeGatewayRequestScope(): PluginRuntimeGatewayRequestScope | undefined;","entrypoint":"plugin-runtime","exportName":"getPluginRuntimeGatewayRequestScope","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"cfe277ce6de0c6ed50f1f54b66c889f6c95e91b058e8bcdc27aa37317a93a447","declaration":"export function listRegisteredPluginAgentPromptGuidance(params?: { surface?: AgentPromptSurfaceKind; includeLegacyGlobalGuidance?: boolean; }): string[];","entrypoint":"plugin-runtime","exportName":"listRegisteredPluginAgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"ef4872995ac1acbe1b2046397e3ddc5d9a4315cb0bd0dfddfac6222418e7c048","declaration":"export function matchPluginCommand(commandBody: string, options?: { channel?: string; }): { command: RegisteredPluginCommand; args?: string; } | null;","entrypoint":"plugin-runtime","exportName":"matchPluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"e02d3651398ab23c38e91a52fc1502e7a97490f17047b4f558b87c94731b0344","declaration":"export function registerPluginCommand(pluginId: string, command: OpenClawPluginCommandDefinition, opts?: { pluginName?: string; pluginRoot?: string; allowReservedCommandNames?: boolean; allowOwnerStatusExposure?: boolean; }): CommandRegistrationResult;","entrypoint":"plugin-runtime","exportName":"registerPluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"16986e5d431f584c2d5053289eca3d2225bbe47a92cdfbbc2af91b264a165846","declaration":"export function registerPluginInteractiveHandler(pluginId: string, registration: PluginInteractiveHandlerRegistration, opts?: { pluginName?: string; pluginRoot?: string; }): InteractiveRegistrationResult;","entrypoint":"plugin-runtime","exportName":"registerPluginInteractiveHandler","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"f20c07a48e2c949fbc889e7a32760f4e52339d9f6d3eab49e00ff249266e2396","declaration":"export function startLazyPluginServiceModule(params: { skipEnvVar?: string; overrideEnvVar?: string; validateOverrideSpecifier?: (specifier: string) => string; loadDefaultModule: () => Promise<LazyServiceModule>; loadOverrideModule?: (specifier: string) => Promise<LazyServiceModule>; startExportNames: string[]; stopExportNames?: string[]; }): Promise<LazyPluginServiceHandle | null>;","entrypoint":"plugin-runtime","exportName":"startLazyPluginServiceModule","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"bad43ffe69d1d9d6c92c79df4c388b3dda685013a92392daef456f1622ade659","declaration":"export type LazyPluginServiceHandle = LazyPluginServiceHandle;","entrypoint":"plugin-runtime","exportName":"LazyPluginServiceHandle","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"fb4fde629072c35c7afe2f3248520c284b439596eb2e25c136b6494b402cee1f","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"b9c63a41b3da754e29aee2040c6b79300801cb59b95dcedf8032f404cd0c9a8d","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"f06379ada10ce0eca4e66bdf978db2c0035e054a135dc044c6d831ac7797c08f","declaration":"export type PluginConversationBinding = PluginConversationBinding;","entrypoint":"plugin-runtime","exportName":"PluginConversationBinding","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"a1223d674b2b66918a576ae05b04318d7b8cbe9b1d3bc6dd7a08d1a4fa79b291","declaration":"export type PluginConversationBindingRequestParams = PluginConversationBindingRequestParams;","entrypoint":"plugin-runtime","exportName":"PluginConversationBindingRequestParams","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
@@ -3655,10 +3655,10 @@
{"closureHash":"e66adcb55dec79be73a52bc76594b7e9210fd93c69a85b56098fbb58cecbb354","declaration":"export type WriteOAuthCredentialsOptions = WriteOAuthCredentialsOptions;","entrypoint":"provider-auth","exportName":"WriteOAuthCredentialsOptions","importSpecifier":"openclaw/plugin-sdk/provider-auth","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","recordType":"module"}
{"closureHash":"b5665596a3f011454a5614681513516acd50b6c749536c43842d811980cf7ad3","declaration":"export function augmentModelCatalogWithProviderPlugins(params: { config?: OpenClawConfig; workspaceDir?: string; env?: NodeJS.ProcessEnv; metadataSnapshot?: PluginMetadataSnapshot; context: ProviderAugmentModelCatalogContext; }): Promise<ModelCatalogEntry[]>;","entrypoint":"provider-catalog-runtime","exportName":"augmentModelCatalogWithProviderPlugins","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"closureHash":"94876118e27fd3a011c350765bc51c045da727a430bf560b76b13c36815e2a21","declaration":"export function isPluginProvidersLoadInFlight(params: Parameters<typeof resolvePluginProviders>[0]): boolean;","entrypoint":"provider-catalog-runtime","exportName":"isPluginProvidersLoadInFlight","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"closureHash":"baabd4ac04b433e27916ad3bfeee5a95952afce9e0685ae5acf3b7dceea69507","declaration":"export function resolveCatalogHookProviderPluginIds(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; metadataSnapshot?: ProviderManifestLoadParams[\"metadataSnapshot\"]; }): string[];","entrypoint":"provider-catalog-runtime","exportName":"resolveCatalogHookProviderPluginIds","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"closureHash":"c21aedf5df214eee9f68930c1aaeef0b9ef5ec66df0a09dc9db095aa1764bd58","declaration":"export function resolveOwningPluginIdsForProvider(params: { provider: string; config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; manifestRegistry?: PluginManifestRegistry; metadataSnapshot?: Pick<PluginMetadataSnapshot, \"owners\" | \"manifestRegistry\" | \"byPluginId\">; }): string[] | undefined;","entrypoint":"provider-catalog-runtime","exportName":"resolveOwningPluginIdsForProvider","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"closureHash":"37b37fd3da65fed3572a4e2d9784e79a338a26b85cacd87039c4741cfb41b07b","declaration":"export function resolvePluginProviders(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; bundledProviderVitestCompat?: boolean; onlyPluginIds?: string[]; providerRefs?: readonly string[]; modelRefs?: readonly string[]; activate?: boolean; cache?: boolean; applyAutoEnable?: boolean; pluginSdkResolution?: PluginLoadOptions[\"pluginSdkResolution\"]; mode?: \"runtime\" | \"setup\"; includeUntrustedWorkspacePlugins?: boolean; pluginMetadataSnapshot?: PluginMetadataRegistryView; skipIfLoadInFlight?: boolean; }): ProviderPlugin[];","entrypoint":"provider-catalog-runtime","exportName":"resolvePluginProviders","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"closureHash":"77aaebb98084205149391d11ef31ffa8a2f29a42271a5f0b47e97e101d581c8c","declaration":"export function isPluginProvidersLoadInFlight(params: Parameters<typeof resolvePluginProviders>[0]): boolean;","entrypoint":"provider-catalog-runtime","exportName":"isPluginProvidersLoadInFlight","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"closureHash":"33a282a2bcfe6babd26520c27b40d86b143d487b044fa25adb696b621f099685","declaration":"export function resolveCatalogHookProviderPluginIds(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; metadataSnapshot?: ProviderManifestLoadParams[\"metadataSnapshot\"]; }): string[];","entrypoint":"provider-catalog-runtime","exportName":"resolveCatalogHookProviderPluginIds","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"closureHash":"3932fb64965f1f19ca12606778b78bb13beab0fd953b7b4025f84edb91c68206","declaration":"export function resolveOwningPluginIdsForProvider(params: { provider: string; config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; manifestRegistry?: PluginManifestRegistry; metadataSnapshot?: Pick<PluginMetadataSnapshot, \"owners\" | \"manifestRegistry\" | \"byPluginId\">; }): string[] | undefined;","entrypoint":"provider-catalog-runtime","exportName":"resolveOwningPluginIdsForProvider","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"closureHash":"35714460e5a066deaceac3617abe4a955bdb14e563c1e76412d65ef9da774e83","declaration":"export function resolvePluginProviders(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; bundledProviderVitestCompat?: boolean; onlyPluginIds?: string[]; providerRefs?: readonly string[]; modelRefs?: readonly string[]; activate?: boolean; cache?: boolean; applyAutoEnable?: boolean; pluginSdkResolution?: PluginLoadOptions[\"pluginSdkResolution\"]; mode?: \"runtime\" | \"setup\"; includeUntrustedWorkspacePlugins?: boolean; pluginMetadataSnapshot?: PluginMetadataRegistryView; skipIfLoadInFlight?: boolean; }): ProviderPlugin[];","entrypoint":"provider-catalog-runtime","exportName":"resolvePluginProviders","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"}
{"category":null,"entrypoint":"proxy-capture","importSpecifier":"openclaw/plugin-sdk/proxy-capture","recordType":"module"}
{"closureHash":"d0e4e026d736bc00b1758d1089c44c3c5f3a09c7254291584de8cb297365804c","declaration":"export function acquireDebugProxyCaptureStore(dbPath: string, blobDir: string): { store: LegacyDebugProxyCaptureStore; release: () => void; };\nexport function acquireDebugProxyCaptureStore(options?: DebugProxyCaptureStoreOptions): { store: SharedDebugProxyCaptureStore; release: () => void; };","entrypoint":"proxy-capture","exportName":"acquireDebugProxyCaptureStore","importSpecifier":"openclaw/plugin-sdk/proxy-capture","kind":"function","recordType":"export"}
{"closureHash":"d41cbb9de51b7aee1c6cf8c713b0bc44f27ac926fbb6422c05726f196d11964e","declaration":"export function captureHttpExchange(params: { url: string; method: string; requestHeaders?: Headers | Record<string, string> | undefined; requestBody?: BodyInit | Buffer | string | null; response: Response; transport?: \"http\" | \"sse\"; flowId?: string; meta?: Record<string, unknown>; }, resolved?: DebugProxySettings, deps?: DebugProxyCaptureRuntimeDeps): void;","entrypoint":"proxy-capture","exportName":"captureHttpExchange","importSpecifier":"openclaw/plugin-sdk/proxy-capture","kind":"function","recordType":"export"}
@@ -4620,16 +4620,16 @@
{"closureHash":"e365d7ad911453b5139ba700931b061e560cff80b50d4cbe5e9615b5d7e13a52","declaration":"export type ScopedExpiringIdCache<TScope extends string | number, TId extends string | number> = ScopedExpiringIdCache<TScope, TId>;","entrypoint":"text-runtime","exportName":"ScopedExpiringIdCache","importSpecifier":"openclaw/plugin-sdk/text-runtime","kind":"type","recordType":"export"}
{"closureHash":"af5502c92594c2e9049a4b4994e17c00d3adee3f6d1e68edd818a539c74c8787","declaration":"export interface CodeRegion {\n start: number;\n end: number;\n}","entrypoint":"text-runtime","exportName":"CodeRegion","importSpecifier":"openclaw/plugin-sdk/text-runtime","kind":"interface","recordType":"export"}
{"category":null,"entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","recordType":"module"}
{"closureHash":"f26f6685ad31a4537184db05b259bef8d78bc3501b70f7ec1e47beda686a7bb2","declaration":"export function defineToolPlugin<TConfigSchema extends TSchema | undefined = undefined>(definition: DefineToolPluginOptions<TConfigSchema>): DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"defineToolPlugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"}
{"closureHash":"bf00fd6de784c5fb00679a000d469fb50e1f18a72969292bf854e183852b719b","declaration":"export function defineToolPlugin<TConfigSchema extends TSchema | undefined = undefined>(definition: DefineToolPluginOptions<TConfigSchema>): DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"defineToolPlugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"}
{"closureHash":"36ef907ce20f885b5f3068cbf0475dc442a68da9652579bb5bf8fb83ad34c38b","declaration":"export function getToolPluginMetadata(entry: unknown): ToolPluginMetadata | undefined;","entrypoint":"tool-plugin","exportName":"getToolPluginMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"}
{"closureHash":"bdc58154e36b2625fb3daccca3eab248d981077d04d747f0ad507cb2ff565198","declaration":"export const toolPluginMetadataSymbol: typeof toolPluginMetadataSymbol;","entrypoint":"tool-plugin","exportName":"toolPluginMetadataSymbol","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"const","recordType":"export"}
{"closureHash":"b50a3bde4f3d253d2096b9e2b626836024852e8839598169e92baadcb356b15a","declaration":"export type DefineToolPluginOptions<TConfigSchema extends TSchema | undefined = undefined> = DefineToolPluginOptions<TConfigSchema>;","entrypoint":"tool-plugin","exportName":"DefineToolPluginOptions","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"d4e2d9bd9e458ac4d17c8dcaa0d241398a9eaca9733c95c89fbb8e6d8cfa5325","declaration":"export type DefinedToolPluginEntry = DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"DefinedToolPluginEntry","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"6bad0c83f5fc9f0c47fe985a7fff2886edd0ee6e832ba29aeb57828d64f4d267","declaration":"export type ToolPluginExecutionContext = ToolPluginExecutionContext;","entrypoint":"tool-plugin","exportName":"ToolPluginExecutionContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"2bb77f487dcd21094e6ced1e7dcec12bd89a4fce580fe129ad07cbf55eb74c6a","declaration":"export type ToolPluginFactoryContext<TConfig> = ToolPluginFactoryContext<TConfig>;","entrypoint":"tool-plugin","exportName":"ToolPluginFactoryContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"68f0e8143972deac8790ce2848dcd32cff726dcdf12b6ff06ddcc468616c4fad","declaration":"export type DefineToolPluginOptions<TConfigSchema extends TSchema | undefined = undefined> = DefineToolPluginOptions<TConfigSchema>;","entrypoint":"tool-plugin","exportName":"DefineToolPluginOptions","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"6bc77664b7b686d12de72ac99dc2fa28c5dfa8ad51ea71d807d86f04dd06402a","declaration":"export type DefinedToolPluginEntry = DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"DefinedToolPluginEntry","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"549a9c7e0542a3cd423b640f655906849da3e1cb54d5c306009b218ed52bef15","declaration":"export type ToolPluginExecutionContext = ToolPluginExecutionContext;","entrypoint":"tool-plugin","exportName":"ToolPluginExecutionContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"bc673018ec3efc5797a01f9786263a24eccdf0eddb857ddb6e967dff3a2d3c4d","declaration":"export type ToolPluginFactoryContext<TConfig> = ToolPluginFactoryContext<TConfig>;","entrypoint":"tool-plugin","exportName":"ToolPluginFactoryContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"f774bd092f51a31fbb34847213f9583234f585f66918d0af55e81bbbae40463b","declaration":"export type ToolPluginMetadata = ToolPluginMetadata;","entrypoint":"tool-plugin","exportName":"ToolPluginMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"414a89d0c80eaaf682dc25d306e7223c981c6fd25366adb973a106f4268a6a54","declaration":"export type ToolPluginStaticToolMetadata = ToolPluginStaticToolMetadata;","entrypoint":"tool-plugin","exportName":"ToolPluginStaticToolMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"3b13d82cf0d5c6358ff9b1c182ade424886c2806387ecdb5b7ad96cd7801ff3c","declaration":"export type ToolPluginToolDefinition<TConfig, TParamsSchema extends TSchema> = ToolPluginToolDefinition<TConfig, TParamsSchema>;","entrypoint":"tool-plugin","exportName":"ToolPluginToolDefinition","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"6304d369f4a05607a4e5a9631c757956f5387f0efdfc3984ac3331915b9a9ccf","declaration":"export type ToolPluginToolDefinition<TConfig, TParamsSchema extends TSchema> = ToolPluginToolDefinition<TConfig, TParamsSchema>;","entrypoint":"tool-plugin","exportName":"ToolPluginToolDefinition","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"tool-results","importSpecifier":"openclaw/plugin-sdk/tool-results","recordType":"module"}
{"closureHash":"c5b0951c3629834dff78f92317cf1421a6bbc0faf9307be1cabb915055665280","declaration":"export function jsonResult<TDetails>(payload: TDetails): AgentToolResult<TDetails>;","entrypoint":"tool-results","exportName":"jsonResult","importSpecifier":"openclaw/plugin-sdk/tool-results","kind":"function","recordType":"export"}
{"closureHash":"b9aefc637a694c74e028e92006004bef18185ed569af48ac43d36b646b0af2f3","declaration":"export function textResult<TDetails>(text: string, details: TDetails): AgentToolResult<TDetails>;","entrypoint":"tool-results","exportName":"textResult","importSpecifier":"openclaw/plugin-sdk/tool-results","kind":"function","recordType":"export"}
@@ -4663,9 +4663,9 @@
{"closureHash":"9f9174f1023a8a451232f5d97d1e922b7faa88b76b58cffbfbe246a1488e0ddd","declaration":"export function readJsonWebhookBodyOrReject(params: { req: IncomingMessage; res: ServerResponse; maxBytes?: number; timeoutMs?: number; profile?: WebhookBodyReadProfile; emptyObjectOnEmpty?: boolean; invalidJsonMessage?: string; }): Promise<{ ok: true; value: unknown; } | { ok: false; }>;","entrypoint":"webhook-ingress","exportName":"readJsonWebhookBodyOrReject","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"1bbddd5d1c8297e315275db4d5e1c8748ff09c0be7c37b0cf456db4fc69f8909","declaration":"export function readRequestBodyWithLimit(req: IncomingMessage, options: ReadRequestBodyOptions): Promise<string>;","entrypoint":"webhook-ingress","exportName":"readRequestBodyWithLimit","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"e8a1174cac83ce346a231fd25e82bb5f7618ffb57cdd9af6eaa208411f70646d","declaration":"export function readWebhookBodyOrReject(params: { req: IncomingMessage; res: ServerResponse; maxBytes?: number; timeoutMs?: number; profile?: WebhookBodyReadProfile; invalidBodyMessage?: string; }): Promise<{ ok: true; value: string; } | { ok: false; }>;","entrypoint":"webhook-ingress","exportName":"readWebhookBodyOrReject","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"3abffbfcb38d18170a05d42b16be25b736f400980aa67c26a77702434576f8d6","declaration":"export function registerPluginHttpRoute(params: { path?: string | null; fallbackPath?: string | null; handler: PluginHttpRouteHandler; auth: PluginHttpRouteRegistration[\"auth\"]; match?: PluginHttpRouteRegistration[\"match\"]; gatewayRuntimeScopeSurface?: PluginHttpRouteRegistration[\"gatewayRuntimeScopeSurface\"]; replaceExisting?: boolean; reuseExistingSameOwner?: boolean; throwOnFailure?: boolean; pluginId?: string; source?: string; accountId?: string; log?: (message: string) => void; registry?: PluginRegistry; }): () => void;","entrypoint":"webhook-ingress","exportName":"registerPluginHttpRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"61e4874e70d24a93651b78454fa1190f5c0a1e1683e648f63333ef37ba9c1365","declaration":"export function registerPluginHttpRoute(params: { path?: string | null; fallbackPath?: string | null; handler: PluginHttpRouteHandler; auth: PluginHttpRouteRegistration[\"auth\"]; match?: PluginHttpRouteRegistration[\"match\"]; gatewayRuntimeScopeSurface?: PluginHttpRouteRegistration[\"gatewayRuntimeScopeSurface\"]; replaceExisting?: boolean; reuseExistingSameOwner?: boolean; throwOnFailure?: boolean; pluginId?: string; source?: string; accountId?: string; log?: (message: string) => void; registry?: PluginRegistry; }): () => void;","entrypoint":"webhook-ingress","exportName":"registerPluginHttpRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"05835f2f66f906f736b82b332a84a9714bc3a6b211890a62d8fc4dbf9258a7d4","declaration":"export function registerWebhookTarget<T extends { path: string; }>(targetsByPath: Map<string, T[]>, target: T, opts?: RegisterWebhookTargetOptions<T>): RegisteredWebhookTarget<T>;","entrypoint":"webhook-ingress","exportName":"registerWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"ffe4d07bee504fb97a834400f1cf0de4ccc0ffc95b51b1f571bc16627407174d","declaration":"export function registerWebhookTargetWithPluginRoute<T extends { path: string; }>(params: { targetsByPath: Map<string, T[]>; target: T; route: RegisterWebhookPluginRouteOptions; onLastPathTargetRemoved?: RegisterWebhookTargetOptions<T>[\"onLastPathTargetRemoved\"]; }): RegisteredWebhookTarget<T>;","entrypoint":"webhook-ingress","exportName":"registerWebhookTargetWithPluginRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"cd5965420fb37544c6a32e98232b117c8fd2074aca149daffacff656a782e60f","declaration":"export function registerWebhookTargetWithPluginRoute<T extends { path: string; }>(params: { targetsByPath: Map<string, T[]>; target: T; route: RegisterWebhookPluginRouteOptions; onLastPathTargetRemoved?: RegisterWebhookTargetOptions<T>[\"onLastPathTargetRemoved\"]; }): RegisteredWebhookTarget<T>;","entrypoint":"webhook-ingress","exportName":"registerWebhookTargetWithPluginRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"ec2f47e9bd7a075a3dd4302ac9e4c0bfe20630445db6735cf803f2d354275841","declaration":"export function requestBodyErrorToText(code: RequestBodyLimitErrorCode): string;","entrypoint":"webhook-ingress","exportName":"requestBodyErrorToText","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"5e1f3b468d56eb0f82104184077fdf4b6bd0c1444aa10b71a65fcaa2ec0298a2","declaration":"export function resolveRequestClientIp(req?: IncomingMessage, trustedProxies?: string[], allowRealIpFallback?: boolean): string | undefined;","entrypoint":"webhook-ingress","exportName":"resolveRequestClientIp","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
{"closureHash":"56c3e9868dfa6ee2a7a128eb02039a16b52696759adadbd3fe0a3bd7a6a07eeb","declaration":"export function resolveSingleWebhookTarget<T>(targets: readonly T[], isMatch: (target: T) => boolean): WebhookTargetMatchResult<T>;","entrypoint":"webhook-ingress","exportName":"resolveSingleWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"}
@@ -4683,7 +4683,7 @@
{"closureHash":"efb74e84339c15d6f607b38d1d477b0504d47d04ae78e77083a1893c756a0b54","declaration":"export const WEBHOOK_RATE_LIMIT_DEFAULTS: Readonly<{ windowMs: 60000; maxRequests: 120; maxTrackedKeys: 4096;}>;","entrypoint":"webhook-ingress","exportName":"WEBHOOK_RATE_LIMIT_DEFAULTS","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"const","recordType":"export"}
{"closureHash":"13b28ec9acae43c3bdcd683b9831154f88118dee8142e42b7eebfd59f08c602c","declaration":"export type BoundedCounter = BoundedCounter;","entrypoint":"webhook-ingress","exportName":"BoundedCounter","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
{"closureHash":"9e737ae8c17038ef7becbd2bf1b756cfeaed571e2ded368c0fe3a446ebd1f666","declaration":"export type FixedWindowRateLimiter = FixedWindowRateLimiter;","entrypoint":"webhook-ingress","exportName":"FixedWindowRateLimiter","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
{"closureHash":"9e6c519882ad4d8c8be55237efb109352dd2c39c8dfe17a8e874a77905ceba96","declaration":"export type RegisterWebhookPluginRouteOptions = RegisterWebhookPluginRouteOptions;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookPluginRouteOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
{"closureHash":"63f32cd8136d7ae5eb5d5a81e0a22cc20c8f90c8717b4a83f6931255a1d44b16","declaration":"export type RegisterWebhookPluginRouteOptions = RegisterWebhookPluginRouteOptions;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookPluginRouteOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
{"closureHash":"b3e98619854462acfac6538ac9a2d0cefb88704a0eac712563f0996b07364152","declaration":"export type RegisterWebhookTargetOptions<T extends {\n path: string;\n}> = RegisterWebhookTargetOptions<T>;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookTargetOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
{"closureHash":"964c2bfd8f268c411ee7b982c9de02c207f4bec402dd62c9f998a59752bb9d1f","declaration":"export type RegisteredWebhookTarget<T> = RegisteredWebhookTarget<T>;","entrypoint":"webhook-ingress","exportName":"RegisteredWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
{"closureHash":"aa552e5bdaefc9eb94d3b5a5cdf8c413fad555d9f452c6a2a6af5a3ce695c9d1","declaration":"export type WebhookAnomalyTracker = WebhookAnomalyTracker;","entrypoint":"webhook-ingress","exportName":"WebhookAnomalyTracker","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
+13
View File
@@ -870,6 +870,19 @@ unrelated inbound runtime helpers.
For channels that accept both canonical top-level DM keys and legacy nested keys, use the helpers from `plugin-sdk/channel-config-helpers`: `resolveChannelDmAccess`, `resolveChannelDmPolicy`, `resolveChannelDmAllowFrom`, and `normalizeChannelDmPolicy` keep account-local values ahead of inherited root values. Pair the same resolver with doctor repair through `normalizeLegacyDmAliases` so runtime and migration read the same contract.
If a channel intentionally applies stricter DM session routing than the
global config, expose that behavior through `security.dmRouting` so Doctor
and security audit resolve the same session owner as runtime. The optional
`resolveDmScope` callback runs before core route resolution; its context
includes `cfg`, `accountId`, the resolved `account`, and a `principalId`
for finite allowlist entries. `resolveDmRoute` receives those fields plus
the resolved core `route`; it may return `{ sessionKey }` for a shared final
bucket, `{ kind: "isolated" }` for an unknown peer, or `{ kind: "core" }`
to preserve core `dmScope` namespace analysis. For wildcard/open policy,
`principalId` is absent and an undefined result is reported as unverified.
Diagnostics never invent a peer ID. Keep both callbacks pure and
import-safe because read-only diagnostics run without channel runtime.
<Accordion title="What createChatChannelPlugin does for you">
Instead of implementing low-level adapter interfaces manually, you pass
declarative options and the builder composes them:
+1 -1
View File
@@ -51,7 +51,6 @@ export {
isBinaryContent,
normalizeForwardedContext,
resetTelegramForumFlagCacheForTest,
resolveTelegramDirectPeerId,
resolveTelegramForumFlag,
resolveTelegramForumThreadId,
resolveTelegramGroupAllowFromContext,
@@ -64,6 +63,7 @@ export {
type TelegramThreadSpec,
withResolvedTelegramForumFlag,
} from "./src/bot/helpers.js";
export { resolveTelegramDirectPeerId } from "./src/dm-session-key.js";
export {
normalizeTelegramCommandDescription,
normalizeTelegramCommandName,
@@ -7,7 +7,6 @@ import {
hasBotMention,
isBinaryContent,
normalizeForwardedContext,
resolveTelegramDirectPeerId,
resolveTelegramBotHasTopicsEnabled,
resolveTelegramForumFlag,
resolveTelegramForumThreadId,
@@ -216,20 +215,6 @@ describe("resolveTelegramBotHasTopicsEnabled", () => {
});
});
describe("resolveTelegramDirectPeerId", () => {
it("prefers sender id when available", () => {
expect(resolveTelegramDirectPeerId({ chatId: 777777777, senderId: 123456789 })).toBe(
"123456789",
);
});
it("falls back to chat id when sender id is missing", () => {
expect(resolveTelegramDirectPeerId({ chatId: 777777777, senderId: undefined })).toBe(
"777777777",
);
});
});
describe("normalizeForwardedContext", () => {
it("handles forward_origin users", () => {
const ctx = normalizeForwardedContext({
-20
View File
@@ -19,7 +19,6 @@ import {
resolveExpiresAtMsFromDurationMs,
} from "openclaw/plugin-sdk/number-runtime";
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { expandTelegramAllowFromWithAccessGroups } from "../access-groups.js";
import {
firstDefined,
@@ -546,25 +545,6 @@ export function buildTelegramGroupPeerId(chatId: number | string, messageThreadI
return messageThreadId != null ? `${chatId}:topic:${messageThreadId}` : String(chatId);
}
/**
* Resolve the direct-message peer identifier for Telegram routing/session keys.
*
* In some Telegram DM deliveries (for example certain business/chat bridge flows),
* `chat.id` can differ from the actual sender user id. Prefer sender id when present
* so per-peer DM scopes isolate users correctly.
*/
export function resolveTelegramDirectPeerId(params: {
chatId: number | string;
senderId?: number | string | null;
}) {
const senderId =
params.senderId != null ? (normalizeOptionalString(String(params.senderId)) ?? "") : "";
if (senderId) {
return senderId;
}
return String(params.chatId);
}
export function buildTelegramGroupFrom(chatId: number | string, messageThreadId?: number) {
return `telegram:group:${buildTelegramGroupPeerId(chatId, messageThreadId)}`;
}
+10 -40
View File
@@ -8,18 +8,17 @@ import {
import {
buildAgentSessionKey,
deriveLastRoutePolicy,
normalizeAccountId,
resolveAgentRoute,
} from "openclaw/plugin-sdk/routing";
import { buildAgentMainSessionKey, sanitizeAgentId } from "openclaw/plugin-sdk/routing";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
import { resolveDefaultTelegramAccountId } from "./accounts.js";
import { buildTelegramGroupPeerId, buildTelegramParentPeer } from "./bot/helpers.js";
import {
buildTelegramGroupPeerId,
buildTelegramParentPeer,
resolveTelegramDirectPeerId,
} from "./bot/helpers.js";
resolveTelegramNamedAccountBaseSessionKey,
} from "./dm-session-key.js";
type TelegramResolvedRoute = ReturnType<typeof resolveAgentRoute>;
type ConfiguredTelegramBinding = NonNullable<ConfiguredBindingRouteResult["bindingResolution"]>;
@@ -54,10 +53,7 @@ export function resolveTelegramConversationRoute(params: {
}): TelegramConversationRouteResult {
const peerId = params.isGroup
? buildTelegramGroupPeerId(params.chatId, params.resolvedThreadId)
: resolveTelegramDirectPeerId({
chatId: params.chatId,
senderId: params.senderId,
});
: resolveTelegramDirectPeerId({ chatId: params.chatId, senderId: params.senderId });
const parentPeer = buildTelegramParentPeer({
isGroup: params.isGroup,
resolvedThreadId: params.resolvedThreadId,
@@ -158,37 +154,11 @@ export function resolveTelegramConversationRoute(params: {
};
}
export function resolveTelegramConversationBaseSessionKey(params: {
cfg: OpenClawConfig;
route: Pick<
ReturnType<typeof resolveTelegramConversationRoute>["route"],
"agentId" | "accountId" | "matchedBy" | "sessionKey"
>;
chatId: number | string;
isGroup: boolean;
senderId?: string | number | null;
}): string {
const routeAccountId = normalizeAccountId(params.route.accountId);
const defaultAccountId = normalizeAccountId(resolveDefaultTelegramAccountId(params.cfg));
const isNamedAccountFallback =
routeAccountId !== defaultAccountId && params.route.matchedBy === "default";
if (!isNamedAccountFallback || params.isGroup) {
return params.route.sessionKey;
}
return normalizeLowercaseStringOrEmpty(
buildAgentSessionKey({
agentId: params.route.agentId,
channel: "telegram",
accountId: params.route.accountId,
peer: {
kind: "direct",
id: resolveTelegramDirectPeerId({
chatId: params.chatId,
senderId: params.senderId,
}),
},
dmScope: "per-account-channel-peer",
identityLinks: params.cfg.session?.identityLinks,
}),
export function resolveTelegramConversationBaseSessionKey(
params: Parameters<typeof resolveTelegramNamedAccountBaseSessionKey>[1],
): string {
return resolveTelegramNamedAccountBaseSessionKey(
resolveDefaultTelegramAccountId(params.cfg),
params,
);
}
@@ -0,0 +1,68 @@
import { describe, expect, it } from "vitest";
import { resolveTelegramDirectPeerId, resolveTelegramSecurityDmRoute } from "./dm-session-key.js";
describe("Telegram DM session keys", () => {
it("prefers sender id and falls back to chat id", () => {
expect(resolveTelegramDirectPeerId({ chatId: 777777777, senderId: 123456789 })).toBe(
"123456789",
);
expect(resolveTelegramDirectPeerId({ chatId: 777777777 })).toBe("777777777");
});
it.each([
{
name: "named-account default fallback",
accountId: "personal",
fallbackRoute: { dmScope: "main" as const, matchedBy: "default" as const },
expected: "isolated",
},
{
name: "default-account main scope",
accountId: "default",
fallbackRoute: { dmScope: "main" as const, matchedBy: "default" as const },
expected: "shared",
},
{
name: "named account with a winning binding",
accountId: "personal",
fallbackRoute: { dmScope: "main" as const, matchedBy: "binding.account" as const },
expected: "shared",
},
{
name: "account-isolated core scope",
accountId: "default",
fallbackRoute: {
dmScope: "per-account-channel-peer" as const,
matchedBy: "default" as const,
},
expected: "isolated",
},
{
name: "per-peer core namespace",
accountId: "default",
fallbackRoute: { dmScope: "per-peer" as const, matchedBy: "default" as const },
expected: "core",
},
{
name: "per-channel core namespace",
accountId: "default",
fallbackRoute: { dmScope: "per-channel-peer" as const, matchedBy: "default" as const },
expected: "core",
},
])("classifies $name as $expected", ({ accountId, fallbackRoute, expected }) => {
const result = resolveTelegramSecurityDmRoute("default", {
cfg: {},
accountId,
route: {
...fallbackRoute,
agentId: "main",
accountId,
channel: "telegram",
sessionKey: "agent:main:main",
mainSessionKey: "agent:main:main",
lastRoutePolicy: "main",
},
});
expect("kind" in result ? result.kind : "shared").toBe(expected);
});
});
+77
View File
@@ -0,0 +1,77 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import {
buildAgentSessionKey,
normalizeAccountId,
type ResolvedAgentRoute,
} from "openclaw/plugin-sdk/routing";
export function resolveTelegramDirectPeerId(params: {
chatId: number | string;
senderId?: number | string | null;
}) {
const normalized = params.senderId == null ? "" : String(params.senderId).trim();
return normalized || String(params.chatId);
}
export function resolveTelegramNamedAccountBaseSessionKey(
defaultAccountId: string,
params: {
cfg: OpenClawConfig;
route: Pick<ResolvedAgentRoute, "agentId" | "accountId" | "matchedBy" | "sessionKey">;
chatId: number | string;
isGroup: boolean;
senderId?: string | number | null;
},
): string {
const routeAccountId = normalizeAccountId(params.route.accountId);
const normalizedDefaultAccountId = normalizeAccountId(defaultAccountId);
const isNamedAccountFallback =
routeAccountId !== normalizedDefaultAccountId && params.route.matchedBy === "default";
if (!isNamedAccountFallback || params.isGroup) {
return params.route.sessionKey;
}
return buildAgentSessionKey({
agentId: params.route.agentId,
channel: "telegram",
accountId: params.route.accountId,
peer: {
kind: "direct",
id: resolveTelegramDirectPeerId({
chatId: params.chatId,
senderId: params.senderId,
}),
},
dmScope: "per-account-channel-peer",
identityLinks: params.cfg.session?.identityLinks,
});
}
export function resolveTelegramSecurityDmRoute(
defaultAccountId: string,
params: {
cfg: OpenClawConfig;
accountId: string;
route: ResolvedAgentRoute;
principalId?: string;
},
): { kind: "core" | "isolated" } | { sessionKey: string } {
if (params.principalId !== undefined) {
return {
sessionKey: resolveTelegramNamedAccountBaseSessionKey(defaultAccountId, {
...params,
chatId: params.principalId,
isGroup: false,
senderId: params.principalId,
}),
};
}
const isNamedAccountFallback =
normalizeAccountId(params.accountId) !== normalizeAccountId(defaultAccountId) &&
params.route.matchedBy === "default";
if (isNamedAccountFallback || params.route.dmScope === "per-account-channel-peer") {
return { kind: "isolated" };
}
return params.route.dmScope === "main"
? { sessionKey: params.route.sessionKey }
: { kind: "core" };
}
+6
View File
@@ -2,7 +2,9 @@
import { createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
import type { ChannelPlugin } from "openclaw/plugin-sdk/channel-core";
import { createAllowlistProviderRouteAllowlistWarningCollector } from "openclaw/plugin-sdk/channel-policy";
import { resolveDefaultTelegramAccountId } from "./account-selection.js";
import type { ResolvedTelegramAccount } from "./accounts.js";
import { resolveTelegramSecurityDmRoute } from "./dm-session-key.js";
import { collectTelegramSecurityAuditFindings } from "./security-audit.js";
const resolveTelegramDmPolicy = createScopedDmSecurityResolver<ResolvedTelegramAccount>({
@@ -36,6 +38,10 @@ const collectTelegramSecurityWarnings =
export const telegramSecurityAdapter = {
resolveDmPolicy: resolveTelegramDmPolicy,
dmRouting: {
resolveDmRoute: (ctx) =>
resolveTelegramSecurityDmRoute(resolveDefaultTelegramAccountId(ctx.cfg), ctx),
},
collectWarnings: collectTelegramSecurityWarnings,
collectAuditFindings: collectTelegramSecurityAuditFindings,
} satisfies NonNullable<ChannelPlugin<ResolvedTelegramAccount>["security"]>;
@@ -49,6 +49,7 @@ import {
parseZalouserOutboundTarget,
resolveZalouserOutboundSessionRoute,
} from "./session-route.js";
import { resolveZalouserDmSessionScope } from "./session-scope.js";
import type { ZaloSendResult } from "./types.js";
const loadZalouserChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime.js"));
@@ -435,6 +436,9 @@ export const zalouserAuthAdapter = {
export const zalouserSecurityAdapter = {
resolveDmPolicy: resolveZalouserDmPolicy,
dmRouting: {
resolveDmScope: ({ cfg }: { cfg: OpenClawConfig }) => resolveZalouserDmSessionScope(cfg),
},
collectAuditFindings: async (params: {
accountId?: string | null;
account: ResolvedZalouserAccount;
+4 -15
View File
@@ -1,8 +1,4 @@
/**
* Direct-message allowlist audit state.
*
* Merges configured and persisted allowFrom entries for setup/status prompts.
*/
/** Merges configured and persisted allowFrom entries for channel security audit. */
import { normalizeStringEntries } from "@openclaw/normalization-core/string-normalization";
import type { ChannelId } from "../plugins/types.public.js";
import { readChannelIngressStoreAllowFromForDmPolicy } from "./store-allow-from.js";
@@ -14,12 +10,7 @@ export async function resolveDmAllowAuditState(params: {
dmPolicy?: string | null;
normalizeEntry?: (raw: string) => string;
readStore?: (provider: ChannelId, accountId: string) => Promise<string[]>;
}): Promise<{
configAllowFrom: string[];
hasWildcard: boolean;
allowCount: number;
isMultiUserDm: boolean;
}> {
}) {
const configAllowFrom = normalizeStringEntries(
Array.isArray(params.allowFrom) ? params.allowFrom : undefined,
);
@@ -37,11 +28,9 @@ export async function resolveDmAllowAuditState(params: {
const normalizedStore = normalizeStringEntries(
storeAllowFrom.map((value) => normalizeEntry(value)),
);
const allowCount = new Set([...normalizedCfg, ...normalizedStore]).size;
const admittedPrincipals = Array.from(new Set([...normalizedCfg, ...normalizedStore]));
return {
configAllowFrom,
hasWildcard,
allowCount,
isMultiUserDm: hasWildcard || allowCount > 1,
admittedPrincipals,
};
}
+13
View File
@@ -6,6 +6,7 @@
import type { ReplyPayload } from "../../auto-reply/reply-payload.js";
import type { LegacyConfigRule } from "../../config/legacy.shared.js";
import type { AgentBinding } from "../../config/types.agents.js";
import type { DmScope } from "../../config/types.base.js";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import type { GroupToolPolicyConfig } from "../../config/types.tools.js";
import type { ChannelApprovalNativeRuntimeAdapter } from "../../infra/approval-handler-runtime-types.js";
@@ -15,6 +16,7 @@ import type {
PluginApprovalRequest,
PluginApprovalResolved,
} from "../../infra/plugin-approvals.js";
import type { ResolvedAgentRoute } from "../../routing/resolve-route.js";
import type { RuntimeEnv } from "../../runtime.js";
import type { ResolverContext, SecretDefaults } from "../../secrets/runtime-shared.js";
import type { SecretTargetRegistryEntry } from "../../secrets/target-registry-types.js";
@@ -810,6 +812,11 @@ export type ChannelConversationBindingSupport = {
}>;
};
type ChannelSecurityDmRouteContext<ResolvedAccount> = ChannelSecurityContext<ResolvedAccount> & {
accountId: string;
principalId?: string;
};
export type ChannelSecurityAdapter<ResolvedAccount = unknown> = {
applyConfigFixes?: (params: {
cfg: OpenClawConfig;
@@ -818,6 +825,12 @@ export type ChannelSecurityAdapter<ResolvedAccount = unknown> = {
resolveDmPolicy?: ChannelAdapterCallback<
(ctx: ChannelSecurityContext<ResolvedAccount>) => ChannelSecurityDmPolicy | null
>;
dmRouting?: {
resolveDmScope?: (ctx: ChannelSecurityDmRouteContext<ResolvedAccount>) => DmScope | undefined;
resolveDmRoute?: (
ctx: ChannelSecurityDmRouteContext<ResolvedAccount> & { route: ResolvedAgentRoute },
) => { kind: "core" | "isolated" } | { sessionKey: string } | undefined;
};
collectWarnings?: ChannelAdapterCallback<
(ctx: ChannelSecurityContext<ResolvedAccount>) => Promise<string[]> | string[]
>;
+25 -8
View File
@@ -271,25 +271,39 @@ describe("noteSecurityWarnings gateway exposure", () => {
expect(note).not.toHaveBeenCalled();
});
it("shows explicit dmScope config command for multi-user DMs", async () => {
it("renders the structured non-default-account DM collision guidance", async () => {
pluginRegistry.list = [
{
id: "test-channel",
meta: { label: "Test Channel" },
config: {
listAccountIds: () => ["default"],
inspectAccount: () => ({ enabled: true, configured: true }),
resolveAccount: () => ({}),
listAccountIds: () => ["default", "secondary"],
defaultAccountId: () => "default",
inspectAccount: (_cfg: OpenClawConfig, accountId: string) => ({
accountId,
enabled: true,
configured: true,
}),
resolveAccount: (_cfg: OpenClawConfig, accountId: string) => ({ accountId }),
isEnabled: () => true,
isConfigured: () => true,
},
security: {
resolveDmPolicy: () => ({
resolveDmPolicy: ({ accountId }: { accountId?: string | null }) => ({
policy: "allowlist",
allowFrom: ["alice", "bob"],
allowFromPath: "channels.whatsapp.",
allowFrom: accountId === "secondary" ? ["alice", "bob"] : ["owner"],
allowFromPath: `channels.test-channel.accounts.${accountId}.`,
approveHint: "approve",
}),
collectWarnings: () => ["- plugin warning remains visible"],
collectAuditFindings: () => [
{
checkId: "channels.test-channel.audit_only",
severity: "warn",
title: "audit-only plugin finding",
detail: "must not appear in Doctor",
},
],
},
},
];
@@ -300,7 +314,10 @@ describe("noteSecurityWarnings gateway exposure", () => {
includeSetupFallbackPlugins: true,
});
const message = lastMessage();
expect(message).toContain('config set session.dmScope "per-channel-peer"');
expect(message).toContain("matching binding or session.dmScope");
expect(message).toContain("secondary");
expect(message).toContain("plugin warning remains visible");
expect(message).not.toContain("audit-only plugin finding");
});
it("clarifies approvals.exec forwarding-only behavior", async () => {
+13 -104
View File
@@ -1,10 +1,7 @@
/** Security warnings for gateway exposure, exec policy drift, channel DMs, and plaintext secrets. */
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
import { note } from "../../packages/terminal-core/src/note.js";
import { resolveDefaultChannelAccountContext } from "../channels/account-context.js";
import { resolveDmAllowAuditState } from "../channels/message-access/dm-allow-state.js";
import { listReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js";
import type { ChannelId } from "../channels/plugins/types.public.js";
import { formatCliCommand } from "../cli/command-format.js";
import type { OpenClawConfig, GatewayBindMode } from "../config/config.js";
import type { AgentConfig } from "../config/types.agents.js";
@@ -23,6 +20,7 @@ import {
import { isLikelySensitiveModelProviderHeaderName } from "../secrets/model-provider-header-policy.js";
import { hasConfiguredPlaintextSecretValue } from "../secrets/secret-value.js";
import { discoverConfigSecretTargets } from "../secrets/target-registry.js";
import { collectChannelSecurityFindings } from "../security/audit-channel.js";
import { collectExecFilesystemPolicyDriftHits } from "../security/exec-filesystem-policy.js";
function collectImplicitHeartbeatDirectPolicyWarnings(cfg: OpenClawConfig): string[] {
@@ -342,107 +340,18 @@ export async function collectSecurityWarnings(
warnings.push(...tokenConflict.warningLines);
}
const warnDmPolicy = async (params: {
label: string;
provider: ChannelId;
accountId: string;
dmPolicy: string;
allowFrom?: Array<string | number> | null;
policyPath?: string;
allowFromPath: string;
approveHint: string;
normalizeEntry?: (raw: string) => string;
}) => {
const dmPolicy = params.dmPolicy;
const policyPath = params.policyPath ?? `${params.allowFromPath}policy`;
const { hasWildcard, allowCount, isMultiUserDm } = await resolveDmAllowAuditState({
provider: params.provider,
accountId: params.accountId,
allowFrom: params.allowFrom,
dmPolicy,
normalizeEntry: params.normalizeEntry,
});
const dmScope = cfg.session?.dmScope ?? "main";
if (dmPolicy === "open") {
const allowFromPath = `${params.allowFromPath}allowFrom`;
warnings.push(`- ${params.label} DMs: OPEN (${policyPath}="open"). Anyone can DM it.`);
if (!hasWildcard) {
warnings.push(
`- ${params.label} DMs: config invalid — "open" requires ${allowFromPath} to include "*".`,
);
}
}
if (dmPolicy === "disabled") {
warnings.push(`- ${params.label} DMs: disabled (${policyPath}="disabled").`);
return;
}
if (dmPolicy !== "open" && allowCount === 0) {
warnings.push(
`- ${params.label} DMs: locked (${policyPath}="${dmPolicy}") with no allowlist; unknown senders will be blocked / get a pairing code.`,
);
warnings.push(` ${params.approveHint}`);
}
if (dmScope === "main" && isMultiUserDm) {
warnings.push(
`- ${params.label} DMs: multiple senders share the main session; run: ` +
formatCliCommand('openclaw config set session.dmScope "per-channel-peer"') +
' (or "per-account-channel-peer" for multi-account channels) to isolate sessions.',
);
}
};
for (const plugin of listReadOnlyChannelPluginsForConfig(cfg, {
includePersistedAuthState: true,
includeSetupFallbackPlugins: true,
})) {
if (!plugin.security) {
continue;
}
const { defaultAccountId, account, enabled, configured, diagnostics } =
await resolveDefaultChannelAccountContext(plugin, cfg, {
mode: "read_only",
commandName: "doctor",
});
for (const diagnostic of diagnostics) {
warnings.push(`- [secrets] ${diagnostic}`);
}
if (!enabled) {
continue;
}
if (!configured) {
continue;
}
const dmPolicy = plugin.security.resolveDmPolicy?.({
cfg,
accountId: defaultAccountId,
account,
});
if (dmPolicy) {
await warnDmPolicy({
label: plugin.meta.label ?? plugin.id,
provider: plugin.id,
accountId: defaultAccountId,
dmPolicy: dmPolicy.policy,
allowFrom: dmPolicy.allowFrom,
policyPath: dmPolicy.policyPath,
allowFromPath: dmPolicy.allowFromPath,
approveHint: dmPolicy.approveHint,
normalizeEntry: dmPolicy.normalizeEntry,
});
}
if (plugin.security.collectWarnings) {
const extra = await plugin.security.collectWarnings({
cfg,
accountId: defaultAccountId,
account,
});
if (extra?.length) {
warnings.push(...extra);
}
const channelFindings = await collectChannelSecurityFindings({
cfg,
mode: "doctor",
plugins: listReadOnlyChannelPluginsForConfig(cfg, {
includePersistedAuthState: true,
includeSetupFallbackPlugins: true,
}),
});
for (const finding of channelFindings) {
warnings.push(`- ${finding.title}: ${finding.detail}`);
if (finding.remediation) {
warnings.push(` ${finding.remediation}`);
}
}
return warnings;
+7
View File
@@ -49,6 +49,10 @@ describe("mutable allowlist table helpers", () => {
describe("createRestrictSendersChannelSecurity", () => {
it("builds dm policy resolution and open-group warnings from one descriptor", () => {
const dmRouting = {
resolveDmScope: () => "per-peer" as const,
resolveDmRoute: () => ({ kind: "core" as const }),
};
const security = createRestrictSendersChannelSecurity<{
accountId: string;
allowFrom?: string[];
@@ -65,8 +69,11 @@ describe("createRestrictSendersChannelSecurity", () => {
groupAllowFromPath: "channels.line.groupAllowFrom",
mentionGated: false,
policyPathSuffix: "dmPolicy",
dmRouting,
});
expect(security.dmRouting).toBe(dmRouting);
expect(
security.resolveDmPolicy?.({
cfg: { channels: {} } as never,
+2
View File
@@ -306,6 +306,7 @@ export function createRestrictSendersChannelSecurity<
normalizeDmEntry?: (raw: string) => string;
/** Allows non-default accounts to inherit shared defaults from the default account. */
inheritSharedDefaultsFromDefaultAccount?: boolean;
dmRouting?: ChannelSecurityAdapter<ResolvedAccount>["dmRouting"];
}): ChannelSecurityAdapter<ResolvedAccount> {
return {
resolveDmPolicy: createScopedDmSecurityResolver<ResolvedAccount>({
@@ -321,6 +322,7 @@ export function createRestrictSendersChannelSecurity<
normalizeEntry: params.normalizeDmEntry,
inheritSharedDefaultsFromDefaultAccount: params.inheritSharedDefaultsFromDefaultAccount,
}),
...(params.dmRouting ? { dmRouting: params.dmRouting } : {}),
collectWarnings: createAllowlistProviderRestrictSendersWarningCollector<ResolvedAccount>({
providerConfigPresent:
params.providerConfigPresent ?? ((cfg) => cfg.channels?.[params.channelKey] !== undefined),
+20
View File
@@ -183,6 +183,26 @@ describe("createChannelPluginBase", () => {
});
describe("createChatChannelPlugin", () => {
it("preserves DM routing through the declarative security shorthand", () => {
const dmRouting = {
resolveDmScope: () => "per-peer" as const,
resolveDmRoute: () => ({ kind: "core" as const }),
};
const plugin = createChatChannelPlugin({
base: createChannelPlugin("security-routing") as ChannelPlugin<{ accountId: string }>,
security: {
dm: {
channelKey: "security-routing",
resolvePolicy: () => "allowlist",
resolveAllowFrom: () => [],
},
dmRouting,
},
});
expect(plugin.security?.dmRouting).toBe(dmRouting);
});
it("preserves account-scoped current-conversation binding support", () => {
const conversationBindings: NonNullable<ChannelPlugin["conversationBindings"]> = {
isCurrentConversationBindingSupported: ({ accountId }) => accountId !== "enterprise",
+2
View File
@@ -650,6 +650,7 @@ type ChatChannelSecurityOptions<TResolvedAccount extends { accountId?: string |
normalizeEntry?: (raw: string) => string;
inheritSharedDefaultsFromDefaultAccount?: boolean;
};
dmRouting?: ChannelSecurityAdapter<TResolvedAccount>["dmRouting"];
collectWarnings?: ChannelSecurityAdapter<TResolvedAccount>["collectWarnings"];
collectAuditFindings?: ChannelSecurityAdapter<TResolvedAccount>["collectAuditFindings"];
};
@@ -760,6 +761,7 @@ function resolveChatChannelSecurity<TResolvedAccount extends { accountId?: strin
inheritSharedDefaultsFromDefaultAccount:
security.dm.inheritSharedDefaultsFromDefaultAccount,
}),
...(security.dmRouting ? { dmRouting: security.dmRouting } : {}),
...(security.collectWarnings ? { collectWarnings: security.collectWarnings } : {}),
...(security.collectAuditFindings
? { collectAuditFindings: security.collectAuditFindings }
+78
View File
@@ -5,8 +5,10 @@ import type { OpenClawConfig } from "../config/config.js";
import * as routingBindings from "./bindings.js";
import {
deriveLastRoutePolicy,
listExactDirectMessageBindingPeerIds,
resolveAgentRoute,
resolveInboundLastRouteSessionKey,
resolveUnknownDirectMessageRoute,
} from "./resolve-route.js";
type ResolvedRouteExpectation = {
@@ -1130,6 +1132,82 @@ describe("role-based agent routing", () => {
});
});
describe("unknown direct-message route decisions", () => {
test("lists unique exact peers from normalized account and any-account bindings", () => {
const binding = (peerId: string, accountId: string, kind: "direct" | "group" = "direct") => ({
agentId: "main",
match: { channel: "Telegram", accountId, peer: { kind, id: peerId } },
});
const cfg = {
bindings: [
binding("peer-b", "*"),
binding("peer-a", " WORK "),
binding("peer-b", "work"),
binding("*", "work"),
binding("room", "work", "group"),
binding("other", "other"),
],
} satisfies OpenClawConfig;
expect(
listExactDirectMessageBindingPeerIds({ cfg, channel: " telegram ", accountId: " work " }),
).toEqual(["peer-b", "peer-a"]);
});
test.each([
{
name: "direct wildcard outranks account and channel",
wildcard: true,
account: true,
expectedMatchedBy: "binding.peer.wildcard",
},
{
name: "account outranks channel when no wildcard exists",
wildcard: false,
account: true,
expectedMatchedBy: "binding.account",
},
{
name: "channel matches when no narrower fallback exists",
wildcard: false,
account: false,
expectedMatchedBy: "binding.channel",
},
] as const)("$name", ({ wildcard, account, expectedMatchedBy }) => {
const bindings: NonNullable<OpenClawConfig["bindings"]> = [
{
agentId: "exact",
match: { channel: "telegram", peer: { kind: "direct", id: "known-user" } },
},
];
if (wildcard) {
bindings.push({
agentId: "wildcard",
match: { channel: "telegram", peer: { kind: "direct", id: "*" } },
});
}
if (account) {
bindings.push({
agentId: "account",
match: { channel: "telegram" },
});
}
bindings.push({
agentId: "channel",
match: { channel: "telegram", accountId: "*" },
});
const route = resolveUnknownDirectMessageRoute({
cfg: { bindings },
channel: "telegram",
accountId: "default",
});
expect(route.matchedBy).toBe(expectedMatchedBy);
expect(route.agentId).not.toBe("exact");
});
});
describe("wildcard peer bindings (peer.id=*)", () => {
test("peer.id=* matches any direct peer and routes to the bound agent", () => {
const cfg: OpenClawConfig = {
+21
View File
@@ -466,6 +466,20 @@ function getEvaluatedBindingIndexForChannelAccount(
return built;
}
/** @internal Lists exact DM peers from the canonical channel/account binding index. */
export function listExactDirectMessageBindingPeerIds(
input: Pick<ResolveAgentRouteInput, "cfg" | "channel" | "accountId">,
): string[] {
const prefix = "direct:";
return [
...getEvaluatedBindingIndexForChannelAccount(
input.cfg,
normalizeLowercaseStringOrEmpty(input.channel),
normalizeAccountId(input.accountId),
).byPeer.keys(),
].flatMap((key) => (key.startsWith(prefix) ? [key.slice(prefix.length)] : []));
}
function normalizePeerConstraint(
peer: { kind?: string; id?: string } | undefined,
): NormalizedPeerConstraint {
@@ -773,4 +787,11 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
return choose(resolveDefaultAgentId(input.cfg), "default");
}
/** @internal Resolves fallback precedence for an unknown direct peer. */
export function resolveUnknownDirectMessageRoute(
input: Pick<ResolveAgentRouteInput, "cfg" | "channel" | "accountId" | "dmScope">,
): ResolvedAgentRoute {
return resolveAgentRoute({ ...input, peer: { kind: "direct", id: "" } });
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+3 -2
View File
@@ -226,7 +226,7 @@ export function buildAgentPeerSessionKey(params: {
const linkedPeerId =
dmScope === "main"
? null
: resolveLinkedPeerId({
: resolveLinkedDirectPeerId({
identityLinks: params.identityLinks,
channel: params.channel,
peerId,
@@ -262,7 +262,8 @@ export function buildAgentPeerSessionKey(params: {
return `agent:${normalizeAgentId(params.agentId)}:${channel}:${peerKind}:${peerId}`;
}
function resolveLinkedPeerId(params: {
/** @internal Resolves a declared cross-channel identity for one direct peer. */
export function resolveLinkedDirectPeerId(params: {
identityLinks?: Record<string, string[]>;
channel: string;
peerId: string;
+485 -87
View File
@@ -1,5 +1,5 @@
// Covers direct-message policy audit findings for channels.
import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";
import type { ChannelPlugin } from "../channels/plugins/types.public.js";
import type { OpenClawConfig } from "../config/config.js";
import { collectChannelSecurityFindings } from "./audit-channel.js";
@@ -17,104 +17,502 @@ function requireFinding(
return finding;
}
describe("security audit channel dm policy", () => {
it("warns when multiple DM senders share the main session", async () => {
const cfg: OpenClawConfig = {
session: { dmScope: "main" },
channels: { whatsapp: { enabled: true } },
};
const plugins: ChannelPlugin[] = [
{
id: "whatsapp",
meta: {
id: "whatsapp",
label: "WhatsApp",
selectionLabel: "WhatsApp",
docsPath: "/channels/whatsapp",
blurb: "Test",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => ["default"],
inspectAccount: () => ({ enabled: true, configured: true }),
resolveAccount: () => ({}),
isEnabled: () => true,
isConfigured: () => true,
},
security: {
resolveDmPolicy: () => ({
policy: "allowlist",
allowFrom: ["user-a", "user-b"],
policyPath: "channels.whatsapp.dmPolicy",
allowFromPath: "channels.whatsapp.",
approveHint: "approve",
}),
},
},
];
function collisionFindings(findings: ChannelSecurityFinding[]): ChannelSecurityFinding[] {
return findings.filter((finding) => finding.checkId.includes(".dm.session_collision."));
}
function createDmPlugin(
params: {
id?: "telegram" | "whatsapp";
accounts?: Record<string, { policy?: string; allowFrom: Array<string | number> }>;
dmRouting?: NonNullable<ChannelPlugin["security"]>["dmRouting"];
} = {},
): ChannelPlugin {
const id = params.id ?? "whatsapp";
const accounts = params.accounts ?? {
default: { policy: "allowlist", allowFrom: ["user-a", "user-b"] },
};
const accountIds = Object.keys(accounts);
const security: NonNullable<ChannelPlugin["security"]> = {
resolveDmPolicy: ({ accountId }: { accountId?: string | null }) => {
const resolvedAccountId = accountId ?? "default";
const policy = accounts[resolvedAccountId];
return policy
? {
policy: policy.policy ?? "allowlist",
allowFrom: policy.allowFrom,
policyPath: `channels.${id}.accounts.${resolvedAccountId}.dmPolicy`,
allowFromPath: `channels.${id}.accounts.${resolvedAccountId}.`,
approveHint: `approve ${resolvedAccountId}`,
}
: null;
},
...(params.dmRouting ? { dmRouting: params.dmRouting } : {}),
};
const label = id === "telegram" ? "Telegram" : "WhatsApp";
return {
id,
meta: {
id,
label,
selectionLabel: label,
docsPath: `/channels/${id}`,
blurb: "Test",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => accountIds,
defaultAccountId: () => accountIds[0] ?? "default",
inspectAccount: (_cfg, accountId) => ({
accountId: accountId ?? "default",
enabled: true,
configured: true,
}),
resolveAccount: (_cfg, accountId) => ({ accountId: accountId ?? "default" }),
isEnabled: () => true,
isConfigured: () => true,
},
security,
};
}
describe("security audit channel dm policy", () => {
it.each([
{
name: "global main + winning isolated binding is safe",
cfg: {
session: { dmScope: "main" },
bindings: [
{
agentId: "main",
match: { channel: "whatsapp", peer: { kind: "direct", id: "*" } },
session: { dmScope: "per-channel-peer" },
},
],
} satisfies OpenClawConfig,
expectedCollisions: 0,
},
{
name: "global isolated + winning main binding collides",
cfg: {
session: { dmScope: "per-channel-peer" },
bindings: [
{
agentId: "main",
match: { channel: "whatsapp", peer: { kind: "direct", id: "*" } },
session: { dmScope: "main" },
},
],
} satisfies OpenClawConfig,
expectedCollisions: 1,
remediation: "matching binding or session.dmScope",
},
{
name: "exact peer bindings outrank a colliding channel binding",
cfg: {
session: { dmScope: "main" },
bindings: [
{
agentId: "main",
match: { channel: "whatsapp" },
session: { dmScope: "main" },
},
{
agentId: "main",
match: { channel: "whatsapp", peer: { kind: "direct", id: "user-a" } },
session: { dmScope: "per-channel-peer" },
},
{
agentId: "main",
match: { channel: "whatsapp", peer: { kind: "direct", id: "user-b" } },
session: { dmScope: "per-channel-peer" },
},
],
} satisfies OpenClawConfig,
expectedCollisions: 0,
},
{
name: "global session aliases remain isolated by routed agent store",
cfg: {
agents: { list: [{ id: "agent-a" }, { id: "agent-b", default: true }] },
session: { scope: "global", dmScope: "main" },
bindings: [
{
agentId: "agent-a",
match: { channel: "whatsapp", peer: { kind: "direct", id: "user-a" } },
},
{
agentId: "agent-b",
match: { channel: "whatsapp", peer: { kind: "direct", id: "user-b" } },
},
],
} satisfies OpenClawConfig,
expectedCollisions: 0,
},
])("$name", async ({ cfg, expectedCollisions, remediation }) => {
const findings = await collectChannelSecurityFindings({
cfg,
plugins,
plugins: [createDmPlugin()],
});
const sharedScopeFinding = requireFinding(
findings,
"channels.whatsapp.dm.scope_main_multiuser",
);
expect(sharedScopeFinding.severity).toBe("warn");
expect(sharedScopeFinding.remediation).toContain(
'config set session.dmScope "per-channel-peer"',
);
const collisions = collisionFindings(findings);
expect(collisions).toHaveLength(expectedCollisions);
if (remediation) {
expect(collisions[0]?.remediation).toContain(remediation);
}
});
it("flags public DMs and shared main-session scope together", async () => {
const cfg: OpenClawConfig = {
session: { dmScope: "main" },
channels: { telegram: { enabled: true } },
};
const plugins: ChannelPlugin[] = [
{
id: "telegram",
meta: {
id: "telegram",
label: "Telegram",
selectionLabel: "Telegram",
docsPath: "/channels/telegram",
blurb: "Test",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => ["default"],
inspectAccount: () => ({ enabled: true, configured: true }),
resolveAccount: () => ({}),
isEnabled: () => true,
isConfigured: () => true,
},
security: {
resolveDmPolicy: () => ({
policy: "open",
allowFrom: ["*"],
policyPath: "channels.telegram.dmPolicy",
allowFromPath: "channels.telegram.",
approveHint: "approve",
}),
},
},
];
it("detects cross-account collisions with one admitted sender per account", async () => {
const findings = await collectChannelSecurityFindings({
cfg,
plugins,
cfg: { session: { dmScope: "main" } },
plugins: [
createDmPlugin({
accounts: {
"Personal Account": { allowFrom: ["user-a"] },
"work@example": { allowFrom: ["user-b"] },
},
}),
],
});
const openDmFinding = requireFinding(findings, "channels.telegram.dm.open");
expect(openDmFinding.severity).toBe("critical");
const collisions = collisionFindings(findings);
expect(collisions).toHaveLength(1);
expect(collisions[0]?.checkId).toContain("whatsapp-personal-account_whatsapp-work-example");
expect(collisions[0]?.checkId).toMatch(/^[a-z0-9._-]+$/);
expect(collisions[0]?.detail).toContain("personal-account");
expect(collisions[0]?.detail).toContain("work-example");
});
const sharedScopeFinding = requireFinding(
it("keeps same-named accounts attributed across channels", async () => {
const findings = await collectChannelSecurityFindings({
cfg: { session: { dmScope: "main" } },
plugins: [
createDmPlugin({ accounts: { default: { allowFrom: ["user-a"] } } }),
createDmPlugin({
id: "telegram",
accounts: { default: { allowFrom: ["user-b"] } },
}),
],
});
const collision = collisionFindings(findings)[0];
expect(collision?.checkId).toContain("telegram-default_whatsapp-default");
expect(collision?.detail).toContain("telegram-default, whatsapp-default");
});
it("counts identity-linked aliases as one logical principal", async () => {
const cfg: OpenClawConfig = {
session: {
dmScope: "main",
identityLinks: { alice: ["whatsapp:user-a", "whatsapp:user-b"] },
},
};
const plugin = createDmPlugin();
const linkedFindings = await collectChannelSecurityFindings({ cfg, plugins: [plugin] });
const distinctFindings = await collectChannelSecurityFindings({
cfg: { session: { dmScope: "main" } },
plugins: [plugin],
});
expect(collisionFindings(linkedFindings)).toHaveLength(0);
expect(collisionFindings(distinctFindings)).toHaveLength(1);
});
it("keeps separate collision topologies distinct", async () => {
const findings = await collectChannelSecurityFindings({
cfg: {
agents: { list: [{ id: "alpha", default: true }, { id: "beta" }] },
session: { dmScope: "main" },
bindings: [
{ agentId: "alpha", match: { channel: "whatsapp", accountId: "a" } },
{ agentId: "alpha", match: { channel: "whatsapp", accountId: "b" } },
{ agentId: "beta", match: { channel: "whatsapp", accountId: "c" } },
{ agentId: "beta", match: { channel: "whatsapp", accountId: "d" } },
],
},
plugins: [
createDmPlugin({
accounts: {
a: { allowFrom: ["user-a"] },
b: { allowFrom: ["user-b"] },
c: { allowFrom: ["user-c"] },
d: { allowFrom: ["user-d"] },
},
}),
],
});
const collisions = collisionFindings(findings);
expect(collisions).toHaveLength(2);
expect(new Set(collisions.map((finding) => finding.checkId)).size).toBe(2);
expect(new Set(collisions.map((finding) => finding.detail)).size).toBe(2);
});
it("uses the channel-owned DM route for wildcard senders", async () => {
const findings = await collectChannelSecurityFindings({
cfg: { session: { dmScope: "main" } },
plugins: [
createDmPlugin({
accounts: { default: { policy: "open", allowFrom: ["*"] } },
dmRouting: { resolveDmScope: () => "per-channel-peer" },
}),
],
});
expect(collisionFindings(findings)).toHaveLength(0);
});
it.each([
{
name: "per-channel-peer collides across accounts",
dmScope: "per-channel-peer" as const,
plugins: () => [
createDmPlugin({
accounts: {
personal: { policy: "open", allowFrom: ["*"] },
work: { policy: "open", allowFrom: ["*"] },
},
}),
],
expectedCollisions: 1,
},
{
name: "per-peer collides across channels",
dmScope: "per-peer" as const,
plugins: () => [
createDmPlugin({ accounts: { default: { policy: "open", allowFrom: ["*"] } } }),
createDmPlugin({
id: "telegram",
accounts: { default: { policy: "open", allowFrom: ["*"] } },
}),
],
expectedCollisions: 1,
},
{
name: "per-account-channel-peer stays isolated",
dmScope: "per-account-channel-peer" as const,
plugins: () => [
createDmPlugin({
accounts: {
personal: { policy: "open", allowFrom: ["*"] },
work: { policy: "open", allowFrom: ["*"] },
},
}),
],
expectedCollisions: 0,
},
])("models wildcard namespace: $name", async ({ dmScope, plugins, expectedCollisions }) => {
const findings = await collectChannelSecurityFindings({
cfg: { session: { dmScope } },
plugins: plugins(),
});
const collisions = collisionFindings(findings);
expect(collisions).toHaveLength(expectedCollisions);
if (expectedCollisions > 0) {
expect(collisions[0]?.detail).toContain("can resolve to the same session bucket");
}
});
it.each([
{
name: "per-channel wildcard intersects a concrete sender on the same channel",
cfg: { session: { dmScope: "per-channel-peer" as const } },
plugins: [
createDmPlugin({
accounts: {
open: { policy: "open", allowFrom: ["*"] },
finite: { allowFrom: ["user-b"] },
},
dmRouting: {
resolveDmRoute: ({ principalId }) =>
principalId === undefined ? { kind: "core" } : undefined,
},
}),
],
expectedCollisions: 1,
},
{
name: "per-peer wildcard intersects a concrete sender on another channel",
cfg: { session: { dmScope: "per-peer" as const } },
plugins: [
createDmPlugin({ accounts: { open: { policy: "open", allowFrom: ["*"] } } }),
createDmPlugin({
id: "telegram",
accounts: { finite: { allowFrom: ["user-b"] } },
}),
],
expectedCollisions: 1,
},
{
name: "per-channel wildcards on different channels stay separate",
cfg: { session: { dmScope: "per-channel-peer" as const } },
plugins: [
createDmPlugin({ accounts: { open: { policy: "open", allowFrom: ["*"] } } }),
createDmPlugin({
id: "telegram",
accounts: { open: { policy: "open", allowFrom: ["*"] } },
}),
],
expectedCollisions: 0,
},
{
name: "per-peer wildcard subsumes an overlapping per-channel wildcard",
cfg: {},
plugins: [
createDmPlugin({
accounts: { open: { policy: "open", allowFrom: ["*"] } },
dmRouting: { resolveDmScope: () => "per-peer" },
}),
createDmPlugin({
id: "telegram",
accounts: { open: { policy: "open", allowFrom: ["*"] } },
dmRouting: { resolveDmScope: () => "per-channel-peer" },
}),
],
expectedCollisions: 1,
},
])("intersects wildcard namespace: $name", async ({ cfg, plugins, expectedCollisions }) => {
const findings = await collectChannelSecurityFindings({ cfg, plugins });
const collisions = collisionFindings(findings);
expect(collisions).toHaveLength(expectedCollisions);
for (const collision of collisions) {
expect(collision.title).toContain("may share");
expect(collision.detail).toContain("can resolve to the same session bucket");
}
});
it("does not let exact bindings on finite probe strings hide an open-DM collision", async () => {
const findings = await collectChannelSecurityFindings({
cfg: {
session: { dmScope: "main" },
bindings: [
{
agentId: "main",
match: {
channel: "whatsapp",
peer: { kind: "direct", id: "__openclaw_audit_unmatched_dm_1__" },
},
session: { dmScope: "per-channel-peer" },
},
{
agentId: "main",
match: {
channel: "whatsapp",
peer: { kind: "direct", id: "__openclaw_audit_unmatched_dm_2__" },
},
session: { dmScope: "per-channel-peer" },
},
],
},
plugins: [
createDmPlugin({
accounts: { default: { policy: "open", allowFrom: ["*"] } },
}),
],
});
expect(collisionFindings(findings)).toHaveLength(1);
});
it("audits exact DM bindings admitted by wildcard policy", async () => {
const findings = await collectChannelSecurityFindings({
cfg: {
session: { dmScope: "per-account-channel-peer" },
bindings: [
{
agentId: "main",
match: {
channel: "whatsapp",
accountId: "*",
peer: { kind: "direct", id: "bound-a" },
},
session: { dmScope: "main" },
},
{
agentId: "main",
match: {
channel: "whatsapp",
accountId: " WORK ",
peer: { kind: "direct", id: "bound-b" },
},
session: { dmScope: "main" },
},
],
},
plugins: [
createDmPlugin({
accounts: { work: { policy: "open", allowFrom: ["*"] } },
}),
],
});
const collisions = collisionFindings(findings);
expect(collisions).toHaveLength(1);
expect(collisions[0]?.title).toBe("DM principals share a session");
expect(collisions[0]?.detail).toContain("2 distinct admitted DM principals");
});
it("does not invoke finite session routing for wildcard analysis", async () => {
const resolveDmRoute = vi.fn(({ principalId, route }) => {
if (principalId === undefined) {
return { kind: "isolated" as const };
}
if (!/^\d+$/.test(principalId)) {
throw new Error("principal must be numeric");
}
return { sessionKey: route.sessionKey };
});
const findings = await collectChannelSecurityFindings({
cfg: { session: { dmScope: "main" } },
plugins: [
createDmPlugin({
accounts: { default: { policy: "open", allowFrom: ["*"] } },
dmRouting: { resolveDmRoute },
}),
],
});
expect(resolveDmRoute).toHaveBeenCalledOnce();
expect(resolveDmRoute.mock.calls[0]?.[0].principalId).toBeUndefined();
expect(collisionFindings(findings)).toHaveLength(0);
});
it("warns when custom finite routing omits an unknown-principal policy", async () => {
const findings = await collectChannelSecurityFindings({
cfg: { session: { dmScope: "main" } },
plugins: [
createDmPlugin({
accounts: { default: { policy: "open", allowFrom: ["*"] } },
dmRouting: {
resolveDmRoute: ({ principalId, route }) =>
principalId === undefined ? undefined : { sessionKey: route.sessionKey },
},
}),
],
});
const finding = requireFinding(
findings,
"channels.telegram.dm.scope_main_multiuser",
"channels.whatsapp.dm.wildcard_routing_unverified.default",
);
expect(sharedScopeFinding.severity).toBe("warn");
expect(finding.detail).toContain("resolveDmRoute returned no unknown-principal policy");
});
it("flags public DMs and shared session ownership together", async () => {
const findings = await collectChannelSecurityFindings({
cfg: { session: { dmScope: "main" } },
plugins: [
createDmPlugin({
accounts: { default: { policy: "open", allowFrom: ["*"] } },
}),
],
});
expect(requireFinding(findings, "channels.whatsapp.dm.open").severity).toBe("critical");
expect(collisionFindings(findings)).toHaveLength(1);
});
});
+216 -24
View File
@@ -1,3 +1,4 @@
import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce";
// Audits channel configuration for exposure, auth, and trust risks.
import { uniqueStrings } from "@openclaw/normalization-core/string-normalization";
import {
@@ -9,12 +10,25 @@ import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
import type { ChannelPlugin } from "../channels/plugins/types.plugin.js";
import type { ChannelId } from "../channels/plugins/types.public.js";
import { inspectReadOnlyChannelAccount } from "../channels/read-only-account-inspect.js";
import { formatCliCommand } from "../cli/command-format.js";
import { isDangerousNameMatchingEnabled } from "../config/dangerous-name-matching.js";
import { canonicalizeMainSessionAlias } from "../config/sessions/main-session.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { formatErrorMessage } from "../infra/errors.js";
import {
listExactDirectMessageBindingPeerIds,
resolveAgentRoute,
resolveUnknownDirectMessageRoute,
type ResolvedAgentRoute,
} from "../routing/resolve-route.js";
import { parseSessionDeliveryRoute, resolveLinkedDirectPeerId } from "../routing/session-key.js";
import type { SecurityAuditFinding, SecurityAuditSeverity } from "./audit.types.js";
type DmPrincipalRoute = {
accountKey: string;
logicalPrincipalKey: string;
bucketKey: string;
};
/** Classify free-form channel warnings into audit severities. */
function classifyChannelWarningSeverity(message: string): SecurityAuditSeverity {
const s = message.toLowerCase();
@@ -85,9 +99,46 @@ export async function collectChannelSecurityFindings(params: {
cfg: OpenClawConfig;
sourceConfig?: OpenClawConfig;
plugins: ChannelPlugin[];
mode?: "audit" | "doctor";
}): Promise<SecurityAuditFinding[]> {
const findings: SecurityAuditFinding[] = [];
const principalRoutes: DmPrincipalRoute[] = [];
const sourceConfig = params.sourceConfig ?? params.cfg;
const includeAuditOnly = params.mode !== "doctor";
const recordPrincipal = (
plugin: ChannelPlugin,
route: ResolvedAgentRoute,
sessionKey: string,
logicalPrincipalKey: string,
indexNamespaces = false,
) => {
const canonicalKey = canonicalizeMainSessionAlias({
cfg: params.cfg,
agentId: route.agentId,
sessionKey,
});
const principal = {
accountKey: `${plugin.id}-${route.accountId}`,
logicalPrincipalKey,
bucketKey: `${route.agentId}\0${canonicalKey}`,
};
principalRoutes.push(principal);
if (!indexNamespaces) {
return;
}
const parsed = parseSessionDeliveryRoute(canonicalKey);
const directChannel =
parsed?.peerKind === "direct" || parsed?.peerKind === "dm" ? parsed.channel : undefined;
if (directChannel || (sessionKey === route.sessionKey && route.dmScope === "per-peer")) {
principalRoutes.push({ ...principal, bucketKey: `${route.agentId}\0symbolic:dm:peer` });
}
if (directChannel) {
principalRoutes.push({
...principal,
bucketKey: `${route.agentId}\0symbolic:dm:channel:${directChannel}`,
});
}
};
const inspectChannelAccount = async (
plugin: (typeof params.plugins)[number],
@@ -210,19 +261,20 @@ export async function collectChannelSecurityFindings(params: {
allowFrom?: Array<string | number> | null;
policyPath?: string;
allowFromPath: string;
approveHint: string;
normalizeEntry?: (raw: string) => string;
}) => {
const policyPath = input.policyPath ?? `${input.allowFromPath}policy`;
// DM allowlist audit may need channel-specific normalization and async
// account ownership checks before classifying open/multi-user exposure.
const { hasWildcard, isMultiUserDm } = await resolveDmAllowAuditState({
const auditState = await resolveDmAllowAuditState({
provider: input.provider,
accountId: input.accountId,
allowFrom: input.allowFrom,
dmPolicy: input.dmPolicy,
normalizeEntry: input.normalizeEntry,
});
const dmScope = params.cfg.session?.dmScope ?? "main";
const { hasWildcard } = auditState;
if (input.dmPolicy === "open") {
const allowFromKey = `${input.allowFromPath}allowFrom`;
@@ -250,22 +302,19 @@ export async function collectChannelSecurityFindings(params: {
title: `${input.label} DMs are disabled`,
detail: `${policyPath}="disabled" ignores inbound DMs.`,
});
return;
return auditState;
}
if (dmScope === "main" && isMultiUserDm) {
if (input.dmPolicy !== "open" && auditState.admittedPrincipals.length === 0) {
findings.push({
checkId: `channels.${input.provider}.dm.scope_main_multiuser`,
severity: "warn",
title: `${input.label} DMs share the main session`,
detail:
"Multiple DM senders currently share the main session, which can leak context across users.",
remediation:
"Run: " +
formatCliCommand('openclaw config set session.dmScope "per-channel-peer"') +
' (or "per-account-channel-peer" for multi-account channels) to isolate DM sessions per sender.',
checkId: `channels.${input.provider}.dm.locked`,
severity: "info",
title: `${input.label} DMs are locked`,
detail: `${policyPath}="${input.dmPolicy}" has no admitted senders; unknown senders are blocked or receive a pairing code.`,
remediation: input.approveHint,
});
}
return auditState;
};
for (const plugin of params.plugins) {
@@ -294,7 +343,7 @@ export async function collectChannelSecurityFindings(params: {
findings.push({
checkId: `channels.${plugin.id}.account.read_only_resolution`,
severity: "warn",
title: `${plugin.meta.label ?? plugin.id} account could not be fully resolved`,
title: `[secrets] ${plugin.meta.label ?? plugin.id} account could not be fully resolved`,
detail: diagnostic,
remediation:
"Ensure referenced secrets are available in this shell or run with a running gateway snapshot so security audit can inspect the full channel configuration.",
@@ -307,14 +356,14 @@ export async function collectChannelSecurityFindings(params: {
continue;
}
const accountNote = formatChannelAccountNote({
orderedAccountIds,
hasExplicitAccountPath,
accountId,
});
const accountConfig = (account as { config?: Record<string, unknown> } | null | undefined)
?.config;
if (isDangerousNameMatchingEnabled(accountConfig)) {
const accountNote = formatChannelAccountNote({
orderedAccountIds,
hasExplicitAccountPath,
accountId,
});
if (includeAuditOnly && isDangerousNameMatchingEnabled(accountConfig)) {
findings.push({
checkId: `channels.${plugin.id}.allowFrom.dangerous_name_matching_enabled`,
severity: "info",
@@ -332,16 +381,109 @@ export async function collectChannelSecurityFindings(params: {
account,
});
if (dmPolicy) {
await warnDmPolicy({
label: plugin.meta.label ?? plugin.id,
const auditState = await warnDmPolicy({
label: `${plugin.meta.label ?? plugin.id}${accountNote}`,
provider: plugin.id,
accountId,
dmPolicy: dmPolicy.policy,
allowFrom: dmPolicy.allowFrom,
policyPath: dmPolicy.policyPath,
allowFromPath: dmPolicy.allowFromPath,
approveHint: dmPolicy.approveHint,
normalizeEntry: dmPolicy.normalizeEntry,
});
if (dmPolicy.policy !== "disabled") {
const dmRouting = plugin.security.dmRouting;
const admittedPrincipals = uniqueStrings([
...auditState.admittedPrincipals,
...(auditState.hasWildcard
? listExactDirectMessageBindingPeerIds({
cfg: params.cfg,
channel: plugin.id,
accountId,
})
: []),
]);
for (const principalId of admittedPrincipals) {
const principalContext = { cfg: params.cfg, accountId, account, principalId };
const channelDmScope = dmRouting?.resolveDmScope?.(principalContext);
const route = resolveAgentRoute({
cfg: params.cfg,
channel: plugin.id,
accountId,
peer: { kind: "direct", id: principalId },
dmScope: channelDmScope,
});
const result = dmRouting?.resolveDmRoute?.({ ...principalContext, route });
const sessionKey =
result && "sessionKey" in result ? result.sessionKey : route.sessionKey;
const linkedIdentity = resolveLinkedDirectPeerId({
identityLinks: params.cfg.session?.identityLinks,
channel: plugin.id,
peerId: principalId,
});
recordPrincipal(
plugin,
route,
sessionKey,
linkedIdentity
? `linked:${normalizeLowercaseStringOrEmpty(linkedIdentity)}`
: `direct:${plugin.id}:${route.accountId}:${normalizeLowercaseStringOrEmpty(principalId)}`,
true,
);
}
if (auditState.hasWildcard) {
const unknownContext = { cfg: params.cfg, accountId, account };
const route = resolveUnknownDirectMessageRoute({
cfg: params.cfg,
channel: plugin.id,
accountId,
dmScope: dmRouting?.resolveDmScope?.(unknownContext),
});
const customRoute = dmRouting?.resolveDmRoute;
const result = customRoute?.({ ...unknownContext, route });
if (customRoute && !result) {
findings.push({
checkId: `channels.${plugin.id}.dm.wildcard_routing_unverified.${route.accountId}`,
severity: "warn",
title: `${plugin.meta.label ?? plugin.id}${accountNote} wildcard DM isolation is unverified`,
detail:
"dmRouting.resolveDmRoute returned no unknown-principal policy; isolation for arbitrary senders cannot be established.",
});
}
const useCoreRoute =
!customRoute || Boolean(result && "kind" in result && result.kind === "core");
const sessionKey =
result && "sessionKey" in result
? result.sessionKey
: useCoreRoute && route.dmScope === "main"
? route.sessionKey
: undefined;
if (sessionKey) {
for (const suffix of ["1", "2"]) {
recordPrincipal(
plugin,
route,
sessionKey,
`wildcard:shared:${plugin.id}-${route.accountId}:${suffix}`,
);
}
} else if (
useCoreRoute &&
(route.dmScope === "per-channel-peer" || route.dmScope === "per-peer")
) {
const namespaces =
route.dmScope === "per-peer" ? ["peer"] : [`channel:${plugin.id}`, "peer"];
for (const namespace of namespaces) {
principalRoutes.push({
accountKey: `${plugin.id}-${route.accountId}`,
logicalPrincipalKey: `wildcard:${route.dmScope}:${plugin.id}-${route.accountId}`,
bucketKey: `${route.agentId}\0symbolic:dm:${namespace}`,
});
}
}
}
}
}
if (plugin.security.collectWarnings) {
@@ -363,7 +505,7 @@ export async function collectChannelSecurityFindings(params: {
});
}
}
if (plugin.security.collectAuditFindings) {
if (includeAuditOnly && plugin.security.collectAuditFindings) {
const auditFindings = await plugin.security.collectAuditFindings({
cfg: params.cfg,
sourceConfig,
@@ -379,5 +521,55 @@ export async function collectChannelSecurityFindings(params: {
}
}
const routesByBucket = new Map<string, DmPrincipalRoute[]>();
for (const route of principalRoutes) {
const routes = routesByBucket.get(route.bucketKey) ?? [];
routes.push(route);
routesByBucket.set(route.bucketKey, routes);
}
const groupedRoutes = [...routesByBucket.entries()].filter(
([, routes]) => new Set(routes.map((route) => route.logicalPrincipalKey)).size > 1,
);
const broadWildcardAgents = new Set(
groupedRoutes
.filter(
([bucketKey, routes]) =>
bucketKey.endsWith("\0symbolic:dm:peer") &&
routes.some((route) => route.logicalPrincipalKey.startsWith("wildcard:per-peer:")),
)
.map(([bucketKey]) => bucketKey.split("\0", 1)[0]),
);
const collisions = groupedRoutes
.filter(([bucketKey, routes]) => {
if (!bucketKey.includes("\0symbolic:")) {
return true;
}
const agentId = bucketKey.split("\0", 1)[0];
if (bucketKey.endsWith("\0symbolic:dm:peer")) {
return routes.some((route) => route.logicalPrincipalKey.startsWith("wildcard:per-peer:"));
}
return (
!broadWildcardAgents.has(agentId) &&
routes.some((route) => route.logicalPrincipalKey.startsWith("wildcard:per-channel-peer:"))
);
})
.toSorted(([left], [right]) => left.localeCompare(right));
for (const [collisionIndex, [bucketKey, routes]] of collisions.entries()) {
const accountKeys = uniqueStrings(routes.map((route) => route.accountKey)).toSorted();
const symbolic = bucketKey.includes("\0symbolic:");
findings.push({
checkId: `channels.dm.session_collision.${accountKeys.join("_")}.${collisionIndex + 1}`,
severity: "warn",
title: symbolic ? "DM principals may share a session" : "DM principals share a session",
detail:
`Collision topology ${collisionIndex + 1}: ${new Set(routes.map((route) => route.logicalPrincipalKey)).size} distinct admitted DM principals from ${accountKeys.join(", ")} ` +
`${symbolic ? "can resolve" : "resolve"} to the same session bucket owned by agent "${bucketKey.split("\0", 1)[0]}"` +
(params.cfg.session?.scope === "global" ? ' under session.scope="global".' : ".") +
" This can leak context across users.",
remediation:
"Set the effective DM route to an account-safe isolated scope; update the matching binding or session.dmScope as applicable.",
});
}
return dedupeFindings(findings);
}