diff --git a/extensions/matrix/src/config-schema.ts b/extensions/matrix/src/config-schema.ts index 210a55eec1a2..6f9c5588c32e 100644 --- a/extensions/matrix/src/config-schema.ts +++ b/extensions/matrix/src/config-schema.ts @@ -56,7 +56,7 @@ const botLoopProtectionSchema = z .strict() .optional(); -const matrixRoomSchema = buildGroupEntrySchema({ +export const matrixRoomSchema = buildGroupEntrySchema({ account: z.string().optional(), allowBots: z.union([z.boolean(), z.literal("mentions")]).optional(), botLoopProtection: botLoopProtectionSchema, @@ -74,7 +74,7 @@ const matrixNetworkSchema = z .strict() .optional(); -const matrixStreamingSchema = z +export const matrixStreamingSchema = z .object({ mode: z.enum(["partial", "quiet", "progress", "off"]).optional(), chunkMode: z.enum(["length", "newline"]).optional(), @@ -127,7 +127,7 @@ function hasCanonicalMatrixAccountStreaming(account: unknown): boolean { return typeof streaming === "object" && streaming !== null && !Array.isArray(streaming); } -const MatrixConfigSchema = z.object({ +export const MatrixConfigSchema = z.object({ name: z.string().optional(), enabled: z.boolean().optional(), configWrites: z.boolean().optional(), diff --git a/extensions/matrix/src/types.ts b/extensions/matrix/src/types.ts index a10bb8eff7b2..b14af50f2083 100644 --- a/extensions/matrix/src/types.ts +++ b/extensions/matrix/src/types.ts @@ -2,231 +2,36 @@ import type { ChannelBotLoopProtectionConfig, ContextVisibilityMode, - DmPolicy, - GroupPolicy, - MentionPatternsPolicyConfig, OpenClawConfig, } from "openclaw/plugin-sdk/config-contracts"; -import type { SecretInput } from "openclaw/plugin-sdk/secret-input"; +import type { z } from "zod"; +import type { + matrixRoomSchema, + matrixStreamingSchema, + MatrixConfigSchema, +} from "./config-schema.js"; -export type ReplyToMode = "off" | "first" | "all" | "batched"; +type MatrixConfigSchemaValue = z.infer; -type MatrixDmConfig = { - /** If false, ignore all incoming Matrix DMs. Default: true. */ - enabled?: boolean; - /** Direct message access policy (default: pairing). */ - policy?: DmPolicy; - /** Allowlist for DM senders (matrix user IDs or "*"). */ - allowFrom?: Array; - /** - * How Matrix DMs map to sessions. - * - `per-user` (default): all DM rooms with the same routed peer share one DM session. - * - `per-room`: each Matrix DM room gets its own session key. - */ +export type ReplyToMode = NonNullable; +export type MatrixRoomConfig = NonNullable>; +export type MatrixStreamingConfig = z.infer; +export type MatrixStreamingMode = NonNullable; +type MatrixDmConfig = NonNullable & { sessionScope?: "per-user" | "per-room"; - /** Per-DM thread reply behavior override (off|inbound|always). Overrides top-level threadReplies for direct messages. */ threadReplies?: "off" | "inbound" | "always"; }; -export type MatrixRoomConfig = { - /** Restrict this room entry to a specific Matrix account in multi-account setups. */ - account?: string; - /** If false, disable the bot in this room. */ - enabled?: boolean; - /** Require mentioning the bot to trigger replies. */ - requireMention?: boolean; - /** - * Allow messages from other configured Matrix bot accounts. - * true accepts all configured bot senders; "mentions" requires they mention this bot. - */ - allowBots?: boolean | "mentions"; - /** Sliding-window bot-pair loop guard for accepted configured-bot messages. */ - botLoopProtection?: ChannelBotLoopProtectionConfig; - /** Optional tool policy overrides for this room. */ - tools?: { allow?: string[]; deny?: string[] }; - /** If true, reply without mention requirements. */ - autoReply?: boolean; - /** Optional allowlist for room senders (matrix user IDs). */ - users?: Array; - /** Optional skill filter for this room. */ - skills?: string[]; - /** Optional system prompt snippet for this room. */ - systemPrompt?: string; -}; - -type MatrixActionConfig = { - reactions?: boolean; - messages?: boolean; - pins?: boolean; - profile?: boolean; - memberInfo?: boolean; - channelInfo?: boolean; - verification?: boolean; -}; - -type MatrixThreadBindingsConfig = { - enabled?: boolean; - idleHours?: number; - maxAgeHours?: number; - spawnSessions?: boolean; - defaultSpawnContext?: "isolated" | "fork"; -}; - -type MatrixExecApprovalTarget = "dm" | "channel" | "both"; - -type MatrixExecApprovalConfig = { - /** Explicitly enable Matrix-native approval prompts when approvers are available. */ - enabled?: boolean | "auto"; - /** Optional approver Matrix user IDs. Falls back to dm.allowFrom. */ - approvers?: Array; - /** Optional agent allowlist for approval delivery. */ - agentFilter?: string[]; - /** Optional session allowlist for approval delivery. */ - sessionFilter?: string[]; - /** Where approval prompts should go. Default: dm. */ - target?: MatrixExecApprovalTarget; -}; - -export type MatrixStreamingMode = "partial" | "quiet" | "progress" | "off"; - -export type MatrixStreamingConfig = { - /** Preview streaming mode for Matrix replies. Default: "off". */ - mode?: MatrixStreamingMode; - /** Chunking mode: "length" (default) splits by size; "newline" splits on every newline. */ - chunkMode?: "length" | "newline"; - /** Block streaming delivery controls (separate from the preview mode). Default: disabled. */ - block?: import("openclaw/plugin-sdk/channel-outbound").ChannelStreamingBlockConfig; - progress?: import("openclaw/plugin-sdk/channel-outbound").ChannelStreamingProgressConfig; - preview?: { - /** Show tool/progress activity in the live draft preview. Default: true. */ - toolProgress?: boolean; - }; -}; - -type MatrixNetworkConfig = { - /** Dangerous opt-in for trusted private/internal Matrix homeservers. */ - dangerouslyAllowPrivateNetwork?: boolean; -}; - -/** Per-account Matrix config (excludes the accounts field to prevent recursion). */ -export type MatrixAccountConfig = Omit; - -export type MatrixConfig = { - /** Introduce the bot when it joins an allowed group room. Default: true. */ - joinIntro?: boolean; - /** Optional display name for this account (used in CLI/UI lists). */ - name?: string; - /** If false, do not start Matrix. Default: true. */ - enabled?: boolean; - /** Multi-account configuration keyed by account ID. */ - accounts?: Record; - /** Optional default account id when multiple accounts are configured. */ - defaultAccount?: string; - /** Matrix homeserver URL (https://matrix.example.org). */ - homeserver?: string; - /** Network policy overrides for trusted private/internal Matrix homeservers. */ - network?: MatrixNetworkConfig; - /** Optional HTTP(S) proxy URL for Matrix connections (e.g. http://127.0.0.1:7890). */ - proxy?: string; - /** Matrix user id (@user:server). */ - userId?: string; - /** Matrix access token. */ - accessToken?: SecretInput; - /** Matrix password (used only to fetch access token). */ - password?: SecretInput; - /** Optional Matrix device id (recommended when using access tokens + E2EE). */ - deviceId?: string; - /** Optional device name when logging in via password. */ - deviceName?: string; - /** Optional desired Matrix avatar source (mxc:// or http(s) URL). */ - avatarUrl?: string; - /** Initial sync limit for startup (defaults to matrix-js-sdk behavior). */ - initialSyncLimit?: number; - /** Enable end-to-end encryption (E2EE). Default: false. */ - encryption?: boolean; - /** If true, enforce allowlists for groups + DMs regardless of policy. */ - allowlistOnly?: boolean; - /** Break-glass compatibility mode for resolving mutable Matrix display names and room names in allowlists. */ - dangerouslyAllowNameMatching?: boolean; - /** - * Allow messages from other configured Matrix bot accounts. - * true accepts all configured bot senders; "mentions" requires they mention this bot. - */ - allowBots?: boolean | "mentions"; - /** Sliding-window bot-pair loop guard for accepted configured-bot messages. */ - botLoopProtection?: ChannelBotLoopProtectionConfig; - /** Group message policy (default: allowlist). */ - groupPolicy?: GroupPolicy; - /** Scope configured groupChat mentionPatterns to selected Matrix room IDs. */ - mentionPatterns?: MentionPatternsPolicyConfig; - /** Supplemental context visibility policy (all|allowlist|allowlist_quote). */ - contextVisibility?: ContextVisibilityMode; - /** Allowlist for group senders (matrix user IDs). */ - groupAllowFrom?: Array; - /** Control reply threading when reply tags are present (off|first|all|batched). */ - replyToMode?: ReplyToMode; - /** How to handle thread replies (off|inbound|always). */ - threadReplies?: "off" | "inbound" | "always"; - /** Outbound text chunk size (chars). Default: 4000. */ - textChunkLimit?: number; - /** Outbound response prefix override for this channel/account. */ - responsePrefix?: string; - /** Ack reaction emoji override for this channel/account. */ - ackReaction?: string; - /** Ack reaction scope override for this channel/account. */ - ackReactionScope?: "group-mentions" | "group-all" | "direct" | "all" | "none" | "off"; - /** Inbound reaction notifications for bot-authored Matrix messages. */ - reactionNotifications?: "off" | "own"; - /** Thread/session binding behavior for Matrix room threads. */ - threadBindings?: MatrixThreadBindingsConfig; - /** Whether Matrix should auto-request self verification on startup when unverified. */ - startupVerification?: "off" | "if-unverified"; - /** Cooldown window for automatic startup verification requests. Default: 24 hours. */ - startupVerificationCooldownHours?: number; - /** Max outbound media size in MB. */ - mediaMaxMb?: number; - /** - * Number of recent room messages shown to the agent as context when it is mentioned - * in a group chat (0 = disabled). Applies to room messages that did not directly - * trigger a reply. Default: 0 (disabled). - */ - historyLimit?: number; - /** Auto-join invites (always|allowlist|off). Default: off. */ - autoJoin?: "always" | "allowlist" | "off"; - /** Allowlist for auto-join invites (room IDs, aliases). */ - autoJoinAllowlist?: Array; - /** Direct message policy + allowlist overrides. */ +export type MatrixAccountConfig = Omit< + MatrixConfigSchemaValue, + "accounts" | "dm" | "groups" | "rooms" +> & { dm?: MatrixDmConfig; - /** Matrix-native exec approval delivery config. */ - execApprovals?: MatrixExecApprovalConfig; - /** Room config allowlist keyed by room ID or alias (names resolved to IDs when possible). */ groups?: Record; - /** @deprecated Use groups. */ rooms?: Record; - /** Per-action tool gating (default: true for all). */ - actions?: MatrixActionConfig; - /** - * Streaming config for Matrix replies (`streaming.mode`): - * - `"partial"`: edit a single draft message in place for the current - * assistant block as the model generates text using normal Matrix text - * messages. This preserves legacy preview-first notification behavior. - * - `"quiet"`: edit a single quiet draft notice in place for the current - * assistant block as the model generates text. - * - `"progress"`: edit a single draft status message with shared progress - * labels and optional tool/task lines until the final answer is ready. - * - `"off"`: deliver the full reply once the model finishes. - * - Use `streaming.block.enabled: true` when you want completed assistant - * blocks to stay visible as separate progress messages. When combined with - * preview streaming, Matrix keeps a live draft for the current block and - * preserves completed blocks as separate messages. - * - `streaming.progress.toolProgress: true` adds interim tool/progress - * lines to the progress draft (default: quiet). `streaming.preview.toolProgress: - * false` keeps legacy answer preview edits but hides interim tool/progress lines. - * Legacy scalar/boolean spellings and the flat `blockStreaming`/`chunkMode` - * keys migrate via `openclaw doctor --fix`. - * Default: `mode: "off"`. - */ - streaming?: MatrixStreamingConfig; +}; +export type MatrixConfig = MatrixAccountConfig & { + accounts?: Record; }; export type CoreConfig = {