adp-openclaw 0.0.50 → 0.0.52
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 +16 -6
- package/package.json +1 -1
- package/src/adp-upload-tool.ts +10 -1
- package/src/channel.ts +62 -26
package/index.ts
CHANGED
|
@@ -97,12 +97,21 @@ const plugin = {
|
|
|
97
97
|
|
|
98
98
|
setAdpOpenclawRuntime(api.runtime);
|
|
99
99
|
|
|
100
|
-
// Register the ADP file upload tool
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
// Register the ADP file upload tool as a factory function
|
|
101
|
+
// Using a factory so the tool is only available when the message originates from the ADP channel.
|
|
102
|
+
// This prevents other channels (e.g. DingTalk) with multimodal models from picking up this tool.
|
|
103
|
+
console.log(`[adp-openclaw] Registering tool factory: ${ADP_UPLOAD_TOOL_NAME}`);
|
|
104
|
+
api.logger.info?.(`[adp-openclaw] Registering tool factory: ${ADP_UPLOAD_TOOL_NAME}`);
|
|
104
105
|
|
|
105
|
-
api.registerTool({
|
|
106
|
+
api.registerTool((ctx: { messageChannel?: string; [key: string]: unknown }) => {
|
|
107
|
+
// Only expose this tool when the message comes from the adp-openclaw channel
|
|
108
|
+
const channel = ctx.messageChannel ?? "";
|
|
109
|
+
if (channel && channel !== "adp-openclaw") {
|
|
110
|
+
api.logger.debug?.(`[adp-openclaw] Skipping ${ADP_UPLOAD_TOOL_NAME} for channel: ${channel}`);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
106
115
|
name: ADP_UPLOAD_TOOL_NAME,
|
|
107
116
|
description:
|
|
108
117
|
"If you can see this tool description, you are connected to the ADP server. " +
|
|
@@ -238,7 +247,8 @@ const plugin = {
|
|
|
238
247
|
isError: false,
|
|
239
248
|
};
|
|
240
249
|
},
|
|
241
|
-
}
|
|
250
|
+
}; // end of tool object
|
|
251
|
+
}); // end of factory function passed to registerTool
|
|
242
252
|
|
|
243
253
|
// Log tool registration success
|
|
244
254
|
console.log(`[adp-openclaw] Tool ${ADP_UPLOAD_TOOL_NAME} registered successfully`);
|
package/package.json
CHANGED
package/src/adp-upload-tool.ts
CHANGED
|
@@ -518,7 +518,7 @@ export const ADP_UPLOAD_TOOL_NAME = "adp_upload_file";
|
|
|
518
518
|
|
|
519
519
|
const ADP_UPLOAD_TOOL_SCHEMA_TITLE = "ADP file upload";
|
|
520
520
|
const ADP_UPLOAD_TOOL_SCHEMA_DESCRIPTION =
|
|
521
|
-
"Upload local files from this machine to ADP storage. If the call succeeds, the files are uploaded and signed download URLs are returned. The user can access the files via these URLs.";
|
|
521
|
+
"Upload local files from this machine to ADP storage. If the call succeeds, the files are uploaded and signed download URLs are returned. The user can access the files via these URLs. IMPORTANT: When presenting download links to users, format them as clickable Markdown links like [filename](url), do NOT wrap URLs in code blocks or backticks.";
|
|
522
522
|
const ADP_UPLOAD_TOOL_PATHS_DESCRIPTION =
|
|
523
523
|
"Local filesystem paths only (1-10 total). Any file type is accepted, including text, images, documents, PDFs, archives, and binary files. Use absolute or workspace-relative local paths that are readable files.";
|
|
524
524
|
|
|
@@ -659,6 +659,8 @@ export interface UploadedFileInfo {
|
|
|
659
659
|
export interface AdpUploadToolResult {
|
|
660
660
|
ok: boolean;
|
|
661
661
|
files?: UploadedFileInfo[];
|
|
662
|
+
/** 预格式化的消息,AI 可以直接展示给用户(不要用代码块包装) */
|
|
663
|
+
message?: string;
|
|
662
664
|
error?: {
|
|
663
665
|
code: number;
|
|
664
666
|
message: string;
|
|
@@ -769,9 +771,16 @@ export const uploadFilesToAdpEndpoint = async (
|
|
|
769
771
|
}
|
|
770
772
|
);
|
|
771
773
|
|
|
774
|
+
// 构建预格式化的消息,告诉 AI 如何展示给用户
|
|
775
|
+
const formattedLinks = uploadResults.map(f =>
|
|
776
|
+
`- [${f.name}](${f.downloadUrl})`
|
|
777
|
+
).join("\n");
|
|
778
|
+
const message = `Files uploaded successfully. Present these download links to the user as clickable Markdown links (do NOT use code blocks):\n${formattedLinks}`;
|
|
779
|
+
|
|
772
780
|
return {
|
|
773
781
|
ok: true,
|
|
774
782
|
files: uploadResults,
|
|
783
|
+
message,
|
|
775
784
|
};
|
|
776
785
|
} catch (error) {
|
|
777
786
|
return {
|
package/src/channel.ts
CHANGED
|
@@ -219,42 +219,78 @@ export const adpOpenclawPlugin: ChannelPlugin<ResolvedAdpOpenclawAccount> = {
|
|
|
219
219
|
});
|
|
220
220
|
},
|
|
221
221
|
},
|
|
222
|
-
// Outbound message support for the "message" tool
|
|
222
|
+
// Outbound message support for the "message" tool and cron tasks
|
|
223
223
|
outbound: {
|
|
224
|
-
|
|
224
|
+
deliveryMode: "direct",
|
|
225
|
+
|
|
226
|
+
// Send text message
|
|
227
|
+
sendText: async (ctx) => {
|
|
228
|
+
const { to, text } = ctx;
|
|
225
229
|
const ws = getActiveWebSocket();
|
|
230
|
+
|
|
226
231
|
if (!ws) {
|
|
227
|
-
|
|
228
|
-
|
|
232
|
+
console.error("[adp-openclaw] No active WebSocket connection for outbound message");
|
|
233
|
+
throw new Error("No active WebSocket connection");
|
|
229
234
|
}
|
|
230
235
|
|
|
231
|
-
// Parse target: expected format is "adp-openclaw:{userId}" or "
|
|
232
|
-
// The "to" parameter comes from the message tool with format like "adp-openclaw:user123"
|
|
236
|
+
// Parse target: expected format is "adp-openclaw:{userId}" or just "{userId}"
|
|
233
237
|
const targetParts = to.split(":");
|
|
234
238
|
const targetUserId = targetParts.length > 1 ? targetParts.slice(1).join(":") : to;
|
|
235
239
|
|
|
236
|
-
log
|
|
240
|
+
console.log(`[adp-openclaw] Sending outbound text to ${targetUserId}: ${text.slice(0, 50)}...`);
|
|
241
|
+
|
|
242
|
+
// Generate unique request ID
|
|
243
|
+
const requestId = `outbound-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
244
|
+
|
|
245
|
+
const outMsg = {
|
|
246
|
+
type: "outbound",
|
|
247
|
+
requestId,
|
|
248
|
+
payload: {
|
|
249
|
+
to: targetUserId,
|
|
250
|
+
text: text,
|
|
251
|
+
},
|
|
252
|
+
timestamp: Date.now(),
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
ws.send(JSON.stringify(outMsg));
|
|
256
|
+
return { channel: "adp-openclaw", messageId: requestId };
|
|
257
|
+
},
|
|
258
|
+
|
|
259
|
+
// Send media message (text with optional media URL)
|
|
260
|
+
sendMedia: async (ctx) => {
|
|
261
|
+
const { to, text, mediaUrl } = ctx;
|
|
262
|
+
const ws = getActiveWebSocket();
|
|
237
263
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const outMsg = {
|
|
243
|
-
type: "outbound",
|
|
244
|
-
requestId,
|
|
245
|
-
payload: {
|
|
246
|
-
to: targetUserId,
|
|
247
|
-
text: text,
|
|
248
|
-
},
|
|
249
|
-
timestamp: Date.now(),
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
ws.send(JSON.stringify(outMsg));
|
|
253
|
-
return { ok: true };
|
|
254
|
-
} catch (err) {
|
|
255
|
-
log?.error?.(`[adp-openclaw] Failed to send outbound message: ${err}`);
|
|
256
|
-
return { ok: false, error: String(err) };
|
|
264
|
+
if (!ws) {
|
|
265
|
+
console.error("[adp-openclaw] No active WebSocket connection for outbound media");
|
|
266
|
+
throw new Error("No active WebSocket connection");
|
|
257
267
|
}
|
|
268
|
+
|
|
269
|
+
// Parse target
|
|
270
|
+
const targetParts = to.split(":");
|
|
271
|
+
const targetUserId = targetParts.length > 1 ? targetParts.slice(1).join(":") : to;
|
|
272
|
+
|
|
273
|
+
console.log(`[adp-openclaw] Sending outbound media to ${targetUserId}: ${text.slice(0, 50)}... (media: ${mediaUrl || "none"})`);
|
|
274
|
+
|
|
275
|
+
// Generate unique request ID
|
|
276
|
+
const requestId = `outbound-media-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
277
|
+
|
|
278
|
+
// Combine text and media URL if present
|
|
279
|
+
const finalText = mediaUrl ? `${text}\n\n📎 ${mediaUrl}` : text;
|
|
280
|
+
|
|
281
|
+
const outMsg = {
|
|
282
|
+
type: "outbound",
|
|
283
|
+
requestId,
|
|
284
|
+
payload: {
|
|
285
|
+
to: targetUserId,
|
|
286
|
+
text: finalText,
|
|
287
|
+
mediaUrl: mediaUrl,
|
|
288
|
+
},
|
|
289
|
+
timestamp: Date.now(),
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
ws.send(JSON.stringify(outMsg));
|
|
293
|
+
return { channel: "adp-openclaw", messageId: requestId };
|
|
258
294
|
},
|
|
259
295
|
},
|
|
260
296
|
};
|