@xmanrui/dsh-im 2.4.0 → 2.6.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 +2 -2
- package/README.md +2 -2
- package/lib/client.js +322 -109
- package/lib/index.js +218 -211
- package/package.json +1 -1
- package/plugin-src/client/channel-card-meta.js +36 -1
- package/plugin-src/client/channels/dingtalk/api.js +2 -0
- package/plugin-src/client/channels/dingtalk/index.js +9 -1
- package/plugin-src/client/channels/feishu/api.js +3 -0
- package/plugin-src/client/channels/feishu/index.js +9 -1
- package/plugin-src/client/channels/qq/api.js +2 -0
- package/plugin-src/client/channels/qq/index.js +9 -1
- package/plugin-src/client/channels/shared/token-api.js +2 -0
- package/plugin-src/client/channels/shared/token-channel.js +9 -1
- package/plugin-src/client/channels/wecom/api.js +2 -0
- package/plugin-src/client/channels/wecom/index.js +9 -1
- package/plugin-src/client/channels/weixin/api.js +2 -10
- package/plugin-src/client/channels/weixin/index.js +9 -5
- package/plugin-src/client/channels/whatsapp/api.js +2 -0
- package/plugin-src/client/channels/whatsapp/index.js +9 -1
- package/plugin-src/client/i18n.js +4 -0
- package/plugin-src/client/index.js +16 -2
- package/plugin-src/client/last-message-error.js +17 -0
- package/plugin-src/client/styles.js +5 -1
- package/plugin-src/host/channels/feishu/rpc.mjs +3 -0
- package/src/channels/dingtalk/dingtalk-api.mjs +102 -6
- package/src/channels/dingtalk/dingtalk-bridge.mjs +247 -38
- package/src/channels/dingtalk/dingtalk-card-stream.mjs +2 -2
- package/src/channels/dingtalk/dingtalk-controller.mjs +2 -0
- package/src/channels/discord/discord-api.mjs +35 -0
- package/src/channels/discord/discord-bridge.mjs +1 -0
- package/src/channels/discord/discord-runtime.mjs +26 -0
- package/src/channels/feishu/bridge.mjs +115 -69
- package/src/channels/feishu/multi-bot-controller.mjs +2 -0
- package/src/channels/qq/qq-bridge.mjs +83 -28
- package/src/channels/qq/qq-controller.mjs +2 -0
- package/src/channels/shared/harness-client.mjs +40 -4
- package/src/channels/shared/i18n-en/shared-a.mjs +77 -0
- package/src/channels/shared/message-failure.mjs +244 -0
- package/src/channels/shared/semantic/artifact-delivery.mjs +9 -2
- package/src/channels/shared/status-reaction.mjs +107 -0
- package/src/channels/shared/text-harness-bridge.mjs +123 -66
- package/src/channels/shared/token-bot-controller.mjs +2 -0
- package/src/channels/slack/manifest.mjs +1 -0
- package/src/channels/slack/slack-api.mjs +28 -0
- package/src/channels/slack/slack-bridge.mjs +5 -0
- package/src/channels/slack/slack-controller.mjs +2 -0
- package/src/channels/slack/slack-runtime.mjs +24 -0
- package/src/channels/telegram/telegram-api.mjs +9 -0
- package/src/channels/telegram/telegram-bridge.mjs +1 -0
- package/src/channels/telegram/telegram-runtime.mjs +20 -0
- package/src/channels/wecom/wecom-bridge.mjs +49 -15
- package/src/channels/wecom/wecom-controller.mjs +2 -0
- package/src/channels/weixin/weixin-api.mjs +47 -0
- package/src/channels/weixin/weixin-bridge.mjs +261 -43
- package/src/channels/weixin/weixin-controller.mjs +2 -15
- package/src/channels/weixin/weixin-runtime.mjs +1 -0
- package/src/channels/whatsapp/whatsapp-bridge.mjs +1 -0
- package/src/channels/whatsapp/whatsapp-controller.mjs +2 -0
- package/src/channels/whatsapp/whatsapp-runtime.mjs +36 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from './message-utils.mjs';
|
|
10
10
|
import {
|
|
11
11
|
hasInboundImages,
|
|
12
|
+
imagePromptDiagnostic,
|
|
12
13
|
imagePromptUserMessage,
|
|
13
14
|
promptContentForMessage,
|
|
14
15
|
} from '../shared/image-prompt.mjs';
|
|
@@ -48,6 +49,13 @@ import { deliverOutboundArtifacts } from '../shared/semantic/artifact-delivery.m
|
|
|
48
49
|
import {
|
|
49
50
|
createDeliveryReceipt,
|
|
50
51
|
} from '../shared/semantic/delivery.mjs';
|
|
52
|
+
import {
|
|
53
|
+
channelDeliveryFailure,
|
|
54
|
+
clearLastMessageFailure,
|
|
55
|
+
messageFailureText,
|
|
56
|
+
setLastMessageFailure,
|
|
57
|
+
} from '../shared/message-failure.mjs';
|
|
58
|
+
import { beginStatusReaction } from '../shared/status-reaction.mjs';
|
|
51
59
|
import {
|
|
52
60
|
MENU_PAGE_SIZE,
|
|
53
61
|
PRESET_FOLLOW_DEFAULT_SENTINEL,
|
|
@@ -365,6 +373,7 @@ function ensureStatus(status) {
|
|
|
365
373
|
status.lastReplyAt ??= null;
|
|
366
374
|
status.lastRejectedAt ??= null;
|
|
367
375
|
status.lastError ??= null;
|
|
376
|
+
status.lastMessageError ??= null;
|
|
368
377
|
}
|
|
369
378
|
|
|
370
379
|
export class FeishuHarnessBridge {
|
|
@@ -541,7 +550,7 @@ export class FeishuHarnessBridge {
|
|
|
541
550
|
}
|
|
542
551
|
|
|
543
552
|
this.#acceptedMessageIds.add(messageId);
|
|
544
|
-
const processingReaction = this.#
|
|
553
|
+
const processingReaction = this.#beginReaction(messageId);
|
|
545
554
|
const commandMessage = extractInboundMessage(event, this.#client);
|
|
546
555
|
const commandText = nonEmptyString(commandMessage.content) ?? '';
|
|
547
556
|
const batchText = event.message.message_type === 'text'
|
|
@@ -801,6 +810,30 @@ export class FeishuHarnessBridge {
|
|
|
801
810
|
return current;
|
|
802
811
|
}
|
|
803
812
|
|
|
813
|
+
#recordFailure(error, {
|
|
814
|
+
logLabel = 'operation',
|
|
815
|
+
logLevel = 'warn',
|
|
816
|
+
userMessage,
|
|
817
|
+
reason,
|
|
818
|
+
} = {}) {
|
|
819
|
+
this.#status.lastError = error?.message ?? String(error);
|
|
820
|
+
const failure = setLastMessageFailure(this.#status, error, { userMessage, reason });
|
|
821
|
+
this.#logger?.[logLevel]?.(
|
|
822
|
+
`[dsh-feishu] ${logLabel} failed [${failure.referenceId}]:`,
|
|
823
|
+
error?.message ?? String(error),
|
|
824
|
+
);
|
|
825
|
+
return failure;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
async #sendFailure(chatId, error, options = {}) {
|
|
829
|
+
const failure = this.#recordFailure(error, options);
|
|
830
|
+
const text = options.appendMessage
|
|
831
|
+
? `${messageFailureText(failure)}\n\n${options.appendMessage}`
|
|
832
|
+
: messageFailureText(failure);
|
|
833
|
+
await this.#send(chatId, text).catch(() => undefined);
|
|
834
|
+
return failure;
|
|
835
|
+
}
|
|
836
|
+
|
|
804
837
|
async #handleMessageFailure(event, messageId, processingReaction, error) {
|
|
805
838
|
if (error?.code === 'turn-stopped') {
|
|
806
839
|
await this.#removeProcessingReaction(messageId, processingReaction);
|
|
@@ -813,15 +846,21 @@ export class FeishuHarnessBridge {
|
|
|
813
846
|
await this.#removeProcessingReaction(messageId, processingReaction);
|
|
814
847
|
return;
|
|
815
848
|
}
|
|
816
|
-
|
|
817
|
-
|
|
849
|
+
const userMessage = inboundFileUserMessage(error)
|
|
850
|
+
?? imagePromptUserMessage(error);
|
|
851
|
+
const failure = this.#recordFailure(error, {
|
|
852
|
+
logLabel: 'message handling',
|
|
853
|
+
logLevel: 'error',
|
|
854
|
+
userMessage,
|
|
855
|
+
reason: imagePromptDiagnostic(error)?.reason,
|
|
856
|
+
});
|
|
818
857
|
await this.#finishReaction(messageId, processingReaction, 'ERROR');
|
|
858
|
+
const failureText = error?.batchInputMessage
|
|
859
|
+
? `${messageFailureText(failure)}\n\n${error.batchInputMessage}`
|
|
860
|
+
: messageFailureText(failure);
|
|
819
861
|
await this.#send(
|
|
820
862
|
event.message.chat_id,
|
|
821
|
-
|
|
822
|
-
?? inboundFileUserMessage(error)
|
|
823
|
-
?? imagePromptUserMessage(error)
|
|
824
|
-
?? t('处理失败,请稍后重试。如果问题持续,请在 DeepSeek Harness 的飞书插件页面检查连接状态。'),
|
|
863
|
+
failureText,
|
|
825
864
|
).catch(() => undefined);
|
|
826
865
|
}
|
|
827
866
|
|
|
@@ -1025,7 +1064,11 @@ export class FeishuHarnessBridge {
|
|
|
1025
1064
|
const batchSubmission = event.batchSubmission ?? null;
|
|
1026
1065
|
let batchAskCompleted = false;
|
|
1027
1066
|
try {
|
|
1028
|
-
const
|
|
1067
|
+
const {
|
|
1068
|
+
receipt,
|
|
1069
|
+
artifactSendErrors,
|
|
1070
|
+
textDeliveryErrors = 0,
|
|
1071
|
+
} = await this.#answerWithStream(event, key, message, {
|
|
1029
1072
|
onAskComplete: batchSubmission
|
|
1030
1073
|
? () => {
|
|
1031
1074
|
batchAskCompleted = this.#batchInputs.complete(
|
|
@@ -1038,6 +1081,9 @@ export class FeishuHarnessBridge {
|
|
|
1038
1081
|
this.#status.messagesReplied += 1;
|
|
1039
1082
|
this.#status.lastReplyAt = new Date().toISOString();
|
|
1040
1083
|
this.#status.lastError = null;
|
|
1084
|
+
if (textDeliveryErrors === 0 && artifactSendErrors === 0) {
|
|
1085
|
+
clearLastMessageFailure(this.#status);
|
|
1086
|
+
}
|
|
1041
1087
|
return receipt;
|
|
1042
1088
|
} catch (error) {
|
|
1043
1089
|
if (batchSubmission && !batchAskCompleted) {
|
|
@@ -1049,6 +1095,9 @@ export class FeishuHarnessBridge {
|
|
|
1049
1095
|
if (failed.retained) {
|
|
1050
1096
|
const batchError = new Error(error?.message ?? String(error), { cause: error });
|
|
1051
1097
|
batchError.code = error?.code;
|
|
1098
|
+
batchError.providerCode = error?.providerCode;
|
|
1099
|
+
batchError.method = error?.method;
|
|
1100
|
+
if (Number.isInteger(error?.status)) batchError.status = error.status;
|
|
1052
1101
|
batchError.batchInputMessage = failed.message;
|
|
1053
1102
|
throw batchError;
|
|
1054
1103
|
}
|
|
@@ -1643,9 +1692,7 @@ export class FeishuHarnessBridge {
|
|
|
1643
1692
|
})
|
|
1644
1693
|
.catch(async (error) => {
|
|
1645
1694
|
if (this.#signal?.aborted) return;
|
|
1646
|
-
this.#
|
|
1647
|
-
this.#status.lastError = error?.message ?? String(error);
|
|
1648
|
-
await this.#send(entry.chatId, t('卡片操作失败,请稍后重试。')).catch(() => undefined);
|
|
1695
|
+
await this.#sendFailure(entry.chatId, error, { logLabel: 'card action' });
|
|
1649
1696
|
})
|
|
1650
1697
|
.finally(() => {
|
|
1651
1698
|
if (this.#cardActionInFlight.get(dedupeKey) === tracked) {
|
|
@@ -2008,8 +2055,7 @@ export class FeishuHarnessBridge {
|
|
|
2008
2055
|
},
|
|
2009
2056
|
);
|
|
2010
2057
|
} catch (error) {
|
|
2011
|
-
this.#
|
|
2012
|
-
await this.#send(chatId, t('暂时无法获取会话列表,请稍后重试。'));
|
|
2058
|
+
await this.#sendFailure(chatId, error, { logLabel: 'session list' });
|
|
2013
2059
|
}
|
|
2014
2060
|
}
|
|
2015
2061
|
|
|
@@ -2026,8 +2072,7 @@ export class FeishuHarnessBridge {
|
|
|
2026
2072
|
{ key, updateMessageId },
|
|
2027
2073
|
);
|
|
2028
2074
|
} catch (error) {
|
|
2029
|
-
this.#
|
|
2030
|
-
await this.#send(chatId, t('暂时无法获取工作区列表,请稍后重试。'));
|
|
2075
|
+
await this.#sendFailure(chatId, error, { logLabel: 'workspace list' });
|
|
2031
2076
|
}
|
|
2032
2077
|
}
|
|
2033
2078
|
|
|
@@ -2038,7 +2083,10 @@ export class FeishuHarnessBridge {
|
|
|
2038
2083
|
await this.#send(chatId, t('已绑定会话「{title}」\nID:{id}', { title, id: bound?.sessionId ?? sessionId }));
|
|
2039
2084
|
await this.#sendMenuCard(key, chatId, { updateMessageId });
|
|
2040
2085
|
} catch (error) {
|
|
2041
|
-
await this.#
|
|
2086
|
+
await this.#sendFailure(chatId, error, {
|
|
2087
|
+
logLabel: 'session binding',
|
|
2088
|
+
userMessage: t('绑定失败:{message}', { message: safeErrorText(error) }),
|
|
2089
|
+
});
|
|
2042
2090
|
}
|
|
2043
2091
|
}
|
|
2044
2092
|
|
|
@@ -2048,7 +2096,10 @@ export class FeishuHarnessBridge {
|
|
|
2048
2096
|
await this.#send(chatId, t('工作区已切换为:{workspace}', { workspace: current }));
|
|
2049
2097
|
await this.#sendMenuCard(key, chatId, { updateMessageId });
|
|
2050
2098
|
} catch (error) {
|
|
2051
|
-
await this.#
|
|
2099
|
+
await this.#sendFailure(chatId, error, {
|
|
2100
|
+
logLabel: 'workspace switch',
|
|
2101
|
+
userMessage: t('切换失败:{message}', { message: safeErrorText(error) }),
|
|
2102
|
+
});
|
|
2052
2103
|
}
|
|
2053
2104
|
}
|
|
2054
2105
|
|
|
@@ -2247,8 +2298,7 @@ export class FeishuHarnessBridge {
|
|
|
2247
2298
|
catalog._currentId = settings.agentPreset;
|
|
2248
2299
|
await this.#sendCard(chatId, presetCard(catalog), { key, updateMessageId });
|
|
2249
2300
|
} catch (error) {
|
|
2250
|
-
this.#
|
|
2251
|
-
await this.#send(chatId, t('暂时无法获取预设列表,请稍后重试。'));
|
|
2301
|
+
await this.#sendFailure(chatId, error, { logLabel: 'preset card' });
|
|
2252
2302
|
}
|
|
2253
2303
|
}
|
|
2254
2304
|
|
|
@@ -2273,8 +2323,7 @@ export class FeishuHarnessBridge {
|
|
|
2273
2323
|
}
|
|
2274
2324
|
await this.#sendCard(chatId, modelCard(catalog), { key, updateMessageId });
|
|
2275
2325
|
} catch (error) {
|
|
2276
|
-
this.#
|
|
2277
|
-
await this.#send(chatId, t('暂时无法获取模型列表,请稍后重试。'));
|
|
2326
|
+
await this.#sendFailure(chatId, error, { logLabel: 'model card' });
|
|
2278
2327
|
}
|
|
2279
2328
|
}
|
|
2280
2329
|
|
|
@@ -2302,8 +2351,7 @@ export class FeishuHarnessBridge {
|
|
|
2302
2351
|
}
|
|
2303
2352
|
await this.#send(chatId, lines.join('\n'));
|
|
2304
2353
|
} catch (error) {
|
|
2305
|
-
this.#
|
|
2306
|
-
await this.#send(chatId, t('暂时无法获取系统状态,请稍后重试。'));
|
|
2354
|
+
await this.#sendFailure(chatId, error, { logLabel: 'status text' });
|
|
2307
2355
|
}
|
|
2308
2356
|
}
|
|
2309
2357
|
|
|
@@ -2355,8 +2403,7 @@ export class FeishuHarnessBridge {
|
|
|
2355
2403
|
|
|
2356
2404
|
await this.#sendCard(chatId, statusCard(info), { key, updateMessageId });
|
|
2357
2405
|
} catch (error) {
|
|
2358
|
-
this.#
|
|
2359
|
-
await this.#send(chatId, t('暂时无法获取系统状态,请稍后重试。'));
|
|
2406
|
+
await this.#sendFailure(chatId, error, { logLabel: 'status card' });
|
|
2360
2407
|
}
|
|
2361
2408
|
}
|
|
2362
2409
|
|
|
@@ -2381,8 +2428,7 @@ export class FeishuHarnessBridge {
|
|
|
2381
2428
|
);
|
|
2382
2429
|
await this.#send(chatId, result?.message || t('上下文压缩失败。'));
|
|
2383
2430
|
} catch (error) {
|
|
2384
|
-
this.#
|
|
2385
|
-
await this.#send(chatId, t('上下文压缩失败,请稍后重试。'));
|
|
2431
|
+
await this.#sendFailure(chatId, error, { logLabel: 'compact' });
|
|
2386
2432
|
}
|
|
2387
2433
|
}
|
|
2388
2434
|
|
|
@@ -2405,8 +2451,7 @@ export class FeishuHarnessBridge {
|
|
|
2405
2451
|
}
|
|
2406
2452
|
await this.#send(chatId, result?.message || t('/stop 执行完成。'));
|
|
2407
2453
|
} catch (error) {
|
|
2408
|
-
this.#
|
|
2409
|
-
await this.#send(chatId, t('停止任务失败,请稍后重试。'));
|
|
2454
|
+
await this.#sendFailure(chatId, error, { logLabel: 'stop' });
|
|
2410
2455
|
}
|
|
2411
2456
|
}
|
|
2412
2457
|
|
|
@@ -2446,8 +2491,7 @@ export class FeishuHarnessBridge {
|
|
|
2446
2491
|
if (reply) await this.#send(chatId, reply);
|
|
2447
2492
|
}
|
|
2448
2493
|
} catch (error) {
|
|
2449
|
-
this.#
|
|
2450
|
-
await this.#send(chatId, t('预设重置失败,请稍后重试。'));
|
|
2494
|
+
await this.#sendFailure(chatId, error, { logLabel: 'preset reset' });
|
|
2451
2495
|
return;
|
|
2452
2496
|
}
|
|
2453
2497
|
try {
|
|
@@ -2470,8 +2514,7 @@ export class FeishuHarnessBridge {
|
|
|
2470
2514
|
if (reply) await this.#send(chatId, reply);
|
|
2471
2515
|
}
|
|
2472
2516
|
} catch (error) {
|
|
2473
|
-
this.#
|
|
2474
|
-
await this.#send(chatId, t('预设切换失败,请稍后重试。'));
|
|
2517
|
+
await this.#sendFailure(chatId, error, { logLabel: 'preset selection' });
|
|
2475
2518
|
return;
|
|
2476
2519
|
}
|
|
2477
2520
|
try {
|
|
@@ -2503,8 +2546,7 @@ export class FeishuHarnessBridge {
|
|
|
2503
2546
|
if (reply) await this.#send(chatId, reply);
|
|
2504
2547
|
}
|
|
2505
2548
|
} catch (error) {
|
|
2506
|
-
this.#
|
|
2507
|
-
await this.#send(chatId, t('模型切换失败,请稍后重试。'));
|
|
2549
|
+
await this.#sendFailure(chatId, error, { logLabel: 'model selection' });
|
|
2508
2550
|
return;
|
|
2509
2551
|
}
|
|
2510
2552
|
try {
|
|
@@ -3046,10 +3088,14 @@ export class FeishuHarnessBridge {
|
|
|
3046
3088
|
signal: this.#signal,
|
|
3047
3089
|
})
|
|
3048
3090
|
: undefined,
|
|
3049
|
-
|
|
3091
|
+
onFailure: (artifact, error) => setLastMessageFailure(this.#status, error, {
|
|
3092
|
+
userMessage: artifactFailureText(artifact?.fileName, error),
|
|
3093
|
+
reason: error?.code,
|
|
3094
|
+
}),
|
|
3095
|
+
sendFailureNotice: async (_artifact, _error, failure) => ({
|
|
3050
3096
|
messageId: await this.#send(
|
|
3051
3097
|
chatId,
|
|
3052
|
-
|
|
3098
|
+
messageFailureText(failure),
|
|
3053
3099
|
),
|
|
3054
3100
|
}),
|
|
3055
3101
|
logger: this.#logger,
|
|
@@ -3065,11 +3111,13 @@ export class FeishuHarnessBridge {
|
|
|
3065
3111
|
presentation: 'feishu-files',
|
|
3066
3112
|
}),
|
|
3067
3113
|
failureNoticeVisible: delivery.failureNoticeVisible,
|
|
3114
|
+
artifactSendErrors: delivery.artifactSendErrors,
|
|
3068
3115
|
};
|
|
3069
3116
|
}
|
|
3070
3117
|
return {
|
|
3071
3118
|
receipt: delivery.receipt,
|
|
3072
3119
|
failureNoticeVisible: delivery.failureNoticeVisible,
|
|
3120
|
+
artifactSendErrors: delivery.artifactSendErrors,
|
|
3073
3121
|
};
|
|
3074
3122
|
}
|
|
3075
3123
|
|
|
@@ -3110,7 +3158,7 @@ export class FeishuHarnessBridge {
|
|
|
3110
3158
|
},
|
|
3111
3159
|
);
|
|
3112
3160
|
} catch (error) {
|
|
3113
|
-
textSendError = error;
|
|
3161
|
+
textSendError = channelDeliveryFailure(error);
|
|
3114
3162
|
this.#logger.warn?.(
|
|
3115
3163
|
'[dsh-feishu] final text delivery failed; continuing with result files:',
|
|
3116
3164
|
error,
|
|
@@ -3123,8 +3171,11 @@ export class FeishuHarnessBridge {
|
|
|
3123
3171
|
if (textSendError && !artifactDispatched && !delivery.failureNoticeVisible) {
|
|
3124
3172
|
throw textSendError;
|
|
3125
3173
|
}
|
|
3174
|
+
if (textSendError && delivery.artifactSendErrors === 0) {
|
|
3175
|
+
setLastMessageFailure(this.#status, textSendError);
|
|
3176
|
+
}
|
|
3126
3177
|
this.#status.streamFallbacks = (this.#status.streamFallbacks ?? 0) + 1;
|
|
3127
|
-
return delivery
|
|
3178
|
+
return { ...delivery, textDeliveryErrors: textSendError ? 1 : 0 };
|
|
3128
3179
|
}
|
|
3129
3180
|
|
|
3130
3181
|
let promptStarted = false;
|
|
@@ -3177,7 +3228,7 @@ export class FeishuHarnessBridge {
|
|
|
3177
3228
|
},
|
|
3178
3229
|
);
|
|
3179
3230
|
} catch (fallbackError) {
|
|
3180
|
-
textSendError = fallbackError;
|
|
3231
|
+
textSendError = channelDeliveryFailure(fallbackError);
|
|
3181
3232
|
this.#logger.warn?.(
|
|
3182
3233
|
'[dsh-feishu] fallback text delivery failed; continuing with result files:',
|
|
3183
3234
|
fallbackError,
|
|
@@ -3195,8 +3246,11 @@ export class FeishuHarnessBridge {
|
|
|
3195
3246
|
if (textSendError && !artifactDispatched && !delivery.failureNoticeVisible) {
|
|
3196
3247
|
throw textSendError;
|
|
3197
3248
|
}
|
|
3249
|
+
if (textSendError && delivery.artifactSendErrors === 0) {
|
|
3250
|
+
setLastMessageFailure(this.#status, textSendError);
|
|
3251
|
+
}
|
|
3198
3252
|
this.#status.streamFallbacks = (this.#status.streamFallbacks ?? 0) + 1;
|
|
3199
|
-
return delivery
|
|
3253
|
+
return { ...delivery, textDeliveryErrors: textSendError ? 1 : 0 };
|
|
3200
3254
|
}
|
|
3201
3255
|
if (promptStarted) throw error;
|
|
3202
3256
|
|
|
@@ -3224,7 +3278,7 @@ export class FeishuHarnessBridge {
|
|
|
3224
3278
|
},
|
|
3225
3279
|
);
|
|
3226
3280
|
} catch (fallbackError) {
|
|
3227
|
-
textSendError = fallbackError;
|
|
3281
|
+
textSendError = channelDeliveryFailure(fallbackError);
|
|
3228
3282
|
this.#logger.warn?.(
|
|
3229
3283
|
'[dsh-feishu] fallback text delivery failed; continuing with result files:',
|
|
3230
3284
|
fallbackError,
|
|
@@ -3237,8 +3291,11 @@ export class FeishuHarnessBridge {
|
|
|
3237
3291
|
if (textSendError && !artifactDispatched && !delivery.failureNoticeVisible) {
|
|
3238
3292
|
throw textSendError;
|
|
3239
3293
|
}
|
|
3294
|
+
if (textSendError && delivery.artifactSendErrors === 0) {
|
|
3295
|
+
setLastMessageFailure(this.#status, textSendError);
|
|
3296
|
+
}
|
|
3240
3297
|
this.#status.streamFallbacks = (this.#status.streamFallbacks ?? 0) + 1;
|
|
3241
|
-
return delivery
|
|
3298
|
+
return { ...delivery, textDeliveryErrors: textSendError ? 1 : 0 };
|
|
3242
3299
|
}
|
|
3243
3300
|
const delivery = await this.#deliverArtifacts(
|
|
3244
3301
|
chatId,
|
|
@@ -3251,7 +3308,7 @@ export class FeishuHarnessBridge {
|
|
|
3251
3308
|
}),
|
|
3252
3309
|
);
|
|
3253
3310
|
this.#status.streamResponses = (this.#status.streamResponses ?? 0) + 1;
|
|
3254
|
-
return delivery
|
|
3311
|
+
return delivery;
|
|
3255
3312
|
}
|
|
3256
3313
|
|
|
3257
3314
|
async #processInteractionReply(event, messageId, key, expected, processingReaction) {
|
|
@@ -3547,35 +3604,24 @@ export class FeishuHarnessBridge {
|
|
|
3547
3604
|
return t('_{text}_', { text: update.text || t('正在处理…') });
|
|
3548
3605
|
}
|
|
3549
3606
|
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
return null;
|
|
3560
|
-
}
|
|
3607
|
+
#beginReaction(messageId) {
|
|
3608
|
+
return beginStatusReaction({
|
|
3609
|
+
adapter: this.#channel,
|
|
3610
|
+
target: messageId,
|
|
3611
|
+
reactions: { processing: 'OnIt', success: 'DONE', error: 'ERROR' },
|
|
3612
|
+
status: this.#status,
|
|
3613
|
+
logger: this.#logger,
|
|
3614
|
+
label: 'feishu',
|
|
3615
|
+
});
|
|
3561
3616
|
}
|
|
3562
3617
|
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
if (reactionId && this.#channel?.removeReaction) {
|
|
3566
|
-
try {
|
|
3567
|
-
await this.#channel.removeReaction(messageId, reactionId);
|
|
3568
|
-
this.#status.reactionsRemoved = (this.#status.reactionsRemoved ?? 0) + 1;
|
|
3569
|
-
} catch (error) {
|
|
3570
|
-
this.#status.reactionErrors = (this.#status.reactionErrors ?? 0) + 1;
|
|
3571
|
-
this.#logger.warn?.('[dsh-feishu] unable to remove processing reaction:', error.message);
|
|
3572
|
-
}
|
|
3573
|
-
}
|
|
3618
|
+
#removeProcessingReaction(_messageId, processingReaction) {
|
|
3619
|
+
processingReaction.clear();
|
|
3574
3620
|
}
|
|
3575
3621
|
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3622
|
+
#finishReaction(_messageId, processingReaction, finalEmojiType) {
|
|
3623
|
+
if (finalEmojiType === 'ERROR') processingReaction.error();
|
|
3624
|
+
else processingReaction.success();
|
|
3579
3625
|
}
|
|
3580
3626
|
|
|
3581
3627
|
async #send(chatId, text) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { connectionTestMessage } from '../shared/connection-test.mjs';
|
|
3
|
+
import { publicMessageFailure } from '../shared/message-failure.mjs';
|
|
3
4
|
import { RegistrationManager } from './registration-manager.mjs';
|
|
4
5
|
import {
|
|
5
6
|
CALLBACK_REPAIR_OPERATION,
|
|
@@ -633,6 +634,7 @@ export class MultiBotDshFeishuController {
|
|
|
633
634
|
groupMessagePermissionGranted: config.groupMessagePermissionGranted === true,
|
|
634
635
|
bot: publicBot(config),
|
|
635
636
|
connection,
|
|
637
|
+
lastMessageError: publicMessageFailure(connection.lastMessageError),
|
|
636
638
|
error,
|
|
637
639
|
};
|
|
638
640
|
});
|