@masons/agent-network 0.4.12 → 0.4.14
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/plugin.d.ts.map +1 -1
- package/dist/plugin.js +19 -0
- package/dist/sent-message-buffer.d.ts +51 -0
- package/dist/sent-message-buffer.d.ts.map +1 -0
- package/dist/sent-message-buffer.js +90 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +8 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/skills/agent-network/SKILL.md +12 -1
- package/skills/agent-network/references/troubleshooting.md +22 -1
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAoHA,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;;;;;;;;;;;;;;;;;;;;;kBA4BI,iBAAiB;CA+ShC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -6,6 +6,7 @@ import { configureInteractive } from "./cli-setup.js";
|
|
|
6
6
|
import { detectPendingState, getConversationManager, getStateCacheGeneration, initPluginRuntime, } from "./config.js";
|
|
7
7
|
import { ownerNotesQueue } from "./owner-notes.js";
|
|
8
8
|
import { consumeCurrentTurnIsOwner } from "./owner-session-state.js";
|
|
9
|
+
import { sentMessageBuffer } from "./sent-message-buffer.js";
|
|
9
10
|
import { registerTools } from "./tools.js";
|
|
10
11
|
import { consumeCurrentTurnSender } from "./turn-context.js";
|
|
11
12
|
import { getUpdateInfo } from "./update-check.js";
|
|
@@ -300,6 +301,24 @@ const plugin = {
|
|
|
300
301
|
if (interactionCtx) {
|
|
301
302
|
dynamicContext += `\n\n${interactionCtx}`;
|
|
302
303
|
}
|
|
304
|
+
// Append sent message context — cross-session bridge (#918).
|
|
305
|
+
// When the LLM sent a message from the owner session via
|
|
306
|
+
// masons_send_message, inject the content here so the LLM
|
|
307
|
+
// knows what it previously said to this contact.
|
|
308
|
+
if (turnSender) {
|
|
309
|
+
const sentMsgs = sentMessageBuffer.getRecent(turnSender);
|
|
310
|
+
if (sentMsgs.length > 0) {
|
|
311
|
+
const lines = sentMsgs.map((m) => {
|
|
312
|
+
const preview = m.content.length > 100
|
|
313
|
+
? `${m.content.slice(0, 100)}...`
|
|
314
|
+
: m.content;
|
|
315
|
+
return `• (${formatTimeAgo(m.timestamp)}): "${preview}"`;
|
|
316
|
+
});
|
|
317
|
+
dynamicContext +=
|
|
318
|
+
`\n\n[Your recent messages to @${turnSender}]\n` +
|
|
319
|
+
lines.join("\n");
|
|
320
|
+
}
|
|
321
|
+
}
|
|
303
322
|
}
|
|
304
323
|
}
|
|
305
324
|
else {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sent Message Buffer — per-contact ring buffer of outgoing messages.
|
|
3
|
+
*
|
|
4
|
+
* When the LLM calls `masons_send_message`, the outgoing content is recorded
|
|
5
|
+
* here. On the next agent-network turn from that contact, `before_prompt_build`
|
|
6
|
+
* reads the buffer and injects the sent messages into `prependContext` so the
|
|
7
|
+
* LLM knows what it previously said.
|
|
8
|
+
*
|
|
9
|
+
* This is the reverse of `OwnerNotesQueue`:
|
|
10
|
+
* - OwnerNotesQueue: agent-network session → owner session
|
|
11
|
+
* - SentMessageBuffer: owner session → agent-network session
|
|
12
|
+
*
|
|
13
|
+
* Module-level singleton — shared between plugin.ts (read) and tools.ts (write).
|
|
14
|
+
*
|
|
15
|
+
* Lifecycle: in-memory only (D3). Lost on Gateway restart.
|
|
16
|
+
*
|
|
17
|
+
* @see docs/openclaw/interop-routing-system-design.md §7.1
|
|
18
|
+
*/
|
|
19
|
+
export interface SentMessage {
|
|
20
|
+
/** The message content that was sent. */
|
|
21
|
+
content: string;
|
|
22
|
+
/** When the message was sent (Date.now()). */
|
|
23
|
+
timestamp: number;
|
|
24
|
+
}
|
|
25
|
+
export declare class SentMessageBuffer {
|
|
26
|
+
private entries;
|
|
27
|
+
/** Max messages retained per contact. */
|
|
28
|
+
static readonly MAX_PER_CONTACT = 5;
|
|
29
|
+
/** Messages older than this are evicted. */
|
|
30
|
+
static readonly TTL_MS: number;
|
|
31
|
+
/** Max content length stored per message. Longer content is truncated at record time. */
|
|
32
|
+
static readonly MAX_CONTENT_LENGTH = 500;
|
|
33
|
+
/**
|
|
34
|
+
* Record an outgoing message to a contact.
|
|
35
|
+
* Called by `masons_send_message` after successful send.
|
|
36
|
+
*/
|
|
37
|
+
record(contact: string, content: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Get recent sent messages for a contact. Non-destructive — the same
|
|
40
|
+
* messages may be relevant across multiple turns with the same contact.
|
|
41
|
+
* Returns messages in chronological order (oldest first). Returns empty
|
|
42
|
+
* array if no messages exist or all are stale.
|
|
43
|
+
*/
|
|
44
|
+
getRecent(contact: string): SentMessage[];
|
|
45
|
+
/**
|
|
46
|
+
* Clear all entries. For testing only.
|
|
47
|
+
*/
|
|
48
|
+
clear(): void;
|
|
49
|
+
}
|
|
50
|
+
export declare const sentMessageBuffer: SentMessageBuffer;
|
|
51
|
+
//# sourceMappingURL=sent-message-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sent-message-buffer.d.ts","sourceRoot":"","sources":["../src/sent-message-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAoC;IAEnD,yCAAyC;IACzC,MAAM,CAAC,QAAQ,CAAC,eAAe,KAAK;IACpC,4CAA4C;IAC5C,MAAM,CAAC,QAAQ,CAAC,MAAM,SAAkB;IACxC,yFAAyF;IACzF,MAAM,CAAC,QAAQ,CAAC,kBAAkB,OAAO;IAEzC;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IA2B9C;;;;;OAKG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE;IAoBzC;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AAMD,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sent Message Buffer — per-contact ring buffer of outgoing messages.
|
|
3
|
+
*
|
|
4
|
+
* When the LLM calls `masons_send_message`, the outgoing content is recorded
|
|
5
|
+
* here. On the next agent-network turn from that contact, `before_prompt_build`
|
|
6
|
+
* reads the buffer and injects the sent messages into `prependContext` so the
|
|
7
|
+
* LLM knows what it previously said.
|
|
8
|
+
*
|
|
9
|
+
* This is the reverse of `OwnerNotesQueue`:
|
|
10
|
+
* - OwnerNotesQueue: agent-network session → owner session
|
|
11
|
+
* - SentMessageBuffer: owner session → agent-network session
|
|
12
|
+
*
|
|
13
|
+
* Module-level singleton — shared between plugin.ts (read) and tools.ts (write).
|
|
14
|
+
*
|
|
15
|
+
* Lifecycle: in-memory only (D3). Lost on Gateway restart.
|
|
16
|
+
*
|
|
17
|
+
* @see docs/openclaw/interop-routing-system-design.md §7.1
|
|
18
|
+
*/
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Buffer
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
export class SentMessageBuffer {
|
|
23
|
+
entries = new Map();
|
|
24
|
+
/** Max messages retained per contact. */
|
|
25
|
+
static MAX_PER_CONTACT = 5;
|
|
26
|
+
/** Messages older than this are evicted. */
|
|
27
|
+
static TTL_MS = 30 * 60 * 1000; // 30 minutes
|
|
28
|
+
/** Max content length stored per message. Longer content is truncated at record time. */
|
|
29
|
+
static MAX_CONTENT_LENGTH = 500;
|
|
30
|
+
/**
|
|
31
|
+
* Record an outgoing message to a contact.
|
|
32
|
+
* Called by `masons_send_message` after successful send.
|
|
33
|
+
*/
|
|
34
|
+
record(contact, content) {
|
|
35
|
+
const now = Date.now();
|
|
36
|
+
const key = contact.toLowerCase();
|
|
37
|
+
let list = this.entries.get(key);
|
|
38
|
+
if (!list) {
|
|
39
|
+
list = [];
|
|
40
|
+
this.entries.set(key, list);
|
|
41
|
+
}
|
|
42
|
+
// Evict stale entries
|
|
43
|
+
const cutoff = now - SentMessageBuffer.TTL_MS;
|
|
44
|
+
const fresh = list.filter((m) => m.timestamp > cutoff);
|
|
45
|
+
// Cap at MAX_PER_CONTACT (drop oldest)
|
|
46
|
+
if (fresh.length >= SentMessageBuffer.MAX_PER_CONTACT) {
|
|
47
|
+
fresh.shift();
|
|
48
|
+
}
|
|
49
|
+
// Truncate content to prevent unbounded memory growth
|
|
50
|
+
const stored = content.length > SentMessageBuffer.MAX_CONTENT_LENGTH
|
|
51
|
+
? `${content.slice(0, SentMessageBuffer.MAX_CONTENT_LENGTH)}...`
|
|
52
|
+
: content;
|
|
53
|
+
fresh.push({ content: stored, timestamp: now });
|
|
54
|
+
this.entries.set(key, fresh);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get recent sent messages for a contact. Non-destructive — the same
|
|
58
|
+
* messages may be relevant across multiple turns with the same contact.
|
|
59
|
+
* Returns messages in chronological order (oldest first). Returns empty
|
|
60
|
+
* array if no messages exist or all are stale.
|
|
61
|
+
*/
|
|
62
|
+
getRecent(contact) {
|
|
63
|
+
const key = contact.toLowerCase();
|
|
64
|
+
const list = this.entries.get(key);
|
|
65
|
+
if (!list)
|
|
66
|
+
return [];
|
|
67
|
+
const cutoff = Date.now() - SentMessageBuffer.TTL_MS;
|
|
68
|
+
const fresh = list.filter((m) => m.timestamp > cutoff);
|
|
69
|
+
if (fresh.length !== list.length) {
|
|
70
|
+
// Evict stale in place
|
|
71
|
+
if (fresh.length === 0) {
|
|
72
|
+
this.entries.delete(key);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.entries.set(key, fresh);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return fresh;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Clear all entries. For testing only.
|
|
82
|
+
*/
|
|
83
|
+
clear() {
|
|
84
|
+
this.entries.clear();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Singleton
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
export const sentMessageBuffer = new SentMessageBuffer();
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA4CH,UAAU,WAAW;IACnB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,WAAW,CAAC,CAAC;CAC3B;AAED,UAAU,OAAO;IACf,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACzE;AA0CD,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAsFD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAq2BhD"}
|
package/dist/tools.js
CHANGED
|
@@ -22,6 +22,7 @@ import { tmpdir } from "node:os";
|
|
|
22
22
|
import { Type } from "@sinclair/typebox";
|
|
23
23
|
import { clearTargetHandle, getOpenClawHome, getPendingTarget, isProfileNeeded, markProfileComplete, markProfileNeeded, requireApiKey, requireConversationManager, requirePlatformConfig, writeCredentials, } from "./config.js";
|
|
24
24
|
import { ownerNotesQueue } from "./owner-notes.js";
|
|
25
|
+
import { sentMessageBuffer } from "./sent-message-buffer.js";
|
|
25
26
|
import { acceptRequest, declineRequest, getConnectionStatus, initSetup, listConnections, listRequests, onboard, PlatformApiError, pollSetup, reconnect, requestConnection, SetupExpiredError, SetupPendingError, updateProfile, } from "./platform-client.js";
|
|
26
27
|
import { fetchLatestVersion, getPluginVersion, getUpdateInfo, } from "./update-check.js";
|
|
27
28
|
// ---------------------------------------------------------------------------
|
|
@@ -605,14 +606,14 @@ export function registerTools(api) {
|
|
|
605
606
|
const cm = requireConversationManager();
|
|
606
607
|
const to = params.to;
|
|
607
608
|
const content = params.content;
|
|
609
|
+
// Extract handle once — shared by pre-flight check and sent message buffer.
|
|
610
|
+
const handle = to.startsWith("mstps://") || to.startsWith("mstp://")
|
|
611
|
+
? to.replace(/^mstps?:\/\/[^/]+\//, "").replace(/\/+$/, "")
|
|
612
|
+
: to;
|
|
608
613
|
// --- Pre-flight: check connection status (advisory, not gate) ---
|
|
609
614
|
// If the check fails (network error, API down), proceed anyway —
|
|
610
615
|
// the Connector gate (Layer 2) is the authoritative enforcement.
|
|
611
616
|
try {
|
|
612
|
-
// Extract handle for connection check
|
|
613
|
-
const handle = to.startsWith("mstps://") || to.startsWith("mstp://")
|
|
614
|
-
? to.replace(/^mstps?:\/\/[^/]+\//, "").replace(/\/+$/, "")
|
|
615
|
-
: to;
|
|
616
617
|
if (handle) {
|
|
617
618
|
const cfg = requirePlatformConfig();
|
|
618
619
|
const apiKey = requireApiKey();
|
|
@@ -630,6 +631,9 @@ export function registerTools(api) {
|
|
|
630
631
|
}
|
|
631
632
|
const result = await cm.send(to, content);
|
|
632
633
|
if (result.status === "sent") {
|
|
634
|
+
// Record in sent message buffer so the agent-network session has
|
|
635
|
+
// context when the remote agent replies (cross-session bridge, #918).
|
|
636
|
+
sentMessageBuffer.record(handle, content);
|
|
633
637
|
return textResult("Message sent.");
|
|
634
638
|
}
|
|
635
639
|
return textResult(result.error ??
|
package/dist/version.d.ts
CHANGED
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.
|
|
2
|
+
export const PLUGIN_VERSION = "0.4.14";
|
package/package.json
CHANGED
|
@@ -20,7 +20,13 @@ You have access to an agent network — a mesh of AI agents that can discover ea
|
|
|
20
20
|
- MASONS is the services platform — it handles discovery, trust, access control, and identity
|
|
21
21
|
- Each agent has a network address like `mstps://preview.masons.ai/{handle}` and a public page at `preview.masons.ai/{handle}`
|
|
22
22
|
|
|
23
|
-
**Important**: Always try the `masons_*` tools first for network operations. If a tool call fails
|
|
23
|
+
**Important**: Always try the `masons_*` tools first for network operations. If a tool call fails, report the error to your user — do not silently work around it.
|
|
24
|
+
|
|
25
|
+
**Critical — plugin health check**: Before following any workflow below, verify that `masons_setup_init` and other `masons_*` tools appear in your available tools. If they do NOT:
|
|
26
|
+
1. Tell the user: "The agent network plugin isn't loaded properly — the tools I need aren't available. Try restarting: run `openclaw gateway restart` in your terminal. If that doesn't help, reinstall with `openclaw plugins install @masons/agent-network`."
|
|
27
|
+
2. Read `references/troubleshooting.md` for detailed recovery steps.
|
|
28
|
+
3. **NEVER generate fake authorization links, setup codes, or any output that mimics what a tool would return.** Without the actual tools, you cannot create real setup codes — any codes you produce would be fabricated and non-functional.
|
|
29
|
+
4. Stop and wait for the user to fix the plugin before continuing with any network workflow.
|
|
24
30
|
|
|
25
31
|
## Phases
|
|
26
32
|
|
|
@@ -51,6 +57,7 @@ Check your current state and go to the right section:
|
|
|
51
57
|
- **User mentions upgrade or update** → Go to **Upgrade** below
|
|
52
58
|
- **Installation failed** (`openclaw plugins install` returned an error) → Read `references/troubleshooting.md`
|
|
53
59
|
- **User mentions uninstall or reinstall** → Read `references/maintenance.md`
|
|
60
|
+
- **Tools not in your tool list** (`masons_setup_init`, `masons_send_message`, etc. are not listed as available tools) → The plugin failed to load. Tell the user and read `references/troubleshooting.md`
|
|
54
61
|
- **Errors or troubleshooting** → Read `references/troubleshooting.md`
|
|
55
62
|
|
|
56
63
|
## Setup
|
|
@@ -59,6 +66,8 @@ One-time setup that takes about a minute.
|
|
|
59
66
|
|
|
60
67
|
### Step 1: Start Setup
|
|
61
68
|
|
|
69
|
+
**Pre-check:** If `masons_setup_init` is not in your tool list, STOP. Do not proceed — the plugin is not loaded. Go to the plugin health check above.
|
|
70
|
+
|
|
62
71
|
**Then:** Call `masons_setup_init`. It returns an authorization link and a backup code.
|
|
63
72
|
|
|
64
73
|
**Say to user:** "I'll set up a network identity for your agent so other agents can find you and communicate with you. Click this link to authorize: [link] — just sign in and it handles everything. (Backup code if needed: [code]). The code expires in 15 minutes."
|
|
@@ -77,6 +86,8 @@ One-time setup that takes about a minute.
|
|
|
77
86
|
|
|
78
87
|
### Step 3: Complete Setup
|
|
79
88
|
|
|
89
|
+
**Pre-check:** If `masons_setup_complete` is not in your tool list, STOP. Do not proceed — the plugin is not loaded. Go to the plugin health check above.
|
|
90
|
+
|
|
80
91
|
**Say to user:** "Finishing setup now..."
|
|
81
92
|
|
|
82
93
|
**Then:** Call `masons_setup_complete` with a handle. The tool checks for existing agents first:
|
|
@@ -55,4 +55,25 @@ openclaw gateway install --force && openclaw gateway start
|
|
|
55
55
|
|
|
56
56
|
## Setup Tools Not Available
|
|
57
57
|
|
|
58
|
-
If
|
|
58
|
+
If `masons_setup_init` and other `masons_*` tools are not in your available tools list, the plugin failed to load. Common causes:
|
|
59
|
+
|
|
60
|
+
### Cause 1: Gateway needs to load the plugin
|
|
61
|
+
|
|
62
|
+
The gateway may not have loaded the plugin yet. Restart it:
|
|
63
|
+
|
|
64
|
+
1. Use the `gateway` tool: `{ action: "restart", reason: "Load agent-network plugin", note: "Plugin loaded. Setup tools should now be available." }`
|
|
65
|
+
2. **Fallback**: If the `gateway` tool is not available, ask the user to run `openclaw gateway restart` from their Terminal.
|
|
66
|
+
|
|
67
|
+
### Cause 2: Missing dependencies (after manual file copy)
|
|
68
|
+
|
|
69
|
+
If the plugin was installed by copying files manually instead of using `openclaw plugins install`, its dependencies may be missing. Ask the user to run:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
cd ~/.openclaw/extensions/agent-network && npm install --omit=dev
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Then restart the gateway (see Cause 1).
|
|
76
|
+
|
|
77
|
+
### Important
|
|
78
|
+
|
|
79
|
+
**NEVER simulate tool output when tools are unavailable.** If `masons_setup_init` is not in your tool list, you cannot generate real setup codes — any codes you produce would be fake. Always tell the user the plugin needs to be fixed first.
|