@dcrays/dcgchat-test 0.2.1 → 0.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcrays/dcgchat-test",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "OpenClaw channel plugin for 书灵墨宝 (WebSocket)",
6
6
  "main": "index.ts",
@@ -20,9 +20,10 @@
20
20
  "typecheck": "tsc --noEmit"
21
21
  },
22
22
  "dependencies": {
23
+ "ali-oss": "file:src/libs/ali-oss-6.23.0.tgz",
23
24
  "axios": "file:src/libs/axios-1.13.6.tgz",
24
25
  "ws": "file:src/libs/ws-8.19.0.tgz",
25
- "mime-types": "file:src/libs/mime-types-3.0.2.tgz",
26
+ "md5": "file:src/libs/md5-2.3.0.tgz",
26
27
  "unzipper": "file:src/libs/unzipper-0.12.3.tgz"
27
28
  },
28
29
  "openclaw": {
package/src/api.ts CHANGED
@@ -10,7 +10,7 @@ export const getStsToken = async (name: string, botToken: string) => {
10
10
  "/user/getStsToken",
11
11
  {
12
12
  sourceFileName: name,
13
- isPrivate: 0,
13
+ isPrivate: 1,
14
14
  },
15
15
  { botToken },
16
16
  );
@@ -21,6 +21,29 @@ export const getStsToken = async (name: string, botToken: string) => {
21
21
 
22
22
  return response.data;
23
23
  };
24
+ export const generateSignUrl = async (file_url: string, botToken: string) => {
25
+ try {
26
+ // 确保 userToken 已缓存(如果未缓存会自动获取并缓存)
27
+ await getUserToken(botToken);
28
+
29
+ const response = await post<any>(
30
+ "/user/generateSignUrl",
31
+ {
32
+ loudPlatform: 0,
33
+ fileName: file_url
34
+ },
35
+ { botToken },
36
+ );
37
+ if (response.code === 0 && response.data) {
38
+ // @ts-ignore
39
+ return response.data?.filePath
40
+ }
41
+ return ''
42
+
43
+ } catch (error) {
44
+ return ''
45
+ }
46
+ };
24
47
 
25
48
  /**
26
49
  * 通过 botToken 查询 userToken
package/src/bot.ts CHANGED
@@ -6,9 +6,8 @@ import type { InboundMessage, OutboundReply } from "./types.js";
6
6
  import { getDcgchatRuntime } from "./runtime.js";
7
7
  import { resolveAccount } from "./channel.js";
8
8
  import { setMsgStatus } from "./tool.js";
9
- import mime from "mime-types"
10
-
11
- const targetPath = path.join(os.homedir(), '../');
9
+ import { generateSignUrl } from "./api.js";
10
+ import { ossUpload } from "./oss.js";
12
11
 
13
12
  type MediaInfo = {
14
13
  path: string;
@@ -16,27 +15,49 @@ type MediaInfo = {
16
15
  placeholder: string;
17
16
  };
18
17
 
19
- async function resolveMediaFromUrls(
20
- files: { url: string, name: string }[],
21
- log?: (msg: string) => void,
22
- ): Promise<MediaInfo[]> {
18
+ const mediaMaxBytes = 300 * 1024 * 1024;
19
+ async function resolveMediaFromUrls(files: { name: string, url: string }[], botToken: string, log: (message: string) => void): Promise<MediaInfo[]> {
20
+ const core = getDcgchatRuntime();
23
21
  const out: MediaInfo[] = [];
22
+ log(`dcgchat media: starting resolve for ${files.length} file(s): ${JSON.stringify(files)}`);
23
+
24
24
  for (let i = 0; i < files.length; i++) {
25
- const url = path.join(targetPath, files[i]?.url);
25
+ const file = files[i];
26
26
  try {
27
- const response = await fetch(url);
28
- const contentType = response.headers.get("content-type") || "";
27
+ const data = await generateSignUrl(file.url, botToken);
28
+ log(`dcgchat media: [${i + 1}/${files.length}] generateSignUrl: ${data}`);
29
+ const response = await fetch(data);
30
+ if (!response.ok) {
31
+ log?.(`dcgchat media: [${i + 1}/${files.length}] fetch failed with HTTP ${response.status}, skipping`);
32
+ continue;
33
+ }
34
+ const buffer = Buffer.from(await response.arrayBuffer());
35
+
36
+ let contentType = response.headers.get("content-type") || "";
37
+ if (!contentType) {
38
+ contentType = await core.media.detectMime({ buffer }) || "";
39
+ }
40
+ const fileName = file.name || path.basename(new URL(file.url).pathname) || "file";
41
+ const saved = await core.channel.media.saveMediaBuffer(
42
+ buffer,
43
+ contentType,
44
+ "inbound",
45
+ // maxByte: mediaMaxBytes,
46
+ fileName,
47
+ );
29
48
  const isImage = contentType.startsWith("image/");
30
49
  out.push({
31
- path: url,
32
- // @ts-ignore
33
- contentType: saved.contentType,
50
+ path: saved.path,
51
+ contentType: saved.contentType || "",
34
52
  placeholder: isImage ? "<media:image>" : "<media:file>",
35
53
  });
54
+
36
55
  } catch (err) {
37
- log?.(`dcgchat media: [${i + 1}/${files.length}] FAILED to process ${url}: ${String(err)}`);
56
+ log(`dcgchat media: [${i + 1}/${files.length}] FAILED to process ${file.url}: ${String(err)}`);
38
57
  }
39
58
  }
59
+ log(`dcgchat media: resolve complete, ${out.length}/${files.length} file(s) succeeded`);
60
+
40
61
  return out;
41
62
  }
42
63
 
@@ -115,15 +136,7 @@ export async function handleDcgchatMessage(params: {
115
136
  const files = msg.content.files ?? [];
116
137
  let mediaPayload: Record<string, unknown> = {};
117
138
  if (files.length > 0) {
118
- const mediaList = files?.map(item => {
119
- const contentType = mime.lookup(item.name) || "application/octet-stream";
120
- const isImage = contentType.startsWith("image/");
121
- return {
122
- path: path.join(targetPath, item?.url),
123
- contentType: contentType,
124
- placeholder: isImage ? "<media:image>" : "<media:file>",
125
- }
126
- });
139
+ const mediaList = await resolveMediaFromUrls(files, msg.content.bot_token, log)
127
140
  mediaPayload = buildMediaPayload(mediaList);
128
141
  log(`dcgchat[${accountId}]: media resolved ${mediaList.length}/${files.length} file(s), payload=${JSON.stringify(mediaList)}`);
129
142
  }
@@ -174,36 +187,10 @@ export async function handleDcgchatMessage(params: {
174
187
  responsePrefixContextProvider: prefixContext.responsePrefixContextProvider,
175
188
  humanDelay: core.channel.reply.resolveHumanDelayConfig(cfg, route.agentId),
176
189
  onReplyStart: async () => {},
177
- deliver: async (payload) => {
178
- // log(`dcgchat[${accountId}][deliver]: received chunk, text length=${payload.text?.length || 0}`);
179
- // const t = payload.text?.trim().replaceAll(
180
- // "/root/.openclaw/workspace/moBooksAgentGenerate",
181
- // "/upload"
182
- // );
183
- // if (t) {
184
- // log(`dcgchat[${accountId}][deliver]: sending chunk to user ${msg._userId}, text="${t.slice(0, 50)}..."`);
185
- // params.onChunk({
186
- // messageType: "openclaw_bot_chat",
187
- // _userId: msg._userId,
188
- // source: "client",
189
- // content: {
190
- // bot_token: msg.content.bot_token,
191
- // domain_id: msg.content.domain_id,
192
- // app_id: msg.content.app_id,
193
- // bot_id: msg.content.bot_id,
194
- // agent_id: msg.content.agent_id,
195
- // session_id: msg.content.session_id,
196
- // message_id: msg.content.message_id,
197
- // response: t,
198
- // state: 'chunk',
199
- // },
200
- // });
201
- // log(`dcgchat[${accountId}][deliver]: chunk sent successfully`);
202
- // } else {
203
- // log(`dcgchat[${accountId}][deliver]: skipping empty chunk`);
204
- // }
190
+ deliver: async (payload: { text: string | any[]; }) => {
191
+ log(`dcgchat[${accountId}][deliver]: received chunk, text length=${payload.text?.length || 0}`);
205
192
  },
206
- onError: (err, info) => {
193
+ onError: (err: any, info: { kind: any; }) => {
207
194
  error(`dcgchat[${accountId}] ${info.kind} reply failed: ${String(err)}`);
208
195
  },
209
196
  onIdle: () => {},
@@ -218,14 +205,25 @@ export async function handleDcgchatMessage(params: {
218
205
  replyOptions: {
219
206
  ...replyOptions,
220
207
  onModelSelected: prefixContext.onModelSelected,
221
- onPartialReply: (payload: ReplyPayload) => {
208
+ onPartialReply: async (payload: ReplyPayload) => {
222
209
  log(`dcgchat[${accountId}][deliver]: received chunk, text length=${payload.text?.length || 0}`);
223
- const t = payload.text?.trim().replaceAll(
224
- "/root/.openclaw/workspace/moBooksAgentGenerate",
225
- "/upload"
226
- );
227
- if (t) {
228
- log(`dcgchat[${accountId}][deliver]: sending chunk to user ${msg._userId}, text="${t.slice(0, 50)}..."`);
210
+ const mediaList =
211
+ payload.mediaUrls && payload.mediaUrls.length > 0
212
+ ? payload.mediaUrls
213
+ : payload.mediaUrl
214
+ ? [payload.mediaUrl]
215
+ : [];
216
+ if (mediaList.length > 0) {
217
+ const files = []
218
+ for (let i = 0; i < mediaList.length; i++) {
219
+ const file = mediaList[i]
220
+ const fileName = file.split(/[\\/]/).pop() || ''
221
+ const url = await ossUpload(file, msg.content.bot_token)
222
+ files.push({
223
+ url: url,
224
+ name: fileName,
225
+ })
226
+ }
229
227
  params.onChunk({
230
228
  messageType: "openclaw_bot_chat",
231
229
  _userId: msg._userId,
@@ -238,12 +236,35 @@ export async function handleDcgchatMessage(params: {
238
236
  agent_id: msg.content.agent_id,
239
237
  session_id: msg.content.session_id,
240
238
  message_id: msg.content.message_id,
241
- response: t.replace(textChunk, ''),
239
+ response: '',
240
+ files: files,
242
241
  state: 'chunk',
243
242
  },
244
243
  });
245
- textChunk = t
244
+ }
245
+ if (payload.text) {
246
+ log(`dcgchat[${accountId}][deliver]: sending chunk to user ${msg._userId}, text="${payload.text.slice(0, 50)}..."`);
247
+ params.onChunk({
248
+ messageType: "openclaw_bot_chat",
249
+ _userId: msg._userId,
250
+ source: "client",
251
+ content: {
252
+ bot_token: msg.content.bot_token,
253
+ domain_id: msg.content.domain_id,
254
+ app_id: msg.content.app_id,
255
+ bot_id: msg.content.bot_id,
256
+ agent_id: msg.content.agent_id,
257
+ session_id: msg.content.session_id,
258
+ message_id: msg.content.message_id,
259
+ response: payload.text.replace(textChunk, ''),
260
+ state: 'chunk',
261
+ },
262
+ });
263
+ textChunk = payload.text
246
264
  log(`dcgchat[${accountId}][deliver]: chunk sent successfully`);
265
+ } else if (payload.mediaUrl && payload.mediaUrls) {
266
+
267
+
247
268
  } else {
248
269
  log(`dcgchat[${accountId}][deliver]: skipping empty chunk`);
249
270
  }
package/src/channel.ts CHANGED
@@ -1,50 +1,10 @@
1
- import { copyFile, mkdir, rename, unlink } from "node:fs/promises";
2
- import { basename, dirname, isAbsolute, relative, resolve } from "node:path";
3
- import os from "node:os";
4
1
  import type { ChannelPlugin, OpenClawConfig } from "openclaw/plugin-sdk";
5
2
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk";
6
3
  import type { ResolvedDcgchatAccount, DcgchatConfig } from "./types.js";
7
- import { logDcgchat } from "./log.js";
8
4
  import { getWsConnection } from "./connection.js";
5
+ import { ossUpload } from "./oss.js";
9
6
  import { getMsgParams } from "./tool.js";
10
7
 
11
- const uploadRoot = resolve('/', "upload");
12
-
13
- function isPathInside(parentPath: string, targetPath: string): boolean {
14
- const relativePath = relative(parentPath, targetPath);
15
- return relativePath === "" || (!relativePath.startsWith("..") && !isAbsolute(relativePath));
16
- }
17
-
18
- async function ensureMediaInUploadDir(url: string): Promise<string> {
19
- if (!url || /^([a-z][a-z\d+\-.]*):\/\//i.test(url) || !isAbsolute(url)) {
20
- return url;
21
- }
22
- const sourcePath = resolve(url);
23
- if (isPathInside(uploadRoot, sourcePath)) {
24
- return sourcePath;
25
- }
26
- const fileName = basename(sourcePath);
27
- if (!fileName) {
28
- return sourcePath;
29
- }
30
- const targetPath = resolve(uploadRoot, fileName);
31
- if (targetPath === sourcePath) {
32
- return targetPath;
33
- }
34
-
35
- await mkdir(uploadRoot, { recursive: true });
36
-
37
- try {
38
- await rename(sourcePath, targetPath);
39
- } catch (error) {
40
- if ((error as NodeJS.ErrnoException).code !== "EXDEV") {
41
- throw error;
42
- }
43
- await copyFile(sourcePath, targetPath);
44
- await unlink(sourcePath);
45
- }
46
- return targetPath;
47
- }
48
8
 
49
9
  export function resolveAccount(cfg: OpenClawConfig, accountId?: string | null): ResolvedDcgchatAccount {
50
10
  const id = accountId ?? DEFAULT_ACCOUNT_ID;
@@ -145,6 +105,7 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
145
105
  sendText: async (ctx) => {
146
106
  const ws = getWsConnection()
147
107
  const params = getMsgParams();
108
+ const log = ctx.runtime?.log ?? console.log;
148
109
  if (ws?.readyState === WebSocket.OPEN) {
149
110
  const {botToken} = resolveAccount(ctx.cfg, ctx.accountId);
150
111
  const content = {
@@ -157,18 +118,15 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
157
118
  app_id: params.appId,
158
119
  bot_id: params.botId,
159
120
  agent_id: params.agentId,
160
- response: ctx.text.replaceAll(
161
- "/root/.openclaw/workspace/moBooksAgentGenerate",
162
- "/upload"
163
- ),
121
+ response: ctx.text,
164
122
  session_id: params.sessionId,
165
123
  message_id: params.messageId || Date.now().toString(),
166
124
  },
167
125
  };
168
126
  ws.send(JSON.stringify(content));
169
- logDcgchat.info(`dcgchat[${ctx.accountId}]: sendText to ${params.userId}, ${JSON.stringify(content)}`);
127
+ log(`dcgchat[${ctx.accountId}]: sendText to ${params.userId}, ${JSON.stringify(content)}`);
170
128
  } else {
171
- logDcgchat.warn(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
129
+ log(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
172
130
  }
173
131
  return {
174
132
  channel: "dcgchat-test",
@@ -179,13 +137,12 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
179
137
  sendMedia: async (ctx) => {
180
138
  const ws = getWsConnection()
181
139
  const params = getMsgParams();
182
-
183
- if (ws?.readyState === WebSocket.OPEN) {
140
+ const log = ctx.runtime?.log ?? console.log;
141
+ if (ws?.readyState === WebSocket.OPEN) {
142
+ const fileName = ctx.mediaUrl?.split(/[\\/]/).pop() || ''
184
143
  const {botToken} = resolveAccount(ctx.cfg, ctx.accountId);
185
-
186
- // try {
187
- const url = await ensureMediaInUploadDir(ctx.mediaUrl ?? '');
188
- const fileName = url?.split(/[\\/]/).pop() || ''
144
+ try {
145
+ const url = ctx.mediaUrl ? await ossUpload(ctx.mediaUrl, botToken) : '';
189
146
  const content = {
190
147
  messageType: "openclaw_bot_chat",
191
148
  _userId: params.userId,
@@ -196,37 +153,42 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
196
153
  app_id: params.appId,
197
154
  bot_id: params.botId,
198
155
  agent_id: params.agentId,
199
- response: ctx.text.replaceAll(
200
- "/root/.openclaw/workspace/moBooksAgentGenerate",
201
- "/upload"
202
- ),
156
+ response: ctx.text,
203
157
  files: [{
204
158
  url: url,
205
159
  name: fileName,
206
160
  }],
207
161
  session_id: params.sessionId,
208
- message_id: params.messageId || Date.now().toString(),
162
+ message_id: params.messageId ||Date.now().toString(),
163
+ },
164
+ };
165
+ ws.send(JSON.stringify(content));
166
+ log(`dcgchat[${ctx.accountId}]: sendMedia alioss to ${params.userId}, ${JSON.stringify(content)}`);
167
+ } catch (error) {
168
+ const content = {
169
+ messageType: "openclaw_bot_chat",
170
+ _userId: params.userId,
171
+ source: "client",
172
+ content: {
173
+ bot_token: botToken,
174
+ domain_id: params.domainId,
175
+ app_id: params.appId,
176
+ bot_id: params.botId,
177
+ agent_id: params.agentId,
178
+ response: ctx.text,
179
+ files: [{
180
+ url: ctx.mediaUrl,
181
+ name: fileName,
182
+ }],
183
+ session_id: params.sessionId || Date.now().toString(),
184
+ message_id: params.messageId ||Date.now().toString(),
209
185
  },
210
186
  };
211
187
  ws.send(JSON.stringify(content));
212
- logDcgchat.info(`dcgchat[${ctx.accountId}]: agent sendMedia to ${params.userId}, ${JSON.stringify(content)}`);
213
- // } catch (error) {
214
- // const content = {
215
- // messageType: "openclaw_bot_chat",
216
- // _userId: target,
217
- // source: "client",
218
- // content: {
219
- // bot_token: botToken,
220
- // response: ctx.text + '\n' + ctx.mediaUrl,
221
- // session_id: params.sessionId || Date.now().toString(),
222
- // message_id: params.messageId ||Date.now().toString(),
223
- // },
224
- // };
225
- // ws.send(JSON.stringify(content));
226
- // logDcgchat.info(`dcgchat[${ctx.accountId}]: sendMedia to ${target}, ${JSON.stringify(content)}`);
227
- // }
188
+ log(`dcgchat[${ctx.accountId}]: error sendMedia to ${params.userId}, ${JSON.stringify(content)}`);
189
+ }
228
190
  } else {
229
- logDcgchat.warn(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
191
+ log(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
230
192
  }
231
193
  return {
232
194
  channel: "dcgchat-test",
package/src/monitor.ts CHANGED
@@ -112,13 +112,14 @@ export async function monitorDcgchatProvider(opts: MonitorDcgchatOpts): Promise<
112
112
  if (parsed.messageType == "openclaw_bot_chat") {
113
113
  const msg = parsed as unknown as InboundMessage;
114
114
  setMsgStatus('running');
115
+ log(`dcgchat[${account.accountId}]: openclaw_bot_chat received, ${JSON.stringify(msg)}`);
115
116
  setMsgParams({
116
117
  userId: msg._userId,
117
118
  token: msg.content.bot_token,
118
119
  sessionId: msg.content.session_id,
119
120
  messageId: msg.content.message_id,
120
- domainId: msg.content.domain_id,
121
- appId: msg.content.app_id,
121
+ domainId: account.domainId || 1000,
122
+ appId: account.appId || '100',
122
123
  botId: msg.content.bot_id,
123
124
  agentId: msg.content.agent_id,
124
125
  });
@@ -138,7 +139,7 @@ export async function monitorDcgchatProvider(opts: MonitorDcgchatOpts): Promise<
138
139
  const { event_type, operation_type, skill_url, skill_code, skill_id, bot_token, websocket_trace_id } = parsed.content ? parsed.content : {} as Record<string, any>;
139
140
  const content = { event_type, operation_type, skill_url, skill_code, skill_id, bot_token, websocket_trace_id };
140
141
  if (event_type === "skill") {
141
- if (operation_type === "install" || operation_type === "enable") {
142
+ if (operation_type === "install" || operation_type === "enable" || operation_type === "update") {
142
143
  installSkill({ path: skill_url, code: skill_code }, content);
143
144
  } else if (operation_type === "remove" || operation_type === "disable") {
144
145
  uninstallSkill({ code: skill_code }, content);
package/src/oss.ts CHANGED
@@ -61,9 +61,9 @@ export const ossUpload = async (file: File | string | Buffer, botToken: string)
61
61
  if (objectResult?.res?.status !== 200) {
62
62
  throw new Error("OSS 上传失败");
63
63
  }
64
- console.log(objectResult.url);
64
+ console.log(11111, JSON.stringify(objectResult));
65
65
  // const url = `${data.protocol || 'http'}://${data.bucket}.${data.endPoint}/${data.uploadDir}${data.ossFileKey}`
66
- return objectResult.url;
66
+ return objectResult.name || objectResult.url;
67
67
  } catch (error) {
68
68
  console.error("OSS 上传失败:", error);
69
69
  throw error;
package/src/request.ts CHANGED
@@ -2,6 +2,7 @@ import axios from "axios";
2
2
  import md5 from "md5";
3
3
  import type { IResponse } from "./types.js";
4
4
  import { getUserTokenCache } from "./userInfo.js";
5
+ import { getMsgParams } from "./tool.js";
5
6
 
6
7
  export const apiUrlMap = {
7
8
  production: "https://api-gateway.shuwenda.com",
@@ -178,17 +179,23 @@ export function post<T = Record<string, unknown>, R = unknown>(
178
179
  botToken?: string;
179
180
  },
180
181
  ): Promise<IResponse<R>> {
182
+ const params = getMsgParams() || {}
181
183
  const config: any = {
182
184
  method: "POST",
183
185
  url,
184
- data,
185
- headers: buildHeaders(data as Record<string, unknown>, url, options?.userToken),
186
+ data: {
187
+ ...data,
188
+ _appId: params.appId
189
+ },
190
+ headers: buildHeaders({
191
+ ...data,
192
+ _appId: params.appId
193
+ } as Record<string, unknown>, url, options?.userToken),
186
194
  };
187
195
 
188
196
  // 将 botToken 附加到配置中,供请求拦截器使用
189
197
  if (options?.botToken) {
190
198
  config.__botToken = options.botToken;
191
199
  }
192
-
193
200
  return axiosInstance.request(config);
194
201
  }
package/src/tool.ts CHANGED
@@ -1,7 +1,6 @@
1
1
 
2
2
  import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
3
3
  import { getWsConnection } from "./connection.js";
4
- import { logDcgchat } from "./log.js";
5
4
 
6
5
  let msgParams = {} as {
7
6
  userId: number;
@@ -29,32 +28,35 @@ export function setMsgStatus(status: 'running' | 'finished' | '') {
29
28
  export function getMsgStatus() {
30
29
  return msgStatus;
31
30
  }
32
-
31
+ let runId = '';
32
+ let toolName = '';
33
33
  export function monitoringToolMessage(api: OpenClawPluginApi) {
34
- api.on("after_tool_call", (event, payload) => {
34
+ api.on("after_tool_call", (event) => {
35
35
  const ws = getWsConnection()
36
36
  const params = getMsgParams();
37
37
  const status = getMsgStatus();
38
38
  //
39
39
  if (ws?.readyState === WebSocket.OPEN && status === 'running') {
40
- ws.send(JSON.stringify({
41
- messageType: "openclaw_bot_chat",
42
- _userId: params?.userId,
43
- source: "client",
44
- content: {
45
- bot_token: params?.token,
46
- response: 'all_finished',
47
- session_id:params?.sessionId,
48
- message_id: params?.messageId || Date.now().toString()
49
- },
50
- }));
40
+ const log = api.runtime?.log ?? api.log;
41
+ // @ts-ignore
42
+ if (!runId || runId !== event.runId || !toolName || toolName !== event.toolName) {
43
+ ws.send(JSON.stringify({
44
+ messageType: "openclaw_bot_chat",
45
+ _userId: params?.userId,
46
+ source: "client",
47
+ content: {
48
+ bot_token: params?.token,
49
+ response: 'all_finished',
50
+ session_id:params?.sessionId,
51
+ message_id: params?.messageId || Date.now().toString()
52
+ },
53
+ }));
54
+ }
51
55
  const text = JSON.stringify({
52
56
  type: 'tool_call',
57
+ specialIdentification: 'dcgchat_tool_call_special_identification',
53
58
  ...event
54
- }).replaceAll(
55
- "/root/.openclaw/workspace/moBooksAgentGenerate",
56
- "/upload"
57
- );
59
+ });
58
60
  ws.send(JSON.stringify({
59
61
  messageType: "openclaw_bot_chat",
60
62
  _userId: params?.userId,
@@ -65,23 +67,29 @@ export function monitoringToolMessage(api: OpenClawPluginApi) {
65
67
  app_id: params?.appId,
66
68
  bot_id: params?.botId,
67
69
  agent_id: params?.agentId,
68
- response: text,
69
- session_id:params?.sessionId,
70
- message_id: params?.messageId || Date.now().toString()
71
- },
72
- }));
73
- ws.send(JSON.stringify({
74
- messageType: "openclaw_bot_chat",
75
- _userId: params?.userId,
76
- source: "client",
77
- content: {
78
- bot_token: params?.token,
79
- response: 'all_finished',
70
+ thinking_content: text,
71
+ response: '',
80
72
  session_id:params?.sessionId,
81
73
  message_id: params?.messageId || Date.now().toString()
82
74
  },
83
75
  }));
84
- logDcgchat.info(`dcgchat: tool message to ${params?.sessionId}, ${JSON.stringify(event)}`);
76
+ // @ts-ignore
77
+ if (!runId || runId !== event.runId || !toolName || toolName !== event.toolName) {
78
+ ws.send(JSON.stringify({
79
+ messageType: "openclaw_bot_chat",
80
+ _userId: params?.userId,
81
+ source: "client",
82
+ content: {
83
+ bot_token: params?.token,
84
+ response: 'all_finished',
85
+ session_id:params?.sessionId,
86
+ message_id: params?.messageId || Date.now().toString()
87
+ },
88
+ }));
89
+ }
90
+ runId = event.runId;
91
+ toolName = event.toolName;
92
+ log?.(`dcgchat[${params?.sessionId}]:11111111 tool message to ${params?.sessionId}, ${JSON.stringify(event)}`);
85
93
  }
86
94
  });
87
95
  }
package/src/types.ts CHANGED
@@ -79,6 +79,7 @@ export type OutboundReply = {
79
79
  app_id?: string;
80
80
  bot_id?: string;
81
81
  agent_id?: string;
82
+ files?: {url: string, name: string}[];
82
83
  };
83
84
  };
84
85