{ "id": "wechat-agent", "channels": ["wechat-agent"], "configSchema": { "type": "object", "additionalProperties": false, "properties": { "channels": { "type": "object", "properties": { "wechat-agent": { "type": "object", "additionalProperties": true, "properties": { "enabled": { "type": "boolean", "default": true, "description": "Master switch for this channel." }, "apiBase": { "type": "string", "description": "Root URL of the wechat-agent HTTP bot, e.g. http://8.138.37.248/api/wechat-agent", "examples": [ "http://127.0.0.1:8138", "http://8.138.37.248/api/wechat-agent" ] }, "pollIntervalMs": { "type": "integer", "minimum": 3000, "maximum": 120000, "default": 10000, "description": "How often to pull new messages (ms)." }, "batchWindowMs": { "type": "integer", "minimum": 0, "maximum": 30000, "default": 3000, "description": "Wait this long after a message before dispatching to the agent, so rapid-fire messages from one sender get merged into a single agent turn. 0 = dispatch immediately." }, "replyCooldownSecPerWxid": { "type": "integer", "minimum": 0, "maximum": 3600, "default": 5, "description": "Minimum seconds between two replies to the same wxid. Prevents the bot from spamming if the agent errors repeatedly." }, "groupEnabled": { "type": "boolean", "default": true, "description": "Enable group-chat inbound handling. When false, all group messages are ignored." }, "groupKeywords": { "type": "array", "items": { "type": "string" }, "default": ["帮我", "请问"], "description": "Group messages trigger the agent when content contains any of these keywords." }, "groupMentionTokens": { "type": "array", "items": { "type": "string" }, "default": ["@bot", "@助手"], "description": "Additional mention-like text tokens that should trigger in groups." }, "groupReplyAtSender": { "type": "boolean", "default": false, "description": "When replying in groups, @-mention the sender wxid (if backend supports ats)." }, "dmPolicy": { "type": "string", "enum": ["open", "allowlist", "pairing"], "default": "open", "description": "Who can initiate DMs. 'open' = anyone, 'allowlist' = only wxids in allowFrom, 'pairing' = require pairing code." }, "allowFrom": { "type": "array", "items": { "type": "string" }, "default": [], "description": "Wxid whitelist (used when dmPolicy=allowlist)." }, "ignoreWxidPrefixes": { "type": "array", "items": { "type": "string" }, "default": ["gh_"], "description": "Skip messages from wxids starting with these prefixes (e.g. gh_ for official accounts)." }, "ignoreWxidExact": { "type": "array", "items": { "type": "string" }, "default": [ "weixin", "fmessage", "medianote", "filehelper", "floatbottle", "qmessage", "qqmail", "tmessage", "newsapp" ], "description": "Skip messages from these exact wxids (system contacts)." }, "ignoreMessageTypes": { "type": "array", "items": { "type": "string" }, "default": ["system", "emoji", "voice", "image", "video", "location", "file"], "description": "Message types to skip. MVP only handles text; others are ignored until v0.2." }, "faq": { "type": "array", "description": "Plugin-layer FAQ fast-path. If a message matches (any keyword in keywords is a substring of content), reply immediately without calling the agent. Saves tokens and latency for canned answers.", "default": [], "items": { "type": "object", "required": ["keywords", "reply"], "properties": { "id": { "type": "string" }, "keywords": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "reply": { "type": "string" }, "stop": { "type": "boolean", "default": true, "description": "If true (default), skip the agent after matching. If false, also forward to agent." } } } }, "defaultTo": { "type": "string", "description": "Default wxid to send to when agent replies without an explicit target (e.g. scheduled broadcasts)." }, "selfWxid": { "type": "string", "description": "The bot's own wxid, used to filter self-sent echoes. If unset, the plugin will try to detect via checkOnline." }, "technical": { "type": "object", "description": "Optional technical-layer config. Values here override same-name top-level fields.", "additionalProperties": true, "properties": { "apiBase": { "type": "string" }, "pollIntervalMs": { "type": "integer", "minimum": 3000, "maximum": 120000 }, "batchWindowMs": { "type": "integer", "minimum": 0, "maximum": 30000 }, "replyCooldownSecPerWxid": { "type": "integer", "minimum": 0, "maximum": 3600 }, "outboundRatePerSec": { "type": "integer", "minimum": 1, "maximum": 100, "description": "Global outbound rate limiter for all send paths." }, "outboundQueueMax": { "type": "integer", "minimum": 10, "maximum": 5000, "description": "Maximum buffered outbound tasks before rejecting new ones." }, "metricsLogIntervalSec": { "type": "integer", "minimum": 30, "maximum": 3600, "description": "Base interval for summary metrics logs. Recommended: 60 (debug), 120~180 (normal), 300 (stable high throughput)." }, "highThroughputOutboundAttemptsPer5Min": { "type": "integer", "minimum": 50, "maximum": 50000, "description": "Auto-switch metrics summary interval to 300s when outbound attempts in 5 minutes exceed this threshold." } } }, "business": { "type": "object", "description": "Optional business-layer config. Values here override same-name top-level fields.", "additionalProperties": true, "properties": { "groupEnabled": { "type": "boolean" }, "groupKeywords": { "type": "array", "items": { "type": "string" } }, "groupMentionTokens": { "type": "array", "items": { "type": "string" } }, "groupReplyAtSender": { "type": "boolean" }, "dmPolicy": { "type": "string", "enum": ["open", "allowlist", "pairing"] }, "allowFrom": { "type": "array", "items": { "type": "string" } }, "ignoreWxidPrefixes": { "type": "array", "items": { "type": "string" } }, "ignoreWxidExact": { "type": "array", "items": { "type": "string" } }, "ignoreMessageTypes": { "type": "array", "items": { "type": "string" } }, "faq": { "type": "array" }, "defaultTo": { "type": "string" }, "selfWxid": { "type": "string" } } } } } } } } } }