@xmanrui/dsh-im 4.4.0 → 4.5.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 +26 -9
- package/lib/index.js +229 -226
- package/package.json +1 -1
- package/plugin-src/client/context-enhancement.js +19 -5
- package/plugin-src/client/i18n.js +5 -1
- package/plugin-src/host/modern-harness-api.mjs +3 -0
- package/src/channels/dingtalk/dingtalk-bridge.mjs +9 -3
- package/src/channels/feishu/bridge.mjs +19 -2
- package/src/channels/feishu/feishu-cards.mjs +2 -2
- package/src/channels/feishu/feishu-channel.mjs +36 -6
- package/src/channels/qq/qq-bridge.mjs +8 -3
- package/src/channels/shared/bot-workspace-store.mjs +5 -0
- package/src/channels/shared/context-enhancement.mjs +9 -4
- package/src/channels/shared/harness-client.mjs +6 -0
- package/src/channels/shared/i18n-en/feishu.mjs +3 -3
- package/src/channels/shared/i18n-en/shared-a.mjs +2 -1
- package/src/channels/shared/i18n-en/shared-b.mjs +6 -3
- package/src/channels/shared/session-title.mjs +74 -0
- package/src/channels/shared/text-harness-bridge.mjs +7 -2
- package/src/channels/shared/workspace-command.mjs +16 -4
- package/src/channels/shared/workspace-session.mjs +28 -2
- package/src/channels/telegram/telegram-runtime.mjs +1 -0
- package/src/channels/wecom/wecom-bridge.mjs +6 -2
- package/src/channels/weixin/weixin-bridge.mjs +8 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { withSessionBindingLock } from './session-binding-lock.mjs';
|
|
2
|
+
import { initialSessionTitle } from './session-title.mjs';
|
|
2
3
|
|
|
3
4
|
export const WORKSPACE_SESSION_STALE = 'workspace-session-stale';
|
|
4
5
|
|
|
@@ -6,7 +7,7 @@ function workspaceSession(harness, sessionId) {
|
|
|
6
7
|
if (typeof harness.workspaceSession === 'function') {
|
|
7
8
|
return harness.workspaceSession(sessionId);
|
|
8
9
|
}
|
|
9
|
-
|
|
10
|
+
const session = {
|
|
10
11
|
sessionId,
|
|
11
12
|
sessionExists: (...args) => harness.sessionExists(sessionId, ...args),
|
|
12
13
|
models: (...args) => harness.getSessionModels(sessionId, ...args),
|
|
@@ -16,7 +17,11 @@ function workspaceSession(harness, sessionId) {
|
|
|
16
17
|
stopActiveTurn: (...args) => harness.stopActiveTurn(sessionId, ...args),
|
|
17
18
|
steerActiveTurn: (...args) => harness.steerActiveTurn(sessionId, ...args),
|
|
18
19
|
ask: (...args) => harness.ask(sessionId, ...args),
|
|
19
|
-
}
|
|
20
|
+
};
|
|
21
|
+
if (typeof harness.renameSession === 'function') {
|
|
22
|
+
session.renameTitle = (...args) => harness.renameSession(sessionId, ...args);
|
|
23
|
+
}
|
|
24
|
+
return Object.freeze(session);
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
async function sessionExists(session, options) {
|
|
@@ -42,10 +47,21 @@ export async function askInWorkspaceSession({
|
|
|
42
47
|
key,
|
|
43
48
|
text,
|
|
44
49
|
content,
|
|
50
|
+
contextEnhanced = false,
|
|
45
51
|
createOptions,
|
|
46
52
|
existsOptions,
|
|
47
53
|
askOptions,
|
|
48
54
|
}) {
|
|
55
|
+
const initialTitle = contextEnhanced
|
|
56
|
+
? initialSessionTitle({
|
|
57
|
+
text,
|
|
58
|
+
content,
|
|
59
|
+
files: typeof askOptions === 'object' ? askOptions?.files : undefined,
|
|
60
|
+
})
|
|
61
|
+
: null;
|
|
62
|
+
const renameSignal = createOptions?.signal
|
|
63
|
+
?? (typeof askOptions === 'object' ? askOptions?.signal : undefined);
|
|
64
|
+
const renameOptions = renameSignal ? { signal: renameSignal } : undefined;
|
|
49
65
|
while (true) {
|
|
50
66
|
try {
|
|
51
67
|
const binding = await withSessionBindingLock(state, key, async () => {
|
|
@@ -55,6 +71,16 @@ export async function askInWorkspaceSession({
|
|
|
55
71
|
sessionId = await createSession(harness, createOptions);
|
|
56
72
|
if (await state.setSession(key, sessionId) === false) return null;
|
|
57
73
|
session = workspaceSession(harness, sessionId);
|
|
74
|
+
if (initialTitle && typeof session.renameTitle === 'function') {
|
|
75
|
+
try {
|
|
76
|
+
await session.renameTitle(initialTitle, renameOptions);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (error?.code === WORKSPACE_SESSION_STALE || renameOptions?.signal?.aborted) {
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
console.warn('[dsh-im] unable to set the initial Session title:', error?.message ?? error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
58
84
|
}
|
|
59
85
|
return { sessionId, session };
|
|
60
86
|
});
|
|
@@ -166,6 +166,7 @@ export function normalizeTelegramUpdate(update, {
|
|
|
166
166
|
senderName: [message.from?.first_name, message.from?.last_name]
|
|
167
167
|
.filter((value) => typeof value === 'string' && value.trim())
|
|
168
168
|
.map((value) => value.trim()).join(' ') || message.from?.username,
|
|
169
|
+
conversationTitle: direct ? undefined : message.chat?.title,
|
|
169
170
|
}),
|
|
170
171
|
senderIsBot: message.from?.is_bot === true,
|
|
171
172
|
kind: direct ? 'direct' : 'group',
|
|
@@ -68,7 +68,7 @@ function helpText() {
|
|
|
68
68
|
t('/new 开启一个全新会话'),
|
|
69
69
|
t('/compact 压缩当前会话的较早上下文'),
|
|
70
70
|
t('/history [数量] 查看最近历史消息(默认 3 条,最多 5 条)'),
|
|
71
|
-
t('/workspace
|
|
71
|
+
t('/workspace 工作区序号或绝对路径 切换工作区'),
|
|
72
72
|
t('/workspacelist 列出工作区绝对路径'),
|
|
73
73
|
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
74
74
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
@@ -1007,11 +1007,14 @@ export class WecomHarnessBridge {
|
|
|
1007
1007
|
? await promptContentForMessage(message, { signal: this.#signal })
|
|
1008
1008
|
: undefined;
|
|
1009
1009
|
const snapshot = this.#acceptedMessageIds.get(messageId);
|
|
1010
|
+
let contextEnhanced = false;
|
|
1010
1011
|
if (snapshot) {
|
|
1011
|
-
|
|
1012
|
+
const originalContent = content ?? text;
|
|
1013
|
+
content = enhanceContextContent(originalContent, snapshot, () => ({
|
|
1012
1014
|
channel: 'wecom',
|
|
1013
1015
|
senderId,
|
|
1014
1016
|
}));
|
|
1017
|
+
contextEnhanced = content !== originalContent;
|
|
1015
1018
|
}
|
|
1016
1019
|
await this.#state.markSeen(messageId);
|
|
1017
1020
|
promptRecorded = true;
|
|
@@ -1021,6 +1024,7 @@ export class WecomHarnessBridge {
|
|
|
1021
1024
|
key,
|
|
1022
1025
|
text,
|
|
1023
1026
|
content,
|
|
1027
|
+
contextEnhanced,
|
|
1024
1028
|
createOptions: { signal: this.#signal },
|
|
1025
1029
|
existsOptions: { signal: this.#signal },
|
|
1026
1030
|
askOptions: {
|
|
@@ -75,7 +75,7 @@ const HELP_TEXT = () => [
|
|
|
75
75
|
t('/new 开启一个全新会话'),
|
|
76
76
|
t('/compact 压缩当前会话的较早上下文'),
|
|
77
77
|
t('/history [数量] 查看最近历史消息(默认 3 条,最多 5 条)'),
|
|
78
|
-
t('/workspace
|
|
78
|
+
t('/workspace 工作区序号或绝对路径 切换工作区'),
|
|
79
79
|
t('/workspacelist 列出工作区绝对路径'),
|
|
80
80
|
t('/sessionlist 或 /sessions [工作区序号或绝对路径] 列出会话 ID 和标题'),
|
|
81
81
|
t('/session Session ID 或当前工作区序号 将当前聊天绑定到指定会话'),
|
|
@@ -705,11 +705,14 @@ export class WeixinHarnessBridge {
|
|
|
705
705
|
? await promptContentForMessage(promptMessage, { signal: this.#signal })
|
|
706
706
|
: undefined;
|
|
707
707
|
const snapshot = this.#acceptedMessageIds.get(messageId);
|
|
708
|
+
let contextEnhanced = false;
|
|
708
709
|
if (snapshot) {
|
|
709
|
-
|
|
710
|
+
const originalContent = content ?? text;
|
|
711
|
+
content = enhanceContextContent(originalContent, snapshot, () => ({
|
|
710
712
|
channel: 'weixin',
|
|
711
713
|
senderId: sender,
|
|
712
714
|
}));
|
|
715
|
+
contextEnhanced = content !== originalContent;
|
|
713
716
|
}
|
|
714
717
|
await this.#state.markSeen(messageId);
|
|
715
718
|
promptRecorded = true;
|
|
@@ -717,7 +720,9 @@ export class WeixinHarnessBridge {
|
|
|
717
720
|
harness: this.#harness,
|
|
718
721
|
state: this.#state,
|
|
719
722
|
key,
|
|
720
|
-
|
|
723
|
+
text,
|
|
724
|
+
content,
|
|
725
|
+
contextEnhanced,
|
|
721
726
|
createOptions: { signal: this.#signal },
|
|
722
727
|
existsOptions: { signal: this.#signal },
|
|
723
728
|
askOptions: {
|