dlinkclaw-openclaw 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/LICENSE +201 -0
- package/README.en.md +46 -0
- package/README.md +15 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +1 -0
- package/dist/package.json +95 -0
- package/dist/src/account.d.ts +54 -0
- package/dist/src/account.js +394 -0
- package/dist/src/channel.d.ts +17 -0
- package/dist/src/channel.js +153 -0
- package/dist/src/client/client-manager.d.ts +4 -0
- package/dist/src/client/client-manager.js +10 -0
- package/dist/src/client/const.d.ts +37 -0
- package/dist/src/client/const.js +155 -0
- package/dist/src/client/crypto.d.ts +47 -0
- package/dist/src/client/crypto.js +260 -0
- package/dist/src/client/dl-client.d.ts +117 -0
- package/dist/src/client/dl-client.js +588 -0
- package/dist/src/client/dl-http.d.ts +27 -0
- package/dist/src/client/dl-http.js +223 -0
- package/dist/src/client/media-handler.d.ts +21 -0
- package/dist/src/client/media-handler.js +196 -0
- package/dist/src/client/message.d.ts +96 -0
- package/dist/src/client/message.js +1211 -0
- package/dist/src/client/timeout.d.ts +20 -0
- package/dist/src/client/timeout.js +36 -0
- package/dist/src/client/types.d.ts +226 -0
- package/dist/src/client/types.js +1 -0
- package/dist/src/monitor.d.ts +18 -0
- package/dist/src/monitor.js +322 -0
- package/dist/src/outbound.d.ts +6 -0
- package/dist/src/outbound.js +78 -0
- package/dist/src/policy.d.ts +42 -0
- package/dist/src/policy.js +216 -0
- package/dist/src/runtime.d.ts +9 -0
- package/dist/src/runtime.js +65 -0
- package/dist/src/services/gateway-rpc.d.ts +37 -0
- package/dist/src/services/gateway-rpc.js +37 -0
- package/dist/src/services/index.d.ts +41 -0
- package/dist/src/services/index.js +245 -0
- package/dist/src/services/services.d.ts +169 -0
- package/dist/src/services/services.js +1160 -0
- package/dist/src/services/types.d.ts +391 -0
- package/dist/src/services/types.js +5 -0
- package/dist/src/services/ws-client.d.ts +186 -0
- package/dist/src/services/ws-client.js +896 -0
- package/dist/src/utils.d.ts +20 -0
- package/dist/src/utils.js +128 -0
- package/ext_capabilities/workrelay-speak/CLONE_GUIDE.md +129 -0
- package/ext_capabilities/workrelay-speak/HARDWARE.md +84 -0
- package/ext_capabilities/workrelay-speak/QWEN_GUIDE.md +151 -0
- package/ext_capabilities/workrelay-speak/README.md +79 -0
- package/ext_capabilities/workrelay-speak/__pycache__/patch-kokoro-en.cpython-312.pyc +0 -0
- package/ext_capabilities/workrelay-speak/install.sh +329 -0
- package/ext_capabilities/workrelay-speak/install.sh.bak-20260814 +376 -0
- package/ext_capabilities/workrelay-speak/manifest.json +63 -0
- package/ext_capabilities/workrelay-speak/patch-kokoro-en.py +85 -0
- package/ext_capabilities/workrelay-speak/status.sh +111 -0
- package/ext_capabilities/workrelay-speak/workrelay-tts.sh +118 -0
- package/ext_capabilities/workrelay-speak-luxtts/README.md +44 -0
- package/ext_capabilities/workrelay-speak-luxtts/install.sh +330 -0
- package/ext_capabilities/workrelay-speak-luxtts/manifest.json +63 -0
- package/ext_capabilities/workrelay-speak-luxtts/samples/45ea2e2c-0863-4966-a739-8bff8817f4c0.wav +0 -0
- package/ext_capabilities/workrelay-speak-luxtts/samples/800e5af4-cba5-441e-8003-6d36f35409e6.wav +0 -0
- package/ext_capabilities/workrelay-speak-luxtts/samples/85fafe01-d4d6-4a48-890e-9ae113f21905.wav +0 -0
- package/ext_capabilities/workrelay-speak-luxtts/samples/reference_text.txt +4 -0
- package/ext_capabilities/workrelay-speak-luxtts/samples/stone-sample-6.4s.wav +0 -0
- package/ext_capabilities/workrelay-speak-luxtts/status.sh +115 -0
- package/ext_capabilities/workrelay-speak-luxtts/workrelay-tts.sh +98 -0
- package/ext_capabilities/workrelay-speak-qwen/README.md +62 -0
- package/ext_capabilities/workrelay-speak-qwen/install.sh +349 -0
- package/ext_capabilities/workrelay-speak-qwen/manifest.json +63 -0
- package/ext_capabilities/workrelay-speak-qwen/status.sh +106 -0
- package/ext_capabilities/workrelay-speak-qwen/workrelay-tts.sh +98 -0
- package/ext_capabilities/workrelay-transcribe/README.md +76 -0
- package/ext_capabilities/workrelay-transcribe/__pycache__/transcribe.cpython-312.pyc +0 -0
- package/ext_capabilities/workrelay-transcribe/__pycache__/transcribe_server.cpython-312.pyc +0 -0
- package/ext_capabilities/workrelay-transcribe/install.sh +227 -0
- package/ext_capabilities/workrelay-transcribe/manifest.json +42 -0
- package/ext_capabilities/workrelay-transcribe/status.sh +63 -0
- package/ext_capabilities/workrelay-transcribe/transcribe.py +56 -0
- package/ext_capabilities/workrelay-transcribe/transcribe_server.py +116 -0
- package/ext_capabilities/workrelay-transcribe/voicebox-transcribe.sh +88 -0
- package/openclaw.plugin.json +142 -0
- package/package.json +95 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CMD 消息处理器
|
|
3
|
+
* 集成到 duolian 的消息处理流程中
|
|
4
|
+
*/
|
|
5
|
+
import ClawServices from "./services.js";
|
|
6
|
+
const AGENT_RELAY_MAP = new Map();
|
|
7
|
+
//const BATCH_COUNT = 10;
|
|
8
|
+
//const BATCH_TRAJECTORY_MAP: Map<string, Array<any>> = new Map();
|
|
9
|
+
/**
|
|
10
|
+
* CMD 消息处理器
|
|
11
|
+
*/
|
|
12
|
+
export class CmdHandler {
|
|
13
|
+
dlClient;
|
|
14
|
+
services;
|
|
15
|
+
isInitialized = false;
|
|
16
|
+
constructor(config, dlClient, logger) {
|
|
17
|
+
this.dlClient = dlClient;
|
|
18
|
+
this.services = new ClawServices(config, logger);
|
|
19
|
+
}
|
|
20
|
+
log(msg, type) {
|
|
21
|
+
this.services.log(msg, type);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 初始化处理器
|
|
25
|
+
*/
|
|
26
|
+
async initialize() {
|
|
27
|
+
try {
|
|
28
|
+
this.services.on('onTick', (_payload) => {
|
|
29
|
+
//this.dlClient.publishEventToDLClient(payload, 'onTick', '0');
|
|
30
|
+
//this.dlClient.publishEventToServer({ "connected": true }, "onConnectState")
|
|
31
|
+
});
|
|
32
|
+
this.services.on('onHealth', (_payload) => {
|
|
33
|
+
//this.dlClient.publishEventToDLClient(payload, 'onHealth', '0')
|
|
34
|
+
});
|
|
35
|
+
this.services.on('onHeartbeat', (_payload) => {
|
|
36
|
+
this.dlClient.publishEventToServer({ "connected": true }, "onConnectState");
|
|
37
|
+
});
|
|
38
|
+
this.services.on('onHandshaked', (payload) => {
|
|
39
|
+
this.dlClient.publishEventToServer(payload, 'onHandshaked', '0');
|
|
40
|
+
});
|
|
41
|
+
this.services.on('onAgentReply', (payload) => {
|
|
42
|
+
const message = payload;
|
|
43
|
+
if (message.stream === 'lifecycle') {
|
|
44
|
+
if (message.data.phase && message.data.phase === 'start') {
|
|
45
|
+
AGENT_RELAY_MAP.set(message.runId, '');
|
|
46
|
+
}
|
|
47
|
+
else if (message.data.phase === 'end') {
|
|
48
|
+
const content = AGENT_RELAY_MAP.get(message.runId);
|
|
49
|
+
if (content && content.length > 0) {
|
|
50
|
+
setTimeout(() => this.dlClient.publishEventToServer({
|
|
51
|
+
runId: message.runId,
|
|
52
|
+
sessionKey: message.sessionKey, //运行的agent SessionKey
|
|
53
|
+
content,
|
|
54
|
+
spawnedBy: message.spawnedBy //指派任务的agent SessionKey(通过消息协议入站执行agent.ask接口的该值为空)
|
|
55
|
+
}, 'onAgentReply', '0'), 1000);
|
|
56
|
+
}
|
|
57
|
+
AGENT_RELAY_MAP.delete(message.runId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (message.stream === 'assistant') {
|
|
61
|
+
if (AGENT_RELAY_MAP.has(message.runId)) {
|
|
62
|
+
if (message.data.text && message.data.text.length > 0) {
|
|
63
|
+
AGENT_RELAY_MAP.set(message.runId, message.data.text);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
// this.services.on('onAgentChat', (payload) => { 这个不需要了,会与onAgentReply上面重复
|
|
69
|
+
// if (!payload) return;
|
|
70
|
+
// if (payload.state === 'final') {
|
|
71
|
+
// setTimeout(() => this.dlClient.publishEventToServer({
|
|
72
|
+
// runId: payload.runId,
|
|
73
|
+
// sessionKey: payload.sessionKey,
|
|
74
|
+
// message: payload.message
|
|
75
|
+
// }, 'onAgentChat', '0'), 1000);
|
|
76
|
+
// }
|
|
77
|
+
// });
|
|
78
|
+
this.services.on('onSessionsChanged', (payload) => {
|
|
79
|
+
// 2026-08-28 会话变更推送(直接推客户端):
|
|
80
|
+
// 原方案 publishEventToServer 走服务端 MQTT 转发,但服务端未定义 onSessionsChanged 接收端,事件会丢;
|
|
81
|
+
// 且网关 sessions.changed 是全量快照(payload 大、每条消息都触发),不宜走服务端转发。
|
|
82
|
+
// 改为 publishEventToDLClient 直接推给 openUserTopics(客户端订阅的 chatTopic 集合,onTick/onHealth 同款通道),
|
|
83
|
+
// 并精简 payload 只保留会话上下文占用所需字段,避免快照体积。
|
|
84
|
+
if (!payload) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// 精简:丢弃全量快照,只保留客户端显示上下文占用百分比所需字段
|
|
88
|
+
const slimPayload = {
|
|
89
|
+
sessionKey: payload.sessionKey,
|
|
90
|
+
totalTokens: payload.totalTokens,
|
|
91
|
+
contextTokens: payload.contextTokens,
|
|
92
|
+
totalTokensFresh: payload.totalTokensFresh,
|
|
93
|
+
model: payload.model,
|
|
94
|
+
};
|
|
95
|
+
this.dlClient.publishEventToDLClient(slimPayload, 'onSessionsChanged', '0');
|
|
96
|
+
});
|
|
97
|
+
this.services.on('onSessionMessage', (payload) => {
|
|
98
|
+
if (!payload) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const sessionKey = payload.sessionKey;
|
|
103
|
+
const message = payload.message;
|
|
104
|
+
const role = message.role;
|
|
105
|
+
if (role !== 'assistant') {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
//this.log(`onSessionMessage >>> ${JSON.stringify(payload)}`, 'warn');
|
|
109
|
+
const stopReason = message.stopReason;
|
|
110
|
+
const content = message.content ?? [];
|
|
111
|
+
const result_contents = content.map(item => {
|
|
112
|
+
if (item.type === 'thinking') {
|
|
113
|
+
return item.thinking;
|
|
114
|
+
}
|
|
115
|
+
else if (item.type === 'text' && stopReason != 'stop') { //stop应该是最终回复了,被免重复推送这里过滤掉(最终回复已在别处处理)
|
|
116
|
+
return item.text;
|
|
117
|
+
}
|
|
118
|
+
return '';
|
|
119
|
+
});
|
|
120
|
+
if (result_contents.length > 0) {
|
|
121
|
+
const content = result_contents.join('').trim();
|
|
122
|
+
if (content.length === 0) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const label = payload.origin.label || undefined;
|
|
126
|
+
if (!label) {
|
|
127
|
+
this.log(`不能StreamId...${label}`, 'error');
|
|
128
|
+
this.dlClient.publishEventToServer({
|
|
129
|
+
sessionKey,
|
|
130
|
+
content,
|
|
131
|
+
}, 'onAgentReply', '0');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (label.includes('_')) {
|
|
135
|
+
const streamId = label.split('_')[1];
|
|
136
|
+
this.dlClient.publishProcessingState({
|
|
137
|
+
streamId,
|
|
138
|
+
content,
|
|
139
|
+
kind: 'plan',
|
|
140
|
+
status: 'read'
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (e) {
|
|
146
|
+
this.log(`onSessionMessage 发生错误 >>> ${String(e)}`, 'info');
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
this.services.on('onCron', (payload) => {
|
|
150
|
+
this.dlClient.publishEventToServer(payload, 'onCron', '0');
|
|
151
|
+
});
|
|
152
|
+
this.services.on('onShutdown', (_payload) => {
|
|
153
|
+
//TODO
|
|
154
|
+
});
|
|
155
|
+
this.services.on('onConnectState', (connected) => {
|
|
156
|
+
this.dlClient.publishEventToServer({ "connected": connected }, "onConnectState");
|
|
157
|
+
});
|
|
158
|
+
this.services.on('onError', (error) => {
|
|
159
|
+
this.dlClient.publishEventToServer({ "error": error }, "onError");
|
|
160
|
+
});
|
|
161
|
+
this.services.on('onPairingResult', data => this.dlClient.publishEventToServer(data, 'onPairingResult', '0'));
|
|
162
|
+
await this.services.initialize();
|
|
163
|
+
this.isInitialized = true;
|
|
164
|
+
this.log('CMD 处理器初始化成功!', 'info');
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
this.log('CMD 处理器初始化失败:' + String(error), 'error');
|
|
169
|
+
this.isInitialized = false;
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 处理 CMD 消息
|
|
175
|
+
*/
|
|
176
|
+
async handleCmdMessage(rawMessage) {
|
|
177
|
+
if (!this.isInitialized || !this.services?.isReady()) {
|
|
178
|
+
this.log('CMD 处理器未初始化,尝试重新初始化...', 'warn');
|
|
179
|
+
const initialized = await this.initialize();
|
|
180
|
+
if (!initialized) {
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
error: 'CMD 处理器未初始化',
|
|
184
|
+
timestamp: Date.now()
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (rawMessage.params?.message) {
|
|
189
|
+
const logMessage = {
|
|
190
|
+
...rawMessage,
|
|
191
|
+
params: {
|
|
192
|
+
...rawMessage.params,
|
|
193
|
+
message: '...'
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
this.log(`🔄CMD 指令:${rawMessage.cmd}, params=${JSON.stringify(logMessage)}`, 'info');
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
this.log(`🔄CMD 指令:${rawMessage.cmd}, params=${JSON.stringify(rawMessage)}`, 'info');
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
// 调用服务层处理
|
|
203
|
+
return await this.services.handleCmdMessage(rawMessage);
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
return {
|
|
207
|
+
success: false,
|
|
208
|
+
error: `cmd:[${rawMessage.cmd}]${error instanceof Error ? error.message : '处理失败'}`,
|
|
209
|
+
timestamp: Date.now()
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* 生成 CMD 响应消息(用于MQTT回复)
|
|
215
|
+
*/
|
|
216
|
+
createCmdResponse(response) {
|
|
217
|
+
return {
|
|
218
|
+
type: 'cmd_response',
|
|
219
|
+
requestId: response.requestId,
|
|
220
|
+
success: response.success,
|
|
221
|
+
data: response.data,
|
|
222
|
+
error: response.error,
|
|
223
|
+
timestamp: response.timestamp
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* 清理资源
|
|
228
|
+
*/
|
|
229
|
+
cleanup() {
|
|
230
|
+
this.services.cleanup();
|
|
231
|
+
this.isInitialized = false;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* 检查处理器是否就绪
|
|
235
|
+
*/
|
|
236
|
+
isReady() {
|
|
237
|
+
return this.isInitialized && (this.services?.isReady() || false);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* 创建 CMD 处理器
|
|
242
|
+
*/
|
|
243
|
+
export function createCmdHandler(config, dlClient, logger) {
|
|
244
|
+
return new CmdHandler(config, dlClient, logger);
|
|
245
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claw-Services 主服务接口
|
|
3
|
+
* 为 duolian 插件提供 OpenClaw API 封装
|
|
4
|
+
*/
|
|
5
|
+
import EventEmitter from 'events';
|
|
6
|
+
import { ClawServiceOptions, CmdMessage, CmdResponse } from './types.js';
|
|
7
|
+
import { PluginLogger } from 'openclaw/plugin-sdk/core';
|
|
8
|
+
/**
|
|
9
|
+
* Claw-Services 主类
|
|
10
|
+
* 处理 CMD 消息并调用相应的 OpenClaw API
|
|
11
|
+
*/
|
|
12
|
+
export declare class ClawServices extends EventEmitter {
|
|
13
|
+
private client;
|
|
14
|
+
private readonly options;
|
|
15
|
+
private isInitialized;
|
|
16
|
+
private readonly logger;
|
|
17
|
+
constructor(options: ClawServiceOptions, logger: PluginLogger);
|
|
18
|
+
log(msg: string, type: 'info' | 'warn' | 'error' | 'debug'): void;
|
|
19
|
+
/**
|
|
20
|
+
* 初始化服务
|
|
21
|
+
*/
|
|
22
|
+
initialize(): Promise<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* 检查服务是否已初始化
|
|
25
|
+
*/
|
|
26
|
+
isReady(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* 处理 CMD 消息
|
|
29
|
+
*/
|
|
30
|
+
handleCmdMessage(cmdMessage: CmdMessage): Promise<CmdResponse>;
|
|
31
|
+
private handleAskAgent;
|
|
32
|
+
/**
|
|
33
|
+
* 更新
|
|
34
|
+
* @param agentId
|
|
35
|
+
* @param userId
|
|
36
|
+
*/
|
|
37
|
+
private handleUpdateSessionModel;
|
|
38
|
+
/**
|
|
39
|
+
* 2026-08-28 解析 direct 会话的真实 sessionKey(兼容 chatId 后缀)
|
|
40
|
+
* 背景:客户端拼的 key 是 agent:<agentId>:<channelId>:direct:<empId>(无后缀),
|
|
41
|
+
* 但网关按 chatId 生成的会话 key 带后缀(agent:<agentId>:<channelId>:direct:<empId>-<botId>-<botType>),
|
|
42
|
+
* store 中两套 key 同时存在时,无后缀 key 可能命中旧遗留会话(模型覆盖过期),
|
|
43
|
+
* 导致 sessions.currentModel 返回旧模型、sessions.patch 写入旧会话。
|
|
44
|
+
* 策略:先精确匹配传入 key;查不到 entry 时,用前缀匹配 store 中 updatedAt 最新的 direct 会话。
|
|
45
|
+
*/
|
|
46
|
+
private resolveDirectSessionKey;
|
|
47
|
+
/**
|
|
48
|
+
* 查询当前会话的模型覆盖(用于 ChatPage 恢复选中状态)
|
|
49
|
+
* 2026-08-28 修复:客户端直接传 sessionKey(不再传 agentId+userId 让插件拼 key)
|
|
50
|
+
*/
|
|
51
|
+
private handleCurrentSessionModel;
|
|
52
|
+
private handleAgentList;
|
|
53
|
+
private handleAgentCreate;
|
|
54
|
+
private handleAgentUpdate;
|
|
55
|
+
private handleAgentDelete;
|
|
56
|
+
private handleAgentGet;
|
|
57
|
+
private handleTaskList;
|
|
58
|
+
private handleTaskCreate;
|
|
59
|
+
private handleTaskUpdate;
|
|
60
|
+
private handleTaskDelete;
|
|
61
|
+
private handleTaskRun;
|
|
62
|
+
private handleStatusHealth;
|
|
63
|
+
private handleStatusSystem;
|
|
64
|
+
private handleStatusUsage;
|
|
65
|
+
private handleListModels;
|
|
66
|
+
private handleSessionList;
|
|
67
|
+
private handleSessionGet;
|
|
68
|
+
private handleSessionsDescribe;
|
|
69
|
+
private handleSessionsResolve;
|
|
70
|
+
/**
|
|
71
|
+
* 创建新会话
|
|
72
|
+
* sessionKey: agent:<agentId>:<channelId>-<suffix>:<chatType>:<userId>
|
|
73
|
+
* 例: agent:main:workrelay-00001:direct:I35916630580137984
|
|
74
|
+
*/
|
|
75
|
+
private handleSessionCreate;
|
|
76
|
+
/**
|
|
77
|
+
* 归档会话
|
|
78
|
+
* 入参: { sessionKey }
|
|
79
|
+
* - sessionKey: 完整的 sessionKey,如 "agent:main:workrelay-00001:direct:i35916630580137984"
|
|
80
|
+
*/
|
|
81
|
+
private handleSessionArchive;
|
|
82
|
+
/**
|
|
83
|
+
* 恢复(取消归档)会话
|
|
84
|
+
* 入参: { sessionKey }
|
|
85
|
+
* - sessionKey: 完整的 sessionKey
|
|
86
|
+
*/
|
|
87
|
+
private handleSessionRestore;
|
|
88
|
+
/**
|
|
89
|
+
* 删除会话
|
|
90
|
+
* 入参: { sessionKey, deleteFiles? }
|
|
91
|
+
* - sessionKey: 完整的 sessionKey
|
|
92
|
+
* - deleteFiles: 是否同时删除会话相关文件(可选,默认 false)
|
|
93
|
+
*/
|
|
94
|
+
private handleSessionDelete;
|
|
95
|
+
private handleSessionReset;
|
|
96
|
+
private handleChatHistories;
|
|
97
|
+
private handleSkillsStatus;
|
|
98
|
+
private handleSkillsSearch;
|
|
99
|
+
private handleSkillDetail;
|
|
100
|
+
private handleSkillInstall;
|
|
101
|
+
private handleSkillUpdate;
|
|
102
|
+
private handleSkillsSecurityVerdicts;
|
|
103
|
+
private handleUsageCost;
|
|
104
|
+
private handleSessionsUsage;
|
|
105
|
+
private handleSessionsUsageLogs;
|
|
106
|
+
/**
|
|
107
|
+
* 取消当前Agent执行,通过Gateway /queue interrupt 中断活跃run
|
|
108
|
+
*/
|
|
109
|
+
private handleCancelMessage;
|
|
110
|
+
/**
|
|
111
|
+
* 强制停止当前Agent run(/stop,比 /queue interrupt 更快)
|
|
112
|
+
* 新增 cmd 通道 agent.stop 指令
|
|
113
|
+
*/
|
|
114
|
+
private handleStopAgent;
|
|
115
|
+
private handlChatAbout;
|
|
116
|
+
/**
|
|
117
|
+
* 2026-09-06 适配 openclaw 2026.9.1:对码审批改走宿主 RPC channels.pairing.approve(按 requestId)
|
|
118
|
+
* - 9.1 起 approveChannelPairingCode 不再从 plugin-sdk 导出(安全收敛:审批权与对码解耦、插件不再直写宿主 store)
|
|
119
|
+
* - requestId 由插件创建对码时通过 channels.pairing.list 获取,随 onPairingRequest 事件下发给客户端
|
|
120
|
+
* - notify=false:不触发宿主 notifyApproval(其内部 dlClient.approved 走 HTTP /guest/relayBot/approved,
|
|
121
|
+
* 服务端暂无该端点会 404 噪音);服务端回调沿用下方 onPairingResult MQTT 事件(7.1 同款链路)
|
|
122
|
+
*/
|
|
123
|
+
private handleApprove;
|
|
124
|
+
/** artifacts.list - 列出会话工件 */
|
|
125
|
+
handleArtifactsList(cmdMessage: CmdMessage): Promise<any>;
|
|
126
|
+
/** artifacts.get - 获取单个工件详情 */
|
|
127
|
+
handleArtifactsGet(cmdMessage: CmdMessage): Promise<any>;
|
|
128
|
+
/** artifacts.download - 下载工件 */
|
|
129
|
+
handleArtifactsDownload(cmdMessage: CmdMessage): Promise<any>;
|
|
130
|
+
/** agents.files.list - 列出 Agent 工作区文件 */
|
|
131
|
+
handleAgentFilesList(cmdMessage: CmdMessage): Promise<any>;
|
|
132
|
+
/** agents.files.get - 获取工作区文件内容 */
|
|
133
|
+
handleAgentFilesGet(cmdMessage: CmdMessage): Promise<any>;
|
|
134
|
+
/**
|
|
135
|
+
* extCapabilities.status - 查询扩展能力安装状态
|
|
136
|
+
* params: { name: 'workrelay-speak' | 'workrelay-transcribe' }
|
|
137
|
+
* 执行 ext_capabilities/<name>/status.sh,返回 JSON 供客户端展示
|
|
138
|
+
*/
|
|
139
|
+
handleExtCapabilityStatus(params: Record<string, any>): Promise<any>;
|
|
140
|
+
/**
|
|
141
|
+
* 2026-08-10 检测指定扩展能力的安装进程是否真实在跑(存活检测)
|
|
142
|
+
* 注意:不能用 pgrep -f "...install.sh" —— 该命令经 bash -c 执行时,bash 进程
|
|
143
|
+
* 自身命令行包含 install.sh 字符串,pgrep 会永远自匹配,导致 installing 恒为 true。
|
|
144
|
+
* 改用 ps + grep 方括号技巧(grep 自身命令行不含字面 install.sh,不会自匹配)。
|
|
145
|
+
*/
|
|
146
|
+
private isExtCapabilityInstalling;
|
|
147
|
+
/**
|
|
148
|
+
* extCapabilities.check - 检查扩展能力安装前置条件
|
|
149
|
+
* params: { name: 'workrelay-speak' | 'workrelay-transcribe' }
|
|
150
|
+
* 读取 ext_capabilities/<name>/manifest.json,逐条执行 requirements[].check(shell 表达式),
|
|
151
|
+
* exit 0 = 条件满足。返回每条条件是否满足,客户端据此展示"安装条件"清单。
|
|
152
|
+
* 2026-08-11 新增:通用适配——每个能力自带前置条件清单,用户安装前即可看到环境是否满足。
|
|
153
|
+
*/
|
|
154
|
+
handleExtCapabilityCheck(params: Record<string, any>): Promise<any>;
|
|
155
|
+
/**
|
|
156
|
+
* extCapabilities.install - 安装扩展能力(长任务,后台执行)
|
|
157
|
+
* params: { name: 'workrelay-speak' | 'workrelay-transcribe' }
|
|
158
|
+
* install.sh 可能需要 5-15 分钟(下载模型),后台 spawn 立即返回"已开始",
|
|
159
|
+
* 客户端通过轮询 extCapabilities.status 感知进度
|
|
160
|
+
*/
|
|
161
|
+
handleExtCapabilityInstall(params: Record<string, any>): Promise<any>;
|
|
162
|
+
/**
|
|
163
|
+
* 2026-08-10 读取日志文件尾部内容(供安装失败报错)
|
|
164
|
+
*/
|
|
165
|
+
private readLogTail;
|
|
166
|
+
private formatUptime;
|
|
167
|
+
cleanup(): void;
|
|
168
|
+
}
|
|
169
|
+
export default ClawServices;
|