adp-openclaw 0.0.45 → 0.0.47
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/index.ts +26 -4
- package/package.json +1 -1
- package/src/adp-upload-tool.ts +9 -0
- package/src/monitor.ts +45 -4
package/index.ts
CHANGED
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
ADP_UPLOAD_TOOL_SCHEMA,
|
|
8
8
|
parseAdpUploadToolParams,
|
|
9
9
|
uploadFilesToAdpEndpoint,
|
|
10
|
+
uploadResultEmitter,
|
|
11
|
+
UPLOAD_RESULT_EVENT,
|
|
10
12
|
type AdpUploadToolResult,
|
|
11
13
|
type UploadedFileInfo,
|
|
12
14
|
} from "./src/adp-upload-tool.js";
|
|
@@ -179,27 +181,47 @@ const plugin = {
|
|
|
179
181
|
|
|
180
182
|
api.logger.debug?.(`[${ADP_UPLOAD_TOOL_NAME}] upload success toolCallId=${toolCallId} count=${successResult.files?.length ?? 0} paths=${JSON.stringify(parsed.value.paths)}`);
|
|
181
183
|
|
|
184
|
+
// Debug: print full downloadUrl for each file
|
|
185
|
+
for (const file of (successResult.files || [])) {
|
|
186
|
+
api.logger.info?.(`[${ADP_UPLOAD_TOOL_NAME}] file.downloadUrl: ${file.downloadUrl}`);
|
|
187
|
+
api.logger.info?.(`[${ADP_UPLOAD_TOOL_NAME}] file.uri: ${file.uri}`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// 发射上传结果事件,让 monitor.ts 能够直接获取完整的下载链接
|
|
191
|
+
uploadResultEmitter.emit(UPLOAD_RESULT_EVENT, {
|
|
192
|
+
toolCallId,
|
|
193
|
+
result: successResult,
|
|
194
|
+
});
|
|
195
|
+
|
|
182
196
|
// Build content with resource links and download URLs
|
|
183
|
-
const content: Array<{ type: string; uri?: string; name?: string; mimeType?: string; text?: string }> = [];
|
|
197
|
+
const content: Array<{ type: string; uri?: string; name?: string; mimeType?: string; text?: string; downloadUrl?: string }> = [];
|
|
184
198
|
|
|
185
199
|
// Add resource links for each file
|
|
186
200
|
for (const file of (successResult.files || [])) {
|
|
187
201
|
content.push({
|
|
188
202
|
type: "resource_link",
|
|
189
|
-
uri: file.uri,
|
|
203
|
+
uri: file.downloadUrl || file.uri, // 使用带签名的下载链接
|
|
190
204
|
name: file.name,
|
|
191
205
|
mimeType: file.mimeType,
|
|
206
|
+
downloadUrl: file.downloadUrl, // 也包含 downloadUrl 字段
|
|
192
207
|
});
|
|
193
208
|
}
|
|
194
209
|
|
|
195
210
|
// Add a text summary with download URLs for AI to include in response
|
|
211
|
+
// 注意:URL 包含签名参数,必须完整保留,不能截断或修改
|
|
196
212
|
const urlSummary = (successResult.files || [])
|
|
197
|
-
.map((f: UploadedFileInfo) =>
|
|
213
|
+
.map((f: UploadedFileInfo) => {
|
|
214
|
+
const url = f.downloadUrl || f.uri;
|
|
215
|
+
// 把完整 URL 作为代码块,防止 AI 截断或修改
|
|
216
|
+
return `- **${f.name}**: \`${url}\``;
|
|
217
|
+
})
|
|
198
218
|
.join("\n");
|
|
199
219
|
|
|
220
|
+
api.logger.info?.(`[${ADP_UPLOAD_TOOL_NAME}] urlSummary: ${urlSummary}`);
|
|
221
|
+
|
|
200
222
|
content.push({
|
|
201
223
|
type: "text",
|
|
202
|
-
text: `Files uploaded successfully:\n${urlSummary}\n\n⚠️
|
|
224
|
+
text: `Files uploaded successfully:\n${urlSummary}\n\n⚠️ IMPORTANT: The URLs above contain authentication signatures. You MUST copy the ENTIRE URL exactly as shown (including all query parameters after the "?"). Do NOT truncate or modify the URLs in any way. The links are valid for 24 hours.`,
|
|
203
225
|
});
|
|
204
226
|
|
|
205
227
|
return {
|
package/package.json
CHANGED
package/src/adp-upload-tool.ts
CHANGED
|
@@ -12,8 +12,17 @@
|
|
|
12
12
|
import { constants } from "node:fs";
|
|
13
13
|
import { access, readFile, stat } from "node:fs/promises";
|
|
14
14
|
import { basename, extname } from "node:path";
|
|
15
|
+
import { EventEmitter } from "node:events";
|
|
15
16
|
import type { AdpOpenclawChannelConfig } from "./channel.js";
|
|
16
17
|
|
|
18
|
+
// ==================== 上传结果事件 ====================
|
|
19
|
+
|
|
20
|
+
/** 上传结果事件发射器,用于通知其他模块上传完成 */
|
|
21
|
+
export const uploadResultEmitter = new EventEmitter();
|
|
22
|
+
|
|
23
|
+
/** 上传结果事件名称 */
|
|
24
|
+
export const UPLOAD_RESULT_EVENT = "adp-upload-result";
|
|
25
|
+
|
|
17
26
|
// ==================== 类型定义 ====================
|
|
18
27
|
|
|
19
28
|
/** 存储凭证请求参数 */
|
package/src/monitor.ts
CHANGED
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
ADP_UPLOAD_TOOL_NAME,
|
|
15
15
|
ADP_UPLOAD_TOOL_SCHEMA,
|
|
16
16
|
executeAdpUploadTool,
|
|
17
|
+
uploadResultEmitter,
|
|
18
|
+
UPLOAD_RESULT_EVENT,
|
|
17
19
|
type AdpUploadToolResult,
|
|
18
20
|
} from "./adp-upload-tool.js";
|
|
19
21
|
import {
|
|
@@ -328,20 +330,58 @@ async function connectAndHandle(params: ConnectParams): Promise<void> {
|
|
|
328
330
|
let lastPartialText = ""; // Track last sent text for delta calculation
|
|
329
331
|
let finalSent = false; // Track if outbound_end has been sent
|
|
330
332
|
const displayName = inMsg.user?.username || inMsg.from;
|
|
333
|
+
|
|
334
|
+
// 收集上传结果,在发送最终回复时追加完整的下载链接
|
|
335
|
+
let pendingUploadResults: AdpUploadToolResult[] = [];
|
|
336
|
+
|
|
337
|
+
// 监听上传结果事件
|
|
338
|
+
const uploadResultHandler = (event: { toolCallId: string; result: AdpUploadToolResult }) => {
|
|
339
|
+
log?.info(`[adp-openclaw] Received upload result event for toolCallId=${event.toolCallId}`);
|
|
340
|
+
if (event.result.ok && event.result.files && event.result.files.length > 0) {
|
|
341
|
+
pendingUploadResults.push(event.result);
|
|
342
|
+
// 打印完整的下载链接
|
|
343
|
+
for (const file of event.result.files) {
|
|
344
|
+
log?.info(`[adp-openclaw] Upload result - file.downloadUrl: ${file.downloadUrl}`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
uploadResultEmitter.on(UPLOAD_RESULT_EVENT, uploadResultHandler);
|
|
331
349
|
|
|
332
350
|
// Helper function to send outbound_end message
|
|
333
351
|
const sendOutboundEnd = (text: string) => {
|
|
334
352
|
if (finalSent) return; // Prevent duplicate sends
|
|
335
353
|
finalSent = true;
|
|
336
354
|
|
|
355
|
+
// 移除事件监听
|
|
356
|
+
uploadResultEmitter.off(UPLOAD_RESULT_EVENT, uploadResultHandler);
|
|
357
|
+
|
|
358
|
+
// 如果有上传结果,追加完整的下载链接到回复中
|
|
359
|
+
let finalText = text;
|
|
360
|
+
if (pendingUploadResults.length > 0) {
|
|
361
|
+
const uploadLinks: string[] = [];
|
|
362
|
+
for (const result of pendingUploadResults) {
|
|
363
|
+
for (const file of (result.files || [])) {
|
|
364
|
+
if (file.downloadUrl) {
|
|
365
|
+
// 使用完整的下载链接,包括签名参数
|
|
366
|
+
uploadLinks.push(`📎 [${file.name}](${file.downloadUrl})`);
|
|
367
|
+
log?.info(`[adp-openclaw] Appending download link: ${file.downloadUrl.substring(0, 100)}...`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (uploadLinks.length > 0) {
|
|
372
|
+
finalText = `${text}\n\n**文件下载链接(24小时有效):**\n${uploadLinks.join("\n")}`;
|
|
373
|
+
log?.info(`[adp-openclaw] Added ${uploadLinks.length} download links to final response`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
337
377
|
if (chunkIndex > 0) {
|
|
338
|
-
log?.info(`[adp-openclaw] Sending outbound_end to ${displayName}: ${
|
|
378
|
+
log?.info(`[adp-openclaw] Sending outbound_end to ${displayName}: ${finalText.slice(0, 50)}... (chunks=${chunkIndex})`);
|
|
339
379
|
const endMsg: WSMessage = {
|
|
340
380
|
type: MsgType.OutboundEnd,
|
|
341
381
|
requestId: generateRequestId(),
|
|
342
382
|
payload: {
|
|
343
383
|
to: inMsg.from,
|
|
344
|
-
text:
|
|
384
|
+
text: finalText,
|
|
345
385
|
conversationId: inMsg.conversationId,
|
|
346
386
|
recordId: inMsg.recordId, // Pass recordId back to server
|
|
347
387
|
streamId: streamId,
|
|
@@ -353,13 +393,13 @@ async function connectAndHandle(params: ConnectParams): Promise<void> {
|
|
|
353
393
|
ws.send(JSON.stringify(endMsg));
|
|
354
394
|
} else {
|
|
355
395
|
// No streaming chunks were sent, send as regular outbound message
|
|
356
|
-
log?.info(`[adp-openclaw] Sending outbound to ${displayName}: ${
|
|
396
|
+
log?.info(`[adp-openclaw] Sending outbound to ${displayName}: ${finalText.slice(0, 50)}...`);
|
|
357
397
|
const outMsg: WSMessage = {
|
|
358
398
|
type: MsgType.Outbound,
|
|
359
399
|
requestId: generateRequestId(),
|
|
360
400
|
payload: {
|
|
361
401
|
to: inMsg.from,
|
|
362
|
-
text:
|
|
402
|
+
text: finalText,
|
|
363
403
|
conversationId: inMsg.conversationId,
|
|
364
404
|
recordId: inMsg.recordId, // Pass recordId back to server
|
|
365
405
|
user: inMsg.user,
|
|
@@ -494,6 +534,7 @@ async function connectAndHandle(params: ConnectParams): Promise<void> {
|
|
|
494
534
|
// SDK may call deliver without kind when streaming ends
|
|
495
535
|
if (kind === "final" || kind === undefined) {
|
|
496
536
|
log?.info(`[adp-openclaw] deliver triggering sendOutboundEnd (kind=${kind})`);
|
|
537
|
+
log?.info(`[adp-openclaw] Final text content: ${text}`);
|
|
497
538
|
sendOutboundEnd(text || lastPartialText);
|
|
498
539
|
}
|
|
499
540
|
},
|