@xmanrui/dsh-im 0.19.0 → 1.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 +12 -1
- package/README.md +12 -1
- package/lib/index.js +160 -154
- package/package.json +1 -1
- package/plugin-src/host/channels/dingtalk/production.mjs +5 -2
- package/plugin-src/host/channels/feishu/production.mjs +5 -2
- package/plugin-src/host/channels/qq/production.mjs +5 -2
- package/plugin-src/host/channels/shared/production.mjs +5 -2
- package/plugin-src/host/channels/slack/production.mjs +5 -2
- package/plugin-src/host/channels/wecom/production.mjs +5 -2
- package/plugin-src/host/channels/weixin/production.mjs +5 -2
- package/plugin-src/host/channels/whatsapp/production.mjs +5 -2
- package/src/channels/dingtalk/dingtalk-bridge.mjs +11 -1
- package/src/channels/discord/discord-api.mjs +1 -1
- package/src/channels/feishu/bridge.mjs +11 -1
- package/src/channels/feishu/feishu-cards.mjs +4 -0
- package/src/channels/qq/qq-bridge.mjs +11 -1
- package/src/channels/shared/bot-workspace-store.mjs +75 -4
- package/src/channels/shared/preset-command.mjs +305 -0
- package/src/channels/shared/text-harness-bridge.mjs +11 -1
- package/src/channels/telegram/telegram-runtime.mjs +2 -0
- package/src/channels/wecom/wecom-bridge.mjs +11 -1
- package/src/channels/weixin/weixin-api.mjs +1 -1
- package/src/channels/weixin/weixin-bridge.mjs +11 -1
package/package.json
CHANGED
|
@@ -53,6 +53,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
53
53
|
const logger = typeof ctx.logger === 'function'
|
|
54
54
|
? ctx.logger('dsh-dingtalk')
|
|
55
55
|
: (ctx.logger ?? console);
|
|
56
|
+
const agentPresetCatalog = () => listAgentPresetCatalog(ctx);
|
|
56
57
|
const paths = pluginPaths(config);
|
|
57
58
|
const configStore = await new ConfigStore(paths.config).load();
|
|
58
59
|
const defaultWorkspace = resolve(config.workspace ?? process.cwd());
|
|
@@ -106,7 +107,9 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
106
107
|
createRuntime: async ({ botId, config: botConfig, clientSecret }) => {
|
|
107
108
|
const state = await stateFor(botId);
|
|
108
109
|
await workspaces.ensure(botId, { defaultAgentPreset: config.agentPreset });
|
|
109
|
-
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
110
|
+
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
111
|
+
botId, workspaces, state, agentPresetCatalog,
|
|
112
|
+
});
|
|
110
113
|
return new Runtime({
|
|
111
114
|
config: botConfig,
|
|
112
115
|
clientSecret,
|
|
@@ -140,7 +143,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
140
143
|
const controller = createWorkspaceAwareController(coreController, {
|
|
141
144
|
workspaces,
|
|
142
145
|
stateFor,
|
|
143
|
-
agentPresetCatalog
|
|
146
|
+
agentPresetCatalog,
|
|
144
147
|
});
|
|
145
148
|
const supervisor = createSupervisor({
|
|
146
149
|
controller,
|
|
@@ -66,6 +66,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
66
66
|
const logger = typeof ctx.logger === 'function'
|
|
67
67
|
? ctx.logger('dsh-feishu')
|
|
68
68
|
: (ctx.logger ?? console);
|
|
69
|
+
const agentPresetCatalog = () => listAgentPresetCatalog(ctx);
|
|
69
70
|
const paths = pluginPaths(config);
|
|
70
71
|
const configStore = await new ConfigStore(paths.config).load();
|
|
71
72
|
const defaultWorkspace = resolve(config.workspace ?? process.cwd());
|
|
@@ -136,7 +137,9 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
136
137
|
const state = await stateFor(botConfig);
|
|
137
138
|
const id = botId ?? botConfig.id ?? botConfig.appId;
|
|
138
139
|
await workspaces.ensure(id, { defaultAgentPreset: config.agentPreset });
|
|
139
|
-
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
140
|
+
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
141
|
+
botId: id, workspaces, state, agentPresetCatalog,
|
|
142
|
+
});
|
|
140
143
|
return new Runtime({
|
|
141
144
|
lark,
|
|
142
145
|
botId: id,
|
|
@@ -170,7 +173,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
170
173
|
const controller = createWorkspaceAwareController(coreController, {
|
|
171
174
|
workspaces,
|
|
172
175
|
stateFor: stateForBotId,
|
|
173
|
-
agentPresetCatalog
|
|
176
|
+
agentPresetCatalog,
|
|
174
177
|
});
|
|
175
178
|
|
|
176
179
|
const supervisor = createSupervisor({
|
|
@@ -50,6 +50,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
50
50
|
const QrAuth = internals.QrAuth ?? QqQrAuth;
|
|
51
51
|
const createSupervisor = internals.createConnectionSupervisor ?? createConnectionSupervisor;
|
|
52
52
|
const logger = typeof ctx.logger === 'function' ? ctx.logger('dsh-im:qq') : (ctx.logger ?? console);
|
|
53
|
+
const agentPresetCatalog = () => listAgentPresetCatalog(ctx);
|
|
53
54
|
const paths = pluginPaths(config);
|
|
54
55
|
const configStore = await new ConfigStore(paths.config).load();
|
|
55
56
|
const defaultWorkspace = resolve(config.workspace ?? process.cwd());
|
|
@@ -97,7 +98,9 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
97
98
|
createRuntime: async ({ botId, config: botConfig, appSecret }) => {
|
|
98
99
|
const state = await stateFor(botId);
|
|
99
100
|
await workspaces.ensure(botId, { defaultAgentPreset: config.agentPreset });
|
|
100
|
-
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
101
|
+
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
102
|
+
botId, workspaces, state, agentPresetCatalog,
|
|
103
|
+
});
|
|
101
104
|
return new Runtime({
|
|
102
105
|
config: botConfig,
|
|
103
106
|
appSecret,
|
|
@@ -130,7 +133,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
130
133
|
const controller = createWorkspaceAwareController(coreController, {
|
|
131
134
|
workspaces,
|
|
132
135
|
stateFor,
|
|
133
|
-
agentPresetCatalog
|
|
136
|
+
agentPresetCatalog,
|
|
134
137
|
});
|
|
135
138
|
const supervisor = createSupervisor({
|
|
136
139
|
controller,
|
|
@@ -52,6 +52,7 @@ export async function createTokenProductionController(ctx, config, internals, de
|
|
|
52
52
|
const createSupervisor = internals.createConnectionSupervisor ?? createTokenConnectionSupervisor;
|
|
53
53
|
const logger = typeof ctx.logger === 'function'
|
|
54
54
|
? ctx.logger(`dsh-im:${channel}`) : (ctx.logger ?? console);
|
|
55
|
+
const agentPresetCatalog = () => listAgentPresetCatalog(ctx);
|
|
55
56
|
const paths = pluginPaths(config, channel);
|
|
56
57
|
const configStore = await new ResolvedConfigStore(paths.config).load();
|
|
57
58
|
const defaultWorkspace = resolve(config.workspace ?? process.cwd());
|
|
@@ -98,7 +99,9 @@ export async function createTokenProductionController(ctx, config, internals, de
|
|
|
98
99
|
createRuntime: async ({ botId, config: botConfig, token }) => {
|
|
99
100
|
const state = await stateFor(botId);
|
|
100
101
|
await workspaces.ensure(botId, { defaultAgentPreset: config.agentPreset });
|
|
101
|
-
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
102
|
+
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
103
|
+
botId, workspaces, state, agentPresetCatalog,
|
|
104
|
+
});
|
|
102
105
|
return new ResolvedRuntime({
|
|
103
106
|
...channelRuntimeOptions,
|
|
104
107
|
config: botConfig,
|
|
@@ -132,7 +135,7 @@ export async function createTokenProductionController(ctx, config, internals, de
|
|
|
132
135
|
const controller = createWorkspaceAwareController(coreController, {
|
|
133
136
|
workspaces,
|
|
134
137
|
stateFor,
|
|
135
|
-
agentPresetCatalog
|
|
138
|
+
agentPresetCatalog,
|
|
136
139
|
});
|
|
137
140
|
const supervisor = createSupervisor({
|
|
138
141
|
channel,
|
|
@@ -30,6 +30,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
30
30
|
const createSupervisor = internals.createConnectionSupervisor ?? createTokenConnectionSupervisor;
|
|
31
31
|
const logger = typeof ctx.logger === 'function'
|
|
32
32
|
? ctx.logger('dsh-im:slack') : (ctx.logger ?? console);
|
|
33
|
+
const agentPresetCatalog = () => listAgentPresetCatalog(ctx);
|
|
33
34
|
const paths = pluginPaths(config, 'slack');
|
|
34
35
|
const configStore = await new ResolvedConfigStore(paths.config).load();
|
|
35
36
|
const defaultWorkspace = resolve(config.workspace ?? process.cwd());
|
|
@@ -76,7 +77,9 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
76
77
|
createRuntime: async ({ botId, config: botConfig, botToken, appToken }) => {
|
|
77
78
|
const state = await stateFor(botId);
|
|
78
79
|
await workspaces.ensure(botId, { defaultAgentPreset: config.agentPreset });
|
|
79
|
-
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
80
|
+
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
81
|
+
botId, workspaces, state, agentPresetCatalog,
|
|
82
|
+
});
|
|
80
83
|
return new ResolvedRuntime({
|
|
81
84
|
config: botConfig,
|
|
82
85
|
botToken,
|
|
@@ -110,7 +113,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
110
113
|
const controller = createWorkspaceAwareController(coreController, {
|
|
111
114
|
workspaces,
|
|
112
115
|
stateFor,
|
|
113
|
-
agentPresetCatalog
|
|
116
|
+
agentPresetCatalog,
|
|
114
117
|
});
|
|
115
118
|
const supervisor = createSupervisor({
|
|
116
119
|
channel: 'slack',
|
|
@@ -50,6 +50,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
50
50
|
const QrAuth = internals.QrAuth ?? WecomQrAuth;
|
|
51
51
|
const createSupervisor = internals.createConnectionSupervisor ?? createConnectionSupervisor;
|
|
52
52
|
const logger = typeof ctx.logger === 'function' ? ctx.logger('dsh-im:wecom') : (ctx.logger ?? console);
|
|
53
|
+
const agentPresetCatalog = () => listAgentPresetCatalog(ctx);
|
|
53
54
|
const paths = pluginPaths(config);
|
|
54
55
|
const configStore = await new ConfigStore(paths.config).load();
|
|
55
56
|
const defaultWorkspace = resolve(config.workspace ?? process.cwd());
|
|
@@ -100,7 +101,9 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
100
101
|
createRuntime: async ({ botId, config: botConfig, secret }) => {
|
|
101
102
|
const state = await stateFor(botId);
|
|
102
103
|
await workspaces.ensure(botId, { defaultAgentPreset: config.agentPreset });
|
|
103
|
-
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
104
|
+
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
105
|
+
botId, workspaces, state, agentPresetCatalog,
|
|
106
|
+
});
|
|
104
107
|
return new Runtime({
|
|
105
108
|
config: botConfig,
|
|
106
109
|
secret,
|
|
@@ -134,7 +137,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
134
137
|
const controller = createWorkspaceAwareController(coreController, {
|
|
135
138
|
workspaces,
|
|
136
139
|
stateFor,
|
|
137
|
-
agentPresetCatalog
|
|
140
|
+
agentPresetCatalog,
|
|
138
141
|
});
|
|
139
142
|
const supervisor = createSupervisor({
|
|
140
143
|
controller,
|
|
@@ -53,6 +53,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
53
53
|
const logger = typeof ctx.logger === 'function'
|
|
54
54
|
? ctx.logger('dsh-weixin')
|
|
55
55
|
: (ctx.logger ?? console);
|
|
56
|
+
const agentPresetCatalog = () => listAgentPresetCatalog(ctx);
|
|
56
57
|
const paths = pluginPaths(config);
|
|
57
58
|
const configStore = await new ConfigStore(paths.config).load();
|
|
58
59
|
const defaultWorkspace = resolve(config.workspace ?? process.cwd());
|
|
@@ -100,7 +101,9 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
100
101
|
createRuntime: async ({ botId, config: accountConfig, token }) => {
|
|
101
102
|
const state = await stateFor(botId);
|
|
102
103
|
await workspaces.ensure(botId, { defaultAgentPreset: config.agentPreset });
|
|
103
|
-
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
104
|
+
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
105
|
+
botId, workspaces, state, agentPresetCatalog,
|
|
106
|
+
});
|
|
104
107
|
return new Runtime({
|
|
105
108
|
api,
|
|
106
109
|
config: accountConfig,
|
|
@@ -134,7 +137,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
134
137
|
const controller = createWorkspaceAwareController(coreController, {
|
|
135
138
|
workspaces,
|
|
136
139
|
stateFor,
|
|
137
|
-
agentPresetCatalog
|
|
140
|
+
agentPresetCatalog,
|
|
138
141
|
});
|
|
139
142
|
const supervisor = createSupervisor({
|
|
140
143
|
controller,
|
|
@@ -50,6 +50,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
50
50
|
if (!ctx?.webServer) throw new TypeError('dsh-im WhatsApp requires ctx.webServer');
|
|
51
51
|
const logger = typeof ctx.logger === 'function'
|
|
52
52
|
? ctx.logger('dsh-im:whatsapp') : (ctx.logger ?? console);
|
|
53
|
+
const agentPresetCatalog = () => listAgentPresetCatalog(ctx);
|
|
53
54
|
const ConfigStore = internals.ConfigStore ?? WhatsappConfigStore;
|
|
54
55
|
const StateStore = internals.StateStore ?? WhatsappStateStore;
|
|
55
56
|
const Harness = internals.HarnessClient ?? WhatsappHarnessClient;
|
|
@@ -103,7 +104,9 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
103
104
|
createRuntime: async ({ botId, config: botConfig, authDir }) => {
|
|
104
105
|
const state = await stateFor(botId);
|
|
105
106
|
await workspaces.ensure(botId, { defaultAgentPreset: config.agentPreset });
|
|
106
|
-
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
107
|
+
const workspaceScope = createBotWorkspaceScope(harness, {
|
|
108
|
+
botId, workspaces, state, agentPresetCatalog,
|
|
109
|
+
});
|
|
107
110
|
return new Runtime({
|
|
108
111
|
config: botConfig,
|
|
109
112
|
authDir,
|
|
@@ -141,7 +144,7 @@ export async function createProductionController(ctx, config = {}, internals = {
|
|
|
141
144
|
const controller = createWorkspaceAwareController(coreController, {
|
|
142
145
|
workspaces,
|
|
143
146
|
stateFor,
|
|
144
|
-
agentPresetCatalog
|
|
147
|
+
agentPresetCatalog,
|
|
145
148
|
});
|
|
146
149
|
const supervisor = createSupervisor({
|
|
147
150
|
channel: 'whatsapp',
|
|
@@ -18,6 +18,10 @@ import {
|
|
|
18
18
|
isModelCommand,
|
|
19
19
|
runModelCommand,
|
|
20
20
|
} from '../shared/model-command.mjs';
|
|
21
|
+
import {
|
|
22
|
+
isPresetCommand,
|
|
23
|
+
runPresetCommand,
|
|
24
|
+
} from '../shared/preset-command.mjs';
|
|
21
25
|
import { runWorkspaceCommand } from '../shared/workspace-command.mjs';
|
|
22
26
|
import { askInWorkspaceSession } from '../shared/workspace-session.mjs';
|
|
23
27
|
import {
|
|
@@ -44,6 +48,10 @@ const HELP_TEXT = [
|
|
|
44
48
|
'/models 按序号列出所有可用模型',
|
|
45
49
|
'/model [序号或完整模型ID] 查看或切换当前会话模型',
|
|
46
50
|
'示例:先发 /models,再发 /model 2',
|
|
51
|
+
'/presetlist 按序号列出可用 Agent Preset',
|
|
52
|
+
'/preset [序号或完整ID] 查看或设置当前机器人 Agent Preset',
|
|
53
|
+
'纯数字 ID:/preset id:<ID>',
|
|
54
|
+
'/preset --default 跟随 Host 默认',
|
|
47
55
|
'/stop 停止当前任务',
|
|
48
56
|
'/steer 补充指令 纠偏当前任务',
|
|
49
57
|
'/status 检查连接状态',
|
|
@@ -336,7 +344,9 @@ export class DingtalkHarnessBridge {
|
|
|
336
344
|
const commandText = nonEmptyString(promptMessage.content) ?? '';
|
|
337
345
|
const commandRunner = isControlCommand(commandText)
|
|
338
346
|
? runControlCommand
|
|
339
|
-
: (isModelCommand(commandText)
|
|
347
|
+
: (isModelCommand(commandText)
|
|
348
|
+
? runModelCommand
|
|
349
|
+
: (isPresetCommand(commandText) ? runPresetCommand : null));
|
|
340
350
|
const addressed = String(message.conversationType) !== '2' || message?.isInAtList === true;
|
|
341
351
|
if (commandRunner && sessionWebhook && addressed) {
|
|
342
352
|
let task;
|
|
@@ -108,7 +108,7 @@ export class DiscordApi {
|
|
|
108
108
|
headers: {
|
|
109
109
|
authorization: `Bot ${this.#token}`,
|
|
110
110
|
'content-type': 'application/json',
|
|
111
|
-
'user-agent': 'DeepSeek-Harness-dsh-im (https://github.com/xmanrui/dsh-im, 0.
|
|
111
|
+
'user-agent': 'DeepSeek-Harness-dsh-im (https://github.com/xmanrui/dsh-im, 1.0.0)',
|
|
112
112
|
},
|
|
113
113
|
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
114
114
|
signal: requestSignal(signal, timeoutMs),
|
|
@@ -28,6 +28,10 @@ import {
|
|
|
28
28
|
isModelCommand,
|
|
29
29
|
runModelCommand,
|
|
30
30
|
} from '../shared/model-command.mjs';
|
|
31
|
+
import {
|
|
32
|
+
isPresetCommand,
|
|
33
|
+
runPresetCommand,
|
|
34
|
+
} from '../shared/preset-command.mjs';
|
|
31
35
|
import { runWorkspaceCommand, resolveSessionListWorkspace, workspacePathSnapshot } from '../shared/workspace-command.mjs';
|
|
32
36
|
import { askInWorkspaceSession } from '../shared/workspace-session.mjs';
|
|
33
37
|
import {
|
|
@@ -88,6 +92,10 @@ const HELP_TEXT = [
|
|
|
88
92
|
'/models 按序号列出所有可用模型',
|
|
89
93
|
'/model [序号或完整模型ID] 查看或切换当前会话模型',
|
|
90
94
|
'示例:先发 /models,再发 /model 2',
|
|
95
|
+
'/presetlist 按序号列出可用 Agent Preset',
|
|
96
|
+
'/preset [序号或完整ID] 查看或设置当前机器人 Agent Preset',
|
|
97
|
+
'纯数字 ID:/preset id:<ID>',
|
|
98
|
+
'/preset --default 跟随 Host 默认',
|
|
91
99
|
'/stop 停止当前任务',
|
|
92
100
|
'/steer 补充指令 纠偏当前任务',
|
|
93
101
|
'/status 检查连接状态',
|
|
@@ -389,7 +397,9 @@ export class FeishuHarnessBridge {
|
|
|
389
397
|
const commandText = nonEmptyString(commandMessage.content) ?? '';
|
|
390
398
|
const commandRunner = isControlCommand(commandText)
|
|
391
399
|
? runControlCommand
|
|
392
|
-
: (isModelCommand(commandText)
|
|
400
|
+
: (isModelCommand(commandText)
|
|
401
|
+
? runModelCommand
|
|
402
|
+
: (isPresetCommand(commandText) ? runPresetCommand : null));
|
|
393
403
|
if (commandRunner && addressed) {
|
|
394
404
|
const processing = this.#processFastCommand(
|
|
395
405
|
event,
|
|
@@ -189,6 +189,10 @@ export function menuHelpText() {
|
|
|
189
189
|
'/watch ID 或序号 关注会话(完成后推送)',
|
|
190
190
|
'/compact 压缩上下文',
|
|
191
191
|
'/workspace 绝对路径 切换工作区',
|
|
192
|
+
'/presetlist 列出可用 Agent Preset',
|
|
193
|
+
'/preset [序号或完整ID] 查看或设置当前机器人 Agent Preset',
|
|
194
|
+
'纯数字 ID:/preset id:<ID>',
|
|
195
|
+
'/preset --default 跟随 Host 默认',
|
|
192
196
|
].join('\n');
|
|
193
197
|
}
|
|
194
198
|
|
|
@@ -15,6 +15,10 @@ import {
|
|
|
15
15
|
isModelCommand,
|
|
16
16
|
runModelCommand,
|
|
17
17
|
} from '../shared/model-command.mjs';
|
|
18
|
+
import {
|
|
19
|
+
isPresetCommand,
|
|
20
|
+
runPresetCommand,
|
|
21
|
+
} from '../shared/preset-command.mjs';
|
|
18
22
|
import { askInWorkspaceSession } from '../shared/workspace-session.mjs';
|
|
19
23
|
import {
|
|
20
24
|
fetchImageBuffer,
|
|
@@ -49,6 +53,10 @@ const HELP_TEXT = [
|
|
|
49
53
|
'/models 按序号列出所有可用模型',
|
|
50
54
|
'/model [序号或完整模型ID] 查看或切换当前会话模型',
|
|
51
55
|
'示例:先发 /models,再发 /model 2',
|
|
56
|
+
'/presetlist 按序号列出可用 Agent Preset',
|
|
57
|
+
'/preset [序号或完整ID] 查看或设置当前机器人 Agent Preset',
|
|
58
|
+
'纯数字 ID:/preset id:<ID>',
|
|
59
|
+
'/preset --default 跟随 Host 默认',
|
|
52
60
|
'/stop 停止当前任务',
|
|
53
61
|
'/steer 补充指令 纠偏当前任务',
|
|
54
62
|
'/status 检查连接状态',
|
|
@@ -201,7 +209,9 @@ export class QqHarnessBridge {
|
|
|
201
209
|
const commandText = safeText(message);
|
|
202
210
|
const commandRunner = isControlCommand(commandText)
|
|
203
211
|
? runControlCommand
|
|
204
|
-
: (isModelCommand(commandText)
|
|
212
|
+
: (isModelCommand(commandText)
|
|
213
|
+
? runModelCommand
|
|
214
|
+
: (isPresetCommand(commandText) ? runPresetCommand : null));
|
|
205
215
|
const allowed = this.#ownerUserOpenid === '*' || sender === this.#ownerUserOpenid;
|
|
206
216
|
const addressed = message.kind !== 'group'
|
|
207
217
|
|| message.rawEventType === 'GROUP_AT_MESSAGE_CREATE';
|
|
@@ -535,6 +535,19 @@ function resolveAgentPresetCatalog(catalog) {
|
|
|
535
535
|
: normalizeAgentPresetCatalog(value);
|
|
536
536
|
}
|
|
537
537
|
|
|
538
|
+
function unavailableAgentPreset() {
|
|
539
|
+
const error = new Error('Agent Preset 不存在或不可用。');
|
|
540
|
+
error.code = 'agent-preset-unavailable';
|
|
541
|
+
return error;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function assertCurrentBotScope(isCurrentScope) {
|
|
545
|
+
if (isCurrentScope()) return;
|
|
546
|
+
const error = new Error('找不到要修改的机器人。');
|
|
547
|
+
error.code = 'workspace-bot-not-found';
|
|
548
|
+
throw error;
|
|
549
|
+
}
|
|
550
|
+
|
|
538
551
|
function decorateResult(workspaces, result, catalog) {
|
|
539
552
|
const decorate = (value) => {
|
|
540
553
|
const decorated = workspaces.decorateStatus(value);
|
|
@@ -580,14 +593,74 @@ export function observeBotWorkspaceRemovals(
|
|
|
580
593
|
});
|
|
581
594
|
}
|
|
582
595
|
|
|
583
|
-
export function createBotWorkspaceScope(
|
|
596
|
+
export function createBotWorkspaceScope(
|
|
597
|
+
harness,
|
|
598
|
+
{ botId, workspaces, state, agentPresetCatalog } = {},
|
|
599
|
+
) {
|
|
584
600
|
if (!harness || !workspaces || !state) throw new TypeError('harness, workspaces, and state are required');
|
|
585
601
|
const incarnation = workspaces.incarnationFor(botId);
|
|
586
602
|
const isCurrentScope = () => workspaces.has(botId)
|
|
587
603
|
&& workspaces.incarnationFor(botId) === incarnation;
|
|
604
|
+
const presetSettings = async (catalog = agentPresetCatalog) => {
|
|
605
|
+
let normalizedCatalog;
|
|
606
|
+
try {
|
|
607
|
+
normalizedCatalog = await resolveAgentPresetCatalog(catalog)
|
|
608
|
+
?? normalizeAgentPresetCatalog(null);
|
|
609
|
+
} catch (error) {
|
|
610
|
+
assertCurrentBotScope(isCurrentScope);
|
|
611
|
+
throw error;
|
|
612
|
+
}
|
|
613
|
+
assertCurrentBotScope(isCurrentScope);
|
|
614
|
+
return {
|
|
615
|
+
agentPreset: workspaces.agentPresetFor(botId),
|
|
616
|
+
agentPresetCatalog: normalizedCatalog,
|
|
617
|
+
};
|
|
618
|
+
};
|
|
588
619
|
const sessionGenerations = new Map();
|
|
589
620
|
const scopedHarness = new Proxy(harness, {
|
|
590
621
|
get(target, property) {
|
|
622
|
+
if (property === 'agentPresetSettings') {
|
|
623
|
+
return async (options = {}) => {
|
|
624
|
+
options?.signal?.throwIfAborted();
|
|
625
|
+
assertCurrentBotScope(isCurrentScope);
|
|
626
|
+
const settings = await presetSettings();
|
|
627
|
+
options?.signal?.throwIfAborted();
|
|
628
|
+
return settings;
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
if (property === 'updateAgentPreset') {
|
|
632
|
+
return async (value, options = {}) => {
|
|
633
|
+
options?.signal?.throwIfAborted();
|
|
634
|
+
assertCurrentBotScope(isCurrentScope);
|
|
635
|
+
const agentPreset = value === '--default' ? null : validateAgentPresetId(value);
|
|
636
|
+
let catalog = null;
|
|
637
|
+
if (agentPreset) {
|
|
638
|
+
({ agentPresetCatalog: catalog } = await presetSettings());
|
|
639
|
+
options?.signal?.throwIfAborted();
|
|
640
|
+
if (!catalog.items.some((item) => item.id === agentPreset)) {
|
|
641
|
+
throw unavailableAgentPreset();
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
await workspaces.setAgentPreset(botId, agentPreset, { incarnation });
|
|
645
|
+
assertCurrentBotScope(isCurrentScope);
|
|
646
|
+
if (catalog) {
|
|
647
|
+
return {
|
|
648
|
+
agentPreset: workspaces.agentPresetFor(botId),
|
|
649
|
+
agentPresetCatalog: catalog,
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
try {
|
|
653
|
+
return await presetSettings();
|
|
654
|
+
} catch (error) {
|
|
655
|
+
if (error?.code === 'workspace-bot-not-found') throw error;
|
|
656
|
+
assertCurrentBotScope(isCurrentScope);
|
|
657
|
+
return {
|
|
658
|
+
agentPreset: workspaces.agentPresetFor(botId),
|
|
659
|
+
agentPresetCatalog: normalizeAgentPresetCatalog(null),
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
}
|
|
591
664
|
if (property === 'currentWorkspace') {
|
|
592
665
|
return () => {
|
|
593
666
|
if (!isCurrentScope()) {
|
|
@@ -912,9 +985,7 @@ export function createWorkspaceAwareController(controller, { workspaces, stateFo
|
|
|
912
985
|
: null;
|
|
913
986
|
if (normalizedAgentPreset && agentPresetCatalog
|
|
914
987
|
&& !catalog?.items.some((item) => item.id === normalizedAgentPreset)) {
|
|
915
|
-
|
|
916
|
-
error.code = 'agent-preset-unavailable';
|
|
917
|
-
throw error;
|
|
988
|
+
throw unavailableAgentPreset();
|
|
918
989
|
}
|
|
919
990
|
await workspaces.setAgentPreset(botId, normalizedAgentPreset, { incarnation });
|
|
920
991
|
return decorateResult(
|