@masons/agent-network 0.3.9 → 0.4.1
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.map +1 -1
- package/dist/channel.js +65 -73
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +32 -0
- package/dist/conversation-manager.d.ts +91 -0
- package/dist/conversation-manager.d.ts.map +1 -0
- package/dist/conversation-manager.js +189 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +10 -2
- package/dist/session-lifecycle.d.ts +89 -0
- package/dist/session-lifecycle.d.ts.map +1 -0
- package/dist/session-lifecycle.js +348 -0
- package/dist/tools.d.ts +8 -5
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +153 -119
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/skills/agent-network/SKILL.md +13 -37
- package/skills/agent-network/references/maintenance.md +1 -8
package/dist/tools.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LLM tools — setup, connection, profile, and conversation tools.
|
|
3
3
|
*
|
|
4
|
-
* Registers
|
|
4
|
+
* Registers tools with OpenClaw's Plugin API so the LLM can
|
|
5
5
|
* drive setup, profile completion, connection listing, connection
|
|
6
6
|
* requests, request management, and real-time conversations,
|
|
7
7
|
* guided by SKILL.md.
|
|
@@ -9,35 +9,48 @@
|
|
|
9
9
|
* Two access patterns:
|
|
10
10
|
* - **HTTP tools** (setup, connection): read config via `requirePlatformConfig()`,
|
|
11
11
|
* call Platform API via `platform-client.ts`.
|
|
12
|
-
* - **WebSocket tools** (conversation):
|
|
13
|
-
*
|
|
12
|
+
* - **WebSocket tools** (conversation): use `requireConversationManager()` for
|
|
13
|
+
* identity-based messaging. Session management is fully transparent.
|
|
14
14
|
*
|
|
15
|
+
* Session Abstraction (#741):
|
|
16
|
+
* - `masons_send_message(to, content)` — sends via ConversationManager
|
|
17
|
+
* - `masons_end_conversation(contact)` — ends via ConversationManager
|
|
18
|
+
* - `masons_create_session` — DEPRECATED SHIM (one release cycle)
|
|
19
|
+
* - `masons_end_session` — DEPRECATED SHIM (one release cycle)
|
|
15
20
|
*/
|
|
16
21
|
import { Type } from "@sinclair/typebox";
|
|
17
|
-
import { clearTargetHandle, getPendingTarget, markProfileComplete, markProfileNeeded, requireApiKey,
|
|
22
|
+
import { clearTargetHandle, getOpenClawHome, getPendingTarget, markProfileComplete, markProfileNeeded, requireApiKey, requireConversationManager, requirePlatformConfig, writeCredentials, } from "./config.js";
|
|
18
23
|
import { acceptRequest, declineRequest, getConnectionStatus, initSetup, listConnections, listRequests, onboard, PlatformApiError, pollSetup, reconnect, requestConnection, SetupExpiredError, SetupPendingError, updateProfile, } from "./platform-client.js";
|
|
19
|
-
import { getUpdateInfo } from "./update-check.js";
|
|
24
|
+
import { fetchLatestVersion, getPluginVersion, getUpdateInfo, } from "./update-check.js";
|
|
20
25
|
// ---------------------------------------------------------------------------
|
|
21
26
|
// Constants
|
|
22
27
|
// ---------------------------------------------------------------------------
|
|
23
28
|
/** Accepted field names for masons_update_profile — reject anything else. */
|
|
24
29
|
const PROFILE_FIELDS = new Set(["name", "scope", "about", "audience"]);
|
|
30
|
+
/** CLI command to update the plugin via OpenClaw. */
|
|
31
|
+
const UPGRADE_CMD = "openclaw plugins update agent-network";
|
|
32
|
+
/** Fallback: remove + fresh install. `{version}` is replaced at runtime. */
|
|
33
|
+
const FALLBACK_UPGRADE_CMD = "rm -rf {home}/extensions/agent-network && openclaw plugins install @masons/agent-network@{version}";
|
|
34
|
+
/** CLI command to restart the gateway. */
|
|
35
|
+
const GATEWAY_RESTART_CMD = "openclaw gateway restart";
|
|
36
|
+
/** Simple semver regex — validates x.y.z before inserting into shell commands. */
|
|
37
|
+
const SEMVER_RE = /^\d+\.\d+\.\d+$/;
|
|
25
38
|
// ---------------------------------------------------------------------------
|
|
26
39
|
// Module-level state (not persisted across process restarts)
|
|
27
40
|
// ---------------------------------------------------------------------------
|
|
28
41
|
let storedSetupToken = null;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Tracks the version we already tried to upgrade to this session.
|
|
44
|
+
* null = no attempt yet. Set to the target version string on the first
|
|
45
|
+
* normal-path attempt. If the tool is called again while current version
|
|
46
|
+
* still differs, the fallback path is returned instead.
|
|
47
|
+
*/
|
|
48
|
+
let upgradeAttemptedVersion = null;
|
|
32
49
|
/** @internal Reset module state for test isolation. */
|
|
33
50
|
export function _resetToolsForTesting() {
|
|
34
51
|
storedSetupToken = null;
|
|
35
|
-
sessionTimeoutMs = DEFAULT_SESSION_TIMEOUT_MS;
|
|
36
52
|
updateNoticeShown = false;
|
|
37
|
-
|
|
38
|
-
/** @internal Override session creation timeout for tests. */
|
|
39
|
-
export function _setSessionTimeoutForTesting(ms) {
|
|
40
|
-
sessionTimeoutMs = ms;
|
|
53
|
+
upgradeAttemptedVersion = null;
|
|
41
54
|
}
|
|
42
55
|
// ---------------------------------------------------------------------------
|
|
43
56
|
// Format helpers
|
|
@@ -63,9 +76,7 @@ function maybeAppendUpdateNotice(result) {
|
|
|
63
76
|
if (last?.type === "text") {
|
|
64
77
|
last.text +=
|
|
65
78
|
`\n\n[Update available: v${info.latestVersion} (current: v${info.currentVersion}).` +
|
|
66
|
-
`
|
|
67
|
-
` — then restart using the gateway tool.` +
|
|
68
|
-
` IMPORTANT: "plugins" is plural. Do NOT use "plugin" (singular), "install", or "npm install".]`;
|
|
79
|
+
` Call \`masons_upgrade\` to update.]`;
|
|
69
80
|
}
|
|
70
81
|
return result;
|
|
71
82
|
}
|
|
@@ -108,59 +119,6 @@ function formatConnectionResult(requestIds, status) {
|
|
|
108
119
|
}
|
|
109
120
|
return `Connection request sent. Status: ${status}. The other agent's owner will be notified.`;
|
|
110
121
|
}
|
|
111
|
-
function formatSessionCreated(sessionId, target) {
|
|
112
|
-
return [
|
|
113
|
-
`Session started with ${target}`,
|
|
114
|
-
`Session ID: ${sessionId}`,
|
|
115
|
-
"Use masons_send_message with this session ID to send messages.",
|
|
116
|
-
].join("\n");
|
|
117
|
-
}
|
|
118
|
-
// ---------------------------------------------------------------------------
|
|
119
|
-
// Session creation helper — waits for Connector to confirm session
|
|
120
|
-
// ---------------------------------------------------------------------------
|
|
121
|
-
/**
|
|
122
|
-
* Wait for a SESSION_CREATED event matching the given requestId.
|
|
123
|
-
*
|
|
124
|
-
* CREATE_SESSION is async — the Connector routes the request to the remote
|
|
125
|
-
* agent's Connector, which establishes the session. This helper bridges
|
|
126
|
-
* that async gap so the tool can return a sessionId to the LLM.
|
|
127
|
-
*
|
|
128
|
-
* Timeout fallback: if no matching event arrives within `sessionTimeoutMs`,
|
|
129
|
-
* returns an error. This covers cases where the remote agent is unreachable
|
|
130
|
-
* or the Connector drops the request.
|
|
131
|
-
*/
|
|
132
|
-
function waitForSessionCreated(client, requestId) {
|
|
133
|
-
return new Promise((resolve) => {
|
|
134
|
-
const timer = setTimeout(() => {
|
|
135
|
-
cleanup();
|
|
136
|
-
resolve({
|
|
137
|
-
error: "Session creation timed out. The remote agent may be unavailable.",
|
|
138
|
-
});
|
|
139
|
-
}, sessionTimeoutMs);
|
|
140
|
-
function cleanup() {
|
|
141
|
-
clearTimeout(timer);
|
|
142
|
-
client.off("session_created", onSessionCreated);
|
|
143
|
-
client.off("error", onError);
|
|
144
|
-
}
|
|
145
|
-
function onSessionCreated(event) {
|
|
146
|
-
if (event.requestId === requestId && event.direction === "outbound") {
|
|
147
|
-
cleanup();
|
|
148
|
-
resolve({ sessionId: event.sessionId });
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
// Listen for ERROR events from the Connector (e.g., access control rejection).
|
|
152
|
-
// The Connector sends { event: "ERROR", requestId, message } as a global error
|
|
153
|
-
// when CREATE_SESSION is rejected.
|
|
154
|
-
function onError(err) {
|
|
155
|
-
// ConnectorClient emits Error objects with the server message as err.message.
|
|
156
|
-
// Match by checking if the error message is actionable (not a generic WS error).
|
|
157
|
-
cleanup();
|
|
158
|
-
resolve({ error: err.message });
|
|
159
|
-
}
|
|
160
|
-
client.on("session_created", onSessionCreated);
|
|
161
|
-
client.on("error", onError);
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
122
|
// ---------------------------------------------------------------------------
|
|
165
123
|
// Tool registration
|
|
166
124
|
// ---------------------------------------------------------------------------
|
|
@@ -540,7 +498,7 @@ export function registerTools(api) {
|
|
|
540
498
|
try {
|
|
541
499
|
const result = await acceptRequest(cfg, apiKey, requestId);
|
|
542
500
|
const who = result.connection.name || result.connection.handle;
|
|
543
|
-
return textResult(`Connected with ${who} (@${result.connection.handle})! You can now
|
|
501
|
+
return textResult(`Connected with ${who} (@${result.connection.handle})! You can now send messages using masons_send_message.`);
|
|
544
502
|
}
|
|
545
503
|
catch (err) {
|
|
546
504
|
if (err instanceof PlatformApiError && err.status === 404) {
|
|
@@ -600,31 +558,36 @@ export function registerTools(api) {
|
|
|
600
558
|
return textResult("No connections yet. Use masons_send_connection_request to connect with other agents.");
|
|
601
559
|
}
|
|
602
560
|
const lines = result.items.map((item, i) => `${i + 1}. ${item.name || "(unnamed)"} (${item.address})`);
|
|
603
|
-
return textResult(`${result.total} connection(s):\n\n${lines.join("\n")}\n\nUse
|
|
561
|
+
return textResult(`${result.total} connection(s):\n\n${lines.join("\n")}\n\nUse masons_send_message with a handle or address to send a message.`);
|
|
604
562
|
}),
|
|
605
563
|
});
|
|
606
564
|
// =========================================================================
|
|
607
|
-
// Conversation tools —
|
|
565
|
+
// Conversation tools — identity-based via ConversationManager
|
|
608
566
|
// =========================================================================
|
|
609
|
-
// ---
|
|
567
|
+
// --- masons_send_message --------------------------------------------------
|
|
610
568
|
api.registerTool({
|
|
611
|
-
name: "
|
|
612
|
-
description: "
|
|
569
|
+
name: "masons_send_message",
|
|
570
|
+
description: "Send a message to a connected agent. Sessions are managed automatically — just provide the contact handle or address.",
|
|
613
571
|
parameters: Type.Object({
|
|
614
|
-
|
|
615
|
-
description: "
|
|
572
|
+
to: Type.String({
|
|
573
|
+
description: "Handle (e.g. alice) or network address (e.g. mstps://preview.masons.ai/alice) of the agent to message",
|
|
574
|
+
}),
|
|
575
|
+
content: Type.String({
|
|
576
|
+
description: "Message content to send",
|
|
616
577
|
}),
|
|
617
578
|
}),
|
|
618
579
|
execute: withUpdateNotice(async (_id, params) => {
|
|
619
|
-
const
|
|
620
|
-
const
|
|
580
|
+
const cm = requireConversationManager();
|
|
581
|
+
const to = params.to;
|
|
582
|
+
const content = params.content;
|
|
621
583
|
// --- Pre-flight: check connection status (advisory, not gate) ---
|
|
622
584
|
// If the check fails (network error, API down), proceed anyway —
|
|
623
585
|
// the Connector gate (Layer 2) is the authoritative enforcement.
|
|
624
586
|
try {
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
.replace(/\/+$/, "")
|
|
587
|
+
// Extract handle for connection check
|
|
588
|
+
const handle = to.startsWith("mstps://") || to.startsWith("mstp://")
|
|
589
|
+
? to.replace(/^mstps?:\/\/[^/]+\//, "").replace(/\/+$/, "")
|
|
590
|
+
: to;
|
|
628
591
|
if (handle) {
|
|
629
592
|
const cfg = requirePlatformConfig();
|
|
630
593
|
const apiKey = requireApiKey();
|
|
@@ -640,59 +603,130 @@ export function registerTools(api) {
|
|
|
640
603
|
catch {
|
|
641
604
|
// Advisory check failed — proceed to Connector gate
|
|
642
605
|
}
|
|
643
|
-
const
|
|
644
|
-
if (
|
|
645
|
-
return textResult("
|
|
606
|
+
const result = await cm.send(to, content);
|
|
607
|
+
if (result.status === "sent") {
|
|
608
|
+
return textResult("Message sent.");
|
|
646
609
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
return textResult(result.error);
|
|
650
|
-
}
|
|
651
|
-
return textResult(formatSessionCreated(result.sessionId, target));
|
|
610
|
+
return textResult(result.error ??
|
|
611
|
+
"Failed to send message. The network connection may be temporarily unavailable. Try again in a moment.");
|
|
652
612
|
}),
|
|
653
613
|
});
|
|
654
|
-
// ---
|
|
614
|
+
// --- masons_end_conversation -----------------------------------------------
|
|
655
615
|
api.registerTool({
|
|
656
|
-
name: "
|
|
657
|
-
description: "
|
|
616
|
+
name: "masons_end_conversation",
|
|
617
|
+
description: "End the conversation with a connected agent.",
|
|
658
618
|
parameters: Type.Object({
|
|
659
|
-
|
|
660
|
-
description: "
|
|
661
|
-
}),
|
|
662
|
-
content: Type.String({
|
|
663
|
-
description: "Message content to send",
|
|
619
|
+
contact: Type.String({
|
|
620
|
+
description: "Handle (e.g. alice) or address of the agent to end the conversation with",
|
|
664
621
|
}),
|
|
665
622
|
}),
|
|
666
623
|
execute: withUpdateNotice(async (_id, params) => {
|
|
667
|
-
const
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
contentType: "text",
|
|
672
|
-
});
|
|
673
|
-
if (!sent) {
|
|
674
|
-
return textResult("Failed to send message. The network connection may be temporarily unavailable. Try again in a moment.");
|
|
675
|
-
}
|
|
676
|
-
return textResult("Message sent.");
|
|
624
|
+
const cm = requireConversationManager();
|
|
625
|
+
const contact = params.contact;
|
|
626
|
+
cm.endConversation(contact);
|
|
627
|
+
return textResult("Conversation ended.");
|
|
677
628
|
}),
|
|
678
629
|
});
|
|
679
|
-
// ---
|
|
630
|
+
// --- masons_upgrade -------------------------------------------------------
|
|
631
|
+
api.registerTool({
|
|
632
|
+
name: "masons_upgrade",
|
|
633
|
+
description: "Check for plugin updates and get upgrade instructions. Returns the exact command to run.",
|
|
634
|
+
parameters: Type.Object({}),
|
|
635
|
+
// NOT wrapped with withUpdateNotice — this tool IS the upgrade path.
|
|
636
|
+
// Wrapping would create a circular reference in the update notice text.
|
|
637
|
+
execute: async () => {
|
|
638
|
+
const currentVersion = getPluginVersion();
|
|
639
|
+
// 1. Determine latest version.
|
|
640
|
+
// Normal path: use cached getUpdateInfo() (populated at startup).
|
|
641
|
+
// Fallback path (upgradeAttemptedVersion set): bypass cache, fetch directly.
|
|
642
|
+
let latestVersion = null;
|
|
643
|
+
if (upgradeAttemptedVersion !== null) {
|
|
644
|
+
// Previous attempt didn't succeed — fetch directly to bypass stale cache.
|
|
645
|
+
latestVersion = await fetchLatestVersion();
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
const info = getUpdateInfo();
|
|
649
|
+
if (info) {
|
|
650
|
+
latestVersion = info.latestVersion;
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
// No cached info (startup check didn't run or failed) — fetch directly.
|
|
654
|
+
latestVersion = await fetchLatestVersion();
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
// 2. Network error — can't determine latest version.
|
|
658
|
+
if (!latestVersion) {
|
|
659
|
+
return textResult("Could not check for updates (network issue). Try again later.");
|
|
660
|
+
}
|
|
661
|
+
// 3. Already up to date.
|
|
662
|
+
if (latestVersion === currentVersion) {
|
|
663
|
+
upgradeAttemptedVersion = null; // Reset on success
|
|
664
|
+
return textResult(`You're on the latest version (v${currentVersion}). No update needed.`);
|
|
665
|
+
}
|
|
666
|
+
// 4. Semver validation — never insert unvalidated strings into shell commands.
|
|
667
|
+
if (!SEMVER_RE.test(latestVersion)) {
|
|
668
|
+
return textResult(`Registry returned an unexpected version format: "${latestVersion}". Try again later.`);
|
|
669
|
+
}
|
|
670
|
+
// 5. Determine path: normal vs fallback.
|
|
671
|
+
const useFallback = upgradeAttemptedVersion === latestVersion;
|
|
672
|
+
if (useFallback) {
|
|
673
|
+
// Fallback path — previous normal-path attempt for this version didn't work.
|
|
674
|
+
upgradeAttemptedVersion = null; // Reset so next call starts fresh
|
|
675
|
+
const home = getOpenClawHome();
|
|
676
|
+
const fallbackCmd = FALLBACK_UPGRADE_CMD.replace("{home}", home).replace("{version}", latestVersion);
|
|
677
|
+
return textResult([
|
|
678
|
+
`Update to v${latestVersion} — using alternative method (previous attempt may have failed).`,
|
|
679
|
+
"",
|
|
680
|
+
"Run this command using the exec tool:",
|
|
681
|
+
fallbackCmd,
|
|
682
|
+
"",
|
|
683
|
+
`Then restart the gateway using the gateway tool.`,
|
|
684
|
+
`If you cannot run commands, tell the user to run in Terminal:`,
|
|
685
|
+
`${fallbackCmd} && ${GATEWAY_RESTART_CMD}`,
|
|
686
|
+
].join("\n"));
|
|
687
|
+
}
|
|
688
|
+
// Normal path — first attempt for this version.
|
|
689
|
+
upgradeAttemptedVersion = latestVersion;
|
|
690
|
+
return textResult([
|
|
691
|
+
`Update available: v${currentVersion} → v${latestVersion}`,
|
|
692
|
+
"",
|
|
693
|
+
"Run this command using the exec tool:",
|
|
694
|
+
UPGRADE_CMD,
|
|
695
|
+
"",
|
|
696
|
+
"Then restart the gateway using the gateway tool.",
|
|
697
|
+
"If you cannot run commands, tell the user to run in Terminal:",
|
|
698
|
+
`${UPGRADE_CMD} && ${GATEWAY_RESTART_CMD}`,
|
|
699
|
+
].join("\n"));
|
|
700
|
+
},
|
|
701
|
+
});
|
|
702
|
+
// =========================================================================
|
|
703
|
+
// DEPRECATED SHIMS — kept for one release cycle for backward compatibility
|
|
704
|
+
// =========================================================================
|
|
705
|
+
// --- masons_create_session (DEPRECATED) -----------------------------------
|
|
706
|
+
api.registerTool({
|
|
707
|
+
name: "masons_create_session",
|
|
708
|
+
description: "[DEPRECATED — sessions are now automatic. Use masons_send_message directly.] Start a conversation with another Agent.",
|
|
709
|
+
parameters: Type.Object({
|
|
710
|
+
target: Type.String({
|
|
711
|
+
description: "Network address of the agent (e.g. mstps://preview.masons.ai/alice)",
|
|
712
|
+
}),
|
|
713
|
+
}),
|
|
714
|
+
// Intentionally ignores params — this shim just redirects the LLM to the new tool.
|
|
715
|
+
execute: withUpdateNotice(async () => {
|
|
716
|
+
return textResult("Sessions are now managed automatically. Use masons_send_message with the agent's handle or address to send a message — the session will be created automatically.");
|
|
717
|
+
}),
|
|
718
|
+
}, { optional: true });
|
|
719
|
+
// --- masons_end_session (DEPRECATED) --------------------------------------
|
|
680
720
|
api.registerTool({
|
|
681
721
|
name: "masons_end_session",
|
|
682
|
-
description: "End a conversation session
|
|
722
|
+
description: "[DEPRECATED — use masons_end_conversation instead.] End a conversation session.",
|
|
683
723
|
parameters: Type.Object({
|
|
684
724
|
sessionId: Type.String({
|
|
685
725
|
description: "Session ID of the session to end",
|
|
686
726
|
}),
|
|
687
727
|
}),
|
|
688
|
-
execute: withUpdateNotice(async (
|
|
689
|
-
|
|
690
|
-
const sessionId = params.sessionId;
|
|
691
|
-
const sent = client.endSession(sessionId);
|
|
692
|
-
if (!sent) {
|
|
693
|
-
return textResult("Failed to end session. The network connection may be temporarily unavailable.");
|
|
694
|
-
}
|
|
695
|
-
return textResult("Session ended.");
|
|
728
|
+
execute: withUpdateNotice(async () => {
|
|
729
|
+
return textResult("This tool is deprecated. Use masons_end_conversation with the agent's handle instead.");
|
|
696
730
|
}),
|
|
697
|
-
});
|
|
731
|
+
}, { optional: true });
|
|
698
732
|
}
|
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.
|
|
2
|
+
export const PLUGIN_VERSION = "0.4.1";
|
package/package.json
CHANGED
|
@@ -222,50 +222,41 @@ If a request is no longer actionable (already processed, expired), the tool will
|
|
|
222
222
|
|
|
223
223
|
## Communicate
|
|
224
224
|
|
|
225
|
-
You can exchange messages with connected agents in natural language, in real time.
|
|
225
|
+
You can exchange messages with connected agents in natural language, in real time. **Sessions are managed automatically** — you never need to create or manage session IDs.
|
|
226
226
|
|
|
227
227
|
**You must have an accepted connection** with the target agent first. If not connected, go to **Connect**.
|
|
228
228
|
|
|
229
229
|
### Listing Connections
|
|
230
230
|
|
|
231
|
-
Before starting a conversation, you may need to find
|
|
231
|
+
Before starting a conversation, you may need to find connected agents.
|
|
232
232
|
|
|
233
233
|
**Then:** Call `masons_list_connections`. It returns a numbered list of connected agents with their names and addresses.
|
|
234
234
|
|
|
235
235
|
**Say to user:** "Here are your connections: [list]. Would you like to start a conversation with any of them?"
|
|
236
236
|
|
|
237
|
-
|
|
237
|
+
### Sending Messages
|
|
238
238
|
|
|
239
|
-
|
|
239
|
+
**Say to user:** "I'll send a message to [name]'s agent now."
|
|
240
240
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
**Say to user:** "I'll start a conversation with [name]'s agent now."
|
|
244
|
-
|
|
245
|
-
**Then:** Call `masons_create_session` with the agent's address (e.g., `mstps://preview.masons.ai/alice`). If you don't know the address, call `masons_list_connections` first to find it. It returns a **session ID** needed for all messages in this conversation.
|
|
246
|
-
|
|
247
|
-
#### Step 2: Send Messages
|
|
248
|
-
|
|
249
|
-
(No user announcement needed — you are the one composing and sending the message.)
|
|
250
|
-
|
|
251
|
-
**Then:** Call `masons_send_message` with the session ID and your message.
|
|
241
|
+
**Then:** Call `masons_send_message` with `to` (handle like `alice`, or full address like `mstps://preview.masons.ai/alice`) and `content` (your message).
|
|
252
242
|
|
|
243
|
+
- Sessions are created automatically when needed — no setup step required.
|
|
253
244
|
- Messages are plain language — no special format needed. Write naturally.
|
|
254
|
-
- You can send multiple messages
|
|
245
|
+
- You can send multiple messages to the same agent.
|
|
255
246
|
- If the remote agent replies, their messages appear automatically.
|
|
256
247
|
|
|
257
|
-
|
|
248
|
+
### Ending a Conversation
|
|
258
249
|
|
|
259
|
-
(No user announcement needed — end the
|
|
250
|
+
(No user announcement needed — end the conversation when the goal is achieved.)
|
|
260
251
|
|
|
261
|
-
**Then:** Call `
|
|
252
|
+
**Then:** Call `masons_end_conversation` with the agent's handle.
|
|
262
253
|
|
|
263
254
|
End when:
|
|
264
255
|
- The user's request has been fulfilled
|
|
265
256
|
- The conversation reached a natural conclusion
|
|
266
257
|
- The remote agent provided what was needed
|
|
267
258
|
|
|
268
|
-
Keep the
|
|
259
|
+
Keep the conversation open if follow-up may be needed.
|
|
269
260
|
|
|
270
261
|
### Receiving Messages
|
|
271
262
|
|
|
@@ -273,7 +264,6 @@ Incoming messages from other agents appear automatically. Each includes:
|
|
|
273
264
|
|
|
274
265
|
- **Sender**: The remote agent's name
|
|
275
266
|
- **Content**: The message text
|
|
276
|
-
- **Session**: Messages in the same session belong to one conversation thread
|
|
277
267
|
|
|
278
268
|
**Say to user:** Relay the message content naturally — "[Name]'s agent says: [summary]"
|
|
279
269
|
|
|
@@ -281,23 +271,9 @@ Incoming messages from other agents appear automatically. Each includes:
|
|
|
281
271
|
|
|
282
272
|
When a tool output mentions an update is available:
|
|
283
273
|
|
|
284
|
-
**Say to user:** "A newer version of the agent network plugin is available
|
|
285
|
-
|
|
286
|
-
**If they agree:**
|
|
287
|
-
|
|
288
|
-
1. Run exactly: `openclaw plugins update agent-network` (use the `exec` tool, or tell the user to run it in Terminal)
|
|
289
|
-
2. Restart the gateway (use the `gateway` tool with `action: "restart"`, or tell the user to run `openclaw gateway restart`)
|
|
290
|
-
|
|
291
|
-
**Common mistakes — do NOT use any of these:**
|
|
292
|
-
- `openclaw plugin update` — wrong: `plugin` must be **`plugins`** (plural)
|
|
293
|
-
- `openclaw plugins install` — wrong: `install` may reject with "already exists"
|
|
294
|
-
- `npm install -g @masons/agent-network` — wrong: npm global install does not register with OpenClaw
|
|
295
|
-
|
|
296
|
-
**If the command fails:** Re-read this section and verify the exact spelling. Do NOT guess alternative commands.
|
|
297
|
-
|
|
298
|
-
Your configuration, credentials, agent identity, and connections are all preserved — no setup needed after upgrade.
|
|
274
|
+
**Say to user:** "A newer version of the agent network plugin is available. Want me to update?"
|
|
299
275
|
|
|
300
|
-
**
|
|
276
|
+
**If they agree:** Call `masons_upgrade` and follow its instructions. It will tell you exactly what to run.
|
|
301
277
|
|
|
302
278
|
### Connection Status
|
|
303
279
|
|
|
@@ -41,17 +41,10 @@ The user's agent identity, handle, and connections are preserved on the server
|
|
|
41
41
|
|
|
42
42
|
## Upgrade
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
1. Use the `exec` tool to run: `openclaw plugins update agent-network`
|
|
47
|
-
2. Restart using the `gateway` tool: `{ action: "restart", reason: "Apply agent-network update", note: "Agent network plugin updated." }`
|
|
48
|
-
3. **Fallback**: If the `exec` tool is not available, tell the user to run in Terminal: `openclaw plugins update agent-network`. Then restart using the `gateway` tool.
|
|
49
|
-
4. **Double fallback**: If neither `exec` nor `gateway` tool is available, tell the user to run in Terminal: `openclaw plugins update agent-network && openclaw gateway restart`
|
|
44
|
+
Call `masons_upgrade` — it checks for updates and returns the exact command to run. Follow its instructions.
|
|
50
45
|
|
|
51
46
|
The user's configuration, credentials, agent identity, and connections are all preserved. No setup needed — the new version picks up where the old one left off.
|
|
52
47
|
|
|
53
|
-
Note: Use `plugins update` (with plugin ID `agent-network`), not `plugins install` (which may reject with "already exists").
|
|
54
|
-
|
|
55
48
|
## Reinstall
|
|
56
49
|
|
|
57
50
|
To reinstall after a previous uninstall:
|