@commonlyai/cli 0.1.5 → 0.1.6
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 +1 -1
- package/src/commands/agent.js +34 -11
package/package.json
CHANGED
package/src/commands/agent.js
CHANGED
|
@@ -502,9 +502,10 @@ export const performRun = ({
|
|
|
502
502
|
// did, its final CLI text is a narration/log — echoing it would duplicate
|
|
503
503
|
// the message and re-fire any @mention. This is the wrapper-side guarantee
|
|
504
504
|
// that a deliberate multi-post ("on it…" then "…done") is never doubled,
|
|
505
|
-
// without relying on the agent to emit NO_REPLY.
|
|
506
|
-
//
|
|
507
|
-
//
|
|
505
|
+
// without relying on the agent to emit NO_REPLY. Against a server that
|
|
506
|
+
// stamps `self` this is exact; against an older one it degrades to the
|
|
507
|
+
// legacy any-bot test, where a concurrent post by another agent can
|
|
508
|
+
// suppress a genuine reply (#757).
|
|
508
509
|
const snapshotMessages = async () => {
|
|
509
510
|
try {
|
|
510
511
|
const { messages = [] } = await client.get(
|
|
@@ -551,18 +552,33 @@ export const performRun = ({
|
|
|
551
552
|
// reply via its output) the wrapper delivers the text as before.
|
|
552
553
|
const replyText = (result.text || '').trim();
|
|
553
554
|
let agentPostedItself = false;
|
|
555
|
+
let suppressedBy = null;
|
|
554
556
|
if (preSpawnIds) {
|
|
555
557
|
const postSpawn = await snapshotMessages();
|
|
556
558
|
if (postSpawn) {
|
|
559
|
+
// The server stamps each message with `self` when it knows who is
|
|
560
|
+
// asking. Trust that over any local guess: the wrapper cannot derive
|
|
561
|
+
// its own bot username reliably (the server applies LEGACY_AGENT_MAP
|
|
562
|
+
// and an owner-scoped instanceId), and a wrong guess double-posts.
|
|
563
|
+
const serverKnowsSelf = postSpawn.some((m) => typeof m.self === 'boolean');
|
|
557
564
|
for (const m of postSpawn) {
|
|
558
|
-
|
|
559
|
-
//
|
|
560
|
-
//
|
|
561
|
-
//
|
|
562
|
-
//
|
|
563
|
-
//
|
|
564
|
-
if (!
|
|
565
|
+
if (preSpawnIds.has(String(m._id || m.id))) continue;
|
|
566
|
+
// A new human-authored message must NEVER suppress the echo: it is
|
|
567
|
+
// either a human typing mid-turn, or the agent misusing an operator
|
|
568
|
+
// CLI profile / human token (the 2026-07-22 as-operator attribution
|
|
569
|
+
// incident) — in both cases the wrapper still delivers the reply
|
|
570
|
+
// under the agent's own identity.
|
|
571
|
+
if (!m.isBot) continue;
|
|
572
|
+
// With `self`, only THIS agent's own post suppresses. Without it (an
|
|
573
|
+
// older server), fall back to the legacy any-bot test — which drops
|
|
574
|
+
// this agent's reply whenever another agent answers first (#757).
|
|
575
|
+
if (serverKnowsSelf ? m.self === true : true) {
|
|
565
576
|
agentPostedItself = true;
|
|
577
|
+
suppressedBy = {
|
|
578
|
+
id: String(m._id || m.id),
|
|
579
|
+
author: m.username || 'unknown',
|
|
580
|
+
basis: serverKnowsSelf ? 'self' : 'legacy-any-bot',
|
|
581
|
+
};
|
|
566
582
|
break;
|
|
567
583
|
}
|
|
568
584
|
}
|
|
@@ -571,7 +587,14 @@ export const performRun = ({
|
|
|
571
587
|
if (!replyText || replyText === 'NO_REPLY') {
|
|
572
588
|
log(`[${event.type}] no wrapper-post (${replyText === 'NO_REPLY' ? 'NO_REPLY' : 'empty output'})`);
|
|
573
589
|
} else if (agentPostedItself) {
|
|
574
|
-
|
|
590
|
+
// Name the message that caused the suppression. A silently dropped reply
|
|
591
|
+
// is invisible to everyone; #757 went unnoticed precisely because this
|
|
592
|
+
// line said only "posted via tool" with no way to tell whose post it saw.
|
|
593
|
+
log(
|
|
594
|
+
`[${event.type}] agent posted via tool this turn — not echoing CLI output `
|
|
595
|
+
+ `(avoids double-post; matched message ${suppressedBy.id} by ${suppressedBy.author} `
|
|
596
|
+
+ `via ${suppressedBy.basis})`,
|
|
597
|
+
);
|
|
575
598
|
} else {
|
|
576
599
|
await client.post(`/api/agents/runtime/pods/${eventPodId}/messages`, {
|
|
577
600
|
content: replyText,
|