feat(memory): complete explicit sharing and postbox

This commit is contained in:
Galin Iliev
2026-08-14 09:26:33 -07:00
parent 30dba2b78d
commit 25490297f1
61 changed files with 5081 additions and 459 deletions
+207 -141
View File
@@ -53,17 +53,17 @@
{"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":"d0cc2d1a92a55bfe73ad51bb32078cf4e8911a2a5a2f1c2f3190ba044922e56b","declaration":"export function createOpenClawCodingTools(options?: OpenClawCodingToolsOptions): AnyAgentTool[];","entrypoint":"agent-harness","exportName":"createOpenClawCodingTools","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"}
{"closureHash":"1b2cd35345f87a8ab4ff0b56aa58d03f90441974df6ee88724bfe43ac8883187","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":"d759a25775cb15d3f1804e39e98518f83b67b29ba3ab2fd84d4bf16106d9fdb9","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"bd666466495cef203461f4484eb439faa6a4fd10756c44a64a45ddef3b65961c","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"cff7e843ff24f7db2fd0f413d247310c86216bd9b51393b64c22f0ef85cda68e","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"7a05a2ecbd984f18210eca5d9c4e06b0f051279e1a9d830c4924969eb3982f76","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness","exportName":"AgentHarnessV2","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":"7cce5f7355df47a66ed208855889b16b2c40782a75575e8e1a8dce43517b801f","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"b56f77aa308700cc9ea82f50957a860852d0c83c006b5020d97f0d9b2d6c9d6a","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"02942c94049e128ca9e7ed1421bc3f6f6bcbb8b3818da0d727265be34a83ca04","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"}
{"closureHash":"bcbecd46dae3e3baa0c248d56356292426a63609aad44039fd6f5f1276bff73f","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParamsV2","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"}
@@ -74,16 +74,16 @@
{"closureHash":"155d94754b1411dd9b9fdae11ca094cbce25610ffb1dd9a617f293596b3a78f7","declaration":"export function assertContextEngineHostSupport(params: { contextEngine: ContextEngine; operation: ContextEngineOperation; host: ContextEngineHostSupport; }): void;","entrypoint":"agent-harness-runtime","exportName":"assertContextEngineHostSupport","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"3209ee56dbd86be4de23a2de59903a4d310fc99ed912d220ebe57efd308ff14f","declaration":"export function assignMcpCatalogSafeServerNames(serverNames: Iterable<string>): Map<string, string>;","entrypoint":"agent-harness-runtime","exportName":"assignMcpCatalogSafeServerNames","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"911838521fabe5f74acfeadabfa855fd9857fa21671b3f0cad08779f3402825a","declaration":"export function attachModelProviderRequestTransport<TModel extends object>(model: TModel, request: ModelProviderRequestTransportOverrides | undefined): TModel;","entrypoint":"agent-harness-runtime","exportName":"attachModelProviderRequestTransport","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"64e007f47389deb6c1a022f914aaff14269e34e906cd29a71464276a9f756560","declaration":"export function awaitAgentEndSideEffects(params: AgentEndSideEffectsParams): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"awaitAgentEndSideEffects","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"ef4cde7cdb9402c3651d90cd36780563d7650cbbd3b83820c5cd94d74e8a9ee8","declaration":"export function awaitAgentHarnessAgentEndHook(params: { event: PluginHookAgentEndEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"awaitAgentHarnessAgentEndHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"37f81c8f07bf6b905fb9d0752476e2dc666023a3a2a4f42cbb7d7fc9d494c32d","declaration":"export function awaitAgentEndSideEffects(params: AgentEndSideEffectsParams): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"awaitAgentEndSideEffects","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"e1ac85abf4da9fd8720aa48d9a3d16f3e519c04ddf121c0c9422a6137d0877fb","declaration":"export function awaitAgentHarnessAgentEndHook(params: { event: PluginHookAgentEndEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"awaitAgentHarnessAgentEndHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"73d8efb2d4171745da0c8f433ec80363cd9ce26b0d76be0cdddaa077489a5134","declaration":"export function bootstrapHarnessContextEngine(params: { hadSessionFile: boolean; contextEngine?: HarnessContextEngine; sessionId: string; sessionKey?: string; sessionTarget?: ContextEngineSessionTarget; sessionFile: string; sessionManager?: unknown; runtimeContext?: ContextEngineRuntimeContext; transcriptReadFence?: UserTurnTranscriptAdmissionReceipt; runtimeSettings?: ContextEngineRuntimeSettings; contextEngineHostSupport?: ContextEngineHostSupport; harnessId?: string | null; runtimeId?: string | null; providerId?: string | null; requestedModelId?: string | null; modelId?: string | null; maxOutputTokens?: number | null; fallbackReason?: string | null; degradedReason?: string | null; runMaintenance?: typeof runHarnessContextEngineMaintenance; config?: OpenClawConfig; warn: (message: string) => void; }): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"bootstrapHarnessContextEngine","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"fdd485fc00b19e46356354d24cc924c694fbb8c01a01e16048183880a3fbf50d","declaration":"export function buildAgentHarnessUserInputAnswers(questions: readonly AgentHarnessUserInputQuestion[], inputText: string): AgentHarnessUserInputAnswers;","entrypoint":"agent-harness-runtime","exportName":"buildAgentHarnessUserInputAnswers","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"bcc8554c0316257b42e7ca95e16c6b1f3bfb9794e5db7f41cf2bcdd2464bb218","declaration":"export function buildAgentHookContextChannelFields(params: { sessionKey?: string | null; messageChannel?: string | null; messageProvider?: string | null; currentChannelId?: string | null; messageTo?: string | null; senderId?: string | null; agentAccountId?: string | null; }): Pick<PluginHookAgentContext, \"accountId\" | \"channel\" | \"channelId\" | \"chatId\" | \"messageProvider\" | \"senderId\">;","entrypoint":"agent-harness-runtime","exportName":"buildAgentHookContextChannelFields","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"3d5e7938f471abeda3976e1fa572ef53e7c95f51349e4419506b626913d1060f","declaration":"export function buildAgentHookContextChannelFields(params: { sessionKey?: string | null; messageChannel?: string | null; messageProvider?: string | null; currentChannelId?: string | null; messageTo?: string | null; senderId?: string | null; agentAccountId?: string | null; }): Pick<PluginHookAgentContext, \"accountId\" | \"channel\" | \"channelId\" | \"chatId\" | \"messageProvider\" | \"senderId\">;","entrypoint":"agent-harness-runtime","exportName":"buildAgentHookContextChannelFields","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"f8ad3d762c9753fdc36b2b9af0980167fdc54090c7bcca2f3dbe7c8951e86821","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":"273bc789e32d09355911a553f30e7fd13f0ac7fc7d08f76d6c6ea96b8ab4e1d3","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":"9cd796a6dc567e647776b5d9af435e8c179796142948b64b088eb9e91c42ba66","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":"558119b330dcc6a677a91f88a180b67d63299880b8fc0efc0d4616c3d6ffab30","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":"a3814447de0f4815068e05a01453fe8e5bc87216e2d88613f21f8f7982ed94b2","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"}
@@ -100,7 +100,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":"1368f69c7a2b975961e4bec1a8709522669fed0df0eca2d669159c9e65eb1cf3","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":"173e3b60315d73b59d370d8ee1101efb7e4653e01dd5d504c0cbe1cd8e04a5bf","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"}
@@ -123,7 +123,7 @@
{"closureHash":"5fa61424d7471cf6f3b142964294cca4723eefc5b673eff97b2b1a8b3f139172","declaration":"export function formatToolAggregate(toolName?: string, metas?: string[], options?: ToolAggregateOptions): string;","entrypoint":"agent-harness-runtime","exportName":"formatToolAggregate","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"cb9c705d6862116c7c61a3cc3941f8fea1c834ad14a628441cff1d1a697eb00b","declaration":"export function formatToolExecutionErrorMessage(error: unknown, fallback: string): string;","entrypoint":"agent-harness-runtime","exportName":"formatToolExecutionErrorMessage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"16ca31a0ec0bec339d1a9ac63252eec5665d00d763c20075a93be176dc098239","declaration":"export function formatToolProgressOutput(output: string, options?: { maxChars?: number; }): string | undefined;","entrypoint":"agent-harness-runtime","exportName":"formatToolProgressOutput","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"ed37bb17e6b49e1120950b88390fa7e9cb14202bf2aeab1bded96c07eb774f47","declaration":"export function getAgentHarnessHookRunner(): AgentHarnessHookRunner;","entrypoint":"agent-harness-runtime","exportName":"getAgentHarnessHookRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"5163319f5736536c61ca48eb7dd744b84ea3d5e386dc283c7de6c9389becd121","declaration":"export function getAgentHarnessHookRunner(): AgentHarnessHookRunner;","entrypoint":"agent-harness-runtime","exportName":"getAgentHarnessHookRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"37c1f0f87fd002e7de9ddb6ec0e4389e7add214dd3ceb6001077038f395d8451","declaration":"export function getBeforeToolCallFailureDisposition(error: unknown): BeforeToolCallFailureDisposition | undefined;","entrypoint":"agent-harness-runtime","exportName":"getBeforeToolCallFailureDisposition","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"2f995f2a9777cac11240f0dd375d2041fdc11ca0ad57c65e102db3d0be6b6f62","declaration":"export function getBeforeToolCallPolicyDiagnosticState(): BeforeToolCallPolicyDiagnosticState;","entrypoint":"agent-harness-runtime","exportName":"getBeforeToolCallPolicyDiagnosticState","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"45828b5ebf771446b493a1af9dee71e58aa8b96a28957a633e5fd5f3d6bfcaa4","declaration":"export function getChannelAgentToolMeta(tool: ChannelAgentTool): ChannelAgentToolMeta | undefined;","entrypoint":"agent-harness-runtime","exportName":"getChannelAgentToolMeta","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
@@ -162,7 +162,7 @@
{"closureHash":"40154c3b7b2a7179df33f4a3fbef5e56078be2759d5aab29f39eb0f3c92fc631","declaration":"export function projectRuntimeToolInputSchema(schema: unknown, path?: string): RuntimeToolInputSchemaProjection;","entrypoint":"agent-harness-runtime","exportName":"projectRuntimeToolInputSchema","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"e42e3dc63e8545bb9a6056336fbd6c1dc8f356dce4f0f1c6d9765254c974390e","declaration":"export function projectSettledTurnFinalizationAttemptResult(result: AgentHarnessAttemptResult): AgentHarnessSettledTurnFinalizationResult;","entrypoint":"agent-harness-runtime","exportName":"projectSettledTurnFinalizationAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"28fce991efc7c1c2e4d24a5380acdeca72aea42a3e3b14d053ec352a84ab5211","declaration":"export function queueAgentHarnessMessage(sessionId: string, text: string, options?: EmbeddedAgentQueueMessageOptions): boolean;","entrypoint":"agent-harness-runtime","exportName":"queueAgentHarnessMessage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"a5942178bfa7de60f6b738d58d5f511a7baa1abf25119454180b81daec365833","declaration":"export function registerNativeHookRelay(params: RegisterNativeHookRelayParams): ActiveNativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"registerNativeHookRelay","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"304995888df64b5f779a8fcc35c3548dfc64d478e793003de1cacf4a5bcc8668","declaration":"export function registerNativeHookRelay(params: RegisterNativeHookRelayParams): ActiveNativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"registerNativeHookRelay","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"b7cc6c35506dc6955e0359aa5c53c15a4d0db23639da8c1717f8fefda953c119","declaration":"export function requestDeferredPluginToolApproval(params: { deferredApproval: DeferredPluginToolApproval; signal?: AbortSignal; }): Promise<HookOutcome>;","entrypoint":"agent-harness-runtime","exportName":"requestDeferredPluginToolApproval","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"a2306cba08cb05ff8430c8362c0cc3c821706da5a4e65a06849ad0d0fb007ae3","declaration":"export function resetAgentEventsForTest(options?: { preserveListeners?: boolean; }): void;","entrypoint":"agent-harness-runtime","exportName":"resetAgentEventsForTest","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"f255a91162ece4c239bb8fa745efa14a1054bc024a291e9954f75f239b2b87c3","declaration":"export function resolveActiveEmbeddedRunSessionId(sessionKey: string): string | undefined;","entrypoint":"agent-harness-runtime","exportName":"resolveActiveEmbeddedRunSessionId","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
@@ -181,7 +181,7 @@
{"closureHash":"a36f94a5d2408964d52b23e38f02c8e9467266d8e06e6fee0fdf16946eae9e79","declaration":"export function resolveModelAuthMode(provider?: string, cfg?: OpenClawConfig, store?: AuthProfileStore, options?: { workspaceDir?: string; }): ModelAuthMode | undefined;","entrypoint":"agent-harness-runtime","exportName":"resolveModelAuthMode","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"714a04276dcddc15a1079835050cdef88837b7159d24a72db8938bb3b45c764f","declaration":"export function resolveNativeHookRelayDeferredToolApproval(params: { relayId: string; toolUseId?: string; signal?: AbortSignal; }): Promise<NativeHookRelayDeferredApprovalOutcome | undefined>;","entrypoint":"agent-harness-runtime","exportName":"resolveNativeHookRelayDeferredToolApproval","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"fbda2ecc8054053facbdaf406268fb2d50f3f68e6e2446f23a90f385278fcc24","declaration":"export function resolveNodeIdFromList(nodes: NodeListNode[], query?: string, allowDefault?: boolean, options?: { allowCompactDisplayName?: boolean; }): string;","entrypoint":"agent-harness-runtime","exportName":"resolveNodeIdFromList","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"b325a6d70ba080e1b2687c21048c06fe8a913eee1c6bfd9166bad6a4b2864675","declaration":"export function resolveSandboxContext(params: { config?: OpenClawConfig; agentId?: string; execOverrides?: ExecPolicyOverrides; requireCurrentConfig?: boolean; sessionKey?: string; skillsSnapshot?: SkillSnapshot; workspaceDir?: string; }): Promise<SandboxContext | null>;","entrypoint":"agent-harness-runtime","exportName":"resolveSandboxContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"929e9f5ae2814b89c43ed24e9b29f72463644875911d384773114510796d7e1d","declaration":"export function resolveSandboxContext(params: { config?: OpenClawConfig; agentId?: string; execOverrides?: ExecPolicyOverrides; requireCurrentConfig?: boolean; sessionKey?: string; skillsSnapshot?: SkillSnapshot; authorizedVirtualProjectionMountPlan?: AuthorizedVirtualProjectionMountPlan; prepareAuthorizedVirtualProjectionMountPlan?: (params: { agentWorkspaceDir: string; }) => Promise<StagedAuthorizedVirtualProjectionMountPlan | undefined>; workspaceDir?: string; }): Promise<SandboxContext | null>;","entrypoint":"agent-harness-runtime","exportName":"resolveSandboxContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"9aab8cf42913a365a7e26efdea7abee4445cf9a47a34067e952ea7ee2ed44731","declaration":"export function resolveSessionAgentIds(params: { sessionKey?: string; config?: OpenClawConfig; agentId?: string; fallbackAgentId?: string; }): { defaultAgentId: string; sessionAgentId: string; };","entrypoint":"agent-harness-runtime","exportName":"resolveSessionAgentIds","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"a34704c97920f0c3cb70407476fb16ebf1a6fb8a74f01c3ab5425bdbf08e9612","declaration":"export function resolveSessionWriteLockAcquireTimeoutMs(_config?: SessionWriteLockAcquireTimeoutConfig, _env?: NodeJS.ProcessEnv): number;","entrypoint":"agent-harness-runtime","exportName":"resolveSessionWriteLockAcquireTimeoutMs","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"2eb76630485e36b410dd663450f0c34b126593961069622cc6bef762f84a71cd","declaration":"export function resolveSessionWriteLockOptions(_config?: SessionWriteLockAcquireTimeoutConfig, _params?: { env?: NodeJS.ProcessEnv; maxHoldMsFallback?: number; }): { timeoutMs: number; staleMs: number; maxHoldMs: number; };","entrypoint":"agent-harness-runtime","exportName":"resolveSessionWriteLockOptions","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
@@ -190,16 +190,16 @@
{"closureHash":"f2fb5a4e5546086c8a69600795e5b6cde1817b2ba5a4680600c41297005b3ee2","declaration":"export function resolveUserPath(input: string, env?: NodeJS.ProcessEnv, homedir?: () => string): string;","entrypoint":"agent-harness-runtime","exportName":"resolveUserPath","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"4204798ce3bf40e0b488d6642a9617f361e53931f634042fcd09dde69f3924c4","declaration":"export function resolveWritableSandboxBindHostRoots(binds: readonly string[] | undefined): string[];","entrypoint":"agent-harness-runtime","exportName":"resolveWritableSandboxBindHostRoots","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"10e5de5d2202452344eca9023fccecd19bcede51b031fe7926bd6335e7767158","declaration":"export function runAgentCleanupStep(params: { runId: string; sessionId: string; step: string; cleanup: () => Promise<void>; getTimeoutDetails?: () => string | undefined; log: AgentCleanupLogger; env?: NodeJS.ProcessEnv; timeoutMs?: number; }): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"runAgentCleanupStep","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"8158f730012e93bff519315eb8188240fdd033e288ab0bb7350d41d693987f74","declaration":"export function runAgentEndSideEffects(params: AgentEndSideEffectsParams): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentEndSideEffects","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"0aa9bec0d281a8caa28e34bd4eb6a7906518fde20decf351ed1e52eaf2112760","declaration":"export function runAgentEndSideEffects(params: AgentEndSideEffectsParams): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentEndSideEffects","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"a88818cc62232eeb75281bb6ccfbaf7928a4bb1390313c73c08b14c73e4e92bb","declaration":"export function runAgentHarnessAfterCompactionHook(params: { sessionFile: string; messages?: AgentMessage[]; ctx: AgentHarnessHookContext; compactedCount: number; }): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessAfterCompactionHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"d6517f30fc90c4fa8ef89ac0fe3d6499adcfad71fd3ab46cc66d3e4a2472a844","declaration":"export function runAgentHarnessAfterToolCallHook(params: { toolName: string; toolCallId: string; runId?: string; agentId?: string; sessionId?: string; sessionKey?: string; channelId?: string; startArgs: Record<string, unknown>; result?: unknown; error?: string; startedAt?: number; }): Promise<void>;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessAfterToolCallHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"63e138290e4629046b4b6f56e8601979be5e851ea930d9f95daef8eb8d6527c3","declaration":"export function runAgentHarnessAgentEndHook(params: { event: PluginHookAgentEndEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessAgentEndHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"da8b724c5858691b8a1c71c63294a397631c031270db92fdff9ef4493efa2492","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":"5037ec4d780f518767d676d52ac55627dd4bf515aee344145b928156b7eef5fc","declaration":"export function runAgentHarnessAgentEndHook(params: { event: PluginHookAgentEndEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessAgentEndHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"d542c7e8b4994cd135222d0914e3714cb39f61a867aee5822e2594b5a008633d","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":"234d68d071e378bce7a3780dd308a39e6f611b722d86203c3366951420d9f1b1","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":"89aa32c12a44b446777bc4cfbb106a048dd9cbc668260525798a895a433256f4","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":"ba63f9cdd34249fba984af87a039494b75b3f93c0c70b925e884f3f98935b984","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":"0c380a0011acae57282121d702249d2ab7e978452fe7f32e8853d9945c5558b9","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":"78e0698de386b8af9caccebe1e0738fc8f88e7ae9f65187759acf7cefea7b578","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":"7347dbea4eac7869440c0db74f329e9fb1389bc8524f398d65961ae98ee80d7d","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"}
{"closureHash":"35268edd668bcf1981dff5f000b8bbb5847a1a9bb7e8923769edc378e21108aa","declaration":"export function runHarnessContextEngineMaintenance(params: { contextEngine?: HarnessContextEngine; sessionId: string; sessionKey?: string; sessionTarget?: ContextEngineSessionTarget; sessionFile: string; reason: \"bootstrap\" | \"compaction\" | \"turn\"; sessionManager?: unknown; runtimeContext?: ContextEngineRuntimeContext; runtimeSettings?: ContextEngineRuntimeSettings; contextEngineHostSupport?: ContextEngineHostSupport; harnessId?: string | null; runtimeId?: string | null; providerId?: string | null; requestedModelId?: string | null; modelId?: string | null; tokenBudget?: number | null; maxOutputTokens?: number | null; fallbackReason?: string | null; degradedReason?: string | null; executionMode?: \"foreground\" | \"background\"; onDeferredMaintenance?: (promise: Promise<void>) => void; withSessionManagerRewriteLock?: <T>(operation: () => Promise<T> | T) => Promise<T>; config?: OpenClawConfig; }): Promise<TranscriptRewriteResult | undefined>;","entrypoint":"agent-harness-runtime","exportName":"runHarnessContextEngineMaintenance","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
{"closureHash":"ac1ea146e8b2031b307790d708076df67f0120365804edffacbf9841edd86185","declaration":"export function sanitizeToolResult(result: unknown): unknown;","entrypoint":"agent-harness-runtime","exportName":"sanitizeToolResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"}
@@ -219,13 +219,13 @@
{"closureHash":"0701a22057edc3b733da7e05948db94aa98b337b224a5718efdd85212a8602bf","declaration":"export const TRANSCRIPT_CREDENTIAL_SAFETY_PROMPT: string;","entrypoint":"agent-harness-runtime","exportName":"TRANSCRIPT_CREDENTIAL_SAFETY_PROMPT","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
{"closureHash":"b5845c99df6c2a834a16678c320e0111bad96a3a7ac245d379aa5e6d2555d29b","declaration":"export const agentHarnessAttemptTerminal: { merge: (current: AgentRunAttemptTerminal, incoming: AgentRunAttemptTerminal) => AgentRunAttemptTerminal; normalize: (input: { aborted?: boolean; externalAbort?: boolean; idleTimedOut?: boolean; promptError?: unknown; promptErrorSource?: AgentRunAttemptFailureSource | null; timedOut?: boolean; timedOutByRunBudget?: boolean; timedOutDuringCompaction?: boolean; timedOutDuringToolExecution?: boolean; }) => AgentRunAttemptTerminal; project: (terminal: AgentRunAttemptTerminal) => { aborted: boolean; cleanupYieldAborted: boolean; externalAbort: boolean; failed: boolean; idleTimedOut: boolean; interrupted: boolean; promptError: unknown; promptErrorSource: AgentRunAttemptFailureSource | null; timedOut: boolean; timedOutByRunBudget: boolean; timedOutDuringCompaction: boolean; timedOutDuringToolExecution: boolean; }; setFailure: (terminal: AgentRunAttemptTerminal, failure: { source: AgentRunAttemptFailureSource; error: unknown; } | null) => AgentRunAttemptTerminal;};","entrypoint":"agent-harness-runtime","exportName":"agentHarnessAttemptTerminal","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
{"closureHash":"22bcf962aa76c76074c4ed4ad7d6558edbc3588e239263e09af74c1000bbe012","declaration":"export const embeddedAgentLog: SubsystemLogger;","entrypoint":"agent-harness-runtime","exportName":"embeddedAgentLog","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
{"closureHash":"c0f6b29e20cd3f18f1f123bc1e5d458f391013e2812541fd58698155bd72fe96","declaration":"export const nativeHookRelayTesting: { readonly clearNativeHookRelaysForTests: () => void; readonly getNativeHookRelayInvocationsForTests: () => NativeHookRelayInvocation[]; readonly getNativeHookRelayRegistrationForTests: (relayId: string) => NativeHookRelayRegistration | undefined; readonly getNativeHookRelayBridgeDirForTests: () => string; readonly getNativeHookRelayBridgeRegistryPathForTests: (relayId: string) => string; readonly getNativeHookRelayBridgeRecordForTests: (relayId: string) => Record<string, unknown> | undefined; readonly isNativeHookRelayBridgeLookupRetryableForTests: (error: unknown, elapsedMs?: number) => boolean; readonly formatPermissionApprovalDescriptionForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestContentFingerprintForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestToolInputKeyFingerprintForTests: (toolInput: Record<string, unknown>) => string; readonly setNativeHookRelayPermissionApprovalRequesterForTests: (requester: NativeHookRelayPermissionApprovalRequester) => void; readonly setNativeHookRelayDeferredToolApprovalRequesterForTests: (requester: NativeHookRelayDeferredToolApprovalRequester) => void;};","entrypoint":"agent-harness-runtime","exportName":"nativeHookRelayTesting","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
{"closureHash":"3e5249851db00013b4755ad9834fcd8bb1f596a83154ab6525f69fcec12fe234","declaration":"export const nativeHookRelayTesting: { readonly clearNativeHookRelaysForTests: () => void; readonly getNativeHookRelayInvocationsForTests: () => NativeHookRelayInvocation[]; readonly getNativeHookRelayRegistrationForTests: (relayId: string) => NativeHookRelayRegistration | undefined; readonly getNativeHookRelayBridgeDirForTests: () => string; readonly getNativeHookRelayBridgeRegistryPathForTests: (relayId: string) => string; readonly getNativeHookRelayBridgeRecordForTests: (relayId: string) => Record<string, unknown> | undefined; readonly isNativeHookRelayBridgeLookupRetryableForTests: (error: unknown, elapsedMs?: number) => boolean; readonly formatPermissionApprovalDescriptionForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestContentFingerprintForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestToolInputKeyFingerprintForTests: (toolInput: Record<string, unknown>) => string; readonly setNativeHookRelayPermissionApprovalRequesterForTests: (requester: NativeHookRelayPermissionApprovalRequester) => void; readonly setNativeHookRelayDeferredToolApprovalRequesterForTests: (requester: NativeHookRelayDeferredToolApprovalRequester) => void;};","entrypoint":"agent-harness-runtime","exportName":"nativeHookRelayTesting","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"}
{"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":"d759a25775cb15d3f1804e39e98518f83b67b29ba3ab2fd84d4bf16106d9fdb9","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness-runtime","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"d759a25775cb15d3f1804e39e98518f83b67b29ba3ab2fd84d4bf16106d9fdb9","declaration":"export type AgentHarnessAttemptParams = AgentHarnessAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"acb796810881f352798f8026ebebc9ba1ce3faf3286785e4b9a964367ebd24d9","declaration":"export type AgentHarnessAttemptParamsV2 = AgentHarnessAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"cff7e843ff24f7db2fd0f413d247310c86216bd9b51393b64c22f0ef85cda68e","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness-runtime","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"cff7e843ff24f7db2fd0f413d247310c86216bd9b51393b64c22f0ef85cda68e","declaration":"export type AgentHarnessAttemptParams = AgentHarnessAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"9bb57b4386260763227e18aa2ba12bb785f760210844d4f9d25f931db493c8aa","declaration":"export type AgentHarnessAttemptParamsV2 = AgentHarnessAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParamsV2","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":"8f496ce75f294f2aa440a49c3c5b065ddff3a4714df775116af5e53f7fd14fe5","declaration":"export type AgentHarnessCompactParams = CompactEmbeddedAgentSessionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessCompactParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
@@ -239,8 +239,8 @@
{"closureHash":"95741b872a194687696eba4a96d6e887ec6e81922695fa0282cb2f0a46ff9f97","declaration":"export type AgentHarnessSessionForkParams = AgentHarnessSessionForkParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSessionForkParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"f3c46fef2a6c3393b0b6ad09915abcd6f57bb58ddddde1d60ebd113c7a1c5fa6","declaration":"export type AgentHarnessSessionForkResult = AgentHarnessSessionForkResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSessionForkResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"4b5a59730309e446f59a8ec1c554c3193aca1959916594cc657347098bd67a35","declaration":"export type AgentHarnessSettledTurnFinalizationResult = AgentHarnessSettledTurnFinalizationResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSettledTurnFinalizationResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"e2c320165e7f072dd5d053d82be3fa5db3b3648112d39a3b40e393d92b07033a","declaration":"export type AgentHarnessSideQuestionParams = AgentHarnessSideQuestionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"1311982296ef9a93957c4559b85e87fc6f3e414476b5c77418df522d2312f795","declaration":"export type AgentHarnessSideQuestionParamsV2 = AgentHarnessSideQuestionParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"717e607091ebd5563ff5d922e2da88958e15d038f02fb07cb4efc21f307f5ad3","declaration":"export type AgentHarnessSideQuestionParams = AgentHarnessSideQuestionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"cbcf0defea227508b796290592c85270b2947c4ab1d4bf20edd409aee14a1de0","declaration":"export type AgentHarnessSideQuestionParamsV2 = AgentHarnessSideQuestionParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"e84173055503c40dd0ef1cb67c6d333e9257fcf995252b27c1d58f5c904e8de9","declaration":"export type AgentHarnessSideQuestionResult = AgentHarnessSideQuestionResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"50214d08dac98e3c1031ac7bc733b85cb2247d2eef3b6b2045758ae403af7647","declaration":"export type AgentHarnessSupport = AgentHarnessSupport;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSupport","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"50ce26ea22bc225e6064d2e5f37356b6f4ce4a57f8b9fa42baa4c421da48aad5","declaration":"export type AgentHarnessSupportContext = AgentHarnessSupportContext;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSupportContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
@@ -250,7 +250,7 @@
{"closureHash":"20a8a7c9d5ebf425c30d04eea3856c6c889a210f1fa53c99299df24882afbf92","declaration":"export type AgentHarnessUserInputOption = AgentHarnessUserInputOption;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputOption","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"6224f51b4189f10a642ad7a8f50a902ec9c6a6a4f8dac0c0de5f7bc0271a27e5","declaration":"export type AgentHarnessUserInputPromptOptions = AgentHarnessUserInputPromptOptions;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputPromptOptions","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"d8f1d0d118e1536d1f442d11aeae5334a1ed7949a6c61824f547e12931278e1d","declaration":"export type AgentHarnessUserInputQuestion = AgentHarnessUserInputQuestion;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"bd666466495cef203461f4484eb439faa6a4fd10756c44a64a45ddef3b65961c","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"7a05a2ecbd984f18210eca5d9c4e06b0f051279e1a9d830c4924969eb3982f76","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"6f2af683e6a31cde5a473c77e4f03b8f0ec0351a43ea6c0af979d5b394a33f95","declaration":"export type AgentMessage = AgentMessage;","entrypoint":"agent-harness-runtime","exportName":"AgentMessage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"4ad0f830bf11a2db48faefb1439b7fbb08d9f22d22083f5e301327e1696f2310","declaration":"export type AgentToolResultMiddleware = AgentToolResultMiddleware;","entrypoint":"agent-harness-runtime","exportName":"AgentToolResultMiddleware","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"185abd2870d4df65e9f94623061a30167d17ef1279a395201fe429398bf23500","declaration":"export type AgentToolResultMiddlewareContext = AgentToolResultMiddlewareContext;","entrypoint":"agent-harness-runtime","exportName":"AgentToolResultMiddlewareContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
@@ -276,8 +276,8 @@
{"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":"7cce5f7355df47a66ed208855889b16b2c40782a75575e8e1a8dce43517b801f","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"b56f77aa308700cc9ea82f50957a860852d0c83c006b5020d97f0d9b2d6c9d6a","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"02942c94049e128ca9e7ed1421bc3f6f6bcbb8b3818da0d727265be34a83ca04","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"bcbecd46dae3e3baa0c248d56356292426a63609aad44039fd6f5f1276bff73f","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParamsV2","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"}
@@ -293,7 +293,7 @@
{"closureHash":"d8a720bf250da8daf4dc6a52087aa8728ec33b650b3ad3906fcb40e184de66a0","declaration":"export type NativeHookRelayEvent = \"pre_tool_use\" | \"post_tool_use\" | \"permission_request\" | \"before_agent_finalize\";","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"cb72ca18e056e52e779d0bf5b67606e1dc160f225225b55937304541105027f4","declaration":"export type NativeHookRelayProcessResponse = NativeHookRelayProcessResponse;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayProcessResponse","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"6ee390ae4784b987e22255c16884fb4171033bbfaefaef655e3dd2a2513814a5","declaration":"export type NativeHookRelayProvider = \"codex\";","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayProvider","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"389e3f59bfd6a95d6edeeb1afc2dbd51e6b26828fda9bbcdef480d7314962976","declaration":"export type NativeHookRelayRegistrationHandle = NativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayRegistrationHandle","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"67a6d6b90ddec773f8be410c658c95c7632bf87cc2558f364e35f0dd8ce14e7b","declaration":"export type NativeHookRelayRegistrationHandle = NativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayRegistrationHandle","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"90fea3155b5d32c22da90460fdaea94e4fd6895d1ca18613d5036ba9835153f9","declaration":"export type NodeListNode = NodeListNode;","entrypoint":"agent-harness-runtime","exportName":"NodeListNode","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"cefe1325c866f0cf7edbec5dcca2fe420237eedc0da172e54094e365894d205d","declaration":"export type NormalizedUsage = NormalizedUsage;","entrypoint":"agent-harness-runtime","exportName":"NormalizedUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"25c6985c3bef2c6efc6a96e70af6d66fe073be0b0d311681cfc0dfc186528d9a","declaration":"export type OpenClawAgentToolResult<TResult = unknown> = OpenClawAgentToolResult<TResult>;","entrypoint":"agent-harness-runtime","exportName":"OpenClawAgentToolResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
@@ -301,7 +301,7 @@
{"closureHash":"76ea2a9e92e8e8830b281d6aba00c33594e680d13600004ac1d7c8403f7d1d97","declaration":"export type RuntimeToolInputSchemaJson = RuntimeToolInputSchemaJson;","entrypoint":"agent-harness-runtime","exportName":"RuntimeToolInputSchemaJson","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"8890b76e12d09d7be78431b1d3f6cda33f01f42ab77e663d00d994aaec19450b","declaration":"export type RuntimeToolInputSchemaProjection = RuntimeToolInputSchemaProjection;","entrypoint":"agent-harness-runtime","exportName":"RuntimeToolInputSchemaProjection","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"4bafe42be9314992dc91904c0e819dc8fde9622f64d6a0692b3464d6c5960b68","declaration":"export type RuntimeToolSchemaDiagnostic = RuntimeToolSchemaDiagnostic;","entrypoint":"agent-harness-runtime","exportName":"RuntimeToolSchemaDiagnostic","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"703fc83a60b9cb59fdf456118c011fd77bebdf23ce631c2fd39809974cc415ba","declaration":"export type SandboxContext = SandboxContext;","entrypoint":"agent-harness-runtime","exportName":"SandboxContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"8047a139df75cf6122dca8f9a2bf94d771e7d0d22b0920445ff4bbda24c5cd30","declaration":"export type SandboxContext = SandboxContext;","entrypoint":"agent-harness-runtime","exportName":"SandboxContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"20064efc037fedb3317e41819e22f77dece60d79d5d9a0cb15ae45b2ddd5ed36","declaration":"export type SandboxWorkspaceAccess = SandboxWorkspaceAccess;","entrypoint":"agent-harness-runtime","exportName":"SandboxWorkspaceAccess","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"c0a9b60ee19d241903cd8393d8b0f47c8bd2c93975fb0d8610d9b118bb4bde30","declaration":"export type SessionMcpRuntime = SessionMcpRuntime;","entrypoint":"agent-harness-runtime","exportName":"SessionMcpRuntime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
{"closureHash":"aad0f56093883431bcc1b035a2c99371c3c58cb1d53d7dc71c6fccb93722dd01","declaration":"export type SessionWriteLockAcquireTimeoutConfig = OpenClawConfig;","entrypoint":"agent-harness-runtime","exportName":"SessionWriteLockAcquireTimeoutConfig","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"}
@@ -315,7 +315,7 @@
{"closureHash":"666634000ee5bf317dabcbd70524833961fad58edc2b3cd66fe5fa0172e89602","declaration":"export function getAgentScopedMediaLocalRoots(cfg: OpenClawConfig, agentId?: string): readonly string[];","entrypoint":"agent-media-payload","exportName":"getAgentScopedMediaLocalRoots","importSpecifier":"openclaw/plugin-sdk/agent-media-payload","kind":"function","recordType":"export"}
{"closureHash":"160c685c3f4e7ed80fb24d3d76655a182116efe6a7b985bb3bc57b89fe436d2a","declaration":"export type AgentMediaPayload = AgentMediaPayload;","entrypoint":"agent-media-payload","exportName":"AgentMediaPayload","importSpecifier":"openclaw/plugin-sdk/agent-media-payload","kind":"type","recordType":"export"}
{"category":"runtime","entrypoint":"agent-runtime","importSpecifier":"openclaw/plugin-sdk/agent-runtime","recordType":"module"}
{"closureHash":"d676259fd3157772725733326c64420d7b5d750225551ac6501664954281135a","declaration":"export function agentCommandFromIngress(opts: AgentCommandIngressOpts, runtime?: RuntimeEnv, deps?: CliDeps): Promise<{ payloads: ReturnType<typeof projectOutboundPayloadPlanForJson>; meta: EmbeddedAgentRunMeta; didSendViaMessagingTool?: boolean; messagingToolSentTexts?: string[]; messagingToolSentMediaUrls?: string[]; messagingToolSentTargets?: MessagingToolSend[]; deliverySucceeded?: boolean; deliveryStatus?: { requested: true; attempted: boolean; status: \"sent\" | \"suppressed\" | \"partial_failed\" | \"failed\"; succeeded: true | false | \"partial\"; error?: true; errorMessage?: string; reason?: string; resultCount?: number; sentBeforeError?: true; payloadOutcomes?: SerializedDurableMessagePayloadOutcome[]; }; }>;","entrypoint":"agent-runtime","exportName":"agentCommandFromIngress","importSpecifier":"openclaw/plugin-sdk/agent-runtime","kind":"function","recordType":"export"}
{"closureHash":"026d8014866b7337c12525e09ed5cf46e6211558fc80a05cb3c842b7b967ff0e","declaration":"export function agentCommandFromIngress(opts: AgentCommandIngressOpts, runtime?: RuntimeEnv, deps?: CliDeps): Promise<{ payloads: ReturnType<typeof projectOutboundPayloadPlanForJson>; meta: EmbeddedAgentRunMeta; didSendViaMessagingTool?: boolean; messagingToolSentTexts?: string[]; messagingToolSentMediaUrls?: string[]; messagingToolSentTargets?: MessagingToolSend[]; deliverySucceeded?: boolean; deliveryStatus?: { requested: true; attempted: boolean; status: \"sent\" | \"suppressed\" | \"partial_failed\" | \"failed\"; succeeded: true | false | \"partial\"; error?: true; errorMessage?: string; reason?: string; resultCount?: number; sentBeforeError?: true; payloadOutcomes?: SerializedDurableMessagePayloadOutcome[]; }; }>;","entrypoint":"agent-runtime","exportName":"agentCommandFromIngress","importSpecifier":"openclaw/plugin-sdk/agent-runtime","kind":"function","recordType":"export"}
{"closureHash":"cb95256473d5489ef80ec3e1d93c6a612b2cc733c26ab535f945f8797995b5cb","declaration":"export function buildConfiguredModelCatalog(params: { cfg: OpenClawConfig; workspaceDir?: string; manifestPlugins?: ModelManifestPlugins; }): ModelCatalogEntry[];","entrypoint":"agent-runtime","exportName":"buildConfiguredModelCatalog","importSpecifier":"openclaw/plugin-sdk/agent-runtime","kind":"function","recordType":"export"}
{"closureHash":"4a71b73b60d846e9d99fa3881cb72eb7eaaebe7b3386b6bcbaa6cfa46eb3a073","declaration":"export function buildModelAliasIndex(params: BuildModelAliasIndexParams): ModelAliasIndex;","entrypoint":"agent-runtime","exportName":"buildModelAliasIndex","importSpecifier":"openclaw/plugin-sdk/agent-runtime","kind":"function","recordType":"export"}
{"closureHash":"ae0f930ec291a0345c4e99e247711465a5d29a8bbdd63968900fa69f382b3a78","declaration":"export function clearExpiredCooldowns(store: AuthProfileStore, now?: number): boolean;","entrypoint":"agent-runtime","exportName":"clearExpiredCooldowns","importSpecifier":"openclaw/plugin-sdk/agent-runtime","kind":"function","recordType":"export"}
@@ -762,7 +762,7 @@
{"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":"9e93bcdfc6299e65ef2a3d267047a9e8c856f0b2f8e9b79d570fb2a4cd238c74","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":"ad9a5a09235e9a426da9b310cd466830ad103dda2e5ce4891ef4131fdf50deda","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":"cb5d7b4d9caafb5d1eaa57839fe6cb95e714bac30f9b697c720b32913c22eec5","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"}
@@ -774,26 +774,26 @@
{"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":"d02e5c7a995847180696d2a05d8ea092b364ef32b36753e4091fc97ffdaf44ab","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":"2ddf03be75f0d46c8a7e1d7a3d3e70122001b190dcb361132cef2f1d23d8ddec","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"d9d24565b06f891a687f49672129beac9d38ccb817526ed1a6579efcb5825eb0","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"b94637421f524b48f7e497e449491475a2cc35f3d6dc43bdf5274b401b9424b0","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"channel-core","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"aded5b666490cf7e5cca6bf3942c5190ad1fc30fc73f542505c53e5999f649a9","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"5c7a4e89ddfb6bed00f2ca8e67e43f150fedb3182275a525411365855d581c22","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"}
{"closureHash":"8d8f8c012d739749de557261960af8c0c714403fefa6fa15bd06ddbaee90aee3","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":"5885bf21e94629126fa96a1a953d2c913eeeaac3fc603e9d23846e0700b53835","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":"237c32c30b7f6979b8e955acfd6520db3ac2d98a3c46539c3b083d5d1af48247","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":"f77c4528b2e7bb9a16d6fd36f1ac0dc1651c33907ffaf66111bdb28c2406aee8","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":"25ffae2b8663333380eae5ee2286e6b0cb4d06bfac849a69574dd29d950b39cd","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":"4b7913e3376b2de7370a5970d8330e81f65574e173a313aec21d5dc5428007dd","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":"03429702fb0781aa0d7082d1ff87b45591c87a19e466c0905ddd3150eb52ceed","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":"882a849a3b180ad11b9622cd5d38b932012672f8a7b7b67c229874bb1862ac48","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":"eb8b57b4881cd186859785495a839aef13bf2e0e2db73970f0b3c804d4f1ea0a","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":"d092260da21786feb5266e642269dc90807ac6a33131fffa66641d95b7544145","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"2a50f49bf524a67b6554ad9e3afc32487403828d09f966191930f7bb701032a1","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"627f955848f6970b3fce5e72f1ccccc136636d67355114ce38aedd886be38db8","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-entry-contract","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"e8d7213538f783ac83a73a2ca082cacdb2011c278d1473a07bc3d667e54a9e09","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"250bf729ec31603b908f4a24cfcd7b732b58c7d362d2fd6aebbb9a82a6948895","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"}
{"closureHash":"cd8d3f56a957044d8c5b62e8f212989ffa77c2ea4d865c094d417097f3d45758","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"}
{"closureHash":"83654579574c8101c8158b4d1a49bd0f72918c26e588d86ac0079aab94bf04de","declaration":"export function createAckReactionHandle(params: { ackReactionValue: string; send: () => Promise<void>; remove: () => Promise<void>; onSendError?: (err: unknown) => void; }): AckReactionHandle | null;","entrypoint":"channel-feedback","exportName":"createAckReactionHandle","importSpecifier":"openclaw/plugin-sdk/channel-feedback","kind":"function","recordType":"export"}
{"closureHash":"16650e7e9aa18195bea992878a273fa2ef564d088dcb872d895387f033fa76f0","declaration":"export function createStatusReactionController(params: { enabled: boolean; adapter: StatusReactionAdapter; initialEmoji: string; emojis?: StatusReactionEmojis; timing?: StatusReactionTiming; onError?: (err: unknown) => void; }): StatusReactionController;","entrypoint":"channel-feedback","exportName":"createStatusReactionController","importSpecifier":"openclaw/plugin-sdk/channel-feedback","kind":"function","recordType":"export"}
@@ -821,9 +821,9 @@
{"closureHash":"4f135bb1dd373312335c02196378368edc69f7512f48bf6d4f6a498c14340484","declaration":"export type StatusReactionEmojis = StatusReactionEmojis;","entrypoint":"channel-feedback","exportName":"StatusReactionEmojis","importSpecifier":"openclaw/plugin-sdk/channel-feedback","kind":"type","recordType":"export"}
{"closureHash":"b673ec55cb115a9cb6b6cba97c839410e36e4d4ddfcca5998ff01876521c9e72","declaration":"export type StatusReactionTiming = StatusReactionTiming;","entrypoint":"channel-feedback","exportName":"StatusReactionTiming","importSpecifier":"openclaw/plugin-sdk/channel-feedback","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"channel-inbound","importSpecifier":"openclaw/plugin-sdk/channel-inbound","recordType":"module"}
{"closureHash":"5012e0bfbfba5f68bff8032ccc56082af2a293e314c340bf250c6a2431ca9c7f","declaration":"export function buildChannelInboundEventContext(params: BuildChannelInboundEventContextAsyncParams): Promise<BuiltChannelInboundEventContext>;\nexport function buildChannelInboundEventContext(params: BuildChannelInboundEventContextParams): BuiltChannelInboundEventContext;","entrypoint":"channel-inbound","exportName":"buildChannelInboundEventContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"b44ede4b85c989679776daa75f72997abbb657747753d3ef1569c03799efd36b","declaration":"export function buildChannelInboundEventContext(params: BuildChannelInboundEventContextAsyncParams): Promise<BuiltChannelInboundEventContext>;\nexport function buildChannelInboundEventContext(params: BuildChannelInboundEventContextParams): BuiltChannelInboundEventContext;","entrypoint":"channel-inbound","exportName":"buildChannelInboundEventContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"8daae3e9dc0e1f6e45f95615d485e25486f261bae83544e6cda331000426a252","declaration":"export function buildChannelInboundMediaPayload(media: readonly InboundMediaFacts[] | null | undefined): ChannelInboundMediaPayload;","entrypoint":"channel-inbound","exportName":"buildChannelInboundMediaPayload","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"a52bb66fff7d6657b879035a98d4cdbe9d40b2675972e1b2f00d79a8e8e1368c","declaration":"export function buildChannelTurnContext(params: BuildChannelTurnContextParams): BuiltChannelTurnContext;","entrypoint":"channel-inbound","exportName":"buildChannelTurnContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"29ed4d823625495cacf13271ae6966e83cc68b75aaf14c8d1b1333eb9326c168","declaration":"export function buildChannelTurnContext(params: BuildChannelTurnContextParams): BuiltChannelTurnContext;","entrypoint":"channel-inbound","exportName":"buildChannelTurnContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"8daae3e9dc0e1f6e45f95615d485e25486f261bae83544e6cda331000426a252","declaration":"export function buildChannelTurnMediaPayload(media: readonly InboundMediaFacts[] | null | undefined): ChannelInboundMediaPayload;","entrypoint":"channel-inbound","exportName":"buildChannelTurnMediaPayload","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"72ebf6b52c0fade0e853243f6d6b499827686a0209a76f1f78b4942226a348eb","declaration":"export function buildMentionRegexes(cfg: OpenClawConfig | undefined, agentId?: string, options?: BuildMentionRegexesOptions): RegExp[];","entrypoint":"channel-inbound","exportName":"buildMentionRegexes","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"dcdbfc4a83fac3936097c3976f2400ac22afd9e953c8a6ba3bd91da42822b32c","declaration":"export function classifyChannelInboundEvent(params: ClassifyChannelInboundEventParams): InboundEventKind;","entrypoint":"channel-inbound","exportName":"classifyChannelInboundEvent","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
@@ -837,7 +837,7 @@
{"closureHash":"552aa82911f9aba585fee69fc351990ad892bd0ba4dd20e69ce6d3c286efc6d4","declaration":"export function dispatchChannelInboundReply(params: AssembledInboundReply): Promise<ChannelTurnResult>;","entrypoint":"channel-inbound","exportName":"dispatchChannelInboundReply","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"3090e3a3315715d8cc2107bf9a577446dc8bc30b05642f5c643b797f79fbb97e","declaration":"export function dispatchChannelInboundTurn(params: ChannelInboundTurnPlan<\"provider_message_sending\">): Promise<ChannelTurnResult>;\nexport function dispatchChannelInboundTurn(params: ChannelInboundTurnPlan): Promise<ChannelTurnResult>;","entrypoint":"channel-inbound","exportName":"dispatchChannelInboundTurn","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"2f997d08980c2c3f531382428c58204ca04e423a64ca201798f7667da15e774e","declaration":"export function dispatchInboundDirectDm(params: DispatchInboundDirectDmParams): Promise<{ route: DirectDmRoute; ctxPayload: FinalizedMsgContext; }>;","entrypoint":"channel-inbound","exportName":"dispatchInboundDirectDm","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"cdf4018d7d355ec02e9126fa21dc9061acda9d2f5612ef590ce0fb4011edf2b3","declaration":"export function dispatchInboundDirectDmWithRuntime(params: DispatchInboundDirectDmParams & { runtime: PluginRuntime; }): Promise<{ route: DirectDmRoute; storePath: string; ctxPayload: FinalizedMsgContext; }>;","entrypoint":"channel-inbound","exportName":"dispatchInboundDirectDmWithRuntime","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"7a8053396c7d9845b096cfe7f930b8e78dbe2401f69c1371a72a810845bfeba3","declaration":"export function dispatchInboundDirectDmWithRuntime(params: DispatchInboundDirectDmParams & { runtime: PluginRuntime; }): Promise<{ route: DirectDmRoute; storePath: string; ctxPayload: FinalizedMsgContext; }>;","entrypoint":"channel-inbound","exportName":"dispatchInboundDirectDmWithRuntime","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"33cb9d760233f3d322599f7745a42e0b9fe2c653ffb9310d8b579f2d70f7638c","declaration":"export function filterChannelInboundQuoteContext(contextVisibility: ContextVisibilityMode | undefined, quote: SupplementalContextFacts[\"quote\"] | undefined): SupplementalContextFacts[\"quote\"] | undefined;","entrypoint":"channel-inbound","exportName":"filterChannelInboundQuoteContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"793b9b84aacb8f5b12daf857de82efc579fa018ba6b2357b0acd044be3dcec5f","declaration":"export function filterChannelInboundSupplementalContext(params: { supplemental?: SupplementalContextFacts; contextVisibility?: ContextVisibilityMode; }): SupplementalContextFacts | undefined;","entrypoint":"channel-inbound","exportName":"filterChannelInboundSupplementalContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"ff1797f8e6adf2331d98af9947dcefef02d743c2c7619fc8b5a2462980cb7126","declaration":"export function finalizeChannelInboundContext<T extends Record<string, unknown>>(params: FinalizeChannelInboundContextAsyncParams<T>): Promise<FinalizeChannelInboundContextResult<T>>;\nexport function finalizeChannelInboundContext<T extends Record<string, unknown>>(params: FinalizeChannelInboundContextParams<T>): FinalizeChannelInboundContextResult<T>;","entrypoint":"channel-inbound","exportName":"finalizeChannelInboundContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
@@ -862,7 +862,7 @@
{"closureHash":"6b537112d5d84ed07c0b9fd24787eabc2f893f7bfdce1ed5915f88574a7e101c","declaration":"export function normalizeMentionText(text: string): string;","entrypoint":"channel-inbound","exportName":"normalizeMentionText","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"92900098c3cc5b73fba7622a3aa5a1a8c48462ff7ec0cfae8ee0a3aa6f8277f0","declaration":"export function normalizeOutboundLocation(value: unknown, label?: string): OutboundLocation | undefined;","entrypoint":"channel-inbound","exportName":"normalizeOutboundLocation","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"65f5f2725c1124096e437bcf5894983eee1023f7033be886f1a506044b77c58e","declaration":"export function recordChannelBotPairLoopAndCheckSuppression(params: ChannelBotLoopProtectionFacts): PairLoopGuardResult;","entrypoint":"channel-inbound","exportName":"recordChannelBotPairLoopAndCheckSuppression","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"b8271620147b917162fda83897092229d5691a4e418288a79912ae41775e83da","declaration":"export function recordChannelFeedbackEvent(params: { cfg: OpenClawConfig; agentId: string; sessionKey: string; event: Parameters<typeof appendTranscriptEvent>[1]; }): Promise<boolean>;","entrypoint":"channel-inbound","exportName":"recordChannelFeedbackEvent","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"8fdc2a5a83820b372e4047777ed9fc1bd8e530c68e76da89abb3b6653546e2ab","declaration":"export function recordChannelFeedbackEvent(params: { cfg: OpenClawConfig; agentId: string; sessionKey: string; event: Parameters<typeof appendTranscriptEvent>[1]; }): Promise<boolean>;","entrypoint":"channel-inbound","exportName":"recordChannelFeedbackEvent","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"33b4280a69de6a4a87acf915c6d694b9ee41fc4f0262a1bb9836c46d53fe337c","declaration":"export function recordDroppedChannelInboundHistory(params: { input: NormalizedTurnInput; preflight: PreflightFacts; admission?: ChannelTurnAdmission; }): Promise<void>;","entrypoint":"channel-inbound","exportName":"recordDroppedChannelInboundHistory","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"33b4280a69de6a4a87acf915c6d694b9ee41fc4f0262a1bb9836c46d53fe337c","declaration":"export function recordDroppedChannelTurnHistory(params: { input: NormalizedTurnInput; preflight: PreflightFacts; admission?: ChannelTurnAdmission; }): Promise<void>;","entrypoint":"channel-inbound","exportName":"recordDroppedChannelTurnHistory","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
{"closureHash":"54b920fd80ac659a03000356b64e34d4a44ec22ae39a77accdd2ac97dc5a094e","declaration":"export function resolveChannelInboundRouteEnvelope(params: ResolveAgentRouteInput): { route: ResolvedAgentRoute; buildEnvelope: (input: ChannelInboundEnvelopeInput) => string; };","entrypoint":"channel-inbound","exportName":"resolveChannelInboundRouteEnvelope","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"}
@@ -887,9 +887,9 @@
{"closureHash":"03bfa4a5365916c2d9f59e4e3c5c6ae3ee7952b2aec209c232bf73a5ccd2ae94","declaration":"export const filterChannelTurnSupplementalContext: (params: { supplemental?: SupplementalContextFacts; contextVisibility?: ContextVisibilityMode;}) => SupplementalContextFacts | undefined;","entrypoint":"channel-inbound","exportName":"filterChannelTurnSupplementalContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"const","recordType":"export"}
{"closureHash":"b028978582295be29c22e06673b8f1b48819511b6b8c26cfff9e322ddc2834e3","declaration":"export type AccessGroupMembershipResolver = AccessGroupMembershipResolver;","entrypoint":"channel-inbound","exportName":"AccessGroupMembershipResolver","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"10d47ee68a65fa2df62012bf98988026560dd0bc30d2be56783ed4132864a149","declaration":"export type AssembledInboundReply = AssembledChannelTurn;","entrypoint":"channel-inbound","exportName":"AssembledInboundReply","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"16e04f044a9af3553fa26fec210bf6d2e6e101c4fe4db18b8914fce21dce573f","declaration":"export type BuildChannelInboundEventContextAsyncParams = BuildChannelInboundEventContextAsyncParams;","entrypoint":"channel-inbound","exportName":"BuildChannelInboundEventContextAsyncParams","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"bfda516454e1d03a16f685f9470c8ce4329328d5658b5ca26bc703c70c5d17c8","declaration":"export type BuildChannelInboundEventContextParams = BuildChannelInboundEventContextParams;","entrypoint":"channel-inbound","exportName":"BuildChannelInboundEventContextParams","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"b6ce3464585a1f042b94574c385dd57ca9be83740ef0fc929db769710dc78061","declaration":"export type BuildChannelTurnContextParams = BuildChannelTurnContextParams;","entrypoint":"channel-inbound","exportName":"BuildChannelTurnContextParams","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"daa855f59ea9d4082f745a763edd8468bd10ef51e0d18740261067cbe39d712b","declaration":"export type BuildChannelInboundEventContextAsyncParams = BuildChannelInboundEventContextAsyncParams;","entrypoint":"channel-inbound","exportName":"BuildChannelInboundEventContextAsyncParams","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"ea286077c4c5222cec3f60186d2920ea535e78e29b3ddc0097c6189f8bd36815","declaration":"export type BuildChannelInboundEventContextParams = BuildChannelInboundEventContextParams;","entrypoint":"channel-inbound","exportName":"BuildChannelInboundEventContextParams","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"90bafa21f065ea6c027f3e40923c34807f265f09f45d4e9bfbb99a0c1179f691","declaration":"export type BuildChannelTurnContextParams = BuildChannelTurnContextParams;","entrypoint":"channel-inbound","exportName":"BuildChannelTurnContextParams","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"6d2f3cd2420a24adc0336afba6a24ec41301e83c2796d56c18d1aee69b7eba4b","declaration":"export type BuildMentionRegexesOptions = BuildMentionRegexesOptions;","entrypoint":"channel-inbound","exportName":"BuildMentionRegexesOptions","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"c7356eefdaeb352d2552e3f5df112db261cc7043ed4c488b3f3212cc981f112a","declaration":"export type BuiltChannelInboundEventContext = BuiltChannelInboundEventContext;","entrypoint":"channel-inbound","exportName":"BuiltChannelInboundEventContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
{"closureHash":"30712d6ebecf99636dd58269720814c94af71ef9d8bcb818dad50bd3dc82aaca","declaration":"export type BuiltChannelTurnContext = BuiltChannelTurnContext;","entrypoint":"channel-inbound","exportName":"BuiltChannelTurnContext","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"type","recordType":"export"}
@@ -1034,7 +1034,7 @@
{"closureHash":"acd64a0d6ce6dbd9db22f9e4a4497cef2110a9e962f240c6f5e90cef31505459","declaration":"export function createFinalizableDraftStreamControlsForState<T = string>(params: { throttleMs: number; state: FinalizableDraftStreamState; sendOrEditStreamMessage: (value: T) => Promise<void | boolean>; emptyValue?: T; isEmpty?: (value: T) => boolean; }): { loop: DraftStreamLoop<T> & { takePending: () => T; }; update: (value: T) => void; stop: () => Promise<void>; seal: () => Promise<void>; discardPending: () => Promise<void>; stopForClear: () => Promise<void>; };","entrypoint":"channel-message","exportName":"createFinalizableDraftStreamControlsForState","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"f2bb1868ec1cf7d97e6b8eb0a9a8a37122ec53c9cd4e2bbfc8448c1555f3d382","declaration":"export function createMessageReceiptFromOutboundResults(params: { results: readonly MessageReceiptInputResult[]; kind?: MessageReceiptPartKind; threadId?: string; replyToId?: string; sentAt?: number; }): MessageReceipt;","entrypoint":"channel-message","exportName":"createMessageReceiptFromOutboundResults","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"3c150fb027a4e4a1685b572d26aa1f70b3838641bd7629434c4265bfda549d0a","declaration":"export function createMessageReceiveContext<TMessage>(params: { id: string; channel: string; accountId?: string; message: TMessage; ackPolicy?: MessageAckPolicy; receivedAt?: number; signal?: AbortSignal; onAck?: () => Promise<void> | void; onNack?: (error: unknown) => Promise<void> | void; }): MessageReceiveContext<TMessage>;","entrypoint":"channel-message","exportName":"createMessageReceiveContext","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"93906d2c7105382007072ea3e79787732a62828361034e59306d3cd0f5b05a25","declaration":"export function createOutboundPayloadPlan(payloads: readonly ReplyPayload[], context?: OutboundPayloadPlanContext): OutboundPayloadPlan[];","entrypoint":"channel-message","exportName":"createOutboundPayloadPlan","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"1df70a2d9c8a3d6bb0813a5f03c8eea7ed85334428c8cf8e4004c567212a1448","declaration":"export function createOutboundPayloadPlan(payloads: readonly ReplyPayload[], context?: OutboundPayloadPlanContext): OutboundPayloadPlan[];","entrypoint":"channel-message","exportName":"createOutboundPayloadPlan","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"7abc004852a9162c3f4241d6c80b9962c9732dd03d2d38a56e4080a4e92758a1","declaration":"export function createPreviewMessageReceipt(params: { id: unknown; threadId?: string; replyToId?: string; sentAt?: number; raw?: unknown; }): MessageReceipt;","entrypoint":"channel-message","exportName":"createPreviewMessageReceipt","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"449a8d46d726b3de6fdf7aabf60939d37565ef5701ef58dd91b817040712ab87","declaration":"export function createReplyPrefixContext(params: { cfg: OpenClawConfig; agentId: string; channel?: string; accountId?: string; }): ReplyPrefixContextBundle;","entrypoint":"channel-message","exportName":"createReplyPrefixContext","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"acb4b6a4562c6a6ac30594fcd9431a9aabb031135fff7faa41a74067139ab572","declaration":"export function createReplyPrefixOptions(params: { cfg: OpenClawConfig; agentId: string; channel?: string; accountId?: string; }): ReplyPrefixOptions;","entrypoint":"channel-message","exportName":"createReplyPrefixOptions","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
@@ -1063,7 +1063,7 @@
{"closureHash":"844a3251dcba84a9735c855d7b6c930570cc486f3a1c5fc49b541572d52bb7d7","declaration":"export function normalizeAgentPlanSteps(value: unknown): AgentPlanStep[] | undefined;","entrypoint":"channel-message","exportName":"normalizeAgentPlanSteps","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"b19d38e15e2054e826fd132198c606165fc369fb5a96f4e6bbbf7b89bee35ac2","declaration":"export function normalizeChannelProgressDraftLineIdentity(line: string | ChannelProgressDraftLine | undefined): string;","entrypoint":"channel-message","exportName":"normalizeChannelProgressDraftLineIdentity","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"ba2389600eeea10867e3891e411bd84e8fd07dcd410249c29ca92ba59ef27bad","declaration":"export function processPidFromOwnerId(ownerId: string): number;","entrypoint":"channel-message","exportName":"processPidFromOwnerId","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"70bfbeeee4a0a2290cbf9620933c2bf7d00fbcaf3c20958c2064f5e2ce5a0bb8","declaration":"export function projectOutboundPayloadPlanForDelivery(plan: readonly OutboundPayloadPlan[]): ReplyPayload[];","entrypoint":"channel-message","exportName":"projectOutboundPayloadPlanForDelivery","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"56fc827d94dd02fdb7eda0269d63e67eed7716da3e373b74b6d2e68ebf797661","declaration":"export function projectOutboundPayloadPlanForDelivery(plan: readonly OutboundPayloadPlan[]): ReplyPayload[];","entrypoint":"channel-message","exportName":"projectOutboundPayloadPlanForDelivery","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"bc16377d8f9c3467da5115ff2d6b3ef0423980794a0f5af287b1f1e8ee9533ef","declaration":"export function recordOutboundMessageIdentity(identity: OutboundMessageIdentity): void;","entrypoint":"channel-message","exportName":"recordOutboundMessageIdentity","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"3090faaaca1e2c970a0eadbb7792c531a053746df6df83a082d8564a8313b401","declaration":"export function resolveAgentOutboundIdentity(cfg: OpenClawConfig, agentId: string): OutboundIdentity | undefined;","entrypoint":"channel-message","exportName":"resolveAgentOutboundIdentity","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
{"closureHash":"ba763bf7ff1dee852fb9b58f5995f9df744028d47ca29f687b215ba316c66723","declaration":"export function resolveChannelDraftStreamingChunking(cfg: OpenClawConfig | undefined, channelId: ChannelId, accountId: string | null | undefined, opts: { fallbackLimit: number; }): ChannelDraftStreamingChunking;","entrypoint":"channel-message","exportName":"resolveChannelDraftStreamingChunking","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"function","recordType":"export"}
@@ -1103,7 +1103,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":"64792a0c33912731a154f8e8e1b3f598b3396d2e0b93ed35fb4cc67a150bf9e2","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":"8b9f39e06d068cd2497a07a2f0ee78c2e5497a58eca6e7e6c2da2ba93535f23c","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"}
@@ -1166,7 +1166,7 @@
{"closureHash":"acd64a0d6ce6dbd9db22f9e4a4497cef2110a9e962f240c6f5e90cef31505459","declaration":"export function createFinalizableDraftStreamControlsForState<T = string>(params: { throttleMs: number; state: FinalizableDraftStreamState; sendOrEditStreamMessage: (value: T) => Promise<void | boolean>; emptyValue?: T; isEmpty?: (value: T) => boolean; }): { loop: DraftStreamLoop<T> & { takePending: () => T; }; update: (value: T) => void; stop: () => Promise<void>; seal: () => Promise<void>; discardPending: () => Promise<void>; stopForClear: () => Promise<void>; };","entrypoint":"channel-outbound","exportName":"createFinalizableDraftStreamControlsForState","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"f2bb1868ec1cf7d97e6b8eb0a9a8a37122ec53c9cd4e2bbfc8448c1555f3d382","declaration":"export function createMessageReceiptFromOutboundResults(params: { results: readonly MessageReceiptInputResult[]; kind?: MessageReceiptPartKind; threadId?: string; replyToId?: string; sentAt?: number; }): MessageReceipt;","entrypoint":"channel-outbound","exportName":"createMessageReceiptFromOutboundResults","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"3c150fb027a4e4a1685b572d26aa1f70b3838641bd7629434c4265bfda549d0a","declaration":"export function createMessageReceiveContext<TMessage>(params: { id: string; channel: string; accountId?: string; message: TMessage; ackPolicy?: MessageAckPolicy; receivedAt?: number; signal?: AbortSignal; onAck?: () => Promise<void> | void; onNack?: (error: unknown) => Promise<void> | void; }): MessageReceiveContext<TMessage>;","entrypoint":"channel-outbound","exportName":"createMessageReceiveContext","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"93906d2c7105382007072ea3e79787732a62828361034e59306d3cd0f5b05a25","declaration":"export function createOutboundPayloadPlan(payloads: readonly ReplyPayload[], context?: OutboundPayloadPlanContext): OutboundPayloadPlan[];","entrypoint":"channel-outbound","exportName":"createOutboundPayloadPlan","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"1df70a2d9c8a3d6bb0813a5f03c8eea7ed85334428c8cf8e4004c567212a1448","declaration":"export function createOutboundPayloadPlan(payloads: readonly ReplyPayload[], context?: OutboundPayloadPlanContext): OutboundPayloadPlan[];","entrypoint":"channel-outbound","exportName":"createOutboundPayloadPlan","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"7abc004852a9162c3f4241d6c80b9962c9732dd03d2d38a56e4080a4e92758a1","declaration":"export function createPreviewMessageReceipt(params: { id: unknown; threadId?: string; replyToId?: string; sentAt?: number; raw?: unknown; }): MessageReceipt;","entrypoint":"channel-outbound","exportName":"createPreviewMessageReceipt","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"449a8d46d726b3de6fdf7aabf60939d37565ef5701ef58dd91b817040712ab87","declaration":"export function createReplyPrefixContext(params: { cfg: OpenClawConfig; agentId: string; channel?: string; accountId?: string; }): ReplyPrefixContextBundle;","entrypoint":"channel-outbound","exportName":"createReplyPrefixContext","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"acb4b6a4562c6a6ac30594fcd9431a9aabb031135fff7faa41a74067139ab572","declaration":"export function createReplyPrefixOptions(params: { cfg: OpenClawConfig; agentId: string; channel?: string; accountId?: string; }): ReplyPrefixOptions;","entrypoint":"channel-outbound","exportName":"createReplyPrefixOptions","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
@@ -1193,7 +1193,7 @@
{"closureHash":"844a3251dcba84a9735c855d7b6c930570cc486f3a1c5fc49b541572d52bb7d7","declaration":"export function normalizeAgentPlanSteps(value: unknown): AgentPlanStep[] | undefined;","entrypoint":"channel-outbound","exportName":"normalizeAgentPlanSteps","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"b19d38e15e2054e826fd132198c606165fc369fb5a96f4e6bbbf7b89bee35ac2","declaration":"export function normalizeChannelProgressDraftLineIdentity(line: string | ChannelProgressDraftLine | undefined): string;","entrypoint":"channel-outbound","exportName":"normalizeChannelProgressDraftLineIdentity","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"ba2389600eeea10867e3891e411bd84e8fd07dcd410249c29ca92ba59ef27bad","declaration":"export function processPidFromOwnerId(ownerId: string): number;","entrypoint":"channel-outbound","exportName":"processPidFromOwnerId","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"70bfbeeee4a0a2290cbf9620933c2bf7d00fbcaf3c20958c2064f5e2ce5a0bb8","declaration":"export function projectOutboundPayloadPlanForDelivery(plan: readonly OutboundPayloadPlan[]): ReplyPayload[];","entrypoint":"channel-outbound","exportName":"projectOutboundPayloadPlanForDelivery","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"56fc827d94dd02fdb7eda0269d63e67eed7716da3e373b74b6d2e68ebf797661","declaration":"export function projectOutboundPayloadPlanForDelivery(plan: readonly OutboundPayloadPlan[]): ReplyPayload[];","entrypoint":"channel-outbound","exportName":"projectOutboundPayloadPlanForDelivery","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"bc16377d8f9c3467da5115ff2d6b3ef0423980794a0f5af287b1f1e8ee9533ef","declaration":"export function recordOutboundMessageIdentity(identity: OutboundMessageIdentity): void;","entrypoint":"channel-outbound","exportName":"recordOutboundMessageIdentity","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"3090faaaca1e2c970a0eadbb7792c531a053746df6df83a082d8564a8313b401","declaration":"export function resolveAgentOutboundIdentity(cfg: OpenClawConfig, agentId: string): OutboundIdentity | undefined;","entrypoint":"channel-outbound","exportName":"resolveAgentOutboundIdentity","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
{"closureHash":"ba763bf7ff1dee852fb9b58f5995f9df744028d47ca29f687b215ba316c66723","declaration":"export function resolveChannelDraftStreamingChunking(cfg: OpenClawConfig | undefined, channelId: ChannelId, accountId: string | null | undefined, opts: { fallbackLimit: number; }): ChannelDraftStreamingChunking;","entrypoint":"channel-outbound","exportName":"resolveChannelDraftStreamingChunking","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"function","recordType":"export"}
@@ -1232,7 +1232,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":"64792a0c33912731a154f8e8e1b3f598b3396d2e0b93ed35fb4cc67a150bf9e2","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":"8b9f39e06d068cd2497a07a2f0ee78c2e5497a58eca6e7e6c2da2ba93535f23c","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"}
@@ -1276,13 +1276,13 @@
{"closureHash":"424d0b4b21b078d07a49a7bc52c3b63250be032a3e17f47c0cc824178b828ded","declaration":"export type TextChunkMode = TextChunkMode;","entrypoint":"channel-outbound","exportName":"TextChunkMode","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"}
{"category":"channel","entrypoint":"channel-pairing","importSpecifier":"openclaw/plugin-sdk/channel-pairing","recordType":"module"}
{"closureHash":"3d2325df85dcb397e7df5c9f380c5d6c517976527acbe7d94d59df8777810d1f","declaration":"export function createChannelPairingChallengeIssuer(params: { channel: ChannelId; accountId?: string; upsertPairingRequest: Parameters<typeof issuePairingChallenge>[0][\"upsertPairingRequest\"]; }): (challenge: Omit<Parameters<typeof issuePairingChallenge>[0], \"channel\" | \"accountId\" | \"upsertPairingRequest\">) => Promise<{ created: boolean; code?: string; }>;","entrypoint":"channel-pairing","exportName":"createChannelPairingChallengeIssuer","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"function","recordType":"export"}
{"closureHash":"3445b7e876a52e005ac43b3864407134c832f481c7883123f77f06121197a229","declaration":"export function createChannelPairingController(params: { core: PluginRuntime; channel: ChannelId; accountId: string; }): ChannelPairingController;","entrypoint":"channel-pairing","exportName":"createChannelPairingController","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"function","recordType":"export"}
{"closureHash":"f1d737696e5df256426c5de34feda92285556bf334e5a2a391313c4db7c24f2c","declaration":"export function createChannelPairingController(params: { core: PluginRuntime; channel: ChannelId; accountId: string; }): ChannelPairingController;","entrypoint":"channel-pairing","exportName":"createChannelPairingController","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"function","recordType":"export"}
{"closureHash":"39648d8f2d5ec14a204569c6266100fef1e455dd53dd6b05ae3034dc98986875","declaration":"export function createLoggedPairingApprovalNotifier(format: string | ((params: PairingNotifyParams) => string), log?: (message: string) => void): NonNullable<ChannelPairingAdapter[\"notifyApproval\"]>;","entrypoint":"channel-pairing","exportName":"createLoggedPairingApprovalNotifier","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"function","recordType":"export"}
{"closureHash":"d5198bb50f3f1c60b384feb93ae07621ceeca6f7d7f7c729ec96dabe984eca10","declaration":"export function createPairingPrefixStripper(prefixRe: RegExp, map?: (entry: string) => string): NonNullable<ChannelPairingAdapter[\"normalizeAllowEntry\"]>;","entrypoint":"channel-pairing","exportName":"createPairingPrefixStripper","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"function","recordType":"export"}
{"closureHash":"b914a433d104666e368d9e2c85d328e0015168b8ad3ade34bc993d3cc7141513","declaration":"export function createTextPairingAdapter(params: { idLabel: string; message: string; normalizeAllowEntry?: ChannelPairingAdapter[\"normalizeAllowEntry\"]; notify: (params: PairingNotifyParams & { message: string; }) => Promise<void> | void; }): ChannelPairingAdapter;","entrypoint":"channel-pairing","exportName":"createTextPairingAdapter","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"function","recordType":"export"}
{"closureHash":"ec2b230fc869584bf4114bc30b34546f3e3e9369d7b6f49d9ff3bc8b19dd1989","declaration":"export function readChannelAllowFromStore(channel: PairingChannel, env?: NodeJS.ProcessEnv, accountId?: string): Promise<string[]>;","entrypoint":"channel-pairing","exportName":"readChannelAllowFromStore","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"function","recordType":"export"}
{"closureHash":"efe4915252d6eb26af5b1c52dadf22e05b4a13f1668a10cc508c0aa4bae11e39","declaration":"export function readChannelAllowFromStoreSync(channel: PairingChannel, env?: NodeJS.ProcessEnv, accountId?: string): string[];","entrypoint":"channel-pairing","exportName":"readChannelAllowFromStoreSync","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"function","recordType":"export"}
{"closureHash":"45a75829d749deafc60692dcff0404d0cbc717cecac807b87e607a5dcc8ff611","declaration":"export type ChannelPairingController = ChannelPairingController;","entrypoint":"channel-pairing","exportName":"ChannelPairingController","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"type","recordType":"export"}
{"closureHash":"fec0eda83190d6050123f4a2802bca17cc9fa3d0a062fca218e8d1c59d490398","declaration":"export type ChannelPairingController = ChannelPairingController;","entrypoint":"channel-pairing","exportName":"ChannelPairingController","importSpecifier":"openclaw/plugin-sdk/channel-pairing","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"channel-plugin-common","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","recordType":"module"}
{"closureHash":"19a3d4c1fdad2b565e7428da26e0dafa76f08498bcf06ac3df098486ff4afc2c","declaration":"export function applyAccountNameToChannelSection(params: { cfg: OpenClawConfig; channelKey: string; accountId: string; name?: string; alwaysUseAccounts?: boolean; }): OpenClawConfig;","entrypoint":"channel-plugin-common","exportName":"applyAccountNameToChannelSection","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"function","recordType":"export"}
{"closureHash":"e97ff96104ab3b7f8462f20d39d2596908a59cb03a634c6c2fb0d7ff80e5bb54","declaration":"export function buildChannelConfigSchema(schema: ZodTypeAny, options?: BuildChannelConfigSchemaOptions): ChannelConfigSchema;","entrypoint":"channel-plugin-common","exportName":"buildChannelConfigSchema","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"function","recordType":"export"}
@@ -1298,8 +1298,8 @@
{"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":"d02e5c7a995847180696d2a05d8ea092b364ef32b36753e4091fc97ffdaf44ab","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":"2ddf03be75f0d46c8a7e1d7a3d3e70122001b190dcb361132cef2f1d23d8ddec","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-plugin-common","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"closureHash":"b94637421f524b48f7e497e449491475a2cc35f3d6dc43bdf5274b401b9424b0","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"channel-plugin-common","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"closureHash":"aded5b666490cf7e5cca6bf3942c5190ad1fc30fc73f542505c53e5999f649a9","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-plugin-common","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"}
{"closureHash":"8d8f8c012d739749de557261960af8c0c714403fefa6fa15bd06ddbaee90aee3","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"}
{"closureHash":"628863a501a389d1fee7ab465a4e9da1751189011e9086a54ab22bfc1f970c8a","declaration":"export function buildChannelGroupsScopeTree(cfg: OpenClawConfig, channel: ChannelId, accountId?: string | null): ScopeTree;","entrypoint":"channel-policy","exportName":"buildChannelGroupsScopeTree","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"}
@@ -1871,7 +1871,7 @@
{"closureHash":"1722c0b0bd09f4a630f5b60e68840478287323ddd401d05fa8d69a9b26d27a74","declaration":"export function resolveThreadBindingThreadName(params: { agentId?: string; label?: string; }): string;","entrypoint":"conversation-runtime","exportName":"resolveThreadBindingThreadName","importSpecifier":"openclaw/plugin-sdk/conversation-runtime","kind":"function","recordType":"export"}
{"closureHash":"98acce64bde4ebfd62ed516fc45829c52c58630c06db6039e282721215af18e4","declaration":"export function resolveThreadBindingsEnabled(params: { channelEnabledRaw: unknown; sessionEnabledRaw: unknown; }): boolean;","entrypoint":"conversation-runtime","exportName":"resolveThreadBindingsEnabled","importSpecifier":"openclaw/plugin-sdk/conversation-runtime","kind":"function","recordType":"export"}
{"closureHash":"6f1d515e9f84bd96d6c6dddca3ebdecc3919838ae043f04c3b7fe9dd8def64a6","declaration":"export function unregisterSessionBindingAdapter(params: { channel: string; accountId: string; adapter?: SessionBindingAdapter; }): void;","entrypoint":"conversation-runtime","exportName":"unregisterSessionBindingAdapter","importSpecifier":"openclaw/plugin-sdk/conversation-runtime","kind":"function","recordType":"export"}
{"closureHash":"9fa1d7adb6620d769dd78db2b1612cdd262871d0d956b5a2e38a18dae4231f2b","declaration":"export function upsertChannelPairingRequest(params: { channel: PairingChannel; id: string | number; accountId: string; meta?: Record<string, string | undefined | null>; env?: NodeJS.ProcessEnv; pairingAdapter?: ChannelPairingAdapter; }): Promise<{ code: string; created: boolean; }>;","entrypoint":"conversation-runtime","exportName":"upsertChannelPairingRequest","importSpecifier":"openclaw/plugin-sdk/conversation-runtime","kind":"function","recordType":"export"}
{"closureHash":"1a40df66a0a0fa20308f970b74c9df993d312ef3e4d67db751e0ddbde3af3461","declaration":"export function upsertChannelPairingRequest(params: { channel: PairingChannel; id: string | number; accountId: string; meta?: Record<string, string | undefined | null>; env?: NodeJS.ProcessEnv; pairingAdapter?: ChannelPairingAdapter; memoryIdentityAdmission?: unknown; }): Promise<{ code: string; created: boolean; }>;","entrypoint":"conversation-runtime","exportName":"upsertChannelPairingRequest","importSpecifier":"openclaw/plugin-sdk/conversation-runtime","kind":"function","recordType":"export"}
{"closureHash":"95a50e38ff0a3b6f23130bce09088e1480cffeef9ac6f4cf447317627f96b58a","declaration":"export const testing: { resetSessionBindingAdaptersForTests(): void; getRegisteredAdapterKeys(): string[];};","entrypoint":"conversation-runtime","exportName":"testing","importSpecifier":"openclaw/plugin-sdk/conversation-runtime","kind":"const","recordType":"export"}
{"closureHash":"003fe46b2233b284dfa7a8b91ed47770d2841dca6aa8764a45f6417f94f529e7","declaration":"export type BindingTargetKind = BindingTargetKind;","entrypoint":"conversation-runtime","exportName":"BindingTargetKind","importSpecifier":"openclaw/plugin-sdk/conversation-runtime","kind":"type","recordType":"export"}
{"closureHash":"0c252e3774705f4c7ff23efe753348ccc467f2c6c829fbcb1ba5788bdb84ece5","declaration":"export type ConfiguredBindingRouteResult = ConfiguredBindingRouteResult;","entrypoint":"conversation-runtime","exportName":"ConfiguredBindingRouteResult","importSpecifier":"openclaw/plugin-sdk/conversation-runtime","kind":"type","recordType":"export"}
@@ -1886,7 +1886,7 @@
{"closureHash":"d734ae6f08592256df8498061c3417f0914fca32019a24b5dc39edcb5d0c118c","declaration":"export function buildChannelOutboundSessionRoute(params: { cfg: OpenClawConfig; agentId: string; channel: string; accountId?: string | null; recipientSessionExact?: boolean | \"direct-alias\" | \"delivery-identity\"; peer: { kind: \"direct\" | \"group\" | \"channel\"; id: string; }; chatType: \"direct\" | \"group\" | \"channel\"; from: string; to: string; threadId?: string | number; }): ChannelOutboundSessionRoute;","entrypoint":"core","exportName":"buildChannelOutboundSessionRoute","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"90d3722f2e13daa2c010659f41d63c50b35a238eac51b8137b1f7824da23055c","declaration":"export function buildJsonChannelConfigSchema(schema: JsonSchemaObject, options?: BuildJsonChannelConfigSchemaOptions): ChannelConfigSchema;","entrypoint":"core","exportName":"buildJsonChannelConfigSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"3d27406644141af2733cfca6e8c1240fc62327910109f585ce9073cafd7fd89c","declaration":"export function buildJsonPluginConfigSchema(schema: JsonSchemaObject, options?: BuildJsonPluginConfigSchemaOptions): OpenClawPluginConfigSchema;","entrypoint":"core","exportName":"buildJsonPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"f26e2150ba5824e830978cd15a8d5ed83d5150c44050a5050d6653b773ea4765","declaration":"export function buildMemorySystemPromptAddition(params: MemoryPromptSectionParams): string | undefined;","entrypoint":"core","exportName":"buildMemorySystemPromptAddition","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"f0e859e945b5f950a5ed8ee5070dc19ed16e685400b41dfa35554f26867b83d4","declaration":"export function buildMemorySystemPromptAddition(params: MemoryPromptSectionParams): string | undefined;","entrypoint":"core","exportName":"buildMemorySystemPromptAddition","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"aff66c792d532642afb9c6e5a03c8d220f219250c3a8b49733f32058f22f98ca","declaration":"export function buildPluginConfigSchema(schema: ZodTypeAny, options?: BuildPluginConfigSchemaOptions): OpenClawPluginConfigSchema;","entrypoint":"core","exportName":"buildPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"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":"core","exportName":"buildThreadAwareOutboundSessionRoute","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"42e686a8f08f2bf03a7b25d14cdcfa089bb6bd8e2654eab8ca9d786df65580d6","declaration":"export function channelTargetSchema(options?: { description?: string; }): Type.TString;","entrypoint":"core","exportName":"channelTargetSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
@@ -1897,8 +1897,8 @@
{"closureHash":"9e93bcdfc6299e65ef2a3d267047a9e8c856f0b2f8e9b79d570fb2a4cd238c74","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":"ad9a5a09235e9a426da9b310cd466830ad103dda2e5ce4891ef4131fdf50deda","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":"fd766c74118002291fa28dcd19a9677cdf9f615fe09994862f95b989dd36479a","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":"cb5d7b4d9caafb5d1eaa57839fe6cb95e714bac30f9b697c720b32913c22eec5","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":"bcdcc487ce9eee949611005455c7cb794c78852875f5749d1712e27c02ce4cf8","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"}
@@ -1922,7 +1922,7 @@
{"closureHash":"0a8fd5850a674bce2d579cfe904dee5e0feb1ea240f4efb5d9df3ba99b5e8791","declaration":"export function optionalStringEnum<T extends readonly string[]>(values: T, options?: StringEnumOptions<T>): Type.TOptional<Type.TUnsafe<T[number]> | Type.TEnum<T[number][]>>;","entrypoint":"core","exportName":"optionalStringEnum","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"8895f7af11b994dcd383ebc45d8cfb3c3b1e6d88a64a001b04f604a83f77e517","declaration":"export function parseOptionalDelimitedEntries(value?: string): string[] | undefined;","entrypoint":"core","exportName":"parseOptionalDelimitedEntries","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"7024da55c2fffd041869aa12cca99a6ebbe4e961ce255e08c83aadc48e3bc574","declaration":"export function parseStrictPositiveInteger(value: unknown): number | undefined;","entrypoint":"core","exportName":"parseStrictPositiveInteger","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"c7378a8a76cf3588080a64f47c77acc7b01c692a0495eff64f25205bca6d5217","declaration":"export function prepareMemorySystemPromptAddition(params: MemoryPromptSectionParams): Promise<string | undefined>;","entrypoint":"core","exportName":"prepareMemorySystemPromptAddition","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"ffdcce01aaf21322f1dd5ee373cac4e05fbd0289616724547bf40605fc8917fa","declaration":"export function prepareMemorySystemPromptAddition(params: MemoryPromptSectionParams): Promise<string | undefined>;","entrypoint":"core","exportName":"prepareMemorySystemPromptAddition","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"824b72afe6f331a51be4b6fc77fc8ee98570526d2ee63bf0404ed3432c11515c","declaration":"export function readNumberParam(params: Record<string, unknown>, key: string, options?: { required?: boolean; label?: string; integer?: boolean; strict?: boolean; positiveInteger?: boolean; nonNegativeInteger?: boolean; }): number | undefined;","entrypoint":"core","exportName":"readNumberParam","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":"650210a986670f4fc6928fcb58f076c28653cc5c1a7cd605120c714b589b7b14","declaration":"export function readReactionParams(params: Record<string, unknown>, options: { emojiKey?: string; removeKey?: string; removeErrorMessage: string; }): ReactionParams;","entrypoint":"core","exportName":"readReactionParams","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
{"closureHash":null,"declaration":"export function readSecretFileSync(filePath: string, label: string, options?: SecretFileReadOptions): string;","entrypoint":"core","exportName":"readSecretFileSync","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"}
@@ -1945,7 +1945,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":"d759a25775cb15d3f1804e39e98518f83b67b29ba3ab2fd84d4bf16106d9fdb9","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"core","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"cff7e843ff24f7db2fd0f413d247310c86216bd9b51393b64c22f0ef85cda68e","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"}
@@ -1971,23 +1971,23 @@
{"closureHash":"78083326f70178db2368226b2fe443362e976e63949ab31ebe46dbc4c8efc7f0","declaration":"export type GatewayRequestHandlerOptions = GatewayRequestHandlerOptions;","entrypoint":"core","exportName":"GatewayRequestHandlerOptions","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"db78504773a1bbfa02018d7352dadbbdae4fcaded93f514c97ba126cbc849f3b","declaration":"export type HistoryEntry = HistoryEntry;","entrypoint":"core","exportName":"HistoryEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"c241077e3f27058240f750d07561778eccb3e7a2dc99be94023eac84cbab7c73","declaration":"export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;","entrypoint":"core","exportName":"MediaUnderstandingProviderPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"0b824778ee420a4a199233d8fe4635960ed53a0c96964a9e90e8e9e31c9ffe4b","declaration":"export type MemoryPluginCapability = MemoryPluginCapability;","entrypoint":"core","exportName":"MemoryPluginCapability","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"786e9bcb90b7e3c4a6bda0a54b84bfad4a6d968a0bb05b2a6649e0107cce0f8d","declaration":"export type MemoryPluginCapability = MemoryPluginCapability;","entrypoint":"core","exportName":"MemoryPluginCapability","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"77d2bdba5dec3f7c4ce6b6f5d9607f693dd84be375c74387eec5dcc04c0ce2aa","declaration":"export type MemoryPluginPublicArtifact = MemoryPluginPublicArtifact;","entrypoint":"core","exportName":"MemoryPluginPublicArtifact","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"975832a2ade859a8066356ef270fdd8edbc8d5f764a3c4dbbbeef52c001d950c","declaration":"export type MemoryPluginPublicArtifactsProvider = MemoryPluginPublicArtifactsProvider;","entrypoint":"core","exportName":"MemoryPluginPublicArtifactsProvider","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"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":"2ddf03be75f0d46c8a7e1d7a3d3e70122001b190dcb361132cef2f1d23d8ddec","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"647007b989ba3d08c520ec68873f65f22f231b0274daf10f5d219074fd2fcba6","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"core","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"aded5b666490cf7e5cca6bf3942c5190ad1fc30fc73f542505c53e5999f649a9","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"1b85aede0a5709f8de9905bcedb2b1acbbdb6db5fdcdd7321e2294c2f8866424","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":"ccae64ce42b52f34fc0f2adffe6202985c2c8464e3e2df19f43ae1eb0005e808","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"87cbaf84f362b665d7e0a8c8d62835b297f00629a3d4200d6d07f3938b439f9c","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"}
{"closureHash":"26dd6974af3127ca18835b3f7294f2dae0f7fab63c6d326e999e90366999dc6e","declaration":"export type OpenClawPluginServiceContext = OpenClawPluginServiceContext;","entrypoint":"core","exportName":"OpenClawPluginServiceContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"3bb6d68fc7970af9b14ace77e71698b7dbc45c447102a74505e872b692753f07","declaration":"export type OpenClawPluginSessionsChangedEvent = OpenClawPluginSessionsChangedEvent;","entrypoint":"core","exportName":"OpenClawPluginSessionsChangedEvent","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"4b4e5425c1e19a0d00f99e3b1f078f101a87a38dbf3cb81e124665ac11bb68d9","declaration":"export type OpenClawPluginToolContext = OpenClawPluginToolContext;","entrypoint":"core","exportName":"OpenClawPluginToolContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"cf4bb672a5d6622273e847afbab9b823e0fdb7bbecd43eebb2620c7711924273","declaration":"export type OpenClawPluginToolFactory = OpenClawPluginToolFactory;","entrypoint":"core","exportName":"OpenClawPluginToolFactory","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"d0230fba39834d6c8e620d19799a0006eeea6a7a75a954930cb10acc0138b09f","declaration":"export type OpenClawPluginToolContext = OpenClawPluginToolContext;","entrypoint":"core","exportName":"OpenClawPluginToolContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"709aac28446af536b23ee9673d2e3ed3ca733faab5c47be6ccbf14b424f48798","declaration":"export type OpenClawPluginToolFactory = OpenClawPluginToolFactory;","entrypoint":"core","exportName":"OpenClawPluginToolFactory","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"747b0a0e9cf9bca79463e90a0850940820d68a35dd4facde3776428d4a18e8e4","declaration":"export type OutboundIdentity = OutboundIdentity;","entrypoint":"core","exportName":"OutboundIdentity","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"e906dde715d40209703e3ddff8afa7f7288c7ed1870416773794b3817b5e1e80","declaration":"export type OutboundLocation = OutboundLocation;","entrypoint":"core","exportName":"OutboundLocation","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"b749d0cceb7b02f8e2e810c9a1f4fea64effc4a2ddb0da972d873781d2a70471","declaration":"export type PluginAgentEventEmitParams = PluginAgentEventEmitParams;","entrypoint":"core","exportName":"PluginAgentEventEmitParams","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
@@ -1995,7 +1995,7 @@
{"closureHash":"028cd39dd470117f37aff9d199e99c7eadaa99a2af56810c3033e488587e56e2","declaration":"export type PluginAgentEventSubscriptionRegistration = PluginAgentEventSubscriptionRegistration;","entrypoint":"core","exportName":"PluginAgentEventSubscriptionRegistration","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"3d9f3c666f1a8f37cd4fd2bf621d793b6626ce36edc96bd3922498a8f4ebfc19","declaration":"export type PluginAgentTurnPrepareEvent = PluginAgentTurnPrepareEvent;","entrypoint":"core","exportName":"PluginAgentTurnPrepareEvent","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"dd9b818f8b19ced207493eea1b75da8a38b24a5dc4c9ac46288f9329ba06f0f3","declaration":"export type PluginAgentTurnPrepareResult = PluginAgentTurnPrepareResult;","entrypoint":"core","exportName":"PluginAgentTurnPrepareResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"d9d24565b06f891a687f49672129beac9d38ccb817526ed1a6579efcb5825eb0","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"5c7a4e89ddfb6bed00f2ca8e67e43f150fedb3182275a525411365855d581c22","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"a50f802cdb46fb073ccba3d7b5c2a3c66c2b5aeccca3368222f9a520e66055ca","declaration":"export type PluginCommandResult = PluginCommandResult;","entrypoint":"core","exportName":"PluginCommandResult","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"b9a7fd2bdde1d99b58227e6ff01853420fee36357c2fa5e2d9ef5fbcef11ac65","declaration":"export type PluginControlUiDescriptor = PluginControlUiDescriptor;","entrypoint":"core","exportName":"PluginControlUiDescriptor","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"83237187559904a1350b07bfcaa20eb473e397884361e9543ccdaeddd6c2c12e","declaration":"export type PluginHeartbeatPromptContributionEvent = PluginHeartbeatPromptContributionEvent;","entrypoint":"core","exportName":"PluginHeartbeatPromptContributionEvent","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
@@ -2014,7 +2014,7 @@
{"closureHash":"f361587d79916f3d1cb73b4d296e1f37f86d799a641ce4a590ee784413d0b7ef","declaration":"export type PluginNextTurnInjectionRecord = PluginNextTurnInjectionRecord;","entrypoint":"core","exportName":"PluginNextTurnInjectionRecord","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"e4f6093e70826c8c7c02433082b9ac1b91755640096339111331fc45a494ca88","declaration":"export type PluginRunContextGetParams = PluginRunContextGetParams;","entrypoint":"core","exportName":"PluginRunContextGetParams","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"f9d14d70abca2a8771c0763736871361e4c223a8e4cbe3ae5c7a17751630b68e","declaration":"export type PluginRunContextPatch = PluginRunContextPatch;","entrypoint":"core","exportName":"PluginRunContextPatch","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"b94637421f524b48f7e497e449491475a2cc35f3d6dc43bdf5274b401b9424b0","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"core","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"8d8f8c012d739749de557261960af8c0c714403fefa6fa15bd06ddbaee90aee3","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"core","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"4a005fd56ceaa1de7ff2c6b45f08a48f48d7ff30e21d0e88d783d86a49e274f4","declaration":"export type PluginRuntimeLifecycleRegistration = PluginRuntimeLifecycleRegistration;","entrypoint":"core","exportName":"PluginRuntimeLifecycleRegistration","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"c599fdbfd9439bdcbbbf621dca995d2d6f87c7aba9606dc1970e1205dfea6357","declaration":"export type PluginSessionActionContext = PluginSessionActionContext;","entrypoint":"core","exportName":"PluginSessionActionContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
{"closureHash":"85a706fb9b56d5c5f41756729736cd4581b98d5cb0ab9a693b8261e4d936e499","declaration":"export type PluginSessionActionRegistration = PluginSessionActionRegistration;","entrypoint":"core","exportName":"PluginSessionActionRegistration","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"}
@@ -2215,8 +2215,8 @@
{"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":"2ddf03be75f0d46c8a7e1d7a3d3e70122001b190dcb361132cef2f1d23d8ddec","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"discord","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"b94637421f524b48f7e497e449491475a2cc35f3d6dc43bdf5274b401b9424b0","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"discord","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"aded5b666490cf7e5cca6bf3942c5190ad1fc30fc73f542505c53e5999f649a9","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"discord","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
{"closureHash":"8d8f8c012d739749de557261960af8c0c714403fefa6fa15bd06ddbaee90aee3","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"}
{"closureHash":"eaabd6155d6f25cbba09ef3c8f2b306f2202affdca4b47e5d67311ff4073fb0d","declaration":"export type ThreadBindingTargetKind = ThreadBindingTargetKind;","entrypoint":"discord","exportName":"ThreadBindingTargetKind","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"}
@@ -2289,7 +2289,7 @@
{"closureHash":"a8874cc3b2cb522f6ca38ba5e353ec290aad0495c56087396ecaeb1cee9981b6","declaration":"export type NodeMatchCandidate = NodeMatchCandidate;","entrypoint":"gateway-runtime","exportName":"NodeMatchCandidate","importSpecifier":"openclaw/plugin-sdk/gateway-runtime","kind":"type","recordType":"export"}
{"closureHash":"909e9434e956f1dfde4cc24f68879e7c3a1aac8aea4ff2d887b37824fdef1994","declaration":"export type NodeSession = NodeSession;","entrypoint":"gateway-runtime","exportName":"NodeSession","importSpecifier":"openclaw/plugin-sdk/gateway-runtime","kind":"type","recordType":"export"}
{"closureHash":"6cfef265e2aebd53c1e7ce29cb204228ac175b07f9d2f22b861e98cac0eaee4a","declaration":"export type NormalizedPluginNodeCapabilityUrl = NormalizedPluginNodeCapabilityUrl;","entrypoint":"gateway-runtime","exportName":"NormalizedPluginNodeCapabilityUrl","importSpecifier":"openclaw/plugin-sdk/gateway-runtime","kind":"type","recordType":"export"}
{"closureHash":"a8ddb69632bf607e66ad3c640b2e676060c1dd1f6be25a70acd31b8a4b1e9fff","declaration":"export class GatewayClient {\n #client: BaseGatewayClient;\n constructor(opts: GatewayClientOptions);\n start(): void;\n stop(): void;\n stopAndWait(opts?: {\n timeoutMs?: number;\n }): Promise<void>;\n request<T = Record<string, unknown>>(method: string, params?: unknown, opts?: GatewayClientRequestOptions): Promise<T>;\n getConnectionMetadata(): GatewayClientConnectionMetadata;\n updateNodeManifest(manifest: {\n caps: string[];\n commands: string[];\n }): void;\n}","entrypoint":"gateway-runtime","exportName":"GatewayClient","importSpecifier":"openclaw/plugin-sdk/gateway-runtime","kind":"class","recordType":"export"}
{"closureHash":"50249daea218a2c3a9219bd6e4b946b38995a089d412b543619bfba3eb7fb39d","declaration":"export class GatewayClient {\n #client: BaseGatewayClient;\n constructor(opts: GatewayClientOptions);\n start(): void;\n stop(): void;\n stopAndWait(opts?: {\n timeoutMs?: number;\n }): Promise<void>;\n request<T = Record<string, unknown>>(method: string, params?: unknown, opts?: GatewayClientRequestOptions): Promise<T>;\n getConnectionMetadata(): GatewayClientConnectionMetadata;\n updateNodeManifest(manifest: {\n caps: string[];\n commands: string[];\n }): void;\n}","entrypoint":"gateway-runtime","exportName":"GatewayClient","importSpecifier":"openclaw/plugin-sdk/gateway-runtime","kind":"class","recordType":"export"}
{"category":null,"entrypoint":"group-access","importSpecifier":"openclaw/plugin-sdk/group-access","recordType":"module"}
{"closureHash":"b6b34cd3844debbe7cda17ad7703e4fcffe4489789ae1763df8f8ab027150203","declaration":"export function evaluateGroupRouteAccessForPolicy(params: { groupPolicy: GroupPolicy; routeAllowlistConfigured: boolean; routeMatched: boolean; routeEnabled?: boolean; }): GroupRouteAccessDecision;","entrypoint":"group-access","exportName":"evaluateGroupRouteAccessForPolicy","importSpecifier":"openclaw/plugin-sdk/group-access","kind":"function","recordType":"export"}
{"closureHash":"bf1a463ce98bf23d639d6e80112ffca836df6d63049bae6fef2a11a2ef1bb74c","declaration":"export function evaluateMatchedGroupAccessForPolicy(params: { groupPolicy: GroupPolicy; allowlistConfigured: boolean; allowlistMatched: boolean; requireMatchInput?: boolean; hasMatchInput?: boolean; }): MatchedGroupAccessDecision;","entrypoint":"group-access","exportName":"evaluateMatchedGroupAccessForPolicy","importSpecifier":"openclaw/plugin-sdk/group-access","kind":"function","recordType":"export"}
@@ -2334,7 +2334,7 @@
{"closureHash":"4e9774b442212bd9346cf95095a42ece3c0e1df29f25e1a81e857981503b4a82","declaration":"export function deriveInboundMessageHookContext(ctx: FinalizedMsgContext, overrides?: { content?: string; messageId?: string; }): CanonicalInboundMessageHookContext;","entrypoint":"hook-runtime","exportName":"deriveInboundMessageHookContext","importSpecifier":"openclaw/plugin-sdk/hook-runtime","kind":"function","recordType":"export"}
{"closureHash":"9bb995aaaf485864e8c02dc5cc71fe5bff42e4d202c20554efc2f3d2d5c2576d","declaration":"export function fireAndForgetBoundedHook(task: () => Promise<unknown>, label: string, logger?: (message: string) => void, options?: FireAndForgetBoundedHookOptions): void;","entrypoint":"hook-runtime","exportName":"fireAndForgetBoundedHook","importSpecifier":"openclaw/plugin-sdk/hook-runtime","kind":"function","recordType":"export"}
{"closureHash":"46f0ed9dbb3fb5cd6d3898f8dd762508eb93dac3255841d96ae9b25d2ed84c96","declaration":"export function fireAndForgetHook(task: Promise<unknown>, label: string, logger?: (message: string) => void): void;","entrypoint":"hook-runtime","exportName":"fireAndForgetHook","importSpecifier":"openclaw/plugin-sdk/hook-runtime","kind":"function","recordType":"export"}
{"closureHash":"819ef2075c836ea71b03cb8cf6247c4d3064e208f9086d0a9d7ed612f4a6844c","declaration":"export function initializeGlobalHookRunner(registry: GlobalHookRunnerRegistry): void;","entrypoint":"hook-runtime","exportName":"initializeGlobalHookRunner","importSpecifier":"openclaw/plugin-sdk/hook-runtime","kind":"function","recordType":"export"}
{"closureHash":"fedfb0278bb4e6fe5606d3abb29eee611787747b1a14d3e7f7c70b5a08df2abe","declaration":"export function initializeGlobalHookRunner(registry: GlobalHookRunnerRegistry): void;","entrypoint":"hook-runtime","exportName":"initializeGlobalHookRunner","importSpecifier":"openclaw/plugin-sdk/hook-runtime","kind":"function","recordType":"export"}
{"closureHash":"05bb072b6ae34d0271798d98d9083ec8290d4123c349862722097a7e87866d07","declaration":"export function registerInternalHook(eventKey: string, handler: InternalHookHandler): void;","entrypoint":"hook-runtime","exportName":"registerInternalHook","importSpecifier":"openclaw/plugin-sdk/hook-runtime","kind":"function","recordType":"export"}
{"closureHash":"f573a2f2542169912da9757a6aac432d067434e759cf40035079ea1d107b7e38","declaration":"export function resetGlobalHookRunner(): void;","entrypoint":"hook-runtime","exportName":"resetGlobalHookRunner","importSpecifier":"openclaw/plugin-sdk/hook-runtime","kind":"function","recordType":"export"}
{"closureHash":"e26c70aedd4d93db7a26367de5a935f8335b657b6333f34797a5349f04589b20","declaration":"export function toInternalMessageReceivedContext(canonical: CanonicalInboundMessageHookContext): MessageReceivedHookContext;","entrypoint":"hook-runtime","exportName":"toInternalMessageReceivedContext","importSpecifier":"openclaw/plugin-sdk/hook-runtime","kind":"function","recordType":"export"}
@@ -2360,7 +2360,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":"871d3ff30c14af1a605fdb47c50923a910a7886f7cc886ba1cd9c2eff1ea8334","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":"64792a0c33912731a154f8e8e1b3f598b3396d2e0b93ed35fb4cc67a150bf9e2","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":"8b9f39e06d068cd2497a07a2f0ee78c2e5497a58eca6e7e6c2da2ba93535f23c","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":"10d47ee68a65fa2df62012bf98988026560dd0bc30d2be56783ed4132864a149","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"}
@@ -3192,34 +3192,34 @@
{"closureHash":"0a8eee30ac3d7beb17a67ed364602e375580d8fe64711e4a88bb77eabb1354f0","declaration":"export function addMeetingSetupCheck(status: MeetingSetupStatus, check: MeetingSetupCheck): MeetingSetupStatus;","entrypoint":"meeting-runtime","exportName":"addMeetingSetupCheck","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"a4294716c3bb64b8732f33b331506a14e4f2fba59f382699961c9db8677e6774","declaration":"export function asMeetingBrowserTabs(result: unknown): MeetingBrowserCandidateTab[];","entrypoint":"meeting-runtime","exportName":"asMeetingBrowserTabs","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"b39bf4bdb91f0aeabac8cbd0ee8dc21afceae20faf463c6a2657258f2aa07976","declaration":"export function buildMeetingSoxAudioCommands(params: MeetingSoxAudioCommandParams): { inputCommand: string[]; outputCommand: string[]; };","entrypoint":"meeting-runtime","exportName":"buildMeetingSoxAudioCommands","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"66f0964725c2b9640e8ab8cfb803a421a9e58a2238ea4fbf7ffa97d0c4d33df0","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":"68da4dfc0e0c799f6810dc070c63a429798a1e1e858e5225426f0b21c424caf4","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":"c7e8cad42fa48c1be4ae1b1f7f87339c849cacf81a53ad53df76e188f4dd4629","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":"eaf5cff3027412d66a1e6488a71c1fb21ae1efb16d5c7415afed7370a1641dbf","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":"992b3300a22ff822840971e86089e57352000b2402625860ef32230d0b48362c","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":"c24206770d1401a9b9e1f698345b6df96665676348368e2051844bc6477ff92c","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":"2ce663d0c867849f055335c2e964429a31516c653e0628173149d4f991067808","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":"d2d5079b8025340a7d77b1342f53aed7b012d14399b3ec3c60805d16ffbac40c","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":"abfbbc6b5eca3947bed22ea782cf5ad582b6a364f554d8851c92c2d3cbc3c6f7","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":"364dbe49fce073de6aff2b666e2e80b9d188f04458f179f0569506702b2e5075","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":"877c0cd3bcc04f1ffe33a7c54d6e87034066d27a50fa0c069338cc64815ac2ab","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":"2327df59b7e4bd680d52b939e9b6709ed6a075eb5538dbc8576ce451168d4fe8","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":"c571be67deff656fc2e53aecb61d02bd58b468d4b548860b37b61eafa18f8d6b","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":"892e54d8bf726606994141005217facb41eef3c0d21c06e186f90c82c7a10127","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"}
{"closureHash":"566d131fb9ec888fb5441ac6e7ae1623e8f5d12a2870d3fc94db607d57f70205","declaration":"export function readMeetingTranscriptWithBrowser<Session, Mode extends string, Health extends MeetingBrowserHealth, Transcript extends MeetingTranscriptSnapshot>(params: { adapter: BrowserAdapter<Session, Mode, Health, Transcript>; callBrowser: MeetingBrowserRequestCaller; finalize: boolean; meetingUrl: string; meetingSessionId: string; tab: MeetingBrowserTab; timeoutMs: number; }): Promise<Transcript>;","entrypoint":"meeting-runtime","exportName":"readMeetingTranscriptWithBrowser","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"0b42493cc0197096c4847c2d6e149c5581580abdda448d07eb1c6d77a775bc4a","declaration":"export function recoverMeetingBrowserTab<Session, Mode extends string, Health extends MeetingBrowserHealth & { browserTitle?: string; browserUrl?: string; notes?: string[]; }, Transcript extends MeetingTranscriptSnapshot>(params: { adapter: BrowserAdapter<Session, Mode, Health, Transcript>; allowSessionAdoption?: boolean; autoJoin?: boolean; callBrowser: MeetingBrowserRequestCaller; captureCaptions?: boolean; config: MeetingBrowserControllerConfig; locationLabel: string; meetingSessionId?: string; mode: Mode; requestedMeetingUrl: string | undefined; readOnly?: boolean; timeoutMs?: number; trackedMeetingUrl: string | undefined; trackedTargetId: string | undefined; }): Promise<{ found: boolean; targetId?: string; tab?: MeetingBrowserCandidateTab; browser?: Health; message: string; }>;","entrypoint":"meeting-runtime","exportName":"recoverMeetingBrowserTab","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"dd5fb0b5816311a03a3ae754c03331e11afae96acc63338bbde9111a919d2060","declaration":"export function resolveLocalMeetingBrowserRequest(runtime: PluginRuntime): Promise<MeetingBrowserRequestCaller>;","entrypoint":"meeting-runtime","exportName":"resolveLocalMeetingBrowserRequest","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"019720abfc1f5af9638270dbeb6d42b6e2c089b6250fff6a936c2a1758acf1a5","declaration":"export function resolveMeetingBrowserNode(params: { runtime: PluginRuntime; adapter: NodeAdapter; requestedNode?: string; }): Promise<string>;","entrypoint":"meeting-runtime","exportName":"resolveMeetingBrowserNode","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"120055d3915ab89e6960d454ba75088f5d000e2abe1715901b791f86ab0f2ba5","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":"9a4c04e7a643c00f4b5fc18eb605a04e1fadf6be2bd9ffc7df7f72804ee2af49","declaration":"export function resolveLocalMeetingBrowserRequest(runtime: PluginRuntime): Promise<MeetingBrowserRequestCaller>;","entrypoint":"meeting-runtime","exportName":"resolveLocalMeetingBrowserRequest","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"0c3b2b99e995c6d0ec4549e09ef96007bf2eaafc565eea1161d0b1184dc32b1a","declaration":"export function resolveMeetingBrowserNode(params: { runtime: PluginRuntime; adapter: NodeAdapter; requestedNode?: string; }): Promise<string>;","entrypoint":"meeting-runtime","exportName":"resolveMeetingBrowserNode","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"}
{"closureHash":"4e175840f739613f81bc3eda9b7e19726a23dee0dde0f6421e400eb5563a97dd","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":"c64d9bc7f2e478a5affc01a910f49882aef707b077d8ebc0da889985cfaf9595","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":"20dff0ae02d5d945273bedcb54a853efed1f43cf1f03754a52e0eb3e584c7b88","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":"3a54658889eb2e0a998f08ae0d0b1d7e7f16a428e40083462bdc9e2c9be1ce6e","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":"896073bc541994b82669b2d3971ac486a05e3be2eb7e551020041d368830cb14","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"}
@@ -3251,7 +3251,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":"8d3f6abdbf39603c6f28a69b9bb8f0b214d978dc10dd83ca3f6a692f565a7cb0","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":"f9bbaf0fd4cc34d647d2721a373df74f61814f497be0af92b548a0ba4461d08f","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"}
@@ -3265,9 +3265,75 @@
{"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":"376e9dae283ed91fb2a5e5769c33f09bed27db7a0d42afe7d305bb1f6d58167e","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":"8c336f7da129c74739921825e397570d057e91a5fb5420dcc83faf10f5529f9a","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":"2bf79ddb49656aafb6210e91b35334500af758fbe90bc6da026a8660fd3ed5b4","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":"3cc6f9a12eabf0fda13fc2b5b2ae36daf143c0878f78375800dd071da4b006b0","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-authorization","importSpecifier":"openclaw/plugin-sdk/memory-authorization","recordType":"module"}
{"closureHash":"0ee4b1ca0b2e0ced619eeebbf22d86bd20e4c2e3c59d49d0d67c06641041cd79","declaration":"export function hasCompleteMemoryAuthorizationCapabilities(capabilities: unknown): capabilities is MemoryAuthorizationCapabilities;","entrypoint":"memory-authorization","exportName":"hasCompleteMemoryAuthorizationCapabilities","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"function","recordType":"export"}
{"closureHash":"f39104a379c1ed53a7b6d31d5ba2d13e9944364fabaff21d52b56b62c3a1b0e6","declaration":"export function isMemoryAuthorizationCapabilities(value: unknown): value is MemoryAuthorizationCapabilities;","entrypoint":"memory-authorization","exportName":"isMemoryAuthorizationCapabilities","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"function","recordType":"export"}
{"closureHash":"7b98d3a2271904e42ee6000ccfa2f4383771864de13e5242be1e39c81d55ee5b","declaration":"export function listMissingMemoryAuthorizationCapabilities(capabilities: unknown): MemoryAuthorizationCapabilityName[];","entrypoint":"memory-authorization","exportName":"listMissingMemoryAuthorizationCapabilities","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"function","recordType":"export"}
{"closureHash":"83604f54c1dba09754a2ddc68a84e70a8673c70735cf1865208345d65857e2f5","declaration":"export const COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES: Readonly<{ version: 1; scopedCandidates: true; exactReadByAuthorizedHandle: true; scopedSync: true; scopedWrite: true; scopedImport: true; scopedExport: true; scopedStatus: true; exposureReceipts: true; egressReceipts: true;}>;","entrypoint":"memory-authorization","exportName":"COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"const","recordType":"export"}
{"closureHash":"9e7240f7d047945d7a8e82f5c871d587777973d9bd846f030bfa311a0c85e0ef","declaration":"export const LEGACY_MEMORY_AUTHORIZATION_CAPABILITIES: Readonly<{ version: 1; scopedCandidates: false; exactReadByAuthorizedHandle: false; scopedSync: false; scopedWrite: false; scopedImport: false; scopedExport: false; scopedStatus: false; exposureReceipts: false; egressReceipts: false;}>;","entrypoint":"memory-authorization","exportName":"LEGACY_MEMORY_AUTHORIZATION_CAPABILITIES","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"const","recordType":"export"}
{"closureHash":"02866d9e60292c5a245bd16b0f8698e5af08e6d17a9d1508188ca6393b75f58e","declaration":"export const MEMORY_AUTHORIZATION_CAPABILITY_NAMES: readonly [\"scopedCandidates\", \"exactReadByAuthorizedHandle\", \"scopedSync\", \"scopedWrite\", \"scopedImport\", \"scopedExport\", \"scopedStatus\", \"exposureReceipts\", \"egressReceipts\"];","entrypoint":"memory-authorization","exportName":"MEMORY_AUTHORIZATION_CAPABILITY_NAMES","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"const","recordType":"export"}
{"closureHash":"838951bf75cc80db9dd24d7bd91663da443dce8df59c5203ff0c75ee04253001","declaration":"export const MEMORY_AUTHORIZATION_CONTRACT_VERSION: 1;","entrypoint":"memory-authorization","exportName":"MEMORY_AUTHORIZATION_CONTRACT_VERSION","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"const","recordType":"export"}
{"closureHash":"0576d5ff05ae40e2f584df67ade98e053cae556dad8e6dc27fed1bed6e8540fa","declaration":"export const MEMORY_OPERATIONS: readonly [\"retrieve\", \"read\", \"append\", \"replace\", \"derive\", \"deposit\", \"project\", \"publish\", \"import\", \"export\", \"delete\", \"sync\", \"status\", \"policy-admin\"];","entrypoint":"memory-authorization","exportName":"MEMORY_OPERATIONS","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"const","recordType":"export"}
{"closureHash":"c49dbc4a64dd5f1f9c130b5b1fc30d21d98057d37fc0c5b6fef1cd2801463300","declaration":"export type AudienceRef = Readonly<{ kind: \"user\" | \"conversation\" | \"role\" | \"agent-shared\" | \"agent\" | \"internal\"; id: string;}>;","entrypoint":"memory-authorization","exportName":"AudienceRef","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"95c8d6d814558ffa3176bb5d9ba0682fa263e5655033205bbcfe52f941f1db25","declaration":"export type AuthorizedMemoryContentPlan<Operation extends MemoryContentAccessOperation = MemoryContentAccessOperation> = AuthorizedMemoryContentPlan<Operation>;","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryContentPlan","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"c78173eba0c1ee6e71cb96f5bf1876cbaa19906b73877f309d1089caab6f4f8e","declaration":"export type AuthorizedMemoryMount = { readonly version: 1; readonly agentId: string; readonly mountHandle: string; readonly capabilities: readonly (\"replace\" | \"status\" | \"read\" | \"delete\" | \"project\" | \"retrieve\" | \"append\" | \"derive\" | \"deposit\" | \"publish\" | \"import\" | \"export\" | \"sync\" | \"policy-admin\")[]; readonly audienceRevision: string;};","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryMount","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"b6dffdcb79f550769a4549e065779f7c93af135ae6f72ef441cba89a5718e13b","declaration":"export type AuthorizedMemoryMutation = AuthorizedMemoryMutation;","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryMutation","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"4b774e18e8524a1bb8414d81067b2a89ae881a6c3353ece57816759d8c4009f1","declaration":"export type AuthorizedMemoryPlan = { readonly version: 1; readonly planId: string; readonly contextFingerprint: string; readonly runId: string; readonly agentId: string; readonly sessionId: string; readonly sessionIdentityRevision: string; readonly subjectRevision: string; readonly memoryPolicyRevision: string; readonly deliveryRevision: string; readonly operation: MemoryOperation; readonly mounts: readonly { readonly version: 1; readonly agentId: string; readonly mountHandle: string; readonly capabilities: readonly (\"replace\" | \"status\" | \"read\" | \"delete\" | \"project\" | \"retrieve\" | \"append\" | \"derive\" | \"deposit\" | \"publish\" | \"import\" | \"export\" | \"sync\" | \"policy-admin\")[]; readonly audienceRevision: string; }[]; readonly bootstrapResourceHandles: readonly { readonly version: 1; readonly handleId: string; readonly planId: string; readonly contextFingerprint: string; readonly resourceRevision: string; readonly policyRevision: string; readonly expiresAt: string; }[]; readonly allowedEgressAudiences: readonly { readonly kind: \"user\" | \"conversation\" | \"role\" | \"agent-shared\" | \"agent\" | \"internal\"; readonly id: string; }[]; readonly expiresAt: string;};","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryPlan","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"9aceb3a04da45b6cb8cb2142bb847b7e5036f92dc934bff47278da3c7b02e332","declaration":"export type AuthorizedMemoryPlanForContext<Context extends MemoryAccessContext> = AuthorizedMemoryPlanForContext<Context>;","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryPlanForContext","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"de16c3afd4ac7c724b38053e2daa9085c40013b4dd387cfac98c0fad205ca3f0","declaration":"export type AuthorizedMemoryReadParams<Operation extends MemoryContentAccessOperation> = Readonly<{ context: MemoryContentAccessContext<Operation>; plan: AuthorizedMemoryContentPlan<Operation>; handle: AuthorizedResourceHandle; from?: number; lines?: number;}>;","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryReadParams","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"31fdaf7321c8ebf7b709ad9e20429dd03506d6738c59429300ef62cb91128b1f","declaration":"export type AuthorizedMemoryResultEnvelope<T> = { readonly version: 1; readonly value: DeepReadonly<T>; readonly exposureReceipt: { readonly version: 1; readonly receiptId: string; readonly contextFingerprint: string; readonly planId: string; readonly runId: string; readonly runExposureRevision: string; readonly sourcePolicySetId: string; readonly exposedRevisionHandles: readonly string[]; readonly recordedAt: string; }; readonly egressReceipt: { readonly version: 1; readonly receiptId: string; readonly contextFingerprint: string; readonly planId: string; readonly runId: string; readonly runExposureRevision: string; readonly sourcePolicySetId: string; readonly allowedAudiences: readonly { readonly kind: \"user\" | \"conversation\" | \"role\" | \"agent-shared\" | \"agent\" | \"internal\"; readonly id: string; }[]; readonly deliveryRevision: string; readonly egressRegistryRevision: string; readonly expiresAt: string; };};","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryResultEnvelope","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"6aa0dea8474477db4c20fdf56bb77f39e6474da7e736f54923c941948af47264","declaration":"export type AuthorizedMemorySearchParams<Operation extends MemoryContentAccessOperation> = Readonly<{ context: MemoryContentAccessContext<Operation>; plan: AuthorizedMemoryContentPlan<Operation>; query: string; subjectHandles?: readonly string[]; sources?: readonly MemorySource[]; limit: number; signal?: AbortSignal;}>;","entrypoint":"memory-authorization","exportName":"AuthorizedMemorySearchParams","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"83e30cb96c283397c5d415a0ec813f69f682280b34cf1449c7d9155167b8b779","declaration":"export type AuthorizedMemorySearchResult = { readonly path: string; readonly startLine: number; readonly endLine: number; readonly score: number; readonly vectorScore?: number | undefined; readonly textScore?: number | undefined; readonly snippet: string; readonly source: MemorySource; readonly importance?: number | undefined; readonly triggers?: string | undefined; readonly projectKey?: string | undefined; readonly originClass?: string | undefined; readonly citation?: string | undefined; readonly provenance?: { readonly originClass: MemoryOriginClass; readonly sessionKind: MemorySessionKind; readonly observedAt: number; readonly supersedesKey?: string | undefined; } | undefined; readonly resourceHandle: { readonly version: 1; readonly handleId: string; readonly planId: string; readonly contextFingerprint: string; readonly resourceRevision: string; readonly policyRevision: string; readonly expiresAt: string; };};","entrypoint":"memory-authorization","exportName":"AuthorizedMemorySearchResult","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"29f68c2597192844ee117e1ff56238287c53ed94b57cc5d9c4a97664b18da5fa","declaration":"export type AuthorizedMemoryStatus = { readonly version: 1; readonly backend: string; readonly provider?: string | undefined; readonly model?: string | undefined; readonly files?: number | undefined; readonly chunks?: number | undefined; readonly dirty?: boolean | undefined;};","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryStatus","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"2a5a77be5b8e6de4357da098ba75efccdd4bc68b0cfd7044b648548c9d9d6343","declaration":"export type AuthorizedMemoryVirtualFile = { readonly version: 1; readonly mountHandle: string; readonly virtualPath: string;};","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryVirtualFile","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"63be70bf8253ab66473fda6aa2d64b4d8ab6f483c9987e9d2cfd01bc5b11847e","declaration":"export type AuthorizedMemoryVirtualRoot = { readonly version: 1; readonly mountHandle: string; readonly virtualRoot: string; readonly access: \"read\";};","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryVirtualRoot","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"cfc64d41fd6e47993eda1c7d39326e1d9a927e1538d5a330ecb2a6ed3e48e843","declaration":"export type AuthorizedMemoryVirtualView = { readonly version: 1; readonly viewId: string; readonly planId: string; readonly contextFingerprint: string; readonly revision: string; readonly roots: readonly { readonly version: 1; readonly mountHandle: string; readonly virtualRoot: string; readonly access: \"read\"; }[]; readonly files: readonly { readonly version: 1; readonly mountHandle: string; readonly virtualPath: string; }[]; readonly expiresAt: string;};","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryVirtualView","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"9e964b706d37f163c6045083b55e9115f5319fcaa72fb86d4595d2ff70f3f0b3","declaration":"export type AuthorizedResourceHandle = { readonly version: 1; readonly handleId: string; readonly planId: string; readonly contextFingerprint: string; readonly resourceRevision: string; readonly policyRevision: string; readonly expiresAt: string;};","entrypoint":"memory-authorization","exportName":"AuthorizedResourceHandle","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"e610c8719f9e2a3b6782001cc4f990586db95c2b514c13427129ba8ca70f171c","declaration":"export type AuthorizedSealedCompactionArtifact = Readonly<{ resourceRevisionId: string; commitInTransaction(params: Readonly<{ database: DatabaseSync; compactionPolicyId: string; eventSeq: number; }>): void;}>;","entrypoint":"memory-authorization","exportName":"AuthorizedSealedCompactionArtifact","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"de26a2e6f50bd0a83387a778b2992ec3d1f7013b96759cdeff421166682d304c","declaration":"export type AuthorizedSealedCompactionStageParams = Readonly<{ context: MemoryAccessContext & Readonly<{ operation: \"derive\"; }>; plan: AuthorizedMemoryPlan & Readonly<{ operation: \"derive\"; }>; content: string; transcriptSource: AuthorizedTranscriptDerivationSource;}>;","entrypoint":"memory-authorization","exportName":"AuthorizedSealedCompactionStageParams","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"6851c7c333fe553520246da63ff16465009570a161f72cb95e0d101659ed7674","declaration":"export type AuthorizedTranscriptDerivationPurpose = AuthorizedTranscriptDerivationPurpose;","entrypoint":"memory-authorization","exportName":"AuthorizedTranscriptDerivationPurpose","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"683eff40eb7ca73217bc8befe198b86adcaff89381eab2191639ac20865ca5d3","declaration":"export type AuthorizedTranscriptDerivationSource = Readonly<{ kind: \"transcript\"; sessionId: string; eventSeqs: readonly number[]; sourcePolicySetId: string; deliveryAudiencesJson: string;}>;","entrypoint":"memory-authorization","exportName":"AuthorizedTranscriptDerivationSource","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"d456f5de097a9c2e255bf770b74f13c41c9e80c35143227375c33d7b14ac42b4","declaration":"export type MemoryAccessContext = { readonly version: 1; readonly contextId: string; readonly contextFingerprint: string; readonly requestId: string; readonly runId: string; readonly agentId: string; readonly sessionKey: string; readonly sessionId: string; readonly sessionIdentityRevision: string; readonly subjectRevision: string; readonly subject: { readonly version: 1; readonly kind: \"user\"; readonly principalId: string; readonly creationEvidence: { readonly kind: \"gateway-profile\" | \"channel-binding\" | \"adapter-attested\" | \"explicit-service\"; readonly revision: string; }; } | { readonly version: 1; readonly kind: \"conversation\"; readonly conversationPrincipalId: string; readonly channel: string; readonly accountId: string; } | { readonly version: 1; readonly kind: \"service\" | \"agent\" | \"system\"; readonly principalId: string; } | { readonly version: 1; readonly kind: \"ambiguous\"; readonly reason: \"shared-main\" | \"unbound\" | \"conflicting-bindings\"; }; readonly actor: { readonly kind: \"principal\"; readonly actorKind: \"human\" | \"agent\" | \"service\" | \"system\"; readonly principalId: string; readonly assurance: VerifiedPrincipalRef[\"assurance\"]; readonly evidenceRevision: string; readonly expiresAt?: string | undefined; } | { readonly kind: \"unattributed\"; readonly transportAuditRef: string; readonly evidenceRevision: string; }; readonly verifiedPrincipals: readonly { readonly principalId: string; readonly assurance: \"gateway-profile\" | \"adapter-attested\" | \"oidc\" | \"service\"; readonly evidenceRevision: string; readonly expiresAt?: string | undefined; }[]; readonly conversation?: { readonly conversationPrincipalId: string; readonly channel: string; readonly accountId: string; readonly evidenceRevision: string; } | undefined; readonly delivery: { readonly sinkKind: \"private\" | \"channel\" | \"session\" | \"internal\"; readonly audiences: readonly { readonly kind: \"user\" | \"conversation\" | \"role\" | \"agent-shared\" | \"agent\" | \"internal\"; readonly id: string; }[]; readonly egressCapabilityIds: readonly string[]; readonly egressRegistryRevision: string; readonly deliveryRevision: string; }; readonly collaboration: { readonly kind: \"gateway-session\"; readonly mode: \"shared\" | \"read-only\" | \"suggest\" | \"draft\"; readonly role: \"admin\" | \"owner\" | \"member\" | \"viewer\"; readonly decisionRevision: string; } | { readonly kind: \"not-applicable\"; }; readonly verifiedMemberships: readonly { readonly principalId: string; readonly groupId: string; readonly provider: string; readonly evidenceRevision: string; readonly observedAt: string; readonly expiresAt: string; }[]; readonly delegation?: { readonly rootPrincipalId: string; readonly rootContextId: string; readonly parentContextId: string; readonly parentMemoryPlanId: string; readonly capabilitySnapshotId: string; readonly allowedOperations: readonly (\"replace\" | \"status\" | \"read\" | \"delete\" | \"project\" | \"retrieve\" | \"append\" | \"derive\" | \"deposit\" | \"publish\" | \"import\" | \"export\" | \"sync\" | \"policy-admin\")[]; readonly maximumAudiences: readonly { readonly kind: \"user\" | \"conversation\" | \"role\" | \"agent-shared\" | \"agent\" | \"internal\"; readonly id: string; }[]; readonly storeCapToken: string; readonly depth: number; } | undefined; readonly operation: MemoryOperation; readonly hostFactsRevision: string;};","entrypoint":"memory-authorization","exportName":"MemoryAccessContext","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"19869d17f0c94844d6355891de03422eca742e0834cba0a3772759aba2b45e02","declaration":"export type MemoryActorEvidence = MemoryActorEvidence;","entrypoint":"memory-authorization","exportName":"MemoryActorEvidence","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"239657c141f6a0cd85bfb4a594877ce1dc082d3e9af0f252cf2d4899a640409b","declaration":"export type MemoryAuthorizationCapabilities = Readonly<{ version: 1;} & Record<\"scopedCandidates\" | \"exactReadByAuthorizedHandle\" | \"scopedSync\" | \"scopedWrite\" | \"scopedImport\" | \"scopedExport\" | \"scopedStatus\" | \"exposureReceipts\" | \"egressReceipts\", boolean>>;","entrypoint":"memory-authorization","exportName":"MemoryAuthorizationCapabilities","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"dd3ce6c8966f40b776e6b64a236e5328c65f21046d0001cd90c727c64dfd7c3c","declaration":"export type MemoryAuthorizationCapabilityName = \"scopedCandidates\" | \"exactReadByAuthorizedHandle\" | \"scopedSync\" | \"scopedWrite\" | \"scopedImport\" | \"scopedExport\" | \"scopedStatus\" | \"exposureReceipts\" | \"egressReceipts\";","entrypoint":"memory-authorization","exportName":"MemoryAuthorizationCapabilityName","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"6d309f78ab8354775900934f2dd78ec6c86fa7645870f47949d953c18f42aec7","declaration":"export type MemoryAuthorizationReasonCode = MemoryAuthorizationReasonCode;","entrypoint":"memory-authorization","exportName":"MemoryAuthorizationReasonCode","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"c1b4e16ab116affc8446ce2484b234feda6c09274ba1f6dab5119f2ee880cd6c","declaration":"export type MemoryContentAccessContext<Operation extends MemoryContentAccessOperation = MemoryContentAccessOperation> = MemoryContentAccessContext<Operation>;","entrypoint":"memory-authorization","exportName":"MemoryContentAccessContext","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"f2cf3f330fd30e4887ea1242bee1867fcc4c285e8f665d263b06a5e4d974f1a0","declaration":"export type MemoryContentAccessOperation = MemoryContentAccessOperation;","entrypoint":"memory-authorization","exportName":"MemoryContentAccessOperation","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"70bd8ae0683e645aaaa30457d19d82ed7e1e97fb6b03d3d702597fca93fa9728","declaration":"export type MemoryEgressAuthorizationReceipt = { readonly version: 1; readonly receiptId: string; readonly contextFingerprint: string; readonly planId: string; readonly runId: string; readonly runExposureRevision: string; readonly sourcePolicySetId: string; readonly allowedAudiences: readonly { readonly kind: \"user\" | \"conversation\" | \"role\" | \"agent-shared\" | \"agent\" | \"internal\"; readonly id: string; }[]; readonly deliveryRevision: string; readonly egressRegistryRevision: string; readonly expiresAt: string;};","entrypoint":"memory-authorization","exportName":"MemoryEgressAuthorizationReceipt","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"9199f85b00d1d24dd60ac881e5374d0cfde151c88bb7235cbc5f9b3d6b35e298","declaration":"export type MemoryExportResult = { readonly version: 1; readonly exportId: string; readonly contentType: \"application/json\" | \"application/x-ndjson\" | \"text/markdown\" | \"text/plain\"; readonly encoding: \"utf8\" | \"base64\"; readonly payload: string; readonly exportedHandles: readonly { readonly version: 1; readonly handleId: string; readonly planId: string; readonly contextFingerprint: string; readonly resourceRevision: string; readonly policyRevision: string; readonly expiresAt: string; }[];};","entrypoint":"memory-authorization","exportName":"MemoryExportResult","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"414d871aba310f6e260efa3c416adb3840bea1eb0ea81d99938e96d72b39067b","declaration":"export type MemoryExposureReceipt = { readonly version: 1; readonly receiptId: string; readonly contextFingerprint: string; readonly planId: string; readonly runId: string; readonly runExposureRevision: string; readonly sourcePolicySetId: string; readonly exposedRevisionHandles: readonly string[]; readonly recordedAt: string;};","entrypoint":"memory-authorization","exportName":"MemoryExposureReceipt","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"acc267c6c3a9c5633a29e054a4d00c9ab983e85dfb049dac492fc80af6358768","declaration":"export type MemoryOperation = \"retrieve\" | \"read\" | \"append\" | \"replace\" | \"derive\" | \"deposit\" | \"project\" | \"publish\" | \"import\" | \"export\" | \"delete\" | \"sync\" | \"status\" | \"policy-admin\";","entrypoint":"memory-authorization","exportName":"MemoryOperation","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"5611711171b3cda58d8d54c2599eaf8db079cb65b0e9fa1007efc6bcaeca573d","declaration":"export type MemorySyncResult = { readonly version: 1; readonly status: \"completed\" | \"unchanged\"; readonly synchronizedHandles: readonly { readonly version: 1; readonly handleId: string; readonly planId: string; readonly contextFingerprint: string; readonly resourceRevision: string; readonly policyRevision: string; readonly expiresAt: string; }[];};","entrypoint":"memory-authorization","exportName":"MemorySyncResult","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"05f1dc697f60a89a2deb005466d8028f5e08070e9ed6fd0d1412b262d9ea7a07","declaration":"export type MemoryVerifiedMembership = Readonly<{ principalId: string; groupId: string; provider: string; evidenceRevision: string; observedAt: string; expiresAt: string;}>;","entrypoint":"memory-authorization","exportName":"MemoryVerifiedMembership","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"44e0a9cd2eccc2fe0cce205b11ce26d4c0f35857a0ff5d33c27ee21431ddd882","declaration":"export type MemoryWriteResult = { readonly version: 1; readonly mutationId: string; readonly status: \"committed\" | \"unchanged\"; readonly resourceHandle?: { readonly version: 1; readonly handleId: string; readonly planId: string; readonly contextFingerprint: string; readonly resourceRevision: string; readonly policyRevision: string; readonly expiresAt: string; } | undefined; readonly policyRevision: string; readonly committedAt: string;};","entrypoint":"memory-authorization","exportName":"MemoryWriteResult","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"581e1fee88fe8dd94a4da7d97673296aa5ccf2f7a72284e43eaa88f3c03bbd77","declaration":"export type SessionMemorySubject = SessionMemorySubject;","entrypoint":"memory-authorization","exportName":"SessionMemorySubject","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"eab5f1c3a7592549e4734f1743575fcc93a77757eeea037fe8116233f380969d","declaration":"export type SubjectEvidenceRef = Readonly<{ kind: \"gateway-profile\" | \"channel-binding\" | \"adapter-attested\" | \"explicit-service\"; revision: string;}>;","entrypoint":"memory-authorization","exportName":"SubjectEvidenceRef","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"2a8e34b1960be304fc69b9736d88eb761fe8573087e61cdcc501aae8bf6e1077","declaration":"export type VerifiedPrincipalRef = Readonly<{ principalId: string; assurance: \"gateway-profile\" | \"adapter-attested\" | \"oidc\" | \"service\"; evidenceRevision: string; expiresAt?: string;}>;","entrypoint":"memory-authorization","exportName":"VerifiedPrincipalRef","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"type","recordType":"export"}
{"closureHash":"37a05c3acd7b7ceec314f5021aa39c374aab4abbe6c1f78b501e544538db8368","declaration":"export interface AuthorizedMemoryRuntime {\n authorize<Context extends MemoryAccessContext>(context: Context): Promise<AuthorizedMemoryPlanForContext<Context>>;\n searchAuthorized(params: AuthorizedMemorySearchParams<\"read\">): Promise<AuthorizedMemoryResultEnvelope<readonly AuthorizedMemorySearchResult[]>>;\n searchAuthorized(params: AuthorizedMemorySearchParams<\"derive\">): Promise<AuthorizedMemoryResultEnvelope<readonly AuthorizedMemorySearchResult[]>>;\n readAuthorized(params: AuthorizedMemoryReadParams<\"read\">): Promise<AuthorizedMemoryResultEnvelope<MemoryReadResult>>;\n readAuthorized(params: AuthorizedMemoryReadParams<\"derive\">): Promise<AuthorizedMemoryResultEnvelope<MemoryReadResult>>;\n writeAuthorized(params: AuthorizedMemoryWriteParams): Promise<MemoryWriteResult>;\n stageSealedCompaction?(params: AuthorizedSealedCompactionStageParams): Promise<AuthorizedSealedCompactionArtifact>;\n importAuthorized(params: AuthorizedMemoryOperationParams<\"import\"> & Readonly<{\n mutation: AuthorizedMemoryMutationForOperation<\"import\">;\n }>): Promise<MemoryWriteResult>;\n syncAuthorized(params: AuthorizedMemoryOperationParams<\"sync\">): Promise<AuthorizedMemoryResultEnvelope<MemorySyncResult>>;\n exportAuthorized(params: AuthorizedMemoryOperationParams<\"export\"> & Readonly<{\n handles: readonly AuthorizedResourceHandle[];\n }>): Promise<AuthorizedMemoryResultEnvelope<MemoryExportResult>>;\n statusAuthorized(params: AuthorizedMemoryOperationParams<\"status\">): Promise<AuthorizedMemoryResultEnvelope<AuthorizedMemoryStatus>>;\n}","entrypoint":"memory-authorization","exportName":"AuthorizedMemoryRuntime","importSpecifier":"openclaw/plugin-sdk/memory-authorization","kind":"interface","recordType":"export"}
{"category":null,"entrypoint":"memory-authorization-conformance","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","recordType":"module"}
{"closureHash":"220abd980950edd8979ea98d46ab63ad78767a5651cb1db7d24dfeb509bd432a","declaration":"export function createMemoryAuthorizationConformanceCases(): MemoryAuthorizationConformanceCase[];","entrypoint":"memory-authorization-conformance","exportName":"createMemoryAuthorizationConformanceCases","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"function","recordType":"export"}
{"closureHash":"728fcf57235b18c416589bb51add99e71d7b94759bf6b10d9310d7accf2dc8e4","declaration":"export function evaluateMemoryAuthorizationConformanceScenario(params: { scenario: MemoryAuthorizationConformanceScenario; resource: MemoryAuthorizationConformanceResource; }): MemoryAuthorizationConformanceDecision;","entrypoint":"memory-authorization-conformance","exportName":"evaluateMemoryAuthorizationConformanceScenario","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"function","recordType":"export"}
{"closureHash":"38bd0c840f5acc11b948614acc6640ddfbece2bb714f210158c1567d8dfab951","declaration":"export function runMemoryAuthorizationConformanceSuite(adapter: MemoryAuthorizationConformanceAdapter): Promise<MemoryAuthorizationConformanceReport>;","entrypoint":"memory-authorization-conformance","exportName":"runMemoryAuthorizationConformanceSuite","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"function","recordType":"export"}
{"closureHash":"de2c9641d3cbeae10f03e26c84e23fa030dfdc480bacf96920c3b952aa09694e","declaration":"export const referenceMemoryAuthorizationConformanceAdapter: Readonly<{ evaluate(params: { scenario: MemoryAuthorizationConformanceScenario; resource: MemoryAuthorizationConformanceResource; }): MemoryAuthorizationConformanceDecision | Promise<MemoryAuthorizationConformanceDecision>; prefilter(scenario: MemoryAuthorizationConformanceScenario): readonly string[] | Promise<readonly string[]>;}>;","entrypoint":"memory-authorization-conformance","exportName":"referenceMemoryAuthorizationConformanceAdapter","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"const","recordType":"export"}
{"closureHash":"2d85822c0d9795c9ebbcbb4bfd0ebc2309267e9c200f3724ff02c60e5c54b2a2","declaration":"export type MemoryAuthorizationConformanceAdapter = Readonly<{ evaluate(params: { scenario: MemoryAuthorizationConformanceScenario; resource: MemoryAuthorizationConformanceResource; }): MemoryAuthorizationConformanceDecision | Promise<MemoryAuthorizationConformanceDecision>; prefilter(scenario: MemoryAuthorizationConformanceScenario): readonly string[] | Promise<readonly string[]>;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceAdapter","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"d66b228cc415b31989a4ce0d7d0b5e0ea49f02f8182f8fb19716d6a6b9920160","declaration":"export type MemoryAuthorizationConformanceCase = Readonly<{ id: string; scenario: MemoryAuthorizationConformanceScenario; expected: Readonly<Record<string, MemoryAuthorizationConformanceDecision>>;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceCase","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"25539e655f697ef3b6c68feb4882db3140b311e8bc3890268e8a782190b36499","declaration":"export type MemoryAuthorizationConformanceDecision = MemoryAuthorizationConformanceDecision;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceDecision","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"914489e7481f6046eca15567a93cf0655df61b77d971f63c318a2fdcca53150a","declaration":"export type MemoryAuthorizationConformanceMembership = MemoryAuthorizationConformanceMembership;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceMembership","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"c927a82e0761858d5954226eeaee64d8eac550de45c143c56572637565a40025","declaration":"export type MemoryAuthorizationConformanceMembershipRef = Readonly<{ principalId: string; groupId: string; provider: string; evidenceRevision: string; hostFactsRevision: string;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceMembershipRef","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"2cb07913d3e7138a4f5c9c196981bae9946a14b8166f2b0555fe572d67c30676","declaration":"export type MemoryAuthorizationConformanceMembershipRequirement = Readonly<{ principalId: string; groupId: string; provider: string;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceMembershipRequirement","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"03f48f3d2160893185e0ac410e6a399df5932adae7d6e9cb464998320a93fbf6","declaration":"export type MemoryAuthorizationConformanceMount = Readonly<{ storeId: string; agentId: string; capabilities: readonly MemoryOperation[]; audienceRevision: string;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceMount","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"504c8d5dd8649c198c92083968994bd057fb63d4bc6f4c7250d7ab1199cb904b","declaration":"export type MemoryAuthorizationConformancePlanBinding = Readonly<{ planId: string; contextFingerprint: string; runId: string; agentId: string; sessionId: string; sessionIdentityRevision: string; subjectRevision: string; deliveryRevision: string; policyRevision: string; hostFactsRevision: string; operation: MemoryOperation; mounts: readonly MemoryAuthorizationConformanceMount[]; allowedEgressAudiences: readonly AudienceRef[]; expiresAt: string;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformancePlanBinding","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"8f2d6477be1f462e8bd2f1d86a15e3e2cc8bf52458a1bbadac0655c8a4ef375d","declaration":"export type MemoryAuthorizationConformancePolicyEntry = Readonly<{ effect: \"allow\" | \"deny\"; principalId: string; resourceId: string; operation: MemoryOperation; expiresAt?: string;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformancePolicyEntry","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"b9e4de7a89bf78c81a03d7913ec5c99840f8bf780567afc605c3c5a893e0c06b","declaration":"export type MemoryAuthorizationConformancePrincipal = MemoryAuthorizationConformancePrincipal;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformancePrincipal","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"138f37fe5b61b377ee6c15dd423d40620b1384e5306d281c48333a87b4003a2a","declaration":"export type MemoryAuthorizationConformancePrincipalRef = Readonly<{ principalId: string; evidenceRevision: string;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformancePrincipalRef","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"ae1c0a4753980acbbe6c9387273b864cfd2bf0b883cc2b438d45a3c8e5117ac2","declaration":"export type MemoryAuthorizationConformanceReport = Readonly<{ ok: boolean; failures: readonly Readonly<{ caseId: string; invariant: \"decision\" | \"authorized-handle\" | \"denial-non-disclosure\" | \"prefilter-superset\" | \"duplicate-prefilter-candidate\"; }>[];}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceReport","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"e50237c8f181b774429a0a61250734f43a4984c9735c33fe71e58565870db46f","declaration":"export type MemoryAuthorizationConformanceResource = Readonly<{ resourceId: string; agentId: string; storeId: string; revision: string; audiences: readonly AudienceRef[]; expiresAt?: string; requiredLineagePolicySetIds?: readonly string[];}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceResource","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"1a2bd8bee6cf9faf9781d128c573d05bdea1bc65984474c5c1b8f2961e373f20","declaration":"export type MemoryAuthorizationConformanceScenario = Readonly<{ id: string; now: string; principals: readonly MemoryAuthorizationConformancePrincipal[]; memberships: readonly MemoryAuthorizationConformanceMembership[]; stores: readonly MemoryAuthorizationConformanceStore[]; resources: readonly MemoryAuthorizationConformanceResource[]; policyEntries: readonly MemoryAuthorizationConformancePolicyEntry[]; viewMounts: readonly MemoryAuthorizationConformanceMount[]; context: Readonly<{ contextFingerprint: string; runId: string; agentId: string; sessionId: string; sessionIdentityRevision: string; subjectRevision: string; deliveryRevision: string; policyRevision: string; hostFactsRevision: string; operation: MemoryOperation; principalRefs: readonly MemoryAuthorizationConformancePrincipalRef[]; membershipRefs: readonly MemoryAuthorizationConformanceMembershipRef[]; deliveryAudiences: readonly AudienceRef[]; lineagePolicySetIds: readonly string[]; delegation?: Readonly<{ allowedOperations: readonly MemoryOperation[]; maximumAudiences: readonly AudienceRef[]; }>; }>; plan: MemoryAuthorizationConformancePlanBinding;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceScenario","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","recordType":"export"}
{"closureHash":"74fbcee9ac3780ed7306763c7edd61bc1edbda2068fcaeab34cdc237a0809746","declaration":"export type MemoryAuthorizationConformanceStore = Readonly<{ storeId: string; agentId: string; placementCapabilities: readonly MemoryOperation[]; requiredMembership?: MemoryAuthorizationConformanceMembershipRequirement;}>;","entrypoint":"memory-authorization-conformance","exportName":"MemoryAuthorizationConformanceStore","importSpecifier":"openclaw/plugin-sdk/memory-authorization-conformance","kind":"type","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"}
@@ -3287,19 +3353,19 @@
{"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"memory-core-host-engine-foundation","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","kind":"type","recordType":"export"}
{"closureHash":"7cedbd544d48277997e5b1733b7f51b7720829ef7652ab5223112b904ad55597","declaration":"export type ResolvedMemorySearchConfig = ResolvedMemorySearchConfig;","entrypoint":"memory-core-host-engine-foundation","exportName":"ResolvedMemorySearchConfig","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"memory-host-core","importSpecifier":"openclaw/plugin-sdk/memory-host-core","recordType":"module"}
{"closureHash":"709f31174b216fbe79ea496787a503e71a5edc85d87bc324cde87db533accb09","declaration":"export function buildActiveMemoryPromptSection(params: MemoryPromptSectionParams, prepared?: PreparedMemoryPromptSection): string[];","entrypoint":"memory-host-core","exportName":"buildActiveMemoryPromptSection","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"85eb87c60f459ce9f171d8bfcd9d6fed25646e5500e929f49c2979783e9c9f25","declaration":"export function buildActiveMemoryPromptSection(params: MemoryPromptSectionParams, prepared?: PreparedMemoryPromptSection): string[];","entrypoint":"memory-host-core","exportName":"buildActiveMemoryPromptSection","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"5e8ea9cbb8511d5dccde893e744ff1f6787e8e28511c5bd2e6785f045f9c0950","declaration":"export function clearMemoryPluginState(): void;","entrypoint":"memory-host-core","exportName":"clearMemoryPluginState","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"4122847b080b5b047e86beaee53535457df1529d8a21dd713c9887c8211ba122","declaration":"export function getMemoryCapabilityRegistration(): MemoryPluginCapabilityRegistration | undefined;","entrypoint":"memory-host-core","exportName":"getMemoryCapabilityRegistration","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"9e1c668214a630630cffa5ef460f0ca13fd086ef6002f93b3ac68587f8b4bca5","declaration":"export function getMemoryCapabilityRegistration(): MemoryPluginCapabilityRegistration | undefined;","entrypoint":"memory-host-core","exportName":"getMemoryCapabilityRegistration","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"fe74b96393cbd8de5b55715478d08bd70fb0e7351188e6deef5eabf5cb07f714","declaration":"export function listActiveMemoryPublicArtifacts(params: { cfg: OpenClawConfig; }): Promise<MemoryPluginPublicArtifact[]>;","entrypoint":"memory-host-core","exportName":"listActiveMemoryPublicArtifacts","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"1175762bd3ca71bbe283f24c09d09fc4ca76908e837b6e63786d8dc5cc15d1e1","declaration":"export function listMemoryHostPublicArtifacts(params: { cfg: OpenClawConfig; }): Promise<MemoryPluginPublicArtifact[]>;","entrypoint":"memory-host-core","exportName":"listMemoryHostPublicArtifacts","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"45dcda94b94389bfd3b01640d03914fb291b7f62e4d4d9119281dba1aea632a4","declaration":"export function registerMemoryCapability(requestedPluginId: string, capability: MemoryPluginCapability): void;","entrypoint":"memory-host-core","exportName":"registerMemoryCapability","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"06eef00cf3100a307eb9ff6a53f4511d8943e153845d21cb8199022975ed2096","declaration":"export function registerMemoryCorpusSupplement(requestedPluginId: string, supplement: MemoryCorpusSupplement): void;","entrypoint":"memory-host-core","exportName":"registerMemoryCorpusSupplement","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"c3ccc1ba311065620d7d7bd25d9046aa206b43ff107db1a3580f7a5ba7657cd2","declaration":"export function registerMemoryCapability(requestedPluginId: string, capability: MemoryPluginCapability): void;","entrypoint":"memory-host-core","exportName":"registerMemoryCapability","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"5c8bb50b82c6b2a67cbc7d592f0ac02aef0fddf590b3a2e3e8463f15aa8200dc","declaration":"export function registerMemoryCorpusSupplement(requestedPluginId: string, supplement: MemoryCorpusSupplement): void;","entrypoint":"memory-host-core","exportName":"registerMemoryCorpusSupplement","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"851fc50d9816836a9c2e923d4223eb86c15411c2d94153f64bf0171013dfc031","declaration":"export function resolveDefaultAgentId(cfg: OpenClawConfig): string;","entrypoint":"memory-host-core","exportName":"resolveDefaultAgentId","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"78ce37a08eff2ab75b9aa6141c90a2ee96898844625bc714e872b90809338b16","declaration":"export function resolveSessionAgentId(params: { sessionKey?: string; config?: OpenClawConfig; agentId?: string; fallbackAgentId?: string; }): string;","entrypoint":"memory-host-core","exportName":"resolveSessionAgentId","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"bb27dfb37540b04bb34f8281a3acd97a37ffb4ab7a5acdab529859f6474a0c1d","declaration":"export function resolveSessionTranscriptsDirForAgent(agentId: string, env?: NodeJS.ProcessEnv, homedir?: () => string): string;","entrypoint":"memory-host-core","exportName":"resolveSessionTranscriptsDirForAgent","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"function","recordType":"export"}
{"closureHash":"0b824778ee420a4a199233d8fe4635960ed53a0c96964a9e90e8e9e31c9ffe4b","declaration":"export type MemoryPluginCapability = MemoryPluginCapability;","entrypoint":"memory-host-core","exportName":"MemoryPluginCapability","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"type","recordType":"export"}
{"closureHash":"786e9bcb90b7e3c4a6bda0a54b84bfad4a6d968a0bb05b2a6649e0107cce0f8d","declaration":"export type MemoryPluginCapability = MemoryPluginCapability;","entrypoint":"memory-host-core","exportName":"MemoryPluginCapability","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"type","recordType":"export"}
{"closureHash":"77d2bdba5dec3f7c4ce6b6f5d9607f693dd84be375c74387eec5dcc04c0ce2aa","declaration":"export type MemoryPluginPublicArtifact = MemoryPluginPublicArtifact;","entrypoint":"memory-host-core","exportName":"MemoryPluginPublicArtifact","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"type","recordType":"export"}
{"closureHash":"4a0bc9cba08233a3c603680a77414170971151fb785bd601ffe26de8d031b0c3","declaration":"export type MemoryPromptSectionBuilder = MemoryPromptSectionBuilder;","entrypoint":"memory-host-core","exportName":"MemoryPromptSectionBuilder","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"type","recordType":"export"}
{"closureHash":"19d10efd8ccd6dac324fb7c843b6b0394761d4ce407cbf76d4b18cdbfa2ea051","declaration":"export type MemoryPromptSectionBuilder = MemoryPromptSectionBuilder;","entrypoint":"memory-host-core","exportName":"MemoryPromptSectionBuilder","importSpecifier":"openclaw/plugin-sdk/memory-host-core","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"messaging-targets","importSpecifier":"openclaw/plugin-sdk/messaging-targets","recordType":"module"}
{"closureHash":"dfc00563b0442ebf2e740c87499b5b5be99ebb2e8a0ad3b1a5456ed577666f6c","declaration":"export function buildMessagingTarget(kind: MessagingTargetKind, id: string, raw: string): MessagingTarget;","entrypoint":"messaging-targets","exportName":"buildMessagingTarget","importSpecifier":"openclaw/plugin-sdk/messaging-targets","kind":"function","recordType":"export"}
{"closureHash":"a4b0c494578e7b33fbcf91fbb24d779092dd8710870bb37a92e7e6523f3c43ec","declaration":"export function ensureTargetId(params: { candidate: string; pattern: RegExp; errorMessage: string; }): string;","entrypoint":"messaging-targets","exportName":"ensureTargetId","importSpecifier":"openclaw/plugin-sdk/messaging-targets","kind":"function","recordType":"export"}
@@ -3385,14 +3451,14 @@
{"closureHash":"e982df4834c8e5e2b45ccc4cde433658e190dcf2a7f3b0d2c700d4ef6eb1632d","declaration":"export type PersistentDedupeOptions = PersistentDedupeOptions;","entrypoint":"persistent-dedupe","exportName":"PersistentDedupeOptions","importSpecifier":"openclaw/plugin-sdk/persistent-dedupe","kind":"type","recordType":"export"}
{"closureHash":"dfc56d38508426a6a78afd761e1a1288222c4467ffda62eb27d7eac30671bc21","declaration":"export type PersistentDedupePluginStateOptions = PersistentDedupePluginStateOptions;","entrypoint":"persistent-dedupe","exportName":"PersistentDedupePluginStateOptions","importSpecifier":"openclaw/plugin-sdk/persistent-dedupe","kind":"type","recordType":"export"}
{"category":"runtime","entrypoint":"plugin-command-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","recordType":"module"}
{"closureHash":"4a8d8b3f396313777190457525e0a155e8ee8ff0692608c97b9d3a2d7ad2ab56","declaration":"export function createPluginCommandRuntime(): PluginCommandRuntime;","entrypoint":"plugin-command-runtime","exportName":"createPluginCommandRuntime","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"function","recordType":"export"}
{"closureHash":"93a9965aea93f7823ff6e0f15ec6bc3586281101f6774cb86329e6af2b01362d","declaration":"export function createPluginCommandRuntime(): PluginCommandRuntime;","entrypoint":"plugin-command-runtime","exportName":"createPluginCommandRuntime","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"function","recordType":"export"}
{"closureHash":"00d993432f711b0223902a7d79b6da2e8ce785bac94b048d069ad8fcbe75db6f","declaration":"export const PLUGIN_COMMAND_DISPATCH: typeof PLUGIN_COMMAND_DISPATCH;","entrypoint":"plugin-command-runtime","exportName":"PLUGIN_COMMAND_DISPATCH","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"const","recordType":"export"}
{"closureHash":"bf2b23c7135b820678675698ff83436b2cb9ee65974575eb5d80fa0f01973549","declaration":"export type PluginCommandCatalogDecision = PluginCommandCatalogDecision;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandCatalogDecision","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"ec1b62205ef1465fac3a939cec5af0db61cc246b298284164f2b25537d503236","declaration":"export type PluginCommandDispatch = Readonly<{ kind: \"plugin\"; execute: (context: PluginCommandDispatchContext) => Promise<PluginCommandResult>; [pluginCommandDispatchBrand]: true;}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandDispatch","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"1e583a3ad9edb24b54ae0b988c89515953bb09f162718ef76dca2dce529e612e","declaration":"export type PluginCommandDispatchContext = Readonly<{ 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\"];}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandDispatchContext","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"7114202fdc199ed3fb7b772e488aad4b0ae5b6142086279a5653832339de78b1","declaration":"export type PluginCommandNativeCandidate = Readonly<{ name: string; description: string; descriptionLocalizations?: Readonly<Record<string, string>>; acceptsArgs: boolean; requireAuth: boolean; progressMessage?: string; prepareDispatch: (rawArgs?: string) => PluginCommandCatalogDecision;}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandNativeCandidate","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"ae80c13f972aceaa33ba8f814bafe2c1e5d9f6c6f5bf4b36de44c5a217cd075b","declaration":"export type PluginCommandCatalogDecision = PluginCommandCatalogDecision;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandCatalogDecision","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"c82316b00a069c77be9d701e35a1db15df936c5ae25682536a191e6bfaf181dd","declaration":"export type PluginCommandDispatch = Readonly<{ kind: \"plugin\"; execute: (context: PluginCommandDispatchContext) => Promise<PluginCommandResult>; [pluginCommandDispatchBrand]: true;}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandDispatch","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"c1bdb21a3a5349518b40e9584b3363dce566c4a9d13adf02f465faa4cb3b694f","declaration":"export type PluginCommandDispatchContext = Readonly<{ 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\"];}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandDispatchContext","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"9cd03a24480d9f60eb50ef65bd1c0b280d7171387bf34d90f25a44a606c2be31","declaration":"export type PluginCommandNativeCandidate = Readonly<{ name: string; description: string; descriptionLocalizations?: Readonly<Record<string, string>>; acceptsArgs: boolean; requireAuth: boolean; progressMessage?: string; prepareDispatch: (rawArgs?: string) => PluginCommandCatalogDecision;}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandNativeCandidate","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"02fc8b5c9bcf5902ce275b0e26f7c219025d431dbecc4d9a605062b03904df3b","declaration":"export type PluginCommandReplyOptions = Readonly<{ [PLUGIN_COMMAND_DISPATCH]?: Readonly<{ kind: \"plugin\" | \"non-plugin\"; }>;}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandReplyOptions","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"e392a0cdd1b2504b72d99d2f342670333602919e6005400e69b9017da01439b2","declaration":"export type PluginCommandRuntime = Readonly<{ listNativeCandidates: (provider: string) => readonly PluginCommandNativeCandidate[]; retainNativeCatalog: (provider: string) => void;}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandRuntime","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"closureHash":"85bc80ebe71a49e20bd694b8e26ce92236d0c399766a95b68d40fc7a780934db","declaration":"export type PluginCommandRuntime = Readonly<{ listNativeCandidates: (provider: string) => readonly PluginCommandNativeCandidate[]; retainNativeCatalog: (provider: string) => void;}>;","entrypoint":"plugin-command-runtime","exportName":"PluginCommandRuntime","importSpecifier":"openclaw/plugin-sdk/plugin-command-runtime","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"plugin-config-runtime","importSpecifier":"openclaw/plugin-sdk/plugin-config-runtime","recordType":"module"}
{"closureHash":"5f7bee4e3a0121f16c56af8da4317eab4a9b874f72e1936866231412b1299d3e","declaration":"export function mergeDeep(base: unknown, override: unknown, options?: DeepMergeOptions): unknown;","entrypoint":"plugin-config-runtime","exportName":"mergeDeep","importSpecifier":"openclaw/plugin-sdk/plugin-config-runtime","kind":"function","recordType":"export"}
{"closureHash":"605ebf4cd3d4d4028a5355b3b3520b99543cf4572b64afcf346b228c1f5cfab3","declaration":"export function requireRuntimeConfig(config: OpenClawConfig, context: string): OpenClawConfig;","entrypoint":"plugin-config-runtime","exportName":"requireRuntimeConfig","importSpecifier":"openclaw/plugin-sdk/plugin-config-runtime","kind":"function","recordType":"export"}
@@ -3403,9 +3469,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":"fd766c74118002291fa28dcd19a9677cdf9f615fe09994862f95b989dd36479a","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":"bcdcc487ce9eee949611005455c7cb794c78852875f5749d1712e27c02ce4cf8","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":"d759a25775cb15d3f1804e39e98518f83b67b29ba3ab2fd84d4bf16106d9fdb9","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"plugin-entry","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"cff7e843ff24f7db2fd0f413d247310c86216bd9b51393b64c22f0ef85cda68e","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"}
@@ -3415,16 +3481,16 @@
{"closureHash":"732f3c1b0e4942089773fad9da886d7b7bed41e7f1bb45d79c26deac15f6770b","declaration":"export type MigrationDetection = MigrationDetection;","entrypoint":"plugin-entry","exportName":"MigrationDetection","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"f40046e61c3037ec599a627e1088b8c78d1fe057d858e13cfaff1eab800e9f1f","declaration":"export type MigrationItem = MigrationItem;","entrypoint":"plugin-entry","exportName":"MigrationItem","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"934363b212df1e356365d44e0684401985228a2aeaf859aa13c840bae6e2190b","declaration":"export type MigrationPlan = MigrationPlan;","entrypoint":"plugin-entry","exportName":"MigrationPlan","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"5f753d95db38cc2d1ce2d35f8603c1599eb108cbb8fab484e9f0f04d2eb7783a","declaration":"export type MigrationProviderContext = MigrationProviderContext;","entrypoint":"plugin-entry","exportName":"MigrationProviderContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"428402413735d12151b028f2c301ec73c0e7cce87e63e105397c626d287a8ba2","declaration":"export type MigrationProviderPlugin = MigrationProviderPlugin;","entrypoint":"plugin-entry","exportName":"MigrationProviderPlugin","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"359b28bf96434ed6f2e65c68a0619e7833f775cc585c7706160a26a0f012f367","declaration":"export type MigrationProviderContext = MigrationProviderContext;","entrypoint":"plugin-entry","exportName":"MigrationProviderContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"2ebb80fd4f82783977822aa52e98416a10567df49a7190a8546ca5be6723113b","declaration":"export type MigrationProviderPlugin = MigrationProviderPlugin;","entrypoint":"plugin-entry","exportName":"MigrationProviderPlugin","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"cea9632d824ebf247f131958f8db4916ae60a37d4d5493e06f789d883dab6574","declaration":"export type MigrationSummary = MigrationSummary;","entrypoint":"plugin-entry","exportName":"MigrationSummary","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"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":"2ddf03be75f0d46c8a7e1d7a3d3e70122001b190dcb361132cef2f1d23d8ddec","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"647007b989ba3d08c520ec68873f65f22f231b0274daf10f5d219074fd2fcba6","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"aded5b666490cf7e5cca6bf3942c5190ad1fc30fc73f542505c53e5999f649a9","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"1b85aede0a5709f8de9905bcedb2b1acbbdb6db5fdcdd7321e2294c2f8866424","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":"ccae64ce42b52f34fc0f2adffe6202985c2c8464e3e2df19f43ae1eb0005e808","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"87cbaf84f362b665d7e0a8c8d62835b297f00629a3d4200d6d07f3938b439f9c","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"}
@@ -3438,14 +3504,14 @@
{"closureHash":"06e75d118c92e256eb6fe3c706844b4f03c2cba936f07c571702e1e606138cde","declaration":"export type OpenClawPluginSecurityAuditContext = OpenClawPluginSecurityAuditContext;","entrypoint":"plugin-entry","exportName":"OpenClawPluginSecurityAuditContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"ddc2738dd0ece94ddde9a7c655f92c15ec6416645ecf932d4aa404c7b7761159","declaration":"export type OpenClawPluginService = OpenClawPluginService;","entrypoint":"plugin-entry","exportName":"OpenClawPluginService","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"26dd6974af3127ca18835b3f7294f2dae0f7fab63c6d326e999e90366999dc6e","declaration":"export type OpenClawPluginServiceContext = OpenClawPluginServiceContext;","entrypoint":"plugin-entry","exportName":"OpenClawPluginServiceContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"4b4e5425c1e19a0d00f99e3b1f078f101a87a38dbf3cb81e124665ac11bb68d9","declaration":"export type OpenClawPluginToolContext = OpenClawPluginToolContext;","entrypoint":"plugin-entry","exportName":"OpenClawPluginToolContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"cf4bb672a5d6622273e847afbab9b823e0fdb7bbecd43eebb2620c7711924273","declaration":"export type OpenClawPluginToolFactory = OpenClawPluginToolFactory;","entrypoint":"plugin-entry","exportName":"OpenClawPluginToolFactory","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"d0230fba39834d6c8e620d19799a0006eeea6a7a75a954930cb10acc0138b09f","declaration":"export type OpenClawPluginToolContext = OpenClawPluginToolContext;","entrypoint":"plugin-entry","exportName":"OpenClawPluginToolContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"709aac28446af536b23ee9673d2e3ed3ca733faab5c47be6ccbf14b424f48798","declaration":"export type OpenClawPluginToolFactory = OpenClawPluginToolFactory;","entrypoint":"plugin-entry","exportName":"OpenClawPluginToolFactory","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"b749d0cceb7b02f8e2e810c9a1f4fea64effc4a2ddb0da972d873781d2a70471","declaration":"export type PluginAgentEventEmitParams = PluginAgentEventEmitParams;","entrypoint":"plugin-entry","exportName":"PluginAgentEventEmitParams","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"402087ed5375c1fadc768f11ff28215402b3db725b9e8f924d195623993aa611","declaration":"export type PluginAgentEventEmitResult = PluginAgentEventEmitResult;","entrypoint":"plugin-entry","exportName":"PluginAgentEventEmitResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"028cd39dd470117f37aff9d199e99c7eadaa99a2af56810c3033e488587e56e2","declaration":"export type PluginAgentEventSubscriptionRegistration = PluginAgentEventSubscriptionRegistration;","entrypoint":"plugin-entry","exportName":"PluginAgentEventSubscriptionRegistration","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"3d9f3c666f1a8f37cd4fd2bf621d793b6626ce36edc96bd3922498a8f4ebfc19","declaration":"export type PluginAgentTurnPrepareEvent = PluginAgentTurnPrepareEvent;","entrypoint":"plugin-entry","exportName":"PluginAgentTurnPrepareEvent","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"dd9b818f8b19ced207493eea1b75da8a38b24a5dc4c9ac46288f9329ba06f0f3","declaration":"export type PluginAgentTurnPrepareResult = PluginAgentTurnPrepareResult;","entrypoint":"plugin-entry","exportName":"PluginAgentTurnPrepareResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"d9d24565b06f891a687f49672129beac9d38ccb817526ed1a6579efcb5825eb0","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"plugin-entry","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"5c7a4e89ddfb6bed00f2ca8e67e43f150fedb3182275a525411365855d581c22","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"plugin-entry","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"a50f802cdb46fb073ccba3d7b5c2a3c66c2b5aeccca3368222f9a520e66055ca","declaration":"export type PluginCommandResult = PluginCommandResult;","entrypoint":"plugin-entry","exportName":"PluginCommandResult","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"b9a7fd2bdde1d99b58227e6ff01853420fee36357c2fa5e2d9ef5fbcef11ac65","declaration":"export type PluginControlUiDescriptor = PluginControlUiDescriptor;","entrypoint":"plugin-entry","exportName":"PluginControlUiDescriptor","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
{"closureHash":"f06379ada10ce0eca4e66bdf978db2c0035e054a135dc044c6d831ac7797c08f","declaration":"export type PluginConversationBinding = PluginConversationBinding;","entrypoint":"plugin-entry","exportName":"PluginConversationBinding","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"}
@@ -3571,23 +3637,23 @@
{"closureHash":"4754c7eecdfeb9bec0f26a3238e6ad00ffcab19368487e8b5263e305b505a0f9","declaration":"export function createChannelInteractiveDispatcher<TChannel extends string, TInteractiveKey extends PropertyKey, TContext extends ChannelInteractiveHandlerContext<TChannel, TInteractiveKey>, TResult extends { handled?: boolean; } | void = void | { handled?: boolean; }, TDispatchInteractiveKey extends PropertyKey = TInteractiveKey>(config: { channel: TChannel; interactiveKey: TInteractiveKey; dispatchInteractiveKey?: TDispatchInteractiveKey; }): (params: { data: string; dedupeId: string; ctx: ChannelInteractiveDispatchContext<TContext, TInteractiveKey, TDispatchInteractiveKey>; respond: TContext[\"respond\"]; conversation?: Parameters<typeof createInteractiveConversationBindingHelpers>[0][\"conversation\"]; onMatched?: () => Promise<void> | void; afterInvoke?: (result: TResult) => Promise<void> | void; }) => Promise<InteractiveDispatchResult<TResult>>;","entrypoint":"plugin-runtime","exportName":"createChannelInteractiveDispatcher","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"0c3a6112c7f680fed5c23a712088c1190973f4bb8d95cae4c334952f332159ad","declaration":"export function createInteractiveConversationBindingHelpers(params: { registration: RegisteredInteractiveMetadata; senderId?: string; conversation: PluginBindingConversation; }): { requestConversationBinding: (binding?: PluginConversationBindingRequestParams) => Promise<PluginConversationBindingRequestResult>; detachConversationBinding: () => Promise<{ removed: boolean; }>; getCurrentConversationBinding: () => Promise<PluginConversationBinding | null>; };","entrypoint":"plugin-runtime","exportName":"createInteractiveConversationBindingHelpers","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"fb50ceec196dacc19da2cb48813071d009170fcb1663d646715a7cfce9d6d956","declaration":"export function dispatchPluginInteractiveHandler<TRegistration extends PluginInteractiveDispatchRegistration, TResult extends { handled?: boolean; } | void = void | { handled?: boolean; }>(params: { channel: TRegistration[\"channel\"]; data: string; dedupeId?: string; onMatched?: () => Promise<void> | void; invoke: (match: PluginInteractiveMatch<TRegistration>) => Promise<TResult> | TResult; afterInvoke?: (result: TResult) => Promise<void> | void; }): Promise<InteractiveDispatchResult<TResult>>;","entrypoint":"plugin-runtime","exportName":"dispatchPluginInteractiveHandler","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"983131a9d5c2971ecd7f2fb04f9d664d6854535d1abe2099baf2292014c30b23","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":"dfc8fc733f281bfbe0cc270964f0f657f17c2b97f21bc1b316aee6e9de8ff6ba","declaration":"export function getGlobalHookRunner(): HookRunner | null;","entrypoint":"plugin-runtime","exportName":"getGlobalHookRunner","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"ad89f0a3d6986be8ac3e462a7e58771c2b205055cefaaa181c00ab0b8cf9126e","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":"79b4dc5c92ca4df7380b2b5b9ef0f47ce05c32399ecdb9358d5ace007f6ac5a0","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":"8240e99e361a089d6dacdaecb1d367e31bdce8be4d3b137a5b0065904bac11c6","declaration":"export function getPluginRuntimeGatewayRequestScope(): PluginRuntimeGatewayRequestScope | undefined;","entrypoint":"plugin-runtime","exportName":"getPluginRuntimeGatewayRequestScope","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"}
{"closureHash":"cd4663caa45fa74583e45884af8ad4f7b257c541f9fc6e2d3e94e36b8f5c0348","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":"c53214cb523257e979580c6683f378f2f8e85c154e18c8e30ad84ae0eba28c28","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":"94e8ab88f5f42afc3ba7300ea0da6364722360be9083d89aade693b82c3e162f","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":"58b1f1492289993c25025fb63fcc64bc3027e882ca04926493ae9edc60dfd378","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":"b9c2311f14f5fbed83650554e94f5323ad37956c527ffb532f0bcecd7a060c76","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":"2ddf03be75f0d46c8a7e1d7a3d3e70122001b190dcb361132cef2f1d23d8ddec","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"aded5b666490cf7e5cca6bf3942c5190ad1fc30fc73f542505c53e5999f649a9","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"}
{"closureHash":"93c034724a937bb1239a3b4a386a20ac75fbcf66229842cc4c702c3360409e4c","declaration":"export type PluginConversationBindingRequestResult = PluginConversationBindingRequestResult;","entrypoint":"plugin-runtime","exportName":"PluginConversationBindingRequestResult","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"590c148a7b82d14242a172bee5027840ddd5366025200e48704ef4ae8f4bf0ee","declaration":"export type PluginInteractiveRegistration<TContext = unknown, TChannel extends string = string, TResult = PluginInteractiveHandlerResult> = PluginInteractiveRegistration<TContext, TChannel, TResult>;","entrypoint":"plugin-runtime","exportName":"PluginInteractiveRegistration","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"b94637421f524b48f7e497e449491475a2cc35f3d6dc43bdf5274b401b9424b0","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"plugin-runtime","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"8d8f8c012d739749de557261960af8c0c714403fefa6fa15bd06ddbaee90aee3","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"plugin-runtime","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"closureHash":"f16f4b33d2dd78e5d5da7b1aaeee0441ab35cd232b032e8a33219def7cf65f0f","declaration":"export type RuntimeLogger = RuntimeLogger;","entrypoint":"plugin-runtime","exportName":"RuntimeLogger","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"provider-auth","importSpecifier":"openclaw/plugin-sdk/provider-auth","recordType":"module"}
{"closureHash":"d5f31c750f1d545b3a51177ba4a008d6cf646165a8fc0c0c1328fa9999b8d6e2","declaration":"export function applyAuthProfileConfig(cfg: OpenClawConfig, params: { profileId: string; provider: string; mode: \"api_key\" | \"aws-sdk\" | \"oauth\" | \"token\"; email?: string; displayName?: string; preferProfileFirst?: boolean; }): OpenClawConfig;","entrypoint":"provider-auth","exportName":"applyAuthProfileConfig","importSpecifier":"openclaw/plugin-sdk/provider-auth","kind":"function","recordType":"export"}
@@ -3671,10 +3737,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":"720c33e7d2fb1f65d8fd6c7949e9498fda0a1b4eb0ccf6a7635b2dce58d68d05","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":"228e8e3d4bd122168da916b923639accece60b5706df52fb437fff2b2a46f18f","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":"b066e2fa15256bc32e1fa098c5302922f0db5ccbca4a59c3331860e822c779fc","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":"b7e37ed1adcc928a9a65520f5c288051f01e873a99bcb559488de03869bb6cf7","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":"bf54f4d4fa91bb7622264448c1d6c8c0877e6c6da7c49017411e4bfbf92440ea","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":"173301408b9dde514a93cd380e45fed805b669a49db3a120089510d82ad8eba5","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":"f37df52cd2e01f2d5a93820aba9cd86666219819bb973d56bca16660ff9e8adf","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":"20fd48026e5e6f620a182ccb85f178477954f31b382c38ab2dddb2340474783b","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"}
@@ -3923,7 +3989,7 @@
{"closureHash":"47c7a11095835696862fe7b72fccf28736af6308347543c26b5b2f538d76860b","declaration":"export const GROUP_POLICY_BLOCKED_LABEL: { readonly group: \"group messages\"; readonly guild: \"guild messages\"; readonly room: \"room messages\"; readonly channel: \"channel messages\"; readonly space: \"space messages\";};","entrypoint":"runtime-group-policy","exportName":"GROUP_POLICY_BLOCKED_LABEL","importSpecifier":"openclaw/plugin-sdk/runtime-group-policy","kind":"const","recordType":"export"}
{"category":"runtime","entrypoint":"runtime-store","importSpecifier":"openclaw/plugin-sdk/runtime-store","recordType":"module"}
{"closureHash":"e11d2c2694b927c79b6e07789be6bb56269d5ef1ec95b395a6e9c46f43883cbc","declaration":"export function createPluginRuntimeStore<T>(errorMessage: string): { setRuntime: (next: T) => void; clearRuntime: () => void; tryGetRuntime: () => T | null; getRuntime: () => T; };\nexport function createPluginRuntimeStore<T>(options: PluginRuntimeStoreOptions): { setRuntime: (next: T) => void; clearRuntime: () => void; tryGetRuntime: () => T | null; getRuntime: () => T; };","entrypoint":"runtime-store","exportName":"createPluginRuntimeStore","importSpecifier":"openclaw/plugin-sdk/runtime-store","kind":"function","recordType":"export"}
{"closureHash":"b94637421f524b48f7e497e449491475a2cc35f3d6dc43bdf5274b401b9424b0","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"runtime-store","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/runtime-store","kind":"type","recordType":"export"}
{"closureHash":"8d8f8c012d739749de557261960af8c0c714403fefa6fa15bd06ddbaee90aee3","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"runtime-store","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/runtime-store","kind":"type","recordType":"export"}
{"category":null,"entrypoint":"secret-file","importSpecifier":"openclaw/plugin-sdk/secret-file","recordType":"module"}
{"closureHash":null,"declaration":"export function createSecretFileAtomic(params: SecretFileWriteParams): Promise<void>;","entrypoint":"secret-file","exportName":"createSecretFileAtomic","importSpecifier":"openclaw/plugin-sdk/secret-file","kind":"function","recordType":"export"}
{"closureHash":null,"declaration":"export function readSecretFile(filePath: string, label: string, options?: SecretFileReadOptions): Promise<string>;","entrypoint":"secret-file","exportName":"readSecretFile","importSpecifier":"openclaw/plugin-sdk/secret-file","kind":"function","recordType":"export"}
@@ -4034,8 +4100,8 @@
{"closureHash":"a7a32cdc228b5a4b027448fe2e79e332d7b5c5ff50f2afdcb9684bf8eb3e1fce","declaration":"export function deleteSessionUpstreamLink(sessionKey: string, agentId: string, options?: OpenClawStateDatabaseOptions): void;","entrypoint":"session-catalog","exportName":"deleteSessionUpstreamLink","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"194cb8ed04679bd319517a0e228373ac6da06736200610a11a4d274339c92f87","declaration":"export function importSessionCatalogHistory(params: { catalogId: string; threadId: string; read: (params: { cursor?: string; limit: number; }) => Promise<SessionsCatalogReadResult>; sessionId: string; sessionKey: string; agentId: string; cwd?: string; config: OpenClawConfig; }): Promise<void>;","entrypoint":"session-catalog","exportName":"importSessionCatalogHistory","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"fb9a9c6a327c81eb3ccfb3550b0d6a3c4b62d7db43f5c248d41ff2abecf0bbc2","declaration":"export function isExternalUserText(probe: SessionUpstreamProbe, text: string | undefined): boolean;","entrypoint":"session-catalog","exportName":"isExternalUserText","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"31fb6209d427f4ed44b9b1f7b65e7245c67bdcfdd65050106f0f4c54d38ad7a4","declaration":"export function listAdoptedSessionCatalogSessions(params: { config: OpenClawConfig; pluginId: string; runtime: PluginRuntime; sessionEntries?: SessionCatalogEntrySnapshot; sourceFromEntry: (entry: SessionCatalogEntry) => SessionCatalogAdoptedSource | undefined; }): Map<string, string>;","entrypoint":"session-catalog","exportName":"listAdoptedSessionCatalogSessions","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"35b393e6be657b65d68f37c1c7726777418db4faafff412a11bba91c44af488a","declaration":"export function listSessionCatalogEntries(params: { config: OpenClawConfig; runtime: PluginRuntime; sessionEntries?: SessionCatalogEntrySnapshot; }): SessionCatalogAgentEntry[];","entrypoint":"session-catalog","exportName":"listSessionCatalogEntries","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"1988a5c5a4b562ce48446bfa75561c662f80390933c09a0ff3b7c1f0e0e35fa1","declaration":"export function listAdoptedSessionCatalogSessions(params: { config: OpenClawConfig; pluginId: string; runtime: PluginRuntime; sessionEntries?: SessionCatalogEntrySnapshot; sourceFromEntry: (entry: SessionCatalogEntry) => SessionCatalogAdoptedSource | undefined; }): Map<string, string>;","entrypoint":"session-catalog","exportName":"listAdoptedSessionCatalogSessions","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"81606f18d8675970e5cefba546a1dfffb9a53ce4e3020e906fb026746df816cb","declaration":"export function listSessionCatalogEntries(params: { config: OpenClawConfig; runtime: PluginRuntime; sessionEntries?: SessionCatalogEntrySnapshot; }): SessionCatalogAgentEntry[];","entrypoint":"session-catalog","exportName":"listSessionCatalogEntries","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"bcb164340d2d8ff229bd4bb7c68126cfc44cfb171a76f363ef7c78c1cdf16f37","declaration":"export function normalizeUserText(text: string): string;","entrypoint":"session-catalog","exportName":"normalizeUserText","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"7fdcd1b85ee1e56ea8faf0afba025d3a9be0a34a8b7fda9f5f9ead922729ecdc","declaration":"export function sessionCatalogAdoptedSessionKey(prefix: string, source: string): string;","entrypoint":"session-catalog","exportName":"sessionCatalogAdoptedSessionKey","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
{"closureHash":"1e09ce9731a5b5932ec01307e90f9ab93ec0a100616a2a6f3b6416b768e5170b","declaration":"export function sessionCatalogAdoptedSourceKey(hostId: string, threadId: string): string;","entrypoint":"session-catalog","exportName":"sessionCatalogAdoptedSourceKey","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"function","recordType":"export"}
@@ -4049,9 +4115,9 @@
{"closureHash":"1b1c2b933616e206af0fa0f9d5f50435c041013b9699e19891c1117af32f2d42","declaration":"export type SessionCatalogDescriptor = { id: string; capabilities: { createSession?: { startTerminal?: boolean | undefined; model: string; } | undefined; openTerminal?: boolean | undefined; archive: boolean; continueSession: boolean; }; label: string;};","entrypoint":"session-catalog","exportName":"SessionCatalogDescriptor","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"4c50703512f3f7448ea7fe80c0938082c2c962a233848c2dfad992411ca99723","declaration":"export type SessionCatalogEntrySnapshot = SessionCatalogEntrySnapshot;","entrypoint":"session-catalog","exportName":"SessionCatalogEntrySnapshot","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"7761b7c4cccd9df93de1309fe9544bc17ed08fe87f1d833d621f335d52a78512","declaration":"export type SessionCatalogHost = { error?: { message: string; code: string; } | undefined; nextCursor?: string | undefined; nodeId?: string | undefined; sessions: { source?: string | undefined; name?: string | undefined; cwd?: string | undefined; sessionKey?: string | undefined; updatedAt?: number | undefined; createdActor?: { id?: string | undefined; label?: string | undefined; avatarUrl?: string | undefined; type: \"system\" | \"agent\" | \"human\"; } | undefined; createdAt?: number | undefined; modelProvider?: string | undefined; recencyAt?: number | undefined; cliVersion?: string | undefined; gitBranch?: string | undefined; customGroup?: string | undefined; pullRequest?: { state: \"open\" | \"draft\" | \"closed\" | \"merged\"; numbers: number[]; } | undefined; canOpenTerminal?: boolean | undefined; status: string; archived: boolean; threadId: string; canContinue: boolean; canArchive: boolean; }[]; kind: \"gateway\" | \"node\"; label: string; hostId: string; connected: boolean;};","entrypoint":"session-catalog","exportName":"SessionCatalogHost","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"83641e5089f40055ca1f8ec0ce6e2d5879026106694e3d9ecdc806d660b06899","declaration":"export type SessionCatalogListProviderParams = SessionCatalogListProviderParams;","entrypoint":"session-catalog","exportName":"SessionCatalogListProviderParams","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"582baad7ecdbdea2ac131ab8352c741e046b159a8e6d8e08ae95856d11f89478","declaration":"export type SessionCatalogListProviderParams = SessionCatalogListProviderParams;","entrypoint":"session-catalog","exportName":"SessionCatalogListProviderParams","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"1b8060a038d38a9dfcdb65119d42049deeb0fa9410a78298cd29bfd9639d2721","declaration":"export type SessionCatalogLocator = { threadId: string; catalogId: string; hostId: string;};","entrypoint":"session-catalog","exportName":"SessionCatalogLocator","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"1dc27982cf3b5451c7f9b18d9c6416bca9a6b7af08cbbf0eb79f36adbbb00624","declaration":"export type SessionCatalogProvider = SessionCatalogProvider;","entrypoint":"session-catalog","exportName":"SessionCatalogProvider","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"4dd4278241875f3607098638b50f9d7a8903b6bbd38ca7c3a1f56086bc3574b7","declaration":"export type SessionCatalogProvider = SessionCatalogProvider;","entrypoint":"session-catalog","exportName":"SessionCatalogProvider","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"031fa3a50e41f0c7d5672cfbfefe6b5f3a74d7b09824d3a0cf386ab08bdc2ce6","declaration":"export type SessionCatalogPullRequestSummary = { state: \"open\" | \"draft\" | \"closed\" | \"merged\"; numbers: number[];};","entrypoint":"session-catalog","exportName":"SessionCatalogPullRequestSummary","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"2fddff39ee355ab2f5efa463b1a2ff1fdce03da36515d6b4d21988ea28bcd45f","declaration":"export type SessionCatalogReadProviderParams = SessionCatalogReadProviderParams;","entrypoint":"session-catalog","exportName":"SessionCatalogReadProviderParams","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
{"closureHash":"c5e0c59d9f38e43b780d5d9cbf38ebd4299694e0f52221eee8c72e3a29d27e42","declaration":"export type SessionCatalogSession = { source?: string | undefined; name?: string | undefined; cwd?: string | undefined; sessionKey?: string | undefined; updatedAt?: number | undefined; createdActor?: { id?: string | undefined; label?: string | undefined; avatarUrl?: string | undefined; type: \"system\" | \"agent\" | \"human\"; } | undefined; createdAt?: number | undefined; modelProvider?: string | undefined; recencyAt?: number | undefined; cliVersion?: string | undefined; gitBranch?: string | undefined; customGroup?: string | undefined; pullRequest?: { state: \"open\" | \"draft\" | \"closed\" | \"merged\"; numbers: number[]; } | undefined; canOpenTerminal?: boolean | undefined; status: string; archived: boolean; threadId: string; canContinue: boolean; canArchive: boolean;};","entrypoint":"session-catalog","exportName":"SessionCatalogSession","importSpecifier":"openclaw/plugin-sdk/session-catalog","kind":"type","recordType":"export"}
@@ -4639,16 +4705,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":"296a332a70c3af6ed244dc40f665226c3fec4c68ee1e6f836ce62ff9504cbabc","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":"490bd22ff071a126c5a97c9e0df661be490be69d85b92eb6c1b20491b7402e8b","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":"6c3a1859eedd030e8f47fd172946ab37de66367752388c459eac4c3261e929e2","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":"dbb9e65a5f0c657542d4f2ee7a9ecc287476375dc2100984c162c2c9c00447db","declaration":"export type DefinedToolPluginEntry = DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"DefinedToolPluginEntry","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"724409d65bf50cf7dcf9c9031c780f03824af1a7e82c7b7024844c57260f5c34","declaration":"export type ToolPluginExecutionContext = ToolPluginExecutionContext;","entrypoint":"tool-plugin","exportName":"ToolPluginExecutionContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"53cee5e8cd018ab1ae19f13012dcaed6e1837f7bd01098e63ceae66ce61237fa","declaration":"export type ToolPluginFactoryContext<TConfig> = ToolPluginFactoryContext<TConfig>;","entrypoint":"tool-plugin","exportName":"ToolPluginFactoryContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"041a48bbd824537af3458c931016026a328d39516ea0077198ace12988ab3a67","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":"682523157781bddc30d75747c1aa27883e627223fc59f813ff2c5f63460b25f1","declaration":"export type DefinedToolPluginEntry = DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"DefinedToolPluginEntry","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"afccffd717ef9dbc1ff199a8e14d14435dda1ed8053d42152574b7433e535382","declaration":"export type ToolPluginExecutionContext = ToolPluginExecutionContext;","entrypoint":"tool-plugin","exportName":"ToolPluginExecutionContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"}
{"closureHash":"d10d9555479e89485366f0a924d0cecbf897ad9ecf616ded56211dc0450b584b","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":"5cb770b85f7a568f9563c0d6d746ab8f10bb551e61c5ee07b28683ec50a28d00","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":"2250e3fd73eb98ecb4d731f13c8b16158321df14234ad1260131d287f101bb55","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"}
@@ -4682,9 +4748,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":"137a9d7b92bee027864e6b3ed9dab727b82cec93e88d72099ea796f3cba761cf","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":"6a64a3cae4fcbcbb8b6f8cfa74f92730415d2e8a19740b8b8d0945081e3706af","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":"081f16d31a0ae6a890fa372cde3100a3544fe95d584bbaef196009b56a60d275","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":"e01955489104aaa3f3650084dadc2002c82d4b13cda23ba1a20d1e9dd823d204","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"}
@@ -4702,7 +4768,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":"9357b6c5e08176f9f4416d77f22dfce793961da76bf7b88ea1b3a756be25d924","declaration":"export type RegisterWebhookPluginRouteOptions = RegisterWebhookPluginRouteOptions;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookPluginRouteOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"}
{"closureHash":"84c1a1bc93ba8d51365cb2f9100fd65159236ba35a82a1ddc42880fb5338b476","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"}
+10 -10
View File
@@ -1636,26 +1636,26 @@ Do not add direct user-to-user private-store grant APIs.
Phase 3 is complete only when all of the following are demonstrated:
- [ ] Agent-shared and role writes require explicit publisher authority
- [x] Agent-shared and role writes require explicit publisher authority
independent of read authority.
- [ ] Every projection names one audience, purpose, source revision, publisher,
- [x] Every projection names one audience, purpose, source revision, publisher,
expiry/no-expiry decision, and revocation behavior.
- [ ] A projection exposes only its reviewed copy; the target cannot read or
- [x] A projection exposes only its reviewed copy; the target cannot read or
mutate the private source.
- [ ] Projection refresh creates a new reviewed revision, while expiry or
- [x] Projection refresh creates a new reviewed revision, while expiry or
revocation removes all new reads and enumerates affected prior exposures.
- [ ] Postbox remains `off` by default and supports review-required mode before
- [x] Postbox remains `off` by default and supports review-required mode before
any labeled automatic-use mode.
- [ ] A source session can deposit only through a current server-issued source
- [x] A source session can deposit only through a current server-issued source
message handle and receives no list/read/exact-get capability over the
result.
- [ ] Postbox rate limits, provenance, review, purge, and no-auto-promotion
- [x] Postbox rate limits, provenance, review, purge, and no-auto-promotion
behavior are persisted and tested.
- [ ] Owner/admin CLI, API, and UI operations authenticate and use authorized
- [x] Owner/admin CLI, API, and UI operations authenticate and use authorized
plans.
- [ ] No tool, SDK, API, CLI, UI, plugin, or raw argument can create direct
- [x] No tool, SDK, API, CLI, UI, plugin, or raw argument can create direct
private user-to-user store access.
- [ ] Projection, publisher, postbox, expiry, revocation, forged-handle, and
- [x] Projection, publisher, postbox, expiry, revocation, forged-handle, and
prior-exposure tests pass.
### Phase 3 rollback
+1
View File
@@ -378,6 +378,7 @@ Use `isLoopbackHost(host)` when a plugin must accept only the local machine. It
| `plugin-sdk/memory-authorization` | Versioned serializable memory-authorization contracts and selected-capability declarations. This contract alone does not enable isolation, capability admission, or an authorization mode. |
| `plugin-sdk/memory-authorization-conformance` | Pure backend conformance helpers for the memory-authorization contract. |
| `plugin-sdk/memory-postbox-runtime` | Private-local runtime resolver and scoped binding keys for core-issued, turn-bound memory postbox source capabilities. |
| `plugin-sdk/memory-sharing-control-runtime` | Private-local Gateway-profile resolver for selected memory-plugin sharing controls. |
| `plugin-sdk/memory-core-host-embedding-registry` | Private-local after July 2026; Lightweight memory embedding provider registry helpers |
| `plugin-sdk/memory-core-host-engine-curated` | Private-local focused curated-memory annotation parsing for doctor and promotion paths |
| `plugin-sdk/memory-core-host-engine-foundation` | Memory host foundation engine exports |
@@ -399,16 +399,14 @@ export async function prepareCodexAttemptConnection({ params, options }: CodexRu
model: reviewerPolicyContext.model,
});
policyAppServer = resolvePolicyAppServer();
appServer = fenceCodexProjectDocumentsForMemoryIsolation({
agentId: sessionAgentId,
appServer: resolveCodexAppServerForModelProvider({
appServer: policyAppServer,
provider: reviewerPolicyContext.modelProvider,
model: reviewerPolicyContext.model,
config: params.config,
env: process.env,
agentDir,
}),
assertCodexMemoryIsolationSupported(sessionAgentId);
appServer = resolveCodexAppServerForModelProvider({
appServer: policyAppServer,
provider: reviewerPolicyContext.modelProvider,
model: reviewerPolicyContext.model,
config: params.config,
env: process.env,
agentDir,
});
approvalPolicyPromotedForOpenClawToolPolicy =
configuredAppServer.approvalPolicy === "never" && appServer.approvalPolicy === "untrusted";
+29 -13
View File
@@ -1,6 +1,10 @@
// Memory Core tests cover index plugin behavior.
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import type { OpenClawPluginApi, OpenClawPluginCommandDefinition } from "openclaw/plugin-sdk/core";
import type {
OpenClawPluginApi,
OpenClawPluginCommandDefinition,
OpenClawPluginToolContext,
} from "openclaw/plugin-sdk/core";
import type { MemoryPluginRuntime } from "openclaw/plugin-sdk/memory-core-host-runtime-core";
import type { MemoryPluginCapability } from "openclaw/plugin-sdk/memory-host-core";
import {
@@ -202,7 +206,9 @@ describe("memory-core plugin runtime registration", () => {
it("hides intent create, list, and cancel from non-owner turns", () => {
let intentFactory:
| ((ctx: { config?: OpenClawConfig; senderIsOwner?: boolean }) => unknown)
| ((
ctx: Pick<OpenClawPluginToolContext, "config" | "senderIsOwner" | "memoryReadEnforced">,
) => unknown)
| undefined;
plugin.register(
createTestPluginApi({
@@ -277,7 +283,7 @@ describe("memory-core plugin runtime registration", () => {
expect(host.remember).toHaveBeenCalledWith({ content: "durable fact" });
});
it("exposes postbox deposit only with the memory-core-scoped host binding", () => {
it("exposes postbox deposit only with the memory-core-scoped host binding and no readback", async () => {
const factories = new Map<string, (ctx: never) => unknown>();
plugin.register(
createTestPluginApi({
@@ -292,16 +298,26 @@ describe("memory-core plugin runtime registration", () => {
);
const postbox = factories.get("memory_postbox_deposit");
expect(postbox?.({ agentId: "main", sessionKey: "session" } as never)).toBeNull();
expect(
postbox?.({
agentId: "main",
sessionKey: "session",
toolBindings: {
[MEMORY_POSTBOX_TURN_CAPABILITY_BINDING]: "opaque-turn-capability",
[MEMORY_POSTBOX_RUN_ID_BINDING]: "run-1",
},
} as never),
).toMatchObject({ name: "memory_postbox_deposit" });
const tool = postbox?.({
agentId: "main",
sessionKey: "session",
sessionId: "session-1",
toolBindings: {
[MEMORY_POSTBOX_TURN_CAPABILITY_BINDING]: "opaque-turn-capability",
[MEMORY_POSTBOX_RUN_ID_BINDING]: "run-1",
},
} as never) as
| {
name: string;
description: string;
execute: (id: string, params: unknown) => Promise<{ details?: unknown }>;
}
| null
| undefined;
expect(tool).toMatchObject({ name: "memory_postbox_deposit" });
expect(tool?.description).toContain("cannot list, read, or identify postbox items");
const result = await tool?.execute("postbox-call", { content: "one-way observation" });
expect(result?.details).toEqual({ accepted: false });
});
it("keeps memory manager initialization demand-driven", () => {
+11 -2
View File
@@ -30,6 +30,7 @@ import {
builtinScopedMemoryAuthorizedRuntime,
builtinScopedMemoryVirtualView,
} from "./src/memory/scoped-memory-runtime.js";
import { registerScopedMemorySharingGatewayMethods } from "./src/memory/scoped-memory-sharing-gateway.js";
import { buildPromptSection } from "./src/prompt-section.js";
import { registerSessionBackfillGatewayMethods } from "./src/session-backfill-gateway.js";
@@ -224,7 +225,14 @@ function createMemoryPostboxDepositTool(ctx: OpenClawPluginToolContext): AnyAgen
const runId = ctx.toolBindings?.[MEMORY_POSTBOX_RUN_ID_BINDING];
const agentId = ctx.agentId?.trim();
const sessionKey = ctx.sessionKey?.trim();
if (typeof turnCapability !== "string" || typeof runId !== "string" || !agentId || !sessionKey) {
const sessionId = ctx.sessionId?.trim();
if (
typeof turnCapability !== "string" ||
typeof runId !== "string" ||
!agentId ||
!sessionKey ||
!sessionId
) {
return null;
}
return {
@@ -248,7 +256,7 @@ function createMemoryPostboxDepositTool(ctx: OpenClawPluginToolContext): AnyAgen
agentId,
runId,
sessionKey,
...(ctx.sessionId ? { sessionId: ctx.sessionId } : {}),
sessionId,
turnCapability,
content,
}),
@@ -399,6 +407,7 @@ export default definePluginEntry({
const memoryRuntime = createLazyMemoryRuntime(host);
registerShortTermPromotionDreaming(api);
registerSessionBackfillGatewayMethods(api);
registerScopedMemorySharingGatewayMethods(api);
api.registerMemoryCapability({
authorization: MEMORY_CORE_AUTHORIZATION_CAPABILITIES,
// Phase 1B publishes the tested policy adapter; Phase 1C owns admitting it for reads.
+3
View File
@@ -19,6 +19,7 @@ import type {
MemorySearchCommandOptions,
} from "./cli.types.js";
import { configureMemoryCoreDreamingState } from "./dreaming-state.js";
import { registerMemorySharingCli } from "./memory-sharing-cli.js";
import type { MemoryCoreRuntimeHost } from "./memory/runtime-host.js";
import type { MemorySessionBackfillOptions } from "./session-backfill.js";
import {
@@ -322,6 +323,8 @@ export function registerMemoryCli(program: Command, hostOptions?: MemoryCoreRunt
await runMemorySessionBackfill(opts, hostOptions);
});
registerMemorySharingCli(memory);
memory.action(() => {
memory.outputHelp();
process.exitCode = 0;
@@ -318,6 +318,9 @@ describe("dreaming gateway restart cleanup", () => {
}),
),
);
if (!cutOver || !legacy) {
throw new Error("fixture expected both configured agents");
}
isLegacyMemorySurfaceDisabledMock.mockImplementation((agentId) => agentId === "main");
const gateway = createGateway({ agentIds: ["main", "researcher"] });
@@ -0,0 +1,158 @@
import { Command } from "commander";
import type { callGatewayFromCli as CallGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
import { afterEach, describe, expect, it, vi } from "vitest";
import { registerMemorySharingCli } from "./memory-sharing-cli.js";
const callGatewayFromCli = vi.hoisted(() =>
vi.fn<typeof CallGatewayFromCli>(async () => ({ ok: true })),
);
vi.mock("openclaw/plugin-sdk/gateway-runtime", () => ({
addGatewayClientOptions(command: Command) {
return command
.option("--url <url>")
.option("--token <token>")
.option("--password <password>")
.option("--timeout <ms>")
.option("--expect-final");
},
callGatewayFromCli,
}));
function createProgram(): Command {
const program = new Command();
program.name("test");
registerMemorySharingCli(program.command("memory"));
return program;
}
async function run(args: string[]) {
const program = createProgram();
await program.parseAsync(["memory", "sharing", ...args], { from: "user" });
}
describe("memory sharing CLI", () => {
afterEach(() => {
callGatewayFromCli.mockClear();
vi.restoreAllMocks();
});
it("exposes the complete Gateway-only projection and postbox workflow", () => {
const memory = createProgram().commands[0];
const sharing = memory?.commands.find((command) => command.name() === "sharing");
expect(sharing?.commands.map((command) => command.name())).toEqual([
"projection",
"postbox",
"status",
]);
expect(
sharing?.commands
.find((command) => command.name() === "projection")
?.commands.map((command) => command.name()),
).toEqual(["target-register", "preview", "create", "refresh", "revoke", "impact"]);
expect(
sharing?.commands
.find((command) => command.name() === "postbox")
?.commands.map((command) => command.name()),
).toEqual(["mode", "inspect", "review", "purge"]);
});
it("sends an edited approval only through the profile-authenticated Gateway method", async () => {
const write = vi
.spyOn(process.stdout, "write")
.mockImplementation((() => true) as typeof process.stdout.write);
try {
await run([
"postbox",
"review",
"--agent",
"main",
"--item-id",
"postbox-1",
"--decision",
"approve",
"--reviewed-content",
"owner-edited copy",
]);
} finally {
write.mockRestore();
}
expect(callGatewayFromCli).toHaveBeenCalledWith(
"memory.sharing.postbox.review",
expect.objectContaining({ agent: "main" }),
{
agentId: "main",
itemId: "postbox-1",
decision: "approve",
reviewedContent: "owner-edited copy",
},
{ scopes: ["operator.admin"] },
);
const payload = callGatewayFromCli.mock.calls[0]?.[2] as Record<string, unknown>;
expect(payload).not.toHaveProperty("principalId");
expect(payload).not.toHaveProperty("storeId");
expect(payload).not.toHaveProperty("reviewerPrincipalId");
});
it("preserves the required audited no-expiry decision despite Commander no-prefix parsing", async () => {
const write = vi
.spyOn(process.stdout, "write")
.mockImplementation((() => true) as typeof process.stdout.write);
try {
await run([
"projection",
"preview",
"--agent",
"main",
"--source-revision-id",
"revision-1",
"--target-kind",
"conversation",
"--target-id",
"conversation-team",
"--purpose",
"share",
"--preview",
"approved summary",
"--no-expiry-audit-reason",
"owner approved durable reference",
]);
} finally {
write.mockRestore();
}
expect(callGatewayFromCli).toHaveBeenCalledWith(
"memory.sharing.projection.preview",
expect.objectContaining({ agent: "main" }),
{
agentId: "main",
sourceRevisionId: "revision-1",
targetKind: "conversation",
targetId: "conversation-team",
purpose: "share",
preview: "approved summary",
noExpiryAuditReason: "owner approved durable reference",
},
{ scopes: ["operator.admin"] },
);
});
it("rejects a raw private-user target before making any Gateway request", async () => {
await expect(
run([
"projection",
"target-register",
"--agent",
"main",
"--target-kind",
"user",
"--target-id",
"principal-bob",
"--store-id",
"store-bob",
]),
).rejects.toThrow("--target-kind must be conversation, role, or agent-shared.");
expect(callGatewayFromCli).not.toHaveBeenCalled();
});
});
@@ -0,0 +1,252 @@
import type { Command } from "commander";
import {
addGatewayClientOptions,
callGatewayFromCli,
type GatewayRpcOpts,
} from "openclaw/plugin-sdk/gateway-runtime";
type SharingCliOptions = GatewayRpcOpts & {
agent: string;
itemId?: string;
projectionId?: string;
sourceRevisionId?: string;
storeId?: string;
targetKind?: string;
targetId?: string;
purpose?: string;
preview?: string;
content?: string;
reviewedContent?: string;
expiresAt?: string;
expiryAuditReason?: string;
mode?: string;
decision?: string;
};
const ADMIN_SCOPE = ["operator.admin"] as const;
function requireOption(value: string | undefined, option: string): string {
const normalized = value?.trim();
if (!normalized) {
throw new Error(`${option} is required.`);
}
return normalized;
}
function requireProjectionTargetKind(value: string | undefined): "conversation" | "role" | "agent-shared" {
const kind = requireOption(value, "--target-kind");
if (kind !== "conversation" && kind !== "role" && kind !== "agent-shared") {
throw new Error("--target-kind must be conversation, role, or agent-shared.");
}
return kind;
}
function print(value: unknown): void {
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
}
function addGatewayOptions(command: Command): Command {
return addGatewayClientOptions(command)
.requiredOption("--agent <id>", "Agent id")
.option("--json", "Print JSON", false);
}
function registerGatewayAction(
command: Command,
method: string,
params: (options: SharingCliOptions) => Record<string, unknown>,
): void {
command.action(async (options: SharingCliOptions) => {
const result = await callGatewayFromCli(
method,
options,
{ agentId: requireOption(options.agent, "--agent"), ...params(options) },
{ scopes: [...ADMIN_SCOPE] },
);
print(result);
});
}
function projectionParams(options: SharingCliOptions, options2: { content: boolean }) {
const expiresAt = options.expiresAt?.trim();
// Commander reserves a `--no-*` option as a negation and removes the prefix
// from its attribute name, even when the option takes a required value.
const noExpiryAuditReason = options.expiryAuditReason?.trim();
if ((expiresAt ? 1 : 0) + (noExpiryAuditReason ? 1 : 0) !== 1) {
throw new Error("provide exactly one of --expires-at or --no-expiry-audit-reason.");
}
return {
sourceRevisionId: requireOption(options.sourceRevisionId, "--source-revision-id"),
purpose: requireOption(options.purpose, "--purpose"),
preview: requireOption(options.preview, "--preview"),
...(options2.content ? { content: requireOption(options.content, "--content") } : {}),
...(expiresAt ? { expiresAt } : { noExpiryAuditReason }),
};
}
/** Gateway-only operator client for explicit sharing and quarantined postbox review. */
export function registerMemorySharingCli(memory: Command): void {
const sharing = memory
.command("sharing")
.description("Review explicit memory projections and quarantined postbox items");
const projection = sharing.command("projection").description("Manage reviewed projection copies");
const postbox = sharing.command("postbox").description("Review quarantined postbox items");
registerGatewayAction(
addGatewayOptions(sharing.command("status").description("Show redacted sharing status")),
"memory.sharing.status",
() => ({}),
);
registerGatewayAction(
addGatewayOptions(
projection
.command("target-register")
.description("Register one existing non-private store as a reviewed projection target")
.requiredOption("--target-kind <kind>", "conversation, role, or agent-shared")
.requiredOption("--target-id <id>", "Named target audience")
.requiredOption("--store-id <id>", "Existing store with the same non-private audience"),
),
"memory.sharing.projection.target.register",
(options) => ({
targetKind: requireProjectionTargetKind(options.targetKind),
targetId: requireOption(options.targetId, "--target-id"),
storeId: requireOption(options.storeId, "--store-id"),
}),
);
registerGatewayAction(
addGatewayOptions(
projection
.command("preview")
.description("Validate the source and target before creating a reviewed projection")
.requiredOption("--source-revision-id <id>", "Immutable source revision")
.requiredOption("--target-kind <kind>", "conversation, role, or agent-shared")
.requiredOption("--target-id <id>", "Named target audience")
.requiredOption("--purpose <text>", "Human-readable purpose")
.requiredOption("--preview <text>", "Human-readable preview")
.option("--expires-at <timestamp>", "Future ISO timestamp")
.option("--no-expiry-audit-reason <text>", "Audited reason for no expiry"),
),
"memory.sharing.projection.preview",
(options) => {
const params = projectionParams(options, { content: false });
return {
...params,
targetKind: requireProjectionTargetKind(options.targetKind),
targetId: requireOption(options.targetId, "--target-id"),
};
},
);
registerGatewayAction(
addGatewayOptions(
projection
.command("create")
.description("Create one reviewed projection copy")
.requiredOption("--source-revision-id <id>", "Immutable source revision")
.requiredOption("--target-kind <kind>", "conversation, role, or agent-shared")
.requiredOption("--target-id <id>", "Named target audience")
.requiredOption("--purpose <text>", "Human-readable purpose")
.requiredOption("--preview <text>", "Human-readable preview")
.requiredOption("--content <text>", "Reviewed copy content")
.option("--expires-at <timestamp>", "Future ISO timestamp")
.option("--no-expiry-audit-reason <text>", "Audited reason for no expiry"),
),
"memory.sharing.projection.create",
(options) => ({
...projectionParams(options, { content: true }),
targetKind: requireProjectionTargetKind(options.targetKind),
targetId: requireOption(options.targetId, "--target-id"),
}),
);
registerGatewayAction(
addGatewayOptions(
projection
.command("refresh")
.description("Create a new reviewed copy and revoke the replaced projection")
.requiredOption("--projection-id <id>", "Projection to replace")
.requiredOption("--source-revision-id <id>", "Immutable source revision")
.requiredOption("--purpose <text>", "Human-readable purpose")
.requiredOption("--preview <text>", "Human-readable preview")
.requiredOption("--content <text>", "Reviewed copy content")
.option("--expires-at <timestamp>", "Future ISO timestamp")
.option("--no-expiry-audit-reason <text>", "Audited reason for no expiry"),
),
"memory.sharing.projection.refresh",
(options) => ({
...projectionParams(options, { content: true }),
projectionId: requireOption(options.projectionId, "--projection-id"),
}),
);
registerGatewayAction(
addGatewayOptions(
projection
.command("revoke")
.description("Revoke a projection and report prior exposure ids")
.requiredOption("--projection-id <id>", "Projection id"),
),
"memory.sharing.projection.revoke",
(options) => ({ projectionId: requireOption(options.projectionId, "--projection-id") }),
);
registerGatewayAction(
addGatewayOptions(
projection
.command("impact")
.description("Show redacted prior exposure ids for one projection")
.requiredOption("--projection-id <id>", "Projection id"),
),
"memory.sharing.projection.impact",
(options) => ({ projectionId: requireOption(options.projectionId, "--projection-id") }),
);
registerGatewayAction(
addGatewayOptions(
postbox
.command("mode")
.description("Set postbox mode")
.requiredOption("--mode <mode>", "off or review-required"),
),
"memory.sharing.postbox.mode.set",
(options) => ({ mode: requireOption(options.mode, "--mode") }),
);
registerGatewayAction(
addGatewayOptions(
postbox
.command("inspect")
.description("Read one pending postbox item for authorized review")
.requiredOption("--item-id <id>", "Postbox item id"),
),
"memory.sharing.postbox.inspect",
(options) => ({ itemId: requireOption(options.itemId, "--item-id") }),
);
registerGatewayAction(
addGatewayOptions(
postbox
.command("review")
.description("Approve an original or edited reviewed copy, or reject one quarantined item")
.requiredOption("--item-id <id>", "Postbox item id")
.requiredOption("--decision <decision>", "approve or reject")
.option("--reviewed-content <text>", "Edited content to promote only on approval"),
),
"memory.sharing.postbox.review",
(options) => ({
itemId: requireOption(options.itemId, "--item-id"),
decision: requireOption(options.decision, "--decision"),
...(options.reviewedContent?.trim()
? { reviewedContent: options.reviewedContent.trim() }
: {}),
}),
);
registerGatewayAction(
addGatewayOptions(
postbox
.command("purge")
.description("Purge a quarantined or reviewed postbox item")
.requiredOption("--item-id <id>", "Postbox item id"),
),
"memory.sharing.postbox.purge",
(options) => ({ itemId: requireOption(options.itemId, "--item-id") }),
);
sharing.action(() => sharing.outputHelp());
projection.action(() => projection.outputHelp());
postbox.action(() => postbox.outputHelp());
}
@@ -315,6 +315,16 @@ export type MemoryPostboxItemRow = {
purged_at: number | null;
};
/** Immutable link between a reviewed postbox item and the revision it admitted. */
export type MemoryPostboxReviewedCopyRow = {
item_id: string;
agent_id: string;
resource_id: string;
revision_id: string;
reviewed_content_hash: string;
created_at: number;
};
/** Local, idempotent audit delivery queue. Memory content is deliberately absent. */
export type MemoryAuditOutboxRow = {
event_id: string;
@@ -374,6 +384,7 @@ export type ScopedMemoryDatabase = {
memory_postbox_source_handles: MemoryPostboxSourceHandleRow;
memory_postbox_rate_limits: MemoryPostboxRateLimitRow;
memory_postbox_items: MemoryPostboxItemRow;
memory_postbox_reviewed_copies: MemoryPostboxReviewedCopyRow;
memory_audit_outbox: MemoryAuditOutboxRow;
memory_migrations: MemoryMigrationRow;
};
@@ -1,6 +1,7 @@
import { createHash, randomUUID } from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import type { DatabaseSync } from "node:sqlite";
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
import {
executeSqliteQuerySync,
@@ -23,9 +23,12 @@ import {
import { appendSqliteTranscriptMessage } from "../../../../src/config/sessions/session-accessor.sqlite-transcript-write.js";
import { readAuthorizedTranscriptDerivation } from "../../../../src/config/sessions/session-transcript-memory-policy.js";
import { withOwnedSessionTranscriptWrites } from "../../../../src/config/sessions/transcript-write-context.js";
import {
registerAgentRunContext,
resetAgentRunRegistryForTest,
} from "../../../../src/infra/agent-run-registry.js";
import { admitMemoryAuthorizationReadRuntime } from "../../../../src/plugins/memory-authorization-runtime.js";
import { resetMemoryIsolationCutoverForTest } from "../../../../src/plugins/memory-cutover.js";
import { registerAgentRunContext, resetAgentRunRegistryForTest } from "../../../../src/infra/agent-run-registry.js";
import {
persistMemoryRunExposureBeforeContentInDatabase,
readLatestDurableMemoryRunExposure,
@@ -52,6 +55,7 @@ import {
} from "../../../../src/state/openclaw-state-db.js";
import { ensureProfileForEmail } from "../../../../src/state/user-profiles.js";
import { MEMORY_CORE_AUTHORIZATION_CAPABILITIES } from "../authorization.js";
import { createMemoryRuntime } from "../runtime-provider.js";
import { resolveScopedMemoryArtifactBase, withScopedMemoryDatabase } from "./scoped-memory-db.js";
import { builtinScopedMemoryConformanceAdapter } from "./scoped-memory-policy.js";
import {
@@ -59,12 +63,16 @@ import {
readBuiltinScopedMemoryRevisionSnapshot,
setBuiltinScopedMemoryRevisionLifecycle,
} from "./scoped-memory-resources.js";
import { registerBuiltinMemoryProjectionTarget } from "./scoped-memory-sharing.js";
import {
builtinScopedMemoryAuthorizedRuntime,
builtinScopedMemoryVirtualView,
resetBuiltinScopedMemoryAuthorizedRuntimeForTest,
} from "./scoped-memory-runtime.js";
import {
createBuiltinMemoryProjection,
inspectBuiltinMemoryProjectionImpact,
registerBuiltinMemoryProjectionTarget,
} from "./scoped-memory-sharing.js";
import { createBuiltinScopedMemoryStore } from "./scoped-memory-store.js";
const dispatchReplyFromConfig = vi.hoisted(() => vi.fn());
@@ -117,7 +125,7 @@ describe("builtin scoped authorized runtime", () => {
authorization: MEMORY_CORE_AUTHORIZATION_CAPABILITIES,
authorizationConformance: builtinScopedMemoryConformanceAdapter,
virtualView: builtinScopedMemoryVirtualView,
runtime: builtinScopedMemoryAuthorizedRuntime,
runtime: { ...createMemoryRuntime(), ...builtinScopedMemoryAuthorizedRuntime },
},
});
setActivePluginRegistry(registry);
@@ -128,6 +136,7 @@ describe("builtin scoped authorized runtime", () => {
sessionId: string;
chatType: "direct" | "group" | "channel";
primaryConversationId?: string;
primaryConversationTarget?: string;
}) {
const database = openOpenClawAgentDatabase({ agentId: "main" });
database.db
@@ -145,8 +154,8 @@ describe("builtin scoped authorized runtime", () => {
.run(
params.primaryConversationId,
params.chatType,
`${params.chatType}-peer`,
`${params.chatType}-target`,
`${params.primaryConversationId}-peer`,
params.primaryConversationTarget ?? `${params.primaryConversationId}-target`,
);
}
database.db
@@ -216,12 +225,14 @@ describe("builtin scoped authorized runtime", () => {
sessionKey: string;
sessionId: string;
conversationId: string;
conversationTarget?: string;
}) {
createSession({
sessionKey: params.sessionKey,
sessionId: params.sessionId,
chatType: "group",
primaryConversationId: params.conversationId,
primaryConversationTarget: params.conversationTarget,
});
const admitted = admitInboundMemorySessionContext({
context: {
@@ -624,6 +635,28 @@ describe("builtin scoped authorized runtime", () => {
},
}),
).rejects.toThrow("projection is unavailable");
await expect(
builtinScopedMemoryAuthorizedRuntime.writeAuthorized({
context: projectContext,
plan: projectPlan,
mutation: {
version: 1,
kind: "project",
mutationId: "project-private-target",
idempotencyKey: "project-private-target-request",
content: "PRIVATE_TARGET_MUST_NOT_CREATE_A_COPY",
contentType: "markdown",
sourceHandles: [sourceHandle],
target: {
// A JS caller can bypass the SDK union. The runtime remains the final boundary.
audience: { kind: "user", id: "principal-other" },
purpose: "forged private share",
preview: "forged private share",
expiry: { kind: "no-expiry", auditReason: "forged" },
},
} as never,
}),
).rejects.toThrow("memory projection target is unavailable");
});
it("authorizes compaction sources with derive rather than downgrading them to read", async () => {
@@ -808,7 +841,11 @@ describe("builtin scoped authorized runtime", () => {
},
async () => {
await appendSqliteTranscriptMessage(
{ agentId: context.agentId, sessionId: context.sessionId, sessionKey: context.sessionKey },
{
agentId: context.agentId,
sessionId: context.sessionId,
sessionKey: context.sessionKey,
},
{
message: {
role: "assistant",
@@ -1041,16 +1078,19 @@ describe("builtin scoped authorized runtime", () => {
expect(activeDispatcher.sendFinalReply({ text: read.results[0]!.snippet })).toBe(true);
return { queuedFinal: true, counts: { tool: 0, block: 0, final: 1 } };
});
await dispatchInboundMessage({
ctx: buildTestCtx({
const directReplyContext = Object.assign(
buildTestCtx({
AgentId: "main",
SessionId: session.sessionId,
SessionKey: session.sessionKey,
Surface: "telegram",
OriginatingChannel: "telegram",
OriginatingTo: "alice",
AccountId: "default",
}),
{ SessionId: session.sessionId },
);
await dispatchInboundMessage({
ctx: directReplyContext,
cfg: {} as never,
dispatcher,
replyOptions: { runId },
@@ -1069,16 +1109,19 @@ describe("builtin scoped authorized runtime", () => {
ctx.OriginatingTo = "mallory";
return { queuedFinal: true, counts: { tool: 0, block: 0, final: 1 } };
});
await dispatchInboundMessage({
ctx: buildTestCtx({
const reboundReplyContext = Object.assign(
buildTestCtx({
AgentId: "main",
SessionId: session.sessionId,
SessionKey: session.sessionKey,
Surface: "telegram",
OriginatingChannel: "telegram",
OriginatingTo: "alice",
AccountId: "default",
}),
{ SessionId: session.sessionId },
);
await dispatchInboundMessage({
ctx: reboundReplyContext,
cfg: {} as never,
dispatcher: reboundDispatcher,
replyOptions: { runId },
@@ -1094,6 +1137,7 @@ describe("builtin scoped authorized runtime", () => {
const conversationPrincipalId = createConversationSession({
...session,
conversationId: "telegram-group-1",
conversationTarget: "group-target",
});
const channelStore = createBuiltinScopedMemoryStore({
agentId: "main",
@@ -1114,23 +1158,35 @@ describe("builtin scoped authorized runtime", () => {
authorityKind: "conversation",
authorityOwnerId: conversationPrincipalId,
defaultCapabilities: ["retrieve", "read"],
policyEntries: [
{
kind: "publish",
effect: "allow",
principalId: "projection-publisher",
operation: "publish",
grantorPrincipalId: "projection-publisher",
reason: "named projection publisher",
},
{
effect: "allow",
principalId: "projection-publisher",
operation: "policy-admin",
grantorPrincipalId: "projection-publisher",
reason: "named projection administrator",
},
],
actor: { kind: "unattributed" },
reason: "explicitly addressed projection placement",
});
const alicePrincipal = ensureMemoryOperationalPrincipal({
kind: "service",
stableRef: "alice-role-shaped-sender",
options: { agentId: "main" },
});
const alicePrivate = createBuiltinScopedMemoryStore({
agentId: "main",
scopeKind: "user",
audienceKind: "user",
audienceId: alicePrincipal.principalId,
audienceId: "projection-publisher",
authorityKind: "user",
authorityOwnerId: alicePrincipal.principalId,
defaultCapabilities: ["retrieve", "read"],
actor: { kind: "human", id: alicePrincipal.principalId },
authorityOwnerId: "projection-publisher",
defaultCapabilities: ["retrieve", "read", "project"],
actor: { kind: "human", id: "projection-publisher" },
reason: "private placement",
});
const ownerRole = createBuiltinScopedMemoryStore({
@@ -1146,17 +1202,11 @@ describe("builtin scoped authorized runtime", () => {
});
for (const [store, logicalLocator, content, actor] of [
[channelStore, "channel.md", "GROUP_CHANNEL_ONLY", { kind: "unattributed" }],
[
projectionStore,
"projection.md",
"GROUP_EXPLICITLY_ADDRESSED_PROJECTION",
{ kind: "unattributed" },
],
[
alicePrivate,
"alice-private.md",
"GROUP_DENIED_ALICE_PRIVATE_PATH_TITLE_SNIPPET_SCORE_COUNT_CITATION_CURSOR",
{ kind: "human", id: alicePrincipal.principalId },
{ kind: "human", id: "projection-publisher" },
],
[ownerRole, "owner-role.md", "GROUP_DENIED_OWNER_ROLE_FROM_LATEST_ACTOR", { kind: "system" }],
] as const) {
@@ -1168,6 +1218,30 @@ describe("builtin scoped authorized runtime", () => {
actor,
});
}
const privateRevision = createBuiltinScopedMemoryResource({
agentId: "main",
store: alicePrivate,
logicalLocator: "projection-private.md",
content: "GROUP_DENIED_PRIVATE_PROJECTION_SOURCE",
actor: { kind: "human", id: "projection-publisher" },
});
registerBuiltinMemoryProjectionTarget({
agentId: "main",
target: { kind: "conversation", id: conversationPrincipalId },
store: projectionStore,
operatorPrincipalId: "projection-publisher",
});
const projection = createBuiltinMemoryProjection({
agentId: "main",
sourceRevisionId: privateRevision.revisionId,
target: { kind: "conversation", id: conversationPrincipalId },
publisherPrincipalId: "projection-publisher",
reviewedByPrincipalId: "projection-publisher",
purpose: "approved group reference",
preview: "approved group reference",
content: "GROUP_EXPLICITLY_ADDRESSED_PROJECTION",
expiry: { kind: "no-expiry", auditReason: "fixture owner approval" },
});
markCutOver();
installBuiltinSelectedRuntime();
@@ -1190,12 +1264,203 @@ describe("builtin scoped authorized runtime", () => {
expect(serialized).not.toContain(
"GROUP_DENIED_ALICE_PRIVATE_PATH_TITLE_SNIPPET_SCORE_COUNT_CITATION_CURSOR",
);
expect(serialized).not.toContain("GROUP_DENIED_PRIVATE_PROJECTION_SOURCE");
expect(serialized).not.toContain("GROUP_DENIED_OWNER_ROLE_FROM_LATEST_ACTOR");
const unrelatedSession = {
sessionKey: "agent:main:telegram:group:unrelated",
sessionId: "unrelated-group-session",
};
createConversationSession({
...unrelatedSession,
conversationId: "telegram-group-unrelated",
conversationTarget: "unrelated-group-target",
});
const unrelatedHost = createAuthorizedMemoryReadHost({
agentId: "main",
...unrelatedSession,
deliveryContext: { channel: "telegram", accountId: "default", to: "unrelated-group-target" },
});
if (!unrelatedHost) {
throw new Error("fixture failed to build an unrelated group memory host");
}
const unrelatedResult = await unrelatedHost.search({
query: "GROUP_EXPLICITLY_ADDRESSED_PROJECTION",
limit: 10,
});
expect(JSON.stringify(unrelatedResult)).not.toContain("GROUP_EXPLICITLY_ADDRESSED_PROJECTION");
const writeHost = createAuthorizedMemoryWriteHost({
agentId: "main",
...session,
deliveryContext: { channel: "telegram", accountId: "default", to: "group-target" },
});
if (!writeHost) {
throw new Error("fixture failed to build a group memory write host");
}
await expect(writeHost.remember({ content: "GROUP_FORGED_TARGET_MUTATION" })).resolves.toEqual({
disabled: true,
unavailable: true,
error: "memory unavailable",
});
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId: "main",
storeIds: [alicePrivate.storeId],
revisionId: privateRevision.revisionId,
})?.content,
).toBe("GROUP_DENIED_PRIVATE_PROJECTION_SOURCE");
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId: "main",
storeIds: [projectionStore.storeId],
revisionId: projection.copyRevisionId,
})?.content,
).toBe("GROUP_EXPLICITLY_ADDRESSED_PROJECTION");
});
it("durably expires a due projection before a fresh authorized group read", async () => {
vi.useFakeTimers();
try {
const nowMs = Date.now();
const session = {
sessionKey: "agent:main:telegram:group:expiring-projection",
sessionId: "expiring-projection-session",
};
const conversationPrincipalId = createConversationSession({
...session,
conversationId: "telegram-group-expiring-projection",
conversationTarget: "group-target",
});
const target = createBuiltinScopedMemoryStore({
agentId: "main",
scopeKind: "conversation",
audienceKind: "conversation",
audienceId: conversationPrincipalId,
authorityKind: "conversation",
authorityOwnerId: conversationPrincipalId,
defaultCapabilities: ["retrieve", "read"],
policyEntries: [
{
kind: "publish",
effect: "allow",
principalId: "projection-publisher",
operation: "publish",
grantorPrincipalId: "projection-publisher",
reason: "named projection publisher",
},
{
effect: "allow",
principalId: "projection-publisher",
operation: "policy-admin",
grantorPrincipalId: "projection-publisher",
reason: "projection administrator",
},
],
actor: { kind: "unattributed" },
reason: "expiring projection target",
});
const source = createBuiltinScopedMemoryStore({
agentId: "main",
scopeKind: "user",
audienceKind: "user",
audienceId: "projection-publisher",
authorityKind: "user",
authorityOwnerId: "projection-publisher",
defaultCapabilities: ["retrieve", "read", "project"],
actor: { kind: "human", id: "projection-publisher" },
reason: "private projection source",
});
const sourceRevision = createBuiltinScopedMemoryResource({
agentId: "main",
store: source,
logicalLocator: "private-expiring-projection.md",
content: "PRIVATE_EXPIRING_PROJECTION_SOURCE",
actor: { kind: "human", id: "projection-publisher" },
nowMs,
});
registerBuiltinMemoryProjectionTarget({
agentId: "main",
target: { kind: "conversation", id: conversationPrincipalId },
store: target,
operatorPrincipalId: "projection-publisher",
nowMs,
});
const projection = createBuiltinMemoryProjection({
agentId: "main",
sourceRevisionId: sourceRevision.revisionId,
target: { kind: "conversation", id: conversationPrincipalId },
publisherPrincipalId: "projection-publisher",
reviewedByPrincipalId: "projection-publisher",
purpose: "short-lived group reference",
preview: "short-lived group reference",
content: "EXPIRED_PROJECTION_MUST_NOT_READ",
expiry: { kind: "expires", expiresAt: nowMs + 1 },
nowMs,
});
const database = openOpenClawAgentDatabase({ agentId: "main" });
database.db
.prepare(
`INSERT INTO memory_policy_sets
(policy_set_id, agent_id, memory_policy_revision, member_policy_set_ids_json, created_at)
VALUES ('runtime-expiry-policy-set', 'main', 'policy-revision', '[]', ?)`,
)
.run(nowMs);
database.db
.prepare(
`INSERT INTO memory_run_exposures
(exposure_set_id, agent_id, run_id, context_fingerprint, plan_id, revision_number,
previous_exposure_set_id, source_policy_set_ids_json, effective_source_policy_set_id,
exposed_resource_revisions_json, exposure_receipt_ids_json, egress_receipt_ids_json,
delivery_audiences_json, delivery_revision, egress_registry_revision, created_at)
VALUES ('runtime-expiry-exposure', 'main', 'run-expiry', 'context', 'plan', 1, NULL,
'[]', 'runtime-expiry-policy-set', '[]', '[]', '[]', '[]', 'delivery', 'egress', ?)`,
)
.run(nowMs);
database.db
.prepare(
`INSERT INTO memory_run_exposure_resources
(exposure_set_id, resource_revision_id, policy_set_id, created_at)
VALUES ('runtime-expiry-exposure', ?, 'runtime-expiry-policy-set', ?)`,
)
.run(projection.copyRevisionId, nowMs);
markCutOver();
installBuiltinSelectedRuntime();
vi.advanceTimersByTime(1);
const host = createAuthorizedMemoryReadHost({
agentId: "main",
...session,
deliveryContext: { channel: "telegram", accountId: "default", to: "group-target" },
});
if (!host) {
throw new Error("fixture failed to build an expiring group memory host");
}
const result = await host.search({ query: "EXPIRED_PROJECTION_MUST_NOT_READ", limit: 10 });
expect(JSON.stringify(result)).not.toContain("EXPIRED_PROJECTION_MUST_NOT_READ");
expect(
database.db
.prepare("SELECT state FROM memory_projections WHERE projection_id = ?")
.get(projection.projectionId),
).toEqual({ state: "expired" });
expect(
inspectBuiltinMemoryProjectionImpact({
agentId: "main",
projectionId: projection.projectionId,
operatorPrincipalId: "projection-publisher",
}),
).toEqual({
projectionId: projection.projectionId,
exposureSetIds: ["runtime-expiry-exposure"],
});
} finally {
vi.useRealTimers();
}
});
it("selects the subject store itself and commits remember/delete through one durable lifecycle", async () => {
const principalId = "writer";
createBuiltinScopedMemoryStore({
const subjectStore = createBuiltinScopedMemoryStore({
agentId: "main",
scopeKind: "user",
audienceKind: "user",
@@ -1206,6 +1471,28 @@ describe("builtin scoped authorized runtime", () => {
actor: { kind: "human", id: principalId },
reason: "authorized write fixture",
});
const roleStore = createBuiltinScopedMemoryStore({
agentId: "main",
scopeKind: "role",
audienceKind: "role",
audienceId: "writers",
authorityKind: "role",
authorityOwnerId: "writers",
defaultCapabilities: ["append"],
actor: { kind: "system" },
reason: "ordinary capture must not select a role store",
});
const agentSharedStore = createBuiltinScopedMemoryStore({
agentId: "main",
scopeKind: "agent-shared",
audienceKind: "agent-shared",
audienceId: "main",
authorityKind: "agent-shared",
authorityOwnerId: "main",
defaultCapabilities: ["append"],
actor: { kind: "system" },
reason: "ordinary capture must not select an agent-shared store",
});
const appendContext = {
...createContext(principalId),
operation: "append" as const,
@@ -1253,6 +1540,16 @@ describe("builtin scoped authorized runtime", () => {
.prepare("SELECT text FROM memory_scoped_chunks WHERE revision_id = ?")
.all(handle.resourceRevision),
).toEqual([{ text: "durable write sentinel" }]);
expect(
database
.prepare("SELECT count(*) AS count FROM memory_resources WHERE store_id IN (?, ?)")
.get(roleStore.storeId, agentSharedStore.storeId),
).toEqual({ count: 0 });
expect(
database
.prepare("SELECT count(*) AS count FROM memory_resources WHERE store_id = ?")
.get(subjectStore.storeId),
).toEqual({ count: 1 });
});
const audit = openOpenClawStateDatabase({ env: { OPENCLAW_STATE_DIR: stateDir } });
expect(
@@ -1433,7 +1730,8 @@ describe("builtin scoped authorized runtime", () => {
contentType: "markdown",
},
});
if (!written.resourceHandle) {
const writtenHandle = written.resourceHandle;
if (!writtenHandle) {
throw new Error("fixture expected an authorized write handle");
}
const unlinkError = Object.assign(new Error("unlink denied"), { code: "EACCES" });
@@ -1455,7 +1753,7 @@ describe("builtin scoped authorized runtime", () => {
kind: "delete",
mutationId: "tombstone-delete",
idempotencyKey: "tombstone-delete-request",
target: written.resourceHandle,
target: writtenHandle,
},
}),
).resolves.toMatchObject({ status: "committed" });
@@ -1466,12 +1764,12 @@ describe("builtin scoped authorized runtime", () => {
expect(
database
.prepare("SELECT lifecycle_state FROM memory_resource_revisions WHERE revision_id = ?")
.get(written.resourceHandle.resourceRevision),
.get(writtenHandle.resourceRevision),
).toEqual({ lifecycle_state: "tombstoned" });
expect(
database
.prepare("SELECT * FROM memory_scoped_chunks WHERE revision_id = ?")
.all(written.resourceHandle.resourceRevision),
.all(writtenHandle.resourceRevision),
).toEqual([]);
expect(
database
@@ -45,7 +45,10 @@ import {
readBuiltinScopedMemoryRevisionSnapshot,
resolveBuiltinScopedMemoryArtifactPath,
} from "./scoped-memory-resources.js";
import { createBuiltinMemoryProjection } from "./scoped-memory-sharing.js";
import {
createBuiltinMemoryProjection,
expireBuiltinMemoryProjections,
} from "./scoped-memory-sharing.js";
import { createScopedMemorySourcePolicySetId } from "./scoped-memory-store.js";
const PLAN_TTL_MS = 60_000;
@@ -137,6 +140,9 @@ function listAuthorizedStores(params: {
context: MemoryAccessContext;
nowMs: number;
}): readonly AuthorizedStore[] {
// Expiry owns a durable tombstone and prior-exposure impact. Run it before every new
// authorization snapshot so a clock-only filter cannot leave an expired projection active.
expireBuiltinMemoryProjections({ agentId: params.context.agentId, nowMs: params.nowMs });
return withScopedMemoryDatabase(params.context.agentId, (database) => {
const rows = database
.prepare(
@@ -241,7 +247,7 @@ function createPlan(context: MemoryAccessContext): PlanState {
? (["retrieve", "read"] as const)
: context.operation === "derive"
? (["retrieve", "read", "derive"] as const)
: ([context.operation] as const),
: ([context.operation] as const),
),
audienceRevision: store.audienceRevision,
}),
@@ -971,7 +977,10 @@ function resolveTranscriptDerivationSource(params: {
.where("policy_set_id", "=", source.sourcePolicySetId)
.orderBy("policy_id"),
).rows;
if (requirements.length === 0 || requirements.some((requirement) => requirement.retention_state !== "retained")) {
if (
requirements.length === 0 ||
requirements.some((requirement) => requirement.retention_state !== "retained")
) {
throw new Error("authorized transcript derivation is unavailable");
}
for (const requirement of requirements) {
@@ -984,7 +993,11 @@ function resolveTranscriptDerivationSource(params: {
"revision.revision_id",
"policy.current_revision_id",
)
.select(["policy.lifecycle_state", "policy.revocation_epoch", "revision.lifecycle_state as revision_state"])
.select([
"policy.lifecycle_state",
"policy.revocation_epoch",
"revision.lifecycle_state as revision_state",
])
.where("policy.policy_id", "=", requirement.policy_id)
.where("policy.current_revision_id", "=", requirement.expected_revision_id)
.where("policy.revocation_epoch", "=", requirement.expected_revocation_epoch)
@@ -1014,7 +1027,9 @@ function resolveTranscriptDerivationSource(params: {
).rows;
const nowMs = Date.now();
if (
exposureSetIds.some((exposureSetId) => !exposures.some((row) => row.exposure_set_id === exposureSetId)) ||
exposureSetIds.some(
(exposureSetId) => !exposures.some((row) => row.exposure_set_id === exposureSetId),
) ||
exposures.some(
(exposure) =>
exposure.lifecycle_state !== "active" ||
@@ -1931,16 +1946,14 @@ async function writeAuthorizedMutation(params: {
);
executeSqliteQuerySync(
database,
db
.insertInto("memory_revision_policy_requirements")
.values({
revision_id: revisionId,
policy_id: store.policyId,
expected_revision_id: store.policyRevisionId,
expected_revocation_epoch: store.policyRevocationEpoch,
requirement_kind: "output-policy",
created_at: nowMs,
}),
db.insertInto("memory_revision_policy_requirements").values({
revision_id: revisionId,
policy_id: store.policyId,
expected_revision_id: store.policyRevisionId,
expected_revocation_epoch: store.policyRevocationEpoch,
requirement_kind: "output-policy",
created_at: nowMs,
}),
);
for (const source of derivationSources) {
for (const requirement of source.policyRequirements) {
@@ -1956,7 +1969,9 @@ async function writeAuthorizedMutation(params: {
requirement_kind: "source-policy",
created_at: nowMs,
})
.onConflict((conflict) => conflict.columns(["revision_id", "policy_id"]).doNothing()),
.onConflict((conflict) =>
conflict.columns(["revision_id", "policy_id"]).doNothing(),
),
);
}
executeSqliteQuerySync(
@@ -1984,7 +1999,9 @@ async function writeAuthorizedMutation(params: {
requirement_kind: "source-policy",
created_at: nowMs,
})
.onConflict((conflict) => conflict.columns(["revision_id", "policy_id"]).doNothing()),
.onConflict((conflict) =>
conflict.columns(["revision_id", "policy_id"]).doNothing(),
),
);
}
for (const sourceRevisionId of transcriptDerivationSource.sourceRevisionIds) {
@@ -2006,9 +2023,7 @@ async function writeAuthorizedMutation(params: {
parent_kind: "transcript-policy-set",
parent_id: transcriptDerivationSource.sourcePolicySetId,
relation_kind:
transcriptDerivationPurpose === "compaction"
? "compacted-from"
: "flushed-from",
transcriptDerivationPurpose === "compaction" ? "compacted-from" : "flushed-from",
created_at: nowMs,
}),
);
@@ -2355,9 +2370,7 @@ async function stageSealedCompaction(
requirement_kind: "source-policy",
created_at: nowMs,
})
.onConflict((conflict) =>
conflict.columns(["revision_id", "policy_id"]).doNothing(),
),
.onConflict((conflict) => conflict.columns(["revision_id", "policy_id"]).doNothing()),
);
}
const lineage = [
@@ -0,0 +1,438 @@
import type { GatewayRequestHandlerOptions } from "openclaw/plugin-sdk/gateway-runtime";
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createEmptyPluginRegistry } from "../../../../src/plugins/registry-empty.js";
import {
resetPluginRuntimeStateForTest,
setActivePluginRegistry,
} from "../../../../src/plugins/runtime.js";
import {
createGatewayMethodRegistry,
createPluginGatewayMethodDescriptor,
} from "../../../../src/gateway/methods/registry.js";
import { handleGatewayRequest } from "../../../../src/gateway/server-methods.js";
import { registerScopedMemorySharingGatewayMethods } from "./scoped-memory-sharing-gateway.js";
const resolveMemoryPrincipalForUserProfile = vi.hoisted(() => vi.fn());
const inspectBuiltinMemorySharingStatus = vi.hoisted(() => vi.fn());
const registerBuiltinMemoryProjectionTargetStore = vi.hoisted(() => vi.fn());
const setBuiltinMemoryPostboxModeForPrincipal = vi.hoisted(() => vi.fn());
const previewBuiltinMemoryProjection = vi.hoisted(() => vi.fn());
const createBuiltinMemoryProjection = vi.hoisted(() => vi.fn());
const refreshBuiltinMemoryProjection = vi.hoisted(() => vi.fn());
const revokeBuiltinMemoryProjection = vi.hoisted(() => vi.fn());
const inspectBuiltinMemoryProjectionImpact = vi.hoisted(() => vi.fn());
const inspectBuiltinMemoryPostboxItem = vi.hoisted(() => vi.fn());
const reviewBuiltinMemoryPostboxItem = vi.hoisted(() => vi.fn());
vi.mock("openclaw/plugin-sdk/memory-sharing-control-runtime", () => ({
resolveMemoryPrincipalForUserProfile,
}));
vi.mock("./scoped-memory-sharing.js", () => ({
inspectBuiltinMemorySharingStatus,
registerBuiltinMemoryProjectionTargetStore,
setBuiltinMemoryPostboxModeForPrincipal,
previewBuiltinMemoryProjection,
createBuiltinMemoryProjection,
refreshBuiltinMemoryProjection,
revokeBuiltinMemoryProjection,
inspectBuiltinMemoryProjectionImpact,
inspectBuiltinMemoryPostboxItem,
reviewBuiltinMemoryPostboxItem,
}));
type RegisteredMethod = {
handler: (options: GatewayRequestHandlerOptions) => Promise<void>;
scope: NonNullable<Parameters<OpenClawPluginApi["registerGatewayMethod"]>[2]>["scope"];
};
function createHarness() {
const methods = new Map<string, RegisteredMethod>();
const api = {
registerGatewayMethod(
method: string,
handler: RegisteredMethod["handler"],
options?: NonNullable<Parameters<OpenClawPluginApi["registerGatewayMethod"]>[2]>,
) {
methods.set(method, { handler, scope: options?.scope });
},
} as unknown as OpenClawPluginApi;
registerScopedMemorySharingGatewayMethods(api);
return methods;
}
async function invoke(params: { method: RegisteredMethod; request: unknown; profileId?: string }) {
const respond = vi.fn();
await params.method.handler({
params: params.request,
client: params.profileId
? ({ authenticatedUserProfile: { profileId: params.profileId } } as never)
: null,
respond,
} as unknown as GatewayRequestHandlerOptions);
return respond;
}
describe("memory sharing gateway methods", () => {
beforeEach(() => {
vi.clearAllMocks();
resolveMemoryPrincipalForUserProfile.mockReturnValue({
principalId: "principal-alice",
kind: "user",
revision: "principal-revision",
});
});
afterEach(() => {
resetPluginRuntimeStateForTest();
});
it("registers read-only status and admin mode controls", () => {
const methods = createHarness();
expect([...methods.entries()].map(([name, value]) => [name, value.scope])).toEqual([
["memory.sharing.status", "operator.read"],
["memory.sharing.projection.target.register", "operator.admin"],
["memory.sharing.projection.preview", "operator.admin"],
["memory.sharing.projection.create", "operator.admin"],
["memory.sharing.projection.refresh", "operator.admin"],
["memory.sharing.projection.revoke", "operator.admin"],
["memory.sharing.projection.impact", "operator.read"],
["memory.sharing.postbox.mode.set", "operator.admin"],
["memory.sharing.postbox.inspect", "operator.read"],
["memory.sharing.postbox.review", "operator.admin"],
["memory.sharing.postbox.purge", "operator.admin"],
]);
});
it("stops an operator.read client at Gateway dispatch before an admin mutation handler", async () => {
const methods = createHarness();
const registered = methods.get("memory.sharing.projection.create")!;
const handler = vi.fn(registered.handler);
const pluginRegistry = createEmptyPluginRegistry();
pluginRegistry.gatewayHandlers["memory.sharing.projection.create"] = handler;
pluginRegistry.gatewayMethodDescriptors.push(
createPluginGatewayMethodDescriptor({
pluginId: "memory-core",
name: "memory.sharing.projection.create",
handler,
scope: registered.scope!,
}),
);
setActivePluginRegistry(pluginRegistry);
const respond = vi.fn();
await handleGatewayRequest({
req: {
type: "req",
id: "memory-sharing-read-denied",
method: "memory.sharing.projection.create",
params: {},
},
respond,
client: {
connId: "operator-read",
connect: {
role: "operator",
scopes: ["operator.read"],
client: { id: "test", version: "test", platform: "linux", mode: "cli" },
minProtocol: 1,
maxProtocol: 1,
},
},
isWebchatConnect: () => false,
context: { logGateway: { warn: vi.fn() } } as never,
methodRegistry: createGatewayMethodRegistry([]),
});
expect(handler).not.toHaveBeenCalled();
expect(respond).toHaveBeenCalledWith(false, undefined, {
code: "FORBIDDEN",
message: "missing scope: operator.admin",
details: {
code: "MISSING_SCOPE",
missingScope: "operator.admin",
requiredScopes: ["operator.admin"],
},
});
});
it("registers only a profile-authorized non-private projection target store", async () => {
const methods = createHarness();
const respond = await invoke({
method: methods.get("memory.sharing.projection.target.register")!,
request: {
agentId: "main",
targetKind: "conversation",
targetId: "conversation-team",
storeId: "store-team",
},
profileId: "profile-alice",
});
expect(registerBuiltinMemoryProjectionTargetStore).toHaveBeenCalledWith({
agentId: "main",
target: { kind: "conversation", id: "conversation-team" },
storeId: "store-team",
operatorPrincipalId: "principal-alice",
});
expect(respond).toHaveBeenCalledWith(true, {
target: { kind: "conversation", id: "conversation-team" },
});
});
it("derives the status principal from the authenticated profile and rejects caller principal input", async () => {
const methods = createHarness();
inspectBuiltinMemorySharingStatus.mockReturnValue({
postboxMode: "off",
projections: [],
postboxItems: [],
});
const status = methods.get("memory.sharing.status")!;
const valid = await invoke({
method: status,
request: { agentId: "main" },
profileId: "profile-alice",
});
const injectedPrincipal = await invoke({
method: status,
request: { agentId: "main", principalId: "principal-bob" },
profileId: "profile-alice",
});
expect(resolveMemoryPrincipalForUserProfile).toHaveBeenCalledWith({
userProfileId: "profile-alice",
});
expect(inspectBuiltinMemorySharingStatus).toHaveBeenCalledWith({
agentId: "main",
operatorPrincipalId: "principal-alice",
});
expect(valid).toHaveBeenCalledWith(true, {
postboxMode: "off",
projections: [],
postboxItems: [],
});
expect(injectedPrincipal.mock.calls[0]?.[2]).toMatchObject({
code: "INVALID_REQUEST",
message: "unexpected parameter: principalId",
});
});
it("requires an authenticated profile and derives postbox ownership without a store argument", async () => {
const methods = createHarness();
const mode = methods.get("memory.sharing.postbox.mode.set")!;
const unauthenticated = await invoke({
method: mode,
request: { agentId: "main", mode: "review-required" },
});
const valid = await invoke({
method: mode,
request: { agentId: "main", mode: "review-required" },
profileId: "profile-alice",
});
expect(unauthenticated.mock.calls[0]?.[2]).toMatchObject({
code: "FORBIDDEN",
message: "memory sharing requires an authenticated Gateway profile.",
});
expect(setBuiltinMemoryPostboxModeForPrincipal).toHaveBeenCalledWith({
agentId: "main",
principalId: "principal-alice",
mode: "review-required",
});
expect(valid).toHaveBeenCalledWith(true, { mode: "review-required" });
});
it("derives publisher and reviewer from the Gateway profile for a projection", async () => {
const methods = createHarness();
createBuiltinMemoryProjection.mockReturnValue({ projectionId: "projection-1" });
const respond = await invoke({
method: methods.get("memory.sharing.projection.create")!,
request: {
agentId: "main",
sourceRevisionId: "revision-private",
targetKind: "conversation",
targetId: "conversation-team",
purpose: "share contact detail",
preview: "approved contact detail",
content: "reviewed copy",
expiresAt: "2030-01-01T00:00:00.000Z",
},
profileId: "profile-alice",
});
expect(createBuiltinMemoryProjection).toHaveBeenCalledWith({
agentId: "main",
sourceRevisionId: "revision-private",
target: { kind: "conversation", id: "conversation-team" },
purpose: "share contact detail",
preview: "approved contact detail",
content: "reviewed copy",
expiry: { kind: "expires", expiresAt: Date.parse("2030-01-01T00:00:00.000Z") },
publisherPrincipalId: "principal-alice",
reviewedByPrincipalId: "principal-alice",
});
expect(respond).toHaveBeenCalledWith(true, { projectionId: "projection-1" });
});
it("rejects a raw private-user target before projection creation", async () => {
const methods = createHarness();
const respond = await invoke({
method: methods.get("memory.sharing.projection.create")!,
request: {
agentId: "main",
sourceRevisionId: "revision-private",
targetKind: "user",
targetId: "principal-bob",
purpose: "share contact detail",
preview: "approved contact detail",
content: "reviewed copy",
expiresAt: "2030-01-01T00:00:00.000Z",
},
profileId: "profile-alice",
});
expect(createBuiltinMemoryProjection).not.toHaveBeenCalled();
expect(respond.mock.calls[0]?.[2]).toMatchObject({
code: "INVALID_REQUEST",
message: "targetKind must be conversation, role, or agent-shared.",
});
});
it("previews with only the profile-derived publisher and no private source body", async () => {
const methods = createHarness();
previewBuiltinMemoryProjection.mockReturnValue({ preview: "approved contact detail" });
const respond = await invoke({
method: methods.get("memory.sharing.projection.preview")!,
request: {
agentId: "main",
sourceRevisionId: "revision-private",
targetKind: "conversation",
targetId: "conversation-team",
purpose: "share contact detail",
preview: "approved contact detail",
noExpiryAuditReason: "owner approved durable reference",
},
profileId: "profile-alice",
});
expect(previewBuiltinMemoryProjection).toHaveBeenCalledWith({
agentId: "main",
sourceRevisionId: "revision-private",
target: { kind: "conversation", id: "conversation-team" },
purpose: "share contact detail",
preview: "approved contact detail",
expiry: { kind: "no-expiry", auditReason: "owner approved durable reference" },
publisherPrincipalId: "principal-alice",
});
expect(respond).toHaveBeenCalledWith(true, { preview: "approved contact detail" });
});
it("reads projection impact through the profile-derived operator", async () => {
const methods = createHarness();
inspectBuiltinMemoryProjectionImpact.mockReturnValue({
projectionId: "projection-1",
exposureSetIds: ["exposure-1"],
});
const respond = await invoke({
method: methods.get("memory.sharing.projection.impact")!,
request: { agentId: "main", projectionId: "projection-1" },
profileId: "profile-alice",
});
expect(inspectBuiltinMemoryProjectionImpact).toHaveBeenCalledWith({
agentId: "main",
projectionId: "projection-1",
operatorPrincipalId: "principal-alice",
});
expect(respond).toHaveBeenCalledWith(true, {
projectionId: "projection-1",
exposureSetIds: ["exposure-1"],
});
});
it("sends edited review content only to the profile-derived target owner", async () => {
const methods = createHarness();
const respond = await invoke({
method: methods.get("memory.sharing.postbox.review")!,
request: {
agentId: "main",
itemId: "postbox-1",
decision: "approve",
reviewedContent: "owner-edited copy",
},
profileId: "profile-alice",
});
expect(reviewBuiltinMemoryPostboxItem).toHaveBeenCalledWith({
agentId: "main",
itemId: "postbox-1",
decision: "approve",
reviewedContent: "owner-edited copy",
operatorPrincipalId: "principal-alice",
});
expect(respond).toHaveBeenCalledWith(true, { itemId: "postbox-1", decision: "approve" });
});
it("rejects edited content with a rejection decision", async () => {
const methods = createHarness();
const respond = await invoke({
method: methods.get("memory.sharing.postbox.review")!,
request: {
agentId: "main",
itemId: "postbox-1",
decision: "reject",
reviewedContent: "must not be promoted",
},
profileId: "profile-alice",
});
expect(reviewBuiltinMemoryPostboxItem).not.toHaveBeenCalled();
expect(respond.mock.calls[0]?.[2]).toMatchObject({
code: "INVALID_REQUEST",
message: "reviewedContent is available only for approve.",
});
});
it("rejects caller-supplied publisher and reviewer fields before projection creation", async () => {
const methods = createHarness();
const respond = await invoke({
method: methods.get("memory.sharing.projection.create")!,
request: {
agentId: "main",
sourceRevisionId: "revision-private",
targetKind: "conversation",
targetId: "conversation-team",
purpose: "share contact detail",
preview: "approved contact detail",
content: "reviewed copy",
expiresAt: "2030-01-01T00:00:00.000Z",
publisherPrincipalId: "principal-mallory",
},
profileId: "profile-alice",
});
expect(createBuiltinMemoryProjection).not.toHaveBeenCalled();
expect(respond.mock.calls[0]?.[2]).toMatchObject({
code: "INVALID_REQUEST",
message: "unexpected parameter: publisherPrincipalId",
});
});
it("denies a profile that has no current memory principal", async () => {
const methods = createHarness();
resolveMemoryPrincipalForUserProfile.mockReturnValue(undefined);
const respond = await invoke({
method: methods.get("memory.sharing.status")!,
request: { agentId: "main" },
profileId: "profile-without-memory",
});
expect(inspectBuiltinMemorySharingStatus).not.toHaveBeenCalled();
expect(respond.mock.calls[0]?.[2]).toMatchObject({
code: "FORBIDDEN",
message: "memory sharing is unavailable for this profile.",
});
});
});
@@ -0,0 +1,542 @@
import {
ErrorCodes,
errorShape,
type GatewayRequestHandlerOptions,
} from "openclaw/plugin-sdk/gateway-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { resolveMemoryPrincipalForUserProfile } from "openclaw/plugin-sdk/memory-sharing-control-runtime";
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
const MEMORY_SHARING_GATEWAY_METHODS = {
status: "memory.sharing.status",
projectionTargetRegister: "memory.sharing.projection.target.register",
projectionPreview: "memory.sharing.projection.preview",
projectionCreate: "memory.sharing.projection.create",
projectionRefresh: "memory.sharing.projection.refresh",
projectionRevoke: "memory.sharing.projection.revoke",
projectionImpact: "memory.sharing.projection.impact",
postboxMode: "memory.sharing.postbox.mode.set",
postboxInspect: "memory.sharing.postbox.inspect",
postboxReview: "memory.sharing.postbox.review",
postboxPurge: "memory.sharing.postbox.purge",
} as const;
const loadSharing = createLazyRuntimeModule(() => import("./scoped-memory-sharing.js"));
class InvalidMemorySharingRequestError extends Error {}
class ForbiddenMemorySharingRequestError extends Error {}
function paramsRecord(value: unknown): Record<string, unknown> {
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new InvalidMemorySharingRequestError("params must be an object.");
}
return value as Record<string, unknown>;
}
function assertOnlyKeys(params: Record<string, unknown>, keys: readonly string[]) {
const allowed = new Set(keys);
const unexpected = Object.keys(params).find((key) => !allowed.has(key));
if (unexpected) {
throw new InvalidMemorySharingRequestError(`unexpected parameter: ${unexpected}`);
}
}
function readRequiredString(params: Record<string, unknown>, key: string): string {
const value = params[key];
if (typeof value !== "string" || !value.trim()) {
throw new InvalidMemorySharingRequestError(`${key} must be a non-empty string.`);
}
return value.trim();
}
function readAgentId(params: Record<string, unknown>): string {
try {
return normalizeAgentId(readRequiredString(params, "agentId"));
} catch (error) {
throw new InvalidMemorySharingRequestError(
error instanceof Error ? error.message : "agentId is invalid.",
);
}
}
function readProjectionTarget(params: Record<string, unknown>, agentId: string) {
const kind = readRequiredString(params, "targetKind");
if (kind !== "conversation" && kind !== "role" && kind !== "agent-shared") {
throw new InvalidMemorySharingRequestError(
"targetKind must be conversation, role, or agent-shared.",
);
}
const id = readRequiredString(params, "targetId");
if (id === "*" || (kind === "agent-shared" && id !== agentId)) {
throw new InvalidMemorySharingRequestError("projection target is unavailable.");
}
return { kind, id } as const;
}
function readExpiry(params: Record<string, unknown>) {
const expiresAt = params.expiresAt;
const noExpiryAuditReason = params.noExpiryAuditReason;
if (typeof expiresAt === "string" && expiresAt.trim() && noExpiryAuditReason === undefined) {
const parsed = Date.parse(expiresAt);
if (!Number.isSafeInteger(parsed) || parsed <= Date.now()) {
throw new InvalidMemorySharingRequestError("expiresAt must be a future ISO timestamp.");
}
return { kind: "expires" as const, expiresAt: parsed };
}
if (
expiresAt === undefined &&
typeof noExpiryAuditReason === "string" &&
noExpiryAuditReason.trim()
) {
return { kind: "no-expiry" as const, auditReason: noExpiryAuditReason.trim() };
}
throw new InvalidMemorySharingRequestError(
"provide either a future expiresAt or a noExpiryAuditReason.",
);
}
type ProjectionDraftRequest = Readonly<{
agentId: string;
sourceRevisionId: string;
purpose: string;
preview: string;
expiry: ReturnType<typeof readExpiry>;
}>;
type ProjectionCreateRequest = ProjectionDraftRequest &
Readonly<{ target: ReturnType<typeof readProjectionTarget>; content: string }>;
type ProjectionPreviewRequest = ProjectionDraftRequest &
Readonly<{ target: ReturnType<typeof readProjectionTarget> }>;
type ProjectionRefreshRequest = ProjectionDraftRequest &
Readonly<{ projectionId: string; content: string }>;
function readProjectionDraftRequest(value: unknown) {
const request = paramsRecord(value);
return {
agentId: readAgentId(request),
sourceRevisionId: readRequiredString(request, "sourceRevisionId"),
purpose: readRequiredString(request, "purpose"),
preview: readRequiredString(request, "preview"),
expiry: readExpiry(request),
} satisfies ProjectionDraftRequest;
}
function readProjectionPreviewRequest(value: unknown): ProjectionPreviewRequest {
const request = paramsRecord(value);
const draft = readProjectionDraftRequest(value);
assertOnlyKeys(request, [
"agentId",
"sourceRevisionId",
"targetKind",
"targetId",
"purpose",
"preview",
"expiresAt",
"noExpiryAuditReason",
]);
return { ...draft, target: readProjectionTarget(request, draft.agentId) };
}
function readProjectionCreateRequest(value: unknown): ProjectionCreateRequest {
const request = paramsRecord(value);
const draft = readProjectionDraftRequest(value);
assertOnlyKeys(request, [
"agentId",
"sourceRevisionId",
"targetKind",
"targetId",
"purpose",
"preview",
"content",
"expiresAt",
"noExpiryAuditReason",
]);
return {
...draft,
target: readProjectionTarget(request, draft.agentId),
content: readRequiredString(request, "content"),
};
}
function readProjectionRefreshRequest(value: unknown): ProjectionRefreshRequest {
const request = paramsRecord(value);
const draft = readProjectionDraftRequest(value);
assertOnlyKeys(request, [
"agentId",
"projectionId",
"sourceRevisionId",
"purpose",
"preview",
"content",
"expiresAt",
"noExpiryAuditReason",
]);
return {
...draft,
projectionId: readRequiredString(request, "projectionId"),
content: readRequiredString(request, "content"),
};
}
function readProjectionIdRequest(value: unknown) {
const request = paramsRecord(value);
assertOnlyKeys(request, ["agentId", "projectionId"]);
return {
agentId: readAgentId(request),
projectionId: readRequiredString(request, "projectionId"),
};
}
function readProjectionTargetRegisterRequest(value: unknown) {
const request = paramsRecord(value);
assertOnlyKeys(request, ["agentId", "targetKind", "targetId", "storeId"]);
const agentId = readAgentId(request);
return {
agentId,
target: readProjectionTarget(request, agentId),
storeId: readRequiredString(request, "storeId"),
};
}
function readPostboxItemIdRequest(value: unknown) {
const request = paramsRecord(value);
assertOnlyKeys(request, ["agentId", "itemId"]);
return {
agentId: readAgentId(request),
itemId: readRequiredString(request, "itemId"),
};
}
function readPostboxReviewRequest(value: unknown): {
agentId: string;
itemId: string;
decision: "approve" | "reject";
reviewedContent?: string;
} {
const request = paramsRecord(value);
assertOnlyKeys(request, ["agentId", "itemId", "decision", "reviewedContent"]);
const decision = readRequiredString(request, "decision");
if (decision !== "approve" && decision !== "reject") {
throw new InvalidMemorySharingRequestError("decision must be approve or reject.");
}
const reviewedContent = request.reviewedContent;
if (decision === "reject" && reviewedContent !== undefined) {
throw new InvalidMemorySharingRequestError("reviewedContent is available only for approve.");
}
return {
agentId: readAgentId(request),
itemId: readRequiredString(request, "itemId"),
decision,
...(reviewedContent === undefined
? {}
: { reviewedContent: readRequiredString(request, "reviewedContent") }),
};
}
function resolveGatewayPrincipal(
client: {
authenticatedUserProfile?: { profileId: string };
} | null,
): string {
const profileId = client?.authenticatedUserProfile?.profileId;
if (!profileId) {
throw new ForbiddenMemorySharingRequestError(
"memory sharing requires an authenticated Gateway profile.",
);
}
const principal = resolveMemoryPrincipalForUserProfile({ userProfileId: profileId });
if (!principal) {
throw new ForbiddenMemorySharingRequestError("memory sharing is unavailable for this profile.");
}
return principal.principalId;
}
function respondInvalid(respond: GatewayRequestHandlerOptions["respond"], error: unknown) {
const message = error instanceof Error ? error.message : "invalid memory sharing request";
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, message));
}
function respondForbidden(respond: GatewayRequestHandlerOptions["respond"], error: unknown) {
const message = error instanceof Error ? error.message : "memory sharing is unavailable";
respond(false, undefined, errorShape(ErrorCodes.FORBIDDEN, message));
}
function respondUnavailable(respond: GatewayRequestHandlerOptions["respond"]) {
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, "memory sharing is unavailable"));
}
/** Register profile-derived, redacted sharing controls. No handler accepts a principal or private-store id. */
export function registerScopedMemorySharingGatewayMethods(api: OpenClawPluginApi): void {
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.status,
async ({ params, client, respond }) => {
try {
const request = paramsRecord(params);
assertOnlyKeys(request, ["agentId"]);
const agentId = readAgentId(request);
const operatorPrincipalId = resolveGatewayPrincipal(client);
const { inspectBuiltinMemorySharingStatus } = await loadSharing();
respond(true, inspectBuiltinMemorySharingStatus({ agentId, operatorPrincipalId }));
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.read" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.projectionTargetRegister,
async ({ params, client, respond }) => {
try {
const request = readProjectionTargetRegisterRequest(params);
const operatorPrincipalId = resolveGatewayPrincipal(client);
const { registerBuiltinMemoryProjectionTargetStore } = await loadSharing();
registerBuiltinMemoryProjectionTargetStore({ ...request, operatorPrincipalId });
respond(true, { target: request.target });
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.admin" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.projectionPreview,
async ({ params, client, respond }) => {
try {
const request = readProjectionPreviewRequest(params);
const publisherPrincipalId = resolveGatewayPrincipal(client);
const { previewBuiltinMemoryProjection } = await loadSharing();
respond(true, previewBuiltinMemoryProjection({ ...request, publisherPrincipalId }));
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.admin" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.projectionCreate,
async ({ params, client, respond }) => {
try {
const request = readProjectionCreateRequest(params);
const publisherPrincipalId = resolveGatewayPrincipal(client);
const { createBuiltinMemoryProjection } = await loadSharing();
respond(
true,
createBuiltinMemoryProjection({
agentId: request.agentId,
sourceRevisionId: request.sourceRevisionId,
target: request.target,
purpose: request.purpose,
preview: request.preview,
content: request.content,
expiry: request.expiry,
publisherPrincipalId,
reviewedByPrincipalId: publisherPrincipalId,
}),
);
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.admin" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.projectionRefresh,
async ({ params, client, respond }) => {
try {
const request = readProjectionRefreshRequest(params);
const publisherPrincipalId = resolveGatewayPrincipal(client);
const { refreshBuiltinMemoryProjection } = await loadSharing();
respond(
true,
refreshBuiltinMemoryProjection({
agentId: request.agentId,
projectionId: request.projectionId,
sourceRevisionId: request.sourceRevisionId,
purpose: request.purpose,
preview: request.preview,
content: request.content,
expiry: request.expiry,
publisherPrincipalId,
reviewedByPrincipalId: publisherPrincipalId,
}),
);
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.admin" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.projectionRevoke,
async ({ params, client, respond }) => {
try {
const request = readProjectionIdRequest(params);
const operatorPrincipalId = resolveGatewayPrincipal(client);
const { revokeBuiltinMemoryProjection } = await loadSharing();
respond(true, {
projectionId: request.projectionId,
exposureSetIds: revokeBuiltinMemoryProjection({ ...request, operatorPrincipalId }),
});
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.admin" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.projectionImpact,
async ({ params, client, respond }) => {
try {
const request = readProjectionIdRequest(params);
const operatorPrincipalId = resolveGatewayPrincipal(client);
const { inspectBuiltinMemoryProjectionImpact } = await loadSharing();
respond(true, inspectBuiltinMemoryProjectionImpact({ ...request, operatorPrincipalId }));
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.read" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.postboxMode,
async ({ params, client, respond }) => {
try {
const request = paramsRecord(params);
assertOnlyKeys(request, ["agentId", "mode"]);
const agentId = readAgentId(request);
const mode = readRequiredString(request, "mode");
if (mode !== "off" && mode !== "review-required") {
throw new InvalidMemorySharingRequestError("mode must be off or review-required.");
}
const principalId = resolveGatewayPrincipal(client);
const { setBuiltinMemoryPostboxModeForPrincipal } = await loadSharing();
setBuiltinMemoryPostboxModeForPrincipal({ agentId, principalId, mode });
respond(true, { mode });
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.admin" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.postboxInspect,
async ({ params, client, respond }) => {
try {
const request = readPostboxItemIdRequest(params);
const operatorPrincipalId = resolveGatewayPrincipal(client);
const { inspectBuiltinMemoryPostboxItem } = await loadSharing();
respond(true, inspectBuiltinMemoryPostboxItem({ ...request, operatorPrincipalId }));
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.read" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.postboxReview,
async ({ params, client, respond }) => {
try {
const request = readPostboxReviewRequest(params);
const operatorPrincipalId = resolveGatewayPrincipal(client);
const { reviewBuiltinMemoryPostboxItem } = await loadSharing();
reviewBuiltinMemoryPostboxItem({ ...request, operatorPrincipalId });
respond(true, { itemId: request.itemId, decision: request.decision });
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.admin" },
);
api.registerGatewayMethod(
MEMORY_SHARING_GATEWAY_METHODS.postboxPurge,
async ({ params, client, respond }) => {
try {
const request = readPostboxItemIdRequest(params);
const operatorPrincipalId = resolveGatewayPrincipal(client);
const { reviewBuiltinMemoryPostboxItem } = await loadSharing();
reviewBuiltinMemoryPostboxItem({ ...request, operatorPrincipalId, decision: "purge" });
respond(true, { itemId: request.itemId, state: "purged" });
} catch (error) {
if (error instanceof InvalidMemorySharingRequestError) {
respondInvalid(respond, error);
} else if (error instanceof ForbiddenMemorySharingRequestError) {
respondForbidden(respond, error);
} else {
respondUnavailable(respond);
}
}
},
{ scope: "operator.admin" },
);
}
@@ -4,12 +4,14 @@ import path from "node:path";
import { closeOpenClawAgentDatabasesForTest } from "openclaw/plugin-sdk/sqlite-runtime-testing";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
admitMemoryPostboxTurnIngress,
mintMemoryPostboxTurnCapability,
resetMemoryPostboxTurnCapabilitiesForTest,
} from "../../../../src/gateway/memory-postbox-turn-capability.js";
import { openOpenClawAgentDatabase } from "../../../../src/state/openclaw-agent-db.js";
import {
createBuiltinScopedMemoryResource,
createBuiltinScopedMemoryResourceRevision,
readBuiltinScopedMemoryRevisionSnapshot,
} from "./scoped-memory-resources.js";
import {
@@ -17,14 +19,25 @@ import {
depositBuiltinMemoryPostbox,
depositBuiltinMemoryPostboxFromTurnCapability,
expireBuiltinMemoryProjections,
inspectBuiltinMemoryProjectionImpact,
inspectBuiltinMemorySharingStatus,
inspectBuiltinMemoryPostboxItem,
previewBuiltinMemoryProjection,
refreshBuiltinMemoryProjection,
registerBuiltinMemoryProjectionTarget,
revokeBuiltinMemoryProjection,
reviewBuiltinMemoryPostboxItem,
setBuiltinMemoryPostboxMode,
setBuiltinMemoryPostboxModeForPrincipal,
} from "./scoped-memory-sharing.js";
import { createBuiltinScopedMemoryStore } from "./scoped-memory-store.js";
const createCurrentMemorySessionContext = vi.hoisted(() => vi.fn());
vi.mock("../../../../src/state/memory-session-subject.js", () => ({
createCurrentMemorySessionContext,
}));
describe("builtin scoped memory sharing", () => {
let stateDir = "";
const agentId = "main";
@@ -34,11 +47,20 @@ describe("builtin scoped memory sharing", () => {
beforeEach(() => {
stateDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-memory-sharing-"));
vi.stubEnv("OPENCLAW_STATE_DIR", stateDir);
createCurrentMemorySessionContext.mockReturnValue({
kind: "current",
context: {
subject: { kind: "user" },
principalId: alice,
fingerprint: "alice-current-session",
},
});
});
afterEach(() => {
closeOpenClawAgentDatabasesForTest();
resetMemoryPostboxTurnCapabilitiesForTest();
createCurrentMemorySessionContext.mockReset();
vi.unstubAllEnvs();
fs.rmSync(stateDir, { recursive: true, force: true });
});
@@ -153,16 +175,29 @@ describe("builtin scoped memory sharing", () => {
function depositFromVerifiedTurn(params: { content: string; sourceMessageRef: string }) {
const runId = `run-${params.sourceMessageRef}`;
const sessionKey = "agent:main:direct:alice";
const sourceContext = {};
const sourceTurnId = `channel-user:v1:${params.sourceMessageRef}`;
admitMemoryPostboxTurnIngress({
context: sourceContext,
agentId,
sessionKey,
sessionId: "session-alice",
provider: "telegram",
inputProvenance: { kind: "external_user" },
sourceTurnId,
sourceChannelRef: "telegram:account:direct-alice",
senderEvidenceRef: "telegram:sender-alice",
});
const token = mintMemoryPostboxTurnCapability({
agentId,
runId,
sessionKey,
sessionId: "session-alice",
sourceChannelRef: "telegram:alice",
sourceMessageRef: params.sourceMessageRef,
senderEvidenceRef: "telegram:sender-alice",
targetPrincipalId: alice,
sourceContext,
});
if (!token) {
throw new Error("expected verified turn capability");
}
return depositBuiltinMemoryPostboxFromTurnCapability({
agentId,
runId,
@@ -220,13 +255,24 @@ describe("builtin scoped memory sharing", () => {
expect(
database.db
.prepare(
"SELECT source_revision_id, reviewed_by_principal_id, expiry_kind FROM memory_projections",
`SELECT target_audience_kind, target_audience_id, source_revision_id, publisher_principal_id,
reviewed_by_principal_id, purpose, preview, expiry_kind, expiry_audit_reason,
revocation_behavior, state
FROM memory_projections`,
)
.get(),
).toEqual({
target_audience_kind: "conversation",
target_audience_id: channel,
source_revision_id: privateRevision.revisionId,
publisher_principal_id: alice,
reviewed_by_principal_id: alice,
purpose: "share approved contact detail",
preview: "one approved detail",
expiry_kind: "no-expiry",
expiry_audit_reason: "owner approved durable reference",
revocation_behavior: "tombstone-copy",
state: "active",
});
expect(
database.db
@@ -237,6 +283,59 @@ describe("builtin scoped memory sharing", () => {
).toEqual({ parent_id: privateRevision.revisionId });
});
it("previews the authorized projection metadata without reading or changing the private source", () => {
const source = sourceStore();
const target = projectionStore();
const privateRevision = createBuiltinScopedMemoryResource({
agentId,
store: source,
logicalLocator: "private.md",
content: "private source that must not appear in preview",
actor: { kind: "human", id: alice },
});
registerBuiltinMemoryProjectionTarget({
agentId,
target: { kind: "conversation", id: channel },
store: target,
operatorPrincipalId: alice,
});
expect(
previewBuiltinMemoryProjection({
agentId,
sourceRevisionId: privateRevision.revisionId,
target: { kind: "conversation", id: channel },
publisherPrincipalId: alice,
purpose: "share approved contact detail",
preview: "one approved detail",
expiry: { kind: "no-expiry", auditReason: "owner approved durable reference" },
}),
).toEqual({
sourceRevisionId: privateRevision.revisionId,
target: { kind: "conversation", id: channel },
purpose: "share approved contact detail",
preview: "one approved detail",
expiry: "no-expiry",
});
expect(
openOpenClawAgentDatabase({ agentId })
.db.prepare("SELECT COUNT(*) AS count FROM memory_projections")
.get(),
).toEqual({ count: 0 });
});
it("refuses raw private-user projection targets before a helper can create a direct grant", () => {
const privateTarget = privateTargetStore();
expect(() =>
registerBuiltinMemoryProjectionTarget({
agentId,
target: { kind: "user", id: "principal-bob" } as never,
store: privateTarget,
operatorPrincipalId: alice,
}),
).toThrow("memory projection target is unavailable");
});
it("requires independent source project and target publisher authority", () => {
const source = createBuiltinScopedMemoryStore({
agentId,
@@ -395,6 +494,24 @@ describe("builtin scoped memory sharing", () => {
operatorPrincipalId: alice,
}),
).toEqual(["projection-impact-exposure"]);
expect(
inspectBuiltinMemoryProjectionImpact({
agentId,
projectionId: projection.projectionId,
operatorPrincipalId: alice,
}),
).toEqual({
projectionId: projection.projectionId,
exposureSetIds: ["projection-impact-exposure"],
});
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId,
storeIds: [target.storeId],
revisionId: projection.copyRevisionId,
}),
).toBeUndefined();
closeOpenClawAgentDatabasesForTest();
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId,
@@ -515,6 +632,30 @@ describe("builtin scoped memory sharing", () => {
expiry: { kind: "no-expiry", auditReason: "initial review" },
});
const editedSource = createBuiltinScopedMemoryResourceRevision({
agentId,
resourceId: firstSource.resourceId,
content: "private v1 edited",
actor: { kind: "human", id: alice },
});
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId,
storeIds: [target.storeId],
revisionId: original.copyRevisionId,
}),
).toBeUndefined();
expect(
openOpenClawAgentDatabase({ agentId })
.db.prepare("SELECT count(*) AS count FROM memory_projections")
.get(),
).toEqual({ count: 1 });
expect(
openOpenClawAgentDatabase({ agentId })
.db.prepare("SELECT count(*) AS count FROM memory_projections WHERE source_revision_id = ?")
.get(editedSource.revisionId),
).toEqual({ count: 0 });
const refreshed = refreshBuiltinMemoryProjection({
agentId,
projectionId: original.projectionId,
@@ -546,7 +687,98 @@ describe("builtin scoped memory sharing", () => {
).toBe("approved v2");
});
it("keeps postbox off by default and makes review-required deposits one-way", () => {
it("rolls back a replacement when the old projection no longer has the same audience", () => {
const source = sourceStore();
const target = projectionStore();
const otherChannel = "conversation-other";
const otherTarget = createBuiltinScopedMemoryStore({
agentId,
scopeKind: "conversation",
audienceKind: "conversation",
audienceId: otherChannel,
authorityKind: "conversation",
authorityOwnerId: otherChannel,
defaultCapabilities: ["read"],
policyEntries: [
{
kind: "publish",
effect: "allow",
principalId: alice,
operation: "publish",
grantorPrincipalId: alice,
reason: "named publisher",
},
{
effect: "allow",
principalId: alice,
operation: "policy-admin",
grantorPrincipalId: alice,
reason: "projection administrator",
},
],
actor: { kind: "human", id: alice },
reason: "different projection target",
});
const sourceRevision = createBuiltinScopedMemoryResource({
agentId,
store: source,
logicalLocator: "private.md",
content: "private source",
actor: { kind: "human", id: alice },
});
registerBuiltinMemoryProjectionTarget({
agentId,
target: { kind: "conversation", id: channel },
store: target,
operatorPrincipalId: alice,
});
registerBuiltinMemoryProjectionTarget({
agentId,
target: { kind: "conversation", id: otherChannel },
store: otherTarget,
operatorPrincipalId: alice,
});
const original = createBuiltinMemoryProjection({
agentId,
sourceRevisionId: sourceRevision.revisionId,
target: { kind: "conversation", id: channel },
publisherPrincipalId: alice,
reviewedByPrincipalId: alice,
purpose: "share",
preview: "original",
content: "original approved copy",
expiry: { kind: "no-expiry", auditReason: "approved" },
});
expect(() =>
createBuiltinMemoryProjection({
agentId,
sourceRevisionId: sourceRevision.revisionId,
target: { kind: "conversation", id: otherChannel },
publisherPrincipalId: alice,
reviewedByPrincipalId: alice,
purpose: "share",
preview: "replacement",
content: "must never become readable",
expiry: { kind: "no-expiry", auditReason: "approved" },
replaceActiveProjectionId: original.projectionId,
}),
).toThrow("memory projection is unavailable");
expect(
openOpenClawAgentDatabase({ agentId })
.db.prepare("SELECT COUNT(*) AS count FROM memory_projections")
.get(),
).toEqual({ count: 1 });
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId,
storeIds: [target.storeId],
revisionId: original.copyRevisionId,
})?.content,
).toBe("original approved copy");
});
it("keeps postbox off by default and promotes only an explicitly approved reviewed copy", () => {
const target = privateTargetStore();
expect(
depositFromVerifiedTurn({ content: "observation", sourceMessageRef: "message-ref-off" }),
@@ -558,6 +790,7 @@ describe("builtin scoped memory sharing", () => {
operatorPrincipalId: alice,
mode: "review-required",
});
closeOpenClawAgentDatabasesForTest();
expect(
depositBuiltinMemoryPostbox({ agentId, sourceHandleId: "forged", content: "observation" }),
).toEqual({ accepted: false });
@@ -579,12 +812,260 @@ describe("builtin scoped memory sharing", () => {
itemId: item.item_id,
operatorPrincipalId: alice,
decision: "approve",
reviewedContent: "owner-edited review copy",
});
expect(database.db.prepare("SELECT state FROM memory_postbox_items").get()).toEqual({
state: "reviewed",
});
expect(database.db.prepare("SELECT COUNT(*) AS count FROM memory_resources").get()).toEqual({
count: 0,
const reviewedCopy = database.db
.prepare(`SELECT revision_id FROM memory_postbox_reviewed_copies WHERE item_id = ?`)
.get(item.item_id) as { revision_id: string };
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId,
storeIds: [target.storeId],
revisionId: reviewedCopy.revision_id,
})?.content,
).toBe("owner-edited review copy");
closeOpenClawAgentDatabasesForTest();
expect(() =>
inspectBuiltinMemoryPostboxItem({
agentId,
itemId: item.item_id,
operatorPrincipalId: alice,
}),
).toThrow("memory postbox item is unavailable");
expect(
openOpenClawAgentDatabase({ agentId })
.db.prepare("SELECT state FROM memory_postbox_items WHERE item_id = ?")
.get(item.item_id),
).toEqual({ state: "reviewed" });
reviewBuiltinMemoryPostboxItem({
agentId,
itemId: item.item_id,
operatorPrincipalId: alice,
decision: "purge",
});
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId,
storeIds: [target.storeId],
revisionId: reviewedCopy.revision_id,
}),
).toBeUndefined();
expect(
openOpenClawAgentDatabase({ agentId })
.db.prepare("SELECT item_id FROM memory_postbox_reviewed_copies WHERE item_id = ?")
.get(item.item_id),
).toEqual({ item_id: item.item_id });
expect(
openOpenClawAgentDatabase({ agentId })
.db.prepare("SELECT state, content, purged_at FROM memory_postbox_items WHERE item_id = ?")
.get(item.item_id),
).toMatchObject({ state: "purged", content: "", purged_at: expect.any(Number) });
});
it("rolls back a purge when the durable postbox redaction cannot commit", () => {
const target = privateTargetStore();
setBuiltinMemoryPostboxMode({
agentId,
targetStoreId: target.storeId,
operatorPrincipalId: alice,
mode: "review-required",
});
expect(
depositFromVerifiedTurn({
content: "review body",
sourceMessageRef: "message-purge-rollback",
}),
).toEqual({ accepted: true });
const database = openOpenClawAgentDatabase({ agentId });
const item = database.db.prepare("SELECT item_id FROM memory_postbox_items").get() as {
item_id: string;
};
reviewBuiltinMemoryPostboxItem({
agentId,
itemId: item.item_id,
operatorPrincipalId: alice,
decision: "approve",
reviewedContent: "owner-reviewed body",
});
const reviewedCopy = database.db
.prepare("SELECT revision_id FROM memory_postbox_reviewed_copies WHERE item_id = ?")
.get(item.item_id) as { revision_id: string };
database.db.exec(`
CREATE TRIGGER fail_postbox_purge_redaction
BEFORE UPDATE OF state ON memory_postbox_items
WHEN NEW.state = 'purged'
BEGIN
SELECT RAISE(ABORT, 'forced postbox purge redaction failure');
END;
`);
try {
expect(() =>
reviewBuiltinMemoryPostboxItem({
agentId,
itemId: item.item_id,
operatorPrincipalId: alice,
decision: "purge",
}),
).toThrow("forced postbox purge redaction failure");
} finally {
database.db.exec("DROP TRIGGER fail_postbox_purge_redaction");
}
expect(
readBuiltinScopedMemoryRevisionSnapshot({
agentId,
storeIds: [target.storeId],
revisionId: reviewedCopy.revision_id,
})?.content,
).toBe("owner-reviewed body");
expect(
database.db
.prepare(
"SELECT state, content, content_hash, purged_at FROM memory_postbox_items WHERE item_id = ?",
)
.get(item.item_id),
).toMatchObject({
state: "reviewed",
content: "review body",
content_hash: expect.any(String),
purged_at: null,
});
expect(
database.db
.prepare(
"SELECT lifecycle_state, retired_at FROM memory_resource_revisions WHERE revision_id = ?",
)
.get(reviewedCopy.revision_id),
).toEqual({ lifecycle_state: "active", retired_at: null });
expect(
database.db
.prepare("SELECT revision_id FROM memory_postbox_reviewed_copies WHERE item_id = ?")
.get(item.item_id),
).toEqual({ revision_id: reviewedCopy.revision_id });
const remainingChunks = database.db
.prepare("SELECT COUNT(*) AS count FROM memory_scoped_chunks WHERE revision_id = ?")
.get(reviewedCopy.revision_id) as { count: number };
expect(remainingChunks.count).toBeGreaterThan(0);
});
it("denies forged, stale, cross-run, cross-session, and replayed postbox capabilities", () => {
const target = privateTargetStore();
setBuiltinMemoryPostboxMode({
agentId,
targetStoreId: target.storeId,
operatorPrincipalId: alice,
mode: "review-required",
});
const sourceContext = {};
const sourceTurnId = "channel-user:v1:message-capability";
admitMemoryPostboxTurnIngress({
context: sourceContext,
agentId,
sessionKey: "agent:main:direct:alice",
sessionId: "session-alice",
provider: "telegram",
inputProvenance: { kind: "external_user" },
sourceTurnId,
sourceChannelRef: "telegram:account:direct-alice",
senderEvidenceRef: "telegram:sender-alice",
});
const token = mintMemoryPostboxTurnCapability({
agentId,
runId: "run-capability",
sessionKey: "agent:main:direct:alice",
sessionId: "session-alice",
sourceContext,
});
if (!token) {
throw new Error("expected verified turn capability");
}
const deposit = (
overrides: Partial<{
runId: string;
sessionKey: string;
sessionId: string;
turnCapability: string;
}> = {},
) =>
depositBuiltinMemoryPostboxFromTurnCapability({
agentId,
runId: "run-capability",
sessionKey: "agent:main:direct:alice",
sessionId: "session-alice",
turnCapability: token,
content: "one-way observation",
...overrides,
});
expect(deposit({ turnCapability: "forged" })).toEqual({ accepted: false });
expect(deposit({ runId: "other-run" })).toEqual({ accepted: false });
expect(deposit({ sessionId: "other-session" })).toEqual({ accepted: false });
createCurrentMemorySessionContext.mockReturnValueOnce({
kind: "current",
context: {
subject: { kind: "user" },
principalId: alice,
fingerprint: "rebound-session",
},
});
expect(deposit()).toEqual({ accepted: false });
expect(deposit()).toEqual({ accepted: true });
expect(deposit()).toEqual({ accepted: false });
});
it("derives the owner quarantine internally and returns only redacted sharing status", () => {
const source = sourceStore();
const target = projectionStore();
privateTargetStore();
const sourceRevision = createBuiltinScopedMemoryResource({
agentId,
store: source,
logicalLocator: "private.md",
content: "private source",
actor: { kind: "human", id: alice },
});
registerBuiltinMemoryProjectionTarget({
agentId,
target: { kind: "conversation", id: channel },
store: target,
operatorPrincipalId: alice,
});
const projection = createBuiltinMemoryProjection({
agentId,
sourceRevisionId: sourceRevision.revisionId,
target: { kind: "conversation", id: channel },
publisherPrincipalId: alice,
reviewedByPrincipalId: alice,
purpose: "share approved detail",
preview: "approved detail",
content: "reviewed copy only",
expiry: { kind: "no-expiry", auditReason: "durable approved reference" },
});
setBuiltinMemoryPostboxModeForPrincipal({
agentId,
principalId: alice,
mode: "review-required",
});
expect(inspectBuiltinMemorySharingStatus({ agentId, operatorPrincipalId: alice })).toEqual({
postboxMode: "review-required",
projections: [
{
projectionId: projection.projectionId,
target: { kind: "conversation", id: channel },
purpose: "share approved detail",
preview: "approved detail",
state: "active",
expiresAt: null,
},
],
postboxItems: [],
});
});
@@ -615,5 +1096,78 @@ describe("builtin scoped memory sharing", () => {
count: 12,
},
);
closeOpenClawAgentDatabasesForTest();
expect(
depositFromVerifiedTurn({
content: "observation-after-reopen",
sourceMessageRef: "message-after-reopen",
}),
).toEqual({ accepted: false });
expect(
openOpenClawAgentDatabase({ agentId })
.db.prepare("SELECT deposit_count FROM memory_postbox_rate_limits")
.get(),
).toEqual({ deposit_count: 12 });
});
it("limits postbox body inspection to the target owner and persists a purged audit record", () => {
const target = privateTargetStore();
setBuiltinMemoryPostboxMode({
agentId,
targetStoreId: target.storeId,
operatorPrincipalId: alice,
mode: "review-required",
});
expect(
depositFromVerifiedTurn({
content: "private review body",
sourceMessageRef: "message-inspect",
}),
).toEqual({ accepted: true });
const database = openOpenClawAgentDatabase({ agentId });
const item = database.db.prepare("SELECT item_id FROM memory_postbox_items").get() as {
item_id: string;
};
expect(
inspectBuiltinMemoryPostboxItem({
agentId,
itemId: item.item_id,
operatorPrincipalId: alice,
}),
).toMatchObject({
itemId: item.item_id,
content: "private review body",
sourceChannelRef: "telegram:account:direct-alice",
});
expect(() =>
inspectBuiltinMemoryPostboxItem({
agentId,
itemId: item.item_id,
operatorPrincipalId: "principal-mallory",
}),
).toThrow("memory sharing authorization is unavailable");
reviewBuiltinMemoryPostboxItem({
agentId,
itemId: item.item_id,
operatorPrincipalId: alice,
decision: "purge",
nowMs: 1_700_000_000_000,
});
expect(
database.db.prepare("SELECT state, content, purged_at FROM memory_postbox_items").get(),
).toEqual({
state: "purged",
content: "",
purged_at: 1_700_000_000_000,
});
expect(() =>
inspectBuiltinMemoryPostboxItem({
agentId,
itemId: item.item_id,
operatorPrincipalId: alice,
}),
).toThrow("memory postbox item is unavailable");
});
});
@@ -12,8 +12,8 @@ import { evaluateBuiltinScopedMemoryPolicy } from "./scoped-memory-policy.js";
import {
createBuiltinScopedMemoryResource,
readBuiltinScopedMemoryRevisionSnapshot,
setBuiltinScopedMemoryRevisionLifecycle,
type BuiltinScopedMemoryDerivedSource,
type BuiltinScopedMemoryRevision,
} from "./scoped-memory-resources.js";
import {
createScopedMemorySourcePolicySetId,
@@ -37,15 +37,50 @@ export type BuiltinMemoryProjection = Readonly<{
sourceRevisionId: string;
target: ProjectionAudience;
expiresAt?: number;
/** Present only for a refresh: the old copy's prior exposure ids under the replacement fence. */
replacedExposureSetIds?: readonly string[];
}>;
export type BuiltinMemoryProjectionPreview = Readonly<{
sourceRevisionId: string;
target: ProjectionAudience;
purpose: string;
preview: string;
expiry: "expires" | "no-expiry";
}>;
export type BuiltinMemoryPostboxDeposit = Readonly<{ accepted: boolean }>;
export type BuiltinMemoryPostboxInspection = Readonly<{
itemId: string;
content: string;
sourceChannelRef: string;
createdAt: number;
}>;
export type BuiltinMemoryProjectionImpact = Readonly<{
projectionId: string;
exposureSetIds: readonly string[];
}>;
export type BuiltinMemorySharingStatus = Readonly<{
postboxMode: "off" | "review-required";
projections: readonly Readonly<{
projectionId: string;
target: ProjectionAudience;
purpose: string;
preview: string;
state: "active" | "revoked" | "expired";
expiresAt: number | null;
}>[];
postboxItems: readonly Readonly<{
itemId: string;
state: "postbox" | "reviewed" | "rejected" | "purged";
sourceChannelRef: string;
createdAt: number;
}>[];
}>;
function hash(value: string): string {
return createHash("sha256").update(value).digest("hex");
}
@@ -119,7 +154,7 @@ function readPostboxTargetStore(params: {
targetPrincipalId: string;
}) {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(params.database);
return executeSqliteQueryTakeFirstSync(
const candidates = executeSqliteQuerySync(
params.database,
db
.selectFrom("memory_stores")
@@ -128,7 +163,58 @@ function readPostboxTargetStore(params: {
.where("audience_kind", "=", "user")
.where("audience_id", "=", params.targetPrincipalId)
.where("lifecycle_state", "=", "active"),
).rows;
const eligible = candidates.filter(
(store) =>
evaluateBuiltinScopedMemoryPolicy({
agentId: params.agentId,
storeId: store.store_id,
principalIds: [params.targetPrincipalId],
deliveryAudiences: [{ kind: "user", id: params.targetPrincipalId }],
operation: "policy-admin",
}).allowed,
);
// A verified principal may own more than one user store. Selecting a first
// row would make quarantine depend on database order; ambiguous targets fail closed.
return eligible.length === 1 ? eligible[0] : undefined;
}
function readPostboxTargetMemoryStore(params: {
database: Parameters<typeof getNodeSqliteKysely<ScopedMemoryDatabase>>[0];
agentId: string;
storeId: string;
}): BuiltinScopedMemoryStore | undefined {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(params.database);
const store = executeSqliteQueryTakeFirstSync(
params.database,
db
.selectFrom("memory_stores as store")
.innerJoin("memory_policies as policy", "policy.policy_id", "store.policy_id")
.select([
"store.store_id",
"store.storage_root_id",
"store.policy_id",
"store.audience_kind",
"policy.current_revision_id",
"policy.revocation_epoch",
])
.where("store.agent_id", "=", params.agentId)
.where("store.store_id", "=", params.storeId)
.where("store.lifecycle_state", "=", "active")
.where("store.audience_kind", "=", "user")
.where("policy.lifecycle_state", "=", "active"),
);
if (!store) {
return undefined;
}
return Object.freeze({
storageRootId: store.storage_root_id,
storeId: store.store_id,
policyId: store.policy_id,
policyRevisionId: store.current_revision_id,
policyRevocationEpoch: store.revocation_epoch,
sourcePolicySetId: createScopedMemorySourcePolicySetId(store.current_revision_id),
});
}
function readSource(params: {
@@ -191,17 +277,28 @@ export function registerBuiltinMemoryProjectionTarget(params: {
store: BuiltinScopedMemoryStore;
operatorPrincipalId: string;
nowMs?: number;
}): void {
registerBuiltinMemoryProjectionTargetStore({
agentId: params.agentId,
target: params.target,
storeId: params.store.storeId,
operatorPrincipalId: params.operatorPrincipalId,
nowMs: params.nowMs,
});
}
/** Register a pre-existing non-private store as the sole reviewed-copy target for its audience. */
export function registerBuiltinMemoryProjectionTargetStore(params: {
agentId: string;
target: ProjectionAudience;
storeId: string;
operatorPrincipalId: string;
nowMs?: number;
}): void {
const target = targetAudience(params.target);
const storeId = normalize(params.storeId, "projection target store id");
const operatorPrincipalId = normalize(params.operatorPrincipalId, "operator principal id");
const nowMs = params.nowMs ?? Date.now();
assertStoreOperation({
agentId: params.agentId,
storeId: params.store.storeId,
principalId: operatorPrincipalId,
audience: target,
operation: "policy-admin",
});
withScopedMemoryDatabase(params.agentId, (database) => {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(database);
runSqliteImmediateTransactionSync(database, () => {
@@ -210,13 +307,20 @@ export function registerBuiltinMemoryProjectionTarget(params: {
db
.selectFrom("memory_stores")
.select(["store_id", "audience_kind", "audience_id"])
.where("store_id", "=", params.store.storeId)
.where("store_id", "=", storeId)
.where("agent_id", "=", params.agentId)
.where("lifecycle_state", "=", "active"),
);
if (!store || store.audience_kind !== target.kind || store.audience_id !== target.id) {
throw new Error("memory projection target is unavailable");
}
assertStoreOperation({
agentId: params.agentId,
storeId,
principalId: operatorPrincipalId,
audience: target,
operation: "policy-admin",
});
executeSqliteQuerySync(
database,
db
@@ -225,13 +329,13 @@ export function registerBuiltinMemoryProjectionTarget(params: {
agent_id: params.agentId,
audience_kind: target.kind,
audience_id: target.id,
store_id: params.store.storeId,
store_id: storeId,
configured_by_principal_id: operatorPrincipalId,
created_at: nowMs,
})
.onConflict((conflict) =>
conflict.columns(["agent_id", "audience_kind", "audience_id"]).doUpdateSet({
store_id: params.store.storeId,
store_id: storeId,
configured_by_principal_id: operatorPrincipalId,
created_at: nowMs,
}),
@@ -254,12 +358,17 @@ export function createBuiltinMemoryProjection(params: {
expiry:
| Readonly<{ kind: "expires"; expiresAt: number }>
| Readonly<{ kind: "no-expiry"; auditReason: string }>;
/** Refresh-only: atomically tombstone this still-active copy while committing the replacement. */
replaceActiveProjectionId?: string;
nowMs?: number;
}): BuiltinMemoryProjection {
const target = targetAudience(params.target);
const sourceRevisionId = normalize(params.sourceRevisionId, "source revision id");
const publisherPrincipalId = normalize(params.publisherPrincipalId, "publisher principal id");
const reviewedByPrincipalId = normalize(params.reviewedByPrincipalId, "reviewer principal id");
const replaceActiveProjectionId = params.replaceActiveProjectionId
? normalize(params.replaceActiveProjectionId, "projection id")
: undefined;
const purpose = normalize(params.purpose, "projection purpose");
const preview = normalize(params.preview, "projection preview");
const nowMs = params.nowMs ?? Date.now();
@@ -323,6 +432,7 @@ export function createBuiltinMemoryProjection(params: {
policyRevocationEpoch: targetStore.revocation_epoch,
sourcePolicySetId: createScopedMemorySourcePolicySetId(targetStore.current_revision_id),
});
let replacedExposureSetIds: readonly string[] | undefined;
const copy = createBuiltinScopedMemoryResource({
agentId: params.agentId,
store,
@@ -334,6 +444,33 @@ export function createBuiltinMemoryProjection(params: {
derivedSources: [sourceEvidence],
commitAdditionalState: ({ database: transactionDatabase, revision }) => {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(transactionDatabase);
if (replaceActiveProjectionId) {
const replaced = executeSqliteQueryTakeFirstSync(
transactionDatabase,
db
.selectFrom("memory_projections")
.selectAll()
.where("agent_id", "=", params.agentId)
.where("projection_id", "=", replaceActiveProjectionId),
);
// Recheck the current projection under the replacement transaction. If it was revoked,
// retargeted, or expired after planning, do not create a second readable copy.
if (
!replaced ||
replaced.state !== "active" ||
replaced.target_store_id !== targetStore.store_id ||
replaced.target_audience_kind !== target.kind ||
replaced.target_audience_id !== target.id
) {
throw new Error("memory projection is unavailable");
}
replacedExposureSetIds = tombstoneProjectionCopy({
database: transactionDatabase,
projection: replaced,
state: "revoked",
nowMs,
});
}
executeSqliteQuerySync(
transactionDatabase,
db.insertInto("memory_projections").values({
@@ -365,10 +502,120 @@ export function createBuiltinMemoryProjection(params: {
sourceRevisionId,
target,
...(expiry.kind === "expires" ? { expiresAt: expiry.expiresAt } : {}),
...(replacedExposureSetIds ? { replacedExposureSetIds } : {}),
});
});
}
/** Validate a proposed reviewed copy without reading its source content or mutating sharing state. */
export function previewBuiltinMemoryProjection(params: {
agentId: string;
sourceRevisionId: string;
target: ProjectionAudience;
publisherPrincipalId: string;
purpose: string;
preview: string;
expiry:
| Readonly<{ kind: "expires"; expiresAt: number }>
| Readonly<{ kind: "no-expiry"; auditReason: string }>;
nowMs?: number;
}): BuiltinMemoryProjectionPreview {
const target = targetAudience(params.target);
const sourceRevisionId = normalize(params.sourceRevisionId, "source revision id");
const publisherPrincipalId = normalize(params.publisherPrincipalId, "publisher principal id");
const purpose = normalize(params.purpose, "projection purpose");
const preview = normalize(params.preview, "projection preview");
const nowMs = params.nowMs ?? Date.now();
if (
(params.expiry.kind === "expires" &&
(!Number.isSafeInteger(params.expiry.expiresAt) || params.expiry.expiresAt <= nowMs)) ||
(params.expiry.kind === "no-expiry" && !params.expiry.auditReason.trim())
) {
throw new Error("memory projection expiry is unavailable");
}
return withScopedMemoryDatabase(params.agentId, (database) => {
const source = readSource({ database, agentId: params.agentId, revisionId: sourceRevisionId });
assertStoreOperation({
agentId: params.agentId,
storeId: source.store_id,
principalId: publisherPrincipalId,
audience: { kind: source.audience_kind, id: source.audience_id },
operation: "project",
});
const targetStore = readTargetStore({ database, agentId: params.agentId, target });
if (!targetStore) {
throw new Error("memory projection target is unavailable");
}
assertStoreOperation({
agentId: params.agentId,
storeId: targetStore.store_id,
principalId: publisherPrincipalId,
audience: target,
operation: "publish",
});
return Object.freeze({
sourceRevisionId,
target,
purpose,
preview,
expiry: params.expiry.kind,
});
});
}
/** Return only redacted prior-exposure ids after checking publisher or target policy administration. */
export function inspectBuiltinMemoryProjectionImpact(params: {
agentId: string;
projectionId: string;
operatorPrincipalId: string;
}): BuiltinMemoryProjectionImpact {
const projectionId = normalize(params.projectionId, "projection id");
const operatorPrincipalId = normalize(params.operatorPrincipalId, "operator principal id");
return withScopedMemoryDatabase(params.agentId, (database) => {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(database);
const projection = executeSqliteQueryTakeFirstSync(
database,
db
.selectFrom("memory_projections")
.select([
"projection_id",
"copy_revision_id",
"publisher_principal_id",
"target_store_id",
"target_audience_kind",
"target_audience_id",
])
.where("agent_id", "=", params.agentId)
.where("projection_id", "=", projectionId),
);
if (!projection) {
throw new Error("memory projection is unavailable");
}
const target = targetAudience({
kind: projection.target_audience_kind,
id: projection.target_audience_id,
});
if (projection.publisher_principal_id !== operatorPrincipalId) {
assertStoreOperation({
agentId: params.agentId,
storeId: projection.target_store_id,
principalId: operatorPrincipalId,
audience: target,
operation: "policy-admin",
});
}
const exposureSetIds = executeSqliteQuerySync(
database,
db
.selectFrom("memory_run_exposure_resources")
.select("exposure_set_id")
.where("resource_revision_id", "=", projection.copy_revision_id)
.orderBy("exposure_set_id"),
).rows.map((row) => row.exposure_set_id);
return Object.freeze({ projectionId, exposureSetIds: Object.freeze(exposureSetIds) });
});
}
/** Tombstones one copy and reads its recorded impact under the caller's write fence. */
function tombstoneProjectionCopy(params: {
database: Parameters<typeof getNodeSqliteKysely<ScopedMemoryDatabase>>[0];
@@ -507,7 +754,7 @@ export function expireBuiltinMemoryProjections(params: {
});
}
/** Refresh explicitly creates a new reviewed copy, then revokes the previous copy and reports its impact. */
/** Refresh commits the new reviewed copy and old-copy tombstone under one revision transaction. */
export function refreshBuiltinMemoryProjection(params: {
agentId: string;
projectionId: string;
@@ -562,15 +809,13 @@ export function refreshBuiltinMemoryProjection(params: {
preview: params.preview,
content: params.content,
expiry: params.expiry,
replaceActiveProjectionId: projectionId,
nowMs: params.nowMs,
});
const replacedExposureSetIds = revokeBuiltinMemoryProjection({
agentId: params.agentId,
projectionId,
operatorPrincipalId: publisherPrincipalId,
nowMs: params.nowMs,
return Object.freeze({
projection,
replacedExposureSetIds: projection.replacedExposureSetIds ?? [],
});
return Object.freeze({ projection, replacedExposureSetIds });
}
/** Postbox stays off until an authenticated owner/admin explicitly enables review-required deposits. */
@@ -624,6 +869,121 @@ export function setBuiltinMemoryPostboxMode(params: {
});
}
/** The target quarantine is derived from the authenticated owner's principal, never RPC input. */
export function setBuiltinMemoryPostboxModeForPrincipal(params: {
agentId: string;
principalId: string;
mode: "off" | "review-required";
nowMs?: number;
}): void {
const targetStoreId = withScopedMemoryDatabase(
params.agentId,
(database) =>
readPostboxTargetStore({
database,
agentId: params.agentId,
targetPrincipalId: normalize(params.principalId, "operator principal id"),
})?.store_id,
);
if (!targetStoreId) {
throw new Error("memory postbox target is unavailable");
}
setBuiltinMemoryPostboxMode({
agentId: params.agentId,
targetStoreId,
operatorPrincipalId: params.principalId,
mode: params.mode,
nowMs: params.nowMs,
});
}
/** Redacted owner inspection: no source revision, private copy, or postbox body leaves this path. */
export function inspectBuiltinMemorySharingStatus(params: {
agentId: string;
operatorPrincipalId: string;
}): BuiltinMemorySharingStatus {
const operatorPrincipalId = normalize(params.operatorPrincipalId, "operator principal id");
return withScopedMemoryDatabase(params.agentId, (database) => {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(database);
const target = readPostboxTargetStore({
database,
agentId: params.agentId,
targetPrincipalId: operatorPrincipalId,
});
if (!target) {
throw new Error("memory sharing is unavailable");
}
assertStoreOperation({
agentId: params.agentId,
storeId: target.store_id,
principalId: operatorPrincipalId,
audience: { kind: "user", id: operatorPrincipalId },
operation: "policy-admin",
});
const settings = executeSqliteQueryTakeFirstSync(
database,
db
.selectFrom("memory_postbox_settings")
.select("mode")
.where("agent_id", "=", params.agentId)
.where("target_store_id", "=", target.store_id),
);
const projections = executeSqliteQuerySync(
database,
db
.selectFrom("memory_projections")
.select([
"projection_id",
"target_audience_kind",
"target_audience_id",
"purpose",
"preview",
"state",
"expires_at",
])
.where("agent_id", "=", params.agentId)
.where("publisher_principal_id", "=", operatorPrincipalId)
.orderBy("created_at", "desc"),
).rows.map((projection) =>
Object.freeze({
projectionId: projection.projection_id,
target: Object.freeze({
kind: targetAudience({
kind: projection.target_audience_kind,
id: projection.target_audience_id,
}).kind,
id: projection.target_audience_id,
}),
purpose: projection.purpose,
preview: projection.preview,
state: projection.state,
expiresAt: projection.expires_at,
}),
);
const postboxItems = executeSqliteQuerySync(
database,
db
.selectFrom("memory_postbox_items")
.select(["item_id", "state", "source_channel_ref", "created_at"])
.where("agent_id", "=", params.agentId)
.where("target_store_id", "=", target.store_id)
.orderBy("created_at", "desc"),
).rows.map((item) =>
Object.freeze({
itemId: item.item_id,
state: item.state,
sourceChannelRef: item.source_channel_ref,
createdAt: item.created_at,
}),
);
return Object.freeze({
postboxMode: settings?.mode ?? "off",
projections: Object.freeze(projections),
postboxItems: Object.freeze(postboxItems),
});
});
}
/** Only core/channel ingress may mint this opaque handle from current verified sender evidence. */
function issueBuiltinMemoryPostboxSourceHandle(params: {
agentId: string;
@@ -677,7 +1037,7 @@ export function depositBuiltinMemoryPostboxFromTurnCapability(params: {
agentId: string;
runId: string;
sessionKey: string;
sessionId?: string;
sessionId: string;
turnCapability: string;
content: string;
nowMs?: number;
@@ -707,9 +1067,11 @@ export function depositBuiltinMemoryPostboxFromTurnCapability(params: {
}
const sourceHandleId = issueBuiltinMemoryPostboxSourceHandle({
agentId: params.agentId,
sourceSessionId: params.sessionId ?? params.sessionKey,
sourceSessionId: params.sessionId,
// These facts are carried by the private ingress marker; never reconstruct route or sender
// identity from model-visible or reply-context strings.
sourceChannelRef: source.sourceChannelRef,
sourceMessageRef: source.sourceMessageRef,
sourceMessageRef: source.sourceTurnId,
senderEvidenceRef: source.senderEvidenceRef,
targetStoreId,
nowMs: params.nowMs,
@@ -834,16 +1196,259 @@ export function depositBuiltinMemoryPostbox(params: {
});
}
/** Owner/admin review changes quarantine state only; it never promotes postbox content into recall. */
/**
* Approval is the one explicit promotion boundary: it writes an immutable owner-reviewed copy,
* while the original channel deposit remains quarantined and immutable. Reject never promotes.
*/
export function reviewBuiltinMemoryPostboxItem(params: {
agentId: string;
itemId: string;
operatorPrincipalId: string;
decision: "approve" | "reject" | "purge";
reviewedContent?: string;
nowMs?: number;
}): void {
const operatorPrincipalId = normalize(params.operatorPrincipalId, "operator principal id");
const nowMs = params.nowMs ?? Date.now();
const itemId = normalize(params.itemId, "postbox item id");
if (params.decision === "reject" && params.reviewedContent !== undefined) {
throw new Error("memory postbox review is unavailable");
}
if (params.decision === "approve") {
const approval = withScopedMemoryDatabase(params.agentId, (database) => {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(database);
const item = executeSqliteQueryTakeFirstSync(
database,
db
.selectFrom("memory_postbox_items as item")
.innerJoin("memory_stores as store", "store.store_id", "item.target_store_id")
.select([
"item.item_id",
"item.content",
"item.state",
"item.target_store_id",
"store.audience_kind",
"store.audience_id",
])
.where("item.item_id", "=", itemId)
.where("item.agent_id", "=", params.agentId),
);
if (!item || item.state !== "postbox" || item.audience_kind !== "user") {
throw new Error("memory postbox item is unavailable");
}
assertStoreOperation({
agentId: params.agentId,
storeId: item.target_store_id,
principalId: operatorPrincipalId,
audience: { kind: "user", id: item.audience_id },
operation: "policy-admin",
});
const store = readPostboxTargetMemoryStore({
database,
agentId: params.agentId,
storeId: item.target_store_id,
});
if (!store) {
throw new Error("memory postbox item is unavailable");
}
const content =
params.reviewedContent === undefined
? item.content
: normalize(params.reviewedContent, "reviewed postbox content");
if (Buffer.byteLength(content) > POSTBOX_MAX_CONTENT_BYTES) {
throw new Error("memory postbox review is unavailable");
}
return Object.freeze({ item, store, content });
});
const copy = createBuiltinScopedMemoryResource({
agentId: params.agentId,
store: approval.store,
logicalLocator: `postbox-reviewed/${approval.item.item_id}.md`,
content: approval.content,
lifecycleState: "pending",
actor: { kind: "human", id: operatorPrincipalId },
nowMs,
});
try {
withScopedMemoryDatabase(params.agentId, (database) => {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(database);
runSqliteImmediateTransactionSync(database, () => {
const item = executeSqliteQueryTakeFirstSync(
database,
db
.selectFrom("memory_postbox_items as item")
.innerJoin("memory_stores as store", "store.store_id", "item.target_store_id")
.select([
"item.item_id",
"item.state",
"item.target_store_id",
"store.audience_kind",
"store.audience_id",
])
.where("item.item_id", "=", itemId)
.where("item.agent_id", "=", params.agentId),
);
if (
!item ||
item.state !== "postbox" ||
item.target_store_id !== approval.item.target_store_id ||
item.audience_kind !== "user"
) {
throw new Error("memory postbox item is unavailable");
}
assertStoreOperation({
agentId: params.agentId,
storeId: item.target_store_id,
principalId: operatorPrincipalId,
audience: { kind: "user", id: item.audience_id },
operation: "policy-admin",
});
const activated = executeSqliteQuerySync(
database,
db
.updateTable("memory_resource_revisions")
.set({ lifecycle_state: "active", activated_at: nowMs })
.where("revision_id", "=", copy.revisionId)
.where("lifecycle_state", "=", "pending"),
);
if (activated.numAffectedRows !== 1n) {
throw new Error("memory postbox item is unavailable");
}
executeSqliteQuerySync(
database,
db.insertInto("memory_postbox_reviewed_copies").values({
item_id: item.item_id,
agent_id: params.agentId,
resource_id: copy.resourceId,
revision_id: copy.revisionId,
reviewed_content_hash: hash(approval.content),
created_at: nowMs,
}),
);
const reviewed = executeSqliteQuerySync(
database,
db
.updateTable("memory_postbox_items")
.set({
state: "reviewed",
reviewed_by_principal_id: operatorPrincipalId,
reviewed_at: nowMs,
})
.where("item_id", "=", item.item_id)
.where("state", "=", "postbox"),
);
if (reviewed.numAffectedRows !== 1n) {
throw new Error("memory postbox item is unavailable");
}
});
});
} catch (error) {
setBuiltinScopedMemoryRevisionLifecycle({
agentId: params.agentId,
revisionId: copy.revisionId,
lifecycleState: "tombstoned",
nowMs,
});
throw error;
}
return;
}
withScopedMemoryDatabase(params.agentId, (database) => {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(database);
runSqliteImmediateTransactionSync(database, () => {
const item = executeSqliteQueryTakeFirstSync(
database,
db
.selectFrom("memory_postbox_items as item")
.innerJoin("memory_stores as store", "store.store_id", "item.target_store_id")
.select([
"item.item_id",
"item.state",
"item.target_store_id",
"store.audience_kind",
"store.audience_id",
])
.where("item.item_id", "=", itemId)
.where("item.agent_id", "=", params.agentId),
);
if (!item || item.audience_kind !== "user") {
throw new Error("memory postbox item is unavailable");
}
assertStoreOperation({
agentId: params.agentId,
storeId: item.target_store_id,
principalId: operatorPrincipalId,
audience: { kind: item.audience_kind, id: item.audience_id },
operation: "policy-admin",
});
if (params.decision === "purge") {
const approvedCopy = executeSqliteQueryTakeFirstSync(
database,
db
.selectFrom("memory_postbox_reviewed_copies")
.select("revision_id")
.where("item_id", "=", item.item_id)
.where("agent_id", "=", params.agentId),
);
if (approvedCopy) {
executeSqliteQuerySync(
database,
db
.updateTable("memory_resource_revisions")
.set({ lifecycle_state: "tombstoned", retired_at: nowMs })
.where("revision_id", "=", approvedCopy.revision_id)
.where("lifecycle_state", "=", "active"),
);
executeSqliteQuerySync(
database,
db
.deleteFrom("memory_scoped_chunks")
.where("revision_id", "=", approvedCopy.revision_id),
);
}
const purged = executeSqliteQuerySync(
database,
db
.updateTable("memory_postbox_items")
// A purge is one irreversible transition: never tombstone its reviewed copy unless
// this provenance row is redacted in the same transaction.
.set({ state: "purged", content: "", content_hash: "", purged_at: nowMs })
.where("item_id", "=", item.item_id)
.where("state", "in", ["postbox", "reviewed", "rejected"]),
);
if (purged.numAffectedRows !== 1n) {
throw new Error("memory postbox item is unavailable");
}
return;
}
const updated = executeSqliteQuerySync(
database,
db
.updateTable("memory_postbox_items")
.set({
state: "rejected",
reviewed_by_principal_id: operatorPrincipalId,
reviewed_at: nowMs,
})
.where("item_id", "=", item.item_id)
.where("state", "in", ["postbox"]),
);
if (updated.numAffectedRows !== 1n) {
throw new Error("memory postbox item is unavailable");
}
});
});
}
/** Only the authorized target owner/admin can read one pending quarantine body for review. */
export function inspectBuiltinMemoryPostboxItem(params: {
agentId: string;
itemId: string;
operatorPrincipalId: string;
}): BuiltinMemoryPostboxInspection {
const itemId = normalize(params.itemId, "postbox item id");
const operatorPrincipalId = normalize(params.operatorPrincipalId, "operator principal id");
return withScopedMemoryDatabase(params.agentId, (database) => {
const db = getNodeSqliteKysely<ScopedMemoryDatabase>(database);
const item = executeSqliteQueryTakeFirstSync(
database,
@@ -852,42 +1457,32 @@ export function reviewBuiltinMemoryPostboxItem(params: {
.innerJoin("memory_stores as store", "store.store_id", "item.target_store_id")
.select([
"item.item_id",
"item.content",
"item.source_channel_ref",
"item.created_at",
"item.state",
"item.target_store_id",
"store.audience_kind",
"store.audience_id",
])
.where("item.item_id", "=", params.itemId)
.where("item.item_id", "=", itemId)
.where("item.agent_id", "=", params.agentId),
);
if (!item || item.audience_kind !== "user") {
if (!item || item.state !== "postbox" || item.audience_kind !== "user") {
throw new Error("memory postbox item is unavailable");
}
assertStoreOperation({
agentId: params.agentId,
storeId: item.target_store_id,
principalId: normalize(params.operatorPrincipalId, "operator principal id"),
audience: { kind: item.audience_kind, id: item.audience_id },
principalId: operatorPrincipalId,
audience: { kind: "user", id: item.audience_id },
operation: "policy-admin",
});
const state =
params.decision === "approve"
? "reviewed"
: params.decision === "reject"
? "rejected"
: "purged";
executeSqliteQuerySync(
database,
db
.updateTable("memory_postbox_items")
.set({
state,
reviewed_by_principal_id: normalize(params.operatorPrincipalId, "operator principal id"),
reviewed_at: nowMs,
...(state === "purged" ? { purged_at: nowMs } : {}),
})
.where("item_id", "=", item.item_id)
.where("state", "=", "postbox"),
);
return Object.freeze({
itemId: item.item_id,
content: item.content,
sourceChannelRef: item.source_channel_ref,
createdAt: item.created_at,
});
});
}
+3 -1
View File
@@ -12,7 +12,9 @@ import type { OpenClawConfig } from "../api.js";
import { syncMemoryWikiBridgeSources } from "./bridge.js";
import { createMemoryWikiTestHarness } from "./test-helpers.js";
const isLegacyMemorySurfaceDisabledMock = vi.hoisted(() => vi.fn(() => false));
const isLegacyMemorySurfaceDisabledMock = vi.hoisted(() =>
vi.fn<(agentId: string) => boolean>(() => false),
);
vi.mock("openclaw/plugin-sdk/memory-core-host-runtime-core", () => ({
isLegacyMemorySurfaceDisabled: isLegacyMemorySurfaceDisabledMock,
+4
View File
@@ -107,6 +107,7 @@
"!dist/plugin-sdk/markdown-table-runtime.d.ts",
"!dist/plugin-sdk/media-generation-runtime.d.ts",
"!dist/plugin-sdk/memory-postbox-runtime.d.ts",
"!dist/plugin-sdk/memory-sharing-control-runtime.d.ts",
"!dist/plugin-sdk/memory-core-host-embedding-registry.d.ts",
"!dist/plugin-sdk/memory-core-host-engine-curated.d.ts",
"!dist/plugin-sdk/memory-core-host-engine-embeddings.d.ts",
@@ -1240,6 +1241,9 @@
"./plugin-sdk/memory-postbox-runtime": {
"default": "./dist/plugin-sdk/memory-postbox-runtime.js"
},
"./plugin-sdk/memory-sharing-control-runtime": {
"default": "./dist/plugin-sdk/memory-sharing-control-runtime.js"
},
"./plugin-sdk/memory-core-host-embedding-registry": {
"default": "./dist/plugin-sdk/memory-core-host-embedding-registry.js"
},
+1
View File
@@ -261,6 +261,7 @@
"memory-authorization",
"memory-authorization-conformance",
"memory-postbox-runtime",
"memory-sharing-control-runtime",
"memory-core-host-embedding-registry",
"memory-core-host-engine-embeddings",
"memory-core-host-engine-curated",
@@ -64,6 +64,7 @@
"markdown-table-runtime",
"media-generation-runtime",
"memory-postbox-runtime",
"memory-sharing-control-runtime",
"memory-core-host-embedding-registry",
"memory-core-host-engine-curated",
"memory-core-host-engine-embeddings",
+2 -1
View File
@@ -272,7 +272,8 @@ export function readPluginSdkSurfaceBudgets(env: NodeJS.ProcessEnv = process.env
// +3: add canonical coercion exports while retaining the shipped asString compatibility name.
// +57: versioned serializable memory-authorization contract and reusable backend-conformance
// types, capability declarations, and helpers.
4923,
// +7: reconcile the existing public memory-authorization contract surface with this ratchet.
4930,
env,
),
publicFunctionExports: readPluginSdkSurfaceBudgetEnv(
+27 -6
View File
@@ -18,15 +18,15 @@ import type { DiagnosticTraceContext } from "../infra/diagnostic-trace-context.j
import { resolveEventSessionRoutingPolicy } from "../infra/event-session-routing.js";
import { applyExecPolicyLayer } from "../infra/exec-policy.js";
import { logWarn } from "../logger.js";
import {
MEMORY_POSTBOX_RUN_ID_BINDING,
MEMORY_POSTBOX_TURN_CAPABILITY_BINDING,
} from "../plugins/memory-postbox-tool-binding.js";
import type {
PluginHookChannelContext,
PluginHookToolRequesterContext,
} from "../plugins/hook-types.js";
import { isMemoryIsolationCutoverAgent } from "../plugins/memory-cutover.js";
import {
MEMORY_POSTBOX_RUN_ID_BINDING,
MEMORY_POSTBOX_TURN_CAPABILITY_BINDING,
} from "../plugins/memory-postbox-tool-binding.js";
import { resolveMemoryFlushPlan } from "../plugins/memory-state.js";
import { appendRuntimePluginToolGrant } from "../plugins/tool-grant-allowlist.js";
import type { AuthorizedMemoryReadHost, AuthorizedMemoryWriteHost } from "../plugins/tool-types.js";
@@ -413,12 +413,33 @@ type OpenClawCodingToolsOptions = {
function resolvePluginToolBindings(options: OpenClawCodingToolsOptions | undefined) {
const turnCapability = options?.memoryPostboxTurnCapability?.trim();
const runId = options?.runId?.trim();
const callerBindings = options?.pluginToolBindings;
const memoryCoreBindings = callerBindings?.["memory-core"];
const { ["memory-core"]: _callerMemoryCoreBindings, ...otherCallerBindings } =
callerBindings ?? {};
const {
[MEMORY_POSTBOX_TURN_CAPABILITY_BINDING]: _ignoredPublicPostboxCapability,
[MEMORY_POSTBOX_RUN_ID_BINDING]: _ignoredPublicPostboxRunId,
...safeMemoryCoreBindings
} = memoryCoreBindings ?? {};
const inheritedBindings =
memoryCoreBindings === undefined
? callerBindings
: {
...otherCallerBindings,
...(Object.keys(safeMemoryCoreBindings).length > 0
? { "memory-core": safeMemoryCoreBindings }
: {}),
};
if (!turnCapability || !runId) {
return options?.pluginToolBindings;
return inheritedBindings;
}
// Gateway-provided plugin bindings are serializable request input. Only the runner may inject
// these reserved names, so a retained or forged token cannot manufacture the postbox tool.
return {
...options?.pluginToolBindings,
...inheritedBindings,
"memory-core": {
...safeMemoryCoreBindings,
[MEMORY_POSTBOX_TURN_CAPABILITY_BINDING]: turnCapability,
[MEMORY_POSTBOX_RUN_ID_BINDING]: runId,
},
+2
View File
@@ -1,11 +1,13 @@
import type { ApplyPatchSummary } from "./apply-patch.js";
import "./apply-patch.js";
import type { MemoryFileMutationGuard } from "./memory-file-mutation-guard.js";
import type { SandboxFsBridge } from "./sandbox/fs-bridge.js";
type ApplyPatchOptions = {
cwd: string;
sandbox?: { root: string; bridge: SandboxFsBridge };
workspaceOnly?: boolean;
memoryFileMutationGuard?: MemoryFileMutationGuard;
signal?: AbortSignal;
};
@@ -42,10 +42,16 @@ export const contextEngineCompactMock = vi.fn(async () => ({
}));
export const isMemoryIsolationCutoverAgentMock = vi.fn(() => false);
export const readAuthorizedTranscriptDerivationMock = vi.fn(() => undefined);
export const readAuthorizedTranscriptDerivationMock = vi.fn<
typeof import("../../config/sessions/session-transcript-memory-policy.js").readAuthorizedTranscriptDerivation
>(() => undefined);
export const admitAuthorizedMemoryDerivationMock = vi.fn(async () => true);
export const createAuthorizedMemoryDerivationHostMock = vi.fn(() => undefined);
export const prepareAuthorizedSealedCompactionHostMock = vi.fn(async () => undefined);
export const createAuthorizedMemoryDerivationHostMock = vi.fn<
typeof import("../memory-authorized-read-host.js").createAuthorizedMemoryDerivationHost
>(() => undefined);
export const prepareAuthorizedSealedCompactionHostMock = vi.fn<
typeof import("../memory-authorized-read-host.js").prepareAuthorizedSealedCompactionHost
>(async () => undefined);
export const hookRunner = {
hasHooks: vi.fn<(hookName?: string) => boolean>(),
@@ -5,7 +5,7 @@ import type { ProviderRuntimePluginHandle } from "../../../plugins/provider-hook
import type { EmbeddedRunAttemptParams } from "./types.js";
const resolveProviderRuntimePluginHandle = vi.hoisted(() => vi.fn());
const resolveSandboxContext = vi.hoisted(() => vi.fn(async () => null));
const resolveSandboxContext = vi.hoisted(() => vi.fn());
const createAuthorizedMemoryReadHost = vi.hoisted(() => vi.fn());
const resolveAuthorizedMemoryVirtualFileBroker = vi.hoisted(() => vi.fn());
const stageAuthorizedVirtualProjectionMountPlan = vi.hoisted(() => vi.fn());
@@ -119,7 +119,7 @@ test.runIf(dockerAvailable)(
const { execDocker } = await import("./docker.js");
const inspected = await execDocker(["inspect", runtimeId]);
const mounts = JSON.parse(inspected.stdout.toString("utf8")) as Array<{
const mounts = JSON.parse(inspected.stdout) as Array<{
Mounts?: Array<{ Destination?: string; Source?: string; RW?: boolean }>;
}>;
expect(mounts[0]?.Mounts).toContainEqual(
@@ -7,7 +7,10 @@ import {
resolveAuthorizedVirtualProjectionRoot,
resolveAuthorizedVirtualProjectionSourcePath,
} from "./authorized-virtual-projection-mounts.js";
import { stageAuthorizedVirtualProjectionMountPlan } from "./authorized-virtual-projection-staging.js";
import {
stageAuthorizedVirtualProjectionMountPlan,
type AuthorizedVirtualProjectionBroker,
} from "./authorized-virtual-projection-staging.js";
const tmpDirs: string[] = [];
@@ -17,7 +20,10 @@ function makeTempDir(): string {
return dir;
}
function createBroker(readFile = vi.fn(async (virtualPath: string) => `contents:${virtualPath}`)) {
function createBroker(
readFile: AuthorizedVirtualProjectionBroker["readFile"] = async (virtualPath) =>
`contents:${virtualPath}`,
) {
return {
view: {
version: 1 as const,
@@ -45,7 +51,7 @@ function createBroker(readFile = vi.fn(async (virtualPath: string) => `contents:
],
expiresAt: "2099-01-01T00:00:00.000Z",
},
readFile,
readFile: vi.fn<AuthorizedVirtualProjectionBroker["readFile"]>(readFile),
};
}
@@ -57,7 +57,6 @@ function allowedFinalAdmission(): MemoryEgressAdmission {
capabilityId: "reply.final",
agentId: "memory-agent",
sessionId: "session-1",
sessionKey: "agent:memory-agent:direct:alice",
runId: "run-1",
deliveryRevision: "delivery-1",
egressRegistryRevision: "registry-1",
@@ -72,7 +71,6 @@ describe("memory egress at final dispatch", () => {
const dispatcher = createReplyDispatcher({ deliver: delivered });
const ctx = buildTestCtx({
AgentId: "memory-agent",
SessionId: "session-1",
SessionKey: "agent:memory-agent:direct:alice",
Surface: "telegram",
OriginatingChannel: "telegram",
@@ -14,17 +14,16 @@ import {
} from "../../agents/run-termination.js";
import { resolveGroupSessionKey } from "../../config/sessions.js";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import {
mintMemoryPostboxTurnCapability,
revokeMemoryPostboxTurnCapability,
} from "../../gateway/memory-postbox-turn-capability.js";
import {
isTrustedMessageActionTurnIngress,
mintMessageActionTurnCapability,
resolveMessageActionTurnCapabilityLifetime,
revokeMessageActionTurnCapability,
} from "../../gateway/message-action-turn-capability.js";
import {
mintMemoryPostboxTurnCapability,
resolveMemoryPostboxTargetPrincipal,
revokeMemoryPostboxTurnCapability,
} from "../../gateway/memory-postbox-turn-capability.js";
import { logVerbose } from "../../globals.js";
import {
isMarkdownCapableMessageChannel,
@@ -176,34 +175,19 @@ export async function runEmbeddedFallbackCandidate(params: {
...resolveMessageActionTurnCapabilityLifetime(runBaseParams.timeoutMs),
})
: undefined;
const memoryPostboxTargetPrincipal =
embeddedContext.agentId && messageActionCapabilitySessionKey && embeddedContext.sessionId
? resolveMemoryPostboxTargetPrincipal({
agentId: embeddedContext.agentId,
sessionKey: messageActionCapabilitySessionKey,
sessionId: embeddedContext.sessionId,
})
: undefined;
const memoryPostboxTurnCapability =
isTrustedMessageActionTurnIngress(turn.sessionCtx.Provider) &&
!turn.isHeartbeat &&
embeddedContext.agentId &&
messageActionCapabilitySessionKey &&
embeddedContext.sessionId &&
embeddedContext.messageProvider &&
embeddedContext.currentChannelId &&
embeddedContext.currentMessageId !== undefined &&
senderContext.senderId &&
memoryPostboxTargetPrincipal
embeddedContext.currentSourceTurnId
? mintMemoryPostboxTurnCapability({
agentId: embeddedContext.agentId,
runId: params.runId,
sessionKey: messageActionCapabilitySessionKey,
sessionId: embeddedContext.sessionId,
sourceChannelRef: `${embeddedContext.messageProvider}:${embeddedContext.currentChannelId}`,
sourceMessageRef: String(embeddedContext.currentMessageId),
senderEvidenceRef: `${embeddedContext.messageProvider}:${senderContext.senderId}`,
targetPrincipalId: memoryPostboxTargetPrincipal,
sourceContext: turn.sessionCtx,
...resolveMessageActionTurnCapabilityLifetime(runBaseParams.timeoutMs),
})
: undefined;
+20 -1
View File
@@ -8,6 +8,7 @@ import { runAgentHarnessBeforeMessageWriteHook } from "../../agents/harness/hook
import { resolveOwnerPromptNumbers } from "../../agents/owner-display.js";
import { conversationIdentityFromMsgContext } from "../../config/sessions/conversation-identity.js";
import { resolveGroupSessionKey } from "../../config/sessions/group.js";
import { admitMemoryPostboxTurnIngress } from "../../gateway/memory-postbox-turn-capability.js";
import { normalizeMediaFacts } from "../../media/media-facts.js";
import { MEDIA_ONLY_USER_TEXT } from "../../sessions/user-turn-media.js";
import {
@@ -178,6 +179,7 @@ export async function executePreparedReplyRun(state: PreparedReplyRunAdmission)
const sourceMessageId =
normalizeOptionalString(sessionCtx.MessageSidFull) ??
normalizeOptionalString(sessionCtx.MessageSid);
const inputProvenance = ctx.InputProvenance ?? sessionCtx.InputProvenance;
const sourceTurnId =
readChannelSourceTurnId(sessionCtx) ??
(shouldMintChannelSourceTurnId(ctx.Provider ?? ctx.Surface ?? promptSessionCtx.Provider)
@@ -189,6 +191,24 @@ export async function executePreparedReplyRun(state: PreparedReplyRunAdmission)
})
: undefined);
setChannelSourceTurnId(sessionCtx, sourceTurnId);
const senderEvidenceRef = normalizeOptionalString(ctx.SenderId);
const sourceChannelRef =
sourceTurnId && messageProvider && replyRoute.accountId && replyRoute.to
? `${messageProvider}:${replyRoute.accountId}:${replyRoute.to}`
: undefined;
admitMemoryPostboxTurnIngress({
context: sessionCtx,
agentId,
// The embedded runner redeems against the runtime-policy key when one is present.
// Bind admission to that same key so an alias cannot transplant this ingress record.
sessionKey: runtimePolicySessionKey ?? sessionKey ?? preparedSessionState.sessionId,
sessionId: preparedSessionState.sessionId,
provider: ctx.Provider ?? ctx.Surface ?? promptSessionCtx.Provider,
inputProvenance,
sourceTurnId,
sourceChannelRef,
senderEvidenceRef,
});
const persistGroupSender = replyRoute.chatType === "group" || replyRoute.chatType === "channel";
const ctxMediaForPersistence = normalizeMediaFacts(ctx.media);
const userTurnMediaForPersistence = [...ctxMediaForPersistence, ...(opts?.media ?? [])];
@@ -199,7 +219,6 @@ export async function executePreparedReplyRun(state: PreparedReplyRunAdmission)
imageOrder: currentTurnImages.imageOrder,
imageSourceIndexes: currentTurnImages.imageSourceIndexes,
});
const inputProvenance = ctx.InputProvenance ?? sessionCtx.InputProvenance;
const userTurnTimestamp = normalizeMessageTimestampMs(ctx.Timestamp);
// prompt-prelude substitutes MEDIA_ONLY_USER_TEXT as transcriptBody for
// bodyless turns; storage stays bare (the LLM boundary re-injects it), while
@@ -8,7 +8,13 @@ import {
clearActiveEmbeddedRun,
setActiveEmbeddedRun,
} from "../../agents/embedded-agent-runner/runs.js";
import { buildChannelInboundEventContext } from "../../channels/inbound-event/context.js";
import type { SessionEntry } from "../../config/sessions.js";
import {
mintMemoryPostboxTurnCapability,
resetMemoryPostboxTurnCapabilitiesForTest,
resolveMemoryPostboxTurnCapability,
} from "../../gateway/memory-postbox-turn-capability.js";
import { withSystemEventOwner } from "../../infra/system-event-ownership.js";
import {
enqueueSystemEvent,
@@ -67,6 +73,7 @@ vi.mock("../../config/sessions/paths.js", () => ({
const loadSessionEntryMock = vi.hoisted(() => vi.fn());
const updateAmbientTranscriptWatermarkMock = vi.hoisted(() => vi.fn().mockResolvedValue(null));
const createCurrentMemorySessionContextMock = vi.hoisted(() => vi.fn());
vi.mock("../../config/sessions/session-accessor.js", () => ({
listSessionEntries: vi.fn().mockReturnValue([]),
@@ -79,6 +86,10 @@ vi.mock("../../config/sessions/ambient-transcript-watermark.js", () => ({
updateAmbientTranscriptWatermark: updateAmbientTranscriptWatermarkMock,
}));
vi.mock("../../state/memory-session-subject.js", () => ({
createCurrentMemorySessionContext: createCurrentMemorySessionContextMock,
}));
vi.mock("../../globals.js", () => ({
logVerbose: vi.fn(),
}));
@@ -356,11 +367,21 @@ describe("runPreparedReply media-only handling", () => {
vi.mocked(resolveInboundUserContextPromptJoiner).mockReturnValue(undefined);
vi.mocked(hasControlCommand).mockReturnValue(false);
replyRunTesting.resetReplyRunRegistry();
resetMemoryPostboxTurnCapabilitiesForTest();
createCurrentMemorySessionContextMock.mockReturnValue({
kind: "current",
context: {
subject: { kind: "user" },
principalId: "principal-alice",
fingerprint: "alice-session-fingerprint",
},
});
});
afterEach(() => {
vi.useRealTimers();
resetSystemEventsForTest();
resetMemoryPostboxTurnCapabilitiesForTest();
const paths = cleanupPaths.splice(0);
return Promise.all(paths.map((entry) => rm(entry, { recursive: true, force: true })));
});
@@ -381,6 +402,99 @@ describe("runPreparedReply media-only handling", () => {
});
});
it.each([
{ name: "native external channel input", inputProvenance: undefined, expected: true },
{
name: "synthetic channel reflection",
inputProvenance: {
kind: "internal_system" as const,
sourceTool: "channel_feedback_reflection",
},
expected: false,
},
{
name: "restart continuation",
inputProvenance: { kind: "internal_system" as const, sourceTool: "restart-sentinel" },
expected: false,
},
])("admits a postbox source only for $name", async ({ inputProvenance, expected }) => {
const inbound = buildChannelInboundEventContext({
channel: "telegram",
accountId: "default",
provider: "telegram",
messageId: "message-postbox-ingress",
from: "telegram:alice",
sender: { id: "alice" },
conversation: { kind: "direct", id: "alice" },
route: {
agentId: "main",
routeSessionKey: "agent:main:telegram:direct:alice",
},
reply: { to: "telegram:alice", originatingTo: "telegram:alice" },
message: { body: "remember this", rawBody: "remember this" },
...(inputProvenance ? { inputProvenance } : {}),
});
let token: string | undefined;
let runIdentity: { agentId: string; sessionKey: string; sessionId: string } | undefined;
vi.mocked(runReplyAgent).mockImplementationOnce(async (params) => {
const run = params.followupRun.run;
const sessionKey = params.runtimePolicySessionKey ?? params.sessionKey ?? run.sessionId;
runIdentity = { agentId: run.agentId, sessionKey, sessionId: run.sessionId };
token = mintMemoryPostboxTurnCapability({
agentId: run.agentId,
runId: "postbox-ingress-composition",
sessionKey,
sessionId: run.sessionId,
sourceContext: params.sessionCtx,
});
return { text: "ok" };
});
await runPrepared({
ctx: inbound,
sessionCtx: inbound,
agentId: "main",
sessionId: "session-postbox-ingress",
sessionKey: "agent:main:telegram:direct:alice",
command: {
surface: "telegram",
channel: "telegram",
isAuthorizedSender: true,
abortKey: "agent:main:telegram:direct:alice",
ownerList: [],
senderIsOwner: false,
rawBodyNormalized: "remember this",
commandBodyNormalized: "remember this",
} as never,
});
if (!expected) {
expect(token).toBeUndefined();
return;
}
expect(token).toEqual(expect.any(String));
expect(runIdentity).toBeDefined();
expect(
resolveMemoryPostboxTurnCapability({
token,
agentId: runIdentity!.agentId,
runId: "postbox-ingress-composition",
sessionKey: runIdentity!.sessionKey,
sessionId: runIdentity!.sessionId,
}),
).toEqual({
sourceTurnId: buildChannelSourceTurnId({
provider: "telegram",
accountId: "default",
conversationId: "telegram:alice",
messageId: "message-postbox-ingress",
}),
sourceChannelRef: "telegram:default:telegram:alice",
senderEvidenceRef: "alice",
targetPrincipalId: "principal-alice",
});
});
it("includes current exec overrides in the queued runner prompt", async () => {
await runPrepared({
execOverrides: {
@@ -69,6 +69,7 @@ describe("buildChannelSourceTurnId", () => {
expect(readChannelSourceTurnSameThreadRequired({ ...context })).toBe(true);
expect(JSON.stringify(context)).toBe('{"MessageSid":"7"}');
});
it("does not mint channel source-turn ids for internal-origin ingress", () => {
// Gateway chat.send stamps the internal channel as the ingress provider and
// keys the persisted user turn by run id; minting a channel id there would
+3
View File
@@ -205,6 +205,9 @@ export async function dispatchInboundDirectDmWithRuntime(
OriginatingTo: params.originatingTo ?? params.recipientAddress,
NativeDirectUserId: params.peer.id,
...params.extraContext,
// This legacy facade is still a native channel ingress boundary. Do not let an adapter-provided
// context relabel a user message as an internal continuation before postbox admission.
InputProvenance: { kind: "external_user", sourceChannel: params.channel },
});
const plan = buildDirectDmTurnPlan(params, route, ctxPayload);
await params.runtime.channel.inbound.run({
+1
View File
@@ -148,6 +148,7 @@ export async function runChannelFeedbackReflection(params: {
},
reply: { to: target, originatingTo: target },
message: { body, bodyForAgent: prompt, rawBody: prompt, commandBody: prompt },
inputProvenance: { kind: "internal_system", sourceTool: "channel_feedback_reflection" },
access: { commands: { authorized: false } },
});
const responses: string[] = [];
@@ -108,6 +108,18 @@ describe("resolveInboundSupplementalSenderAllowed", () => {
});
describe("buildChannelInboundEventContext", () => {
it("records native channel messages as external-user ingress and preserves synthetic provenance", () => {
expect(buildTestInboundEventContext().InputProvenance).toEqual({
kind: "external_user",
sourceChannel: "test",
});
expect(
buildTestInboundEventContext({
inputProvenance: { kind: "internal_system", sourceTool: "channel_feedback_reflection" },
}).InputProvenance,
).toEqual({ kind: "internal_system", sourceTool: "channel_feedback_reflection" });
});
it("maps normalized inbound facts into a finalized message context", async () => {
const ctx = buildChannelInboundEventContext({
channel: "test",
+9 -2
View File
@@ -23,6 +23,7 @@ import type { ContextVisibilityMode } from "../../config/types.base.js";
import type { GroupToolPolicyConfig } from "../../config/types.tools.js";
import type { PluginHookChannelContext } from "../../plugins/hook-channel-context.types.js";
import { shouldIncludeSupplementalContext } from "../../security/context-visibility.js";
import type { InputProvenance } from "../../sessions/input-provenance.js";
import type { InboundImplicitMentionKind } from "../mention-gating.js";
import type { ChannelIngressCommandAccess } from "../message-access/runtime-types.js";
import type {
@@ -98,6 +99,8 @@ export type BuildChannelInboundEventContextParams = {
supplemental?: ChannelInboundSupplementalFacts;
channelContext?: PluginHookChannelContext;
contextVisibility?: ContextVisibilityMode;
/** Trusted source classification for synthetic channel events; native channel messages default external. */
inputProvenance?: InputProvenance;
finalize?: FinalizeInboundContextFn;
finalizeOptions?: FinalizeInboundContextOptions;
extra?: Record<string, unknown>;
@@ -548,10 +551,14 @@ export function buildChannelInboundEventContext(
OriginatingChannel: params.channel,
OriginatingTo: params.reply.originatingTo ?? params.reply.to,
ThreadParentId: params.reply.threadParentId ?? params.conversation.parentId,
// This builder is the post-admission boundary for channel events. Preserve
// that fact so interceptors cannot bypass sender, route, or pairing gates.
// This builder is the post-admission boundary for channel events. Native messages are
// external-user input; synthetic owners must classify themselves before dispatch.
InboundAccessAuthorized: true,
...params.extra,
InputProvenance: params.inputProvenance ?? {
kind: "external_user" as const,
sourceChannel: params.channel,
},
};
const finalizeParams = {
finalize: params.finalize,
+3 -2
View File
@@ -2,6 +2,7 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { resetMemoryIsolationCutoverForTest } from "../plugins/memory-cutover.js";
import {
closeOpenClawAgentDatabasesForTest,
@@ -11,9 +12,9 @@ import { runDoctorMemoryIsolation } from "./doctor-memory-isolation.js";
describe("runDoctorMemoryIsolation", () => {
let stateDir = "";
const cfg = {
const cfg: OpenClawConfig = {
agents: { list: [{ id: "main", default: true }, { id: "support" }] },
} as const;
};
beforeEach(() => {
stateDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-doctor-memory-isolation-"));
@@ -203,7 +203,9 @@ describe("SQLite transcript archive worker", () => {
const legacyArchive = materializeSqliteTranscriptArchiveInWorker(
planArchiveWorker(database, path.dirname(storePath), legacySessionId),
);
expect(readArchiveLines(legacyArchive.archivedPath)).toEqual([JSON.stringify(legacyEvent)]);
const legacyArchivePath = legacyArchive.archivedPath;
expect(legacyArchivePath).not.toBeNull();
expect(readArchiveLines(legacyArchivePath ?? undefined)).toEqual([JSON.stringify(legacyEvent)]);
const sessionId = "enforced-policy-archive-session";
const sessionKey = "agent:main:enforced-policy-archive";
@@ -215,7 +217,9 @@ describe("SQLite transcript archive worker", () => {
const archive = materializeSqliteTranscriptArchiveInWorker(
planArchiveWorker(database, path.dirname(storePath), sessionId),
);
const lines = readArchiveLines(archive.archivedPath);
const archivePath = archive.archivedPath;
expect(archivePath).not.toBeNull();
const lines = readArchiveLines(archivePath ?? undefined);
expect(lines).toHaveLength(2);
expect(lines[0]).toBe(JSON.stringify(event));
expect(JSON.parse(lines[1] ?? "")).toMatchObject({
@@ -272,7 +276,7 @@ describe("SQLite transcript archive worker", () => {
{ agentId: database.agentId, path: database.path },
);
expect(readAuthorizedTranscriptEventSeqs(database.db, sessionId)).toEqual(new Set([eventSeq]));
expect(readArchiveLines(archive.archivedPath)).toHaveLength(2);
expect(readArchiveLines(archivePath ?? undefined)).toHaveLength(2);
});
it("restores a confirmed archive only through its original immutable session subject", async () => {
@@ -1,6 +1,7 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { expectDefined } from "@openclaw/normalization-core";
import { afterEach, describe, expect, it, vi } from "vitest";
import { runDoctorMemoryIsolation } from "../../commands/doctor-memory-isolation.js";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
@@ -363,6 +364,10 @@ describe("transcript memory policy companions", () => {
if (!source) {
throw new Error("fixture expected an authorized compaction source");
}
const sourceEventSeq = expectDefined(
source.eventSeqs[0],
"authorized compaction source event at index zero",
);
const sourceCompanion = database.db
.prepare(
`SELECT policy.run_id, detail.source_event_seq
@@ -371,7 +376,7 @@ describe("transcript memory policy companions", () => {
ON detail.session_id = policy.session_id AND detail.event_seq = policy.event_seq
WHERE policy.session_id = ? AND policy.event_seq = ?`,
)
.get(SESSION_ID, source.eventSeqs[0]);
.get(SESSION_ID, sourceEventSeq);
let committed: { eventSeq: number; policyId: string } | undefined;
const commit = async () =>
await withOwnedSessionTranscriptWrites(
@@ -421,6 +426,10 @@ describe("transcript memory policy companions", () => {
compactionPolicy: { compactionPolicyId: "sealed-compaction-policy" },
});
expect(committed).toEqual({ eventSeq: expect.any(Number), policyId: "sealed-compaction-policy" });
const committedEventSeq = expectDefined(
committed?.eventSeq,
"committed sealed compaction event sequence",
);
expect(
readSessionEntryRow(database, SESSION_KEY)?.entry.compactionCheckpoints?.map(
(checkpoint) => checkpoint.checkpointId,
@@ -456,7 +465,7 @@ describe("transcript memory policy companions", () => {
ON detail.session_id = policy.session_id AND detail.event_seq = policy.event_seq
WHERE policy.session_id = ? AND policy.event_seq = ?`,
)
.get(SESSION_ID, committed?.eventSeq),
.get(SESSION_ID, committedEventSeq),
).toEqual(sourceCompanion);
expect(
loadSqliteTranscriptEventsSync(scope(env)).some(
@@ -19,6 +19,7 @@ type TranscriptMemoryPolicyDatabase = Pick<
| "memory_policy_set_members"
| "memory_policy_sets"
| "memory_compaction_policies"
| "memory_compaction_policy_sources"
| "memory_resource_revisions"
| "memory_run_exposure_resources"
| "memory_run_exposures"
@@ -7,6 +7,7 @@ vi.mock("../state/memory-session-subject.js", () => ({
}));
import {
admitMemoryPostboxTurnIngress,
mintMemoryPostboxTurnCapability,
resetMemoryPostboxTurnCapabilitiesForTest,
resolveMemoryPostboxTurnCapability,
@@ -20,16 +21,41 @@ describe("memory postbox turn capability", () => {
sessionContextMock.mockReset();
});
function admittedUserContext() {
return {
kind: "current" as const,
context: {
subject: { kind: "user" as const },
principalId: "principal-alice",
fingerprint: "current-user-fingerprint",
},
};
}
function sourceContext(sourceTurnId = "channel-user:v1:source-1") {
const context = {};
admitMemoryPostboxTurnIngress({
context,
agentId: "main",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
provider: "telegram",
inputProvenance: { kind: "external_user" },
sourceTurnId,
sourceChannelRef: "telegram:account:team",
senderEvidenceRef: "telegram:sender-alice",
});
return context;
}
it("binds trusted source evidence to one live agent run and session", () => {
sessionContextMock.mockReturnValue(admittedUserContext());
const token = mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
sourceChannelRef: "telegram:team",
sourceMessageRef: "message-1",
senderEvidenceRef: "sender-evidence-1",
targetPrincipalId: "principal-alice",
sourceContext: sourceContext(),
nowMs: 100,
ttlMs: 1_000,
});
@@ -44,18 +70,40 @@ describe("memory postbox turn capability", () => {
nowMs: 101,
}),
).toEqual({
sourceChannelRef: "telegram:team",
sourceMessageRef: "message-1",
senderEvidenceRef: "sender-evidence-1",
sourceTurnId: "channel-user:v1:source-1",
sourceChannelRef: "telegram:account:team",
senderEvidenceRef: "telegram:sender-alice",
targetPrincipalId: "principal-alice",
});
for (const mismatch of [
{ agentId: "other", runId: "run-1", sessionKey: "agent:main:group:team", sessionId: "session-1" },
{ agentId: "main", runId: "run-2", sessionKey: "agent:main:group:team", sessionId: "session-1" },
{ agentId: "main", runId: "run-1", sessionKey: "agent:main:group:other", sessionId: "session-1" },
{ agentId: "main", runId: "run-1", sessionKey: "agent:main:group:team", sessionId: "session-2" },
{
agentId: "other",
runId: "run-1",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
},
{
agentId: "main",
runId: "run-2",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
},
{
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:group:other",
sessionId: "session-1",
},
{
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:group:team",
sessionId: "session-2",
},
]) {
expect(resolveMemoryPostboxTurnCapability({ token, ...mismatch, nowMs: 101 })).toBeUndefined();
expect(
resolveMemoryPostboxTurnCapability({ token, ...mismatch, nowMs: 101 }),
).toBeUndefined();
}
expect(
resolveMemoryPostboxTurnCapability({
@@ -70,14 +118,13 @@ describe("memory postbox turn capability", () => {
});
it("cannot be redeemed after explicit terminal revocation", () => {
sessionContextMock.mockReturnValue(admittedUserContext());
const token = mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:group:team",
sourceChannelRef: "telegram:team",
sourceMessageRef: "message-1",
senderEvidenceRef: "sender-evidence-1",
targetPrincipalId: "principal-alice",
sessionId: "session-1",
sourceContext: sourceContext(),
});
expect(revokeMemoryPostboxTurnCapability(token)).toBe(true);
expect(
@@ -86,15 +133,144 @@ describe("memory postbox turn capability", () => {
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
}),
).toBeUndefined();
});
it("requires a private ingress source marker and rechecks the current user subject", () => {
sessionContextMock.mockReturnValue(admittedUserContext());
expect(
mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:direct:alice",
sessionId: "session-1",
sourceContext: {},
}),
).toBeUndefined();
const source = {};
admitMemoryPostboxTurnIngress({
context: source,
agentId: "main",
sessionKey: "agent:main:direct:alice",
sessionId: "session-1",
provider: "telegram",
inputProvenance: { kind: "external_user" },
sourceTurnId: "channel-user:v1:direct-alice",
sourceChannelRef: "telegram:account:alice",
senderEvidenceRef: "telegram:sender-alice",
});
const token = mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:direct:alice",
sessionId: "session-1",
sourceContext: source,
});
expect(token).toEqual(expect.any(String));
sessionContextMock.mockReturnValue({
kind: "current",
context: {
subject: { kind: "user" },
principalId: "principal-alice",
fingerprint: "rebound-user-fingerprint",
},
});
expect(
resolveMemoryPostboxTurnCapability({
token,
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:direct:alice",
sessionId: "session-1",
}),
).toBeUndefined();
});
it("binds provenance to the exact admitted external-user context and session", () => {
sessionContextMock.mockReturnValue(admittedUserContext());
const source = sourceContext();
expect(
mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-1",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
sourceContext: source,
}),
).toEqual(expect.any(String));
for (const context of [{ ...source }, {}]) {
expect(
mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-2",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
sourceContext: context,
}),
).toBeUndefined();
}
expect(
mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-2",
sessionKey: "agent:main:direct:alice",
sessionId: "session-1",
sourceContext: source,
}),
).toBeUndefined();
const internal = {};
admitMemoryPostboxTurnIngress({
context: internal,
agentId: "main",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
provider: "telegram",
inputProvenance: { kind: "internal_system", sourceTool: "restart-sentinel" },
sourceTurnId: "channel-user:v1:restarted",
sourceChannelRef: "telegram:account:team",
senderEvidenceRef: "telegram:sender-alice",
});
expect(
mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-3",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
sourceContext: internal,
}),
).toBeUndefined();
const missingProvenance = {};
admitMemoryPostboxTurnIngress({
context: missingProvenance,
agentId: "main",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
provider: "telegram",
inputProvenance: undefined,
sourceTurnId: "channel-user:v1:unknown-provenance",
sourceChannelRef: "telegram:account:team",
senderEvidenceRef: "telegram:sender-alice",
});
expect(
mintMemoryPostboxTurnCapability({
agentId: "main",
runId: "run-4",
sessionKey: "agent:main:group:team",
sessionId: "session-1",
sourceContext: missingProvenance,
}),
).toBeUndefined();
});
it("selects a postbox target only from the current verified direct-user session", () => {
sessionContextMock.mockReturnValue({
kind: "current",
context: { subject: { kind: "user" }, principalId: "principal-alice" },
});
sessionContextMock.mockReturnValue(admittedUserContext());
expect(
resolveMemoryPostboxTargetPrincipal({
@@ -111,7 +287,11 @@ describe("memory postbox turn capability", () => {
sessionContextMock.mockReturnValue({
kind: "current",
context: { subject: { kind: "conversation" }, principalId: "conversation-team" },
context: {
subject: { kind: "conversation" },
principalId: "conversation-team",
fingerprint: "conversation-fingerprint",
},
});
expect(
resolveMemoryPostboxTargetPrincipal({
+132 -28
View File
@@ -2,7 +2,9 @@ import { randomBytes } from "node:crypto";
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
import { pruneMapToMaxSize } from "../infra/map-size.js";
import { normalizeAgentId } from "../routing/session-key.js";
import type { InputProvenance } from "../sessions/input-provenance.js";
import { createCurrentMemorySessionContext } from "../state/memory-session-subject.js";
import { isTrustedMessageActionTurnIngress } from "./message-action-turn-capability.js";
const DEFAULT_TTL_MS = 15 * 60_000;
const MAX_TTL_MS = 24 * 60 * 60_000;
@@ -13,23 +15,35 @@ type MemoryPostboxTurnCapability = Readonly<{
agentId: string;
runId: string;
sessionKey: string;
sessionId?: string;
sessionId: string;
sourceTurnId: string;
sourceChannelRef: string;
sourceMessageRef: string;
senderEvidenceRef: string;
targetPrincipalId: string;
sessionContextFingerprint: string;
expiresAtMs: number;
}>;
export type ResolvedMemoryPostboxSource = Readonly<{
/** Opaque, account-and-conversation-scoped identity minted at trusted channel ingress. */
sourceTurnId: string;
sourceChannelRef: string;
sourceMessageRef: string;
senderEvidenceRef: string;
/** The core-selected private subject whose quarantine receives this source. */
targetPrincipalId: string;
}>;
const capabilitiesByToken = new Map<string, MemoryPostboxTurnCapability>();
const admittedIngressByContext = new WeakMap<object, AdmittedMemoryPostboxIngress>();
type AdmittedMemoryPostboxIngress = Readonly<
ResolvedMemoryPostboxSource & {
agentId: string;
sessionKey: string;
sessionId: string;
sessionContextFingerprint: string;
}
>;
function resolveTtlMs(value: number | undefined): number {
if (!Number.isFinite(value) || value === undefined || value <= 0) {
@@ -46,6 +60,75 @@ function required(value: string | undefined, label: string): string {
return normalized;
}
function readCurrentUserSubject(params: {
agentId: string;
sessionKey: string;
sessionId: string;
}) {
const session = createCurrentMemorySessionContext({
sessionKey: params.sessionKey,
sessionId: params.sessionId,
options: { agentId: params.agentId },
});
return session.kind === "current" && session.context.subject.kind === "user"
? Object.freeze({
principalId: session.context.principalId,
fingerprint: session.context.fingerprint,
})
: undefined;
}
/**
* Stamps one exact inbound context after channel routing has selected both the source message and
* the current user subject. A copied symbol field or caller-supplied session tuple cannot recover
* this record, and non-user/system continuations intentionally receive no postbox authority.
*/
export function admitMemoryPostboxTurnIngress(params: {
context: object;
agentId: string;
sessionKey: string;
sessionId: string;
provider: string | undefined;
inputProvenance: InputProvenance | undefined;
sourceTurnId: string | undefined;
sourceChannelRef: string | undefined;
senderEvidenceRef: string | undefined;
}): void {
admittedIngressByContext.delete(params.context);
if (
!isTrustedMessageActionTurnIngress(params.provider) ||
params.inputProvenance?.kind !== "external_user"
) {
return;
}
const sourceTurnId = normalizeOptionalString(params.sourceTurnId);
const sourceChannelRef = normalizeOptionalString(params.sourceChannelRef);
const senderEvidenceRef = normalizeOptionalString(params.senderEvidenceRef);
if (!sourceTurnId || !sourceChannelRef || !senderEvidenceRef) {
return;
}
const agentId = normalizeAgentId(params.agentId);
const sessionKey = required(params.sessionKey, "session identity");
const sessionId = required(params.sessionId, "session generation");
const subject = readCurrentUserSubject({ agentId, sessionKey, sessionId });
if (!subject) {
return;
}
admittedIngressByContext.set(
params.context,
Object.freeze({
agentId,
sessionKey,
sessionId,
sourceTurnId,
sourceChannelRef,
senderEvidenceRef,
targetPrincipalId: subject.principalId,
sessionContextFingerprint: subject.fingerprint,
}),
);
}
function sweepExpiredMemoryPostboxTurnCapabilities(nowMs: number = Date.now()): void {
for (const [token, capability] of capabilitiesByToken) {
if (nowMs >= capability.expiresAtMs) {
@@ -55,26 +138,41 @@ function sweepExpiredMemoryPostboxTurnCapabilities(nowMs: number = Date.now()):
}
/**
* Minted only from an admitted inbound user turn. The opaque token is later scoped to the selected
* memory plugin, which redeems current channel/sender evidence without accepting it from tool args.
* Minted only from the exact context admitted at trusted external-user ingress. Neither callers nor
* models may select the source, sender evidence, target principal, or the session it belongs to.
*/
export function mintMemoryPostboxTurnCapability(params: {
agentId: string;
runId: string;
sessionKey: string;
sessionId?: string;
sourceChannelRef: string;
sourceMessageRef: string;
senderEvidenceRef: string;
/** Resolved only by core from the current verified user session subject. */
targetPrincipalId: string;
sessionId: string;
/** The inbound context whose private marker is written only by trusted channel ingress. */
sourceContext: object;
expiresWithRun?: boolean;
ttlMs?: number;
nowMs?: number;
}): string {
}): string | undefined {
const agentId = normalizeAgentId(params.agentId);
const runId = required(params.runId, "run identity");
const sessionKey = required(params.sessionKey, "session identity");
const sessionId = required(params.sessionId, "session generation");
const source = admittedIngressByContext.get(params.sourceContext);
if (
!source ||
source.agentId !== agentId ||
source.sessionKey !== sessionKey ||
source.sessionId !== sessionId
) {
return undefined;
}
const subject = readCurrentUserSubject({ agentId, sessionKey, sessionId });
if (
!subject ||
subject.principalId !== source.targetPrincipalId ||
subject.fingerprint !== source.sessionContextFingerprint
) {
return undefined;
}
const nowMs = params.nowMs ?? Date.now();
sweepExpiredMemoryPostboxTurnCapabilities(nowMs);
pruneMapToMaxSize(capabilitiesByToken, MAX_ACTIVE_CAPABILITIES - 1);
@@ -85,11 +183,12 @@ export function mintMemoryPostboxTurnCapability(params: {
agentId,
runId,
sessionKey,
sessionId: normalizeOptionalString(params.sessionId),
sourceChannelRef: required(params.sourceChannelRef, "source channel evidence"),
sourceMessageRef: required(params.sourceMessageRef, "source message evidence"),
senderEvidenceRef: required(params.senderEvidenceRef, "sender evidence"),
targetPrincipalId: required(params.targetPrincipalId, "target principal"),
sessionId,
sourceTurnId: source.sourceTurnId,
sourceChannelRef: source.sourceChannelRef,
senderEvidenceRef: source.senderEvidenceRef,
targetPrincipalId: source.targetPrincipalId,
sessionContextFingerprint: source.sessionContextFingerprint,
expiresAtMs: params.expiresWithRun
? RUN_LIFETIME_EXPIRES_AT_MS
: nowMs + resolveTtlMs(params.ttlMs),
@@ -98,7 +197,7 @@ export function mintMemoryPostboxTurnCapability(params: {
return token;
}
/** Rejects forged, stale, cross-agent, cross-run, and cross-session tokens without disclosure. */
/** Rejects forged, stale, rebound, cross-agent, cross-run, and cross-session tokens without disclosure. */
export function resolveMemoryPostboxTurnCapability(params: {
token?: string;
agentId: string;
@@ -121,16 +220,28 @@ export function resolveMemoryPostboxTurnCapability(params: {
capability.agentId !== normalizeAgentId(params.agentId) ||
capability.runId !== normalizeOptionalString(params.runId) ||
capability.sessionKey !== normalizeOptionalString(params.sessionKey) ||
(capability.sessionId && capability.sessionId !== normalizeOptionalString(params.sessionId))
capability.sessionId !== normalizeOptionalString(params.sessionId)
) {
if (nowMs >= capability.expiresAtMs) {
capabilitiesByToken.delete(token);
}
return undefined;
}
const subject = readCurrentUserSubject({
agentId: capability.agentId,
sessionKey: capability.sessionKey,
sessionId: capability.sessionId,
});
if (
!subject ||
subject.principalId !== capability.targetPrincipalId ||
subject.fingerprint !== capability.sessionContextFingerprint
) {
return undefined;
}
return Object.freeze({
sourceTurnId: capability.sourceTurnId,
sourceChannelRef: capability.sourceChannelRef,
sourceMessageRef: capability.sourceMessageRef,
senderEvidenceRef: capability.senderEvidenceRef,
targetPrincipalId: capability.targetPrincipalId,
});
@@ -145,14 +256,7 @@ export function resolveMemoryPostboxTargetPrincipal(params: {
sessionKey: string;
sessionId: string;
}): string | undefined {
const session = createCurrentMemorySessionContext({
sessionKey: params.sessionKey,
sessionId: params.sessionId,
options: { agentId: params.agentId },
});
return session.kind === "current" && session.context.subject.kind === "user"
? session.context.principalId
: undefined;
return readCurrentUserSubject(params)?.principalId;
}
export function revokeMemoryPostboxTurnCapability(token: string | undefined): boolean {
+5
View File
@@ -265,6 +265,7 @@ describe("channel-inbound direct-message helpers", () => {
ReplyToId: "event-parent",
ReplyToIdFull: "event-parent",
MessageThreadId: "thread-7",
InputProvenance: { kind: "internal_system", sourceTool: "forged-adapter-context" },
},
timestamp: 1_710_000_000_000,
commandAuthorized: true,
@@ -288,6 +289,10 @@ describe("channel-inbound direct-message helpers", () => {
expect(result.ctxPayload.NativeDirectUserId).toBe("sender-1");
expect(result.ctxPayload.OriginatingTo).toBe("nostr:bot-1");
expect(result.ctxPayload.CommandAuthorized).toBe(true);
expect(result.ctxPayload.InputProvenance).toEqual({
kind: "external_user",
sourceChannel: "nostr",
});
expect(recordInboundSession).toHaveBeenCalledTimes(1);
expect(dispatchReplyWithBufferedBlockDispatcher).toHaveBeenCalledTimes(1);
expect(deliver).toHaveBeenCalledWith({ text: "reply text" });
@@ -0,0 +1,5 @@
/** Core-owned Gateway-profile resolver for selected memory sharing controls. */
export {
resolveMemoryPrincipalForUserProfile,
type MemoryPrincipal,
} from "../state/memory-identity.js";
+115 -67
View File
@@ -4,8 +4,14 @@ import {
type AuthorizedMemoryPlan,
type AuthorizedMemoryResultEnvelope,
type AuthorizedMemorySearchResult,
type AuthorizedMemoryVirtualView,
type MemoryAccessContext,
} from "../plugin-sdk/memory-authorization.js";
import type {
AuthorizedMemoryReadInvocation,
AuthorizedMemoryWriteInvocation,
MemoryInvocationUnavailable,
} from "./memory-invocation.js";
const mocks = vi.hoisted(() => ({
admit: vi.fn(),
@@ -44,6 +50,7 @@ const {
readAuthorizedMemoryForInvocation,
readAuthorizedMemoryRunExposure,
searchAuthorizedMemoryForInvocation,
stageAuthorizedMemorySealedCompactionForInvocation,
writeAuthorizedMemoryForInvocation,
} = await import("./memory-invocation.js");
const { clearMemoryRunExposureForTest } = await import("./memory-run-exposure.js");
@@ -118,10 +125,18 @@ function createWritePlan(): AuthorizedMemoryPlan & Readonly<{ operation: "append
return { ...createPlan(), operation: "append" };
}
function createDeriveContext(): MemoryAccessContext & Readonly<{ operation: "derive" }> {
return { ...createContext(), operation: "derive" };
}
function createDerivePlan(): AuthorizedMemoryPlan & Readonly<{ operation: "derive" }> {
return { ...createPlan(), operation: "derive" };
}
let receiptSequence = 0;
function createEnvelope<T>(
value: T,
value: AuthorizedMemoryResultEnvelope<T>["value"],
overrides?: Readonly<{
exposureReceipt?: Partial<AuthorizedMemoryResultEnvelope<T>["exposureReceipt"]>;
egressReceipt?: Partial<AuthorizedMemoryResultEnvelope<T>["egressReceipt"]>;
@@ -160,6 +175,32 @@ function createEnvelope<T>(
};
}
function assertMemoryInvocationAvailable(
value: AuthorizedMemoryReadInvocation | MemoryInvocationUnavailable,
message?: string,
): asserts value is AuthorizedMemoryReadInvocation;
function assertMemoryInvocationAvailable(
value: AuthorizedMemoryWriteInvocation | MemoryInvocationUnavailable,
message?: string,
): asserts value is AuthorizedMemoryWriteInvocation;
function assertMemoryInvocationAvailable(
value: AuthorizedMemoryVirtualView | MemoryInvocationUnavailable,
message?: string,
): asserts value is AuthorizedMemoryVirtualView;
function assertMemoryInvocationAvailable(
value:
| AuthorizedMemoryReadInvocation
| AuthorizedMemoryWriteInvocation
| AuthorizedMemoryVirtualView
| MemoryInvocationUnavailable,
message = "fixture failed to create an authorized memory value",
): void {
expect(value).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if ("unavailable" in value) {
throw new Error(message);
}
}
describe("authorized memory read invocation", () => {
afterEach(() => {
clearMemoryRunExposureForTest();
@@ -243,10 +284,7 @@ describe("authorized memory read invocation", () => {
authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES,
},
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(
searchAuthorizedMemoryForInvocation({ invocation, query: "allowed" }),
).resolves.toEqual({
@@ -311,10 +349,7 @@ describe("authorized memory read invocation", () => {
context: {} as never,
capability: { authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES },
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
const response = await searchAuthorizedMemoryForInvocation({ invocation, query: "private" });
@@ -365,10 +400,7 @@ describe("authorized memory read invocation", () => {
context: {} as never,
capability: { authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES },
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(
searchAuthorizedMemoryForInvocation({ invocation, query: "private" }),
).resolves.toEqual(
@@ -426,10 +458,7 @@ describe("authorized memory read invocation", () => {
context: {} as never,
capability: { authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES },
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(
searchAuthorizedMemoryForInvocation({ invocation, query: "private" }),
).resolves.toEqual(
@@ -485,10 +514,7 @@ describe("authorized memory read invocation", () => {
context: {} as never,
capability: { authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES },
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(searchAuthorizedMemoryForInvocation({ invocation, query: "first" })).resolves.toBe(
MEMORY_INVOCATION_UNAVAILABLE,
);
@@ -534,10 +560,7 @@ describe("authorized memory read invocation", () => {
context: {} as never,
capability: { authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES },
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(
searchAuthorizedMemoryForInvocation({ invocation, query: "private" }),
).resolves.toBe(MEMORY_INVOCATION_UNAVAILABLE);
@@ -559,10 +582,7 @@ describe("authorized memory read invocation", () => {
context: {} as never,
capability: { authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES },
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(
searchAuthorizedMemoryForInvocation({ invocation, query: "private" }),
@@ -611,10 +631,7 @@ describe("authorized memory read invocation", () => {
context: {} as never,
capability: { authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES },
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(
searchAuthorizedMemoryForInvocation({ invocation, query: "allowed" }),
).resolves.toEqual({
@@ -689,10 +706,7 @@ describe("authorized memory read invocation", () => {
context: {} as never,
capability: { authorization: COMPLETE_MEMORY_AUTHORIZATION_CAPABILITIES },
});
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(
searchAuthorizedMemoryForInvocation({ invocation, query: "allowed" }),
).resolves.toMatchObject({
@@ -722,7 +736,7 @@ describe("authorized memory read invocation", () => {
files: [{ version: 1 as const, mountHandle: "mount-1", virtualPath: "private/1.md" }],
expiresAt: new Date(Date.now() + 60_000).toISOString(),
})),
readAuthorizedVirtualFile: vi.fn(async () =>
readAuthorizedVirtualFile: vi.fn(async (_params) =>
createEnvelope({ text: "allowed", path: "memory/private/1.md" }),
),
};
@@ -748,13 +762,9 @@ describe("authorized memory read invocation", () => {
mocks.admit.mockResolvedValue({ ok: true, runtime });
const invocation = await createAuthorizedMemoryReadInvocation({ context: {} as never });
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
throw new Error("fixture failed to admit virtual provider");
}
assertMemoryInvocationAvailable(invocation, "fixture failed to admit virtual provider");
const view = await materializeAuthorizedMemoryVirtualView({ invocation });
if (view === MEMORY_INVOCATION_UNAVAILABLE) {
throw new Error("fixture failed to materialize virtual view");
}
assertMemoryInvocationAvailable(view, "fixture failed to materialize virtual view");
await expect(
readAuthorizedMemoryVirtualFile({ invocation, view, virtualPath: "private/2.md" }),
).resolves.toBe(MEMORY_INVOCATION_UNAVAILABLE);
@@ -786,9 +796,7 @@ describe("authorized memory read invocation", () => {
});
const invocation = await createAuthorizedMemoryDeriveInvocation({ context: {} as never });
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
throw new Error("fixture failed to admit derive invocation");
}
assertMemoryInvocationAvailable(invocation, "fixture failed to admit derive invocation");
await expect(materializeAuthorizedMemoryVirtualView({ invocation })).resolves.toBe(
MEMORY_INVOCATION_UNAVAILABLE,
@@ -841,9 +849,7 @@ describe("authorized memory read invocation", () => {
mocks.admit.mockResolvedValue({ ok: true, runtime });
const invocation = await createAuthorizedMemoryReadInvocation({ context: {} as never });
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
throw new Error("fixture failed to admit virtual provider");
}
assertMemoryInvocationAvailable(invocation, "fixture failed to admit virtual provider");
await expect(materializeAuthorizedMemoryVirtualView({ invocation })).resolves.toBe(
MEMORY_INVOCATION_UNAVAILABLE,
);
@@ -870,7 +876,7 @@ describe("authorized memory read invocation", () => {
};
const admittedVirtualView = {
materializeAuthorizedVirtualView: vi.fn(async () => issuedView),
readAuthorizedVirtualFile: vi.fn(async () =>
readAuthorizedVirtualFile: vi.fn(async (_params) =>
createEnvelope({ text: "allowed", path: "memory/private/1.md" }),
),
};
@@ -895,13 +901,9 @@ describe("authorized memory read invocation", () => {
mocks.admit.mockResolvedValue({ ok: true, runtime });
const invocation = await createAuthorizedMemoryReadInvocation({ context: {} as never });
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
throw new Error("fixture failed to admit virtual provider");
}
assertMemoryInvocationAvailable(invocation, "fixture failed to admit virtual provider");
const view = await materializeAuthorizedMemoryVirtualView({ invocation });
if (view === MEMORY_INVOCATION_UNAVAILABLE) {
throw new Error("fixture failed to materialize virtual view");
}
assertMemoryInvocationAvailable(view, "fixture failed to materialize virtual view");
issuedView.revision = "replacement-revision";
issuedView.files[0]!.virtualPath = "private/replacement.md";
@@ -968,9 +970,7 @@ describe("authorized memory read invocation", () => {
mocks.admit.mockResolvedValue({ ok: true, runtime });
const invocation = await createAuthorizedMemoryReadInvocation({ context: {} as never });
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
throw new Error("fixture failed to admit virtual provider");
}
assertMemoryInvocationAvailable(invocation, "fixture failed to admit virtual provider");
runtime.virtualView = replacement;
await expect(materializeAuthorizedMemoryVirtualView({ invocation })).resolves.toMatchObject({
viewId: "view-admitted",
@@ -1001,10 +1001,7 @@ describe("authorized memory write invocation", () => {
mocks.materialize.mockReturnValue(createWriteContext());
mocks.admit.mockResolvedValue({ ok: true, runtime });
const invocation = await createAuthorizedMemoryWriteInvocation({ context: {} as never });
expect(invocation).not.toBe(MEMORY_INVOCATION_UNAVAILABLE);
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
return;
}
assertMemoryInvocationAvailable(invocation);
await expect(
writeAuthorizedMemoryForInvocation({
invocation,
@@ -1041,9 +1038,7 @@ describe("authorized memory write invocation", () => {
mocks.materialize.mockReturnValueOnce(context).mockReturnValueOnce(undefined);
mocks.admit.mockResolvedValue({ ok: true, runtime });
const invocation = await createAuthorizedMemoryWriteInvocation({ context: {} as never });
if (invocation === MEMORY_INVOCATION_UNAVAILABLE) {
throw new Error("fixture failed to create a write invocation");
}
assertMemoryInvocationAvailable(invocation, "fixture failed to create a write invocation");
await expect(
writeAuthorizedMemoryForInvocation({
invocation,
@@ -1059,4 +1054,57 @@ describe("authorized memory write invocation", () => {
).resolves.toBe(MEMORY_INVOCATION_UNAVAILABLE);
expect(runtime.writeAuthorized).not.toHaveBeenCalled();
});
it("stages sealed compaction only for a revalidated derive invocation", async () => {
const artifact = {
resourceRevisionId: "revision-derive-1",
commitInTransaction: vi.fn(),
};
const deriveRuntime = {
authorize: vi.fn().mockResolvedValue(createDerivePlan()),
stageSealedCompaction: vi.fn().mockResolvedValue(artifact),
};
mocks.materialize.mockReturnValue(createDeriveContext());
mocks.admit.mockResolvedValue({ ok: true, runtime: deriveRuntime });
const deriveInvocation = await createAuthorizedMemoryWriteInvocation({ context: {} as never });
assertMemoryInvocationAvailable(deriveInvocation, "fixture failed to create a derive invocation");
const transcriptSource = {
kind: "transcript" as const,
sessionId: "session-1",
eventSeqs: [1],
sourcePolicySetId: "policy-set-1",
deliveryAudiencesJson: '[{"kind":"user","id":"alice"}]',
};
await expect(
stageAuthorizedMemorySealedCompactionForInvocation({
invocation: deriveInvocation,
content: "sealed summary",
transcriptSource,
}),
).resolves.toBe(artifact);
expect(deriveRuntime.stageSealedCompaction).toHaveBeenCalledWith(
expect.objectContaining({
context: expect.objectContaining({ operation: "derive" }),
plan: expect.objectContaining({ operation: "derive" }),
transcriptSource,
}),
);
const appendRuntime = {
authorize: vi.fn().mockResolvedValue(createWritePlan()),
stageSealedCompaction: vi.fn(),
};
mocks.materialize.mockReturnValue(createWriteContext());
mocks.admit.mockResolvedValue({ ok: true, runtime: appendRuntime });
const appendInvocation = await createAuthorizedMemoryWriteInvocation({ context: {} as never });
assertMemoryInvocationAvailable(appendInvocation, "fixture failed to create an append invocation");
await expect(
stageAuthorizedMemorySealedCompactionForInvocation({
invocation: appendInvocation,
content: "must not stage",
transcriptSource,
}),
).resolves.toBe(MEMORY_INVOCATION_UNAVAILABLE);
expect(appendRuntime.stageSealedCompaction).not.toHaveBeenCalled();
});
});
+21 -2
View File
@@ -104,6 +104,12 @@ type WriteInvocationState = Readonly<{
runtime: Readonly<AuthorizedMemoryRuntime>;
}>;
type DeriveWriteInvocationState = Omit<WriteInvocationState, "context" | "plan"> &
Readonly<{
context: MemoryAccessContext & Readonly<{ operation: "derive" }>;
plan: AuthorizedMemoryPlan & Readonly<{ operation: "derive" }>;
}>;
const writeInvocationStates = new WeakMap<object, WriteInvocationState>();
type MemoryInvocationDiagnostic =
@@ -171,6 +177,18 @@ function readCurrentWriteContext(state: WriteInvocationState): MemoryAccessConte
return current;
}
function isDeriveWriteInvocationState(
state: WriteInvocationState,
): state is DeriveWriteInvocationState {
return state.context.operation === "derive" && state.plan.operation === "derive";
}
function isDeriveMemoryAccessContext(
context: MemoryAccessContext,
): context is MemoryAccessContext & Readonly<{ operation: "derive" }> {
return context.operation === "derive";
}
function readCurrentContext(
state: InvocationState,
): MemoryContentAccessContext | undefined {
@@ -585,7 +603,8 @@ export async function stageAuthorizedMemorySealedCompactionForInvocation(params:
if (
!state ||
!context ||
context.operation !== "derive" ||
!isDeriveMemoryAccessContext(context) ||
!isDeriveWriteInvocationState(state) ||
!state.runtime.stageSealedCompaction ||
!isCurrentPlan({ context, plan: state.plan, nowMs: Date.now() })
) {
@@ -594,7 +613,7 @@ export async function stageAuthorizedMemorySealedCompactionForInvocation(params:
try {
return await state.runtime.stageSealedCompaction({
context,
plan: state.plan as AuthorizedMemoryPlan & Readonly<{ operation: "derive" }>,
plan: state.plan,
content: params.content,
transcriptSource: params.transcriptSource,
});
+3 -1
View File
@@ -1,7 +1,9 @@
// Covers plugin-backed memory state registration and reset behavior.
import { afterEach, describe, expect, it, vi } from "vitest";
const isMemoryIsolationCutoverAgentMock = vi.hoisted(() => vi.fn(() => false));
const isMemoryIsolationCutoverAgentMock = vi.hoisted(() =>
vi.fn<(agentId: string) => boolean>(() => false),
);
vi.mock("./memory-cutover.js", () => ({
isMemoryIsolationCutoverAgent: isMemoryIsolationCutoverAgentMock,
+6 -2
View File
@@ -2016,8 +2016,12 @@ describe("resolvePluginTools optional tools", () => {
});
it("delivers a host binding only to its selected plugin factory", () => {
const memoryFactory = vi.fn(() => makeTool("memory_postbox_deposit"));
const otherFactory = vi.fn(() => makeTool("other_tool"));
const memoryFactory = vi.fn<MockRegistryToolEntry["factory"]>((_context) =>
makeTool("memory_postbox_deposit"),
);
const otherFactory = vi.fn<MockRegistryToolEntry["factory"]>((_context) =>
makeTool("other_tool"),
);
setRegistry([
{
pluginId: "memory-core",
+10
View File
@@ -199,6 +199,15 @@ export interface MemoryPostboxRateLimits {
window_started_at: number;
}
export interface MemoryPostboxReviewedCopies {
agent_id: string;
created_at: number;
item_id: string;
resource_id: string;
reviewed_content_hash: string;
revision_id: string;
}
export interface MemoryPostboxSettings {
agent_id: string;
mode: string;
@@ -912,6 +921,7 @@ export interface DB {
memory_compaction_policy_sources: MemoryCompactionPolicySources;
memory_postbox_items: MemoryPostboxItems;
memory_postbox_rate_limits: MemoryPostboxRateLimits;
memory_postbox_reviewed_copies: MemoryPostboxReviewedCopies;
memory_postbox_settings: MemoryPostboxSettings;
memory_postbox_source_handles: MemoryPostboxSourceHandles;
memory_embedding_cache: MemoryEmbeddingCache;
+35 -1
View File
@@ -1388,7 +1388,9 @@ CREATE TABLE IF NOT EXISTS memory_postbox_source_handles (
used_at INTEGER,
created_at INTEGER NOT NULL,
FOREIGN KEY (target_store_id) REFERENCES memory_stores(store_id) ON DELETE RESTRICT,
UNIQUE (agent_id, source_session_id, source_message_ref, target_store_id)
-- source_message_ref is the opaque route-scoped source-turn id, so a reset session
-- cannot deposit the same inbound message a second time.
UNIQUE (agent_id, source_message_ref, target_store_id)
) STRICT;
CREATE INDEX IF NOT EXISTS idx_memory_postbox_source_handles_live
@@ -1426,10 +1428,42 @@ CREATE TABLE IF NOT EXISTS memory_postbox_items (
CREATE INDEX IF NOT EXISTS idx_memory_postbox_items_review
ON memory_postbox_items(agent_id, target_store_id, state, created_at);
CREATE TABLE IF NOT EXISTS memory_postbox_reviewed_copies (
item_id TEXT NOT NULL PRIMARY KEY,
agent_id TEXT NOT NULL,
resource_id TEXT NOT NULL,
revision_id TEXT NOT NULL,
reviewed_content_hash TEXT NOT NULL,
created_at INTEGER NOT NULL,
FOREIGN KEY (item_id) REFERENCES memory_postbox_items(item_id) ON DELETE CASCADE,
FOREIGN KEY (resource_id) REFERENCES memory_resources(resource_id) ON DELETE RESTRICT,
FOREIGN KEY (revision_id) REFERENCES memory_resource_revisions(revision_id) ON DELETE RESTRICT
) STRICT;
CREATE INDEX IF NOT EXISTS idx_memory_postbox_reviewed_copies_revision
ON memory_postbox_reviewed_copies(agent_id, revision_id);
CREATE TRIGGER IF NOT EXISTS memory_postbox_items_immutable_provenance
BEFORE UPDATE OF item_id, agent_id, source_handle_id, target_store_id, source_channel_ref,
sender_evidence_ref, content, content_hash, created_at
ON memory_postbox_items
WHEN
NEW.item_id <> OLD.item_id OR
NEW.agent_id <> OLD.agent_id OR
NEW.source_handle_id <> OLD.source_handle_id OR
NEW.target_store_id <> OLD.target_store_id OR
NEW.source_channel_ref <> OLD.source_channel_ref OR
NEW.sender_evidence_ref <> OLD.sender_evidence_ref OR
NEW.created_at <> OLD.created_at OR
(
(NEW.content <> OLD.content OR NEW.content_hash <> OLD.content_hash) AND
NOT (
OLD.state IN ('postbox', 'reviewed', 'rejected') AND
NEW.state = 'purged' AND
NEW.content = '' AND
NEW.content_hash = ''
)
)
BEGIN
SELECT RAISE(ABORT, 'memory postbox provenance is immutable');
END;
@@ -145,6 +145,61 @@ describe("scoped memory additive agent schema", () => {
);
});
it("repairs the legacy postbox trigger so purge can erase a body without changing provenance", () => {
const database = createDatabase();
ensureOpenClawAgentScopedMemorySchema(database);
database.exec(`
DROP TRIGGER memory_postbox_items_immutable_provenance;
CREATE TRIGGER memory_postbox_items_immutable_provenance
BEFORE UPDATE OF item_id, agent_id, source_handle_id, target_store_id, source_channel_ref,
sender_evidence_ref, content, content_hash, created_at
ON memory_postbox_items
BEGIN
SELECT RAISE(ABORT, 'memory postbox provenance is immutable');
END;
`);
ensureOpenClawAgentScopedMemorySchema(database);
database.exec("PRAGMA foreign_keys = OFF");
database
.prepare(
`INSERT INTO memory_postbox_items
(item_id, agent_id, source_handle_id, target_store_id, source_channel_ref,
sender_evidence_ref, content, content_hash, state, created_at)
VALUES ('postbox-1', 'main', 'handle-1', 'store-1', 'channel-1',
'sender-1', 'secret', 'digest-1', 'postbox', 1)`,
)
.run();
expect(() =>
database
.prepare(
"UPDATE memory_postbox_items SET content = 'replacement' WHERE item_id = 'postbox-1'",
)
.run(),
).toThrow(/immutable/u);
database
.prepare(
`UPDATE memory_postbox_items
SET state = 'purged', content = '', content_hash = '', purged_at = 2
WHERE item_id = 'postbox-1'`,
)
.run();
expect(
database
.prepare(
"SELECT state, content, content_hash, sender_evidence_ref, purged_at FROM memory_postbox_items",
)
.get(),
).toEqual({
state: "purged",
content: "",
content_hash: "",
sender_evidence_ref: "sender-1",
purged_at: 2,
});
});
it("keeps the pre-output exposure ledger in the canonical scoped schema payload", () => {
expect(AGENT_SCOPED_MEMORY_SCHEMA_SQL).toContain(
"CREATE TABLE IF NOT EXISTS memory_preoutput_exposure_ledger (",
@@ -35,6 +35,7 @@ export const AGENT_SCOPED_MEMORY_TABLES = [
"memory_postbox_source_handles",
"memory_postbox_rate_limits",
"memory_postbox_items",
"memory_postbox_reviewed_copies",
] as const;
export const AGENT_SCOPED_MEMORY_FTS_TABLE = "memory_scoped_chunks_fts";
@@ -97,11 +98,53 @@ function extractScopedMemorySchema(): string {
/** Canonical additive schema for scoped resources, policy, indexes, and receipts. */
export const AGENT_SCOPED_MEMORY_SCHEMA_SQL = extractScopedMemorySchema();
const POSTBOX_PURGE_TRIGGER_MARKER = "NEW.state = 'purged'";
const POSTBOX_PURGE_TRIGGER_SQL = `
CREATE TRIGGER memory_postbox_items_immutable_provenance
BEFORE UPDATE OF item_id, agent_id, source_handle_id, target_store_id, source_channel_ref,
sender_evidence_ref, content, content_hash, created_at
ON memory_postbox_items
WHEN
NEW.item_id <> OLD.item_id OR
NEW.agent_id <> OLD.agent_id OR
NEW.source_handle_id <> OLD.source_handle_id OR
NEW.target_store_id <> OLD.target_store_id OR
NEW.source_channel_ref <> OLD.source_channel_ref OR
NEW.sender_evidence_ref <> OLD.sender_evidence_ref OR
NEW.created_at <> OLD.created_at OR
(
(NEW.content <> OLD.content OR NEW.content_hash <> OLD.content_hash) AND
NOT (
OLD.state IN ('postbox', 'reviewed', 'rejected') AND
NEW.state = 'purged' AND
NEW.content = '' AND
NEW.content_hash = ''
)
)
BEGIN
SELECT RAISE(ABORT, 'memory postbox provenance is immutable');
END;
`;
function repairPostboxPurgeTrigger(db: DatabaseSync): void {
const trigger = db
.prepare("SELECT sql FROM sqlite_master WHERE type = 'trigger' AND name = ?")
.get("memory_postbox_items_immutable_provenance") as { sql?: unknown } | undefined;
if (typeof trigger?.sql === "string" && trigger.sql.includes(POSTBOX_PURGE_TRIGGER_MARKER)) {
return;
}
// Existing additive databases have the older immutable trigger. Replace only that trigger so
// a purge can redact the body/digest while every identity-bearing provenance field stays fixed.
db.exec("DROP TRIGGER IF EXISTS memory_postbox_items_immutable_provenance");
db.exec(POSTBOX_PURGE_TRIGGER_SQL); // sqlite-allow-raw -- canonical trigger convergence.
}
/** Lazily install the full idempotent group; do not cache transaction-local success. */
export function ensureOpenClawAgentScopedMemorySchema(db: DatabaseSync): void {
const ensure = () => {
// A partially applied group is completed rather than inferred from one marker table.
db.exec(AGENT_SCOPED_MEMORY_SCHEMA_SQL); // sqlite-allow-raw -- Canonical additive DDL only.
repairPostboxPurgeTrigger(db);
};
if (db.isTransaction) {
ensure();
+50
View File
@@ -2577,6 +2577,56 @@ export const en: TranslationMap = {
search: {
intro: "Embedding and retrieval defaults shared by every agent that has no memory override.",
},
sharing: {
title: "Sharing and postbox",
intro:
"Create reviewed projection copies and review one-way postbox deposits without granting access to a private store.",
statusTitle: "Sharing status",
postboxMode: "Postbox mode",
postboxOff: "Off",
postboxReviewRequired: "Review required",
projectionCount: "Projections",
postboxCount: "Postbox items",
requestFailed: "The sharing request could not be completed.",
completeRequiredFields:
"Complete the required projection fields and choose either an expiry or an audited no-expiry reason.",
invalidAgentSharedTarget: "Agent-shared projections must target the selected agent.",
previewRequired: "Preview the projection before creating it.",
targets: {
conversation: "Conversation",
role: "Role",
agentShared: "Agent shared",
},
projection: {
title: "Reviewed projection",
description: "A projection creates one reviewed copy for a named non-private audience.",
id: "Projection to refresh",
sourceRevision: "Source revision",
targetKind: "Target kind",
targetId: "Target id",
targetStoreId: "Reviewed-copy target store id",
purpose: "Purpose",
preview: "Human-readable preview",
expiry: "Expiry",
noExpiryReason: "No-expiry audit reason",
content: "Reviewed copy",
previewAction: "Preview",
registerTarget: "Register target store",
create: "Create projection",
refresh: "Refresh projection",
},
projections: "Existing projections",
emptyProjections: "No projections are available for this profile.",
impact: "Prior exposure impact",
priorExposure: "{count} prior exposure records",
revoke: "Revoke",
postbox: "Postbox review",
emptyPostbox: "No quarantined postbox items are available.",
inspect: "Inspect",
approve: "Approve",
reject: "Reject",
purge: "Purge",
},
dreaming: {
intro:
"Dreaming runs as one managed automation across every agent workspace, so these settings are global. They are owned by the {plugin} plugin.",
+5
View File
@@ -47,6 +47,7 @@ import {
type MemoryEngineSelection,
type MemoryTab,
} from "./memory-schema.ts";
import { renderMemorySharingHost } from "./memory-sharing-host.ts";
import {
buildMemoryAddonRows,
buildMemoryEngineOptions,
@@ -697,6 +698,10 @@ class MemorySettingsPage extends OpenClawLightDomElement {
editor:
activeTab === "settings" ? this.buildEditor(memorySchemaKeysForTab("settings")) : html``,
dreamingSettings: activeTab === "settings" ? this.renderDreamingControls() : html``,
sharing:
activeTab === "settings"
? renderMemorySharingHost(this.context.gateway.snapshot, agentId)
: html``,
});
}
}
@@ -0,0 +1,40 @@
import { html, type TemplateResult } from "lit";
import type { ApplicationContext } from "../../app/context.ts";
import { readGatewayOperatorAccess } from "../../app/operator-access.ts";
import { isGatewayMethodAdvertised } from "../../lib/gateway-methods.ts";
import "./memory-sharing.ts";
const MEMORY_SHARING_METHODS = [
"memory.sharing.status",
"memory.sharing.projection.target.register",
"memory.sharing.projection.preview",
"memory.sharing.projection.create",
"memory.sharing.projection.refresh",
"memory.sharing.projection.revoke",
"memory.sharing.projection.impact",
"memory.sharing.postbox.mode.set",
"memory.sharing.postbox.inspect",
"memory.sharing.postbox.review",
"memory.sharing.postbox.purge",
] as const;
type GatewaySnapshot = ApplicationContext["gateway"]["snapshot"];
/** Hide the sharing controls until this Gateway advertises the complete profile-derived contract. */
export function renderMemorySharingHost(
gateway: GatewaySnapshot,
agentId: string | null,
): TemplateResult {
const methodsAvailable = MEMORY_SHARING_METHODS.every(
(method) => isGatewayMethodAdvertised(gateway, method) === true,
);
return html`
<openclaw-memory-sharing
.client=${gateway.client}
.connected=${gateway.phase === "connected"}
.canAdmin=${readGatewayOperatorAccess(gateway).canAdmin}
.methodsAvailable=${methodsAvailable}
.agentId=${agentId}
></openclaw-memory-sharing>
`;
}
+215
View File
@@ -0,0 +1,215 @@
/* @vitest-environment jsdom */
import { html, render } from "lit";
import { describe, expect, it, vi } from "vitest";
import { waitForFast } from "../../test-helpers/wait-for.ts";
import { renderMemorySharingHost } from "./memory-sharing-host.ts";
type Request = (method: string, params: Record<string, unknown>) => Promise<unknown>;
const SHARING_METHODS = [
"memory.sharing.status",
"memory.sharing.projection.target.register",
"memory.sharing.projection.preview",
"memory.sharing.projection.create",
"memory.sharing.projection.refresh",
"memory.sharing.projection.revoke",
"memory.sharing.projection.impact",
"memory.sharing.postbox.mode.set",
"memory.sharing.postbox.inspect",
"memory.sharing.postbox.review",
"memory.sharing.postbox.purge",
] as const;
type SharingElement = HTMLElement & {
client: { request: Request } | null;
connected: boolean;
canAdmin: boolean;
methodsAvailable: boolean;
agentId: string | null;
updateComplete: Promise<unknown>;
};
function findButton(element: HTMLElement, text: string): HTMLButtonElement {
const button = [...element.querySelectorAll<HTMLButtonElement>("button")].find(
(candidate) => candidate.textContent?.trim() === text,
);
if (!button) {
throw new Error(`button ${text} is unavailable`);
}
return button;
}
function renderSharingHost(params: {
methods: readonly string[];
scopes?: readonly string[];
request: Request;
}) {
const container = document.createElement("div");
render(
renderMemorySharingHost(
{
phase: "connected",
client: { request: params.request },
hello: {
auth: { role: "operator", scopes: params.scopes ?? ["operator.admin"] },
features: { methods: [...params.methods] },
},
} as never,
"main",
),
container,
);
const element = container.querySelector<SharingElement>("openclaw-memory-sharing");
if (!element) {
throw new Error("sharing control is unavailable");
}
document.body.append(container);
return { container, element };
}
describe("MemorySharingElement", () => {
it("stays hidden unless an admin Gateway advertises the complete sharing contract", async () => {
const request = vi.fn();
const partial = renderSharingHost({ methods: SHARING_METHODS.slice(0, -1), request });
const readOnly = renderSharingHost({
methods: SHARING_METHODS,
scopes: ["operator.read"],
request,
});
try {
await partial.element.updateComplete;
await readOnly.element.updateComplete;
expect(partial.element.textContent).toBe("");
expect(readOnly.element.textContent).toBe("");
expect(request).not.toHaveBeenCalled();
} finally {
partial.container.remove();
readOnly.container.remove();
}
});
it("uses only agent and reviewed-operation fields in postbox requests", async () => {
const request = vi.fn<Request>((method) => {
if (method === "memory.sharing.status") {
return Promise.resolve({
postboxMode: "off",
projections: [],
postboxItems: [
{
itemId: "postbox-1",
state: "postbox",
sourceChannelRef: "telegram:alice",
createdAt: 1,
},
],
});
}
if (method === "memory.sharing.postbox.inspect") {
return Promise.resolve({ itemId: "postbox-1", content: "sender observation" });
}
return Promise.resolve({ itemId: "postbox-1" });
});
const { container, element } = renderSharingHost({ methods: SHARING_METHODS, request });
try {
await waitForFast(() => expect(element.textContent).toContain("telegram:alice"));
expect(request).toHaveBeenCalledWith("memory.sharing.status", { agentId: "main" });
request.mockClear();
findButton(element, "Inspect").click();
await waitForFast(() =>
expect(request).toHaveBeenCalledWith("memory.sharing.postbox.inspect", {
agentId: "main",
itemId: "postbox-1",
}),
);
const reviewTextarea = () =>
[...element.querySelectorAll<HTMLTextAreaElement>("textarea")].at(-1);
await waitForFast(() => expect(reviewTextarea()?.value).toBe("sender observation"));
const textarea = reviewTextarea();
if (!textarea) {
throw new Error("review textarea is unavailable");
}
textarea.value = "owner-edited copy";
textarea.dispatchEvent(new Event("input", { bubbles: true }));
request.mockClear();
findButton(element, "Approve").click();
await waitForFast(() =>
expect(request).toHaveBeenCalledWith("memory.sharing.postbox.review", {
agentId: "main",
itemId: "postbox-1",
decision: "approve",
reviewedContent: "owner-edited copy",
}),
);
expect(request.mock.calls.every(([, payload]) => !("principalId" in payload))).toBe(true);
expect(request.mock.calls.every(([, payload]) => !("storeId" in payload))).toBe(true);
} finally {
container.remove();
}
});
it("renders prior projection exposure without accepting a caller-selected audience", async () => {
const request = vi.fn<Request>((method) => {
if (method === "memory.sharing.status") {
return Promise.resolve({
postboxMode: "off",
postboxItems: [],
projections: [
{
projectionId: "projection-1",
purpose: "handoff",
preview: "reviewed note",
state: "active",
target: { kind: "role", id: "support" },
expiresAt: null,
},
],
});
}
if (method === "memory.sharing.projection.impact") {
return Promise.resolve({ exposureSetIds: ["exposure-1", "exposure-2"] });
}
return Promise.resolve({});
});
const { container, element } = renderSharingHost({ methods: SHARING_METHODS, request });
try {
await waitForFast(() => expect(element.textContent).toContain("handoff"));
request.mockClear();
findButton(element, "Prior exposure impact").click();
await waitForFast(() =>
expect(request).toHaveBeenCalledWith("memory.sharing.projection.impact", {
agentId: "main",
projectionId: "projection-1",
}),
);
await waitForFast(() => expect(element.textContent).toContain("2 prior exposure records"));
expect(request.mock.calls.every(([, payload]) => !("audience" in payload))).toBe(true);
} finally {
container.remove();
}
});
it("renders no private-user projection target input", async () => {
const request = vi.fn<Request>((method) =>
Promise.resolve(
method === "memory.sharing.status"
? { postboxMode: "off", projections: [], postboxItems: [] }
: {},
),
);
const { container, element } = renderSharingHost({ methods: SHARING_METHODS, request });
try {
await waitForFast(() => expect(element.querySelector("select")).not.toBeNull());
expect(
[...element.querySelectorAll<HTMLSelectElement>("select")]
.flatMap((select) => [...select.options].map((option) => option.value)),
).toEqual(expect.arrayContaining(["conversation", "role", "agent-shared"]));
expect(element.querySelectorAll('option[value="user"]')).toHaveLength(0);
expect(element.textContent).not.toContain("private-user");
} finally {
container.remove();
}
});
});
+644
View File
@@ -0,0 +1,644 @@
import { isRecord } from "@openclaw/normalization-core/record-coerce";
import { html, nothing, type PropertyValues } from "lit";
import { property, state } from "lit/decorators.js";
import type { GatewayBrowserClient } from "../../api/gateway.ts";
import {
renderSettingsRow,
renderSettingsSection,
renderSettingsValue,
} from "../../components/settings-ui.ts";
import { t } from "../../i18n/index.ts";
import { OpenClawLightDomElement } from "../../lit/openclaw-element.ts";
type ProjectionTarget = Readonly<{
kind: "conversation" | "role" | "agent-shared";
id: string;
}>;
type SharingStatus = Readonly<{
postboxMode: "off" | "review-required";
projections: readonly Readonly<{
projectionId: string;
target: ProjectionTarget;
purpose: string;
preview: string;
state: string;
expiresAt: number | null;
}>[];
postboxItems: readonly Readonly<{
itemId: string;
state: string;
sourceChannelRef: string;
createdAt: number;
}>[];
}>;
type ProjectionForm = {
projectionId: string;
sourceRevisionId: string;
targetKind: ProjectionTarget["kind"];
targetId: string;
targetStoreId: string;
purpose: string;
preview: string;
content: string;
expiresAt: string;
noExpiryAuditReason: string;
};
function asText(value: unknown): string | null {
return typeof value === "string" && value.trim() ? value.trim() : null;
}
function parseTarget(value: unknown): ProjectionTarget | null {
if (!isRecord(value)) {
return null;
}
const kind = value.kind;
const id = asText(value.id);
return (kind === "conversation" || kind === "role" || kind === "agent-shared") && id
? { kind, id }
: null;
}
function isProjectionTargetKind(value: string): value is ProjectionTarget["kind"] {
return value === "conversation" || value === "role" || value === "agent-shared";
}
function parseStatus(value: unknown): SharingStatus | null {
if (
!isRecord(value) ||
(value.postboxMode !== "off" && value.postboxMode !== "review-required")
) {
return null;
}
const projections = Array.isArray(value.projections)
? value.projections.flatMap((entry) => {
if (!isRecord(entry)) {
return [];
}
const projectionId = asText(entry.projectionId);
const target = parseTarget(entry.target);
const purpose = asText(entry.purpose);
const preview = asText(entry.preview);
const state = asText(entry.state);
const expiresAt = entry.expiresAt;
return projectionId &&
target &&
purpose &&
preview &&
state &&
(expiresAt === null || typeof expiresAt === "number")
? [{ projectionId, target, purpose, preview, state, expiresAt }]
: [];
})
: [];
const postboxItems = Array.isArray(value.postboxItems)
? value.postboxItems.flatMap((entry) => {
if (!isRecord(entry)) {
return [];
}
const itemId = asText(entry.itemId);
const state = asText(entry.state);
const sourceChannelRef = asText(entry.sourceChannelRef);
return itemId && state && sourceChannelRef && typeof entry.createdAt === "number"
? [{ itemId, state, sourceChannelRef, createdAt: entry.createdAt }]
: [];
})
: [];
return { postboxMode: value.postboxMode, projections, postboxItems };
}
function emptyProjectionForm(): ProjectionForm {
return {
projectionId: "",
sourceRevisionId: "",
targetKind: "conversation",
targetId: "",
targetStoreId: "",
purpose: "",
preview: "",
content: "",
expiresAt: "",
noExpiryAuditReason: "",
};
}
/** Profile-derived sharing controls. This element never accepts or renders a principal or store id. */
class MemorySharingElement extends OpenClawLightDomElement {
@property({ attribute: false }) client: GatewayBrowserClient | null = null;
@property({ type: Boolean }) connected = false;
@property({ type: Boolean }) canAdmin = false;
@property({ type: Boolean }) methodsAvailable = false;
@property() agentId: string | null = null;
@state() private status: SharingStatus | null = null;
@state() private form = emptyProjectionForm();
@state() private inspectedBodies = new Map<string, string>();
@state() private impact = new Map<string, readonly string[]>();
@state() private previewReady = false;
@state() private busy = false;
@state() private error: string | null = null;
private loadGeneration = 0;
protected override willUpdate(changed: PropertyValues<this>) {
if (
changed.has("client") ||
changed.has("connected") ||
changed.has("canAdmin") ||
changed.has("methodsAvailable") ||
changed.has("agentId")
) {
this.status = null;
this.inspectedBodies = new Map();
this.impact = new Map();
this.previewReady = false;
if (changed.has("agentId")) {
this.form = emptyProjectionForm();
}
void this.load();
}
}
private canUse(): this is this & { client: GatewayBrowserClient; agentId: string } {
return Boolean(
this.connected && this.canAdmin && this.methodsAvailable && this.client && this.agentId,
);
}
private async load() {
if (!this.canUse()) {
return;
}
const generation = ++this.loadGeneration;
try {
const response = await this.client.request("memory.sharing.status", {
agentId: this.agentId,
});
if (!this.canUse() || generation !== this.loadGeneration) {
return;
}
const status = parseStatus(response);
if (!status) {
throw new Error("invalid sharing status");
}
this.status = status;
} catch {
if (generation === this.loadGeneration) {
this.error = t("memoryPage.sharing.requestFailed");
}
}
}
private async request(method: string, payload: Record<string, unknown>): Promise<unknown | null> {
if (!this.canUse() || this.busy) {
return null;
}
this.busy = true;
this.error = null;
try {
return await this.client.request(method, { agentId: this.agentId, ...payload });
} catch {
this.error = t("memoryPage.sharing.requestFailed");
return null;
} finally {
this.busy = false;
}
}
private updateForm(key: keyof ProjectionForm, value: string) {
this.form = { ...this.form, [key]: value };
this.previewReady = false;
}
private projectionPayload(options: {
content: boolean;
refresh: boolean;
}): Record<string, unknown> | null {
const form = this.form;
const sourceRevisionId = form.sourceRevisionId.trim();
const purpose = form.purpose.trim();
const preview = form.preview.trim();
const expiry = form.expiresAt.trim();
const noExpiryAuditReason = form.noExpiryAuditReason.trim();
if (
!sourceRevisionId ||
!purpose ||
!preview ||
Boolean(expiry) === Boolean(noExpiryAuditReason) ||
(options.content && !form.content.trim()) ||
(options.refresh && !form.projectionId.trim())
) {
this.error = t("memoryPage.sharing.completeRequiredFields");
return null;
}
if (!options.refresh && !form.targetId.trim()) {
this.error = t("memoryPage.sharing.completeRequiredFields");
return null;
}
if (!isProjectionTargetKind(form.targetKind)) {
this.error = t("memoryPage.sharing.completeRequiredFields");
return null;
}
if (form.targetKind === "agent-shared" && form.targetId.trim() !== this.agentId) {
this.error = t("memoryPage.sharing.invalidAgentSharedTarget");
return null;
}
return {
sourceRevisionId,
purpose,
preview,
...(options.refresh
? { projectionId: form.projectionId.trim() }
: { targetKind: form.targetKind, targetId: form.targetId.trim() }),
...(options.content ? { content: form.content.trim() } : {}),
...(expiry ? { expiresAt: expiry } : { noExpiryAuditReason }),
};
}
private async previewProjection() {
const payload = this.projectionPayload({ content: false, refresh: false });
if (!payload) {
return;
}
const response = await this.request("memory.sharing.projection.preview", payload);
if (response !== null) {
this.previewReady = true;
}
}
private async registerProjectionTarget() {
const targetId = this.form.targetId.trim();
const storeId = this.form.targetStoreId.trim();
if (!targetId || !storeId) {
this.error = t("memoryPage.sharing.completeRequiredFields");
return;
}
if (!isProjectionTargetKind(this.form.targetKind)) {
this.error = t("memoryPage.sharing.completeRequiredFields");
return;
}
if (this.form.targetKind === "agent-shared" && targetId !== this.agentId) {
this.error = t("memoryPage.sharing.invalidAgentSharedTarget");
return;
}
await this.request("memory.sharing.projection.target.register", {
targetKind: this.form.targetKind,
targetId,
storeId,
});
}
private async saveProjection() {
const refreshing = Boolean(this.form.projectionId.trim());
if (!this.previewReady && !refreshing) {
this.error = t("memoryPage.sharing.previewRequired");
return;
}
const payload = this.projectionPayload({ content: true, refresh: refreshing });
if (!payload) {
return;
}
const response = await this.request(
refreshing ? "memory.sharing.projection.refresh" : "memory.sharing.projection.create",
payload,
);
if (response !== null) {
this.form = emptyProjectionForm();
this.previewReady = false;
await this.load();
}
}
private async revokeProjection(projectionId: string) {
const response = await this.request("memory.sharing.projection.revoke", { projectionId });
if (response !== null) {
await this.load();
}
}
private prepareRefresh(projection: SharingStatus["projections"][number]) {
this.form = {
...emptyProjectionForm(),
projectionId: projection.projectionId,
purpose: projection.purpose,
preview: projection.preview,
};
this.previewReady = false;
}
private async loadImpact(projectionId: string) {
const response = await this.request("memory.sharing.projection.impact", { projectionId });
if (!isRecord(response) || !Array.isArray(response.exposureSetIds)) {
return;
}
const exposureSetIds = response.exposureSetIds.filter(
(entry): entry is string => typeof entry === "string",
);
this.impact = new Map(this.impact).set(projectionId, exposureSetIds);
}
private async setPostboxMode(mode: "off" | "review-required") {
const response = await this.request("memory.sharing.postbox.mode.set", { mode });
if (response !== null) {
await this.load();
}
}
private async inspectPostbox(itemId: string) {
const response = await this.request("memory.sharing.postbox.inspect", { itemId });
if (!isRecord(response) || typeof response.content !== "string") {
return;
}
this.inspectedBodies = new Map(this.inspectedBodies).set(itemId, response.content);
}
private async reviewPostbox(itemId: string, decision: "approve" | "reject") {
const reviewedContent = this.inspectedBodies.get(itemId)?.trim();
const response = await this.request("memory.sharing.postbox.review", {
itemId,
decision,
...(decision === "approve" && reviewedContent ? { reviewedContent } : {}),
});
if (response !== null) {
this.inspectedBodies = new Map(this.inspectedBodies);
this.inspectedBodies.delete(itemId);
await this.load();
}
}
private async purgePostbox(itemId: string) {
const response = await this.request("memory.sharing.postbox.purge", { itemId });
if (response !== null) {
this.inspectedBodies = new Map(this.inspectedBodies);
this.inspectedBodies.delete(itemId);
await this.load();
}
}
private renderProjectionForm() {
const form = this.form;
const refresh = Boolean(form.projectionId);
return renderSettingsSection(
{
title: t("memoryPage.sharing.projection.title"),
description: t("memoryPage.sharing.projection.description"),
},
html`
<div class="settings-form-grid">
<label
>${t("memoryPage.sharing.projection.id")}<input
.value=${form.projectionId}
@input=${(event: Event) =>
this.updateForm("projectionId", (event.target as HTMLInputElement).value)}
/></label>
<label
>${t("memoryPage.sharing.projection.sourceRevision")}<input
.value=${form.sourceRevisionId}
@input=${(event: Event) =>
this.updateForm("sourceRevisionId", (event.target as HTMLInputElement).value)}
/></label>
${refresh
? nothing
: html`
<label
>${t("memoryPage.sharing.projection.targetKind")}
<select
.value=${form.targetKind}
@change=${(event: Event) =>
this.updateForm("targetKind", (event.target as HTMLSelectElement).value)}
>
<option value="conversation">
${t("memoryPage.sharing.targets.conversation")}
</option>
<option value="role">${t("memoryPage.sharing.targets.role")}</option>
<option value="agent-shared">
${t("memoryPage.sharing.targets.agentShared")}
</option>
</select>
</label>
<label
>${t("memoryPage.sharing.projection.targetId")}<input
.value=${form.targetId}
@input=${(event: Event) =>
this.updateForm("targetId", (event.target as HTMLInputElement).value)}
/></label>
<label
>${t("memoryPage.sharing.projection.targetStoreId")}<input
.value=${form.targetStoreId}
@input=${(event: Event) =>
this.updateForm("targetStoreId", (event.target as HTMLInputElement).value)}
/></label>
`}
<label
>${t("memoryPage.sharing.projection.purpose")}<input
.value=${form.purpose}
@input=${(event: Event) =>
this.updateForm("purpose", (event.target as HTMLInputElement).value)}
/></label>
<label
>${t("memoryPage.sharing.projection.preview")}<input
.value=${form.preview}
@input=${(event: Event) =>
this.updateForm("preview", (event.target as HTMLInputElement).value)}
/></label>
<label
>${t("memoryPage.sharing.projection.expiry")}<input
type="datetime-local"
.value=${form.expiresAt}
@input=${(event: Event) =>
this.updateForm("expiresAt", (event.target as HTMLInputElement).value)}
/></label>
<label
>${t("memoryPage.sharing.projection.noExpiryReason")}<input
.value=${form.noExpiryAuditReason}
@input=${(event: Event) =>
this.updateForm("noExpiryAuditReason", (event.target as HTMLInputElement).value)}
/></label>
</div>
<label
>${t("memoryPage.sharing.projection.content")}<textarea
.value=${form.content}
@input=${(event: Event) =>
this.updateForm("content", (event.target as HTMLTextAreaElement).value)}
></textarea>
</label>
<p>
${refresh
? nothing
: html`<button
class="btn btn--sm"
?disabled=${this.busy}
@click=${() => void this.registerProjectionTarget()}
>
${t("memoryPage.sharing.projection.registerTarget")}
</button>
<button
class="btn btn--sm"
?disabled=${this.busy}
@click=${() => void this.previewProjection()}
>
${t("memoryPage.sharing.projection.previewAction")}
</button>`}
<button
class="btn btn--sm"
?disabled=${this.busy}
@click=${() => void this.saveProjection()}
>
${refresh
? t("memoryPage.sharing.projection.refresh")
: t("memoryPage.sharing.projection.create")}
</button>
</p>
`,
);
}
override render() {
if (!this.canUse()) {
return nothing;
}
const status = this.status;
return html`
<section class="settings-page" aria-label=${t("memoryPage.sharing.title")}>
<h2>${t("memoryPage.sharing.title")}</h2>
<p class="settings-page__intro">${t("memoryPage.sharing.intro")}</p>
${this.error ? html`<p role="alert">${this.error}</p>` : nothing}
${renderSettingsSection(
{ title: t("memoryPage.sharing.statusTitle") },
html`
${renderSettingsRow({
title: t("memoryPage.sharing.postboxMode"),
control: html`<select
.value=${status?.postboxMode ?? "off"}
?disabled=${this.busy}
@change=${(event: Event) =>
void this.setPostboxMode(
(event.target as HTMLSelectElement).value as "off" | "review-required",
)}
>
<option value="off">${t("memoryPage.sharing.postboxOff")}</option>
<option value="review-required">
${t("memoryPage.sharing.postboxReviewRequired")}
</option>
</select>`,
})}
${renderSettingsRow({
title: t("memoryPage.sharing.projectionCount"),
control: renderSettingsValue(String(status?.projections.length ?? 0)),
})}
${renderSettingsRow({
title: t("memoryPage.sharing.postboxCount"),
control: renderSettingsValue(String(status?.postboxItems.length ?? 0)),
})}
`,
)}
${this.renderProjectionForm()}
${renderSettingsSection(
{ title: t("memoryPage.sharing.projections") },
status?.projections.length
? status.projections.map(
(projection) => html`
${renderSettingsRow({
title: projection.purpose,
description: `${projection.target.kind}: ${projection.target.id} · ${projection.preview}`,
control: renderSettingsValue(projection.state),
})}
<p>
<button
class="btn btn--sm"
?disabled=${this.busy || projection.state !== "active"}
@click=${() => this.prepareRefresh(projection)}
>
${t("memoryPage.sharing.projection.refresh")}
</button>
<button
class="btn btn--sm"
?disabled=${this.busy}
@click=${() => this.loadImpact(projection.projectionId)}
>
${t("memoryPage.sharing.impact")}
</button>
<button
class="btn btn--sm btn--danger"
?disabled=${this.busy || projection.state !== "active"}
@click=${() => void this.revokeProjection(projection.projectionId)}
>
${t("memoryPage.sharing.revoke")}
</button>
</p>
${(this.impact.get(projection.projectionId) ?? []).length
? html`<p>
${t("memoryPage.sharing.priorExposure", {
count: String(this.impact.get(projection.projectionId)?.length ?? 0),
})}
</p>`
: nothing}
`,
)
: renderSettingsRow({ title: t("memoryPage.sharing.emptyProjections") }),
)}
${renderSettingsSection(
{ title: t("memoryPage.sharing.postbox") },
status?.postboxItems.length
? status.postboxItems.map(
(item) => html`
${renderSettingsRow({
title: item.sourceChannelRef,
description: item.state,
control: renderSettingsValue(item.itemId, { mono: true }),
})}
${this.inspectedBodies.has(item.itemId)
? html`<textarea
.value=${this.inspectedBodies.get(item.itemId) ?? ""}
@input=${(event: Event) => {
this.inspectedBodies = new Map(this.inspectedBodies).set(
item.itemId,
(event.target as HTMLTextAreaElement).value,
);
}}
></textarea>`
: nothing}
<p>
<button
class="btn btn--sm"
?disabled=${this.busy || item.state !== "postbox"}
@click=${() => void this.inspectPostbox(item.itemId)}
>
${t("memoryPage.sharing.inspect")}
</button>
<button
class="btn btn--sm"
?disabled=${this.busy || item.state !== "postbox"}
@click=${() => void this.reviewPostbox(item.itemId, "approve")}
>
${t("memoryPage.sharing.approve")}
</button>
<button
class="btn btn--sm"
?disabled=${this.busy || item.state !== "postbox"}
@click=${() => void this.reviewPostbox(item.itemId, "reject")}
>
${t("memoryPage.sharing.reject")}
</button>
<button
class="btn btn--sm btn--danger"
?disabled=${this.busy}
@click=${() => void this.purgePostbox(item.itemId)}
>
${t("memoryPage.sharing.purge")}
</button>
</p>
`,
)
: renderSettingsRow({ title: t("memoryPage.sharing.emptyPostbox") }),
)}
</section>
`;
}
}
if (!customElements.get("openclaw-memory-sharing")) {
customElements.define("openclaw-memory-sharing", MemorySharingElement);
}
+1
View File
@@ -57,6 +57,7 @@ function createProps(overrides: Partial<MemoryViewProps> = {}): MemoryViewProps
dreams: html`<div class="test-dreams"></div>`,
editor: html`<div class="test-editor"></div>`,
dreamingSettings: html`<div class="test-dreaming-settings"></div>`,
sharing: html`<div class="test-sharing"></div>`,
agentId: "main",
agents: [
{ value: "main", label: "Main" },
+3 -1
View File
@@ -180,6 +180,8 @@ type MemoryViewProps = {
editor: TemplateResult;
/** Global dreaming controls, sharing runtimeConfig with the editor above. */
dreamingSettings: TemplateResult;
/** Authenticated, profile-derived projection and postbox controls. */
sharing: TemplateResult;
agentId: string | null;
agents: readonly AgentSelectOption[];
onAgentChange: (agentId: string | null) => void;
@@ -378,7 +380,7 @@ function renderSettingsTab(props: MemoryViewProps) {
</div>
${props.editor}
<div class="settings-page">
${props.dreamingSettings}
${props.dreamingSettings} ${props.sharing}
${renderSettingsSection(
{ title: t("memoryPage.import.title"), description: t("memoryPage.import.description") },
renderSettingsRow({