@masons/agent-network 0.4.25 → 0.4.26

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/channel.d.ts CHANGED
@@ -1,6 +1,14 @@
1
1
  import type { AgentNetworkAccount } from "./config-schema.js";
2
2
  /** Get the stored owner Passport address (first is_owner visit). */
3
3
  export declare function getOwnerPassportAddress(): string | null;
4
+ /**
5
+ * Consume the identity linking nudge flag. Destructive read — returns true
6
+ * at most once per detection cycle. Called by before_prompt_build on
7
+ * non-Passport owner turns to deliver the nudge where the action is relevant.
8
+ */
9
+ export declare function consumeIdentityLinkingNudge(): boolean;
10
+ /** Test-only: set the nudge flag without going through the detection path. */
11
+ export declare function _setNudgePendingForTesting(value: boolean): void;
4
12
  interface ChannelMeta {
5
13
  name: string;
6
14
  description: string;
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AA2B9D,oEAAoE;AACpE,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAEvD;AAUD,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,oBAAoB,CAAC,CAAC;IAC9B,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC;IACvD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;IACpE,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;IACjE,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAC/D;AAED,UAAU,sBAAsB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,sBAAsB;IAC9B,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC9C,QAAQ,CAAC,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACzE;AAED,UAAU,qBAAqB,CAAC,CAAC,GAAG,OAAO;IACzC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAuDD,UAAU,qBAAqB,CAAC,CAAC,GAAG,OAAO;IACzC,YAAY,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,WAAW,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,UAAU,yBAAyB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;IAClD,QAAQ,EAAE,sBAAsB,CAAC;IACjC,OAAO,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;CACrD;AAsQD,eAAO,MAAM,mBAAmB,EAAE,yBAwNjC,CAAC"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAkC9D,oEAAoE;AACpE,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAIrD;AAED,8EAA8E;AAC9E,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE/D;AAUD,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,oBAAoB,CAAC,CAAC;IAC9B,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC;IACvD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;IACpE,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;IACjE,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAC/D;AAED,UAAU,sBAAsB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,sBAAsB;IAC9B,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC9C,QAAQ,CAAC,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACzE;AAED,UAAU,qBAAqB,CAAC,CAAC,GAAG,OAAO;IACzC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAuDD,UAAU,qBAAqB,CAAC,CAAC,GAAG,OAAO;IACzC,YAAY,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,WAAW,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,UAAU,yBAAyB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;IAClD,QAAQ,EAAE,sBAAsB,CAAC;IACjC,OAAO,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;CACrD;AA8PD,eAAO,MAAM,mBAAmB,EAAE,yBAyNjC,CAAC"}
package/dist/channel.js CHANGED
@@ -5,7 +5,6 @@ import { ConnectorClient } from "./connector-client.js";
5
5
  import { ConversationManager } from "./conversation-manager.js";
6
6
  import { clearEnvironmentContext } from "./environment-context.js";
7
7
  import { extractHandleFromAddress } from "./handle-utils.js";
8
- import { ownerNotesQueue } from "./owner-notes.js";
9
8
  import { clearOwnerState, isOwnerAddress, markOwnerAddress, setCurrentTurnIsOwner, } from "./owner-session-state.js";
10
9
  import { setCurrentTurnSender } from "./turn-context.js";
11
10
  import { checkForUpdate } from "./update-check.js";
@@ -14,6 +13,13 @@ const dbg = createDebug("agent-network:channel");
14
13
  // Reset on startAccount(). isIdentityLinksConfigured() provides the
15
14
  // cross-restart idempotency (checks config file).
16
15
  let notificationAttempted = false;
16
+ // Identity linking nudge — set when the owner first visits via Passport and
17
+ // cross-channel linking is available. Delivered on the owner's next
18
+ // non-Passport turn (Telegram/Feishu) where the linking action is relevant.
19
+ // Separate from ownerNotesQueue to avoid the Passport drain deadlock (#1158):
20
+ // the queue drains on ALL owner turns (including Passport), but this nudge
21
+ // only fires on non-Passport owner turns.
22
+ let identityLinkingNudgePending = false;
17
23
  // Owner's Passport address: recorded on first is_owner MESSAGE_RECEIVED.
18
24
  // Used by masons_link_identity tool to auto-include the Passport entry.
19
25
  let storedOwnerPassportAddress = null;
@@ -21,6 +27,21 @@ let storedOwnerPassportAddress = null;
21
27
  export function getOwnerPassportAddress() {
22
28
  return storedOwnerPassportAddress;
23
29
  }
30
+ /**
31
+ * Consume the identity linking nudge flag. Destructive read — returns true
32
+ * at most once per detection cycle. Called by before_prompt_build on
33
+ * non-Passport owner turns to deliver the nudge where the action is relevant.
34
+ */
35
+ export function consumeIdentityLinkingNudge() {
36
+ if (!identityLinkingNudgePending)
37
+ return false;
38
+ identityLinkingNudgePending = false;
39
+ return true;
40
+ }
41
+ /** Test-only: set the nudge flag without going through the detection path. */
42
+ export function _setNudgePendingForTesting(value) {
43
+ identityLinkingNudgePending = value;
44
+ }
24
45
  // --- Sender identity ---
25
46
  /**
26
47
  * Extract a human-readable name from the sender's metadata.
@@ -98,24 +119,17 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
98
119
  storedOwnerPassportAddress = fromAddress;
99
120
  dbg("recorded owner Passport address: %s", fromAddress);
100
121
  }
101
- // --- dmScope-aware notification (2026-03-26, #986 redesign) ---
102
- // Notify the owner about cross-channel identity linking availability.
103
- // Notification is:
104
- // - Skipped in "main" mode (linking has no effect — Gateway skips resolveLinkedPeerId)
105
- // - Skipped if identityLinks already configured (already linked)
106
- // - Sent once per startAccount lifecycle (in-memory idempotency)
107
- // Content is channel-agnostic and language-neutral (semantic event, not identity claim).
122
+ // --- dmScope-aware identity linking nudge (#986 redesign, #1158 fix) ---
123
+ // Detect that identity linking is available but not configured.
124
+ // Sets a flag (NOT enqueued into ownerNotesQueue) for delivery on the
125
+ // owner's next non-Passport turn, where the linking action is relevant.
126
+ // Separated from the queue to avoid the Passport drain deadlock (#1158).
108
127
  if (getDmScope() !== "main" &&
109
128
  !isIdentityLinksConfigured() &&
110
129
  !notificationAttempted) {
111
130
  notificationAttempted = true;
112
- ownerNotesQueue.enqueue({
113
- content: "Owner visited via Passport (verified). " +
114
- "Cross-channel identity linking is available but not configured. " +
115
- "The owner can link their identity across channels so conversations share context.",
116
- timestamp: Date.now(),
117
- });
118
- dbg("queued identity linking notification (dmScope=%s)", getDmScope());
131
+ identityLinkingNudgePending = true;
132
+ dbg("identity linking nudge pending (dmScope=%s)", getDmScope());
119
133
  }
120
134
  }
121
135
  setCurrentTurnIsOwner(isOwnerAddress(fromAddress));
@@ -294,6 +308,7 @@ export const agentNetworkChannel = {
294
308
  dbg("starting account %s", ctx.accountId);
295
309
  // Reset per-session state
296
310
  notificationAttempted = false;
311
+ identityLinkingNudgePending = false;
297
312
  storedOwnerPassportAddress = null;
298
313
  // Defensive: clear stale singletons from a previous cycle.
299
314
  // The abort handler intentionally leaves them alive for in-flight tool
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA4HA,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;CAyVhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAiJA,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;CAkWhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/plugin.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Loaded by OpenClaw Gateway via the "openclaw.extensions" field in package.json.
3
3
  // NOT imported by index.ts to avoid pulling ws/typebox into Next.js app bundles.
4
4
  import pluginManifest from "../openclaw.plugin.json" with { type: "json" };
5
- import { agentNetworkChannel } from "./channel.js";
5
+ import { agentNetworkChannel, consumeIdentityLinkingNudge } from "./channel.js";
6
6
  import { configureInteractive } from "./cli-setup.js";
7
7
  import { detectPendingState, getConversationManager, getDmScope, getStateCacheGeneration, initPluginRuntime, } from "./config.js";
8
8
  import { getAgentIdentity } from "./environment-context.js";
@@ -30,6 +30,24 @@ function formatTimeAgo(timestamp) {
30
30
  const days = Math.floor(hours / 24);
31
31
  return `${days}d ago`;
32
32
  }
33
+ /**
34
+ * Drain ownerNotesQueue and format into an "[Agent Network — Updates]" block.
35
+ * Returns null if the queue was empty.
36
+ */
37
+ function drainAndFormatNotes(reportInstruction) {
38
+ const notes = ownerNotesQueue.drain();
39
+ if (notes.length === 0)
40
+ return null;
41
+ const lines = notes.map((n) => {
42
+ const fromStr = n.from ? `@${n.from}` : "agent";
43
+ const timeStr = formatTimeAgo(n.timestamp);
44
+ return `• ${fromStr} (${timeStr}): "${n.content}"`;
45
+ });
46
+ return ("[Agent Network — Updates]\n" +
47
+ "The following happened on the agent network since your last turn:\n" +
48
+ `${lines.join("\n")}\n` +
49
+ reportInstruction);
50
+ }
33
51
  /** Max active interactions to inject into context to avoid noise. */
34
52
  const MAX_INTERACTIONS = 5;
35
53
  /**
@@ -268,12 +286,10 @@ const plugin = {
268
286
  // Owner visiting via Passport — no routing warning needed.
269
287
  // The LLM's text reply goes to the owner (the visitor IS the owner).
270
288
  //
271
- // DO NOT drain ownerNotesQueue here (#986). Notes are meant for
272
- // non-Passport channels (Telegram/Feishu) where the owner can act
273
- // on them e.g., identity linking notifications require the owner
274
- // to provide their Telegram ID, which only makes sense on Telegram.
275
- // Draining here would consume notifications on the same turn that
276
- // generated them, leaving nothing for the target channel.
289
+ // Drain ownerNotesQueue (#1158). General notes from network turns
290
+ // should reach the owner wherever they are — including Passport.
291
+ // The identity linking nudge is handled separately (boolean flag
292
+ // in channel.ts) and delivered only on non-Passport owner turns.
277
293
  dynamicContext =
278
294
  "[Agent Network — Owner via Passport] Your owner (Principal) is talking to you " +
279
295
  "via Passport (your public web chat page where visitors can reach you). " +
@@ -281,6 +297,10 @@ const plugin = {
281
297
  "Your text reply goes directly to your owner. " +
282
298
  "You can share information freely — no information boundary applies. " +
283
299
  "Do NOT use masons_note_for_owner — your owner is right here.";
300
+ const notesBlock = drainAndFormatNotes("Report these to your owner now — they are right here.");
301
+ if (notesBlock) {
302
+ dynamicContext += `\n\n${notesBlock}`;
303
+ }
284
304
  }
285
305
  else {
286
306
  // Turn triggered by a remote agent/stranger — routing warning +
@@ -317,18 +337,21 @@ const plugin = {
317
337
  }
318
338
  else {
319
339
  // Owner turn (or other channel) — drain pending notes if any.
320
- const notes = ownerNotesQueue.drain();
321
- if (notes.length > 0) {
322
- const lines = notes.map((n) => {
323
- const fromStr = n.from ? `@${n.from}` : "agent";
324
- const timeStr = formatTimeAgo(n.timestamp);
325
- return `• ${fromStr} (${timeStr}): "${n.content}"`;
326
- });
327
- dynamicContext =
328
- "[Agent Network Updates]\n" +
329
- "The following happened on the agent network since your last turn:\n" +
330
- `${lines.join("\n")}\n` +
331
- "Report these to your owner.";
340
+ const notesBlock = drainAndFormatNotes("Report these to your owner.");
341
+ if (notesBlock) {
342
+ dynamicContext = notesBlock;
343
+ }
344
+ // Identity linking nudge — delivered here (non-Passport owner turn)
345
+ // where the linking action is relevant (#1158).
346
+ if (consumeIdentityLinkingNudge()) {
347
+ const nudge = "[Agent Network — Identity Linking Available]\n" +
348
+ "Your owner visited via Passport (verified). " +
349
+ "Cross-channel identity linking is available but not configured. " +
350
+ "The owner can link their identity across channels so conversations share context. " +
351
+ "Suggest using masons_link_identity.";
352
+ dynamicContext = dynamicContext
353
+ ? `${dynamicContext}\n\n${nudge}`
354
+ : nudge;
332
355
  }
333
356
  // Append interaction space on owner turns too (#873).
334
357
  // Gives the agent awareness of active network interactions.
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Plugin version — must match package.json. Validated by prepublishOnly. */
2
- export declare const PLUGIN_VERSION = "0.4.25";
2
+ export declare const PLUGIN_VERSION = "0.4.26";
3
3
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Plugin version — must match package.json. Validated by prepublishOnly. */
2
- export const PLUGIN_VERSION = "0.4.25";
2
+ export const PLUGIN_VERSION = "0.4.26";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masons/agent-network",
3
- "version": "0.4.25",
3
+ "version": "0.4.26",
4
4
  "description": "MASONS plugin for OpenClaw — connect your agent to the agent network",
5
5
  "license": "MIT",
6
6
  "author": "MASONS.ai <hello@masons.ai> (https://masons.ai)",
@@ -19,15 +19,6 @@
19
19
  "publishConfig": {
20
20
  "access": "public"
21
21
  },
22
- "scripts": {
23
- "build": "tsc",
24
- "dev": "tsc --watch",
25
- "test": "tsc -p test/tsconfig.json && node --test --loader ts-node/esm test/**/*.test.ts",
26
- "lint": "biome check",
27
- "format": "biome format --write",
28
- "prepublishOnly": "bash scripts/check-version.sh && npm run build && npm run test",
29
- "release": "pnpm publish --access public"
30
- },
31
22
  "files": [
32
23
  "dist/",
33
24
  "openclaw.plugin.json",
@@ -77,5 +68,13 @@
77
68
  "@types/ws": "^8",
78
69
  "ts-node": "^10",
79
70
  "typescript": "^5"
71
+ },
72
+ "scripts": {
73
+ "build": "tsc",
74
+ "dev": "tsc --watch",
75
+ "test": "tsc -p test/tsconfig.json && node --test --loader ts-node/esm test/**/*.test.ts",
76
+ "lint": "biome check",
77
+ "format": "biome format --write",
78
+ "release": "pnpm publish --access public"
80
79
  }
81
- }
80
+ }