@xmanrui/dsh-im 1.5.0 → 2.0.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 +16 -4
- package/README.md +16 -4
- package/lib/index.js +208 -178
- package/package.json +1 -1
- package/plugin-src/host/index.mjs +2 -0
- package/src/channels/dingtalk/config-store.mjs +5 -3
- package/src/channels/dingtalk/dingtalk-api.mjs +2 -1
- package/src/channels/dingtalk/dingtalk-bridge.mjs +45 -40
- package/src/channels/dingtalk/dingtalk-card-stream.mjs +3 -1
- package/src/channels/dingtalk/dingtalk-controller.mjs +24 -23
- package/src/channels/dingtalk/dingtalk-runtime.mjs +4 -3
- package/src/channels/dingtalk/state-store.mjs +3 -1
- package/src/channels/discord/config-store.mjs +2 -1
- package/src/channels/discord/discord-api.mjs +25 -1
- package/src/channels/discord/discord-runtime.mjs +237 -11
- package/src/channels/feishu/bridge.mjs +131 -123
- package/src/channels/feishu/feishu-cards.mjs +62 -54
- package/src/channels/feishu/feishu-channel.mjs +5 -4
- package/src/channels/feishu/feishu-runtime.mjs +10 -9
- package/src/channels/feishu/message-utils.mjs +4 -3
- package/src/channels/office/office-job-executor.mjs +15 -14
- package/src/channels/office/office-runtime.mjs +6 -5
- package/src/channels/qq/config-store.mjs +3 -1
- package/src/channels/qq/markdown-reply.mjs +4 -2
- package/src/channels/qq/qq-bridge.mjs +57 -52
- package/src/channels/qq/qq-controller.mjs +17 -16
- package/src/channels/qq/qq-runtime.mjs +3 -2
- package/src/channels/shared/agent-preset.mjs +3 -1
- package/src/channels/shared/compact-command.mjs +15 -14
- package/src/channels/shared/connection-test.mjs +6 -4
- package/src/channels/shared/control-command.mjs +13 -11
- package/src/channels/shared/editable-message-stream.mjs +4 -2
- package/src/channels/shared/harness-approval.mjs +23 -21
- package/src/channels/shared/harness-client.mjs +3 -2
- package/src/channels/shared/harness-question.mjs +8 -6
- package/src/channels/shared/i18n-en/dingtalk.mjs +52 -0
- package/src/channels/shared/i18n-en/discord.mjs +8 -0
- package/src/channels/shared/i18n-en/feishu.mjs +217 -0
- package/src/channels/shared/i18n-en/office.mjs +23 -0
- package/src/channels/shared/i18n-en/qq.mjs +54 -0
- package/src/channels/shared/i18n-en/shared-a.mjs +91 -0
- package/src/channels/shared/i18n-en/shared-b.mjs +215 -0
- package/src/channels/shared/i18n-en/shared-c.mjs +99 -0
- package/src/channels/shared/i18n-en/slack.mjs +27 -0
- package/src/channels/shared/i18n-en/telegram.mjs +21 -0
- package/src/channels/shared/i18n-en/wecom.mjs +38 -0
- package/src/channels/shared/i18n-en/weixin.mjs +80 -0
- package/src/channels/shared/i18n-en/whatsapp.mjs +17 -0
- package/src/channels/shared/i18n-en.mjs +35 -0
- package/src/channels/shared/i18n.mjs +35 -0
- package/src/channels/shared/image-prompt.mjs +17 -15
- package/src/channels/shared/inbound-file.mjs +5 -3
- package/src/channels/shared/model-command.mjs +35 -31
- package/src/channels/shared/preset-command.mjs +41 -38
- package/src/channels/shared/semantic/artifact-delivery.mjs +1 -1
- package/src/channels/shared/semantic/delivery.mjs +38 -0
- package/src/channels/shared/text-harness-bridge.mjs +130 -63
- package/src/channels/shared/token-bot-controller.mjs +32 -11
- package/src/channels/shared/workspace-command.mjs +69 -58
- package/src/channels/slack/config-store.mjs +3 -1
- package/src/channels/slack/slack-api.mjs +6 -5
- package/src/channels/slack/slack-controller.mjs +10 -9
- package/src/channels/slack/slack-runtime.mjs +16 -4
- package/src/channels/telegram/config-store.mjs +2 -1
- package/src/channels/telegram/telegram-api.mjs +72 -6
- package/src/channels/telegram/telegram-rich-message.mjs +147 -0
- package/src/channels/telegram/telegram-runtime.mjs +373 -5
- package/src/channels/wecom/config-store.mjs +3 -1
- package/src/channels/wecom/wecom-bridge.mjs +59 -55
- package/src/channels/wecom/wecom-controller.mjs +20 -19
- package/src/channels/wecom/wecom-runtime.mjs +2 -1
- package/src/channels/weixin/config-store.mjs +2 -1
- package/src/channels/weixin/weixin-bridge.mjs +50 -49
- package/src/channels/weixin/weixin-controller.mjs +22 -21
- package/src/channels/weixin/weixin-runtime.mjs +3 -2
- package/src/channels/whatsapp/config-store.mjs +3 -1
- package/src/channels/whatsapp/whatsapp-bridge.mjs +3 -1
- package/src/channels/whatsapp/whatsapp-controller.mjs +15 -14
- package/src/channels/whatsapp/whatsapp-runtime.mjs +5 -4
- package/src/channels/whatsapp/whatsapp-web-session.mjs +3 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { t } from './i18n.mjs';
|
|
2
|
+
|
|
1
3
|
const APPROVAL_REPLIES = new Map([
|
|
2
4
|
['批准', 'allowed-once'],
|
|
3
5
|
['同意', 'allowed-once'],
|
|
@@ -68,16 +70,16 @@ export function harnessApprovalText(payload, {
|
|
|
68
70
|
if (!operation || operation.length > maxArgumentsLength) return null;
|
|
69
71
|
|
|
70
72
|
const lines = [
|
|
71
|
-
'DeepSeek Harness 需要你的审批:',
|
|
73
|
+
t('DeepSeek Harness 需要你的审批:'),
|
|
72
74
|
'',
|
|
73
|
-
|
|
74
|
-
'操作参数:',
|
|
75
|
+
t('工具:{tool}', { tool: printableText(payload.toolName) }),
|
|
76
|
+
t('操作参数:'),
|
|
75
77
|
operation,
|
|
76
78
|
];
|
|
77
79
|
const reason = printableText(payload.reason);
|
|
78
|
-
if (reason) lines.push(
|
|
79
|
-
lines.push('', APPROVAL_PROMPT);
|
|
80
|
-
if (requiresMention) lines.push('', '群聊中请 @机器人 后发送审批决定。');
|
|
80
|
+
if (reason) lines.push(t('原因:{reason}', { reason }));
|
|
81
|
+
lines.push('', t(APPROVAL_PROMPT));
|
|
82
|
+
if (requiresMention) lines.push('', t('群聊中请 @机器人 后发送审批决定。'));
|
|
81
83
|
return lines.join('\n');
|
|
82
84
|
}
|
|
83
85
|
|
|
@@ -93,9 +95,9 @@ function approvalResult(pending, outcome) {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
function approvalOutcomeText(outcome) {
|
|
96
|
-
if (outcome === 'allowed-once') return '已批准,仅对本次操作有效。';
|
|
97
|
-
if (outcome === 'rejected') return '已拒绝此次操作。';
|
|
98
|
-
return APPROVAL_RESOLVED_TEXT;
|
|
98
|
+
if (outcome === 'allowed-once') return t('已批准,仅对本次操作有效。');
|
|
99
|
+
if (outcome === 'rejected') return t('已拒绝此次操作。');
|
|
100
|
+
return t(APPROVAL_RESOLVED_TEXT);
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
export class HarnessApprovalQueue {
|
|
@@ -149,11 +151,11 @@ export class HarnessApprovalQueue {
|
|
|
149
151
|
return null;
|
|
150
152
|
}
|
|
151
153
|
if (!decision) return null;
|
|
152
|
-
return notice(APPROVAL_RESOLVED_TEXT, true);
|
|
154
|
+
return notice(t(APPROVAL_RESOLVED_TEXT), true);
|
|
153
155
|
}
|
|
154
156
|
if (pending.actor !== actor || (pending.requiresMention && addressed !== true)) {
|
|
155
157
|
if (!decision) return null;
|
|
156
|
-
return notice('只有发起当前任务的用户可以处理这条审批。');
|
|
158
|
+
return notice(t('只有发起当前任务的用户可以处理这条审批。'));
|
|
157
159
|
}
|
|
158
160
|
|
|
159
161
|
return {
|
|
@@ -168,14 +170,14 @@ export class HarnessApprovalQueue {
|
|
|
168
170
|
await questionCompletion.catch(() => undefined);
|
|
169
171
|
if (pending.inactive || pending.resolving) return;
|
|
170
172
|
if (typeof isQuestionPending === 'function' && isQuestionPending()) {
|
|
171
|
-
await send(APPROVAL_AFTER_QUESTION_PROMPT);
|
|
173
|
+
await send(t(APPROVAL_AFTER_QUESTION_PROMPT));
|
|
172
174
|
return;
|
|
173
175
|
}
|
|
174
176
|
}
|
|
175
177
|
await pending.activationTask?.catch(() => undefined);
|
|
176
178
|
await pending.presentationTask?.catch(() => undefined);
|
|
177
179
|
if (pending.inactive || pending.resolving) {
|
|
178
|
-
await send(APPROVAL_RESOLVED_TEXT);
|
|
180
|
+
await send(t(APPROVAL_RESOLVED_TEXT));
|
|
179
181
|
return;
|
|
180
182
|
}
|
|
181
183
|
pending.send = send;
|
|
@@ -185,15 +187,15 @@ export class HarnessApprovalQueue {
|
|
|
185
187
|
if (!presentedWhenClaimed || !pending.presented) {
|
|
186
188
|
if (!pending.presented) await this.#present(pending);
|
|
187
189
|
if (pending.inactive || pending.resolving) return;
|
|
188
|
-
await send(APPROVAL_PROMPT);
|
|
190
|
+
await send(t(APPROVAL_PROMPT));
|
|
189
191
|
return;
|
|
190
192
|
}
|
|
191
193
|
if (pending.submitting) {
|
|
192
|
-
await send('审批决定正在提交,请稍候。');
|
|
194
|
+
await send(t('审批决定正在提交,请稍候。'));
|
|
193
195
|
return;
|
|
194
196
|
}
|
|
195
197
|
if (!decision) {
|
|
196
|
-
await send(APPROVAL_PROMPT);
|
|
198
|
+
await send(t(APPROVAL_PROMPT));
|
|
197
199
|
return;
|
|
198
200
|
}
|
|
199
201
|
await this.#submit(pending, decision);
|
|
@@ -251,8 +253,8 @@ export class HarnessApprovalQueue {
|
|
|
251
253
|
if (!text) {
|
|
252
254
|
const rejected = await this.#rejectInteraction(interaction, payload);
|
|
253
255
|
await send(rejected
|
|
254
|
-
? '无法完整展示这次操作,已安全拒绝此次审批。'
|
|
255
|
-
: APPROVAL_RESOLVED_TEXT);
|
|
256
|
+
? t('无法完整展示这次操作,已安全拒绝此次审批。')
|
|
257
|
+
: t(APPROVAL_RESOLVED_TEXT));
|
|
256
258
|
return true;
|
|
257
259
|
}
|
|
258
260
|
|
|
@@ -335,7 +337,7 @@ export class HarnessApprovalQueue {
|
|
|
335
337
|
pending.closedOutcome = 'resolved';
|
|
336
338
|
if ((pending.presented || pending.deliveryCompleted) && !pending.resolutionNotified) {
|
|
337
339
|
pending.resolutionNotified = true;
|
|
338
|
-
await pending.send(APPROVAL_RESOLVED_TEXT).catch(() => undefined);
|
|
340
|
+
await pending.send(t(APPROVAL_RESOLVED_TEXT)).catch(() => undefined);
|
|
339
341
|
}
|
|
340
342
|
} else {
|
|
341
343
|
this.#logger.warn?.(`[dsh-im:${this.#label}] failed to reject a closing approval:`, error);
|
|
@@ -377,7 +379,7 @@ export class HarnessApprovalQueue {
|
|
|
377
379
|
const next = this.#remove(pending);
|
|
378
380
|
await this.#transition(next, async () => {
|
|
379
381
|
if (!pending.resolutionNotified) {
|
|
380
|
-
await send(APPROVAL_RESOLVED_TEXT).catch(() => undefined);
|
|
382
|
+
await send(t(APPROVAL_RESOLVED_TEXT)).catch(() => undefined);
|
|
381
383
|
}
|
|
382
384
|
});
|
|
383
385
|
return;
|
|
@@ -385,7 +387,7 @@ export class HarnessApprovalQueue {
|
|
|
385
387
|
if (pending.inactive) return;
|
|
386
388
|
pending.submitting = false;
|
|
387
389
|
this.#logger.error?.(`[dsh-im:${this.#label}] failed to submit an approval:`, error);
|
|
388
|
-
await pending.send('审批提交失败,请重新回复「批准」或「拒绝」。').catch(() => undefined);
|
|
390
|
+
await pending.send(t('审批提交失败,请重新回复「批准」或「拒绝」。')).catch(() => undefined);
|
|
389
391
|
return;
|
|
390
392
|
}
|
|
391
393
|
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
InboundFileError,
|
|
9
9
|
} from './inbound-file.mjs';
|
|
10
10
|
import { outboundArtifactRegistry } from './semantic/artifact.mjs';
|
|
11
|
+
import { t } from './i18n.mjs';
|
|
11
12
|
|
|
12
13
|
// Every channel plugin runs in the same Host process. Sharing ownership by
|
|
13
14
|
// Harness origin prevents two channel-specific clients bound to one Session
|
|
@@ -438,7 +439,7 @@ export class HarnessReplyTracker {
|
|
|
438
439
|
}
|
|
439
440
|
|
|
440
441
|
if (event.type === 'tool/call') {
|
|
441
|
-
const name = nonEmptyText(event.data?.name) ?? '工具';
|
|
442
|
+
const name = nonEmptyText(event.data?.name) ?? t('工具');
|
|
442
443
|
const callId = nonEmptyText(event.data?.callId)
|
|
443
444
|
?? nonEmptyText(event.data?.subCallId);
|
|
444
445
|
if (callId) this.#toolNames.set(callId, name);
|
|
@@ -453,7 +454,7 @@ export class HarnessReplyTracker {
|
|
|
453
454
|
const error = toolResultErrorText(event.data?.error);
|
|
454
455
|
pushUpdate({
|
|
455
456
|
type: 'status',
|
|
456
|
-
text: '正在整理结果…',
|
|
457
|
+
text: t('正在整理结果…'),
|
|
457
458
|
...(toolName ? { toolName } : {}),
|
|
458
459
|
...(error ? { error } : {}),
|
|
459
460
|
});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { t } from './i18n.mjs';
|
|
2
|
+
|
|
1
3
|
function nonEmptyString(value) {
|
|
2
4
|
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
3
5
|
}
|
|
@@ -17,9 +19,9 @@ export function validHarnessQuestion(question) {
|
|
|
17
19
|
export function harnessQuestionText(question, index, total, { requiresMention = false } = {}) {
|
|
18
20
|
const lines = [];
|
|
19
21
|
const progress = total > 1 ? `(${index + 1}/${total})` : '';
|
|
20
|
-
lines.push(
|
|
22
|
+
lines.push(t('DeepSeek Harness 需要你补充信息{progress}:', { progress }));
|
|
21
23
|
if (nonEmptyString(question.header)) lines.push('', question.header.trim());
|
|
22
|
-
lines.push('', nonEmptyString(question.question) ?? '请输入你的回答。');
|
|
24
|
+
lines.push('', nonEmptyString(question.question) ?? t('请输入你的回答。'));
|
|
23
25
|
if (nonEmptyString(question.detail)) lines.push('', question.detail.trim());
|
|
24
26
|
|
|
25
27
|
const options = Array.isArray(question.options) ? question.options : [];
|
|
@@ -31,12 +33,12 @@ export function harnessQuestionText(question, index, total, { requiresMention =
|
|
|
31
33
|
lines.push(`${optionIndex + 1}. ${label}${description ? ` — ${description}` : ''}`);
|
|
32
34
|
});
|
|
33
35
|
lines.push('', question.multiSelect === true
|
|
34
|
-
? '请回复选项序号或文字;多选用逗号分隔,也可补充其他内容。'
|
|
35
|
-
: '请回复一个选项序号或文字,也可直接输入其他答案。');
|
|
36
|
+
? t('请回复选项序号或文字;多选用逗号分隔,也可补充其他内容。')
|
|
37
|
+
: t('请回复一个选项序号或文字,也可直接输入其他答案。'));
|
|
36
38
|
} else {
|
|
37
|
-
lines.push('', '请直接回复你的答案。');
|
|
39
|
+
lines.push('', t('请直接回复你的答案。'));
|
|
38
40
|
}
|
|
39
|
-
if (requiresMention) lines.push('', '群聊中请 @机器人 后发送答案。');
|
|
41
|
+
if (requiresMention) lines.push('', t('群聊中请 @机器人 后发送答案。'));
|
|
40
42
|
return lines.join('\n');
|
|
41
43
|
}
|
|
42
44
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// English translations (dingtalk area). Keys are exact Chinese literals passed to t().
|
|
2
|
+
export default {
|
|
3
|
+
// Bot chat replies and card text (dingtalk-bridge.mjs, dingtalk-card-stream.mjs,
|
|
4
|
+
// dingtalk-api.mjs)
|
|
5
|
+
'已连接 DeepSeek Harness,正在思考…': 'Connected to DeepSeek Harness, thinking…',
|
|
6
|
+
|
|
7
|
+
'钉钉机器人已连接 DeepSeek Harness。': 'The DingTalk bot is connected to DeepSeek Harness.',
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
'钉钉未能换取图片下载地址,请重新发送;若持续失败,请检查机器人的“企业内机器人发送消息权限”。': 'DingTalk could not provide the image download address. Please resend; if it keeps failing, check the bot\'s "Send messages as an internal robot" permission.',
|
|
13
|
+
'钉钉没有返回图片下载地址,请重新发送。': 'DingTalk did not return an image download address. Please resend.',
|
|
14
|
+
'钉钉返回的图片临时地址无法读取,请重新发送。': 'The temporary image address returned by DingTalk could not be read. Please resend.',
|
|
15
|
+
'结果文件「{name}」发送结果未能确认,请先检查聊天内是否已收到,不要立即重试。': 'Delivery of the result file "{name}" could not be confirmed. Please check whether it already arrived in the chat before retrying.',
|
|
16
|
+
'结果文件「{name}」已生成,但钉钉应用或机器人缺少文件消息权限。请开通应用 qyapi_base 权限,并确认机器人具备文件消息发送能力。': 'Result file "{name}" was generated, but the DingTalk app or bot lacks file message permission. Enable the app\'s qyapi_base permission and make sure the bot can send file messages.',
|
|
17
|
+
'结果文件「{name}」超过当前钉钉机器人可发送的文件大小,未发送。': 'Result file "{name}" exceeds the file size limit of the current DingTalk bot and was not sent.',
|
|
18
|
+
'结果文件「{name}」暂时被钉钉限流,未能发送,请稍后重试。': 'Result file "{name}" was rate-limited by DingTalk and could not be sent. Please try again later.',
|
|
19
|
+
'结果文件「{name}」已生成,但钉钉拒绝了该文件消息,请检查文件类型和机器人文件消息配置。': 'Result file "{name}" was generated, but DingTalk rejected the file message. Check the file type and the bot\'s file message configuration.',
|
|
20
|
+
|
|
21
|
+
'结果文件「{name}」已生成,但暂时未能通过钉钉发送,请稍后重试。': 'Result file "{name}" was generated but could not be sent via DingTalk right now. Please try again later.',
|
|
22
|
+
'结果文件已生成。': 'The result file has been generated.',
|
|
23
|
+
'钉钉机器人与 DeepSeek Harness 连接正常。': 'The DingTalk bot is connected to DeepSeek Harness normally.',
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// Host-side status and error text (dingtalk-bridge.mjs, dingtalk-runtime.mjs,
|
|
28
|
+
// dingtalk-controller.mjs, config-store.mjs, state-store.mjs)
|
|
29
|
+
'钉钉命令处理失败。': 'Failed to process the DingTalk command.',
|
|
30
|
+
'钉钉消息没有安全的回复地址。': 'The DingTalk message has no safe reply address.',
|
|
31
|
+
'钉钉审批处理失败。': 'Failed to process the DingTalk approval.',
|
|
32
|
+
'钉钉消息处理失败。': 'Failed to process the DingTalk message.',
|
|
33
|
+
'钉钉消息格式无效。': 'Invalid DingTalk message format.',
|
|
34
|
+
'钉钉交互问题发送失败。': 'Failed to send the DingTalk interaction question.',
|
|
35
|
+
'钉钉用户': 'DingTalk user',
|
|
36
|
+
'钉钉机器人': 'DingTalk bot',
|
|
37
|
+
'身份已隐藏': 'Identity hidden',
|
|
38
|
+
'钉钉机器人凭据缺失,请移除后重新扫码。': 'The DingTalk bot credentials are missing. Remove the bot and scan the QR code again.',
|
|
39
|
+
'钉钉连接未就绪,请稍后重试。': 'The DingTalk connection is not ready. Please try again later.',
|
|
40
|
+
'钉钉连接仍未就绪,请稍后重试。': 'The DingTalk connection is still not ready. Please try again later.',
|
|
41
|
+
'扫码接入已取消。': 'QR code setup has been cancelled.',
|
|
42
|
+
'无法生成钉钉二维码,请稍后重试。': 'Could not generate the DingTalk QR code. Please try again later.',
|
|
43
|
+
'二维码已过期,请重新生成。': 'The QR code has expired. Generate a new one.',
|
|
44
|
+
'钉钉已接入,但消息连接暂未就绪,请稍后重试。': 'DingTalk is connected, but the message connection is not ready yet. Please try again later.',
|
|
45
|
+
'钉钉未完成机器人授权,请重新扫码。': 'DingTalk did not complete the bot authorization. Please scan the QR code again.',
|
|
46
|
+
'钉钉授权状态暂时不可用,正在重试。': 'The DingTalk authorization status is temporarily unavailable. Retrying.',
|
|
47
|
+
'钉钉已授权,但无法安全保存接入配置。': 'DingTalk authorization succeeded, but the configuration could not be saved safely.',
|
|
48
|
+
'钉钉授权查询暂时失败,正在重试。': 'The DingTalk authorization query failed temporarily. Retrying.',
|
|
49
|
+
'钉钉机器人({clientId})': 'DingTalk bot ({clientId})',
|
|
50
|
+
'钉钉 Stream 消息连接运行正常': 'The DingTalk Stream message connection is running normally',
|
|
51
|
+
'钉钉消息连接当前离线': 'The DingTalk message connection is currently offline',
|
|
52
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// English translations (discord area). Keys are exact Chinese literals passed to t().
|
|
2
|
+
export default {
|
|
3
|
+
'Discord Bot Token 无效,请重新填写。': 'The Discord Bot Token is invalid. Please enter it again.',
|
|
4
|
+
'Discord Gateway Intents 配置不正确,请检查 Developer Portal 的 Bot 设置。':
|
|
5
|
+
'The Discord Gateway Intents are misconfigured. Please check the Bot settings in the Developer Portal.',
|
|
6
|
+
'Discord机器人': 'Discord Bot',
|
|
7
|
+
' Gateway 长连接': ' Gateway long-lived connection',
|
|
8
|
+
};
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
// English translations (feishu area). Keys are exact Chinese literals passed to t().
|
|
2
|
+
export default {
|
|
3
|
+
// feishu/bridge.mjs — welcome / help
|
|
4
|
+
'北汇星河 AIOS 已连接 DeepSeek Harness。':
|
|
5
|
+
'BeiHui XingHe AIOS is connected to DeepSeek Harness.',
|
|
6
|
+
'/repair 修复卡片按钮回调': '/repair Repair the card-button callback',
|
|
7
|
+
'/m(或 /menu) 打开交互卡片菜单': '/m (or /menu) Open the interactive card menu',
|
|
8
|
+
'/watch [Session ID 或序号] 关注会话,任务完成自动推送':
|
|
9
|
+
'/watch [Session ID or index] Watch a session; completion is pushed automatically',
|
|
10
|
+
'/unwatch [Session ID 或序号] 取消关注':
|
|
11
|
+
'/unwatch [Session ID or index] Stop watching',
|
|
12
|
+
'/watchlist 查看关注列表': '/watchlist View the watch list',
|
|
13
|
+
'/archived on|off 会话列表是否包含归档会话':
|
|
14
|
+
'/archived on|off Whether the session list includes archived sessions',
|
|
15
|
+
'工作区必须是绝对路径。': 'The workspace must be an absolute path.',
|
|
16
|
+
'工作区路径不存在。': 'The workspace path does not exist.',
|
|
17
|
+
'工作区路径必须指向一个目录。': 'The workspace path must point to a directory.',
|
|
18
|
+
'机器人正在移除或已重新接入,无法操作原会话的工作区。':
|
|
19
|
+
'The bot is being removed or has been reconnected; the original session’s workspace cannot be changed.',
|
|
20
|
+
'操作失败,请稍后重试。': 'The operation failed. Please try again later.',
|
|
21
|
+
'结果文件「{name}」已生成,但机器人缺少飞书文件上传权限。请为应用添加 im:resource 并完成必要审批后重试。':
|
|
22
|
+
'The result file "{name}" was generated, but the bot lacks Feishu file-upload permission. Add the im:resource scope to the app, complete the required approval, and try again.',
|
|
23
|
+
'结果文件「{name}」超过飞书 30 MB 上限,未发送。':
|
|
24
|
+
'The result file "{name}" exceeds the Feishu 30 MB limit and was not sent.',
|
|
25
|
+
'结果文件「{name}」为空,飞书不允许发送空文件。':
|
|
26
|
+
'The result file "{name}" is empty; Feishu does not allow sending empty files.',
|
|
27
|
+
'结果文件「{name}」暂时被飞书限流,未能发送,请稍后重试。':
|
|
28
|
+
'The result file "{name}" was temporarily rate-limited by Feishu and could not be sent. Please try again later.',
|
|
29
|
+
'结果文件「{name}」已生成,但暂时未能发送,请稍后重试。':
|
|
30
|
+
'The result file "{name}" was generated but could not be sent right now. Please try again later.',
|
|
31
|
+
'处理失败,请稍后重试。如果问题持续,请在 DeepSeek Harness 的飞书插件页面检查连接状态。':
|
|
32
|
+
'Message processing failed. Please try again later. If the problem persists, check the connection status on the Feishu plugin page in DeepSeek Harness.',
|
|
33
|
+
'已开启全新 Harness 会话。': 'A brand-new Harness session has started.',
|
|
34
|
+
'飞书机器人与 DeepSeek Harness 连接正常。':
|
|
35
|
+
'The Feishu bot is connected to DeepSeek Harness and working normally.',
|
|
36
|
+
'用法:/archived on(包含归档会话)或 /archived off(隐藏归档会话)':
|
|
37
|
+
'Usage: /archived on (include archived sessions) or /archived off (hide archived sessions)',
|
|
38
|
+
'已开启:会话列表包含归档会话。': 'On: the session list includes archived sessions.',
|
|
39
|
+
'已关闭:会话列表隐藏归档会话。': 'Off: the session list hides archived sessions.',
|
|
40
|
+
|
|
41
|
+
// feishu/bridge.mjs — repair flow
|
|
42
|
+
'为避免授权链接暴露,请私聊机器人发送 /repair。':
|
|
43
|
+
'To keep the authorization link private, send /repair to the bot in a direct message.',
|
|
44
|
+
'当前机器人没有可验证的接入者身份,不能从聊天发起修复;请先在插件页设置管理员。':
|
|
45
|
+
'This bot has no verifiable owner identity, so repair cannot be started from chat. Set an administrator on the plugin page first.',
|
|
46
|
+
'此操作只能由机器人接入者在私聊中发起,未进行任何修改。':
|
|
47
|
+
'This action can only be started by the bot owner in a direct message. Nothing was changed.',
|
|
48
|
+
'当前 Host 版本暂不支持聊天内修复,请先更新插件。':
|
|
49
|
+
'The current Host version does not support in-chat repair. Update the plugin first.',
|
|
50
|
+
'用法:/repair、/repair qr、/repair status、/repair cancel 或 /repair verify':
|
|
51
|
+
'Usage: /repair, /repair qr, /repair status, /repair cancel, or /repair verify',
|
|
52
|
+
'当前 Runtime 没有可恢复的修复任务记录(机器人可能刚完成密钥更新并重启)。本命令不会启动新的授权;请查看机器人发送的验证结果,确认上一次任务已结束后再发送 /repair。':
|
|
53
|
+
'The current Runtime has no recoverable repair attempt (the bot may have just rotated its secret and restarted). This command starts no new authorization. Check the verification result the bot sent, then send /repair after the previous attempt has finished.',
|
|
54
|
+
'另一位管理员正在修复该机器人,本次不会显示其授权信息。':
|
|
55
|
+
'Another administrator is repairing this bot; its authorization info will not be shown this time.',
|
|
56
|
+
'暂时无法取消修复任务,请稍后重试。':
|
|
57
|
+
'Could not cancel the repair task right now. Please try again later.',
|
|
58
|
+
'暂时无法查询修复状态,请稍后重试。':
|
|
59
|
+
'Could not check the repair status right now. Please try again later.',
|
|
60
|
+
'修复流程暂时失败,现有机器人连接不受影响;请稍后发送 /repair 重试。':
|
|
61
|
+
'The repair flow failed for now; the existing bot connection is unaffected. Send /repair again later.',
|
|
62
|
+
'飞书返回了无法安全验证的授权链接,已中止本次修复。':
|
|
63
|
+
'Feishu returned an authorization link that cannot be verified safely. This repair was aborted.',
|
|
64
|
+
'飞书未返回授权链接,已中止本次修复。':
|
|
65
|
+
'Feishu did not return an authorization link. This repair was aborted.',
|
|
66
|
+
'授权已确认,正在发送并等待测试按钮回调;收到真实回调后才会完成。':
|
|
67
|
+
'Authorization confirmed. Sending a test button and waiting for its callback; this completes only after a real callback arrives.',
|
|
68
|
+
'修复状态查询中断,现有机器人连接不受影响;发送 /repair status 重试查询。':
|
|
69
|
+
'The repair status query was interrupted; the existing bot connection is unaffected. Send /repair status to retry.',
|
|
70
|
+
'链接为短期有效': 'The link is valid for a short time.',
|
|
71
|
+
'链接约 {minutes} 分钟后过期': 'The link expires in about {minutes} minutes',
|
|
72
|
+
'已有一个修复任务在等待授权。': 'A repair task is already waiting for authorization.',
|
|
73
|
+
'🔧 准备修复卡片按钮。': '🔧 Preparing to repair the card buttons.',
|
|
74
|
+
'本次只会增量添加 card.action.trigger。请核对确认页只显示这一项;若出现其他权限或事件,请取消。':
|
|
75
|
+
'Only card.action.trigger will be added. Check that the confirmation page shows only this item; cancel if any other permission or event appears.',
|
|
76
|
+
'当前设备直接打开:': 'Open directly on this device:',
|
|
77
|
+
'若要用另一台设备扫码,发送 /repair qr。{expiry}。':
|
|
78
|
+
'To scan with another device, send /repair qr. {expiry}.',
|
|
79
|
+
'请用另一台设备扫码完成授权{remaining}。':
|
|
80
|
+
'Complete authorization by scanning with another device{remaining}.',
|
|
81
|
+
'(剩余约 {minutes} 分钟)': ' (about {minutes} minutes left)',
|
|
82
|
+
'二维码暂时无法发送,请直接打开授权链接:\n{url}':
|
|
83
|
+
'The QR code could not be sent. Open the authorization link directly:\n{url}',
|
|
84
|
+
'授权链接已过期;平台未返回成功结果,无法确认已修复。发送 /repair 生成新链接。':
|
|
85
|
+
'The authorization link expired; the platform returned no success, so the repair cannot be confirmed. Send /repair for a new link.',
|
|
86
|
+
'已取消本次修复授权,未确认完成修复。':
|
|
87
|
+
'Repair authorization was cancelled; the repair was not confirmed.',
|
|
88
|
+
'你已取消或拒绝授权,没有确认修复;发送 /repair 可重试。':
|
|
89
|
+
'You cancelled or declined authorization, so the repair was not confirmed. Send /repair to retry.',
|
|
90
|
+
'授权已提交,但未收到测试按钮回调。可能尚未点击或配置仍在传播;稍后发送 /repair verify 查询,不要盲目重复授权。':
|
|
91
|
+
'Authorization was submitted, but no test-button callback arrived. It may not have been tapped yet, or the config is still propagating. Send /repair verify later to check; do not authorize blindly again.',
|
|
92
|
+
'修复流程暂时失败,现有机器人连接不受影响;发送 /repair 可重试。':
|
|
93
|
+
'The repair flow failed for now; the existing bot connection is unaffected. Send /repair to retry.',
|
|
94
|
+
'授权已确认,正在等待专用测试按钮的真实回调;回调到达前不会宣告成功。':
|
|
95
|
+
'Authorization confirmed. Waiting for the real callback from the dedicated test button; success is not declared until it arrives.',
|
|
96
|
+
'授权尚未完成,暂时不能验证卡片按钮。请先打开授权链接并确认。':
|
|
97
|
+
'Authorization is not complete, so the card buttons cannot be verified yet. Open the authorization link and confirm first.',
|
|
98
|
+
'修复任务正在等待授权{remaining}。发送 /repair qr 可获取二维码,/repair cancel 可取消。':
|
|
99
|
+
'The repair task is waiting for authorization{remaining}. Send /repair qr for the QR code, or /repair cancel to cancel.',
|
|
100
|
+
',剩余约 {minutes} 分钟': ', about {minutes} minutes left',
|
|
101
|
+
'这个菜单已过期,请回复 /m 重新打开。': 'This menu has expired. Send /m to reopen it.',
|
|
102
|
+
'菜单没有这个编号,回复 /m 重新打开。': 'This menu has no such number. Send /m to reopen it.',
|
|
103
|
+
'本页只有 {count} 个会话,回复 /sessionlist 重新查看。':
|
|
104
|
+
'This page has only {count} sessions. Send /sessionlist to view them again.',
|
|
105
|
+
'只有 {count} 个工作区,回复 /workspacelist 重新查看。':
|
|
106
|
+
'There are only {count} workspaces. Send /workspacelist to view them again.',
|
|
107
|
+
'关注列表只有 {count} 个会话。': 'The watch list has only {count} sessions.',
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
'已绑定会话「{title}」\nID:{id}': 'Session bound: "{title}"\nID: {id}',
|
|
113
|
+
'绑定失败:{message}': 'Binding failed: {message}',
|
|
114
|
+
|
|
115
|
+
'切换失败:{message}': 'Switch failed: {message}',
|
|
116
|
+
'用法:/watch <Session ID 或当前工作区序号>':
|
|
117
|
+
'Usage: /watch <Session ID or the current workspace index>',
|
|
118
|
+
'当前机器人没有可用的工作区,无法按序号解析会话。':
|
|
119
|
+
'This bot has no available workspace, so sessions cannot be resolved by index.',
|
|
120
|
+
'当前工作区只有 {count} 个会话。': 'The current workspace has only {count} sessions.',
|
|
121
|
+
'没有找到这个会话,请用 /sessionlist 查看可用会话。':
|
|
122
|
+
'Session not found. Use /sessionlist to see the available sessions.',
|
|
123
|
+
'当前状态存储不支持关注。': 'The current state store does not support watching.',
|
|
124
|
+
'无法解析会话:{message}': 'Could not resolve the session: {message}',
|
|
125
|
+
'每个聊天最多关注 {count} 个会话。': 'Each chat can watch at most {count} sessions.',
|
|
126
|
+
'关注列表里没有这个会话,回复 /watchlist 查看。':
|
|
127
|
+
'This session is not in the watch list. Send /watchlist to view it.',
|
|
128
|
+
'已关注会话「{title}」,任务完成会推送结果。':
|
|
129
|
+
'Watching session "{title}"; results are pushed when the task completes.',
|
|
130
|
+
'关注失败:{message}': 'Could not watch: {message}',
|
|
131
|
+
'已取消关注「{title}」。': 'Unwatched "{title}".',
|
|
132
|
+
'取消失败:{message}': 'Could not unwatch: {message}',
|
|
133
|
+
'飞书交互问题发送失败。': 'Failed to send the Feishu interaction question.',
|
|
134
|
+
|
|
135
|
+
// feishu/feishu-cards.mjs — interactive cards
|
|
136
|
+
'🤖 助手菜单': '🤖 Assistant menu',
|
|
137
|
+
'**点击按钮或直接回复数字**': '**Tap a button or reply with a number**',
|
|
138
|
+
'1 · 会话列表': '1 · Sessions',
|
|
139
|
+
'2 · 工作区': '2 · Workspace',
|
|
140
|
+
'3 · 新会话': '3 · New session',
|
|
141
|
+
'4 · 状态': '4 · Status',
|
|
142
|
+
'5 · 帮助': '5 · Help',
|
|
143
|
+
'**6 · 修复卡片按钮**(请直接回复数字 **6**)':
|
|
144
|
+
'**6 · Repair card buttons** (reply with the number **6**)',
|
|
145
|
+
'7 · 关注列表': '7 · Watch list',
|
|
146
|
+
'🧪 验证卡片按钮': '🧪 Verify card buttons',
|
|
147
|
+
'授权已提交。请点击下方按钮;机器人真实收到回调后才会判定修复成功。':
|
|
148
|
+
'Authorization submitted. Tap the button below; the repair is confirmed only after the bot receives the real callback.',
|
|
149
|
+
'完成验证': 'Finish verification',
|
|
150
|
+
'**工作区**:{workspace}\n共 **{total}** 个会话{paging}':
|
|
151
|
+
'**Workspace**: {workspace}\n**{total}** sessions in total{paging}',
|
|
152
|
+
'(第 {page}/{pageCount} 页)': ' (page {page}/{pageCount})',
|
|
153
|
+
'⭐取关': '⭐ Unwatch',
|
|
154
|
+
'⭐关注': '⭐ Watch',
|
|
155
|
+
'◀ 上一页': '◀ Previous',
|
|
156
|
+
'下一页 ▶': 'Next ▶',
|
|
157
|
+
'回复数字(1~N)绑定本页会话。': 'Reply with a number (1–N) to bind a session on this page.',
|
|
158
|
+
'📂 会话列表': '📂 Session list',
|
|
159
|
+
'当前 Host 上没有已登记的工作区。': 'No workspaces are registered on the current Host.',
|
|
160
|
+
'回复数字切换工作区,或点击按钮:': 'Reply with a number to switch workspaces, or tap a button:',
|
|
161
|
+
'🗂 工作区': '🗂 Workspace',
|
|
162
|
+
'🤖 助手菜单(回复数字即可,无需记命令)':
|
|
163
|
+
'🤖 Assistant menu (reply with a number — no need to memorize commands)',
|
|
164
|
+
'1 · /sessionlist 列出会话(回复数字绑定)':
|
|
165
|
+
'1 · /sessionlist List sessions (reply with a number to bind)',
|
|
166
|
+
'2 · /workspacelist 列出工作区(回复数字切换)':
|
|
167
|
+
'2 · /workspacelist List workspaces (reply with a number to switch)',
|
|
168
|
+
'3 · /new 开启新会话': '3 · /new Start a new session',
|
|
169
|
+
'4 · /status 连接状态': '4 · /status Connection status',
|
|
170
|
+
'5 · /help 本帮助': '5 · /help This help',
|
|
171
|
+
'6 · /repair 修复卡片按钮(请回复数字 6)':
|
|
172
|
+
'6 · /repair Repair card buttons (reply with the number 6)',
|
|
173
|
+
'7 · /watchlist 关注列表': '7 · /watchlist Watch list',
|
|
174
|
+
'直接发送文字/图片即继续当前会话。':
|
|
175
|
+
'Send text or an image directly to continue the current session.',
|
|
176
|
+
'/session ID 或序号 绑定已有会话': '/session ID or index Bind an existing session',
|
|
177
|
+
'/watch ID 或序号 关注会话(完成后推送)':
|
|
178
|
+
'/watch ID or index Watch a session (push when done)',
|
|
179
|
+
'/compact 压缩上下文': '/compact Compact the context',
|
|
180
|
+
'/workspace 绝对路径 切换工作区': '/workspace <absolute path> Switch workspace',
|
|
181
|
+
'/presetlist 列出可用 Agent Preset': '/presetlist List available Agent Presets',
|
|
182
|
+
'任务完成会自动推送,回复数字或点按钮取消关注:':
|
|
183
|
+
'Completion is pushed automatically. Reply with a number or tap a button to unwatch:',
|
|
184
|
+
'👁 关注列表': '👁 Watch list',
|
|
185
|
+
'已完成': 'Completed',
|
|
186
|
+
'已停止': 'Stopped',
|
|
187
|
+
'已中止': 'Aborted',
|
|
188
|
+
'已取消': 'Cancelled',
|
|
189
|
+
'已结束': 'Ended',
|
|
190
|
+
'✅ 任务完成': '✅ Task complete',
|
|
191
|
+
'**状态**:{reason}': '**Status**: {reason}',
|
|
192
|
+
'打开会话列表': 'Open session list',
|
|
193
|
+
'工作区': 'Workspace',
|
|
194
|
+
'绑定该会话后可继续追问,输入文字即可。':
|
|
195
|
+
'After binding this session you can keep asking; just type a message.',
|
|
196
|
+
'当前没有关注的会话。\n`/watch <ID|序号>` 关注后,任务完成会自动推送。':
|
|
197
|
+
'No sessions are being watched.\nWatch one with `/watch <ID|index>` and completion is pushed automatically.',
|
|
198
|
+
|
|
199
|
+
// feishu/feishu-channel.mjs
|
|
200
|
+
'正在生成…': 'Generating…',
|
|
201
|
+
'回答完成': 'Answer complete',
|
|
202
|
+
'飞书机器人': 'Feishu bot',
|
|
203
|
+
|
|
204
|
+
// feishu/message-utils.mjs
|
|
205
|
+
'飞书机器人缺少图片读取权限。请在飞书开放平台为该应用添加 im:message:readonly,发布新版本并完成必要的管理员审批后,再重新发送图片。':
|
|
206
|
+
'The Feishu bot is missing image-read permission. Add im:message:readonly to the app in Feishu Open Platform, publish a new version, complete the required admin approval, then resend the image.',
|
|
207
|
+
|
|
208
|
+
// feishu/feishu-runtime.mjs — callback probe notices
|
|
209
|
+
'✅ 修复完成:已实测收到 card.action.trigger,菜单按钮现在可用。':
|
|
210
|
+
'✅ Repair complete: card.action.trigger was received in a real test; the menu buttons now work.',
|
|
211
|
+
'⚠️ 修复验证超时:未收到测试卡按钮的 card.action.trigger,不能确认按钮已修复。请不要重复授权;先检查飞书开放平台的卡片回调配置,确认后再发送 /repair。':
|
|
212
|
+
'⚠️ Repair verification timed out: no card.action.trigger from the test card button was received, so the buttons cannot be confirmed repaired. Do not authorize again; check the card-callback configuration in Feishu Open Platform first, then send /repair.',
|
|
213
|
+
'⚠️ 修复验证失败:无法发送专用测试卡,不能确认 card.action.trigger 已恢复。请不要重复授权;先检查机器人消息权限和连接状态。':
|
|
214
|
+
'⚠️ Repair verification failed: the dedicated test card could not be sent, so card.action.trigger cannot be confirmed restored. Do not authorize again; check the bot message permission and connection status first.',
|
|
215
|
+
'⚠️ 修复验证中断:Runtime 已停止,未完成 card.action.trigger 实测,不能确认修复成功。请不要重复授权;先等待机器人恢复连接。':
|
|
216
|
+
'⚠️ Repair verification interrupted: the Runtime stopped before the card.action.trigger test completed, so the repair cannot be confirmed. Do not authorize again; wait for the bot to reconnect.',
|
|
217
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// English translations (office area). Keys are exact Chinese literals passed to t().
|
|
2
|
+
export default {
|
|
3
|
+
'AI Office 拒绝了 Device Token。': 'AI Office rejected the Device Token.',
|
|
4
|
+
'AI Office Connector Hook 尚未就绪。': 'The AI Office Connector Hook is not ready yet.',
|
|
5
|
+
'AI Office Connector 协议版本不兼容。': 'The AI Office Connector protocol version is incompatible.',
|
|
6
|
+
'本机暂时无法访问 AI Office。': 'This machine cannot reach AI Office right now.',
|
|
7
|
+
'AI Office 连接已中断。': 'The AI Office connection was interrupted.',
|
|
8
|
+
'本机 Harness 已停止这次执行。': 'The local Harness stopped this run.',
|
|
9
|
+
'Office Job 已被领取、取消或结束。': 'The Office Job has already been claimed, cancelled, or finished.',
|
|
10
|
+
'本机 Harness 未能完成任务;请检查 Harness 会话后重试。': 'The local Harness could not complete the task; check the Harness Session and try again.',
|
|
11
|
+
'Office Job 引用了本机未配置的 Workspace/Preset alias。': 'The Office Job references a Workspace/Preset alias that is not configured locally.',
|
|
12
|
+
'你正在本机 DeepSeek Harness 中继续一个来自 AI Office 的任务。': 'You are continuing an AI Office task inside the local DeepSeek Harness.',
|
|
13
|
+
'只在当前 Workspace 内行动。完成后必须返回:结果摘要、改动文件、验证证据、未解决风险。': 'Act only within the current Workspace. When finished you must return: a result summary, changed files, verification evidence, and unresolved risks.',
|
|
14
|
+
'## 本机 Instruction Preset': '## Local Instruction Preset',
|
|
15
|
+
'## 本轮补充指令': '## Additional Instructions for This Round',
|
|
16
|
+
'## Office 时间线': '## Office Timeline',
|
|
17
|
+
'批准 {tool}': 'Approve {tool}',
|
|
18
|
+
'Harness 工具': 'Harness tool',
|
|
19
|
+
'Harness 需要 {count} 项补充信息': 'Harness needs {count} pieces of additional information',
|
|
20
|
+
'已领取 Job,准备 Workspace alias:{alias}': 'Job claimed; preparing Workspace alias: {alias}',
|
|
21
|
+
'Harness Session 已创建。': 'Harness Session created.',
|
|
22
|
+
'正在使用 {tool}…': 'Using {tool}…',
|
|
23
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// English translations (qq area). Keys are exact Chinese literals passed to t().
|
|
2
|
+
export default {
|
|
3
|
+
|
|
4
|
+
'QQ 机器人已连接 DeepSeek Harness。':
|
|
5
|
+
'The QQ bot is connected to DeepSeek Harness.',
|
|
6
|
+
'回答较长,后续内容未能通过 QQ 完整发送,请回复“继续”。':
|
|
7
|
+
'The answer is long and the rest could not be sent fully through QQ. Reply “继续” (continue) to receive it.',
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
'结果文件「{name}」已生成,但 QQ 今日文件上传额度已用完,请稍后重试。':
|
|
13
|
+
'The result file "{name}" was generated, but QQ\'s daily file upload quota is used up. Please try again later.',
|
|
14
|
+
|
|
15
|
+
'结果文件「{name}」已生成,但当前 QQ 机器人没有文件消息权限。':
|
|
16
|
+
'The result file "{name}" was generated, but the current QQ bot does not have file message permission.',
|
|
17
|
+
'结果文件「{name}」超过当前 QQ 机器人可发送的文件大小,未发送。':
|
|
18
|
+
'The result file "{name}" exceeds the file size the current QQ bot can send and was not sent.',
|
|
19
|
+
'结果文件「{name}」为空,QQ 不允许发送空文件。':
|
|
20
|
+
'The result file "{name}" is empty, and QQ does not allow sending empty files.',
|
|
21
|
+
|
|
22
|
+
'结果文件「{name}」暂时被 QQ 限流,未能发送,请稍后重试。':
|
|
23
|
+
'The result file "{name}" was temporarily rate-limited by QQ and was not sent. Please try again later.',
|
|
24
|
+
'结果文件「{name}」已生成,但 QQ 拒绝了该文件或文件消息。':
|
|
25
|
+
'The result file "{name}" was generated, but QQ rejected the file or file message.',
|
|
26
|
+
'结果文件「{name}」已生成,但暂时未能通过 QQ 发送,请稍后重试。':
|
|
27
|
+
'The result file "{name}" was generated but could not be sent via QQ right now. Please try again later.',
|
|
28
|
+
'QQ 机器人与 DeepSeek Harness 连接正常。':
|
|
29
|
+
'The QQ bot is connected to DeepSeek Harness normally.',
|
|
30
|
+
'QQ 交互问题发送失败。': 'Failed to send the QQ interaction question.',
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
'QQ 机器人凭据缺失,请移除后重新扫码。':
|
|
34
|
+
'The QQ bot credentials are missing. Remove the bot and scan the QR code again.',
|
|
35
|
+
'QQ 连接未就绪,插件会自动重试。':
|
|
36
|
+
'The QQ connection is not ready; the plugin will retry automatically.',
|
|
37
|
+
'QQ 扫码服务暂时不可用,请重新生成二维码。':
|
|
38
|
+
'The QQ QR service is temporarily unavailable. Please generate a new QR code.',
|
|
39
|
+
'无法生成 QQ 二维码,请稍后重试。':
|
|
40
|
+
'Unable to generate the QQ QR code. Please try again later.',
|
|
41
|
+
'QQ 机器人已绑定,消息连接暂未就绪。':
|
|
42
|
+
'The QQ bot is bound, but the message connection is not ready yet.',
|
|
43
|
+
'QQ 连接仍未就绪,请稍后重试。':
|
|
44
|
+
'The QQ connection is still not ready. Please try again later.',
|
|
45
|
+
QQ机器人尚未连接: 'The QQ bot is not connected yet',
|
|
46
|
+
'QQ 机器人({appId})': 'QQ bot ({appId})',
|
|
47
|
+
QQ机器人: 'QQ bot',
|
|
48
|
+
'QQ WebSocket 长连接运行正常': 'The QQ WebSocket long connection is running normally',
|
|
49
|
+
'QQ 连接未就绪,插件会自动重试':
|
|
50
|
+
'The QQ connection is not ready; the plugin will retry automatically',
|
|
51
|
+
'QQ 连接当前离线': 'The QQ connection is currently offline',
|
|
52
|
+
'QQ 已授权,但无法安全保存接入配置。':
|
|
53
|
+
'QQ authorization succeeded, but the connection configuration could not be saved safely.',
|
|
54
|
+
};
|