openclaw-xiaoyou 1.3.8 → 1.4.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/index.ts CHANGED
@@ -47,9 +47,12 @@ const plugin = {
47
47
  console.error("--to <conversationId> is required");
48
48
  return;
49
49
  }
50
- const result = await xiayouPlugin.outbound.send({
50
+ const result = await xiayouPlugin.outbound.sendText({
51
51
  to: opts.to,
52
- payload: { kind: "text", text: opts.text },
52
+ text: opts.text,
53
+ accountId: "default",
54
+ replyToId: undefined,
55
+ cfg: undefined,
53
56
  });
54
57
  console.log(JSON.stringify(result, null, 2));
55
58
  });
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "id": "xiaoyou",
3
3
  "channels": ["xiaoyou"],
4
+ "capabilities": {
5
+ "proactiveMessaging": true,
6
+ "cronJobs": true
7
+ },
4
8
  "configSchema": {
5
9
  "type": "object",
6
10
  "additionalProperties": true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-xiaoyou",
3
- "version": "1.3.8",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "description": "Xiaoyou channel plugin for OpenClaw — connects enterprise services via persistent outbound WebSocket",
6
6
  "openclaw": {
package/src/channel.ts CHANGED
@@ -207,6 +207,7 @@ export const xiayouPlugin = {
207
207
  conversationId,
208
208
  messageId: replyMessageId,
209
209
  replyToMessageId: inboundMessageId,
210
+ senderId,
210
211
  text: textToSend,
211
212
  streamStatus: "chunk",
212
213
  seq: chunkSeq++,
@@ -223,6 +224,7 @@ export const xiayouPlugin = {
223
224
  conversationId,
224
225
  messageId: replyMessageId,
225
226
  replyToMessageId: inboundMessageId,
227
+ senderId,
226
228
  text: fullText,
227
229
  streamStatus: "end",
228
230
  timestamp: Date.now(),
@@ -240,6 +242,7 @@ export const xiayouPlugin = {
240
242
  conversationId,
241
243
  messageId: replyMessageId,
242
244
  replyToMessageId: inboundMessageId,
245
+ senderId,
243
246
  text: fullText,
244
247
  streamStatus: "end",
245
248
  timestamp: Date.now(),
@@ -273,34 +276,52 @@ export const xiayouPlugin = {
273
276
  },
274
277
  },
275
278
 
276
- // ── Outbound 出站 ──────────────────────────────────
279
+ // ── Outbound 出站(符合 ChannelPluginOutbound 接口)──────
277
280
  outbound: {
278
- send: async ({ to, payload }: any) => {
281
+ deliveryMode: "direct" as const,
282
+ textChunkLimit: 2000,
283
+
284
+ sendText: async ({ to, text, accountId, replyToId, cfg }: any) => {
279
285
  if (!_client || !_client.isConnected()) {
280
- return { ok: false, error: "xiaoyou: not connected" };
286
+ return { channel: "xiaoyou", error: new Error("xiaoyou: not connected") };
281
287
  }
282
288
 
283
- const baseReply = {
289
+ const reply = {
284
290
  type: "reply" as const,
285
- conversationId: to,
291
+ conversationId: to || "cron-delivery",
286
292
  messageId: `xiaoyou-${Date.now()}`,
287
- agentId: payload.agentId,
293
+ replyToMessageId: replyToId,
294
+ senderId: to,
295
+ source: "scheduled_task" as const,
296
+ text: text,
288
297
  timestamp: Date.now(),
289
298
  };
290
299
 
291
- if (payload.kind === "text") {
292
- _client.sendReply({ ...baseReply, text: payload.text });
293
- return { ok: true };
294
- }
295
- if (payload.kind === "image" || payload.kind === "file") {
296
- _client.sendReply({
297
- ...baseReply,
298
- text: payload.caption ?? "",
299
- mediaUrls: [payload.url ?? payload.filePath],
300
- });
301
- return { ok: true };
300
+ _client.sendReply(reply);
301
+ console.log(`[xiaoyou][outbound] sendText to=${to}, text=${text?.substring(0, 50)}`);
302
+ return { channel: "xiaoyou", messageId: reply.messageId };
303
+ },
304
+
305
+ sendMedia: async ({ to, text, mediaUrl, accountId, replyToId, cfg }: any) => {
306
+ if (!_client || !_client.isConnected()) {
307
+ return { channel: "xiaoyou", error: new Error("xiaoyou: not connected") };
302
308
  }
303
- return { ok: false, error: `Unsupported payload kind: ${payload.kind}` };
309
+
310
+ const reply = {
311
+ type: "reply" as const,
312
+ conversationId: to || "cron-delivery",
313
+ messageId: `xiaoyou-${Date.now()}`,
314
+ replyToMessageId: replyToId,
315
+ senderId: to,
316
+ source: "scheduled_task" as const,
317
+ text: text ?? "",
318
+ mediaUrls: mediaUrl ? [mediaUrl] : [],
319
+ timestamp: Date.now(),
320
+ };
321
+
322
+ _client.sendReply(reply);
323
+ console.log(`[xiaoyou][outbound] sendMedia to=${to}`);
324
+ return { channel: "xiaoyou", messageId: reply.messageId };
304
325
  },
305
326
  },
306
327
 
package/src/types.ts CHANGED
@@ -60,10 +60,13 @@ export type OutboundReply = {
60
60
  conversationId: string;
61
61
  messageId: string;
62
62
  replyToMessageId?: string;
63
+ senderId?: string;
63
64
  text: string;
64
65
  mediaUrls?: string[];
65
66
  agentId?: string;
66
67
  timestamp: number;
68
+ /** 消息来源标识:scheduled_task=定时任务推送,不传=正常对话回复 */
69
+ source?: "scheduled_task";
67
70
  /** 流式标记:chunk=增量片段, end=流结束, 不传=一次性完整回复 */
68
71
  streamStatus?: StreamStatus;
69
72
  /** 流式片段序号(仅 streamStatus="chunk" 时有值,从 0 开始) */