@essentialai/cogent-plugin 3.21.9 β†’ 3.23.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.
@@ -171,6 +171,9 @@ export function selectUnanswered({ messages, me, scope }) {
171
171
  // is explicitly a failure is never an answer β€” check that first, it is stronger than any
172
172
  // string match.
173
173
  if (m.success === false || m.error) continue;
174
+ // ...but in CLOUD mode those two fields are fabricated by the relay (always true/null),
175
+ // so the guard above never fires and the notice must be recognised by its own text.
176
+ if (isBridgeFailureNotice(m.message)) continue;
174
177
  if (isMetaNonAnswer(m.message)) continue;
175
178
  if (m.toPeerId === "*") dequeueOldestBroadcast();
176
179
  else dequeueFrom(m.toPeerId);
@@ -187,6 +190,38 @@ export function selectUnanswered({ messages, me, scope }) {
187
190
  return { items: items.map(({ _i, ...m }) => m) };
188
191
  }
189
192
 
193
+ /**
194
+ * Is this outbound of mine one of the BRIDGE's own "I could not wake that agent" notices, rather
195
+ * than an answer I wrote?
196
+ *
197
+ * πŸ”΄ WHY A STRING MATCH, WHEN THE LINE ABOVE SAYS success IS STRONGER. It is stronger β€” in LOCAL
198
+ * mode. In CLOUD mode `success`/`error` do not survive the wire at all: HttpBackend.recordMessage
199
+ * posts only {fromPeerId, toPeerId, message} (+isRelayEcho/attachments) because the relay's POST
200
+ * body schema is .strict() and rejects anything else (server/src/routes/messages.ts:57-80), and
201
+ * the relay then FABRICATES `success: true, error: null` on every stored record (:193-195) β€”
202
+ * hardcoded since 2026-02-13. So `m.success === false || m.error` is unreachable for every cloud
203
+ * agent, which is all of them by default since 3.14.0.
204
+ *
205
+ * The effect was that rail B's own failure notice β€” "⚠️ Cogent could not capture a reply…" β€” read
206
+ * as an answer and DEQUEUED the pending message, so rail C went silent on precisely the wakes
207
+ * that failed: blind to the miss it exists to catch. Reproduced by three tests in
208
+ * check-on-stop.lib.test.mjs before this existed.
209
+ *
210
+ * Anchored at the start and restricted to strings the bridge itself generates (auto-relay.ts:1082,
211
+ * :1165, :1245, :1248 and buildStatusNotice's `[cogent:*]` markers), so a genuine answer that
212
+ * merely mentions Cogent is unaffected. Kept in sync with isBridgeNotice() in
213
+ * scripts/wake-matrix-lib.mjs β€” the hooks are zero-dependency standalone .mjs shipped to users and
214
+ * cannot import from src/, so this predicate is deliberately duplicated rather than shared.
215
+ */
216
+ export function isBridgeFailureNotice(text) {
217
+ const t = String(text ?? "").trimStart();
218
+ return (
219
+ /^\[cogent:(queued|processing|needs-manual|failed)\]/.test(t) ||
220
+ /^\u26a0\ufe0f\s*Cogent could not /.test(t) ||
221
+ /^\ud83d\udce8\s*Queued for /.test(t)
222
+ );
223
+ }
224
+
190
225
  /**
191
226
  * Is this outbound of mine a "meta non-answer" β€” a note ABOUT answering rather than an answer?
192
227
  * (COG-20)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@essentialai/cogent-plugin",
3
- "version": "3.21.9",
3
+ "version": "3.23.0",
4
4
  "description": "Cogent β€” Claude Code plugin (skills + slash-commands + MCP server) for the cross-agent comms fabric.",
5
5
  "author": { "name": "Essential AI Solutions Ltd.", "url": "https://essentialai.uk" },
6
6
  "homepage": "https://cogent.tools",