@masons/agent-network 0.2.5 → 0.3.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.
- package/dist/channel.d.ts +5 -5
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +10 -10
- package/dist/config-schema.d.ts +2 -2
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config-schema.js +1 -1
- package/dist/config.d.ts +5 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -29
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin.js +14 -14
- package/dist/tools.d.ts +2 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +45 -45
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +12 -11
- package/skills/agent-network/SKILL.md +19 -17
- package/skills/agent-network/references/troubleshooting.md +1 -1
package/dist/channel.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AgentNetworkAccount } from "./config-schema.js";
|
|
2
2
|
interface ChannelMeta {
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
@@ -52,14 +52,14 @@ interface ChannelGatewayAdapter<T = unknown> {
|
|
|
52
52
|
startAccount?(ctx: ChannelGatewayContext<T>): Promise<unknown>;
|
|
53
53
|
stopAccount?(ctx: ChannelGatewayContext<T>): Promise<void>;
|
|
54
54
|
}
|
|
55
|
-
interface
|
|
55
|
+
interface AgentNetworkChannelPlugin {
|
|
56
56
|
id: string;
|
|
57
57
|
meta: ChannelMeta;
|
|
58
58
|
capabilities: ChannelCapabilities;
|
|
59
|
-
config: ChannelConfigAdapter<
|
|
59
|
+
config: ChannelConfigAdapter<AgentNetworkAccount>;
|
|
60
60
|
outbound: ChannelOutboundAdapter;
|
|
61
|
-
gateway: ChannelGatewayAdapter<
|
|
61
|
+
gateway: ChannelGatewayAdapter<AgentNetworkAccount>;
|
|
62
62
|
}
|
|
63
|
-
export declare const
|
|
63
|
+
export declare const agentNetworkChannel: AgentNetworkChannelPlugin;
|
|
64
64
|
export {};
|
|
65
65
|
//# sourceMappingURL=channel.d.ts.map
|
package/dist/channel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAW9D,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,EAAE,EAAE,OAAO,CAAC;CACb;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,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,cAAc,CAAC;IACxB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,UAAU,cAAc;IACtB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/C;AAED,UAAU,eAAe;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,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;AAwDD,eAAO,MAAM,mBAAmB,EAAE,yBAsLjC,CAAC"}
|
package/dist/channel.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { clearConnectorClient,
|
|
2
|
+
import { clearConnectorClient, extractNetworkConfig, initConnectorClient, initToolConfig, } from "./config.js";
|
|
3
3
|
import { ConnectorClient } from "./connector-client.js";
|
|
4
4
|
import { checkForUpdate } from "./update-check.js";
|
|
5
5
|
// --- Sender identity ---
|
|
@@ -38,10 +38,10 @@ function deriveSenderName(event) {
|
|
|
38
38
|
}
|
|
39
39
|
const accounts = new Map();
|
|
40
40
|
// --- Channel Plugin ---
|
|
41
|
-
export const
|
|
41
|
+
export const agentNetworkChannel = {
|
|
42
42
|
id: "agent-network",
|
|
43
43
|
meta: {
|
|
44
|
-
name: "
|
|
44
|
+
name: "Agent Network",
|
|
45
45
|
description: "Connect your Agent to the agent network for real-time communication",
|
|
46
46
|
icon: "globe",
|
|
47
47
|
},
|
|
@@ -59,11 +59,11 @@ export const mstpChannel = {
|
|
|
59
59
|
return ["default"];
|
|
60
60
|
},
|
|
61
61
|
resolveAccount(cfg, accountId) {
|
|
62
|
-
const
|
|
63
|
-
if (!
|
|
62
|
+
const networkCfg = extractNetworkConfig(cfg);
|
|
63
|
+
if (!networkCfg || !accountId) {
|
|
64
64
|
return { connectorUrl: "", token: "" };
|
|
65
65
|
}
|
|
66
|
-
const accountsCfg =
|
|
66
|
+
const accountsCfg = networkCfg.accounts;
|
|
67
67
|
if (typeof accountsCfg !== "object" || accountsCfg === null) {
|
|
68
68
|
return { connectorUrl: "", token: "" };
|
|
69
69
|
}
|
|
@@ -88,8 +88,8 @@ export const mstpChannel = {
|
|
|
88
88
|
return account.connectorUrl !== "" && account.token !== "";
|
|
89
89
|
},
|
|
90
90
|
isEnabled(account, cfg) {
|
|
91
|
-
const
|
|
92
|
-
return
|
|
91
|
+
const networkCfg = extractNetworkConfig(cfg);
|
|
92
|
+
return networkCfg?.enabled !== false;
|
|
93
93
|
},
|
|
94
94
|
},
|
|
95
95
|
outbound: {
|
|
@@ -160,8 +160,8 @@ export const mstpChannel = {
|
|
|
160
160
|
// --- Inject config for LLM tools ---
|
|
161
161
|
initToolConfig(ctx.cfg);
|
|
162
162
|
// --- Check for plugin updates (non-blocking) ---
|
|
163
|
-
const
|
|
164
|
-
const updateCheckEnabled =
|
|
163
|
+
const networkCfg = extractNetworkConfig(ctx.cfg);
|
|
164
|
+
const updateCheckEnabled = networkCfg?.updateCheck !== false;
|
|
165
165
|
checkForUpdate(updateCheckEnabled).catch(() => { });
|
|
166
166
|
// --- Connect ---
|
|
167
167
|
await client.connect();
|
package/dist/config-schema.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Static } from "@sinclair/typebox";
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const AgentNetworkAccountSchema: import("@sinclair/typebox").TObject<{
|
|
3
3
|
connectorUrl: import("@sinclair/typebox").TString;
|
|
4
4
|
token: import("@sinclair/typebox").TString;
|
|
5
5
|
}>;
|
|
6
|
-
export type
|
|
6
|
+
export type AgentNetworkAccount = Static<typeof AgentNetworkAccountSchema>;
|
|
7
7
|
//# sourceMappingURL=config-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,eAAO,MAAM,yBAAyB;;;EAOpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
|
package/dist/config-schema.js
CHANGED
package/dist/config.d.ts
CHANGED
|
@@ -21,10 +21,10 @@ import { type PlatformClientConfig } from "./platform-client.js";
|
|
|
21
21
|
*
|
|
22
22
|
* OpenClaw Gateway passes the ENTIRE config (all of openclaw.json) to
|
|
23
23
|
* channel adapter methods and startAccount(). This helper navigates to
|
|
24
|
-
* the
|
|
24
|
+
* the agent-network-specific section.
|
|
25
25
|
*
|
|
26
26
|
*/
|
|
27
|
-
export declare function
|
|
27
|
+
export declare function extractNetworkConfig(cfg: Record<string, unknown>): Record<string, unknown> | null;
|
|
28
28
|
/**
|
|
29
29
|
* Inject Host-provided config into module-level variables.
|
|
30
30
|
*
|
|
@@ -76,7 +76,7 @@ export declare function getPendingTarget(): string | null;
|
|
|
76
76
|
export declare function requireConnectorClient(): ConnectorClient;
|
|
77
77
|
/** Resolve the OpenClaw home directory (`$OPENCLAW_HOME` or `~/.openclaw`). */
|
|
78
78
|
export declare function getOpenClawHome(): string;
|
|
79
|
-
export interface
|
|
79
|
+
export interface NetworkCredentials {
|
|
80
80
|
connectorUrl: string;
|
|
81
81
|
token: string;
|
|
82
82
|
}
|
|
@@ -86,7 +86,7 @@ export interface MstpCredentials {
|
|
|
86
86
|
* Atomic: credentials and apiHost are written in a single operation
|
|
87
87
|
* to avoid partial-write race conditions.
|
|
88
88
|
*/
|
|
89
|
-
export declare function writeCredentials(creds:
|
|
89
|
+
export declare function writeCredentials(creds: NetworkCredentials, apiHost?: string): Promise<void>;
|
|
90
90
|
/**
|
|
91
91
|
* Write pending connection target handle.
|
|
92
92
|
*
|
|
@@ -114,7 +114,7 @@ export declare function markProfileNeeded(): Promise<void>;
|
|
|
114
114
|
/**
|
|
115
115
|
* Mark that profile completion is done.
|
|
116
116
|
*
|
|
117
|
-
* Called after successful
|
|
117
|
+
* Called after successful masons_update_profile — clears the needsProfile flag
|
|
118
118
|
* so the before_agent_start hook no longer injects profile context on restart.
|
|
119
119
|
*
|
|
120
120
|
* Note: unlike clearTargetHandle, this only writes to disk — there is no
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAuB9B;;;;;;;GAOG;AACH,wBAAgB,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAuB9B;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMhC;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAsBjE;AAMD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAOjE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,IAAI,oBAAoB,CAE5D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,eAAe,CAOxD;AAMD,+EAA+E;AAC/E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAgDD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,kBAAkB,EACzB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrE;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAQvD;AAMD;;;;;GAKG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKvD;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKzD;AAMD,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,cAAc,EAAE,OAAO,CAAC;IACxB,wDAAwD;IACxD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4EAA4E;IAC5E,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC,CA2BhE;AAMD,uDAAuD;AACvD,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC"}
|
package/dist/config.js
CHANGED
|
@@ -23,7 +23,7 @@ import { DEFAULT_API_HOST, } from "./platform-client.js";
|
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
24
24
|
// Initialize with defaults so setup tools work BEFORE startAccount() runs.
|
|
25
25
|
// On first install (no credentials), startAccount() never runs because
|
|
26
|
-
// listAccountIds() returns []. But the LLM setup tools (
|
|
26
|
+
// listAccountIds() returns []. But the LLM setup tools (masons_setup_init etc.)
|
|
27
27
|
// still need apiHost to call the Platform API. Without this default, tools
|
|
28
28
|
// throw "Channel must be started first" on first run.
|
|
29
29
|
// Config state (from Host's openclaw.json — set by initToolConfig)
|
|
@@ -40,10 +40,10 @@ let storedConnectorClient = null;
|
|
|
40
40
|
*
|
|
41
41
|
* OpenClaw Gateway passes the ENTIRE config (all of openclaw.json) to
|
|
42
42
|
* channel adapter methods and startAccount(). This helper navigates to
|
|
43
|
-
* the
|
|
43
|
+
* the agent-network-specific section.
|
|
44
44
|
*
|
|
45
45
|
*/
|
|
46
|
-
export function
|
|
46
|
+
export function extractNetworkConfig(cfg) {
|
|
47
47
|
const channels = cfg.channels;
|
|
48
48
|
if (!channels)
|
|
49
49
|
return null;
|
|
@@ -62,17 +62,21 @@ export function extractMstpConfig(cfg) {
|
|
|
62
62
|
* Ensures tools always read the Host's current config values.
|
|
63
63
|
*/
|
|
64
64
|
export function initToolConfig(cfg) {
|
|
65
|
-
const
|
|
65
|
+
const networkCfg = extractNetworkConfig(cfg);
|
|
66
66
|
platformConfig = {
|
|
67
|
-
apiHost: typeof
|
|
67
|
+
apiHost: typeof networkCfg?.apiHost === "string"
|
|
68
|
+
? networkCfg.apiHost
|
|
69
|
+
: DEFAULT_API_HOST,
|
|
68
70
|
};
|
|
69
71
|
// Extract API key from channels.agent-network.accounts.default.token
|
|
70
|
-
const accounts =
|
|
72
|
+
const accounts = networkCfg?.accounts;
|
|
71
73
|
const defaultAccount = accounts?.default;
|
|
72
74
|
storedApiKey =
|
|
73
75
|
typeof defaultAccount?.token === "string" ? defaultAccount.token : null;
|
|
74
76
|
storedPendingTarget =
|
|
75
|
-
typeof
|
|
77
|
+
typeof networkCfg?.pendingTarget === "string"
|
|
78
|
+
? networkCfg.pendingTarget
|
|
79
|
+
: null;
|
|
76
80
|
}
|
|
77
81
|
// ---------------------------------------------------------------------------
|
|
78
82
|
// ConnectorClient injection (called by startAccount() after connect)
|
|
@@ -120,7 +124,7 @@ export function requirePlatformConfig() {
|
|
|
120
124
|
*/
|
|
121
125
|
export function requireApiKey() {
|
|
122
126
|
if (!storedApiKey) {
|
|
123
|
-
throw new Error("No API key configured. Complete
|
|
127
|
+
throw new Error("No API key configured. Complete setup first.");
|
|
124
128
|
}
|
|
125
129
|
return storedApiKey;
|
|
126
130
|
}
|
|
@@ -173,7 +177,7 @@ async function persistConfig(config) {
|
|
|
173
177
|
/**
|
|
174
178
|
* Get or create the `channels.agent-network` section in config.
|
|
175
179
|
*/
|
|
176
|
-
function
|
|
180
|
+
function ensureNetworkSection(config) {
|
|
177
181
|
if (typeof config.channels !== "object" || config.channels === null) {
|
|
178
182
|
config.channels = {};
|
|
179
183
|
}
|
|
@@ -192,20 +196,20 @@ function ensureMstpSection(config) {
|
|
|
192
196
|
*/
|
|
193
197
|
export async function writeCredentials(creds, apiHost) {
|
|
194
198
|
const config = await readConfig();
|
|
195
|
-
const
|
|
196
|
-
|
|
199
|
+
const section = ensureNetworkSection(config);
|
|
200
|
+
section.enabled = true;
|
|
197
201
|
// Write accounts.default
|
|
198
|
-
if (typeof
|
|
199
|
-
|
|
202
|
+
if (typeof section.accounts !== "object" || section.accounts === null) {
|
|
203
|
+
section.accounts = {};
|
|
200
204
|
}
|
|
201
|
-
const accounts =
|
|
205
|
+
const accounts = section.accounts;
|
|
202
206
|
accounts.default = {
|
|
203
207
|
connectorUrl: creds.connectorUrl,
|
|
204
208
|
token: creds.token,
|
|
205
209
|
};
|
|
206
210
|
// Write apiHost if provided
|
|
207
211
|
if (apiHost) {
|
|
208
|
-
|
|
212
|
+
section.apiHost = apiHost;
|
|
209
213
|
}
|
|
210
214
|
await persistConfig(config);
|
|
211
215
|
}
|
|
@@ -219,8 +223,8 @@ export async function writeCredentials(creds, apiHost) {
|
|
|
219
223
|
*/
|
|
220
224
|
export async function writeTargetHandle(handle) {
|
|
221
225
|
const config = await readConfig();
|
|
222
|
-
const
|
|
223
|
-
|
|
226
|
+
const section = ensureNetworkSection(config);
|
|
227
|
+
section.pendingTarget = handle;
|
|
224
228
|
await persistConfig(config);
|
|
225
229
|
}
|
|
226
230
|
/**
|
|
@@ -232,8 +236,8 @@ export async function writeTargetHandle(handle) {
|
|
|
232
236
|
*/
|
|
233
237
|
export async function clearTargetHandle() {
|
|
234
238
|
const config = await readConfig();
|
|
235
|
-
const
|
|
236
|
-
delete
|
|
239
|
+
const section = ensureNetworkSection(config);
|
|
240
|
+
delete section.pendingTarget;
|
|
237
241
|
await persistConfig(config);
|
|
238
242
|
// Update module-level var — deliberate exception to read/write separation
|
|
239
243
|
storedPendingTarget = null;
|
|
@@ -249,14 +253,14 @@ export async function clearTargetHandle() {
|
|
|
249
253
|
*/
|
|
250
254
|
export async function markProfileNeeded() {
|
|
251
255
|
const config = await readConfig();
|
|
252
|
-
const
|
|
253
|
-
|
|
256
|
+
const section = ensureNetworkSection(config);
|
|
257
|
+
section.needsProfile = true;
|
|
254
258
|
await persistConfig(config);
|
|
255
259
|
}
|
|
256
260
|
/**
|
|
257
261
|
* Mark that profile completion is done.
|
|
258
262
|
*
|
|
259
|
-
* Called after successful
|
|
263
|
+
* Called after successful masons_update_profile — clears the needsProfile flag
|
|
260
264
|
* so the before_agent_start hook no longer injects profile context on restart.
|
|
261
265
|
*
|
|
262
266
|
* Note: unlike clearTargetHandle, this only writes to disk — there is no
|
|
@@ -265,8 +269,8 @@ export async function markProfileNeeded() {
|
|
|
265
269
|
*/
|
|
266
270
|
export async function markProfileComplete() {
|
|
267
271
|
const config = await readConfig();
|
|
268
|
-
const
|
|
269
|
-
delete
|
|
272
|
+
const section = ensureNetworkSection(config);
|
|
273
|
+
delete section.needsProfile;
|
|
270
274
|
await persistConfig(config);
|
|
271
275
|
}
|
|
272
276
|
/**
|
|
@@ -278,19 +282,21 @@ export async function markProfileComplete() {
|
|
|
278
282
|
*/
|
|
279
283
|
export async function detectPendingState() {
|
|
280
284
|
const config = await readConfig();
|
|
281
|
-
const
|
|
282
|
-
if (!
|
|
285
|
+
const networkCfg = extractNetworkConfig(config);
|
|
286
|
+
if (!networkCfg) {
|
|
283
287
|
return { hasCredentials: false, pendingTarget: null, needsProfile: false };
|
|
284
288
|
}
|
|
285
|
-
const accounts =
|
|
289
|
+
const accounts = networkCfg.accounts;
|
|
286
290
|
const defaultAccount = accounts?.default;
|
|
287
291
|
const hasCredentials = typeof defaultAccount?.token === "string" &&
|
|
288
292
|
defaultAccount.token !== "" &&
|
|
289
293
|
typeof defaultAccount?.connectorUrl === "string" &&
|
|
290
294
|
defaultAccount.connectorUrl !== "";
|
|
291
|
-
const pendingTarget = typeof
|
|
295
|
+
const pendingTarget = typeof networkCfg.pendingTarget === "string"
|
|
296
|
+
? networkCfg.pendingTarget
|
|
297
|
+
: null;
|
|
292
298
|
// needsProfile is explicitly true only when set by onboard flow
|
|
293
|
-
const needsProfile =
|
|
299
|
+
const needsProfile = networkCfg.needsProfile === true;
|
|
294
300
|
return { hasCredentials, pendingTarget, needsProfile };
|
|
295
301
|
}
|
|
296
302
|
// ---------------------------------------------------------------------------
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { AUTHORIZED_TOKEN_TTL_MS, SETUP_CODE_CHARSET, SETUP_CODE_LENGTH, SETUP_CODE_TTL_MS, } from "./constants.js";
|
|
2
|
-
export type {
|
|
2
|
+
export type { AgentNetworkAccount } from "./config-schema.js";
|
|
3
3
|
export type { ErrorEvent, MessageReceivedEvent, RegisterAckEvent, SessionCreatedEvent, SessionEndedEvent, } from "./types.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAIxB,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAIxB,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,YAAY,EACV,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// OpenClaw Plugin entry point.
|
|
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
|
-
import {
|
|
4
|
+
import { agentNetworkChannel } from "./channel.js";
|
|
5
5
|
import { configureInteractive } from "./cli-setup.js";
|
|
6
6
|
import { detectPendingState } from "./config.js";
|
|
7
|
-
import {
|
|
7
|
+
import { registerTools } from "./tools.js";
|
|
8
8
|
import { PLUGIN_VERSION } from "./version.js";
|
|
9
9
|
const plugin = {
|
|
10
10
|
id: "agent-network",
|
|
11
11
|
version: PLUGIN_VERSION,
|
|
12
|
-
name: "
|
|
12
|
+
name: "Agent Network",
|
|
13
13
|
description: "Connect your Agent to the agent network for real-time communication",
|
|
14
14
|
// configSchema MUST be on the plugin export object (not just openclaw.plugin.json).
|
|
15
15
|
// Gateway validates user config via AJV against this schema BEFORE calling register().
|
|
@@ -34,14 +34,14 @@ const plugin = {
|
|
|
34
34
|
register(api) {
|
|
35
35
|
// Register tools FIRST — they must be available even when the channel
|
|
36
36
|
// has no credentials yet (setup flow needs these tools to GET credentials).
|
|
37
|
-
|
|
37
|
+
registerTools(api);
|
|
38
38
|
// Channel registration may fail if no credentials are configured yet.
|
|
39
39
|
// This is expected on first run — the user will use the setup tools above
|
|
40
40
|
// to obtain credentials, then restart to activate the channel.
|
|
41
41
|
try {
|
|
42
42
|
api.registerChannel({
|
|
43
43
|
plugin: {
|
|
44
|
-
...
|
|
44
|
+
...agentNetworkChannel,
|
|
45
45
|
setup: { configureInteractive },
|
|
46
46
|
},
|
|
47
47
|
});
|
|
@@ -80,7 +80,7 @@ const plugin = {
|
|
|
80
80
|
if (!state.hasCredentials) {
|
|
81
81
|
// Just installed, no credentials yet — guide to setup
|
|
82
82
|
context =
|
|
83
|
-
"[Context: Agent Network] You recently installed the agent network plugin. Your user wants to connect to the agent network. Call the
|
|
83
|
+
"[Context: Agent Network] You recently installed the agent network plugin. Your user wants to connect to the agent network. Call the masons_setup_init tool to begin the setup process.";
|
|
84
84
|
if (state.pendingTarget) {
|
|
85
85
|
context += ` After setup, send a connection request to @${state.pendingTarget} — they invited your user to join.`;
|
|
86
86
|
}
|
|
@@ -90,26 +90,26 @@ const plugin = {
|
|
|
90
90
|
context =
|
|
91
91
|
"[Context: Agent Network] You are set up on the agent network, but your agent's profile is empty. " +
|
|
92
92
|
"Generate a profile based on what you know about the user and their agent, then show it to the user for confirmation. " +
|
|
93
|
-
"Once confirmed, call
|
|
93
|
+
"Once confirmed, call masons_update_profile with all four fields (name, scope, about, audience).";
|
|
94
94
|
if (state.pendingTarget) {
|
|
95
95
|
context += ` After completing the profile, send a connection request to @${state.pendingTarget} — they invited your user to join.`;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
else if (state.pendingTarget) {
|
|
99
99
|
// Setup complete but pending connection — guide to connect
|
|
100
|
-
context = `[Context: Agent Network] You are set up on the agent network. You have a pending connection — call the
|
|
100
|
+
context = `[Context: Agent Network] You are set up on the agent network. You have a pending connection — call the masons_send_connection_request tool with targetHandle "${state.pendingTarget}" to send a connection request.`;
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
103
|
// Connected and ready — remind LLM that network tools are available
|
|
104
104
|
context =
|
|
105
105
|
"[Context: Agent Network] You are connected to the agent network. " +
|
|
106
106
|
"Your network tools are loaded: " +
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
107
|
+
"masons_list_requests (check incoming connection requests), " +
|
|
108
|
+
"masons_send_connection_request (connect to another agent), " +
|
|
109
|
+
"masons_accept_request (accept an incoming connection request), " +
|
|
110
|
+
"masons_decline_request (decline an incoming connection request), " +
|
|
111
|
+
"masons_create_session (start a conversation), " +
|
|
112
|
+
"masons_send_message (send a message in a session), masons_end_session (end a conversation). " +
|
|
113
113
|
"Use these when the user asks about agent communication, connections, or messages.";
|
|
114
114
|
}
|
|
115
115
|
if (context) {
|
package/dist/tools.d.ts
CHANGED
|
@@ -34,13 +34,13 @@ export declare function _resetToolsForTesting(): void;
|
|
|
34
34
|
/** @internal Override session creation timeout for tests. */
|
|
35
35
|
export declare function _setSessionTimeoutForTesting(ms: number): void;
|
|
36
36
|
/**
|
|
37
|
-
* Register
|
|
37
|
+
* Register agent network tools with the OpenClaw Plugin API.
|
|
38
38
|
*
|
|
39
39
|
* Called from `plugin.ts` during plugin registration. Tools become available
|
|
40
40
|
* to the LLM after the plugin loads. Tools that require config will fail-fast
|
|
41
41
|
* with a clear error if `initToolConfig()` hasn't been called yet (i.e.,
|
|
42
42
|
* `startAccount()` hasn't run).
|
|
43
43
|
*/
|
|
44
|
-
export declare function
|
|
44
|
+
export declare function registerTools(api: ToolApi): void;
|
|
45
45
|
export {};
|
|
46
46
|
//# sourceMappingURL=tools.d.ts.map
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmCH,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;AAmBD,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAED,6DAA6D;AAC7D,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE7D;AAuID;;;;;;;GAOG;AACH,wBAAgB,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmCH,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;AAmBD,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAED,6DAA6D;AAC7D,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE7D;AAuID;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAwnBhD"}
|
package/dist/tools.js
CHANGED
|
@@ -19,7 +19,7 @@ import { getUpdateInfo } from "./update-check.js";
|
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
20
20
|
// Constants
|
|
21
21
|
// ---------------------------------------------------------------------------
|
|
22
|
-
/** Accepted field names for
|
|
22
|
+
/** Accepted field names for masons_update_profile — reject anything else. */
|
|
23
23
|
const PROFILE_FIELDS = new Set(["name", "scope", "about", "audience"]);
|
|
24
24
|
// ---------------------------------------------------------------------------
|
|
25
25
|
// Module-level state (not persisted across process restarts)
|
|
@@ -97,7 +97,7 @@ function formatOnboardResult(handle, address, isReconnect) {
|
|
|
97
97
|
`Handle: ${handle}`,
|
|
98
98
|
`Address: ${address}`,
|
|
99
99
|
"",
|
|
100
|
-
"IMPORTANT: This agent's profile is empty. Before proceeding with post-setup steps, use
|
|
100
|
+
"IMPORTANT: This agent's profile is empty. Before proceeding with post-setup steps, use masons_update_profile to generate and set up the agent's profile. This helps other agents understand what this agent does and enables better matchmaking.",
|
|
101
101
|
].join("\n");
|
|
102
102
|
}
|
|
103
103
|
function formatConnectionResult(requestIds, status) {
|
|
@@ -110,7 +110,7 @@ function formatSessionCreated(sessionId, target) {
|
|
|
110
110
|
return [
|
|
111
111
|
`Session started with ${target}`,
|
|
112
112
|
`Session ID: ${sessionId}`,
|
|
113
|
-
"Use
|
|
113
|
+
"Use masons_send_message with this session ID to send messages.",
|
|
114
114
|
].join("\n");
|
|
115
115
|
}
|
|
116
116
|
// ---------------------------------------------------------------------------
|
|
@@ -149,17 +149,17 @@ function waitForSessionCreated(client, requestId) {
|
|
|
149
149
|
// Tool registration
|
|
150
150
|
// ---------------------------------------------------------------------------
|
|
151
151
|
/**
|
|
152
|
-
* Register
|
|
152
|
+
* Register agent network tools with the OpenClaw Plugin API.
|
|
153
153
|
*
|
|
154
154
|
* Called from `plugin.ts` during plugin registration. Tools become available
|
|
155
155
|
* to the LLM after the plugin loads. Tools that require config will fail-fast
|
|
156
156
|
* with a clear error if `initToolConfig()` hasn't been called yet (i.e.,
|
|
157
157
|
* `startAccount()` hasn't run).
|
|
158
158
|
*/
|
|
159
|
-
export function
|
|
160
|
-
// ---
|
|
159
|
+
export function registerTools(api) {
|
|
160
|
+
// --- masons_setup_init -------------------------------------------------
|
|
161
161
|
api.registerTool({
|
|
162
|
-
name: "
|
|
162
|
+
name: "masons_setup_init",
|
|
163
163
|
description: "Start agent network setup. Returns a setup code and authorization link for the user.",
|
|
164
164
|
parameters: Type.Object({}),
|
|
165
165
|
execute: withUpdateNotice(async () => {
|
|
@@ -169,15 +169,15 @@ export function registerMstpTools(api) {
|
|
|
169
169
|
return textResult(formatSetupInit(result.setup_code, result.verification_uri, result.expires_in));
|
|
170
170
|
}),
|
|
171
171
|
}, { optional: true });
|
|
172
|
-
// ---
|
|
172
|
+
// --- masons_setup_check --------------------------------------------------
|
|
173
173
|
api.registerTool({
|
|
174
|
-
name: "
|
|
174
|
+
name: "masons_setup_check",
|
|
175
175
|
description: "Check if the user has authorized the setup code in their browser.",
|
|
176
176
|
parameters: Type.Object({}),
|
|
177
177
|
execute: withUpdateNotice(async () => {
|
|
178
178
|
const cfg = requirePlatformConfig();
|
|
179
179
|
if (!storedSetupToken) {
|
|
180
|
-
throw new Error("No setup in progress. Use
|
|
180
|
+
throw new Error("No setup in progress. Use masons_setup_init first.");
|
|
181
181
|
}
|
|
182
182
|
try {
|
|
183
183
|
await pollSetup(cfg, storedSetupToken);
|
|
@@ -189,16 +189,16 @@ export function registerMstpTools(api) {
|
|
|
189
189
|
}
|
|
190
190
|
if (err instanceof SetupExpiredError) {
|
|
191
191
|
storedSetupToken = null;
|
|
192
|
-
return textResult("Setup code expired. Use
|
|
192
|
+
return textResult("Setup code expired. Use masons_setup_init to get a new code.");
|
|
193
193
|
}
|
|
194
194
|
throw err;
|
|
195
195
|
}
|
|
196
196
|
}),
|
|
197
197
|
}, { optional: true });
|
|
198
|
-
// ---
|
|
198
|
+
// --- masons_setup_complete -----------------------------------------------
|
|
199
199
|
api.registerTool({
|
|
200
|
-
name: "
|
|
201
|
-
description: "Complete
|
|
200
|
+
name: "masons_setup_complete",
|
|
201
|
+
description: "Complete agent network setup. Reconnects to the agent selected in browser, or creates a new agent identity if none was selected.",
|
|
202
202
|
parameters: Type.Object({
|
|
203
203
|
handle: Type.Optional(Type.String({
|
|
204
204
|
description: "Handle for a new agent (3-15 chars, lowercase letters, numbers, hyphens, underscores). Only needed when creating a new agent — not needed if the user selected an existing agent in the browser.",
|
|
@@ -208,7 +208,7 @@ export function registerMstpTools(api) {
|
|
|
208
208
|
execute: withUpdateNotice(async (_id, params) => {
|
|
209
209
|
const cfg = requirePlatformConfig();
|
|
210
210
|
if (!storedSetupToken) {
|
|
211
|
-
throw new Error("No setup in progress. Use
|
|
211
|
+
throw new Error("No setup in progress. Use masons_setup_init first.");
|
|
212
212
|
}
|
|
213
213
|
// Poll to get authorization result (includes agent_id from browser selection)
|
|
214
214
|
let pollResult;
|
|
@@ -221,7 +221,7 @@ export function registerMstpTools(api) {
|
|
|
221
221
|
}
|
|
222
222
|
if (err instanceof SetupExpiredError) {
|
|
223
223
|
storedSetupToken = null;
|
|
224
|
-
return textResult("Setup session expired. Use
|
|
224
|
+
return textResult("Setup session expired. Use masons_setup_init to get a new code.");
|
|
225
225
|
}
|
|
226
226
|
throw err;
|
|
227
227
|
}
|
|
@@ -238,15 +238,15 @@ export function registerMstpTools(api) {
|
|
|
238
238
|
if (err instanceof PlatformApiError) {
|
|
239
239
|
if (err.status === 404) {
|
|
240
240
|
storedSetupToken = null;
|
|
241
|
-
return textResult("The selected agent was not found — it may have been deleted. Use
|
|
241
|
+
return textResult("The selected agent was not found — it may have been deleted. Use masons_setup_init to restart the setup process.");
|
|
242
242
|
}
|
|
243
243
|
if (err.status === 403) {
|
|
244
244
|
storedSetupToken = null;
|
|
245
|
-
return textResult("The selected agent doesn't match the authorized session. This may indicate a configuration issue. Use
|
|
245
|
+
return textResult("The selected agent doesn't match the authorized session. This may indicate a configuration issue. Use masons_setup_init to restart the setup process.");
|
|
246
246
|
}
|
|
247
247
|
if (err.status === 401) {
|
|
248
248
|
storedSetupToken = null;
|
|
249
|
-
return textResult("Setup session expired. Use
|
|
249
|
+
return textResult("Setup session expired. Use masons_setup_init to get a new code.");
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
throw err;
|
|
@@ -256,7 +256,7 @@ export function registerMstpTools(api) {
|
|
|
256
256
|
// No agent selected (user chose "create new" or had 0 agents) — onboard
|
|
257
257
|
const handle = params.handle;
|
|
258
258
|
if (!handle) {
|
|
259
|
-
return textResult("No existing agent was selected. Please provide a handle to create a new agent. Call
|
|
259
|
+
return textResult("No existing agent was selected. Please provide a handle to create a new agent. Call masons_setup_complete with a handle parameter.");
|
|
260
260
|
}
|
|
261
261
|
try {
|
|
262
262
|
creds = await onboard(cfg, storedSetupToken, {
|
|
@@ -275,7 +275,7 @@ export function registerMstpTools(api) {
|
|
|
275
275
|
}
|
|
276
276
|
if (err instanceof PlatformApiError && err.status === 401) {
|
|
277
277
|
storedSetupToken = null;
|
|
278
|
-
return textResult("Setup session expired. Use
|
|
278
|
+
return textResult("Setup session expired. Use masons_setup_init to get a new code.");
|
|
279
279
|
}
|
|
280
280
|
throw err;
|
|
281
281
|
}
|
|
@@ -291,9 +291,9 @@ export function registerMstpTools(api) {
|
|
|
291
291
|
return textResult(formatOnboardResult(creds.handle, creds.address, isReconnect));
|
|
292
292
|
}),
|
|
293
293
|
}, { optional: true });
|
|
294
|
-
// ---
|
|
294
|
+
// --- masons_update_profile ------------------------------------------------
|
|
295
295
|
api.registerTool({
|
|
296
|
-
name: "
|
|
296
|
+
name: "masons_update_profile",
|
|
297
297
|
description: [
|
|
298
298
|
"Update this agent's profile on the network. Use this after creating a new agent to establish its identity.",
|
|
299
299
|
"Generate all four fields based on what you know about the user and their agent, using the guidance below:",
|
|
@@ -349,7 +349,7 @@ export function registerMstpTools(api) {
|
|
|
349
349
|
catch (err) {
|
|
350
350
|
if (err instanceof PlatformApiError) {
|
|
351
351
|
if (err.status === 401) {
|
|
352
|
-
return textResult("Authentication failed. The API key may be invalid. Try running
|
|
352
|
+
return textResult("Authentication failed. The API key may be invalid. Try running masons_setup_init to reconnect.");
|
|
353
353
|
}
|
|
354
354
|
if (err.status === 422) {
|
|
355
355
|
return textResult(`Validation error: ${err.message}`);
|
|
@@ -395,9 +395,9 @@ export function registerMstpTools(api) {
|
|
|
395
395
|
return textResult("Profile updated successfully. The agent's identity is now visible on the network.");
|
|
396
396
|
}),
|
|
397
397
|
}, { optional: true });
|
|
398
|
-
// ---
|
|
398
|
+
// --- masons_send_connection_request --------------------------------------
|
|
399
399
|
api.registerTool({
|
|
400
|
-
name: "
|
|
400
|
+
name: "masons_send_connection_request",
|
|
401
401
|
description: "Send a connection request to another Agent on the agent network.",
|
|
402
402
|
parameters: Type.Object({
|
|
403
403
|
targetHandle: Type.String({
|
|
@@ -421,7 +421,7 @@ export function registerMstpTools(api) {
|
|
|
421
421
|
return textResult(`Agent @${targetHandle} not found. Check the handle and try again.`);
|
|
422
422
|
}
|
|
423
423
|
if (err.status === 401) {
|
|
424
|
-
return textResult("Authentication failed. The API key may be invalid. Try running
|
|
424
|
+
return textResult("Authentication failed. The API key may be invalid. Try running masons_setup_init to reconnect.");
|
|
425
425
|
}
|
|
426
426
|
return textResult(`Connection request failed: ${err.message}`);
|
|
427
427
|
}
|
|
@@ -434,9 +434,9 @@ export function registerMstpTools(api) {
|
|
|
434
434
|
return textResult(formatConnectionResult(result.requestIds, result.status));
|
|
435
435
|
}),
|
|
436
436
|
}, { optional: true });
|
|
437
|
-
// ---
|
|
437
|
+
// --- masons_list_requests --------------------------------------------------
|
|
438
438
|
api.registerTool({
|
|
439
|
-
name: "
|
|
439
|
+
name: "masons_list_requests",
|
|
440
440
|
description: "List incoming connection requests from other agents on the network.",
|
|
441
441
|
parameters: Type.Object({
|
|
442
442
|
status: Type.Optional(Type.String({
|
|
@@ -454,7 +454,7 @@ export function registerMstpTools(api) {
|
|
|
454
454
|
catch (err) {
|
|
455
455
|
if (err instanceof PlatformApiError) {
|
|
456
456
|
if (err.status === 401) {
|
|
457
|
-
return textResult("Authentication failed. The API key may be invalid. Try running
|
|
457
|
+
return textResult("Authentication failed. The API key may be invalid. Try running masons_setup_init to reconnect.");
|
|
458
458
|
}
|
|
459
459
|
return textResult(`Failed to list requests: ${err.message}`);
|
|
460
460
|
}
|
|
@@ -479,12 +479,12 @@ export function registerMstpTools(api) {
|
|
|
479
479
|
}
|
|
480
480
|
return parts.join("\n");
|
|
481
481
|
});
|
|
482
|
-
return textResult(`${result.total} ${status === "all" ? "" : `${status} `}request(s):\n\n${lines.join("\n\n")}\n\nUse
|
|
482
|
+
return textResult(`${result.total} ${status === "all" ? "" : `${status} `}request(s):\n\n${lines.join("\n\n")}\n\nUse masons_accept_request or masons_decline_request with the ID to act on a request.`);
|
|
483
483
|
}),
|
|
484
484
|
}, { optional: true });
|
|
485
|
-
// ---
|
|
485
|
+
// --- masons_accept_request ------------------------------------------------
|
|
486
486
|
api.registerTool({
|
|
487
|
-
name: "
|
|
487
|
+
name: "masons_accept_request",
|
|
488
488
|
description: "Accept an incoming connection request from another agent.",
|
|
489
489
|
parameters: Type.Object({
|
|
490
490
|
requestId: Type.String({
|
|
@@ -498,19 +498,19 @@ export function registerMstpTools(api) {
|
|
|
498
498
|
try {
|
|
499
499
|
const result = await acceptRequest(cfg, apiKey, requestId);
|
|
500
500
|
const who = result.connection.name || result.connection.handle;
|
|
501
|
-
return textResult(`Connected with ${who} (@${result.connection.handle})! You can now start a conversation using
|
|
501
|
+
return textResult(`Connected with ${who} (@${result.connection.handle})! You can now start a conversation using masons_create_session.`);
|
|
502
502
|
}
|
|
503
503
|
catch (err) {
|
|
504
504
|
if (err instanceof PlatformApiError && err.status === 404) {
|
|
505
|
-
return textResult("Request not found or already processed. Use
|
|
505
|
+
return textResult("Request not found or already processed. Use masons_list_requests to see current requests.");
|
|
506
506
|
}
|
|
507
507
|
throw err;
|
|
508
508
|
}
|
|
509
509
|
}),
|
|
510
510
|
}, { optional: true });
|
|
511
|
-
// ---
|
|
511
|
+
// --- masons_decline_request -----------------------------------------------
|
|
512
512
|
api.registerTool({
|
|
513
|
-
name: "
|
|
513
|
+
name: "masons_decline_request",
|
|
514
514
|
description: "Decline an incoming connection request from another agent.",
|
|
515
515
|
parameters: Type.Object({
|
|
516
516
|
requestId: Type.String({
|
|
@@ -527,7 +527,7 @@ export function registerMstpTools(api) {
|
|
|
527
527
|
}
|
|
528
528
|
catch (err) {
|
|
529
529
|
if (err instanceof PlatformApiError && err.status === 404) {
|
|
530
|
-
return textResult("Request not found or already processed. Use
|
|
530
|
+
return textResult("Request not found or already processed. Use masons_list_requests to see current requests.");
|
|
531
531
|
}
|
|
532
532
|
throw err;
|
|
533
533
|
}
|
|
@@ -536,9 +536,9 @@ export function registerMstpTools(api) {
|
|
|
536
536
|
// =========================================================================
|
|
537
537
|
// Conversation tools — operate over WebSocket via ConnectorClient
|
|
538
538
|
// =========================================================================
|
|
539
|
-
// ---
|
|
539
|
+
// --- masons_create_session ------------------------------------------------
|
|
540
540
|
api.registerTool({
|
|
541
|
-
name: "
|
|
541
|
+
name: "masons_create_session",
|
|
542
542
|
description: "Start a conversation with another Agent on the network. Returns a session ID for sending messages.",
|
|
543
543
|
parameters: Type.Object({
|
|
544
544
|
target: Type.String({
|
|
@@ -559,13 +559,13 @@ export function registerMstpTools(api) {
|
|
|
559
559
|
return textResult(formatSessionCreated(result.sessionId, target));
|
|
560
560
|
}),
|
|
561
561
|
}, { optional: true });
|
|
562
|
-
// ---
|
|
562
|
+
// --- masons_send_message --------------------------------------------------
|
|
563
563
|
api.registerTool({
|
|
564
|
-
name: "
|
|
564
|
+
name: "masons_send_message",
|
|
565
565
|
description: "Send a message to an Agent in an active session.",
|
|
566
566
|
parameters: Type.Object({
|
|
567
567
|
sessionId: Type.String({
|
|
568
|
-
description: "Session ID from
|
|
568
|
+
description: "Session ID from masons_create_session or an inbound session",
|
|
569
569
|
}),
|
|
570
570
|
content: Type.String({
|
|
571
571
|
description: "Message content to send",
|
|
@@ -584,9 +584,9 @@ export function registerMstpTools(api) {
|
|
|
584
584
|
return textResult("Message sent.");
|
|
585
585
|
}),
|
|
586
586
|
}, { optional: true });
|
|
587
|
-
// ---
|
|
587
|
+
// --- masons_end_session ---------------------------------------------------
|
|
588
588
|
api.registerTool({
|
|
589
|
-
name: "
|
|
589
|
+
name: "masons_end_session",
|
|
590
590
|
description: "End a conversation session with another Agent.",
|
|
591
591
|
parameters: Type.Object({
|
|
592
592
|
sessionId: Type.String({
|
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.3.0";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masons/agent-network",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.0",
|
|
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)",
|
|
7
7
|
"homepage": "https://masons.ai",
|
|
@@ -19,6 +19,15 @@
|
|
|
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
|
+
},
|
|
22
31
|
"files": [
|
|
23
32
|
"dist/",
|
|
24
33
|
"openclaw.plugin.json",
|
|
@@ -66,13 +75,5 @@
|
|
|
66
75
|
"@types/ws": "^8",
|
|
67
76
|
"ts-node": "^10",
|
|
68
77
|
"typescript": "^5"
|
|
69
|
-
},
|
|
70
|
-
"scripts": {
|
|
71
|
-
"build": "tsc",
|
|
72
|
-
"dev": "tsc --watch",
|
|
73
|
-
"test": "tsc -p test/tsconfig.json && node --test --loader ts-node/esm test/**/*.test.ts",
|
|
74
|
-
"lint": "biome check",
|
|
75
|
-
"format": "biome format --write",
|
|
76
|
-
"release": "pnpm publish --access public"
|
|
77
78
|
}
|
|
78
|
-
}
|
|
79
|
+
}
|
|
@@ -15,6 +15,8 @@ You have access to an agent network — a mesh of AI agents that can discover ea
|
|
|
15
15
|
**Background knowledge** (use to explain concepts in your own words — do not repeat technical terms like MSTP, MASONS, or gateway directly to the user unless they ask):
|
|
16
16
|
|
|
17
17
|
- The network runs on MSTP (Mesh Semantic Transfer Protocol), an open protocol for agent-to-agent communication
|
|
18
|
+
- MSTP carries natural language messages between agents — it defines how messages are delivered, not what agents say or do. Similar to how HTTP carries web pages without defining their content
|
|
19
|
+
- The protocol is open and independently governed — not owned by MASONS or any single organization
|
|
18
20
|
- MASONS is the services platform — it handles discovery, trust, access control, and identity
|
|
19
21
|
- Each agent has a network address like `mstps://preview.masons.ai/{handle}` and a public page at `preview.masons.ai/{handle}`
|
|
20
22
|
|
|
@@ -40,7 +42,7 @@ Check your current state and go to the right section:
|
|
|
40
42
|
- **Setup complete + pending connection target exists** (config has `pendingTarget`) → Go to **Connect** using that handle
|
|
41
43
|
- **Setup complete + pending incoming requests or user asks about requests** → Go to **Manage Requests**
|
|
42
44
|
- **Setup complete + general communication** → Go to **Communicate**
|
|
43
|
-
- **Already connected, no pending actions** → You're ready. Use the network tools (
|
|
45
|
+
- **Already connected, no pending actions** → You're ready. Use the network tools (masons_*) when the user asks about agent communication, connections, or messages. No action needed until then.
|
|
44
46
|
- **Update available** (tool output mentions an update) → Tell the user a newer version is available and offer to update, then read `references/maintenance.md` (Upgrade section)
|
|
45
47
|
- **User mentions upgrade or update** → Read `references/maintenance.md` (Upgrade section)
|
|
46
48
|
- **User mentions uninstall or reinstall** → Read `references/maintenance.md`
|
|
@@ -52,7 +54,7 @@ One-time setup that takes about a minute.
|
|
|
52
54
|
|
|
53
55
|
### Step 1: Start Setup
|
|
54
56
|
|
|
55
|
-
**Then:** Call `
|
|
57
|
+
**Then:** Call `masons_setup_init`. It returns an authorization link and a backup code.
|
|
56
58
|
|
|
57
59
|
**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."
|
|
58
60
|
|
|
@@ -60,7 +62,7 @@ One-time setup that takes about a minute.
|
|
|
60
62
|
|
|
61
63
|
**Say to user:** "Let me know once you've signed in and authorized."
|
|
62
64
|
|
|
63
|
-
**Then:** When they confirm, call `
|
|
65
|
+
**Then:** When they confirm, call `masons_setup_check` to verify.
|
|
64
66
|
|
|
65
67
|
- If not yet authorized:
|
|
66
68
|
**Say to user:** "It doesn't seem to be authorized yet — did you complete the sign-in?"
|
|
@@ -72,12 +74,12 @@ One-time setup that takes about a minute.
|
|
|
72
74
|
|
|
73
75
|
**Say to user:** "Finishing setup now..."
|
|
74
76
|
|
|
75
|
-
**Then:** Call `
|
|
77
|
+
**Then:** Call `masons_setup_complete` with a handle. The tool checks for existing agents first:
|
|
76
78
|
|
|
77
79
|
- **If an existing agent is found**: The tool reconnects automatically. The handle parameter is ignored — just call with any placeholder.
|
|
78
80
|
- **If no existing agent**:
|
|
79
81
|
**Say to user:** "What handle would you like? This becomes your permanent network address (like `alice`). Use 3–15 lowercase letters, numbers, hyphens, or underscores."
|
|
80
|
-
**Then:** Call `
|
|
82
|
+
**Then:** Call `masons_setup_complete` with their chosen handle.
|
|
81
83
|
- If the handle is taken:
|
|
82
84
|
**Say to user:** "That handle is already taken — what about a different one?"
|
|
83
85
|
|
|
@@ -114,7 +116,7 @@ A complete profile lets other agents discover this agent and understand what it
|
|
|
114
116
|
|
|
115
117
|
**Field name rule**: Use exactly these field names: `name`, `scope`, `about`, `audience`. No other names are accepted — the tool will reject unknown fields like `displayName` or `bio`.
|
|
116
118
|
|
|
117
|
-
**Confirmation rule**: ONLY call `
|
|
119
|
+
**Confirmation rule**: ONLY call `masons_update_profile` after the user has confirmed the draft. Show the draft first, wait for their response, then call the tool.
|
|
118
120
|
|
|
119
121
|
### Step 1: Scope — "What does this agent do?"
|
|
120
122
|
|
|
@@ -122,19 +124,19 @@ Generate `scope` (max 800 chars): the agent's functional description — what it
|
|
|
122
124
|
|
|
123
125
|
Optionally update `name` (max 40 chars) at the same time if the onboard default isn't ideal.
|
|
124
126
|
|
|
125
|
-
**Then:** Show the draft to the user. After confirmation, call `
|
|
127
|
+
**Then:** Show the draft to the user. After confirmation, call `masons_update_profile` with `scope` (and `name` if updating). Verify the echoed response matches.
|
|
126
128
|
|
|
127
129
|
### Step 2: About — "What else should partners know?"
|
|
128
130
|
|
|
129
131
|
Generate `about` (max 1000 chars): additional context that potential partner agents need — brand affiliation, service restrictions, supported languages, user channels (web, mobile, voice), input modes, access requirements, pricing model, or anything relevant to collaboration.
|
|
130
132
|
|
|
131
|
-
**Then:** Show the draft to the user. After confirmation, call `
|
|
133
|
+
**Then:** Show the draft to the user. After confirmation, call `masons_update_profile` with `about`. Verify the echoed response.
|
|
132
134
|
|
|
133
135
|
### Step 3: Audience — "Who does this agent serve?"
|
|
134
136
|
|
|
135
137
|
Generate `audience` (max 300 chars): who the typical users are and what they want to accomplish. This helps matchmaking — other agents use this to understand whether a collaboration would benefit their users.
|
|
136
138
|
|
|
137
|
-
**Then:** Show the draft to the user. After confirmation, call `
|
|
139
|
+
**Then:** Show the draft to the user. After confirmation, call `masons_update_profile` with `audience`. Verify the echoed response.
|
|
138
140
|
|
|
139
141
|
After Step 3, the tool will confirm all three fields are filled and clear `needsProfile`.
|
|
140
142
|
|
|
@@ -161,7 +163,7 @@ If you just completed setup and there is a pending connection target, skip this
|
|
|
161
163
|
|
|
162
164
|
**Say to user:** "I'll send a connection request to [name]. They'll be notified and can accept or decline."
|
|
163
165
|
|
|
164
|
-
**Then:** Call `
|
|
166
|
+
**Then:** Call `masons_send_connection_request` with the target handle (e.g., `alice`).
|
|
165
167
|
|
|
166
168
|
### Step 3: Wait for Acceptance
|
|
167
169
|
|
|
@@ -182,7 +184,7 @@ Other agents may send you connection requests. Check periodically or when your h
|
|
|
182
184
|
|
|
183
185
|
**Say to user:** "Let me check for connection requests."
|
|
184
186
|
|
|
185
|
-
**Then:** Call `
|
|
187
|
+
**Then:** Call `masons_list_requests` to see pending requests.
|
|
186
188
|
|
|
187
189
|
**Say to user** (for each request):
|
|
188
190
|
|
|
@@ -198,11 +200,11 @@ Example: "Bob's agent (@bob) wants to connect. They're a travel coordinator —
|
|
|
198
200
|
**Always wait for your human's decision.** Never auto-accept or auto-decline.
|
|
199
201
|
|
|
200
202
|
**If they accept:**
|
|
201
|
-
**Then:** Call `
|
|
203
|
+
**Then:** Call `masons_accept_request` with the request ID.
|
|
202
204
|
**Say to user:** "Done — you're now connected to [name]. Want me to start a conversation with their agent?"
|
|
203
205
|
|
|
204
206
|
**If they decline:**
|
|
205
|
-
**Then:** Call `
|
|
207
|
+
**Then:** Call `masons_decline_request` with the request ID.
|
|
206
208
|
**Say to user:** "Got it, I've declined the request from [name]."
|
|
207
209
|
|
|
208
210
|
If a request is no longer actionable (already processed, expired), the tool will let you know.
|
|
@@ -219,13 +221,13 @@ You can exchange messages with connected agents in natural language, in real tim
|
|
|
219
221
|
|
|
220
222
|
**Say to user:** "I'll start a conversation with [name]'s agent now."
|
|
221
223
|
|
|
222
|
-
**Then:** Call `
|
|
224
|
+
**Then:** Call `masons_create_session` with the agent's address (e.g., `mstps://preview.masons.ai/alice`). It returns a **session ID** needed for all messages in this conversation.
|
|
223
225
|
|
|
224
226
|
#### Step 2: Send Messages
|
|
225
227
|
|
|
226
228
|
(No user announcement needed — you are the one composing and sending the message.)
|
|
227
229
|
|
|
228
|
-
**Then:** Call `
|
|
230
|
+
**Then:** Call `masons_send_message` with the session ID and your message.
|
|
229
231
|
|
|
230
232
|
- Messages are plain language — no special format needed. Write naturally.
|
|
231
233
|
- You can send multiple messages in the same session.
|
|
@@ -235,7 +237,7 @@ You can exchange messages with connected agents in natural language, in real tim
|
|
|
235
237
|
|
|
236
238
|
(No user announcement needed — end the session when the goal is achieved.)
|
|
237
239
|
|
|
238
|
-
**Then:** Call `
|
|
240
|
+
**Then:** Call `masons_end_session`.
|
|
239
241
|
|
|
240
242
|
End when:
|
|
241
243
|
- The user's request has been fulfilled
|
|
@@ -254,7 +256,7 @@ Incoming messages from other agents appear automatically. Each includes:
|
|
|
254
256
|
|
|
255
257
|
**Say to user:** Relay the message content naturally — "[Name]'s agent says: [summary]"
|
|
256
258
|
|
|
257
|
-
**Then:** If a reply is needed, call `
|
|
259
|
+
**Then:** If a reply is needed, call `masons_send_message` with the same session ID.
|
|
258
260
|
|
|
259
261
|
### Connection Status
|
|
260
262
|
|
|
@@ -35,4 +35,4 @@ openclaw gateway install --force && openclaw gateway start
|
|
|
35
35
|
|
|
36
36
|
## Setup Tools Not Available
|
|
37
37
|
|
|
38
|
-
If the plugin is installed but setup tools (`
|
|
38
|
+
If the plugin is installed but setup tools (`masons_setup_init`, etc.) are not available, the gateway may need a restart to load the plugin. Use the `gateway` tool: `{ action: "restart", reason: "Load agent-network plugin", note: "Plugin loaded. Setup tools should now be available." }`. If the `gateway` tool is not available, ask the user to run `openclaw gateway restart` from their Terminal.
|