diff --git a/docs/.generated/plugin-sdk-api-baseline.json b/docs/.generated/plugin-sdk-api-baseline.json index 1d020ab4e4a..396bed37eae 100644 --- a/docs/.generated/plugin-sdk-api-baseline.json +++ b/docs/.generated/plugin-sdk-api-baseline.json @@ -154,7 +154,7 @@ "exportName": "ChannelMessageActionAdapter", "kind": "type", "source": { - "line": 529, + "line": 551, "path": "src/channels/plugins/types.core.ts" } }, @@ -163,7 +163,7 @@ "exportName": "ChannelMessageActionContext", "kind": "type", "source": { - "line": 493, + "line": 515, "path": "src/channels/plugins/types.core.ts" } }, @@ -1170,7 +1170,7 @@ "exportName": "BaseProbeResult", "kind": "type", "source": { - "line": 572, + "line": 594, "path": "src/channels/plugins/types.core.ts" } }, @@ -1179,7 +1179,7 @@ "exportName": "BaseTokenResolution", "kind": "type", "source": { - "line": 578, + "line": 600, "path": "src/channels/plugins/types.core.ts" } }, @@ -1224,7 +1224,7 @@ "exportName": "ChannelMessageActionAdapter", "kind": "type", "source": { - "line": 529, + "line": 551, "path": "src/channels/plugins/types.core.ts" } }, @@ -1233,7 +1233,7 @@ "exportName": "ChannelMessageActionContext", "kind": "type", "source": { - "line": 493, + "line": 515, "path": "src/channels/plugins/types.core.ts" } }, @@ -1752,7 +1752,7 @@ "exportName": "BaseProbeResult", "kind": "type", "source": { - "line": 572, + "line": 594, "path": "src/channels/plugins/types.core.ts" } }, @@ -1761,7 +1761,7 @@ "exportName": "BaseTokenResolution", "kind": "type", "source": { - "line": 578, + "line": 600, "path": "src/channels/plugins/types.core.ts" } }, @@ -1797,7 +1797,7 @@ "exportName": "ChannelAgentPromptAdapter", "kind": "type", "source": { - "line": 466, + "line": 488, "path": "src/channels/plugins/types.core.ts" } }, @@ -1977,7 +1977,7 @@ "exportName": "ChannelDirectoryEntry", "kind": "type", "source": { - "line": 480, + "line": 502, "path": "src/channels/plugins/types.core.ts" } }, @@ -1986,7 +1986,7 @@ "exportName": "ChannelDirectoryEntryKind", "kind": "type", "source": { - "line": 478, + "line": 500, "path": "src/channels/plugins/types.core.ts" } }, @@ -2130,7 +2130,7 @@ "exportName": "ChannelMessageActionAdapter", "kind": "type", "source": { - "line": 529, + "line": 551, "path": "src/channels/plugins/types.core.ts" } }, @@ -2139,7 +2139,7 @@ "exportName": "ChannelMessageActionContext", "kind": "type", "source": { - "line": 493, + "line": 515, "path": "src/channels/plugins/types.core.ts" } }, @@ -2274,7 +2274,7 @@ "exportName": "ChannelPollContext", "kind": "type", "source": { - "line": 560, + "line": 582, "path": "src/channels/plugins/types.core.ts" } }, @@ -2283,7 +2283,7 @@ "exportName": "ChannelPollResult", "kind": "type", "source": { - "line": 551, + "line": 573, "path": "src/channels/plugins/types.core.ts" } }, @@ -2427,7 +2427,7 @@ "exportName": "ChannelToolSend", "kind": "type", "source": { - "line": 522, + "line": 544, "path": "src/channels/plugins/types.core.ts" } }, @@ -2683,7 +2683,7 @@ "exportName": "buildCommandsMessage", "kind": "function", "source": { - "line": 1075, + "line": 1076, "path": "src/auto-reply/status.ts" } }, @@ -2692,7 +2692,7 @@ "exportName": "buildCommandsMessagePaginated", "kind": "function", "source": { - "line": 1084, + "line": 1085, "path": "src/auto-reply/status.ts" } }, @@ -2728,7 +2728,7 @@ "exportName": "buildHelpMessage", "kind": "function", "source": { - "line": 870, + "line": 871, "path": "src/auto-reply/status.ts" } }, @@ -3738,7 +3738,7 @@ "exportName": "ChannelMessageActionContext", "kind": "type", "source": { - "line": 493, + "line": 515, "path": "src/channels/plugins/types.core.ts" } }, diff --git a/docs/.generated/plugin-sdk-api-baseline.jsonl b/docs/.generated/plugin-sdk-api-baseline.jsonl index 814f47c7ff1..19ca3e07316 100644 --- a/docs/.generated/plugin-sdk-api-baseline.jsonl +++ b/docs/.generated/plugin-sdk-api-baseline.jsonl @@ -15,8 +15,8 @@ {"declaration":"export type ChannelConfiguredBindingProvider = ChannelConfiguredBindingProvider;","entrypoint":"index","exportName":"ChannelConfiguredBindingProvider","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":674,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelGatewayContext = ChannelGatewayContext;","entrypoint":"index","exportName":"ChannelGatewayContext","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":271,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelId = ChannelId;","entrypoint":"index","exportName":"ChannelId","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":14,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelMessageActionAdapter = ChannelMessageActionAdapter;","entrypoint":"index","exportName":"ChannelMessageActionAdapter","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":529,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"index","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":493,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelMessageActionAdapter = ChannelMessageActionAdapter;","entrypoint":"index","exportName":"ChannelMessageActionAdapter","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":551,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"index","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":515,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelMessageActionName = \"send\" | \"broadcast\" | \"poll\" | \"poll-vote\" | \"react\" | \"reactions\" | \"read\" | \"edit\" | \"unsend\" | \"reply\" | \"sendWithEffect\" | \"renameGroup\" | \"setGroupIcon\" | \"addParticipant\" | \"removeParticipant\" | \"leaveGroup\" | \"sendAttachment\" | \"delete\" | \"pin\" | \"unpin\" | \"list-pins\" | \"permissions\" | \"thread-create\" | \"thread-list\" | \"thread-reply\" | \"search\" | \"sticker\" | \"sticker-search\" | \"member-info\" | \"role-info\" | \"emoji-list\" | \"emoji-upload\" | \"sticker-upload\" | \"role-add\" | \"role-remove\" | \"channel-info\" | \"channel-list\" | \"channel-create\" | \"channel-edit\" | \"channel-delete\" | \"channel-move\" | \"category-create\" | \"category-edit\" | \"category-delete\" | \"topic-create\" | \"topic-edit\" | \"voice-status\" | \"event-list\" | \"event-create\" | \"timeout\" | \"kick\" | \"ban\" | \"set-profile\" | \"set-presence\" | \"download-file\" | \"upload-file\";","entrypoint":"index","exportName":"ChannelMessageActionName","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":6,"sourcePath":"src/channels/plugins/types.ts"} {"declaration":"export type ChannelPlugin = ChannelPlugin;","entrypoint":"index","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":77,"sourcePath":"src/channels/plugins/types.plugin.ts"} {"declaration":"export type ChannelSetupAdapter = ChannelSetupAdapter;","entrypoint":"index","exportName":"ChannelSetupAdapter","importSpecifier":"openclaw/plugin-sdk","kind":"type","recordType":"export","sourceLine":63,"sourcePath":"src/channels/plugins/types.adapters.ts"} @@ -127,14 +127,14 @@ {"declaration":"export const ToolPolicySchema: z.ZodOptional>; alsoAllow: z.ZodOptional>; deny: z.ZodOptional>; }, z.core.$strict>>;","entrypoint":"channel-config-schema","exportName":"ToolPolicySchema","importSpecifier":"openclaw/plugin-sdk/channel-config-schema","kind":"const","recordType":"export","sourceLine":253,"sourcePath":"src/config/zod-schema.agent-runtime.ts"} {"declaration":"export const WhatsAppConfigSchema: z.ZodObject<{ enabled: z.ZodOptional; capabilities: z.ZodOptional>; markdown: z.ZodOptional>; }, z.core.$strict>>; configWrites: z.ZodOptional; sendReadReceipts: z.ZodOptional; messagePrefix: z.ZodOptional; responsePrefix: z.ZodOptional; dmPolicy: z.ZodDefault>>; selfChatMode: z.ZodOptional; allowFrom: z.ZodOptional>; defaultTo: z.ZodOptional; groupAllowFrom: z.ZodOptional>; groupPolicy: z.ZodDefault>>; historyLimit: z.ZodOptional; dmHistoryLimit: z.ZodOptional; dms: z.ZodOptional; }, z.core.$strict>>>>; textChunkLimit: z.ZodOptional; chunkMode: z.ZodOptional>; blockStreaming: z.ZodOptional; blockStreamingCoalesce: z.ZodOptional; maxChars: z.ZodOptional; idleMs: z.ZodOptional; }, z.core.$strict>>; groups: z.ZodOptional; tools: z.ZodOptional>; alsoAllow: z.ZodOptional>; deny: z.ZodOptional>; }, z.core.$strict>>; toolsBySender: z.ZodOptional>; alsoAllow: z.ZodOptional>; deny: z.ZodOptional>; }, z.core.$strict>>>>; }, z.core.$strict>>>>; ackReaction: z.ZodOptional; direct: z.ZodDefault>; group: z.ZodDefault>>; }, z.core.$strict>>; debounceMs: z.ZodDefault>; heartbeat: z.ZodOptional; showAlerts: z.ZodOptional; useIndicator: z.ZodOptional; }, z.core.$strict>>; healthMonitor: z.ZodOptional; }, z.core.$strict>>; accounts: z.ZodOptional>; markdown: z.ZodOptional>; }, z.core.$strict>>; configWrites: z.ZodOptional; sendReadReceipts: z.ZodOptional; messagePrefix: z.ZodOptional; responsePrefix: z.ZodOptional; dmPolicy: z.ZodDefault>>; selfChatMode: z.ZodOptional; allowFrom: z.ZodOptional>; defaultTo: z.ZodOptional; groupAllowFrom: z.ZodOptional>; groupPolicy: z.ZodDefault>>; historyLimit: z.ZodOptional; dmHistoryLimit: z.ZodOptional; dms: z.ZodOptional; }, z.core.$strict>>>>; textChunkLimit: z.ZodOptional; chunkMode: z.ZodOptional>; blockStreaming: z.ZodOptional; blockStreamingCoalesce: z.ZodOptional; maxChars: z.ZodOptional; idleMs: z.ZodOptional; }, z.core.$strict>>; groups: z.ZodOptional; tools: z.ZodOptional>; alsoAllow: z.ZodOptional>; deny: z.ZodOptional>; }, z.core.$strict>>; toolsBySender: z.ZodOptional>; alsoAllow: z.ZodOptional>; deny: z.ZodOptional>; }, z.core.$strict>>>>; }, z.core.$strict>>>>; ackReaction: z.ZodOptional; direct: z.ZodDefault>; group: z.ZodDefault>>; }, z.core.$strict>>; debounceMs: z.ZodDefault>; heartbeat: z.ZodOptional; showAlerts: z.ZodOptional; useIndicator: z.ZodOptional; }, z.core.$strict>>; healthMonitor: z.ZodOptional; }, z.core.$strict>>; name: z.ZodOptional; enabled: z.ZodOptional; authDir: z.ZodOptional; mediaMaxMb: z.ZodOptional; }, z.core.$strict>>>>; defaultAccount: z.ZodOptional; mediaMaxMb: z.ZodDefault>; actions: z.ZodOptional; sendMessage: z.ZodOptional; polls: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>;","entrypoint":"channel-config-schema","exportName":"WhatsAppConfigSchema","importSpecifier":"openclaw/plugin-sdk/channel-config-schema","kind":"const","recordType":"export","sourceLine":119,"sourcePath":"src/config/zod-schema.providers-whatsapp.ts"} {"category":"channel","entrypoint":"channel-contract","importSpecifier":"openclaw/plugin-sdk/channel-contract","recordType":"module","sourceLine":1,"sourcePath":"src/plugin-sdk/channel-contract.ts"} -{"declaration":"export type BaseProbeResult = BaseProbeResult;","entrypoint":"channel-contract","exportName":"BaseProbeResult","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":572,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type BaseTokenResolution = BaseTokenResolution;","entrypoint":"channel-contract","exportName":"BaseTokenResolution","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":578,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type BaseProbeResult = BaseProbeResult;","entrypoint":"channel-contract","exportName":"BaseProbeResult","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":594,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type BaseTokenResolution = BaseTokenResolution;","entrypoint":"channel-contract","exportName":"BaseTokenResolution","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":600,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelAccountSnapshot = ChannelAccountSnapshot;","entrypoint":"channel-contract","exportName":"ChannelAccountSnapshot","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":147,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelAgentTool = ChannelAgentTool;","entrypoint":"channel-contract","exportName":"ChannelAgentTool","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":19,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelCommandConversationContext = ChannelCommandConversationContext;","entrypoint":"channel-contract","exportName":"ChannelCommandConversationContext","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":662,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelGroupContext = ChannelGroupContext;","entrypoint":"channel-contract","exportName":"ChannelGroupContext","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":219,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelMessageActionAdapter = ChannelMessageActionAdapter;","entrypoint":"channel-contract","exportName":"ChannelMessageActionAdapter","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":529,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"channel-contract","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":493,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelMessageActionAdapter = ChannelMessageActionAdapter;","entrypoint":"channel-contract","exportName":"ChannelMessageActionAdapter","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":551,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"channel-contract","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":515,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelMessageActionDiscoveryContext = ChannelMessageActionDiscoveryContext;","entrypoint":"channel-contract","exportName":"ChannelMessageActionDiscoveryContext","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":32,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelMessageActionName = \"send\" | \"broadcast\" | \"poll\" | \"poll-vote\" | \"react\" | \"reactions\" | \"read\" | \"edit\" | \"unsend\" | \"reply\" | \"sendWithEffect\" | \"renameGroup\" | \"setGroupIcon\" | \"addParticipant\" | \"removeParticipant\" | \"leaveGroup\" | \"sendAttachment\" | \"delete\" | \"pin\" | \"unpin\" | \"list-pins\" | \"permissions\" | \"thread-create\" | \"thread-list\" | \"thread-reply\" | \"search\" | \"sticker\" | \"sticker-search\" | \"member-info\" | \"role-info\" | \"emoji-list\" | \"emoji-upload\" | \"sticker-upload\" | \"role-add\" | \"role-remove\" | \"channel-info\" | \"channel-list\" | \"channel-create\" | \"channel-edit\" | \"channel-delete\" | \"channel-move\" | \"category-create\" | \"category-edit\" | \"category-delete\" | \"topic-create\" | \"topic-edit\" | \"voice-status\" | \"event-list\" | \"event-create\" | \"timeout\" | \"kick\" | \"ban\" | \"set-profile\" | \"set-presence\" | \"download-file\" | \"upload-file\";","entrypoint":"channel-contract","exportName":"ChannelMessageActionName","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":6,"sourcePath":"src/channels/plugins/types.ts"} {"declaration":"export type ChannelMessageToolDiscovery = ChannelMessageToolDiscovery;","entrypoint":"channel-contract","exportName":"ChannelMessageToolDiscovery","importSpecifier":"openclaw/plugin-sdk/channel-contract","kind":"type","recordType":"export","sourceLine":57,"sourcePath":"src/channels/plugins/types.core.ts"} @@ -191,12 +191,12 @@ {"declaration":"export const isWhatsAppGroupJid: (value: string) => boolean;","entrypoint":"channel-runtime","exportName":"isWhatsAppGroupJid","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"const","recordType":"export","sourceLine":13,"sourcePath":"src/plugin-sdk/whatsapp-targets.ts"} {"declaration":"export const isWhatsAppUserTarget: (value: string) => boolean;","entrypoint":"channel-runtime","exportName":"isWhatsAppUserTarget","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"const","recordType":"export","sourceLine":15,"sourcePath":"src/plugin-sdk/whatsapp-targets.ts"} {"declaration":"export const normalizeWhatsAppTarget: (value: string) => string | null;","entrypoint":"channel-runtime","exportName":"normalizeWhatsAppTarget","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"const","recordType":"export","sourceLine":17,"sourcePath":"src/plugin-sdk/whatsapp-targets.ts"} -{"declaration":"export type BaseProbeResult = BaseProbeResult;","entrypoint":"channel-runtime","exportName":"BaseProbeResult","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":572,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type BaseTokenResolution = BaseTokenResolution;","entrypoint":"channel-runtime","exportName":"BaseTokenResolution","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":578,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type BaseProbeResult = BaseProbeResult;","entrypoint":"channel-runtime","exportName":"BaseProbeResult","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":594,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type BaseTokenResolution = BaseTokenResolution;","entrypoint":"channel-runtime","exportName":"BaseTokenResolution","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":600,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelAccountSnapshot = ChannelAccountSnapshot;","entrypoint":"channel-runtime","exportName":"ChannelAccountSnapshot","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":147,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelAccountState = ChannelAccountState;","entrypoint":"channel-runtime","exportName":"ChannelAccountState","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":110,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelActionAvailabilityState = ChannelActionAvailabilityState;","entrypoint":"channel-runtime","exportName":"ChannelActionAvailabilityState","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":32,"sourcePath":"src/channels/plugins/types.adapters.ts"} -{"declaration":"export type ChannelAgentPromptAdapter = ChannelAgentPromptAdapter;","entrypoint":"channel-runtime","exportName":"ChannelAgentPromptAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":466,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelAgentPromptAdapter = ChannelAgentPromptAdapter;","entrypoint":"channel-runtime","exportName":"ChannelAgentPromptAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":488,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelAgentTool = ChannelAgentTool;","entrypoint":"channel-runtime","exportName":"ChannelAgentTool","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":19,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelAgentToolFactory = ChannelAgentToolFactory;","entrypoint":"channel-runtime","exportName":"ChannelAgentToolFactory","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":24,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelAllowlistAdapter = ChannelAllowlistAdapter;","entrypoint":"channel-runtime","exportName":"ChannelAllowlistAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":597,"sourcePath":"src/channels/plugins/types.adapters.ts"} @@ -216,8 +216,8 @@ {"declaration":"export type ChannelConfiguredBindingProvider = ChannelConfiguredBindingProvider;","entrypoint":"channel-runtime","exportName":"ChannelConfiguredBindingProvider","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":674,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelConversationBindingSupport = ChannelConversationBindingSupport;","entrypoint":"channel-runtime","exportName":"ChannelConversationBindingSupport","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":690,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelDirectoryAdapter = ChannelDirectoryAdapter;","entrypoint":"channel-runtime","exportName":"ChannelDirectoryAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":454,"sourcePath":"src/channels/plugins/types.adapters.ts"} -{"declaration":"export type ChannelDirectoryEntry = ChannelDirectoryEntry;","entrypoint":"channel-runtime","exportName":"ChannelDirectoryEntry","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":480,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelDirectoryEntryKind = ChannelDirectoryEntryKind;","entrypoint":"channel-runtime","exportName":"ChannelDirectoryEntryKind","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":478,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelDirectoryEntry = ChannelDirectoryEntry;","entrypoint":"channel-runtime","exportName":"ChannelDirectoryEntry","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":502,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelDirectoryEntryKind = ChannelDirectoryEntryKind;","entrypoint":"channel-runtime","exportName":"ChannelDirectoryEntryKind","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":500,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelElevatedAdapter = ChannelElevatedAdapter;","entrypoint":"channel-runtime","exportName":"ChannelElevatedAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":485,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelGatewayAdapter = ChannelGatewayAdapter;","entrypoint":"channel-runtime","exportName":"ChannelGatewayAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":379,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelGatewayContext = ChannelGatewayContext;","entrypoint":"channel-runtime","exportName":"ChannelGatewayContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":271,"sourcePath":"src/channels/plugins/types.adapters.ts"} @@ -233,8 +233,8 @@ {"declaration":"export type ChannelLogoutResult = ChannelLogoutResult;","entrypoint":"channel-runtime","exportName":"ChannelLogoutResult","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":344,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelLogSink = ChannelLogSink;","entrypoint":"channel-runtime","exportName":"ChannelLogSink","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":212,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelMentionAdapter = ChannelMentionAdapter;","entrypoint":"channel-runtime","exportName":"ChannelMentionAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":263,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelMessageActionAdapter = ChannelMessageActionAdapter;","entrypoint":"channel-runtime","exportName":"ChannelMessageActionAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":529,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"channel-runtime","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":493,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelMessageActionAdapter = ChannelMessageActionAdapter;","entrypoint":"channel-runtime","exportName":"ChannelMessageActionAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":551,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"channel-runtime","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":515,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelMessageActionDiscoveryContext = ChannelMessageActionDiscoveryContext;","entrypoint":"channel-runtime","exportName":"ChannelMessageActionDiscoveryContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":32,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelMessageActionName = \"send\" | \"broadcast\" | \"poll\" | \"poll-vote\" | \"react\" | \"reactions\" | \"read\" | \"edit\" | \"unsend\" | \"reply\" | \"sendWithEffect\" | \"renameGroup\" | \"setGroupIcon\" | \"addParticipant\" | \"removeParticipant\" | \"leaveGroup\" | \"sendAttachment\" | \"delete\" | \"pin\" | \"unpin\" | \"list-pins\" | \"permissions\" | \"thread-create\" | \"thread-list\" | \"thread-reply\" | \"search\" | \"sticker\" | \"sticker-search\" | \"member-info\" | \"role-info\" | \"emoji-list\" | \"emoji-upload\" | \"sticker-upload\" | \"role-add\" | \"role-remove\" | \"channel-info\" | \"channel-list\" | \"channel-create\" | \"channel-edit\" | \"channel-delete\" | \"channel-move\" | \"category-create\" | \"category-edit\" | \"category-delete\" | \"topic-create\" | \"topic-edit\" | \"voice-status\" | \"event-list\" | \"event-create\" | \"timeout\" | \"kick\" | \"ban\" | \"set-profile\" | \"set-presence\" | \"download-file\" | \"upload-file\";","entrypoint":"channel-runtime","exportName":"ChannelMessageActionName","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":6,"sourcePath":"src/channels/plugins/types.ts"} {"declaration":"export type ChannelMessageCapability = \"interactive\" | \"buttons\" | \"cards\" | \"components\" | \"blocks\";","entrypoint":"channel-runtime","exportName":"ChannelMessageCapability","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":9,"sourcePath":"src/channels/plugins/message-capabilities.ts"} @@ -249,8 +249,8 @@ {"declaration":"export type ChannelOutboundTargetRef = ChannelOutboundTargetRef;","entrypoint":"channel-runtime","exportName":"ChannelOutboundTargetRef","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":164,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelPairingAdapter = ChannelPairingAdapter;","entrypoint":"channel-runtime","exportName":"ChannelPairingAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":368,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelPlugin = ChannelPlugin;","entrypoint":"channel-runtime","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":77,"sourcePath":"src/channels/plugins/types.plugin.ts"} -{"declaration":"export type ChannelPollContext = ChannelPollContext;","entrypoint":"channel-runtime","exportName":"ChannelPollContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":560,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelPollResult = ChannelPollResult;","entrypoint":"channel-runtime","exportName":"ChannelPollResult","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":551,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelPollContext = ChannelPollContext;","entrypoint":"channel-runtime","exportName":"ChannelPollContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":582,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelPollResult = ChannelPollResult;","entrypoint":"channel-runtime","exportName":"ChannelPollResult","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":573,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelResolveKind = ChannelResolveKind;","entrypoint":"channel-runtime","exportName":"ChannelResolveKind","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":465,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelResolverAdapter = ChannelResolverAdapter;","entrypoint":"channel-runtime","exportName":"ChannelResolverAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":475,"sourcePath":"src/channels/plugins/types.adapters.ts"} {"declaration":"export type ChannelResolveResult = ChannelResolveResult;","entrypoint":"channel-runtime","exportName":"ChannelResolveResult","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":467,"sourcePath":"src/channels/plugins/types.adapters.ts"} @@ -266,7 +266,7 @@ {"declaration":"export type ChannelThreadingAdapter = ChannelThreadingAdapter;","entrypoint":"channel-runtime","exportName":"ChannelThreadingAdapter","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":325,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelThreadingContext = ChannelThreadingContext;","entrypoint":"channel-runtime","exportName":"ChannelThreadingContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":368,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelThreadingToolContext = ChannelThreadingToolContext;","entrypoint":"channel-runtime","exportName":"ChannelThreadingToolContext","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":382,"sourcePath":"src/channels/plugins/types.core.ts"} -{"declaration":"export type ChannelToolSend = ChannelToolSend;","entrypoint":"channel-runtime","exportName":"ChannelToolSend","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":522,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelToolSend = ChannelToolSend;","entrypoint":"channel-runtime","exportName":"ChannelToolSend","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":544,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChatType = ChatType;","entrypoint":"channel-runtime","exportName":"ChatType","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":1,"sourcePath":"src/channels/chat-type.ts"} {"declaration":"export type CreateTypingCallbacksParams = CreateTypingCallbacksParams;","entrypoint":"channel-runtime","exportName":"CreateTypingCallbacksParams","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":11,"sourcePath":"src/channels/typing.ts"} {"declaration":"export type HeartbeatEventPayload = HeartbeatEventPayload;","entrypoint":"channel-runtime","exportName":"HeartbeatEventPayload","importSpecifier":"openclaw/plugin-sdk/channel-runtime","kind":"type","recordType":"export","sourceLine":6,"sourcePath":"src/infra/heartbeat-events.ts"} @@ -294,12 +294,12 @@ {"declaration":"export type ChannelSetupWizard = ChannelSetupWizard;","entrypoint":"channel-setup","exportName":"ChannelSetupWizard","importSpecifier":"openclaw/plugin-sdk/channel-setup","kind":"type","recordType":"export","sourceLine":247,"sourcePath":"src/channels/plugins/setup-wizard.ts"} {"declaration":"export type OptionalChannelSetupSurface = OptionalChannelSetupSurface;","entrypoint":"channel-setup","exportName":"OptionalChannelSetupSurface","importSpecifier":"openclaw/plugin-sdk/channel-setup","kind":"type","recordType":"export","sourceLine":29,"sourcePath":"src/plugin-sdk/channel-setup.ts"} {"category":"channel","entrypoint":"command-auth","importSpecifier":"openclaw/plugin-sdk/command-auth","recordType":"module","sourceLine":1,"sourcePath":"src/plugin-sdk/command-auth.ts"} -{"declaration":"export function buildCommandsMessage(cfg?: OpenClawConfig | undefined, skillCommands?: SkillCommandSpec[] | undefined, options?: CommandsMessageOptions | undefined): string;","entrypoint":"command-auth","exportName":"buildCommandsMessage","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":1075,"sourcePath":"src/auto-reply/status.ts"} -{"declaration":"export function buildCommandsMessagePaginated(cfg?: OpenClawConfig | undefined, skillCommands?: SkillCommandSpec[] | undefined, options?: CommandsMessageOptions | undefined): CommandsMessageResult;","entrypoint":"command-auth","exportName":"buildCommandsMessagePaginated","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":1084,"sourcePath":"src/auto-reply/status.ts"} +{"declaration":"export function buildCommandsMessage(cfg?: OpenClawConfig | undefined, skillCommands?: SkillCommandSpec[] | undefined, options?: CommandsMessageOptions | undefined): string;","entrypoint":"command-auth","exportName":"buildCommandsMessage","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":1076,"sourcePath":"src/auto-reply/status.ts"} +{"declaration":"export function buildCommandsMessagePaginated(cfg?: OpenClawConfig | undefined, skillCommands?: SkillCommandSpec[] | undefined, options?: CommandsMessageOptions | undefined): CommandsMessageResult;","entrypoint":"command-auth","exportName":"buildCommandsMessagePaginated","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":1085,"sourcePath":"src/auto-reply/status.ts"} {"declaration":"export function buildCommandsPaginationKeyboard(currentPage: number, totalPages: number, agentId?: string | undefined): { text: string; callback_data: string; }[][];","entrypoint":"command-auth","exportName":"buildCommandsPaginationKeyboard","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":175,"sourcePath":"src/auto-reply/reply/commands-info.ts"} {"declaration":"export function buildCommandText(commandName: string, args?: string | undefined): string;","entrypoint":"command-auth","exportName":"buildCommandText","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":199,"sourcePath":"src/auto-reply/commands-registry.ts"} {"declaration":"export function buildCommandTextFromArgs(command: ChatCommandDefinition, args?: CommandArgs | undefined): string;","entrypoint":"command-auth","exportName":"buildCommandTextFromArgs","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":291,"sourcePath":"src/auto-reply/commands-registry.ts"} -{"declaration":"export function buildHelpMessage(cfg?: OpenClawConfig | undefined): string;","entrypoint":"command-auth","exportName":"buildHelpMessage","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":870,"sourcePath":"src/auto-reply/status.ts"} +{"declaration":"export function buildHelpMessage(cfg?: OpenClawConfig | undefined): string;","entrypoint":"command-auth","exportName":"buildHelpMessage","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":871,"sourcePath":"src/auto-reply/status.ts"} {"declaration":"export function buildModelsProviderData(cfg: OpenClawConfig, agentId?: string | undefined): Promise;","entrypoint":"command-auth","exportName":"buildModelsProviderData","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":39,"sourcePath":"src/auto-reply/reply/commands-models.ts"} {"declaration":"export function createPreCryptoDirectDmAuthorizer(params: { resolveAccess: (senderId: string) => Promise>; issuePairingChallenge?: ((params: { ...; }) => Promise<...>) | undefined; onBlocked?: ((params: { ...; }) => void) | undefined; }): (input: { ...; }) => Promise<...>;","entrypoint":"command-auth","exportName":"createPreCryptoDirectDmAuthorizer","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":105,"sourcePath":"src/plugin-sdk/direct-dm.ts"} {"declaration":"export function findCommandByNativeName(name: string, provider?: string | undefined): ChatCommandDefinition | undefined;","entrypoint":"command-auth","exportName":"findCommandByNativeName","importSpecifier":"openclaw/plugin-sdk/command-auth","kind":"function","recordType":"export","sourceLine":187,"sourcePath":"src/auto-reply/commands-registry.ts"} @@ -411,7 +411,7 @@ {"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","sourceLine":5,"sourcePath":"src/infra/secret-file.ts"} {"declaration":"export type AnyAgentTool = AnyAgentTool;","entrypoint":"core","exportName":"AnyAgentTool","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":9,"sourcePath":"src/agents/tools/common.ts"} {"declaration":"export type ChannelConfigUiHint = ChannelConfigUiHint;","entrypoint":"core","exportName":"ChannelConfigUiHint","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":38,"sourcePath":"src/channels/plugins/types.plugin.ts"} -{"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"core","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":493,"sourcePath":"src/channels/plugins/types.core.ts"} +{"declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"core","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":515,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelMessagingAdapter = ChannelMessagingAdapter;","entrypoint":"core","exportName":"ChannelMessagingAdapter","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":398,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelOutboundSessionRoute = ChannelOutboundSessionRoute;","entrypoint":"core","exportName":"ChannelOutboundSessionRoute","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":312,"sourcePath":"src/channels/plugins/types.core.ts"} {"declaration":"export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; resolvedTarget?: { to: string; kind: import(\"../channels/plugins/types.core.js\").ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};","entrypoint":"core","exportName":"ChannelOutboundSessionRouteParams","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export","sourceLine":159,"sourcePath":"src/plugin-sdk/core.ts"} diff --git a/docs/plugins/sdk-channel-plugins.md b/docs/plugins/sdk-channel-plugins.md index bd169c8fd87..6af4b630435 100644 --- a/docs/plugins/sdk-channel-plugins.md +++ b/docs/plugins/sdk-channel-plugins.md @@ -36,10 +36,16 @@ Core owns the shared message tool, prompt wiring, the outer session-key shape, generic `:thread:` bookkeeping, and dispatch. If your platform stores extra scope inside conversation ids, keep that parsing -in the plugin by implementing `messaging.resolveSessionConversation(...)` and -`messaging.resolveParentConversationCandidates(...)`. Use those hooks for -platform-specific suffixes or inheritance rules instead of adding provider -checks to core. +in the plugin with `messaging.resolveSessionConversation(...)`. That is the +canonical hook for mapping `rawId` to the base conversation id, optional thread +id, and any `parentConversationCandidates`. + +`messaging.resolveParentConversationCandidates(...)` remains available as a +legacy compatibility fallback when a plugin only needs parent fallbacks on top +of the generic/raw id. If both hooks exist, core uses +`resolveSessionConversation(...).parentConversationCandidates` first and only +falls back to `resolveParentConversationCandidates(...)` when the canonical hook +omits them. ## Approvals and channel capabilities diff --git a/extensions/discord/src/monitor/threading.ts b/extensions/discord/src/monitor/threading.ts index 24ead3e8c68..c7dbb3df4ba 100644 --- a/extensions/discord/src/monitor/threading.ts +++ b/extensions/discord/src/monitor/threading.ts @@ -501,6 +501,7 @@ function resolveDiscordThreadTitleModelRef(params: { cfg: params.cfg, channel, groupId: params.threadId, + groupChatType: "channel", groupChannel, groupSubject: groupChannel, parentSessionKey, diff --git a/extensions/feishu/src/channel.test.ts b/extensions/feishu/src/channel.test.ts index 7b50e1704d6..3a5e6455396 100644 --- a/extensions/feishu/src/channel.test.ts +++ b/extensions/feishu/src/channel.test.ts @@ -200,17 +200,14 @@ describe("feishuPlugin messaging", () => { parentConversationCandidates: ["oc_group_chat:topic:om_topic_root", "oc_group_chat"], }); expect( - feishuPlugin.messaging?.resolveParentConversationCandidates?.({ - kind: "group", - rawId: "oc_group_chat:topic:om_topic_root:sender:ou_topic_user", - }), - ).toEqual(["oc_group_chat:topic:om_topic_root", "oc_group_chat"]); - expect( - feishuPlugin.messaging?.resolveParentConversationCandidates?.({ + feishuPlugin.messaging?.resolveSessionConversation?.({ kind: "group", rawId: "oc_group_chat:topic:om_topic_root", }), - ).toEqual(["oc_group_chat"]); + ).toEqual({ + id: "oc_group_chat:topic:om_topic_root", + parentConversationCandidates: ["oc_group_chat"], + }); }); }); diff --git a/extensions/feishu/src/channel.ts b/extensions/feishu/src/channel.ts index 01f20cb01cf..e6e072f47ca 100644 --- a/extensions/feishu/src/channel.ts +++ b/extensions/feishu/src/channel.ts @@ -1106,8 +1106,6 @@ export const feishuPlugin: ChannelPlugin normalizeFeishuTarget(raw) ?? undefined, resolveSessionConversation: ({ rawId }) => resolveFeishuSessionConversation(rawId), - resolveParentConversationCandidates: ({ rawId }) => - resolveFeishuParentConversationCandidates(rawId), resolveOutboundSessionRoute: (params) => resolveFeishuOutboundSessionRoute(params), targetResolver: { looksLikeId: looksLikeFeishuId, diff --git a/extensions/telegram/src/channel.test.ts b/extensions/telegram/src/channel.test.ts index fcca39f7e75..39c16129179 100644 --- a/extensions/telegram/src/channel.test.ts +++ b/extensions/telegram/src/channel.test.ts @@ -200,11 +200,15 @@ describe("telegramPlugin messaging", () => { parentConversationCandidates: ["-1001"], }); expect( - telegramPlugin.messaging?.resolveParentConversationCandidates?.({ + telegramPlugin.messaging?.resolveSessionConversation?.({ kind: "group", - rawId: "-1001:topic:77", + rawId: "-1001:Topic:77", }), - ).toEqual(["-1001"]); + ).toEqual({ + id: "-1001", + threadId: "77", + parentConversationCandidates: ["-1001"], + }); expect( telegramPlugin.messaging?.resolveSessionConversation?.({ kind: "group", diff --git a/extensions/telegram/src/channel.ts b/extensions/telegram/src/channel.ts index d6cfdfd5830..560784a6be4 100644 --- a/extensions/telegram/src/channel.ts +++ b/extensions/telegram/src/channel.ts @@ -543,8 +543,6 @@ export const telegramPlugin = createChatChannelPlugin({ messaging: { normalizeTarget: normalizeTelegramMessagingTarget, resolveSessionConversation: ({ rawId }) => resolveTelegramSessionConversation(rawId), - resolveParentConversationCandidates: ({ rawId }) => - resolveTelegramSessionConversation(rawId)?.parentConversationCandidates ?? null, parseExplicitTarget: ({ raw }) => parseTelegramExplicitTarget(raw), inferTargetChatType: ({ to }) => parseTelegramExplicitTarget(to).chatType, formatTargetDisplay: ({ target, display, kind }) => { diff --git a/src/acp/conversation-id.ts b/src/acp/conversation-id.ts index 9cf17c9a579..639d6113463 100644 --- a/src/acp/conversation-id.ts +++ b/src/acp/conversation-id.ts @@ -43,7 +43,7 @@ export function parseTelegramTopicConversation(params: { parentConversationId?: string; }): ParsedTelegramTopicConversation | null { const conversation = params.conversationId.trim(); - const directMatch = conversation.match(/^(-?\d+):topic:(\d+)$/); + const directMatch = conversation.match(/^(-?\d+):topic:(\d+)$/i); if (directMatch?.[1] && directMatch[2]) { const canonicalConversationId = buildTelegramTopicConversationId({ chatId: directMatch[1], diff --git a/src/auto-reply/reply/get-reply.ts b/src/auto-reply/reply/get-reply.ts index 8f911af8cf3..adf1d9d9d5c 100644 --- a/src/auto-reply/reply/get-reply.ts +++ b/src/auto-reply/reply/get-reply.ts @@ -267,6 +267,7 @@ export async function getReplyFromConfig( : undefined) ?? finalized.Provider, groupId: groupResolution?.id ?? sessionEntry.groupId, + groupChatType: sessionEntry.chatType ?? sessionCtx.ChatType ?? finalized.ChatType, groupChannel: sessionEntry.groupChannel ?? sessionCtx.GroupChannel ?? finalized.GroupChannel, groupSubject: sessionEntry.subject ?? sessionCtx.GroupSubject ?? finalized.GroupSubject, parentSessionKey: sessionCtx.ParentSessionKey, diff --git a/src/auto-reply/status.ts b/src/auto-reply/status.ts index b0774239b65..256efc6ebe2 100644 --- a/src/auto-reply/status.ts +++ b/src/auto-reply/status.ts @@ -763,6 +763,7 @@ export function buildStatusMessage(args: StatusArgs): string { cfg: args.config, channel: entry.channel ?? entry.origin?.provider, groupId: entry.groupId, + groupChatType: entry.chatType ?? entry.origin?.chatType, groupChannel: entry.groupChannel, groupSubject: entry.subject, parentSessionKey: args.parentSessionKey, diff --git a/src/channels/model-overrides.test.ts b/src/channels/model-overrides.test.ts index 8d276f16e74..5d00dfe4372 100644 --- a/src/channels/model-overrides.test.ts +++ b/src/channels/model-overrides.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { setActivePluginRegistry } from "../plugins/runtime.js"; +import { createTestRegistry } from "../test-utils/channel-plugins.js"; import { createSessionConversationTestRegistry } from "../test-utils/session-conversation-registry.js"; import { resolveChannelModelOverride } from "./model-overrides.js"; @@ -110,4 +111,60 @@ describe("resolveChannelModelOverride", () => { expect(resolved?.model).toBe(expected.model); expect(resolved?.matchKey).toBe(expected.matchKey); }); + + it("passes channel kind to plugin-owned parent fallback resolution", () => { + setActivePluginRegistry( + createTestRegistry([ + { + pluginId: "channel-kind", + source: "test", + plugin: { + id: "channel-kind", + meta: { + id: "channel-kind", + label: "Channel Kind", + selectionLabel: "Channel Kind", + docsPath: "/channels/channel-kind", + blurb: "test stub.", + }, + capabilities: { chatTypes: ["group", "channel"] }, + messaging: { + resolveSessionConversation: ({ + kind, + rawId, + }: { + kind: "group" | "channel"; + rawId: string; + }) => ({ + id: rawId, + parentConversationCandidates: kind === "channel" ? ["thread-parent"] : [], + }), + }, + config: { + listAccountIds: () => ["default"], + resolveAccount: () => ({}), + }, + }, + }, + ]), + ); + + const resolved = resolveChannelModelOverride({ + cfg: { + channels: { + modelByChannel: { + "channel-kind": { + "thread-parent": "demo-provider/demo-channel-model", + }, + }, + }, + } as unknown as OpenClawConfig, + channel: "channel-kind", + groupId: "thread-123", + groupChatType: "channel", + }); + + expect(resolved?.model).toBe("demo-provider/demo-channel-model"); + expect(resolved?.matchKey).toBe("thread-parent"); + }); }); diff --git a/src/channels/model-overrides.ts b/src/channels/model-overrides.ts index 4bc52c12df0..5cfa2fc2839 100644 --- a/src/channels/model-overrides.ts +++ b/src/channels/model-overrides.ts @@ -6,8 +6,9 @@ import { resolveChannelEntryMatchWithFallback, type ChannelMatchSource, } from "./channel-config.js"; +import { normalizeChatType } from "./chat-type.js"; import { - resolveParentConversationCandidates, + resolveSessionConversation, resolveSessionConversationRef, } from "./plugins/session-conversation.js"; @@ -24,6 +25,7 @@ type ChannelModelOverrideParams = { cfg: OpenClawConfig; channel?: string | null; groupId?: string | null; + groupChatType?: string | null; groupChannel?: string | null; groupSubject?: string | null; parentSessionKey?: string | null; @@ -48,13 +50,24 @@ function resolveProviderEntry( function buildChannelCandidates( params: Pick< ChannelModelOverrideParams, - "channel" | "groupId" | "groupChannel" | "groupSubject" | "parentSessionKey" + "channel" | "groupId" | "groupChatType" | "groupChannel" | "groupSubject" | "parentSessionKey" >, ): { keys: string[]; parentKeys: string[] } { const normalizedChannel = normalizeMessageChannel(params.channel ?? "") ?? params.channel?.trim().toLowerCase(); const groupId = params.groupId?.trim(); const sessionConversation = resolveSessionConversationRef(params.parentSessionKey); + const groupConversationKind = + normalizeChatType(params.groupChatType ?? undefined) === "channel" + ? "channel" + : sessionConversation?.kind === "channel" + ? "channel" + : "group"; + const groupConversation = resolveSessionConversation({ + channel: normalizedChannel ?? "", + kind: groupConversationKind, + rawId: groupId ?? "", + }); const groupChannel = params.groupChannel?.trim(); const groupSubject = params.groupSubject?.trim(); const channelBare = groupChannel ? groupChannel.replace(/^#/, "") : undefined; @@ -74,11 +87,7 @@ function buildChannelCandidates( subjectSlug, ), parentKeys: buildChannelKeyCandidates( - ...resolveParentConversationCandidates({ - channel: normalizedChannel ?? "", - kind: "group", - rawId: groupId ?? "", - }), + ...(groupConversation?.parentConversationCandidates ?? []), ...(sessionConversation?.parentConversationCandidates ?? []), ), }; diff --git a/src/channels/plugins/session-conversation.test.ts b/src/channels/plugins/session-conversation.test.ts index b544ab1df7b..54b1f461c4b 100644 --- a/src/channels/plugins/session-conversation.test.ts +++ b/src/channels/plugins/session-conversation.test.ts @@ -1,8 +1,9 @@ import { beforeEach, describe, expect, it } from "vitest"; -import { setActivePluginRegistry } from "../../plugins/runtime.js"; +import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../../plugins/runtime.js"; +import { createTestRegistry } from "../../test-utils/channel-plugins.js"; import { createSessionConversationTestRegistry } from "../../test-utils/session-conversation-registry.js"; import { - resolveParentConversationCandidates, + resolveSessionConversation, resolveSessionConversationRef, resolveSessionParentSessionKey, resolveSessionThreadInfo, @@ -46,6 +47,20 @@ describe("session conversation routing", () => { ); }); + it("keeps bundled Telegram topic parsing available before registry bootstrap", () => { + resetPluginRuntimeStateForTest(); + + expect(resolveSessionConversationRef("agent:main:telegram:group:-100123:topic:77")).toEqual({ + channel: "telegram", + kind: "group", + rawId: "-100123:topic:77", + id: "-100123", + threadId: "77", + baseSessionKey: "agent:main:telegram:group:-100123", + parentConversationCandidates: ["-100123"], + }); + }); + it("lets Feishu own parent fallback candidates", () => { expect( resolveSessionConversationRef( @@ -61,17 +76,52 @@ describe("session conversation routing", () => { "agent:main:feishu:group:oc_group_chat:topic:om_topic_root:sender:ou_topic_user", parentConversationCandidates: ["oc_group_chat:topic:om_topic_root", "oc_group_chat"], }); - expect( - resolveParentConversationCandidates({ - channel: "feishu", - kind: "group", - rawId: "oc_group_chat:topic:om_topic_root:sender:ou_topic_user", - }), - ).toEqual(["oc_group_chat:topic:om_topic_root", "oc_group_chat"]); expect( resolveSessionParentSessionKey( "agent:main:feishu:group:oc_group_chat:topic:om_topic_root:sender:ou_topic_user", ), ).toBeNull(); }); + + it("keeps the legacy parent-candidate hook as a fallback only", () => { + setActivePluginRegistry( + createTestRegistry([ + { + pluginId: "legacy-parent", + source: "test", + plugin: { + id: "legacy-parent", + meta: { + id: "legacy-parent", + label: "Legacy Parent", + selectionLabel: "Legacy Parent", + docsPath: "/channels/legacy-parent", + blurb: "test stub.", + }, + capabilities: { chatTypes: ["group"] }, + messaging: { + resolveParentConversationCandidates: ({ rawId }: { rawId: string }) => + rawId.endsWith(":sender:user") ? [rawId.replace(/:sender:user$/i, "")] : null, + }, + config: { + listAccountIds: () => ["default"], + resolveAccount: () => ({}), + }, + }, + }, + ]), + ); + + expect( + resolveSessionConversation({ + channel: "legacy-parent", + kind: "group", + rawId: "room:sender:user", + }), + ).toEqual({ + id: "room:sender:user", + threadId: undefined, + parentConversationCandidates: ["room"], + }); + }); }); diff --git a/src/channels/plugins/session-conversation.ts b/src/channels/plugins/session-conversation.ts index 24a7ebe694d..68816d553b5 100644 --- a/src/channels/plugins/session-conversation.ts +++ b/src/channels/plugins/session-conversation.ts @@ -1,3 +1,4 @@ +import { parseTelegramTopicConversation } from "../../acp/conversation-id.js"; import { parseRawSessionConversationRef, parseThreadSessionSuffix, @@ -23,7 +24,15 @@ export type ResolvedSessionConversationRef = { parentConversationCandidates: string[]; }; -type SessionConversationResolution = ResolvedSessionConversation; +type SessionConversationHookResult = { + id: string; + threadId?: string | null; + parentConversationCandidates?: string[]; +}; + +type NormalizedSessionConversationResolution = ResolvedSessionConversation & { + hasExplicitParentConversationCandidates: boolean; +}; function normalizeResolvedChannel(channel: string): string { return ( @@ -80,40 +89,82 @@ function buildGenericConversationResolution(rawId: string): ResolvedSessionConve }; } +function normalizeSessionConversationResolution( + resolved: SessionConversationHookResult | null | undefined, +): NormalizedSessionConversationResolution | null { + if (!resolved?.id?.trim()) { + return null; + } + + return { + id: resolved.id.trim(), + threadId: resolved.threadId?.trim() || undefined, + parentConversationCandidates: dedupeConversationIds( + resolved.parentConversationCandidates ?? [], + ), + hasExplicitParentConversationCandidates: Object.hasOwn( + resolved, + "parentConversationCandidates", + ), + }; +} + +function resolveBundledSessionConversationFallback(params: { + channel: string; + rawId: string; +}): NormalizedSessionConversationResolution | null { + if (normalizeResolvedChannel(params.channel) !== "telegram") { + return null; + } + + const parsed = parseTelegramTopicConversation({ conversationId: params.rawId }); + if (!parsed) { + return null; + } + + return { + id: parsed.chatId, + threadId: parsed.topicId, + parentConversationCandidates: [parsed.chatId], + hasExplicitParentConversationCandidates: true, + }; +} + function resolveSessionConversationResolution(params: { channel: string; kind: "group" | "channel"; rawId: string; -}): SessionConversationResolution | null { +}): ResolvedSessionConversation | null { const rawId = params.rawId.trim(); if (!rawId) { return null; } const messaging = getMessagingAdapter(params.channel); - const pluginResolved = messaging?.resolveSessionConversation?.({ - kind: params.kind, - rawId, - }); + const pluginResolved = normalizeSessionConversationResolution( + messaging?.resolveSessionConversation?.({ + kind: params.kind, + rawId, + }), + ); const resolved = - pluginResolved && pluginResolved.id?.trim() - ? { - id: pluginResolved.id.trim(), - threadId: pluginResolved.threadId?.trim() || undefined, - parentConversationCandidates: dedupeConversationIds( - pluginResolved.parentConversationCandidates ?? [], - ), - } - : buildGenericConversationResolution(rawId); + pluginResolved ?? + resolveBundledSessionConversationFallback({ + channel: params.channel, + rawId, + }) ?? + buildGenericConversationResolution(rawId); if (!resolved) { return null; } const parentConversationCandidates = dedupeConversationIds( - messaging?.resolveParentConversationCandidates?.({ - kind: params.kind, - rawId, - }) ?? resolved.parentConversationCandidates, + pluginResolved?.hasExplicitParentConversationCandidates + ? resolved.parentConversationCandidates + : (messaging?.resolveParentConversationCandidates?.({ + kind: params.kind, + rawId, + }) ?? resolved.parentConversationCandidates), ); return { @@ -130,14 +181,6 @@ export function resolveSessionConversation(params: { return resolveSessionConversationResolution(params); } -export function resolveParentConversationCandidates(params: { - channel: string; - kind: "group" | "channel"; - rawId: string; -}): string[] { - return resolveSessionConversationResolution(params)?.parentConversationCandidates ?? []; -} - function buildBaseSessionKey(raw: RawSessionConversationRef, id: string): string { return `${raw.prefix}:${id}`; } diff --git a/src/channels/plugins/types.core.ts b/src/channels/plugins/types.core.ts index cdedf51a3dd..d95cca61b8c 100644 --- a/src/channels/plugins/types.core.ts +++ b/src/channels/plugins/types.core.ts @@ -398,9 +398,11 @@ export type ChannelThreadingToolContext = { export type ChannelMessagingAdapter = { normalizeTarget?: (raw: string) => string | undefined; /** - * Plugin-owned session conversation grammar. + * Canonical plugin-owned session conversation grammar. * Use this when the provider encodes thread or scoped-conversation semantics * inside `rawId` (for example Telegram topics or Feishu sender scopes). + * Return `parentConversationCandidates` here when you can so parsing and + * inheritance stay in one place. */ resolveSessionConversation?: (params: { kind: "group" | "channel"; rawId: string }) => { id: string; @@ -408,8 +410,10 @@ export type ChannelMessagingAdapter = { parentConversationCandidates?: string[]; } | null; /** - * Plugin-owned inheritance chain for channel-specific conversation ids. - * Return broader parent ids in priority order, without repeating `rawId`. + * Legacy compatibility hook for parent fallbacks when a plugin does not need + * to customize `id` or `threadId`. Core only uses this when + * `resolveSessionConversation(...)` does not return + * `parentConversationCandidates`. */ resolveParentConversationCandidates?: (params: { kind: "group" | "channel"; diff --git a/src/test-utils/session-conversation-registry.ts b/src/test-utils/session-conversation-registry.ts index 6aaee6dd35a..6767d2e9ec1 100644 --- a/src/test-utils/session-conversation-registry.ts +++ b/src/test-utils/session-conversation-registry.ts @@ -132,8 +132,6 @@ export function createSessionConversationTestRegistry() { normalizeTarget: (raw: string) => raw.replace(/^group:/, ""), resolveSessionConversation: ({ rawId }: { rawId: string }) => parseTelegramTopicConversation(rawId), - resolveParentConversationCandidates: ({ rawId }: { rawId: string }) => - parseTelegramTopicConversation(rawId)?.parentConversationCandidates ?? null, }, config: { listAccountIds: () => ["default"], @@ -158,8 +156,6 @@ export function createSessionConversationTestRegistry() { normalizeTarget: (raw: string) => raw.replace(/^group:/, ""), resolveSessionConversation: ({ rawId }: { rawId: string }) => resolveFeishuConversation(rawId), - resolveParentConversationCandidates: ({ rawId }: { rawId: string }) => - resolveFeishuConversation(rawId)?.parentConversationCandidates ?? null, }, config: { listAccountIds: () => ["default"],