@xmanrui/dsh-im 0.17.0 → 0.18.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.
- package/README.en.md +3 -2
- package/README.md +3 -2
- package/lib/client.js +964 -538
- package/lib/index.js +189 -144
- package/package.json +1 -1
- package/plugin-src/client/agent-preset.js +110 -0
- package/plugin-src/client/channels/dingtalk/api.js +5 -0
- package/plugin-src/client/channels/dingtalk/index.js +48 -2
- package/plugin-src/client/channels/feishu/api.js +5 -0
- package/plugin-src/client/channels/feishu/index.js +39 -2
- package/plugin-src/client/channels/qq/api.js +5 -0
- package/plugin-src/client/channels/qq/index.js +37 -6
- package/plugin-src/client/channels/shared/token-api.js +5 -0
- package/plugin-src/client/channels/shared/token-channel.js +34 -6
- package/plugin-src/client/channels/wecom/api.js +5 -0
- package/plugin-src/client/channels/wecom/index.js +37 -6
- package/plugin-src/client/channels/weixin/api.js +15 -0
- package/plugin-src/client/channels/weixin/index.js +54 -4
- package/plugin-src/client/channels/whatsapp/api.js +5 -0
- package/plugin-src/client/channels/whatsapp/index.js +30 -4
- package/plugin-src/client/i18n.js +29 -0
- package/plugin-src/client/styles.js +8 -0
- package/plugin-src/host/channels/dingtalk/production.mjs +10 -4
- package/plugin-src/host/channels/dingtalk/rpc.mjs +12 -0
- package/plugin-src/host/channels/feishu/connection-supervisor.mjs +1 -1
- package/plugin-src/host/channels/feishu/production.mjs +6 -3
- package/plugin-src/host/channels/feishu/rpc.mjs +17 -0
- package/plugin-src/host/channels/qq/production.mjs +10 -4
- package/plugin-src/host/channels/qq/rpc.mjs +12 -0
- package/plugin-src/host/channels/shared/agent-preset-rpc.mjs +25 -0
- package/plugin-src/host/channels/shared/production.mjs +10 -4
- package/plugin-src/host/channels/shared/rpc.mjs +12 -0
- package/plugin-src/host/channels/shared/workspace-rpc.mjs +2 -0
- package/plugin-src/host/channels/slack/production.mjs +10 -4
- package/plugin-src/host/channels/slack/rpc.mjs +13 -0
- package/plugin-src/host/channels/wecom/production.mjs +10 -4
- package/plugin-src/host/channels/wecom/rpc.mjs +12 -0
- package/plugin-src/host/channels/weixin/production.mjs +10 -4
- package/plugin-src/host/channels/weixin/rpc.mjs +15 -0
- package/plugin-src/host/channels/whatsapp/production.mjs +10 -4
- package/plugin-src/host/channels/whatsapp/rpc.mjs +12 -0
- package/src/channels/discord/discord-api.mjs +1 -1
- package/src/channels/shared/agent-preset.mjs +74 -0
- package/src/channels/shared/bot-workspace-store.mjs +141 -14
- package/src/channels/shared/harness-client.mjs +6 -4
- package/src/channels/shared/image-prompt.mjs +32 -1
- package/src/channels/weixin/weixin-api.mjs +1 -1
- package/src/channels/weixin/weixin-bridge.mjs +23 -3
- package/src/channels/weixin/weixin-controller.mjs +15 -0
|
@@ -23,12 +23,14 @@ import { runWorkspaceCommand } from '../shared/workspace-command.mjs';
|
|
|
23
23
|
import { askInWorkspaceSession } from '../shared/workspace-session.mjs';
|
|
24
24
|
import {
|
|
25
25
|
hasInboundImages,
|
|
26
|
+
imagePromptDiagnostic,
|
|
26
27
|
imagePromptUserMessage,
|
|
27
28
|
promptContentForMessage,
|
|
28
29
|
} from '../shared/image-prompt.mjs';
|
|
29
30
|
import { rememberConnectionTestTarget } from '../shared/connection-test.mjs';
|
|
30
31
|
|
|
31
32
|
const INTERACTION_RESOLVED_TEXT = '这个问题已在其他客户端处理,无需再次回答。';
|
|
33
|
+
const GENERIC_PROCESSING_ERROR = '消息处理失败,请稍后重试。';
|
|
32
34
|
|
|
33
35
|
const HELP_TEXT = [
|
|
34
36
|
'微信已连接 DeepSeek Harness。',
|
|
@@ -69,6 +71,16 @@ function canClaimInteractionReply(message, pending) {
|
|
|
69
71
|
&& nonEmptyString(extractWeixinText(message));
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
function safeMessageError(error, userMessage = GENERIC_PROCESSING_ERROR) {
|
|
75
|
+
const diagnostic = imagePromptDiagnostic(error);
|
|
76
|
+
return {
|
|
77
|
+
code: diagnostic?.code ?? 'message-processing-failed',
|
|
78
|
+
reason: diagnostic?.reason ?? 'UNKNOWN',
|
|
79
|
+
message: diagnostic?.userMessage ?? userMessage,
|
|
80
|
+
at: Date.now(),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
72
84
|
export function createWeixinBridgeStatus() {
|
|
73
85
|
return {
|
|
74
86
|
messagesReceived: 0,
|
|
@@ -78,6 +90,7 @@ export function createWeixinBridgeStatus() {
|
|
|
78
90
|
lastReplyAt: null,
|
|
79
91
|
lastRejectedAt: null,
|
|
80
92
|
lastError: null,
|
|
93
|
+
lastMessageError: null,
|
|
81
94
|
};
|
|
82
95
|
}
|
|
83
96
|
|
|
@@ -168,8 +181,9 @@ export class WeixinHarnessBridge {
|
|
|
168
181
|
).catch((error) => {
|
|
169
182
|
if (error?.code === 'turn-stopped' || this.#signal?.aborted) return;
|
|
170
183
|
this.#status.lastError = error?.message ?? String(error);
|
|
184
|
+
this.#status.lastMessageError = safeMessageError(error);
|
|
171
185
|
this.#logger.error?.('[dsh-weixin] failed to process a command:', error);
|
|
172
|
-
return this.#send(sender,
|
|
186
|
+
return this.#send(sender, GENERIC_PROCESSING_ERROR, contextToken, runId)
|
|
173
187
|
.catch(() => undefined);
|
|
174
188
|
}).finally(() => {
|
|
175
189
|
this.#acceptedMessageIds.delete(messageId);
|
|
@@ -289,6 +303,7 @@ export class WeixinHarnessBridge {
|
|
|
289
303
|
if (reply) await this.#send(sender, reply, contextToken, runId);
|
|
290
304
|
}
|
|
291
305
|
this.#status.lastError = null;
|
|
306
|
+
this.#status.lastMessageError = null;
|
|
292
307
|
}
|
|
293
308
|
|
|
294
309
|
async #process(message, key, { alreadyRecorded = false } = {}) {
|
|
@@ -401,6 +416,7 @@ export class WeixinHarnessBridge {
|
|
|
401
416
|
this.#status.messagesReplied += 1;
|
|
402
417
|
this.#status.lastReplyAt = new Date().toISOString();
|
|
403
418
|
this.#status.lastError = null;
|
|
419
|
+
this.#status.lastMessageError = null;
|
|
404
420
|
} catch (error) {
|
|
405
421
|
if (error?.code === 'turn-stopped') {
|
|
406
422
|
await this.#state.markSeen(messageId);
|
|
@@ -408,11 +424,13 @@ export class WeixinHarnessBridge {
|
|
|
408
424
|
}
|
|
409
425
|
if (this.#signal?.aborted) return;
|
|
410
426
|
this.#status.lastError = error?.message ?? String(error);
|
|
427
|
+
const userMessage = imagePromptUserMessage(error) ?? GENERIC_PROCESSING_ERROR;
|
|
428
|
+
this.#status.lastMessageError = safeMessageError(error, userMessage);
|
|
411
429
|
this.#logger.error?.('[dsh-weixin] failed to process an inbound message:', error);
|
|
412
430
|
try {
|
|
413
431
|
await this.#send(
|
|
414
432
|
sender,
|
|
415
|
-
|
|
433
|
+
userMessage,
|
|
416
434
|
contextToken,
|
|
417
435
|
runId,
|
|
418
436
|
);
|
|
@@ -526,6 +544,7 @@ export class WeixinHarnessBridge {
|
|
|
526
544
|
});
|
|
527
545
|
this.#clearPendingInteraction(key, pending.interactionId);
|
|
528
546
|
this.#status.lastError = null;
|
|
547
|
+
this.#status.lastMessageError = null;
|
|
529
548
|
} catch (error) {
|
|
530
549
|
if (this.#signal?.aborted) return;
|
|
531
550
|
if (error?.code === 'interaction-not-pending') {
|
|
@@ -719,13 +738,14 @@ export class WeixinHarnessBridge {
|
|
|
719
738
|
async #handleInteractionFailure(message, messageId, error) {
|
|
720
739
|
if (this.#signal?.aborted) return;
|
|
721
740
|
this.#status.lastError = error?.message ?? String(error);
|
|
741
|
+
this.#status.lastMessageError = safeMessageError(error);
|
|
722
742
|
this.#logger.error?.('[dsh-weixin] failed to process an interaction reply:', error);
|
|
723
743
|
if (!this.#state.hasSeen(messageId)) {
|
|
724
744
|
await this.#state.markSeen(messageId).catch(() => undefined);
|
|
725
745
|
}
|
|
726
746
|
await this.#send(
|
|
727
747
|
nonEmptyString(message?.from_user_id),
|
|
728
|
-
|
|
748
|
+
GENERIC_PROCESSING_ERROR,
|
|
729
749
|
nonEmptyString(message?.context_token) ?? undefined,
|
|
730
750
|
nonEmptyString(message?.run_id) ?? undefined,
|
|
731
751
|
).catch(() => undefined);
|
|
@@ -62,6 +62,20 @@ function safeAccountError(code, message) {
|
|
|
62
62
|
return Object.freeze({ code, message });
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
function publicMessageError(value) {
|
|
66
|
+
if (!value || typeof value !== 'object'
|
|
67
|
+
|| typeof value.code !== 'string' || !value.code
|
|
68
|
+
|| typeof value.reason !== 'string' || !value.reason
|
|
69
|
+
|| typeof value.message !== 'string' || !value.message
|
|
70
|
+
|| !Number.isFinite(value.at)) return null;
|
|
71
|
+
return {
|
|
72
|
+
code: value.code.slice(0, 64),
|
|
73
|
+
reason: value.reason.slice(0, 128),
|
|
74
|
+
message: value.message.slice(0, 500),
|
|
75
|
+
at: value.at,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
65
79
|
function activationStageError(code, cause) {
|
|
66
80
|
const error = new Error(`Weixin activation failed during ${code}`, { cause });
|
|
67
81
|
error.name = 'WeixinActivationStageError';
|
|
@@ -351,6 +365,7 @@ export class WeixinController {
|
|
|
351
365
|
messagesReceived: runtimeStatus?.messagesReceived ?? 0,
|
|
352
366
|
messagesReplied: runtimeStatus?.messagesReplied ?? 0,
|
|
353
367
|
},
|
|
368
|
+
lastMessageError: publicMessageError(runtimeStatus?.lastMessageError),
|
|
354
369
|
error: error ? structuredClone(error) : null,
|
|
355
370
|
};
|
|
356
371
|
});
|