refactor(matrix): derive config types from schema (#142026)

This commit is contained in:
Dallin Romney 2026-09-08 01:37:36 -07:00 • committed by GitHub
parent 87f14c2823
commit bb3a3402fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 22 additions and 217 deletions

View file

@ -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(),

View file

@ -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<typeof MatrixConfigSchema>;
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<string | number>;
/**
* 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<MatrixConfigSchemaValue["replyToMode"]>;
export type MatrixRoomConfig = NonNullable<z.infer<typeof matrixRoomSchema>>;
export type MatrixStreamingConfig = z.infer<typeof matrixStreamingSchema>;
export type MatrixStreamingMode = NonNullable<MatrixStreamingConfig["mode"]>;
type MatrixDmConfig = NonNullable<MatrixConfigSchemaValue["dm"]> & {
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<string | number>;
/** 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<string | number>;
/** 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<MatrixConfig, "accounts">;
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<string, MatrixAccountConfig>;
/** 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<string | number>;
/** 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<string | number>;
/** 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<string, MatrixRoomConfig>;
/** @deprecated Use groups. */
rooms?: Record<string, MatrixRoomConfig>;
/** 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<string, MatrixAccountConfig>;
};
export type CoreConfig = {