@xmanrui/dsh-im 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +3 -1
- package/README.md +3 -1
- package/lib/client.js +15 -14
- package/lib/index.js +122 -122
- package/package.json +1 -1
- package/plugin-src/client/styles.js +15 -14
- package/plugin-src/host/channels/dingtalk/index.mjs +1 -1
- package/plugin-src/host/channels/dingtalk/production.mjs +3 -0
- package/plugin-src/host/channels/discord/index.mjs +1 -1
- package/plugin-src/host/channels/feishu/index.mjs +1 -1
- package/plugin-src/host/channels/feishu/production.mjs +3 -0
- package/plugin-src/host/channels/qq/index.mjs +1 -1
- package/plugin-src/host/channels/qq/production.mjs +3 -0
- package/plugin-src/host/channels/shared/production.mjs +3 -0
- package/plugin-src/host/channels/slack/index.mjs +1 -1
- package/plugin-src/host/channels/slack/production.mjs +3 -0
- package/plugin-src/host/channels/telegram/index.mjs +1 -1
- package/plugin-src/host/channels/wecom/index.mjs +1 -1
- package/plugin-src/host/channels/wecom/production.mjs +3 -0
- package/plugin-src/host/channels/weixin/index.mjs +1 -1
- package/plugin-src/host/channels/weixin/production.mjs +3 -0
- package/plugin-src/host/channels/whatsapp/index.mjs +1 -1
- package/plugin-src/host/channels/whatsapp/production.mjs +3 -0
- package/plugin-src/host/harness-command-executor.mjs +21 -0
- package/plugin-src/host/index.mjs +1 -1
- package/src/channels/dingtalk/dingtalk-bridge.mjs +13 -0
- package/src/channels/discord/discord-api.mjs +1 -1
- package/src/channels/feishu/bridge.mjs +13 -0
- package/src/channels/qq/qq-bridge.mjs +14 -0
- package/src/channels/shared/bot-workspace-store.mjs +13 -0
- package/src/channels/shared/compact-command.mjs +95 -0
- package/src/channels/shared/harness-client.mjs +24 -0
- package/src/channels/shared/text-harness-bridge.mjs +13 -0
- package/src/channels/wecom/wecom-bridge.mjs +14 -0
- package/src/channels/weixin/weixin-api.mjs +1 -1
- package/src/channels/weixin/weixin-bridge.mjs +14 -0
|
@@ -318,6 +318,7 @@ export class HarnessClient {
|
|
|
318
318
|
#interactionReconnectDelayMs;
|
|
319
319
|
#rpcIdPrefix;
|
|
320
320
|
#logPrefix;
|
|
321
|
+
#commandExecutor;
|
|
321
322
|
#managedProcess = null;
|
|
322
323
|
#interactionRegistry;
|
|
323
324
|
#interactionOwnerships;
|
|
@@ -334,6 +335,7 @@ export class HarnessClient {
|
|
|
334
335
|
interactionReconnectDelayMs = 500,
|
|
335
336
|
rpcIdPrefix = 'im',
|
|
336
337
|
logPrefix = 'dsh-im',
|
|
338
|
+
commandExecutor,
|
|
337
339
|
}) {
|
|
338
340
|
if (typeof createWebSocket !== 'function') {
|
|
339
341
|
throw new TypeError('createWebSocket must be a function');
|
|
@@ -347,6 +349,9 @@ export class HarnessClient {
|
|
|
347
349
|
if (typeof logPrefix !== 'string' || !logPrefix.trim()) {
|
|
348
350
|
throw new TypeError('logPrefix must be a non-empty string');
|
|
349
351
|
}
|
|
352
|
+
if (commandExecutor !== undefined && typeof commandExecutor !== 'function') {
|
|
353
|
+
throw new TypeError('commandExecutor must be a function');
|
|
354
|
+
}
|
|
350
355
|
this.#baseUrl = new URL(baseUrl);
|
|
351
356
|
this.#workspace = workspace;
|
|
352
357
|
this.#agentPreset = agentPreset;
|
|
@@ -357,6 +362,7 @@ export class HarnessClient {
|
|
|
357
362
|
this.#interactionReconnectDelayMs = interactionReconnectDelayMs;
|
|
358
363
|
this.#rpcIdPrefix = rpcIdPrefix.trim();
|
|
359
364
|
this.#logPrefix = logPrefix.trim();
|
|
365
|
+
this.#commandExecutor = commandExecutor;
|
|
360
366
|
this.#interactionRegistry = interactionRegistry(this.#baseUrl.origin);
|
|
361
367
|
this.#interactionOwnerships = this.#interactionRegistry.ownerships;
|
|
362
368
|
this.#interactionClaims = this.#interactionRegistry.claims;
|
|
@@ -459,6 +465,24 @@ export class HarnessClient {
|
|
|
459
465
|
return created.sessionId;
|
|
460
466
|
}
|
|
461
467
|
|
|
468
|
+
async executeCommand(sessionId, line, options = {}) {
|
|
469
|
+
if (typeof sessionId !== 'string' || !sessionId) throw new TypeError('sessionId is required');
|
|
470
|
+
if (typeof line !== 'string' || !line) throw new TypeError('command line is required');
|
|
471
|
+
if (!this.#commandExecutor) {
|
|
472
|
+
const error = new Error('Harness command execution is unavailable');
|
|
473
|
+
error.code = 'commands-unavailable';
|
|
474
|
+
throw error;
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
return await this.#commandExecutor(sessionId, line, options);
|
|
478
|
+
} catch (error) {
|
|
479
|
+
if (error?.failure && typeof error.failure === 'object') {
|
|
480
|
+
throw new HarnessRpcError('commands.execute', error.failure);
|
|
481
|
+
}
|
|
482
|
+
throw error;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
462
486
|
async sessionExists(sessionId, options = {}) {
|
|
463
487
|
try {
|
|
464
488
|
await this.rpc('session.history', { sessionId, maxMessages: 1 }, 30_000, options);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { runWorkspaceCommand } from './workspace-command.mjs';
|
|
2
|
+
import { runCompactCommand } from './compact-command.mjs';
|
|
2
3
|
import { askInWorkspaceSession } from './workspace-session.mjs';
|
|
3
4
|
import { HarnessApprovalQueue } from './harness-approval.mjs';
|
|
4
5
|
import {
|
|
@@ -218,6 +219,7 @@ export class TextHarnessBridge {
|
|
|
218
219
|
'',
|
|
219
220
|
'直接发送文字即可继续当前会话。',
|
|
220
221
|
'/new 开启一个全新会话',
|
|
222
|
+
'/compact 压缩当前会话的较早上下文',
|
|
221
223
|
'/workspace 工作区绝对路径 切换工作区',
|
|
222
224
|
'/workspacelist 列出工作区绝对路径',
|
|
223
225
|
'/sessionlist [工作区序号或绝对路径] 列出会话 ID 和标题',
|
|
@@ -244,6 +246,17 @@ export class TextHarnessBridge {
|
|
|
244
246
|
await this.#bot.sendText(target, '已开启新会话。请发送你的问题。');
|
|
245
247
|
return;
|
|
246
248
|
}
|
|
249
|
+
const compactCommand = await runCompactCommand(
|
|
250
|
+
text,
|
|
251
|
+
this.#harness,
|
|
252
|
+
this.#state,
|
|
253
|
+
conversationKey,
|
|
254
|
+
{ signal: this.#signal },
|
|
255
|
+
);
|
|
256
|
+
if (compactCommand) {
|
|
257
|
+
await this.#bot.sendText(target, compactCommand.message);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
247
260
|
|
|
248
261
|
await this.#bot.sendTyping?.(target).catch((error) => {
|
|
249
262
|
this.#logger.warn?.(`[dsh-im:${this.#descriptor.key}] typing indicator failed:`, error);
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
validHarnessQuestion,
|
|
6
6
|
} from '../shared/harness-question.mjs';
|
|
7
7
|
import { HarnessApprovalQueue } from '../shared/harness-approval.mjs';
|
|
8
|
+
import { runCompactCommand } from '../shared/compact-command.mjs';
|
|
8
9
|
import { runWorkspaceCommand } from '../shared/workspace-command.mjs';
|
|
9
10
|
import { askInWorkspaceSession } from '../shared/workspace-session.mjs';
|
|
10
11
|
|
|
@@ -13,6 +14,7 @@ const HELP_TEXT = [
|
|
|
13
14
|
'',
|
|
14
15
|
'直接发送文字即可继续当前会话。',
|
|
15
16
|
'/new 开启一个全新会话',
|
|
17
|
+
'/compact 压缩当前会话的较早上下文',
|
|
16
18
|
'/workspace 工作区绝对路径 切换工作区',
|
|
17
19
|
'/workspacelist 列出工作区绝对路径',
|
|
18
20
|
'/sessionlist [工作区序号或绝对路径] 列出会话 ID 和标题',
|
|
@@ -321,6 +323,18 @@ export class WecomHarnessBridge {
|
|
|
321
323
|
await this.#state.markSeen(messageId);
|
|
322
324
|
return;
|
|
323
325
|
}
|
|
326
|
+
const compactCommand = await runCompactCommand(
|
|
327
|
+
text,
|
|
328
|
+
this.#harness,
|
|
329
|
+
this.#state,
|
|
330
|
+
key,
|
|
331
|
+
{ signal: this.#signal },
|
|
332
|
+
);
|
|
333
|
+
if (compactCommand) {
|
|
334
|
+
await this.#sendImmediate(frame, chatId, compactCommand.message);
|
|
335
|
+
await this.#state.markSeen(messageId);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
324
338
|
|
|
325
339
|
streamId = this.#generateReqId('stream');
|
|
326
340
|
try {
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
validHarnessQuestion,
|
|
10
10
|
} from '../shared/harness-question.mjs';
|
|
11
11
|
import { HarnessApprovalQueue } from '../shared/harness-approval.mjs';
|
|
12
|
+
import { runCompactCommand } from '../shared/compact-command.mjs';
|
|
12
13
|
import { runWorkspaceCommand } from '../shared/workspace-command.mjs';
|
|
13
14
|
import { askInWorkspaceSession } from '../shared/workspace-session.mjs';
|
|
14
15
|
|
|
@@ -19,6 +20,7 @@ const HELP_TEXT = [
|
|
|
19
20
|
'',
|
|
20
21
|
'直接发送文字或带文字识别结果的语音即可继续当前会话。',
|
|
21
22
|
'/new 开启一个全新会话',
|
|
23
|
+
'/compact 压缩当前会话的较早上下文',
|
|
22
24
|
'/workspace 工作区绝对路径 切换工作区',
|
|
23
25
|
'/workspacelist 列出工作区绝对路径',
|
|
24
26
|
'/sessionlist [工作区序号或绝对路径] 列出会话 ID 和标题',
|
|
@@ -248,6 +250,18 @@ export class WeixinHarnessBridge {
|
|
|
248
250
|
await this.#state.markSeen(messageId);
|
|
249
251
|
return;
|
|
250
252
|
}
|
|
253
|
+
const compactCommand = await runCompactCommand(
|
|
254
|
+
text,
|
|
255
|
+
this.#harness,
|
|
256
|
+
this.#state,
|
|
257
|
+
key,
|
|
258
|
+
{ signal: this.#signal },
|
|
259
|
+
);
|
|
260
|
+
if (compactCommand) {
|
|
261
|
+
await this.#send(sender, compactCommand.message, contextToken, runId);
|
|
262
|
+
await this.#state.markSeen(messageId);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
251
265
|
|
|
252
266
|
let answer;
|
|
253
267
|
try {
|