@xmanrui/dsh-im 4.23.0 → 4.24.1
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 +7 -2
- package/README.md +7 -2
- package/lib/client.js +498 -347
- package/lib/index.js +284 -283
- package/package.json +11 -2
- package/plugin-src/client/channel-card-meta.js +3 -9
- package/plugin-src/client/channels/dingtalk/index.js +9 -8
- package/plugin-src/client/channels/feishu/index.js +21 -17
- package/plugin-src/client/channels/qq/index.js +9 -8
- package/plugin-src/client/channels/shared/collapsible-account.js +49 -26
- package/plugin-src/client/channels/shared/token-api.js +3 -0
- package/plugin-src/client/channels/shared/token-channel.js +9 -8
- package/plugin-src/client/channels/telegram/index.js +3 -0
- package/plugin-src/client/channels/telegram/styles.js +12 -0
- package/plugin-src/client/channels/telegram/thinking-traces.js +25 -0
- package/plugin-src/client/channels/wecom/index.js +9 -8
- package/plugin-src/client/channels/wecom-app/index.js +9 -8
- package/plugin-src/client/channels/weixin/index.js +9 -8
- package/plugin-src/client/channels/whatsapp/index.js +9 -8
- package/plugin-src/client/i18n.js +13 -1
- package/plugin-src/client/index.js +10 -2
- package/plugin-src/client/styles.js +12 -8
- package/plugin-src/client/update-panel.js +18 -8
- package/plugin-src/host/channels/shared/rpc.mjs +9 -0
- package/plugin-src/host/channels/shared/thinking-traces-rpc.mjs +11 -0
- package/plugin-src/host/modern-harness-api.mjs +7 -2
- package/plugin-src/host/update-service.mjs +19 -14
- package/scripts/verify-package.mjs +11 -5
- package/src/channels/email/email-runtime.mjs +9 -2
- package/src/channels/email/transports/agent-mail.mjs +14 -3
- package/src/channels/feishu/bridge.mjs +122 -46
- package/src/channels/feishu/feishu-channel.mjs +35 -0
- package/src/channels/feishu/live-cot.mjs +260 -0
- package/src/channels/feishu/slash-command-registry.mjs +17 -0
- package/src/channels/feishu/step-push-mode.mjs +10 -4
- package/src/channels/shared/harness-client.mjs +224 -39
- package/src/channels/shared/text-harness-bridge.mjs +60 -14
- package/src/channels/shared/workspace-session.mjs +7 -1
- package/src/channels/telegram/config-store.mjs +4 -1
- package/src/channels/telegram/telegram-controller.mjs +13 -1
- package/src/channels/telegram/telegram-runtime.mjs +198 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xmanrui/dsh-im",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.24.1",
|
|
4
4
|
"description": "把十一种 IM 渠道和公网 AI Office 接入本机 DeepSeek Harness。 Connect eleven IM channels and a public AI Office to a local DeepSeek Harness.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -80,6 +80,10 @@
|
|
|
80
80
|
{
|
|
81
81
|
"name": "wings1848",
|
|
82
82
|
"url": "https://github.com/wings1848"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "Zhe (Phil) Yang",
|
|
86
|
+
"url": "https://github.com/yangzhe1991"
|
|
83
87
|
}
|
|
84
88
|
],
|
|
85
89
|
"license": "MIT",
|
|
@@ -110,7 +114,12 @@
|
|
|
110
114
|
"cordis.patch.yml",
|
|
111
115
|
"lib",
|
|
112
116
|
"plugin-src",
|
|
113
|
-
"scripts",
|
|
117
|
+
"scripts/verify-interface-language.mjs",
|
|
118
|
+
"scripts/verify-lan-management.mjs",
|
|
119
|
+
"scripts/verify-model-setting.mjs",
|
|
120
|
+
"scripts/verify-package.mjs",
|
|
121
|
+
"scripts/verify-session-channel-logos.mjs",
|
|
122
|
+
"scripts/verify-session-title-prefix.mjs",
|
|
114
123
|
"src",
|
|
115
124
|
"PROACTIVE_DELIVERY.md",
|
|
116
125
|
"PROACTIVE_DELIVERY.en.md",
|
|
@@ -7,7 +7,7 @@ export const BotSettingsContext = React.createContext(Object.freeze({
|
|
|
7
7
|
openBotSettings() {},
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
|
-
function SettingsGlyph() {
|
|
10
|
+
export function SettingsGlyph() {
|
|
11
11
|
return h('svg', {
|
|
12
12
|
viewBox: '0 0 24 24',
|
|
13
13
|
width: 16,
|
|
@@ -32,14 +32,12 @@ export function BotSettingsButton({
|
|
|
32
32
|
channelSettings,
|
|
33
33
|
}) {
|
|
34
34
|
const { openBotSettings } = React.useContext(BotSettingsContext);
|
|
35
|
-
const tooltipId = React.useId();
|
|
36
35
|
return h('span', { className: 'dim-botSettingsAction' },
|
|
37
36
|
h('button', {
|
|
38
37
|
type: 'button',
|
|
39
38
|
className: 'dim-botSettingsButton',
|
|
40
39
|
'data-delivery-channel': channel,
|
|
41
40
|
'aria-label': '更多机器人设置',
|
|
42
|
-
'aria-describedby': tooltipId,
|
|
43
41
|
onClick: () => openBotSettings?.({
|
|
44
42
|
...(channelSettings && typeof channelSettings === 'object' ? channelSettings : {}),
|
|
45
43
|
channel,
|
|
@@ -48,12 +46,8 @@ export function BotSettingsButton({
|
|
|
48
46
|
connected: Boolean(connected),
|
|
49
47
|
accessPolicy,
|
|
50
48
|
}),
|
|
51
|
-
}, h(SettingsGlyph)),
|
|
52
|
-
h('span', {
|
|
53
|
-
id: tooltipId,
|
|
54
|
-
className: 'dim-botSettingsTooltip',
|
|
55
|
-
role: 'tooltip',
|
|
56
|
-
}, '更多机器人设置'));
|
|
49
|
+
}, h(SettingsGlyph), h('span', null, '更多设置'),
|
|
50
|
+
h('span', { className: 'dim-moreSettingsChevron', 'aria-hidden': 'true' })));
|
|
57
51
|
}
|
|
58
52
|
|
|
59
53
|
function messageErrorTime(value) {
|
|
@@ -3,7 +3,7 @@ import { BotName } from '../../bot-alias.js';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
|
|
5
5
|
import { CredentialActionIcon, CredentialBindingPanel, QrActionIcon } from '../../credential-binding.js';
|
|
6
|
-
import { CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
6
|
+
import { AccountSettingsToggle, CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
7
7
|
import { h } from '../../i18n.js';
|
|
8
8
|
import { WorkspaceEditor } from '../../workspace-editor.js';
|
|
9
9
|
import { ContextEnhancementEditor } from '../../context-enhancement.js';
|
|
@@ -251,6 +251,13 @@ export function AccountCard({
|
|
|
251
251
|
return h('article', { className: 'ddt-card dim-botCard', tabIndex: -1, 'data-bot-id': account.botId },
|
|
252
252
|
h('div', { className: 'ddt-cardBody dim-botCardBody' },
|
|
253
253
|
h(CollapsibleAccountSection, {
|
|
254
|
+
settings: h(BotSettingsButton, {
|
|
255
|
+
channel: 'dingtalk',
|
|
256
|
+
botId: account.botId,
|
|
257
|
+
botName: account.bot.name,
|
|
258
|
+
connected: account.connected,
|
|
259
|
+
accessPolicy: account.accessPolicy,
|
|
260
|
+
}),
|
|
254
261
|
id: `ddt-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, '-')}`,
|
|
255
262
|
header: h('div', { className: 'ddt-accountTop dim-botCardTop' },
|
|
256
263
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
@@ -272,13 +279,7 @@ export function AccountCard({
|
|
|
272
279
|
lastCheckedAt: account.health.lastCheckedAt,
|
|
273
280
|
formatCheckedTime: checkedTime,
|
|
274
281
|
}),
|
|
275
|
-
h(
|
|
276
|
-
channel: 'dingtalk',
|
|
277
|
-
botId: account.botId,
|
|
278
|
-
botName: account.bot.name,
|
|
279
|
-
connected: account.connected,
|
|
280
|
-
accessPolicy: account.accessPolicy,
|
|
281
|
-
})))
|
|
282
|
+
h(AccountSettingsToggle)))
|
|
282
283
|
},
|
|
283
284
|
h(WorkspaceEditor, {
|
|
284
285
|
workspace: account.workspace,
|
|
@@ -4,7 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
|
|
5
5
|
import { FeishuLogoGlyph } from "../../channel-logos.js";
|
|
6
6
|
import { CredentialActionIcon, CredentialBindingPanel, QrActionIcon } from "../../credential-binding.js";
|
|
7
|
-
import { CollapsibleAccountSection } from "../shared/collapsible-account.js";
|
|
7
|
+
import { AccountSettingsToggle, CollapsibleAccountSection } from "../shared/collapsible-account.js";
|
|
8
8
|
import { h } from "../../i18n.js";
|
|
9
9
|
import {
|
|
10
10
|
FEISHU_ENDPOINTS,
|
|
@@ -466,7 +466,7 @@ function RemoveConfirmation({ bot, busy, onConfirm, onCancel }) {
|
|
|
466
466
|
);
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
-
/** One select for the step-push presentation
|
|
469
|
+
/** One select for the step-push presentation. */
|
|
470
470
|
function StepPushEditor({ value = false, mode = "post", disabled = false, onSave, onModeSave }) {
|
|
471
471
|
const titleId = React.useId();
|
|
472
472
|
const helpId = `${titleId}-help`;
|
|
@@ -496,7 +496,7 @@ function StepPushEditor({ value = false, mode = "post", disabled = false, onSave
|
|
|
496
496
|
if (value === true) await onSave?.(false);
|
|
497
497
|
return;
|
|
498
498
|
}
|
|
499
|
-
const nextMode =
|
|
499
|
+
const nextMode = ["streaming_card", "live_cot"].includes(next) ? next : "post";
|
|
500
500
|
// Enabling (or switching presentation) may need both writes; the flag
|
|
501
501
|
// must land before the mode so the runtime never sees a mode without
|
|
502
502
|
// step push enabled.
|
|
@@ -507,7 +507,9 @@ function StepPushEditor({ value = false, mode = "post", disabled = false, onSave
|
|
|
507
507
|
|
|
508
508
|
const helpText = current === "off"
|
|
509
509
|
? "适合日常问答:执行过程中不显示工具调用等中间步骤,只回复最终结果"
|
|
510
|
-
: current === "
|
|
510
|
+
: current === "live_cot"
|
|
511
|
+
? "使用飞书原生思考过程展示推理、工具调用与结果,最终答案单独发送"
|
|
512
|
+
: current === "streaming_card"
|
|
511
513
|
? "推荐长任务使用:过程与最终答案都在同一张卡片里实时更新,不刷屏"
|
|
512
514
|
: "每一步都单独发一条消息(含工具调用和过程说明);注意长任务会连续发送较多消息";
|
|
513
515
|
|
|
@@ -529,7 +531,7 @@ function StepPushEditor({ value = false, mode = "post", disabled = false, onSave
|
|
|
529
531
|
id: helpId,
|
|
530
532
|
className: "dim-presetTooltip",
|
|
531
533
|
role: "tooltip",
|
|
532
|
-
}, "
|
|
534
|
+
}, "设置任务执行过程的呈现方式:不显示、原生直播、实时卡片或逐步消息"))),
|
|
533
535
|
saving
|
|
534
536
|
? h("span", { className: "dim-feishuGroupControlStatus", role: "status" }, "保存中…")
|
|
535
537
|
: null),
|
|
@@ -541,6 +543,7 @@ function StepPushEditor({ value = false, mode = "post", disabled = false, onSave
|
|
|
541
543
|
onChange: change,
|
|
542
544
|
},
|
|
543
545
|
h("option", { value: "off" }, "不显示过程(只发送最终答案)"),
|
|
546
|
+
h("option", { value: "live_cot" }, "实时直播(飞书原生思考过程)"),
|
|
544
547
|
h("option", { value: "streaming_card" }, "实时过程卡(全程一张卡片动态更新)"),
|
|
545
548
|
h("option", { value: "post" }, "逐步直播(每一步单独发一条消息)")),
|
|
546
549
|
h("p", { className: "dim-feishuGroupHelp" }, helpText),
|
|
@@ -597,6 +600,18 @@ export function BotCard({
|
|
|
597
600
|
},
|
|
598
601
|
h("div", { className: "bxf-cardBody dim-botCardBody" },
|
|
599
602
|
h(CollapsibleAccountSection, {
|
|
603
|
+
settings: h(BotSettingsButton, {
|
|
604
|
+
channel: "feishu",
|
|
605
|
+
botId: connection.botId,
|
|
606
|
+
botName: bot.name,
|
|
607
|
+
connected,
|
|
608
|
+
accessPolicy: connection.accessPolicy,
|
|
609
|
+
channelSettings: {
|
|
610
|
+
groupResponseMode: connection.groupResponseMode,
|
|
611
|
+
groupTopicReply: connection.groupTopicReply,
|
|
612
|
+
groupMessagePermissionGranted: connection.groupMessagePermissionGranted,
|
|
613
|
+
},
|
|
614
|
+
}),
|
|
600
615
|
id: `bxf-settings-${connection.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`,
|
|
601
616
|
header: h("div", { className: "bxf-connectedTop dim-botCardTop" },
|
|
602
617
|
h("div", { className: "bxf-botIdentity dim-botIdentity" },
|
|
@@ -621,18 +636,7 @@ export function BotCard({
|
|
|
621
636
|
formatCheckedTime,
|
|
622
637
|
healthState: stateForDisplay,
|
|
623
638
|
}),
|
|
624
|
-
h(
|
|
625
|
-
channel: "feishu",
|
|
626
|
-
botId: connection.botId,
|
|
627
|
-
botName: bot.name,
|
|
628
|
-
connected,
|
|
629
|
-
accessPolicy: connection.accessPolicy,
|
|
630
|
-
channelSettings: {
|
|
631
|
-
groupResponseMode: connection.groupResponseMode,
|
|
632
|
-
groupTopicReply: connection.groupTopicReply,
|
|
633
|
-
groupMessagePermissionGranted: connection.groupMessagePermissionGranted,
|
|
634
|
-
},
|
|
635
|
-
}))),
|
|
639
|
+
h(AccountSettingsToggle))),
|
|
636
640
|
},
|
|
637
641
|
h(WorkspaceEditor, {
|
|
638
642
|
workspace: connection.workspace,
|
|
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
|
|
5
5
|
import { QqLogoGlyph } from '../../channel-logos.js';
|
|
6
6
|
import { CredentialActionIcon, CredentialBindingPanel, QrActionIcon } from '../../credential-binding.js';
|
|
7
|
-
import { CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
7
|
+
import { AccountSettingsToggle, CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
8
8
|
import { h } from '../../i18n.js';
|
|
9
9
|
import { WorkspaceEditor } from '../../workspace-editor.js';
|
|
10
10
|
import { ContextEnhancementEditor } from '../../context-enhancement.js';
|
|
@@ -189,6 +189,13 @@ export function AccountCard({
|
|
|
189
189
|
return h('article', { className: 'ddt-card dim-botCard', 'data-bot-id': account.botId },
|
|
190
190
|
h('div', { className: 'ddt-cardBody dim-botCardBody' },
|
|
191
191
|
h(CollapsibleAccountSection, {
|
|
192
|
+
settings: h(BotSettingsButton, {
|
|
193
|
+
channel: 'qq',
|
|
194
|
+
botId: account.botId,
|
|
195
|
+
botName: account.bot.name,
|
|
196
|
+
connected: account.connected,
|
|
197
|
+
accessPolicy: account.accessPolicy,
|
|
198
|
+
}),
|
|
192
199
|
id: `qq-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, '-')}`,
|
|
193
200
|
header: h('div', { className: 'ddt-accountTop dim-botCardTop' },
|
|
194
201
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
@@ -209,13 +216,7 @@ export function AccountCard({
|
|
|
209
216
|
lastCheckedAt: account.health.lastCheckedAt,
|
|
210
217
|
formatCheckedTime: checkedTime,
|
|
211
218
|
}),
|
|
212
|
-
h(
|
|
213
|
-
channel: 'qq',
|
|
214
|
-
botId: account.botId,
|
|
215
|
-
botName: account.bot.name,
|
|
216
|
-
connected: account.connected,
|
|
217
|
-
accessPolicy: account.accessPolicy,
|
|
218
|
-
})))
|
|
219
|
+
h(AccountSettingsToggle)))
|
|
219
220
|
},
|
|
220
221
|
h(WorkspaceEditor, {
|
|
221
222
|
workspace: account.workspace,
|
|
@@ -3,32 +3,64 @@
|
|
|
3
3
|
*
|
|
4
4
|
* When several accounts are connected, each account's workspace / preset /
|
|
5
5
|
* context-enhancement editors make the list extremely long. This component
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* keeps one settings toggle in the existing header tools slot. Clicking the
|
|
7
|
+
* header also expands the settings details; more settings live in the body.
|
|
8
8
|
*
|
|
9
9
|
* Design notes:
|
|
10
|
-
* - The
|
|
11
|
-
*
|
|
12
|
-
* - A chevron sits at the end of the header line as the affordance.
|
|
10
|
+
* - The native toggle owns keyboard interaction. Header controls stop click
|
|
11
|
+
* propagation so editing a name cannot accidentally toggle the card.
|
|
13
12
|
* - Height animation uses grid-template-rows: 0fr -> 1fr (pure CSS).
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
13
|
+
* - The toggle exposes aria-expanded / aria-controls; the body keeps native
|
|
14
|
+
* semantics and hides collapsed controls from focus and accessibility.
|
|
16
15
|
* - Honors prefers-reduced-motion.
|
|
17
16
|
* - Styles are managed by the IM settings plugin, not individual accounts.
|
|
18
17
|
*/
|
|
19
18
|
import * as React from 'react';
|
|
20
19
|
import { h } from '../../i18n.js';
|
|
20
|
+
import { SettingsGlyph } from '../../channel-card-meta.js';
|
|
21
|
+
|
|
22
|
+
const AccountSectionContext = React.createContext(null);
|
|
23
|
+
|
|
24
|
+
/** Renders in the original settings-button slot, beside the status metadata. */
|
|
25
|
+
export function AccountSettingsToggle() {
|
|
26
|
+
const { open, toggle, contentId } = React.useContext(AccountSectionContext);
|
|
27
|
+
return h('button', {
|
|
28
|
+
type: 'button',
|
|
29
|
+
className: 'dim-accountSettingsToggle',
|
|
30
|
+
'aria-label': open ? '收起该账号的设置' : '展开该账号的设置',
|
|
31
|
+
'aria-expanded': open ? 'true' : 'false',
|
|
32
|
+
'aria-controls': contentId,
|
|
33
|
+
onClick: (event) => {
|
|
34
|
+
event.stopPropagation();
|
|
35
|
+
toggle();
|
|
36
|
+
},
|
|
37
|
+
}, h(SettingsGlyph),
|
|
38
|
+
h('svg', {
|
|
39
|
+
className: 'dim-collapsibleChevron',
|
|
40
|
+
viewBox: '0 0 12 16',
|
|
41
|
+
width: 12,
|
|
42
|
+
height: 16,
|
|
43
|
+
fill: 'none',
|
|
44
|
+
stroke: 'currentColor',
|
|
45
|
+
strokeWidth: 1.8,
|
|
46
|
+
strokeLinecap: 'round',
|
|
47
|
+
strokeLinejoin: 'round',
|
|
48
|
+
'aria-hidden': 'true',
|
|
49
|
+
}, h('path', { d: 'M2 6 6 10 10 6' })));
|
|
50
|
+
}
|
|
21
51
|
|
|
22
52
|
/**
|
|
23
53
|
* Collapsible account card.
|
|
24
54
|
*
|
|
25
55
|
* `header` renders the always-visible header line; clicking it toggles.
|
|
26
56
|
* Any interactive control inside the header should stop the click event so it
|
|
27
|
-
* does not toggle the section (e.g. the
|
|
57
|
+
* does not toggle the section (e.g. the alias editor).
|
|
58
|
+
* `settings` is the original more-settings action, shown above the editors.
|
|
28
59
|
* `children` is the collapsed details region.
|
|
29
60
|
*/
|
|
30
61
|
export function CollapsibleAccountSection({
|
|
31
62
|
header,
|
|
63
|
+
settings,
|
|
32
64
|
defaultOpen = false,
|
|
33
65
|
open: controlledOpen,
|
|
34
66
|
onToggle,
|
|
@@ -37,44 +69,35 @@ export function CollapsibleAccountSection({
|
|
|
37
69
|
children,
|
|
38
70
|
}) {
|
|
39
71
|
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
|
|
72
|
+
const generatedId = React.useId();
|
|
40
73
|
const open = controlledOpen ?? uncontrolledOpen;
|
|
41
|
-
const contentId = id
|
|
74
|
+
const contentId = `${id ?? generatedId}-content`;
|
|
42
75
|
|
|
43
76
|
const toggle = () => {
|
|
44
77
|
if (controlledOpen === undefined) setUncontrolledOpen((value) => !value);
|
|
45
78
|
onToggle?.(!open);
|
|
46
79
|
};
|
|
47
80
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
event.preventDefault();
|
|
51
|
-
toggle();
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return h('div', {
|
|
81
|
+
return h(AccountSectionContext.Provider, { value: { open, toggle, contentId } },
|
|
82
|
+
h('div', {
|
|
56
83
|
className: `dim-collapsibleAccount ${open ? 'is-open' : ''} ${className}`.trim(),
|
|
57
84
|
'data-open': open ? 'true' : 'false',
|
|
58
85
|
},
|
|
59
86
|
h('div', {
|
|
60
87
|
className: 'dim-collapsibleHead',
|
|
61
|
-
role: 'button',
|
|
62
|
-
tabIndex: 0,
|
|
63
88
|
onClick: toggle,
|
|
64
|
-
onKeyDown,
|
|
65
|
-
'aria-expanded': open ? 'true' : 'false',
|
|
66
|
-
'aria-controls': contentId,
|
|
67
|
-
'aria-label': open ? '收起该账号的设置' : '展开该账号的设置',
|
|
68
89
|
},
|
|
69
90
|
h('div', { className: 'dim-collapsibleHeaderContent' }, header),
|
|
70
|
-
h('span', { className: 'dim-collapsibleChevron', 'aria-hidden': 'true' }),
|
|
71
91
|
),
|
|
72
92
|
h('div', {
|
|
73
93
|
id: contentId,
|
|
74
94
|
className: 'dim-collapsibleBody',
|
|
75
95
|
role: 'region',
|
|
76
96
|
},
|
|
77
|
-
h('div', { className: 'dim-collapsibleBodyInner' },
|
|
97
|
+
h('div', { className: 'dim-collapsibleBodyInner' },
|
|
98
|
+
settings ? h('div', { className: 'dim-accountSettingsHeader' },
|
|
99
|
+
h('span', null, '常用配置'), settings) : null,
|
|
100
|
+
children),
|
|
78
101
|
),
|
|
79
|
-
);
|
|
102
|
+
));
|
|
80
103
|
}
|
|
@@ -38,6 +38,7 @@ export const TOKEN_BOT_ENDPOINTS = Object.freeze({
|
|
|
38
38
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
39
39
|
setAccessPolicy: 'bot.access-policy.set',
|
|
40
40
|
setAlias: 'bot.alias.set',
|
|
41
|
+
setThinkingTraces: 'bot.thinking-traces.set',
|
|
41
42
|
});
|
|
42
43
|
|
|
43
44
|
export function createTokenChannelApi(channel, connectionSummary, {
|
|
@@ -69,6 +70,8 @@ export function createTokenChannelApi(channel, connectionSummary, {
|
|
|
69
70
|
model: normalizeModelSelection(value.model),
|
|
70
71
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
71
72
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
73
|
+
// Absent from the backend means ON; only an explicit false opts out.
|
|
74
|
+
thinkingTraces: value.thinkingTraces !== false,
|
|
72
75
|
...(Object.hasOwn(value, 'accessPolicy')
|
|
73
76
|
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
74
77
|
: {}),
|
|
@@ -3,7 +3,7 @@ import { BotName } from '../../bot-alias.js';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
|
|
5
5
|
import { CredentialActionIcon, CredentialBindingPanel } from '../../credential-binding.js';
|
|
6
|
-
import { CollapsibleAccountSection } from './collapsible-account.js';
|
|
6
|
+
import { AccountSettingsToggle, CollapsibleAccountSection } from './collapsible-account.js';
|
|
7
7
|
import { h } from '../../i18n.js';
|
|
8
8
|
import { installDingtalkStyles } from '../dingtalk/styles.js';
|
|
9
9
|
import { WorkspaceEditor } from '../../workspace-editor.js';
|
|
@@ -92,6 +92,13 @@ export function createTokenChannelSettings(definition) {
|
|
|
92
92
|
return h('article', { className: 'ddt-card dim-botCard', 'data-bot-id': account.botId },
|
|
93
93
|
h('div', { className: 'ddt-cardBody dim-botCardBody' },
|
|
94
94
|
h(CollapsibleAccountSection, {
|
|
95
|
+
settings: h(BotSettingsButton, {
|
|
96
|
+
channel: channel.toLowerCase(),
|
|
97
|
+
botId: account.botId,
|
|
98
|
+
botName: account.bot.name,
|
|
99
|
+
connected: account.connected,
|
|
100
|
+
accessPolicy: account.accessPolicy,
|
|
101
|
+
}),
|
|
95
102
|
id: `tok-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, '-')}`,
|
|
96
103
|
header: h('div', { className: 'ddt-accountTop dim-botCardTop' },
|
|
97
104
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
@@ -113,13 +120,7 @@ export function createTokenChannelSettings(definition) {
|
|
|
113
120
|
lastCheckedAt: account.health.lastCheckedAt,
|
|
114
121
|
formatCheckedTime: checkedTime,
|
|
115
122
|
}),
|
|
116
|
-
h(
|
|
117
|
-
channel: channel.toLowerCase(),
|
|
118
|
-
botId: account.botId,
|
|
119
|
-
botName: account.bot.name,
|
|
120
|
-
connected: account.connected,
|
|
121
|
-
accessPolicy: account.accessPolicy,
|
|
122
|
-
}))),
|
|
123
|
+
h(AccountSettingsToggle))),
|
|
123
124
|
},
|
|
124
125
|
h(WorkspaceEditor, {
|
|
125
126
|
workspace: account.workspace,
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
TELEGRAM_ENDPOINTS,
|
|
5
5
|
telegramClientApi,
|
|
6
6
|
} from './api.js';
|
|
7
|
+
import { ThinkingTracesSettings } from './thinking-traces.js';
|
|
7
8
|
import { installTelegramStyles } from './styles.js';
|
|
8
9
|
|
|
9
10
|
const channel = createTokenChannelSettings({
|
|
@@ -19,6 +20,8 @@ const channel = createTokenChannelSettings({
|
|
|
19
20
|
emptyTitle: '接入 Telegram 机器人',
|
|
20
21
|
emptyDescription: '先通过 @BotFather 获取 Bot Token,再在这里完成接入。',
|
|
21
22
|
platformLabel: 'Telegram',
|
|
23
|
+
AccountSettings: ThinkingTracesSettings,
|
|
24
|
+
accountSettingsEndpoint: 'bot.thinking-traces.set',
|
|
22
25
|
});
|
|
23
26
|
|
|
24
27
|
export const TelegramSettingsTab = channel.SettingsTab;
|
|
@@ -4,6 +4,18 @@ const CSS = String.raw`
|
|
|
4
4
|
.dtg-page { --ddt-accent: #229ed9; --ddt-accent-deep: #1687bd; --ddt-accent-wash: #eaf7fd; }
|
|
5
5
|
.dtg-avatar { color: #fff; background: #229ed9; }
|
|
6
6
|
.dtg-avatar svg { display: block; }
|
|
7
|
+
.dim-accountSettings { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--dsw-alias-border-l2, #eceef1); }
|
|
8
|
+
.dim-accountSettingsTitle { margin: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-secondary, #646a73); letter-spacing: 0.02em; }
|
|
9
|
+
.dim-accountSettingsRow { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 40px; cursor: pointer; }
|
|
10
|
+
.dim-accountSettingsText { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
|
11
|
+
.dim-accountSettingsLabel { font-size: 13px; font-weight: 500; color: var(--dsw-alias-label, #1f2329); }
|
|
12
|
+
.dim-accountSettingsHelp { font-size: 12px; color: var(--dsw-alias-label-tertiary, #8a919f); }
|
|
13
|
+
.dim-accountSettingsSwitch { appearance: none; flex: none; width: 32px; height: 19px; margin: 0; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 12px; background: var(--dsw-alias-interactive-bg-hover, #eef0f3); cursor: pointer; position: relative; }
|
|
14
|
+
.dim-accountSettingsSwitch::before { content: ""; position: absolute; top: 2px; left: 2px; width: 13px; height: 13px; border-radius: 50%; background: var(--dsw-alias-label-secondary, #646a73); transition: transform 120ms ease, background 120ms ease; }
|
|
15
|
+
.dim-accountSettingsSwitch:checked { border-color: #229ed9; background: #229ed9; }
|
|
16
|
+
.dim-accountSettingsSwitch:checked::before { transform: translateX(13px); background: #fff; }
|
|
17
|
+
.dim-accountSettingsSwitch:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
18
|
+
@media (prefers-reduced-motion: reduce) { .dim-accountSettingsSwitch::before { transition: none; } }
|
|
7
19
|
`;
|
|
8
20
|
|
|
9
21
|
export function installTelegramStyles() {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话行为设置块:思考过程留痕开关(Telegram 专属)。
|
|
3
|
+
*
|
|
4
|
+
* 开启后,机器人把 agent 的推理与工具调用作为独立的 💭/🔧 消息实时发出来,
|
|
5
|
+
* 最终答案单独成条;关闭则回到「占位符被最终答案覆盖」的原有单消息行为。
|
|
6
|
+
*/
|
|
7
|
+
import { h } from '../../i18n.js';
|
|
8
|
+
|
|
9
|
+
export function ThinkingTracesSettings({ account, busy, onSave }) {
|
|
10
|
+
const checked = account.thinkingTraces !== false;
|
|
11
|
+
return h('div', { className: 'dim-accountSettings' },
|
|
12
|
+
h('h4', { className: 'dim-accountSettingsTitle' }, '会话行为'),
|
|
13
|
+
h('label', { className: 'dim-accountSettingsRow' },
|
|
14
|
+
h('span', { className: 'dim-accountSettingsText' },
|
|
15
|
+
h('span', { className: 'dim-accountSettingsLabel' }, '思考过程留痕'),
|
|
16
|
+
h('span', { className: 'dim-accountSettingsHelp' },
|
|
17
|
+
'实时显示思考步骤与工具调用,最终答案单独成条')),
|
|
18
|
+
h('input', {
|
|
19
|
+
type: 'checkbox',
|
|
20
|
+
className: 'dim-accountSettingsSwitch',
|
|
21
|
+
checked,
|
|
22
|
+
disabled: Boolean(busy),
|
|
23
|
+
onChange: (event) => { onSave?.({ thinkingTraces: event.target.checked }); },
|
|
24
|
+
})));
|
|
25
|
+
}
|
|
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
|
|
5
5
|
import { WecomLogoGlyph } from '../../channel-logos.js';
|
|
6
6
|
import { CredentialActionIcon, CredentialBindingPanel, QrActionIcon } from '../../credential-binding.js';
|
|
7
|
-
import { CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
7
|
+
import { AccountSettingsToggle, CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
8
8
|
import { h } from '../../i18n.js';
|
|
9
9
|
import { WorkspaceEditor } from '../../workspace-editor.js';
|
|
10
10
|
import { ContextEnhancementEditor } from '../../context-enhancement.js';
|
|
@@ -188,6 +188,13 @@ export function AccountCard({
|
|
|
188
188
|
return h('article', { className: 'ddt-card dim-botCard', 'data-bot-id': account.botId },
|
|
189
189
|
h('div', { className: 'ddt-cardBody dim-botCardBody' },
|
|
190
190
|
h(CollapsibleAccountSection, {
|
|
191
|
+
settings: h(BotSettingsButton, {
|
|
192
|
+
channel: 'wecom',
|
|
193
|
+
botId: account.botId,
|
|
194
|
+
botName: account.bot.name,
|
|
195
|
+
connected: account.connected,
|
|
196
|
+
accessPolicy: account.accessPolicy,
|
|
197
|
+
}),
|
|
191
198
|
id: `wec-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, '-')}`,
|
|
192
199
|
header: h('div', { className: 'ddt-accountTop dim-botCardTop' },
|
|
193
200
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
@@ -208,13 +215,7 @@ export function AccountCard({
|
|
|
208
215
|
lastCheckedAt: account.health.lastCheckedAt,
|
|
209
216
|
formatCheckedTime: checkedTime,
|
|
210
217
|
}),
|
|
211
|
-
h(
|
|
212
|
-
channel: 'wecom',
|
|
213
|
-
botId: account.botId,
|
|
214
|
-
botName: account.bot.name,
|
|
215
|
-
connected: account.connected,
|
|
216
|
-
accessPolicy: account.accessPolicy,
|
|
217
|
-
})))
|
|
218
|
+
h(AccountSettingsToggle)))
|
|
218
219
|
},
|
|
219
220
|
h(WorkspaceEditor, {
|
|
220
221
|
workspace: account.workspace,
|
|
@@ -3,7 +3,7 @@ import { BotName } from '../../bot-alias.js';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
|
|
5
5
|
import { WecomLogoGlyph } from '../../channel-logos.js';
|
|
6
|
-
import { CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
6
|
+
import { AccountSettingsToggle, CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
7
7
|
import { h } from '../../i18n.js';
|
|
8
8
|
import { WorkspaceEditor } from '../../workspace-editor.js';
|
|
9
9
|
import { ContextEnhancementEditor } from '../../context-enhancement.js';
|
|
@@ -263,6 +263,13 @@ export function AccountCard({
|
|
|
263
263
|
return h('article', { className: 'ddt-card dim-botCard', 'data-bot-id': account.botId },
|
|
264
264
|
h('div', { className: 'ddt-cardBody dim-botCardBody' },
|
|
265
265
|
h(CollapsibleAccountSection, {
|
|
266
|
+
settings: h(BotSettingsButton, {
|
|
267
|
+
channel: 'wecomApp',
|
|
268
|
+
botId: account.botId,
|
|
269
|
+
botName: account.bot.name,
|
|
270
|
+
connected: account.connected,
|
|
271
|
+
accessPolicy: account.accessPolicy,
|
|
272
|
+
}),
|
|
266
273
|
id: elementId,
|
|
267
274
|
header: h('div', { className: 'ddt-accountTop dim-botCardTop' },
|
|
268
275
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
@@ -283,13 +290,7 @@ export function AccountCard({
|
|
|
283
290
|
lastCheckedAt: account.health.lastCheckedAt,
|
|
284
291
|
formatCheckedTime: checkedTime,
|
|
285
292
|
}),
|
|
286
|
-
h(
|
|
287
|
-
channel: 'wecomApp',
|
|
288
|
-
botId: account.botId,
|
|
289
|
-
botName: account.bot.name,
|
|
290
|
-
connected: account.connected,
|
|
291
|
-
accessPolicy: account.accessPolicy,
|
|
292
|
-
})))
|
|
293
|
+
h(AccountSettingsToggle)))
|
|
293
294
|
},
|
|
294
295
|
h(CallbackUrlBox, {
|
|
295
296
|
url: account.bot.callbackUrl,
|
|
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
|
|
5
5
|
import { WeixinLogoGlyph } from '../../channel-logos.js';
|
|
6
6
|
import { QrActionIcon } from '../../credential-binding.js';
|
|
7
|
-
import { CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
7
|
+
import { AccountSettingsToggle, CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
8
8
|
import { h } from '../../i18n.js';
|
|
9
9
|
import {
|
|
10
10
|
WEIXIN_ENDPOINTS,
|
|
@@ -230,6 +230,13 @@ export function AccountCard({
|
|
|
230
230
|
return h('article', { className: 'dxw-card dim-botCard', tabIndex: -1, 'data-bot-id': account.botId },
|
|
231
231
|
h('div', { className: 'dxw-cardBody dim-botCardBody' },
|
|
232
232
|
h(CollapsibleAccountSection, {
|
|
233
|
+
settings: h(BotSettingsButton, {
|
|
234
|
+
channel: 'weixin',
|
|
235
|
+
botId: account.botId,
|
|
236
|
+
botName: account.bot.name,
|
|
237
|
+
connected: account.connected,
|
|
238
|
+
accessPolicy: account.accessPolicy,
|
|
239
|
+
}),
|
|
233
240
|
id: `dxw-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, '-')}`,
|
|
234
241
|
header: h('div', { className: 'dxw-accountTop dim-botCardTop' },
|
|
235
242
|
h('div', { className: 'dxw-accountIdentity dim-botIdentity' },
|
|
@@ -249,13 +256,7 @@ export function AccountCard({
|
|
|
249
256
|
lastCheckedAt: account.health.lastCheckedAt,
|
|
250
257
|
formatCheckedTime: checkedTime,
|
|
251
258
|
}),
|
|
252
|
-
h(
|
|
253
|
-
channel: 'weixin',
|
|
254
|
-
botId: account.botId,
|
|
255
|
-
botName: account.bot.name,
|
|
256
|
-
connected: account.connected,
|
|
257
|
-
accessPolicy: account.accessPolicy,
|
|
258
|
-
})))
|
|
259
|
+
h(AccountSettingsToggle)))
|
|
259
260
|
},
|
|
260
261
|
h(WorkspaceEditor, {
|
|
261
262
|
workspace: account.workspace,
|
|
@@ -4,7 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
|
|
5
5
|
import { WhatsappLogoGlyph } from '../../channel-logos.js';
|
|
6
6
|
import { QrActionIcon } from '../../credential-binding.js';
|
|
7
|
-
import { CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
7
|
+
import { AccountSettingsToggle, CollapsibleAccountSection } from '../shared/collapsible-account.js';
|
|
8
8
|
import { h } from '../../i18n.js';
|
|
9
9
|
import { WorkspaceEditor } from '../../workspace-editor.js';
|
|
10
10
|
import { ContextEnhancementEditor } from '../../context-enhancement.js';
|
|
@@ -208,6 +208,13 @@ export function WhatsappAccountCard({
|
|
|
208
208
|
return h('article', { className: 'ddt-card dim-botCard', 'data-bot-id': account.botId },
|
|
209
209
|
h('div', { className: 'ddt-cardBody dim-botCardBody' },
|
|
210
210
|
h(CollapsibleAccountSection, {
|
|
211
|
+
settings: h(BotSettingsButton, {
|
|
212
|
+
channel: 'whatsapp',
|
|
213
|
+
botId: account.botId,
|
|
214
|
+
botName: account.bot.name,
|
|
215
|
+
connected: account.connected,
|
|
216
|
+
accessPolicy: account.accessPolicy,
|
|
217
|
+
}),
|
|
211
218
|
id: `wsp-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, '-')}`,
|
|
212
219
|
header: h('div', { className: 'ddt-accountTop dim-botCardTop' },
|
|
213
220
|
h('div', { className: 'ddt-accountIdentity dim-botIdentity' },
|
|
@@ -231,13 +238,7 @@ export function WhatsappAccountCard({
|
|
|
231
238
|
lastCheckedAt: account.health.lastCheckedAt,
|
|
232
239
|
formatCheckedTime: checkedTime,
|
|
233
240
|
}),
|
|
234
|
-
h(
|
|
235
|
-
channel: 'whatsapp',
|
|
236
|
-
botId: account.botId,
|
|
237
|
-
botName: account.bot.name,
|
|
238
|
-
connected: account.connected,
|
|
239
|
-
accessPolicy: account.accessPolicy,
|
|
240
|
-
})))
|
|
241
|
+
h(AccountSettingsToggle)))
|
|
241
242
|
},
|
|
242
243
|
h(WorkspaceEditor, {
|
|
243
244
|
workspace: account.workspace,
|