From ed2798417e002cf8a295eac1642bfadf96e11b86 Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Thu, 26 Mar 2026 23:56:16 -0500 Subject: [PATCH] check: restore bundled channel config metadata gate --- package.json | 8 +- ...enerate-bundled-channel-config-metadata.ts | 212 + ...ndled-channel-config-metadata.generated.ts | 14583 ++++++++++++++++ 3 files changed, 14799 insertions(+), 4 deletions(-) create mode 100644 scripts/generate-bundled-channel-config-metadata.ts create mode 100644 src/config/bundled-channel-config-metadata.generated.ts diff --git a/package.json b/package.json index 6779c237ca2..8d1bd44074c 100644 --- a/package.json +++ b/package.json @@ -682,17 +682,17 @@ "canon:check:json": "node scripts/canon.mjs check --json", "canon:enforce": "node scripts/canon.mjs enforce --json", "canvas:a2ui:bundle": "bash scripts/bundle-a2ui.sh", - "check": "pnpm check:no-conflict-markers && pnpm check:host-env-policy:swift && pnpm check:base-config-schema && pnpm check:bundled-plugin-metadata && pnpm check:bundled-provider-auth-env-vars && pnpm format:check && pnpm tsgo && pnpm plugin-sdk:check-exports && pnpm lint && pnpm lint:tmp:no-random-messaging && pnpm lint:tmp:channel-agnostic-boundaries && pnpm lint:tmp:no-raw-channel-fetch && pnpm lint:agent:ingress-owner && pnpm lint:plugins:no-register-http-handler && pnpm lint:plugins:no-monolithic-plugin-sdk-entry-imports && pnpm lint:plugins:no-extension-src-imports && pnpm lint:plugins:no-extension-test-core-imports && pnpm lint:plugins:no-extension-imports && pnpm lint:plugins:plugin-sdk-subpaths-exported && pnpm lint:extensions:no-src-outside-plugin-sdk && pnpm lint:extensions:no-plugin-sdk-internal && pnpm lint:extensions:no-relative-outside-package && pnpm lint:web-search-provider-boundaries && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope", + "check": "pnpm check:no-conflict-markers && pnpm check:host-env-policy:swift && pnpm check:bundled-channel-config-metadata && pnpm check:base-config-schema && pnpm check:bundled-plugin-metadata && pnpm check:bundled-provider-auth-env-vars && pnpm format:check && pnpm tsgo && pnpm plugin-sdk:check-exports && pnpm lint && pnpm lint:tmp:no-random-messaging && pnpm lint:tmp:channel-agnostic-boundaries && pnpm lint:tmp:no-raw-channel-fetch && pnpm lint:agent:ingress-owner && pnpm lint:plugins:no-register-http-handler && pnpm lint:plugins:no-monolithic-plugin-sdk-entry-imports && pnpm lint:plugins:no-extension-src-imports && pnpm lint:plugins:no-extension-test-core-imports && pnpm lint:plugins:no-extension-imports && pnpm lint:plugins:plugin-sdk-subpaths-exported && pnpm lint:extensions:no-src-outside-plugin-sdk && pnpm lint:extensions:no-plugin-sdk-internal && pnpm lint:extensions:no-relative-outside-package && pnpm lint:web-search-provider-boundaries && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope", "check:base-config-schema": "node --import tsx scripts/generate-base-config-schema.ts --check", - "check:bundled-channel-config-metadata": "node scripts/generate-bundled-plugin-metadata.mjs --check", + "check:bundled-channel-config-metadata": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --check", "check:bundled-plugin-metadata": "node scripts/generate-bundled-plugin-metadata.mjs --check", "check:bundled-provider-auth-env-vars": "node scripts/generate-bundled-provider-auth-env-vars.mjs --check", "check:docs": "pnpm format:docs:check && pnpm lint:docs && pnpm docs:check-i18n-glossary && pnpm docs:check-links", "check:host-env-policy:swift": "node scripts/generate-host-env-security-policy-swift.mjs --check", "check:loc": "node --import tsx scripts/check-ts-max-loc.ts --max 500", "check:no-conflict-markers": "node scripts/check-no-conflict-markers.mjs", - "config:channels:check": "node scripts/generate-bundled-plugin-metadata.mjs --check", - "config:channels:gen": "node scripts/generate-bundled-plugin-metadata.mjs", + "config:channels:check": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --check", + "config:channels:gen": "node --import tsx scripts/generate-bundled-channel-config-metadata.ts --write", "config:docs:check": "node --import tsx scripts/generate-config-doc-baseline.ts --check", "config:docs:gen": "node --import tsx scripts/generate-config-doc-baseline.ts --write", "config:schema:check": "node --import tsx scripts/generate-base-config-schema.ts --check", diff --git a/scripts/generate-bundled-channel-config-metadata.ts b/scripts/generate-bundled-channel-config-metadata.ts new file mode 100644 index 00000000000..2d009748dfc --- /dev/null +++ b/scripts/generate-bundled-channel-config-metadata.ts @@ -0,0 +1,212 @@ +#!/usr/bin/env node +import fs from "node:fs"; +import path from "node:path"; +import { loadChannelConfigSurfaceModule } from "./load-channel-config-surface.ts"; + +const GENERATED_BY = "scripts/generate-bundled-channel-config-metadata.ts"; +const DEFAULT_OUTPUT_PATH = "src/config/bundled-channel-config-metadata.generated.ts"; + +type BundledPluginSource = { + dirName: string; + pluginDir: string; + manifestPath: string; + manifest: { + id: string; + channels?: unknown; + name?: string; + description?: string; + } & Record; + packageJson?: Record; +}; + +const { collectBundledPluginSources } = (await import( + new URL("./lib/bundled-plugin-source-utils.mjs", import.meta.url).href +)) as { + collectBundledPluginSources: (params?: { + repoRoot?: string; + requirePackageJson?: boolean; + }) => BundledPluginSource[]; +}; + +const { formatGeneratedModule } = (await import( + new URL("./lib/format-generated-module.mjs", import.meta.url).href +)) as { + formatGeneratedModule: ( + source: string, + options: { + repoRoot: string; + outputPath: string; + errorLabel: string; + }, + ) => string; +}; + +const { writeGeneratedOutput } = (await import( + new URL("./lib/generated-output-utils.mjs", import.meta.url).href +)) as { + writeGeneratedOutput: (params: { + repoRoot: string; + outputPath: string; + next: string; + check?: boolean; + }) => { + changed: boolean; + wrote: boolean; + outputPath: string; + }; +}; + +type BundledChannelConfigMetadata = { + pluginId: string; + channelId: string; + label?: string; + description?: string; + schema: Record; + uiHints?: Record; +}; + +function resolveChannelConfigSchemaModulePath(rootDir: string): string | null { + const candidates = [ + path.join(rootDir, "src", "config-schema.ts"), + path.join(rootDir, "src", "config-schema.js"), + path.join(rootDir, "src", "config-schema.mts"), + path.join(rootDir, "src", "config-schema.mjs"), + ]; + for (const candidate of candidates) { + if (fs.existsSync(candidate)) { + return candidate; + } + } + return null; +} + +function resolvePackageChannelMeta(source: BundledPluginSource) { + const openclawMeta = + source.packageJson && + typeof source.packageJson === "object" && + !Array.isArray(source.packageJson) && + "openclaw" in source.packageJson + ? (source.packageJson.openclaw as Record | undefined) + : undefined; + const channelMeta = + openclawMeta && + typeof openclawMeta.channel === "object" && + openclawMeta.channel && + !Array.isArray(openclawMeta.channel) + ? (openclawMeta.channel as Record) + : undefined; + return channelMeta; +} + +function resolveRootLabel(source: BundledPluginSource, channelId: string): string | undefined { + const channelMeta = resolvePackageChannelMeta(source); + if (channelMeta?.id === channelId && typeof channelMeta.label === "string") { + return channelMeta.label.trim(); + } + if (typeof source.manifest?.name === "string" && source.manifest.name.trim()) { + return source.manifest.name.trim(); + } + return undefined; +} + +function resolveRootDescription( + source: BundledPluginSource, + channelId: string, +): string | undefined { + const channelMeta = resolvePackageChannelMeta(source); + if (channelMeta?.id === channelId && typeof channelMeta.blurb === "string") { + return channelMeta.blurb.trim(); + } + if (typeof source.manifest?.description === "string" && source.manifest.description.trim()) { + return source.manifest.description.trim(); + } + return undefined; +} + +function formatTypeScriptModule(source: string, outputPath: string, repoRoot: string): string { + return formatGeneratedModule(source, { + repoRoot, + outputPath, + errorLabel: "bundled channel config metadata", + }); +} + +export async function collectBundledChannelConfigMetadata(params?: { repoRoot?: string }) { + const repoRoot = path.resolve(params?.repoRoot ?? process.cwd()); + const sources = collectBundledPluginSources({ repoRoot, requirePackageJson: true }); + const entries: BundledChannelConfigMetadata[] = []; + + for (const source of sources) { + const channelIds = Array.isArray(source.manifest?.channels) + ? source.manifest.channels.filter( + (entry: unknown): entry is string => typeof entry === "string" && entry.trim().length > 0, + ) + : []; + if (channelIds.length === 0) { + continue; + } + const modulePath = resolveChannelConfigSchemaModulePath(source.pluginDir); + if (!modulePath) { + continue; + } + const surface = await loadChannelConfigSurfaceModule(modulePath, { repoRoot }); + if (!surface?.schema) { + continue; + } + for (const channelId of channelIds) { + const label = resolveRootLabel(source, channelId); + const description = resolveRootDescription(source, channelId); + entries.push({ + pluginId: String(source.manifest.id), + channelId, + ...(label ? { label } : {}), + ...(description ? { description } : {}), + schema: surface.schema, + ...(Object.keys(surface.uiHints ?? {}).length > 0 ? { uiHints: surface.uiHints } : {}), + }); + } + } + + return entries.toSorted((left, right) => left.channelId.localeCompare(right.channelId)); +} + +export async function writeBundledChannelConfigMetadataModule(params?: { + repoRoot?: string; + outputPath?: string; + check?: boolean; +}) { + const repoRoot = path.resolve(params?.repoRoot ?? process.cwd()); + const outputPath = params?.outputPath ?? DEFAULT_OUTPUT_PATH; + const entries = await collectBundledChannelConfigMetadata({ repoRoot }); + const next = formatTypeScriptModule( + `// Auto-generated by ${GENERATED_BY}. Do not edit directly. + +export const GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA = ${JSON.stringify(entries, null, 2)} as const; +`, + outputPath, + repoRoot, + ); + return writeGeneratedOutput({ + repoRoot, + outputPath, + next, + check: params?.check, + }); +} + +if (import.meta.url === new URL(process.argv[1] ?? "", "file://").href) { + const check = process.argv.includes("--check"); + const result = await writeBundledChannelConfigMetadataModule({ check }); + if (!result.changed) { + process.exitCode = 0; + } else if (check) { + console.error( + `[bundled-channel-config-metadata] stale generated output at ${path.relative(process.cwd(), result.outputPath)}`, + ); + process.exitCode = 1; + } else { + console.log( + `[bundled-channel-config-metadata] wrote ${path.relative(process.cwd(), result.outputPath)}`, + ); + } +} diff --git a/src/config/bundled-channel-config-metadata.generated.ts b/src/config/bundled-channel-config-metadata.generated.ts new file mode 100644 index 00000000000..1a3d18e4164 --- /dev/null +++ b/src/config/bundled-channel-config-metadata.generated.ts @@ -0,0 +1,14583 @@ +// Auto-generated by scripts/generate-bundled-channel-config-metadata.ts. Do not edit directly. + +export const GENERATED_BUNDLED_CHANNEL_CONFIG_METADATA = [ + { + pluginId: "bluebubbles", + channelId: "bluebubbles", + label: "BlueBubbles", + description: "iMessage via the BlueBubbles mac app + REST API.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + serverUrl: { + type: "string", + }, + password: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + webhookPath: { + type: "string", + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + enrichGroupParticipantsFromContacts: { + default: true, + type: "boolean", + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + mediaMaxMb: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + mediaLocalRoots: { + type: "array", + items: { + type: "string", + }, + }, + sendReadReceipts: { + type: "boolean", + }, + allowPrivateNetwork: { + type: "boolean", + }, + blockStreaming: { + type: "boolean", + }, + groups: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + }, + accounts: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + serverUrl: { + type: "string", + }, + password: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + webhookPath: { + type: "string", + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + enrichGroupParticipantsFromContacts: { + default: true, + type: "boolean", + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + mediaMaxMb: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + mediaLocalRoots: { + type: "array", + items: { + type: "string", + }, + }, + sendReadReceipts: { + type: "boolean", + }, + allowPrivateNetwork: { + type: "boolean", + }, + blockStreaming: { + type: "boolean", + }, + groups: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + }, + }, + required: ["enrichGroupParticipantsFromContacts"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + actions: { + type: "object", + properties: { + reactions: { + default: true, + type: "boolean", + }, + edit: { + default: true, + type: "boolean", + }, + unsend: { + default: true, + type: "boolean", + }, + reply: { + default: true, + type: "boolean", + }, + sendWithEffect: { + default: true, + type: "boolean", + }, + renameGroup: { + default: true, + type: "boolean", + }, + setGroupIcon: { + default: true, + type: "boolean", + }, + addParticipant: { + default: true, + type: "boolean", + }, + removeParticipant: { + default: true, + type: "boolean", + }, + leaveGroup: { + default: true, + type: "boolean", + }, + sendAttachment: { + default: true, + type: "boolean", + }, + }, + required: [ + "reactions", + "edit", + "unsend", + "reply", + "sendWithEffect", + "renameGroup", + "setGroupIcon", + "addParticipant", + "removeParticipant", + "leaveGroup", + "sendAttachment", + ], + additionalProperties: false, + }, + }, + required: ["enrichGroupParticipantsFromContacts"], + additionalProperties: false, + }, + }, + { + pluginId: "discord", + channelId: "discord", + label: "Discord", + description: "very well supported right now.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + commands: { + type: "object", + properties: { + native: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + nativeSkills: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + token: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + proxy: { + type: "string", + }, + allowBots: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "mentions", + }, + ], + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + streaming: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + enum: ["off", "partial", "block", "progress"], + }, + ], + }, + streamMode: { + type: "string", + enum: ["partial", "block", "off"], + }, + draftChunk: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + breakPreference: { + anyOf: [ + { + type: "string", + const: "paragraph", + }, + { + type: "string", + const: "newline", + }, + { + type: "string", + const: "sentence", + }, + ], + }, + }, + additionalProperties: false, + }, + maxLinesPerMessage: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + retry: { + type: "object", + properties: { + attempts: { + type: "integer", + minimum: 1, + maximum: 9007199254740991, + }, + minDelayMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + maxDelayMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + jitter: { + type: "number", + minimum: 0, + maximum: 1, + }, + }, + additionalProperties: false, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + stickers: { + type: "boolean", + }, + emojiUploads: { + type: "boolean", + }, + stickerUploads: { + type: "boolean", + }, + polls: { + type: "boolean", + }, + permissions: { + type: "boolean", + }, + messages: { + type: "boolean", + }, + threads: { + type: "boolean", + }, + pins: { + type: "boolean", + }, + search: { + type: "boolean", + }, + memberInfo: { + type: "boolean", + }, + roleInfo: { + type: "boolean", + }, + roles: { + type: "boolean", + }, + channelInfo: { + type: "boolean", + }, + voiceStatus: { + type: "boolean", + }, + events: { + type: "boolean", + }, + moderation: { + type: "boolean", + }, + channels: { + type: "boolean", + }, + presence: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + type: "string", + }, + dm: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + policy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupEnabled: { + type: "boolean", + }, + groupChannels: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + }, + additionalProperties: false, + }, + guilds: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + slug: { + type: "string", + }, + requireMention: { + type: "boolean", + }, + ignoreOtherMentions: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all", "allowlist"], + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + roles: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + channels: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + ignoreOtherMentions: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + roles: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + includeThreadStarter: { + type: "boolean", + }, + autoThread: { + type: "boolean", + }, + autoThreadName: { + type: "string", + enum: ["message", "generated"], + }, + autoArchiveDuration: { + anyOf: [ + { + type: "string", + enum: ["60", "1440", "4320", "10080"], + }, + { + type: "number", + const: 60, + }, + { + type: "number", + const: 1440, + }, + { + type: "number", + const: 4320, + }, + { + type: "number", + const: 10080, + }, + ], + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + execApprovals: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + approvers: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + agentFilter: { + type: "array", + items: { + type: "string", + }, + }, + sessionFilter: { + type: "array", + items: { + type: "string", + }, + }, + cleanupAfterResolve: { + type: "boolean", + }, + target: { + type: "string", + enum: ["dm", "channel", "both"], + }, + }, + additionalProperties: false, + }, + agentComponents: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + ui: { + type: "object", + properties: { + components: { + type: "object", + properties: { + accentColor: { + type: "string", + pattern: "^#?[0-9a-fA-F]{6}$", + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + slashCommand: { + type: "object", + properties: { + ephemeral: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + threadBindings: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + idleHours: { + type: "number", + minimum: 0, + }, + maxAgeHours: { + type: "number", + minimum: 0, + }, + spawnSubagentSessions: { + type: "boolean", + }, + spawnAcpSessions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + intents: { + type: "object", + properties: { + presence: { + type: "boolean", + }, + guildMembers: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + voice: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + autoJoin: { + type: "array", + items: { + type: "object", + properties: { + guildId: { + type: "string", + minLength: 1, + }, + channelId: { + type: "string", + minLength: 1, + }, + }, + required: ["guildId", "channelId"], + additionalProperties: false, + }, + }, + daveEncryption: { + type: "boolean", + }, + decryptionFailureTolerance: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + tts: { + type: "object", + properties: { + auto: { + type: "string", + enum: ["off", "always", "inbound", "tagged"], + }, + enabled: { + type: "boolean", + }, + mode: { + type: "string", + enum: ["final", "all"], + }, + provider: { + type: "string", + minLength: 1, + }, + summaryModel: { + type: "string", + }, + modelOverrides: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allowText: { + type: "boolean", + }, + allowProvider: { + type: "boolean", + }, + allowVoice: { + type: "boolean", + }, + allowModelId: { + type: "boolean", + }, + allowVoiceSettings: { + type: "boolean", + }, + allowNormalization: { + type: "boolean", + }, + allowSeed: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + elevenlabs: { + type: "object", + properties: { + apiKey: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + baseUrl: { + type: "string", + }, + voiceId: { + type: "string", + }, + modelId: { + type: "string", + }, + seed: { + type: "integer", + minimum: 0, + maximum: 4294967295, + }, + applyTextNormalization: { + type: "string", + enum: ["auto", "on", "off"], + }, + languageCode: { + type: "string", + }, + voiceSettings: { + type: "object", + properties: { + stability: { + type: "number", + minimum: 0, + maximum: 1, + }, + similarityBoost: { + type: "number", + minimum: 0, + maximum: 1, + }, + style: { + type: "number", + minimum: 0, + maximum: 1, + }, + useSpeakerBoost: { + type: "boolean", + }, + speed: { + type: "number", + minimum: 0.5, + maximum: 2, + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + openai: { + type: "object", + properties: { + apiKey: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + baseUrl: { + type: "string", + }, + model: { + type: "string", + }, + voice: { + type: "string", + }, + speed: { + type: "number", + minimum: 0.25, + maximum: 4, + }, + instructions: { + type: "string", + }, + }, + additionalProperties: false, + }, + edge: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + voice: { + type: "string", + }, + lang: { + type: "string", + }, + outputFormat: { + type: "string", + }, + pitch: { + type: "string", + }, + rate: { + type: "string", + }, + volume: { + type: "string", + }, + saveSubtitles: { + type: "boolean", + }, + proxy: { + type: "string", + }, + timeoutMs: { + type: "integer", + minimum: 1000, + maximum: 120000, + }, + }, + additionalProperties: false, + }, + microsoft: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + voice: { + type: "string", + }, + lang: { + type: "string", + }, + outputFormat: { + type: "string", + }, + pitch: { + type: "string", + }, + rate: { + type: "string", + }, + volume: { + type: "string", + }, + saveSubtitles: { + type: "boolean", + }, + proxy: { + type: "string", + }, + timeoutMs: { + type: "integer", + minimum: 1000, + maximum: 120000, + }, + }, + additionalProperties: false, + }, + prefsPath: { + type: "string", + }, + maxTextLength: { + type: "integer", + minimum: 1, + maximum: 9007199254740991, + }, + timeoutMs: { + type: "integer", + minimum: 1000, + maximum: 120000, + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + pluralkit: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + token: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + ackReaction: { + type: "string", + }, + ackReactionScope: { + type: "string", + enum: ["group-mentions", "group-all", "direct", "all", "off", "none"], + }, + activity: { + type: "string", + }, + status: { + type: "string", + enum: ["online", "dnd", "idle", "invisible"], + }, + autoPresence: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + intervalMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + minUpdateIntervalMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + healthyText: { + type: "string", + }, + degradedText: { + type: "string", + }, + exhaustedText: { + type: "string", + }, + }, + additionalProperties: false, + }, + activityType: { + anyOf: [ + { + type: "number", + const: 0, + }, + { + type: "number", + const: 1, + }, + { + type: "number", + const: 2, + }, + { + type: "number", + const: 3, + }, + { + type: "number", + const: 4, + }, + { + type: "number", + const: 5, + }, + ], + }, + activityUrl: { + type: "string", + format: "uri", + }, + inboundWorker: { + type: "object", + properties: { + runTimeoutMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + eventQueue: { + type: "object", + properties: { + listenerTimeout: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxQueueSize: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxConcurrency: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + commands: { + type: "object", + properties: { + native: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + nativeSkills: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + token: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + proxy: { + type: "string", + }, + allowBots: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "mentions", + }, + ], + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + streaming: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + enum: ["off", "partial", "block", "progress"], + }, + ], + }, + streamMode: { + type: "string", + enum: ["partial", "block", "off"], + }, + draftChunk: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + breakPreference: { + anyOf: [ + { + type: "string", + const: "paragraph", + }, + { + type: "string", + const: "newline", + }, + { + type: "string", + const: "sentence", + }, + ], + }, + }, + additionalProperties: false, + }, + maxLinesPerMessage: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + retry: { + type: "object", + properties: { + attempts: { + type: "integer", + minimum: 1, + maximum: 9007199254740991, + }, + minDelayMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + maxDelayMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + jitter: { + type: "number", + minimum: 0, + maximum: 1, + }, + }, + additionalProperties: false, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + stickers: { + type: "boolean", + }, + emojiUploads: { + type: "boolean", + }, + stickerUploads: { + type: "boolean", + }, + polls: { + type: "boolean", + }, + permissions: { + type: "boolean", + }, + messages: { + type: "boolean", + }, + threads: { + type: "boolean", + }, + pins: { + type: "boolean", + }, + search: { + type: "boolean", + }, + memberInfo: { + type: "boolean", + }, + roleInfo: { + type: "boolean", + }, + roles: { + type: "boolean", + }, + channelInfo: { + type: "boolean", + }, + voiceStatus: { + type: "boolean", + }, + events: { + type: "boolean", + }, + moderation: { + type: "boolean", + }, + channels: { + type: "boolean", + }, + presence: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + type: "string", + }, + dm: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + policy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupEnabled: { + type: "boolean", + }, + groupChannels: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + }, + additionalProperties: false, + }, + guilds: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + slug: { + type: "string", + }, + requireMention: { + type: "boolean", + }, + ignoreOtherMentions: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all", "allowlist"], + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + roles: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + channels: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + ignoreOtherMentions: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + roles: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + includeThreadStarter: { + type: "boolean", + }, + autoThread: { + type: "boolean", + }, + autoThreadName: { + type: "string", + enum: ["message", "generated"], + }, + autoArchiveDuration: { + anyOf: [ + { + type: "string", + enum: ["60", "1440", "4320", "10080"], + }, + { + type: "number", + const: 60, + }, + { + type: "number", + const: 1440, + }, + { + type: "number", + const: 4320, + }, + { + type: "number", + const: 10080, + }, + ], + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + execApprovals: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + approvers: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + agentFilter: { + type: "array", + items: { + type: "string", + }, + }, + sessionFilter: { + type: "array", + items: { + type: "string", + }, + }, + cleanupAfterResolve: { + type: "boolean", + }, + target: { + type: "string", + enum: ["dm", "channel", "both"], + }, + }, + additionalProperties: false, + }, + agentComponents: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + ui: { + type: "object", + properties: { + components: { + type: "object", + properties: { + accentColor: { + type: "string", + pattern: "^#?[0-9a-fA-F]{6}$", + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + slashCommand: { + type: "object", + properties: { + ephemeral: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + threadBindings: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + idleHours: { + type: "number", + minimum: 0, + }, + maxAgeHours: { + type: "number", + minimum: 0, + }, + spawnSubagentSessions: { + type: "boolean", + }, + spawnAcpSessions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + intents: { + type: "object", + properties: { + presence: { + type: "boolean", + }, + guildMembers: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + voice: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + autoJoin: { + type: "array", + items: { + type: "object", + properties: { + guildId: { + type: "string", + minLength: 1, + }, + channelId: { + type: "string", + minLength: 1, + }, + }, + required: ["guildId", "channelId"], + additionalProperties: false, + }, + }, + daveEncryption: { + type: "boolean", + }, + decryptionFailureTolerance: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + tts: { + type: "object", + properties: { + auto: { + type: "string", + enum: ["off", "always", "inbound", "tagged"], + }, + enabled: { + type: "boolean", + }, + mode: { + type: "string", + enum: ["final", "all"], + }, + provider: { + type: "string", + minLength: 1, + }, + summaryModel: { + type: "string", + }, + modelOverrides: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allowText: { + type: "boolean", + }, + allowProvider: { + type: "boolean", + }, + allowVoice: { + type: "boolean", + }, + allowModelId: { + type: "boolean", + }, + allowVoiceSettings: { + type: "boolean", + }, + allowNormalization: { + type: "boolean", + }, + allowSeed: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + elevenlabs: { + type: "object", + properties: { + apiKey: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + baseUrl: { + type: "string", + }, + voiceId: { + type: "string", + }, + modelId: { + type: "string", + }, + seed: { + type: "integer", + minimum: 0, + maximum: 4294967295, + }, + applyTextNormalization: { + type: "string", + enum: ["auto", "on", "off"], + }, + languageCode: { + type: "string", + }, + voiceSettings: { + type: "object", + properties: { + stability: { + type: "number", + minimum: 0, + maximum: 1, + }, + similarityBoost: { + type: "number", + minimum: 0, + maximum: 1, + }, + style: { + type: "number", + minimum: 0, + maximum: 1, + }, + useSpeakerBoost: { + type: "boolean", + }, + speed: { + type: "number", + minimum: 0.5, + maximum: 2, + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + openai: { + type: "object", + properties: { + apiKey: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + baseUrl: { + type: "string", + }, + model: { + type: "string", + }, + voice: { + type: "string", + }, + speed: { + type: "number", + minimum: 0.25, + maximum: 4, + }, + instructions: { + type: "string", + }, + }, + additionalProperties: false, + }, + edge: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + voice: { + type: "string", + }, + lang: { + type: "string", + }, + outputFormat: { + type: "string", + }, + pitch: { + type: "string", + }, + rate: { + type: "string", + }, + volume: { + type: "string", + }, + saveSubtitles: { + type: "boolean", + }, + proxy: { + type: "string", + }, + timeoutMs: { + type: "integer", + minimum: 1000, + maximum: 120000, + }, + }, + additionalProperties: false, + }, + microsoft: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + voice: { + type: "string", + }, + lang: { + type: "string", + }, + outputFormat: { + type: "string", + }, + pitch: { + type: "string", + }, + rate: { + type: "string", + }, + volume: { + type: "string", + }, + saveSubtitles: { + type: "boolean", + }, + proxy: { + type: "string", + }, + timeoutMs: { + type: "integer", + minimum: 1000, + maximum: 120000, + }, + }, + additionalProperties: false, + }, + prefsPath: { + type: "string", + }, + maxTextLength: { + type: "integer", + minimum: 1, + maximum: 9007199254740991, + }, + timeoutMs: { + type: "integer", + minimum: 1000, + maximum: 120000, + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + pluralkit: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + token: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + ackReaction: { + type: "string", + }, + ackReactionScope: { + type: "string", + enum: ["group-mentions", "group-all", "direct", "all", "off", "none"], + }, + activity: { + type: "string", + }, + status: { + type: "string", + enum: ["online", "dnd", "idle", "invisible"], + }, + autoPresence: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + intervalMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + minUpdateIntervalMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + healthyText: { + type: "string", + }, + degradedText: { + type: "string", + }, + exhaustedText: { + type: "string", + }, + }, + additionalProperties: false, + }, + activityType: { + anyOf: [ + { + type: "number", + const: 0, + }, + { + type: "number", + const: 1, + }, + { + type: "number", + const: 2, + }, + { + type: "number", + const: 3, + }, + { + type: "number", + const: 4, + }, + { + type: "number", + const: 5, + }, + ], + }, + activityUrl: { + type: "string", + format: "uri", + }, + inboundWorker: { + type: "object", + properties: { + runTimeoutMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + eventQueue: { + type: "object", + properties: { + listenerTimeout: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxQueueSize: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxConcurrency: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + required: ["groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "feishu", + channelId: "feishu", + label: "Feishu", + description: "飞书/Lark enterprise messaging with doc/wiki/drive tools.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + enabled: { + type: "boolean", + }, + defaultAccount: { + type: "string", + }, + appId: { + type: "string", + }, + appSecret: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + encryptKey: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + verificationToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + domain: { + default: "feishu", + anyOf: [ + { + type: "string", + enum: ["feishu", "lark"], + }, + { + type: "string", + format: "uri", + pattern: "^https:\\/\\/.*", + }, + ], + }, + connectionMode: { + default: "websocket", + type: "string", + enum: ["websocket", "webhook"], + }, + webhookPath: { + default: "/feishu/events", + type: "string", + }, + webhookHost: { + type: "string", + }, + webhookPort: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + mode: { + type: "string", + enum: ["native", "escape", "strip"], + }, + tableMode: { + type: "string", + enum: ["native", "ascii", "simple"], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["open", "pairing", "allowlist"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + anyOf: [ + { + type: "string", + enum: ["open", "allowlist", "disabled"], + }, + {}, + ], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupSenderAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + requireMention: { + type: "boolean", + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + groupSessionScope: { + type: "string", + enum: ["group", "group_sender", "group_topic", "group_topic_sender"], + }, + topicSessionMode: { + type: "string", + enum: ["disabled", "enabled"], + }, + replyInThread: { + type: "string", + enum: ["disabled", "enabled"], + }, + }, + additionalProperties: false, + }, + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreamingCoalesce: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + minDelayMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxDelayMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + httpTimeoutMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 300000, + }, + heartbeat: { + type: "object", + properties: { + visibility: { + type: "string", + enum: ["visible", "hidden"], + }, + intervalMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + renderMode: { + type: "string", + enum: ["auto", "raw", "card"], + }, + streaming: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + doc: { + type: "boolean", + }, + chat: { + type: "boolean", + }, + wiki: { + type: "boolean", + }, + drive: { + type: "boolean", + }, + perm: { + type: "boolean", + }, + scopes: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + replyInThread: { + type: "string", + enum: ["disabled", "enabled"], + }, + reactionNotifications: { + default: "own", + type: "string", + enum: ["off", "own", "all"], + }, + typingIndicator: { + default: true, + type: "boolean", + }, + resolveSenderNames: { + default: true, + type: "boolean", + }, + groupSessionScope: { + type: "string", + enum: ["group", "group_sender", "group_topic", "group_topic_sender"], + }, + topicSessionMode: { + type: "string", + enum: ["disabled", "enabled"], + }, + dynamicAgentCreation: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + workspaceTemplate: { + type: "string", + }, + agentDirTemplate: { + type: "string", + }, + maxAgents: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + name: { + type: "string", + }, + appId: { + type: "string", + }, + appSecret: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + encryptKey: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + verificationToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + domain: { + anyOf: [ + { + type: "string", + enum: ["feishu", "lark"], + }, + { + type: "string", + format: "uri", + pattern: "^https:\\/\\/.*", + }, + ], + }, + connectionMode: { + type: "string", + enum: ["websocket", "webhook"], + }, + webhookPath: { + type: "string", + }, + webhookHost: { + type: "string", + }, + webhookPort: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + mode: { + type: "string", + enum: ["native", "escape", "strip"], + }, + tableMode: { + type: "string", + enum: ["native", "ascii", "simple"], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + dmPolicy: { + type: "string", + enum: ["open", "pairing", "allowlist"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + anyOf: [ + { + type: "string", + enum: ["open", "allowlist", "disabled"], + }, + {}, + ], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupSenderAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + requireMention: { + type: "boolean", + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + groupSessionScope: { + type: "string", + enum: ["group", "group_sender", "group_topic", "group_topic_sender"], + }, + topicSessionMode: { + type: "string", + enum: ["disabled", "enabled"], + }, + replyInThread: { + type: "string", + enum: ["disabled", "enabled"], + }, + }, + additionalProperties: false, + }, + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreamingCoalesce: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + minDelayMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxDelayMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + httpTimeoutMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 300000, + }, + heartbeat: { + type: "object", + properties: { + visibility: { + type: "string", + enum: ["visible", "hidden"], + }, + intervalMs: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + renderMode: { + type: "string", + enum: ["auto", "raw", "card"], + }, + streaming: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + doc: { + type: "boolean", + }, + chat: { + type: "boolean", + }, + wiki: { + type: "boolean", + }, + drive: { + type: "boolean", + }, + perm: { + type: "boolean", + }, + scopes: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + replyInThread: { + type: "string", + enum: ["disabled", "enabled"], + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all"], + }, + typingIndicator: { + type: "boolean", + }, + resolveSenderNames: { + type: "boolean", + }, + groupSessionScope: { + type: "string", + enum: ["group", "group_sender", "group_topic", "group_topic_sender"], + }, + topicSessionMode: { + type: "string", + enum: ["disabled", "enabled"], + }, + }, + additionalProperties: false, + }, + }, + }, + required: [ + "domain", + "connectionMode", + "webhookPath", + "dmPolicy", + "groupPolicy", + "reactionNotifications", + "typingIndicator", + "resolveSenderNames", + ], + additionalProperties: false, + }, + }, + { + pluginId: "googlechat", + channelId: "googlechat", + label: "Google Chat", + description: "Google Workspace Chat app via HTTP webhooks.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + configWrites: { + type: "boolean", + }, + allowBots: { + type: "boolean", + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allow: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + defaultTo: { + type: "string", + }, + serviceAccount: { + anyOf: [ + { + type: "string", + }, + { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: {}, + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + serviceAccountRef: { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + serviceAccountFile: { + type: "string", + }, + audienceType: { + type: "string", + enum: ["app-url", "project-number"], + }, + audience: { + type: "string", + }, + appPrincipal: { + type: "string", + }, + webhookPath: { + type: "string", + }, + webhookUrl: { + type: "string", + }, + botUser: { + type: "string", + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + streamMode: { + default: "replace", + type: "string", + enum: ["replace", "status_final", "append"], + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + dm: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + policy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + }, + required: ["policy"], + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + typingIndicator: { + type: "string", + enum: ["none", "message", "reaction"], + }, + responsePrefix: { + type: "string", + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + configWrites: { + type: "boolean", + }, + allowBots: { + type: "boolean", + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allow: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + defaultTo: { + type: "string", + }, + serviceAccount: { + anyOf: [ + { + type: "string", + }, + { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: {}, + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + serviceAccountRef: { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + serviceAccountFile: { + type: "string", + }, + audienceType: { + type: "string", + enum: ["app-url", "project-number"], + }, + audience: { + type: "string", + }, + appPrincipal: { + type: "string", + }, + webhookPath: { + type: "string", + }, + webhookUrl: { + type: "string", + }, + botUser: { + type: "string", + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + streamMode: { + default: "replace", + type: "string", + enum: ["replace", "status_final", "append"], + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + dm: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + policy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + }, + required: ["policy"], + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + typingIndicator: { + type: "string", + enum: ["none", "message", "reaction"], + }, + responsePrefix: { + type: "string", + }, + }, + required: ["groupPolicy", "streamMode"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["groupPolicy", "streamMode"], + additionalProperties: false, + }, + }, + { + pluginId: "imessage", + channelId: "imessage", + label: "iMessage", + description: "this is still a work in progress.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + configWrites: { + type: "boolean", + }, + cliPath: { + type: "string", + }, + dbPath: { + type: "string", + }, + remoteHost: { + type: "string", + }, + service: { + anyOf: [ + { + type: "string", + const: "imessage", + }, + { + type: "string", + const: "sms", + }, + { + type: "string", + const: "auto", + }, + ], + }, + region: { + type: "string", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + type: "string", + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + includeAttachments: { + type: "boolean", + }, + attachmentRoots: { + type: "array", + items: { + type: "string", + }, + }, + remoteAttachmentRoots: { + type: "array", + items: { + type: "string", + }, + }, + mediaMaxMb: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + configWrites: { + type: "boolean", + }, + cliPath: { + type: "string", + }, + dbPath: { + type: "string", + }, + remoteHost: { + type: "string", + }, + service: { + anyOf: [ + { + type: "string", + const: "imessage", + }, + { + type: "string", + const: "sms", + }, + { + type: "string", + const: "auto", + }, + ], + }, + region: { + type: "string", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + type: "string", + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + includeAttachments: { + type: "boolean", + }, + attachmentRoots: { + type: "array", + items: { + type: "string", + }, + }, + remoteAttachmentRoots: { + type: "array", + items: { + type: "string", + }, + }, + mediaMaxMb: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "irc", + channelId: "irc", + label: "IRC", + description: "classic IRC networks with DM/channel routing and pairing controls.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + host: { + type: "string", + }, + port: { + type: "integer", + minimum: 1, + maximum: 65535, + }, + tls: { + type: "boolean", + }, + nick: { + type: "string", + }, + username: { + type: "string", + }, + realname: { + type: "string", + }, + password: { + type: "string", + }, + passwordFile: { + type: "string", + }, + nickserv: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + service: { + type: "string", + }, + password: { + type: "string", + }, + passwordFile: { + type: "string", + }, + register: { + type: "boolean", + }, + registerEmail: { + type: "string", + }, + }, + additionalProperties: false, + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + channels: { + type: "array", + items: { + type: "string", + }, + }, + mentionPatterns: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + host: { + type: "string", + }, + port: { + type: "integer", + minimum: 1, + maximum: 65535, + }, + tls: { + type: "boolean", + }, + nick: { + type: "string", + }, + username: { + type: "string", + }, + realname: { + type: "string", + }, + password: { + type: "string", + }, + passwordFile: { + type: "string", + }, + nickserv: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + service: { + type: "string", + }, + password: { + type: "string", + }, + passwordFile: { + type: "string", + }, + register: { + type: "boolean", + }, + registerEmail: { + type: "string", + }, + }, + additionalProperties: false, + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + channels: { + type: "array", + items: { + type: "string", + }, + }, + mentionPatterns: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "line", + channelId: "line", + label: "LINE", + description: "LINE Messaging API bot for Japan/Taiwan/Thailand markets.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + enabled: { + type: "boolean", + }, + channelAccessToken: { + type: "string", + }, + channelSecret: { + type: "string", + }, + tokenFile: { + type: "string", + }, + secretFile: { + type: "string", + }, + name: { + type: "string", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["open", "allowlist", "pairing", "disabled"], + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "allowlist", "disabled"], + }, + responsePrefix: { + type: "string", + }, + mediaMaxMb: { + type: "number", + }, + webhookPath: { + type: "string", + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + channelAccessToken: { + type: "string", + }, + channelSecret: { + type: "string", + }, + tokenFile: { + type: "string", + }, + secretFile: { + type: "string", + }, + name: { + type: "string", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["open", "allowlist", "pairing", "disabled"], + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "allowlist", "disabled"], + }, + responsePrefix: { + type: "string", + }, + mediaMaxMb: { + type: "number", + }, + webhookPath: { + type: "string", + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + requireMention: { + type: "boolean", + }, + systemPrompt: { + type: "string", + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + requireMention: { + type: "boolean", + }, + systemPrompt: { + type: "string", + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "matrix", + channelId: "matrix", + label: "Matrix", + description: "open protocol; install the plugin to enable.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + defaultAccount: { + type: "string", + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: {}, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + homeserver: { + type: "string", + }, + allowPrivateNetwork: { + type: "boolean", + }, + userId: { + type: "string", + }, + accessToken: { + type: "string", + }, + password: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + deviceId: { + type: "string", + }, + deviceName: { + type: "string", + }, + avatarUrl: { + type: "string", + }, + initialSyncLimit: { + type: "number", + }, + encryption: { + type: "boolean", + }, + allowlistOnly: { + type: "boolean", + }, + allowBots: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "mentions", + }, + ], + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + replyToMode: { + type: "string", + enum: ["off", "first", "all"], + }, + threadReplies: { + type: "string", + enum: ["off", "inbound", "always"], + }, + textChunkLimit: { + type: "number", + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + responsePrefix: { + type: "string", + }, + ackReaction: { + type: "string", + }, + ackReactionScope: { + type: "string", + enum: ["group-mentions", "group-all", "direct", "all", "none", "off"], + }, + reactionNotifications: { + type: "string", + enum: ["off", "own"], + }, + threadBindings: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + idleHours: { + type: "number", + minimum: 0, + }, + maxAgeHours: { + type: "number", + minimum: 0, + }, + spawnSubagentSessions: { + type: "boolean", + }, + spawnAcpSessions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + startupVerification: { + type: "string", + enum: ["off", "if-unverified"], + }, + startupVerificationCooldownHours: { + type: "number", + }, + mediaMaxMb: { + type: "number", + }, + autoJoin: { + type: "string", + enum: ["always", "allowlist", "off"], + }, + autoJoinAllowlist: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + dm: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + policy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + }, + additionalProperties: false, + }, + groups: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allow: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + allowBots: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "mentions", + }, + ], + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + autoReply: { + type: "boolean", + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + rooms: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allow: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + allowBots: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "mentions", + }, + ], + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + autoReply: { + type: "boolean", + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + messages: { + type: "boolean", + }, + pins: { + type: "boolean", + }, + profile: { + type: "boolean", + }, + memberInfo: { + type: "boolean", + }, + channelInfo: { + type: "boolean", + }, + verification: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + }, + { + pluginId: "mattermost", + channelId: "mattermost", + label: "Mattermost", + description: "self-hosted Slack-style chat; install the plugin to enable.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + configWrites: { + type: "boolean", + }, + botToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + baseUrl: { + type: "string", + }, + chatmode: { + type: "string", + enum: ["oncall", "onmessage", "onchar"], + }, + oncharPrefixes: { + type: "array", + items: { + type: "string", + }, + }, + requireMention: { + type: "boolean", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + replyToMode: { + type: "string", + enum: ["off", "first", "all"], + }, + responsePrefix: { + type: "string", + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + commands: { + type: "object", + properties: { + native: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + nativeSkills: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + callbackPath: { + type: "string", + }, + callbackUrl: { + type: "string", + }, + }, + additionalProperties: false, + }, + interactions: { + type: "object", + properties: { + callbackBaseUrl: { + type: "string", + }, + allowedSourceIps: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + allowPrivateNetwork: { + type: "boolean", + }, + dmChannelRetry: { + type: "object", + properties: { + maxRetries: { + type: "integer", + minimum: 0, + maximum: 10, + }, + initialDelayMs: { + type: "integer", + minimum: 100, + maximum: 60000, + }, + maxDelayMs: { + type: "integer", + minimum: 1000, + maximum: 60000, + }, + timeoutMs: { + type: "integer", + minimum: 5000, + maximum: 120000, + }, + }, + additionalProperties: false, + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + configWrites: { + type: "boolean", + }, + botToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + baseUrl: { + type: "string", + }, + chatmode: { + type: "string", + enum: ["oncall", "onmessage", "onchar"], + }, + oncharPrefixes: { + type: "array", + items: { + type: "string", + }, + }, + requireMention: { + type: "boolean", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + replyToMode: { + type: "string", + enum: ["off", "first", "all"], + }, + responsePrefix: { + type: "string", + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + commands: { + type: "object", + properties: { + native: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + nativeSkills: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + callbackPath: { + type: "string", + }, + callbackUrl: { + type: "string", + }, + }, + additionalProperties: false, + }, + interactions: { + type: "object", + properties: { + callbackBaseUrl: { + type: "string", + }, + allowedSourceIps: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + allowPrivateNetwork: { + type: "boolean", + }, + dmChannelRetry: { + type: "object", + properties: { + maxRetries: { + type: "integer", + minimum: 0, + maximum: 10, + }, + initialDelayMs: { + type: "integer", + minimum: 100, + maximum: 60000, + }, + maxDelayMs: { + type: "integer", + minimum: 1000, + maximum: 60000, + }, + timeoutMs: { + type: "integer", + minimum: 5000, + maximum: 120000, + }, + }, + additionalProperties: false, + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "msteams", + channelId: "msteams", + label: "Microsoft Teams", + description: "Teams SDK; enterprise support.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + enabled: { + type: "boolean", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + appId: { + type: "string", + }, + appPassword: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + tenantId: { + type: "string", + }, + webhook: { + type: "object", + properties: { + port: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + path: { + type: "string", + }, + }, + additionalProperties: false, + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + defaultTo: { + type: "string", + }, + groupAllowFrom: { + type: "array", + items: { + type: "string", + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + mediaAllowHosts: { + type: "array", + items: { + type: "string", + }, + }, + mediaAuthAllowHosts: { + type: "array", + items: { + type: "string", + }, + }, + requireMention: { + type: "boolean", + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + replyStyle: { + type: "string", + enum: ["thread", "top-level"], + }, + teams: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + replyStyle: { + type: "string", + enum: ["thread", "top-level"], + }, + channels: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + replyStyle: { + type: "string", + enum: ["thread", "top-level"], + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + sharePointSiteId: { + type: "string", + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + welcomeCard: { + type: "boolean", + }, + promptStarters: { + type: "array", + items: { + type: "string", + }, + }, + groupWelcomeCard: { + type: "boolean", + }, + feedbackEnabled: { + type: "boolean", + }, + feedbackReflection: { + type: "boolean", + }, + feedbackReflectionCooldownMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "nextcloud-talk", + channelId: "nextcloud-talk", + label: "Nextcloud Talk", + description: "Self-hosted chat via Nextcloud Talk webhook bots.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + baseUrl: { + type: "string", + }, + botSecret: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + botSecretFile: { + type: "string", + }, + apiUser: { + type: "string", + }, + apiPassword: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + apiPasswordFile: { + type: "string", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + webhookPort: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + webhookHost: { + type: "string", + }, + webhookPath: { + type: "string", + }, + webhookPublicUrl: { + type: "string", + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + groupAllowFrom: { + type: "array", + items: { + type: "string", + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + rooms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + allowPrivateNetwork: { + type: "boolean", + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + baseUrl: { + type: "string", + }, + botSecret: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + botSecretFile: { + type: "string", + }, + apiUser: { + type: "string", + }, + apiPassword: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + apiPasswordFile: { + type: "string", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + webhookPort: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + webhookHost: { + type: "string", + }, + webhookPath: { + type: "string", + }, + webhookPublicUrl: { + type: "string", + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + groupAllowFrom: { + type: "array", + items: { + type: "string", + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + rooms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + allowPrivateNetwork: { + type: "boolean", + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "nostr", + channelId: "nostr", + label: "Nostr", + description: "Decentralized protocol; encrypted DMs via NIP-04.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + defaultAccount: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + privateKey: { + type: "string", + }, + relays: { + type: "array", + items: { + type: "string", + }, + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + profile: { + type: "object", + properties: { + name: { + type: "string", + maxLength: 256, + }, + displayName: { + type: "string", + maxLength: 256, + }, + about: { + type: "string", + maxLength: 2000, + }, + picture: { + type: "string", + format: "uri", + }, + banner: { + type: "string", + format: "uri", + }, + website: { + type: "string", + format: "uri", + }, + nip05: { + type: "string", + }, + lud16: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + }, + { + pluginId: "signal", + channelId: "signal", + label: "Signal", + description: 'signal-cli linked device; more setup (David Reagans: "Hop on Discord.").', + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + configWrites: { + type: "boolean", + }, + account: { + type: "string", + }, + accountUuid: { + type: "string", + }, + httpUrl: { + type: "string", + }, + httpHost: { + type: "string", + }, + httpPort: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + cliPath: { + type: "string", + }, + autoStart: { + type: "boolean", + }, + startupTimeoutMs: { + type: "integer", + minimum: 1000, + maximum: 120000, + }, + receiveMode: { + anyOf: [ + { + type: "string", + const: "on-start", + }, + { + type: "string", + const: "manual", + }, + ], + }, + ignoreAttachments: { + type: "boolean", + }, + ignoreStories: { + type: "boolean", + }, + sendReadReceipts: { + type: "boolean", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + type: "string", + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + mediaMaxMb: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all", "allowlist"], + }, + reactionAllowlist: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + reactionLevel: { + type: "string", + enum: ["off", "ack", "minimal", "extensive"], + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + configWrites: { + type: "boolean", + }, + account: { + type: "string", + }, + accountUuid: { + type: "string", + }, + httpUrl: { + type: "string", + }, + httpHost: { + type: "string", + }, + httpPort: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + cliPath: { + type: "string", + }, + autoStart: { + type: "boolean", + }, + startupTimeoutMs: { + type: "integer", + minimum: 1000, + maximum: 120000, + }, + receiveMode: { + anyOf: [ + { + type: "string", + const: "on-start", + }, + { + type: "string", + const: "manual", + }, + ], + }, + ignoreAttachments: { + type: "boolean", + }, + ignoreStories: { + type: "boolean", + }, + sendReadReceipts: { + type: "boolean", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + type: "string", + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + mediaMaxMb: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all", "allowlist"], + }, + reactionAllowlist: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + reactionLevel: { + type: "string", + enum: ["off", "ack", "minimal", "extensive"], + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "slack", + channelId: "slack", + label: "Slack", + description: "supported (Socket Mode).", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + mode: { + default: "socket", + type: "string", + enum: ["socket", "http"], + }, + signingSecret: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + webhookPath: { + default: "/slack/events", + type: "string", + }, + capabilities: { + anyOf: [ + { + type: "array", + items: { + type: "string", + }, + }, + { + type: "object", + properties: { + interactiveReplies: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + ], + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + commands: { + type: "object", + properties: { + native: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + nativeSkills: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + botToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + appToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + userToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + userTokenReadOnly: { + default: true, + type: "boolean", + }, + allowBots: { + type: "boolean", + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + streaming: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + enum: ["off", "partial", "block", "progress"], + }, + ], + }, + nativeStreaming: { + type: "boolean", + }, + streamMode: { + type: "string", + enum: ["replace", "status_final", "append"], + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all", "allowlist"], + }, + reactionAllowlist: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + replyToModeByChatType: { + type: "object", + properties: { + direct: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + group: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + channel: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + }, + additionalProperties: false, + }, + thread: { + type: "object", + properties: { + historyScope: { + type: "string", + enum: ["thread", "channel"], + }, + inheritParent: { + type: "boolean", + }, + initialHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + messages: { + type: "boolean", + }, + pins: { + type: "boolean", + }, + search: { + type: "boolean", + }, + permissions: { + type: "boolean", + }, + memberInfo: { + type: "boolean", + }, + channelInfo: { + type: "boolean", + }, + emojiList: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + slashCommand: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + name: { + type: "string", + }, + sessionPrefix: { + type: "string", + }, + ephemeral: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + type: "string", + }, + dm: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + policy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupEnabled: { + type: "boolean", + }, + groupChannels: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + }, + additionalProperties: false, + }, + channels: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allow: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + allowBots: { + type: "boolean", + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + ackReaction: { + type: "string", + }, + typingReaction: { + type: "string", + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + mode: { + type: "string", + enum: ["socket", "http"], + }, + signingSecret: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + webhookPath: { + type: "string", + }, + capabilities: { + anyOf: [ + { + type: "array", + items: { + type: "string", + }, + }, + { + type: "object", + properties: { + interactiveReplies: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + ], + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + commands: { + type: "object", + properties: { + native: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + nativeSkills: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + botToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + appToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + userToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + userTokenReadOnly: { + default: true, + type: "boolean", + }, + allowBots: { + type: "boolean", + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + streaming: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + enum: ["off", "partial", "block", "progress"], + }, + ], + }, + nativeStreaming: { + type: "boolean", + }, + streamMode: { + type: "string", + enum: ["replace", "status_final", "append"], + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all", "allowlist"], + }, + reactionAllowlist: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + replyToModeByChatType: { + type: "object", + properties: { + direct: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + group: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + channel: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + }, + additionalProperties: false, + }, + thread: { + type: "object", + properties: { + historyScope: { + type: "string", + enum: ["thread", "channel"], + }, + inheritParent: { + type: "boolean", + }, + initialHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + messages: { + type: "boolean", + }, + pins: { + type: "boolean", + }, + search: { + type: "boolean", + }, + permissions: { + type: "boolean", + }, + memberInfo: { + type: "boolean", + }, + channelInfo: { + type: "boolean", + }, + emojiList: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + slashCommand: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + name: { + type: "string", + }, + sessionPrefix: { + type: "string", + }, + ephemeral: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + type: "string", + }, + dm: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + policy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupEnabled: { + type: "boolean", + }, + groupChannels: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + }, + additionalProperties: false, + }, + channels: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + allow: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + allowBots: { + type: "boolean", + }, + users: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + systemPrompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + responsePrefix: { + type: "string", + }, + ackReaction: { + type: "string", + }, + typingReaction: { + type: "string", + }, + }, + required: ["userTokenReadOnly"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["mode", "webhookPath", "userTokenReadOnly", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "synology-chat", + channelId: "synology-chat", + label: "Synology Chat", + description: "Connect your Synology NAS Chat to OpenClaw with full agent capabilities.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + dangerouslyAllowNameMatching: { + type: "boolean", + }, + dangerouslyAllowInheritedWebhookPath: { + type: "boolean", + }, + }, + additionalProperties: {}, + }, + }, + { + pluginId: "telegram", + channelId: "telegram", + label: "Telegram", + description: "simplest way to get started — register a bot with @BotFather and get going.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + anyOf: [ + { + type: "array", + items: { + type: "string", + }, + }, + { + type: "object", + properties: { + inlineButtons: { + type: "string", + enum: ["off", "dm", "group", "all", "allowlist"], + }, + }, + additionalProperties: false, + }, + ], + }, + execApprovals: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + approvers: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + agentFilter: { + type: "array", + items: { + type: "string", + }, + }, + sessionFilter: { + type: "array", + items: { + type: "string", + }, + }, + target: { + type: "string", + enum: ["dm", "channel", "both"], + }, + }, + additionalProperties: false, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + commands: { + type: "object", + properties: { + native: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + nativeSkills: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + }, + additionalProperties: false, + }, + customCommands: { + type: "array", + items: { + type: "object", + properties: { + command: { + type: "string", + }, + description: { + type: "string", + }, + }, + required: ["command", "description"], + additionalProperties: false, + }, + }, + configWrites: { + type: "boolean", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + botToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + tokenFile: { + type: "string", + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + disableAudioPreflight: { + type: "boolean", + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + topics: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + disableAudioPreflight: { + type: "boolean", + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + agentId: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + direct: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + topics: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + disableAudioPreflight: { + type: "boolean", + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + agentId: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + requireTopic: { + type: "boolean", + }, + autoTopicLabel: { + anyOf: [ + { + type: "boolean", + }, + { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + prompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + ], + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + streaming: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + enum: ["off", "partial", "block", "progress"], + }, + ], + }, + blockStreaming: { + type: "boolean", + }, + draftChunk: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + breakPreference: { + anyOf: [ + { + type: "string", + const: "paragraph", + }, + { + type: "string", + const: "newline", + }, + { + type: "string", + const: "sentence", + }, + ], + }, + }, + additionalProperties: false, + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + streamMode: { + type: "string", + enum: ["off", "partial", "block"], + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + timeoutSeconds: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + retry: { + type: "object", + properties: { + attempts: { + type: "integer", + minimum: 1, + maximum: 9007199254740991, + }, + minDelayMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + maxDelayMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + jitter: { + type: "number", + minimum: 0, + maximum: 1, + }, + }, + additionalProperties: false, + }, + network: { + type: "object", + properties: { + autoSelectFamily: { + type: "boolean", + }, + dnsResultOrder: { + type: "string", + enum: ["ipv4first", "verbatim"], + }, + }, + additionalProperties: false, + }, + proxy: { + type: "string", + }, + webhookUrl: { + description: + "Public HTTPS webhook URL registered with Telegram for inbound updates. This must be internet-reachable and requires channels.telegram.webhookSecret.", + type: "string", + }, + webhookSecret: { + description: + "Secret token sent to Telegram during webhook registration and verified on inbound webhook requests. Telegram returns this value for verification; this is not the gateway auth token and not the bot token.", + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + webhookPath: { + description: + "Local webhook route path served by the gateway listener. Defaults to /telegram-webhook.", + type: "string", + }, + webhookHost: { + description: + "Local bind host for the webhook listener. Defaults to 127.0.0.1; keep loopback unless you intentionally expose direct ingress.", + type: "string", + }, + webhookPort: { + description: + "Local bind port for the webhook listener. Defaults to 8787; set to 0 to let the OS assign an ephemeral port.", + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + webhookCertPath: { + description: + "Path to the self-signed certificate (PEM) to upload to Telegram during webhook registration. Required for self-signed certs (direct IP or no domain).", + type: "string", + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + sendMessage: { + type: "boolean", + }, + poll: { + type: "boolean", + }, + deleteMessage: { + type: "boolean", + }, + editMessage: { + type: "boolean", + }, + sticker: { + type: "boolean", + }, + createForumTopic: { + type: "boolean", + }, + editForumTopic: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + threadBindings: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + idleHours: { + type: "number", + minimum: 0, + }, + maxAgeHours: { + type: "number", + minimum: 0, + }, + spawnSubagentSessions: { + type: "boolean", + }, + spawnAcpSessions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all"], + }, + reactionLevel: { + type: "string", + enum: ["off", "ack", "minimal", "extensive"], + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + linkPreview: { + type: "boolean", + }, + silentErrorReplies: { + type: "boolean", + }, + responsePrefix: { + type: "string", + }, + ackReaction: { + type: "string", + }, + apiRoot: { + type: "string", + format: "uri", + }, + autoTopicLabel: { + anyOf: [ + { + type: "boolean", + }, + { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + prompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + ], + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + capabilities: { + anyOf: [ + { + type: "array", + items: { + type: "string", + }, + }, + { + type: "object", + properties: { + inlineButtons: { + type: "string", + enum: ["off", "dm", "group", "all", "allowlist"], + }, + }, + additionalProperties: false, + }, + ], + }, + execApprovals: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + approvers: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + agentFilter: { + type: "array", + items: { + type: "string", + }, + }, + sessionFilter: { + type: "array", + items: { + type: "string", + }, + }, + target: { + type: "string", + enum: ["dm", "channel", "both"], + }, + }, + additionalProperties: false, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + enabled: { + type: "boolean", + }, + commands: { + type: "object", + properties: { + native: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + nativeSkills: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + const: "auto", + }, + ], + }, + }, + additionalProperties: false, + }, + customCommands: { + type: "array", + items: { + type: "object", + properties: { + command: { + type: "string", + }, + description: { + type: "string", + }, + }, + required: ["command", "description"], + additionalProperties: false, + }, + }, + configWrites: { + type: "boolean", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + botToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + tokenFile: { + type: "string", + }, + replyToMode: { + anyOf: [ + { + type: "string", + const: "off", + }, + { + type: "string", + const: "first", + }, + { + type: "string", + const: "all", + }, + ], + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + disableAudioPreflight: { + type: "boolean", + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + topics: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + disableAudioPreflight: { + type: "boolean", + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + agentId: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + defaultTo: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + direct: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + topics: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + disableAudioPreflight: { + type: "boolean", + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + skills: { + type: "array", + items: { + type: "string", + }, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + systemPrompt: { + type: "string", + }, + agentId: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + requireTopic: { + type: "boolean", + }, + autoTopicLabel: { + anyOf: [ + { + type: "boolean", + }, + { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + prompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + ], + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + streaming: { + anyOf: [ + { + type: "boolean", + }, + { + type: "string", + enum: ["off", "partial", "block", "progress"], + }, + ], + }, + blockStreaming: { + type: "boolean", + }, + draftChunk: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + breakPreference: { + anyOf: [ + { + type: "string", + const: "paragraph", + }, + { + type: "string", + const: "newline", + }, + { + type: "string", + const: "sentence", + }, + ], + }, + }, + additionalProperties: false, + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + streamMode: { + type: "string", + enum: ["off", "partial", "block"], + }, + mediaMaxMb: { + type: "number", + exclusiveMinimum: 0, + }, + timeoutSeconds: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + retry: { + type: "object", + properties: { + attempts: { + type: "integer", + minimum: 1, + maximum: 9007199254740991, + }, + minDelayMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + maxDelayMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + jitter: { + type: "number", + minimum: 0, + maximum: 1, + }, + }, + additionalProperties: false, + }, + network: { + type: "object", + properties: { + autoSelectFamily: { + type: "boolean", + }, + dnsResultOrder: { + type: "string", + enum: ["ipv4first", "verbatim"], + }, + }, + additionalProperties: false, + }, + proxy: { + type: "string", + }, + webhookUrl: { + description: + "Public HTTPS webhook URL registered with Telegram for inbound updates. This must be internet-reachable and requires channels.telegram.webhookSecret.", + type: "string", + }, + webhookSecret: { + description: + "Secret token sent to Telegram during webhook registration and verified on inbound webhook requests. Telegram returns this value for verification; this is not the gateway auth token and not the bot token.", + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + webhookPath: { + description: + "Local webhook route path served by the gateway listener. Defaults to /telegram-webhook.", + type: "string", + }, + webhookHost: { + description: + "Local bind host for the webhook listener. Defaults to 127.0.0.1; keep loopback unless you intentionally expose direct ingress.", + type: "string", + }, + webhookPort: { + description: + "Local bind port for the webhook listener. Defaults to 8787; set to 0 to let the OS assign an ephemeral port.", + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + webhookCertPath: { + description: + "Path to the self-signed certificate (PEM) to upload to Telegram during webhook registration. Required for self-signed certs (direct IP or no domain).", + type: "string", + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + sendMessage: { + type: "boolean", + }, + poll: { + type: "boolean", + }, + deleteMessage: { + type: "boolean", + }, + editMessage: { + type: "boolean", + }, + sticker: { + type: "boolean", + }, + createForumTopic: { + type: "boolean", + }, + editForumTopic: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + threadBindings: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + idleHours: { + type: "number", + minimum: 0, + }, + maxAgeHours: { + type: "number", + minimum: 0, + }, + spawnSubagentSessions: { + type: "boolean", + }, + spawnAcpSessions: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + reactionNotifications: { + type: "string", + enum: ["off", "own", "all"], + }, + reactionLevel: { + type: "string", + enum: ["off", "ack", "minimal", "extensive"], + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + linkPreview: { + type: "boolean", + }, + silentErrorReplies: { + type: "boolean", + }, + responsePrefix: { + type: "string", + }, + ackReaction: { + type: "string", + }, + apiRoot: { + type: "string", + format: "uri", + }, + autoTopicLabel: { + anyOf: [ + { + type: "boolean", + }, + { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + prompt: { + type: "string", + }, + }, + additionalProperties: false, + }, + ], + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["dmPolicy", "groupPolicy"], + additionalProperties: false, + }, + }, + { + pluginId: "tlon", + channelId: "tlon", + label: "Tlon", + description: "decentralized messaging on Urbit; install the plugin to enable.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + ship: { + type: "string", + minLength: 1, + }, + url: { + type: "string", + }, + code: { + type: "string", + }, + allowPrivateNetwork: { + type: "boolean", + }, + groupChannels: { + type: "array", + items: { + type: "string", + minLength: 1, + }, + }, + dmAllowlist: { + type: "array", + items: { + type: "string", + minLength: 1, + }, + }, + autoDiscoverChannels: { + type: "boolean", + }, + showModelSignature: { + type: "boolean", + }, + responsePrefix: { + type: "string", + }, + autoAcceptDmInvites: { + type: "boolean", + }, + autoAcceptGroupInvites: { + type: "boolean", + }, + ownerShip: { + type: "string", + minLength: 1, + }, + authorization: { + type: "object", + properties: { + channelRules: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + mode: { + type: "string", + enum: ["restricted", "open"], + }, + allowedShips: { + type: "array", + items: { + type: "string", + minLength: 1, + }, + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + defaultAuthorizedShips: { + type: "array", + items: { + type: "string", + minLength: 1, + }, + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + ship: { + type: "string", + minLength: 1, + }, + url: { + type: "string", + }, + code: { + type: "string", + }, + allowPrivateNetwork: { + type: "boolean", + }, + groupChannels: { + type: "array", + items: { + type: "string", + minLength: 1, + }, + }, + dmAllowlist: { + type: "array", + items: { + type: "string", + minLength: 1, + }, + }, + autoDiscoverChannels: { + type: "boolean", + }, + showModelSignature: { + type: "boolean", + }, + responsePrefix: { + type: "string", + }, + autoAcceptDmInvites: { + type: "boolean", + }, + autoAcceptGroupInvites: { + type: "boolean", + }, + ownerShip: { + type: "string", + minLength: 1, + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + { + pluginId: "twitch", + channelId: "twitch", + label: "Twitch", + description: "Twitch chat integration", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + anyOf: [ + { + allOf: [ + { + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + { + type: "object", + properties: { + username: { + type: "string", + }, + accessToken: { + type: "string", + }, + clientId: { + type: "string", + }, + channel: { + type: "string", + minLength: 1, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + allowedRoles: { + type: "array", + items: { + type: "string", + enum: ["moderator", "owner", "vip", "subscriber", "all"], + }, + }, + requireMention: { + type: "boolean", + }, + responsePrefix: { + type: "string", + }, + clientSecret: { + type: "string", + }, + refreshToken: { + type: "string", + }, + expiresIn: { + anyOf: [ + { + type: "number", + }, + { + type: "null", + }, + ], + }, + obtainmentTimestamp: { + type: "number", + }, + }, + required: ["username", "accessToken", "channel"], + additionalProperties: false, + }, + ], + }, + { + allOf: [ + { + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + { + type: "object", + properties: { + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + username: { + type: "string", + }, + accessToken: { + type: "string", + }, + clientId: { + type: "string", + }, + channel: { + type: "string", + minLength: 1, + }, + enabled: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + allowedRoles: { + type: "array", + items: { + type: "string", + enum: ["moderator", "owner", "vip", "subscriber", "all"], + }, + }, + requireMention: { + type: "boolean", + }, + responsePrefix: { + type: "string", + }, + clientSecret: { + type: "string", + }, + refreshToken: { + type: "string", + }, + expiresIn: { + anyOf: [ + { + type: "number", + }, + { + type: "null", + }, + ], + }, + obtainmentTimestamp: { + type: "number", + }, + }, + required: ["username", "accessToken", "channel"], + additionalProperties: false, + }, + }, + }, + required: ["accounts"], + additionalProperties: false, + }, + ], + }, + ], + }, + }, + { + pluginId: "whatsapp", + channelId: "whatsapp", + label: "WhatsApp", + description: "works with your own number; recommend a separate phone + eSIM.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + enabled: { + type: "boolean", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + sendReadReceipts: { + type: "boolean", + }, + messagePrefix: { + type: "string", + }, + responsePrefix: { + type: "string", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + selfChatMode: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + defaultTo: { + type: "string", + }, + groupAllowFrom: { + type: "array", + items: { + type: "string", + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + ackReaction: { + type: "object", + properties: { + emoji: { + type: "string", + }, + direct: { + default: true, + type: "boolean", + }, + group: { + default: "mentions", + type: "string", + enum: ["always", "mentions", "never"], + }, + }, + required: ["direct", "group"], + additionalProperties: false, + }, + debounceMs: { + default: 0, + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + accounts: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + capabilities: { + type: "array", + items: { + type: "string", + }, + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + configWrites: { + type: "boolean", + }, + sendReadReceipts: { + type: "boolean", + }, + messagePrefix: { + type: "string", + }, + responsePrefix: { + type: "string", + }, + dmPolicy: { + default: "pairing", + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + selfChatMode: { + type: "boolean", + }, + allowFrom: { + type: "array", + items: { + type: "string", + }, + }, + defaultTo: { + type: "string", + }, + groupAllowFrom: { + type: "array", + items: { + type: "string", + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dmHistoryLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + dms: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + }, + textChunkLimit: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + chunkMode: { + type: "string", + enum: ["length", "newline"], + }, + blockStreaming: { + type: "boolean", + }, + blockStreamingCoalesce: { + type: "object", + properties: { + minChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + maxChars: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + idleMs: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + }, + additionalProperties: false, + }, + groups: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + toolsBySender: { + type: "object", + propertyNames: { + type: "string", + }, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + }, + additionalProperties: false, + }, + }, + ackReaction: { + type: "object", + properties: { + emoji: { + type: "string", + }, + direct: { + default: true, + type: "boolean", + }, + group: { + default: "mentions", + type: "string", + enum: ["always", "mentions", "never"], + }, + }, + required: ["direct", "group"], + additionalProperties: false, + }, + debounceMs: { + default: 0, + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + heartbeat: { + type: "object", + properties: { + showOk: { + type: "boolean", + }, + showAlerts: { + type: "boolean", + }, + useIndicator: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + healthMonitor: { + type: "object", + properties: { + enabled: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + name: { + type: "string", + }, + authDir: { + type: "string", + }, + mediaMaxMb: { + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + }, + required: ["dmPolicy", "groupPolicy", "debounceMs"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + mediaMaxMb: { + default: 50, + type: "integer", + exclusiveMinimum: 0, + maximum: 9007199254740991, + }, + actions: { + type: "object", + properties: { + reactions: { + type: "boolean", + }, + sendMessage: { + type: "boolean", + }, + polls: { + type: "boolean", + }, + }, + additionalProperties: false, + }, + }, + required: ["dmPolicy", "groupPolicy", "debounceMs", "mediaMaxMb"], + additionalProperties: false, + }, + }, + { + pluginId: "zalo", + channelId: "zalo", + label: "Zalo", + description: "Vietnam-focused messaging platform with Bot API.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + botToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + tokenFile: { + type: "string", + }, + webhookUrl: { + type: "string", + }, + webhookSecret: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + webhookPath: { + type: "string", + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + mediaMaxMb: { + type: "number", + }, + proxy: { + type: "string", + }, + responsePrefix: { + type: "string", + }, + accounts: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + botToken: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + tokenFile: { + type: "string", + }, + webhookUrl: { + type: "string", + }, + webhookSecret: { + anyOf: [ + { + type: "string", + }, + { + oneOf: [ + { + type: "object", + properties: { + source: { + type: "string", + const: "env", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + pattern: "^[A-Z][A-Z0-9_]{0,127}$", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "file", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + { + type: "object", + properties: { + source: { + type: "string", + const: "exec", + }, + provider: { + type: "string", + pattern: "^[a-z][a-z0-9_-]{0,63}$", + }, + id: { + type: "string", + }, + }, + required: ["source", "provider", "id"], + additionalProperties: false, + }, + ], + }, + ], + }, + webhookPath: { + type: "string", + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + mediaMaxMb: { + type: "number", + }, + proxy: { + type: "string", + }, + responsePrefix: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + additionalProperties: false, + }, + }, + { + pluginId: "zalouser", + channelId: "zalouser", + label: "Zalo Personal", + description: "Zalo personal account via QR code login.", + schema: { + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + profile: { + type: "string", + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groups: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "boolean", + }, + enabled: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + }, + messagePrefix: { + type: "string", + }, + responsePrefix: { + type: "string", + }, + accounts: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + name: { + type: "string", + }, + enabled: { + type: "boolean", + }, + markdown: { + type: "object", + properties: { + tables: { + type: "string", + enum: ["off", "bullets", "code"], + }, + }, + additionalProperties: false, + }, + profile: { + type: "string", + }, + dangerouslyAllowNameMatching: { + type: "boolean", + }, + dmPolicy: { + type: "string", + enum: ["pairing", "allowlist", "open", "disabled"], + }, + allowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + historyLimit: { + type: "integer", + minimum: 0, + maximum: 9007199254740991, + }, + groupAllowFrom: { + type: "array", + items: { + anyOf: [ + { + type: "string", + }, + { + type: "number", + }, + ], + }, + }, + groupPolicy: { + default: "allowlist", + type: "string", + enum: ["open", "disabled", "allowlist"], + }, + groups: { + type: "object", + properties: {}, + additionalProperties: { + type: "object", + properties: { + allow: { + type: "boolean", + }, + enabled: { + type: "boolean", + }, + requireMention: { + type: "boolean", + }, + tools: { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string", + }, + }, + alsoAllow: { + type: "array", + items: { + type: "string", + }, + }, + deny: { + type: "array", + items: { + type: "string", + }, + }, + }, + additionalProperties: false, + }, + }, + additionalProperties: false, + }, + }, + messagePrefix: { + type: "string", + }, + responsePrefix: { + type: "string", + }, + }, + required: ["groupPolicy"], + additionalProperties: false, + }, + }, + defaultAccount: { + type: "string", + }, + }, + required: ["groupPolicy"], + additionalProperties: false, + }, + }, +] as const;