@dingxiang-me/openclaw-wechat 2.0.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.en.md +204 -32
  3. package/README.md +234 -63
  4. package/docs/channels/wecom.md +137 -1
  5. package/openclaw.plugin.json +694 -10
  6. package/package.json +207 -4
  7. package/scripts/wecom-agent-selfcheck.mjs +775 -0
  8. package/scripts/wecom-bot-longconn-probe.mjs +582 -0
  9. package/scripts/wecom-bot-selfcheck.mjs +952 -0
  10. package/scripts/wecom-callback-matrix.mjs +224 -0
  11. package/scripts/wecom-doctor.mjs +1407 -0
  12. package/scripts/wecom-e2e-scenario.mjs +333 -0
  13. package/scripts/wecom-migrate.mjs +261 -0
  14. package/scripts/wecom-quickstart.mjs +1824 -0
  15. package/scripts/wecom-release-check.mjs +232 -0
  16. package/scripts/wecom-remote-e2e.mjs +310 -0
  17. package/scripts/wecom-selfcheck.mjs +1255 -0
  18. package/scripts/wecom-smoke.sh +74 -0
  19. package/src/core/delivery-router.js +21 -0
  20. package/src/core.js +631 -34
  21. package/src/wecom/account-config-core.js +27 -1
  22. package/src/wecom/account-config.js +19 -2
  23. package/src/wecom/agent-dispatch-executor.js +11 -0
  24. package/src/wecom/agent-dispatch-handlers.js +61 -8
  25. package/src/wecom/agent-inbound-guards.js +63 -16
  26. package/src/wecom/agent-inbound-processor.js +34 -2
  27. package/src/wecom/agent-late-reply-runtime.js +30 -2
  28. package/src/wecom/agent-text-sender.js +2 -0
  29. package/src/wecom/api-client-core.js +27 -19
  30. package/src/wecom/api-client-media.js +16 -7
  31. package/src/wecom/api-client-send-text.js +4 -0
  32. package/src/wecom/api-client-send-typed.js +4 -1
  33. package/src/wecom/api-client-senders.js +41 -3
  34. package/src/wecom/api-client.js +1 -0
  35. package/src/wecom/bot-dispatch-fallback.js +18 -3
  36. package/src/wecom/bot-dispatch-handlers.js +47 -10
  37. package/src/wecom/bot-inbound-dispatch-runtime.js +3 -0
  38. package/src/wecom/bot-inbound-executor-helpers.js +11 -1
  39. package/src/wecom/bot-inbound-executor.js +25 -1
  40. package/src/wecom/bot-inbound-guards.js +78 -23
  41. package/src/wecom/bot-long-connection-manager.js +4 -4
  42. package/src/wecom/channel-config-schema.js +132 -0
  43. package/src/wecom/channel-plugin.js +370 -7
  44. package/src/wecom/command-handlers.js +107 -10
  45. package/src/wecom/command-status-text.js +275 -1
  46. package/src/wecom/doc-client.js +7 -1
  47. package/src/wecom/inbound-content-handler-file-video-link.js +4 -0
  48. package/src/wecom/inbound-content-handler-image-voice.js +6 -0
  49. package/src/wecom/inbound-content.js +5 -0
  50. package/src/wecom/installer-api.js +910 -0
  51. package/src/wecom/media-download.js +2 -2
  52. package/src/wecom/migration-diagnostics.js +816 -0
  53. package/src/wecom/network-config.js +91 -0
  54. package/src/wecom/observability-metrics.js +9 -3
  55. package/src/wecom/outbound-agent-delivery.js +313 -0
  56. package/src/wecom/outbound-agent-media-sender.js +37 -7
  57. package/src/wecom/outbound-agent-push.js +1 -0
  58. package/src/wecom/outbound-delivery.js +129 -12
  59. package/src/wecom/outbound-stream-msg-item.js +25 -2
  60. package/src/wecom/outbound-webhook-delivery.js +19 -0
  61. package/src/wecom/outbound-webhook-media.js +30 -6
  62. package/src/wecom/pairing.js +188 -0
  63. package/src/wecom/pending-reply-manager.js +143 -0
  64. package/src/wecom/plugin-account-policy-services.js +26 -0
  65. package/src/wecom/plugin-base-services.js +58 -0
  66. package/src/wecom/plugin-constants.js +1 -1
  67. package/src/wecom/plugin-delivery-inbound-services.js +25 -0
  68. package/src/wecom/plugin-processing-deps.js +7 -0
  69. package/src/wecom/plugin-route-runtime-deps.js +1 -0
  70. package/src/wecom/plugin-services.js +87 -0
  71. package/src/wecom/policy-resolvers.js +93 -20
  72. package/src/wecom/quickstart-metadata.js +1247 -0
  73. package/src/wecom/reasoning-visibility.js +104 -0
  74. package/src/wecom/register-runtime.js +10 -0
  75. package/src/wecom/reliable-delivery-persistence.js +138 -0
  76. package/src/wecom/reliable-delivery.js +642 -0
  77. package/src/wecom/reply-output-policy.js +171 -0
  78. package/src/wecom/text-inbound-scheduler.js +6 -1
  79. package/src/wecom/workspace-auto-sender.js +2 -0
@@ -12,6 +12,10 @@ export function createWecomPolicyResolvers({
12
12
  resolveWecomDebounceConfig,
13
13
  resolveWecomStreamingConfig,
14
14
  resolveWecomDeliveryFallbackConfig,
15
+ resolveWecomPendingReplyConfig,
16
+ resolveWecomQuotaTrackingConfig,
17
+ resolveWecomReasoningConfig,
18
+ resolveWecomReplyFormatConfig,
15
19
  resolveWecomWebhookBotDeliveryConfig,
16
20
  resolveWecomStreamManagerConfig,
17
21
  resolveWecomObservabilityConfig,
@@ -25,6 +29,44 @@ export function createWecomPolicyResolvers({
25
29
  throw new Error("createWecomPolicyResolvers: normalizeAccountId is required");
26
30
  }
27
31
 
32
+ function asObject(value) {
33
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
34
+ }
35
+
36
+ function resolveLegacyInlineAccountConfig(channelConfig, normalizedAccountId) {
37
+ const channel = asObject(channelConfig);
38
+ for (const [key, value] of Object.entries(channel)) {
39
+ if (normalizeAccountId(key) !== normalizedAccountId) continue;
40
+ if (!value || typeof value !== "object" || Array.isArray(value)) continue;
41
+ return value;
42
+ }
43
+ return {};
44
+ }
45
+
46
+ function resolveRawWecomAccountConfig(channelConfig, normalizedAccountId) {
47
+ if (normalizedAccountId === "default") return asObject(channelConfig);
48
+ const rawChannel = asObject(channelConfig);
49
+ const accountConfig = asObject(rawChannel?.accounts)?.[normalizedAccountId];
50
+ if (accountConfig && typeof accountConfig === "object" && !Array.isArray(accountConfig)) {
51
+ return accountConfig;
52
+ }
53
+ return resolveLegacyInlineAccountConfig(rawChannel, normalizedAccountId);
54
+ }
55
+
56
+ function resolveWecomPolicyAccountInputs(api, accountId = "default", accountConfig = {}) {
57
+ const inputs = resolveWecomPolicyInputs(api);
58
+ const normalizedAccountId = normalizeAccountId(accountId ?? accountConfig?.accountId ?? "default");
59
+ const rawAccountConfig = resolveRawWecomAccountConfig(inputs.channelConfig, normalizedAccountId);
60
+ return {
61
+ ...inputs,
62
+ accountId: normalizedAccountId,
63
+ accountConfig: {
64
+ ...rawAccountConfig,
65
+ ...(accountConfig && typeof accountConfig === "object" ? accountConfig : {}),
66
+ },
67
+ };
68
+ }
69
+
28
70
  function resolveWecomPolicyInputs(api) {
29
71
  const cfg = api?.config ?? getGatewayRuntime()?.config ?? {};
30
72
  return {
@@ -95,28 +137,17 @@ export function createWecomPolicyResolvers({
95
137
  }
96
138
 
97
139
  function resolveWecomAllowFromPolicy(api, accountId, accountConfig = {}) {
98
- const inputs = resolveWecomPolicyInputs(api);
99
- return resolveWecomAllowFromPolicyConfig({
100
- ...inputs,
101
- accountId: normalizeAccountId(accountId ?? "default"),
102
- accountConfig: accountConfig ?? {},
103
- });
140
+ return resolveWecomAllowFromPolicyConfig(resolveWecomPolicyAccountInputs(api, accountId, accountConfig));
104
141
  }
105
142
 
106
143
  function resolveWecomDmPolicy(api, accountId, accountConfig = {}) {
107
- const inputs = resolveWecomPolicyInputs(api);
108
144
  if (typeof resolveWecomDmPolicyConfig !== "function") {
109
145
  return { mode: "open", allowFrom: [], rejectMessage: "当前私聊账号未授权,请联系管理员。", enabled: false };
110
146
  }
111
- return resolveWecomDmPolicyConfig({
112
- ...inputs,
113
- accountId: normalizeAccountId(accountId ?? "default"),
114
- accountConfig: accountConfig ?? {},
115
- });
147
+ return resolveWecomDmPolicyConfig(resolveWecomPolicyAccountInputs(api, accountId, accountConfig));
116
148
  }
117
149
 
118
150
  function resolveWecomEventPolicy(api, accountId, accountConfig = {}) {
119
- const inputs = resolveWecomPolicyInputs(api);
120
151
  if (typeof resolveWecomEventPolicyConfig !== "function") {
121
152
  return {
122
153
  enabled: true,
@@ -124,15 +155,14 @@ export function createWecomPolicyResolvers({
124
155
  enterAgentWelcomeText: "你好,我是 AI 助手,直接发消息即可开始对话。",
125
156
  };
126
157
  }
127
- return resolveWecomEventPolicyConfig({
128
- ...inputs,
129
- accountId: normalizeAccountId(accountId ?? "default"),
130
- accountConfig: accountConfig ?? {},
131
- });
158
+ return resolveWecomEventPolicyConfig(resolveWecomPolicyAccountInputs(api, accountId, accountConfig));
132
159
  }
133
160
 
134
- function resolveWecomGroupChatPolicy(api) {
135
- return resolveWecomGroupChatConfig(resolveWecomPolicyInputs(api));
161
+ function resolveWecomGroupChatPolicy(api, accountId = "default", accountConfig = {}, chatId = "") {
162
+ return resolveWecomGroupChatConfig({
163
+ ...resolveWecomPolicyAccountInputs(api, accountId, accountConfig),
164
+ chatId,
165
+ });
136
166
  }
137
167
 
138
168
  function resolveWecomTextDebouncePolicy(api) {
@@ -151,6 +181,45 @@ export function createWecomPolicyResolvers({
151
181
  return resolveWecomWebhookBotDeliveryConfig(resolveWecomPolicyInputs(api));
152
182
  }
153
183
 
184
+ function resolveWecomPendingReplyPolicy(api) {
185
+ if (typeof resolveWecomPendingReplyConfig !== "function") {
186
+ return {
187
+ enabled: true,
188
+ maxRetries: 3,
189
+ retryBackoffMs: 15000,
190
+ expireMs: 10 * 60 * 1000,
191
+ };
192
+ }
193
+ return resolveWecomPendingReplyConfig(resolveWecomPolicyInputs(api));
194
+ }
195
+
196
+ function resolveWecomQuotaTrackingPolicy(api) {
197
+ if (typeof resolveWecomQuotaTrackingConfig !== "function") {
198
+ return { enabled: true };
199
+ }
200
+ return resolveWecomQuotaTrackingConfig(resolveWecomPolicyInputs(api));
201
+ }
202
+
203
+ function resolveWecomReasoningPolicy(api) {
204
+ if (typeof resolveWecomReasoningConfig !== "function") {
205
+ return {
206
+ mode: "separate",
207
+ sendThinkingMessage: true,
208
+ includeInFinalAnswer: false,
209
+ title: "思考过程",
210
+ maxChars: 1200,
211
+ };
212
+ }
213
+ return resolveWecomReasoningConfig(resolveWecomPolicyInputs(api));
214
+ }
215
+
216
+ function resolveWecomReplyFormatPolicy(api) {
217
+ if (typeof resolveWecomReplyFormatConfig !== "function") {
218
+ return { mode: "auto" };
219
+ }
220
+ return resolveWecomReplyFormatConfig(resolveWecomPolicyInputs(api));
221
+ }
222
+
154
223
  function resolveWecomStreamManagerPolicy(api) {
155
224
  return resolveWecomStreamManagerConfig(resolveWecomPolicyInputs(api));
156
225
  }
@@ -176,6 +245,10 @@ export function createWecomPolicyResolvers({
176
245
  resolveWecomTextDebouncePolicy,
177
246
  resolveWecomReplyStreamingPolicy,
178
247
  resolveWecomDeliveryFallbackPolicy,
248
+ resolveWecomPendingReplyPolicy,
249
+ resolveWecomQuotaTrackingPolicy,
250
+ resolveWecomReasoningPolicy,
251
+ resolveWecomReplyFormatPolicy,
179
252
  resolveWecomWebhookBotDeliveryPolicy,
180
253
  resolveWecomStreamManagerPolicy,
181
254
  resolveWecomObservabilityPolicy,