openclaw-pincer 0.3.3 → 0.3.5
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/dist/src/channel.js +44 -2
- package/package.json +1 -1
- package/src/channel.ts +46 -2
package/dist/src/channel.js
CHANGED
|
@@ -247,6 +247,12 @@ function handleMessage(config, ctx, msg) {
|
|
|
247
247
|
const roomId = data.room_id ?? msg.room_id ?? "";
|
|
248
248
|
if (sender === config.agentId || !content)
|
|
249
249
|
return;
|
|
250
|
+
// Mention-only: only respond when @agentName or @all (prevents echo loops)
|
|
251
|
+
const agentName = config.agentName ?? "";
|
|
252
|
+
const isMentioned = agentName && content.includes(`@${agentName}`);
|
|
253
|
+
const isBroadcast = content.includes("@all") || content.includes("@所有人");
|
|
254
|
+
if (!isMentioned && !isBroadcast)
|
|
255
|
+
return;
|
|
250
256
|
console.log(`[openclaw-pincer] 💬 Room msg from ${sender.slice(0, 8)}: ${content.slice(0, 60)}`);
|
|
251
257
|
dispatchToAgent(config, ctx, runtime, sender, content, roomId);
|
|
252
258
|
return;
|
|
@@ -281,10 +287,46 @@ function dispatchToAgent(config, ctx, runtime, senderId, text, roomId) {
|
|
|
281
287
|
accountId: ctx.accountId,
|
|
282
288
|
peer,
|
|
283
289
|
});
|
|
290
|
+
// Build structured route header so the agent knows exactly how to respond
|
|
291
|
+
// and which API endpoints to call for opincer operations.
|
|
292
|
+
const baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
293
|
+
const routeHeader = roomId
|
|
294
|
+
? [
|
|
295
|
+
`[Pincer Route]`,
|
|
296
|
+
`type: room`,
|
|
297
|
+
`room_id: ${roomId}`,
|
|
298
|
+
`from_agent_id: ${senderId}`,
|
|
299
|
+
`my_agent_id: ${config.agentId}`,
|
|
300
|
+
``,
|
|
301
|
+
`[Pincer Room msg from ${senderId}]`,
|
|
302
|
+
].join("\n")
|
|
303
|
+
: [
|
|
304
|
+
`[Pincer Route]`,
|
|
305
|
+
`type: dm`,
|
|
306
|
+
`from_agent_id: ${senderId}`,
|
|
307
|
+
`my_agent_id: ${config.agentId}`,
|
|
308
|
+
``,
|
|
309
|
+
`[Pincer DM from ${senderId}]`,
|
|
310
|
+
].join("\n");
|
|
311
|
+
const replyHint = roomId
|
|
312
|
+
? [
|
|
313
|
+
``,
|
|
314
|
+
`To reply in this room, POST to ${baseUrl}/api/v1/rooms/${roomId}/messages:`,
|
|
315
|
+
` {"sender_agent_id": "${config.agentId}", "content": "<reply>"}`,
|
|
316
|
+
` Header: X-API-Key: ${config.token}`,
|
|
317
|
+
`Do NOT reply via Feishu or other messaging channels.`,
|
|
318
|
+
].join("\n")
|
|
319
|
+
: [
|
|
320
|
+
``,
|
|
321
|
+
`To reply via DM, POST to ${baseUrl}/api/v1/messages/send:`,
|
|
322
|
+
` {"from_agent_id": "${config.agentId}", "to_agent_id": "${senderId}", "payload": {"text": "<reply>"}}`,
|
|
323
|
+
` Header: X-API-Key: ${config.token}`,
|
|
324
|
+
].join("\n");
|
|
325
|
+
const agentText = `${routeHeader}\n${text}${replyHint}`;
|
|
284
326
|
runtime.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
285
327
|
ctx: {
|
|
286
|
-
Body:
|
|
287
|
-
BodyForAgent:
|
|
328
|
+
Body: agentText,
|
|
329
|
+
BodyForAgent: agentText,
|
|
288
330
|
From: senderId,
|
|
289
331
|
SessionKey: route.sessionKey,
|
|
290
332
|
Channel: "openclaw-pincer",
|
package/package.json
CHANGED
package/src/channel.ts
CHANGED
|
@@ -277,6 +277,11 @@ function handleMessage(config: PincerConfig, ctx: any, msg: any) {
|
|
|
277
277
|
const content = data.content ?? "";
|
|
278
278
|
const roomId = data.room_id ?? msg.room_id ?? "";
|
|
279
279
|
if (sender === config.agentId || !content) return;
|
|
280
|
+
// Mention-only: only respond when @agentName or @all (prevents echo loops)
|
|
281
|
+
const agentName = config.agentName ?? "";
|
|
282
|
+
const isMentioned = agentName && content.includes(`@${agentName}`);
|
|
283
|
+
const isBroadcast = content.includes("@all") || content.includes("@所有人");
|
|
284
|
+
if (!isMentioned && !isBroadcast) return;
|
|
280
285
|
console.log(`[openclaw-pincer] 💬 Room msg from ${sender.slice(0, 8)}: ${content.slice(0, 60)}`);
|
|
281
286
|
dispatchToAgent(config, ctx, runtime, sender, content, roomId);
|
|
282
287
|
return;
|
|
@@ -320,10 +325,49 @@ function dispatchToAgent(
|
|
|
320
325
|
peer,
|
|
321
326
|
});
|
|
322
327
|
|
|
328
|
+
// Build structured route header so the agent knows exactly how to respond
|
|
329
|
+
// and which API endpoints to call for opincer operations.
|
|
330
|
+
const baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
331
|
+
const routeHeader = roomId
|
|
332
|
+
? [
|
|
333
|
+
`[Pincer Route]`,
|
|
334
|
+
`type: room`,
|
|
335
|
+
`room_id: ${roomId}`,
|
|
336
|
+
`from_agent_id: ${senderId}`,
|
|
337
|
+
`my_agent_id: ${config.agentId}`,
|
|
338
|
+
``,
|
|
339
|
+
`[Pincer Room msg from ${senderId}]`,
|
|
340
|
+
].join("\n")
|
|
341
|
+
: [
|
|
342
|
+
`[Pincer Route]`,
|
|
343
|
+
`type: dm`,
|
|
344
|
+
`from_agent_id: ${senderId}`,
|
|
345
|
+
`my_agent_id: ${config.agentId}`,
|
|
346
|
+
``,
|
|
347
|
+
`[Pincer DM from ${senderId}]`,
|
|
348
|
+
].join("\n");
|
|
349
|
+
|
|
350
|
+
const replyHint = roomId
|
|
351
|
+
? [
|
|
352
|
+
``,
|
|
353
|
+
`To reply in this room, POST to ${baseUrl}/api/v1/rooms/${roomId}/messages:`,
|
|
354
|
+
` {"sender_agent_id": "${config.agentId}", "content": "<reply>"}`,
|
|
355
|
+
` Header: X-API-Key: ${config.token}`,
|
|
356
|
+
`Do NOT reply via Feishu or other messaging channels.`,
|
|
357
|
+
].join("\n")
|
|
358
|
+
: [
|
|
359
|
+
``,
|
|
360
|
+
`To reply via DM, POST to ${baseUrl}/api/v1/messages/send:`,
|
|
361
|
+
` {"from_agent_id": "${config.agentId}", "to_agent_id": "${senderId}", "payload": {"text": "<reply>"}}`,
|
|
362
|
+
` Header: X-API-Key: ${config.token}`,
|
|
363
|
+
].join("\n");
|
|
364
|
+
|
|
365
|
+
const agentText = `${routeHeader}\n${text}${replyHint}`;
|
|
366
|
+
|
|
323
367
|
runtime.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
324
368
|
ctx: {
|
|
325
|
-
Body:
|
|
326
|
-
BodyForAgent:
|
|
369
|
+
Body: agentText,
|
|
370
|
+
BodyForAgent: agentText,
|
|
327
371
|
From: senderId,
|
|
328
372
|
SessionKey: route.sessionKey,
|
|
329
373
|
Channel: "openclaw-pincer",
|