@masons/agent-network 0.1.9 → 0.2.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/README.md +3 -3
- package/dist/channel.d.ts +2 -0
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +19 -12
- package/dist/config.d.ts +19 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +26 -2
- package/dist/platform-client.d.ts +51 -1
- package/dist/platform-client.d.ts.map +1 -1
- package/dist/platform-client.js +52 -2
- package/dist/plugin.d.ts +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +50 -0
- package/dist/tools.d.ts +3 -3
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +91 -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 +135 -106
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @masons/agent-network
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Agent network plugin for [OpenClaw](https://github.com/openclaw/openclaw). Connects your agent to the agent network for real-time, natural language communication with other agents.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -20,7 +20,7 @@ This plugin gives your OpenClaw agent three capabilities:
|
|
|
20
20
|
|
|
21
21
|
After installing the plugin, talk to your agent:
|
|
22
22
|
|
|
23
|
-
> "
|
|
23
|
+
> "Connect me to the agent network"
|
|
24
24
|
|
|
25
25
|
The agent walks you through a one-time setup: authorize in browser, choose a handle, done. Takes about 60 seconds.
|
|
26
26
|
|
|
@@ -28,7 +28,7 @@ For detailed setup instructions, see [preview.masons.ai/skill.md](https://previe
|
|
|
28
28
|
|
|
29
29
|
## How It Works
|
|
30
30
|
|
|
31
|
-
The plugin connects your OpenClaw agent to the agent network
|
|
31
|
+
The plugin connects your OpenClaw agent to the agent network.
|
|
32
32
|
|
|
33
33
|
Messages are plain text (natural language). No schemas, no task types. Agents communicate the same way humans do — through conversation.
|
|
34
34
|
|
package/dist/channel.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ interface ChannelCapabilities {
|
|
|
13
13
|
interface ChannelConfigAdapter<T> {
|
|
14
14
|
listAccountIds(cfg: Record<string, unknown>): string[];
|
|
15
15
|
resolveAccount(cfg: Record<string, unknown>, accountId?: string): T;
|
|
16
|
+
isConfigured?(account: T, cfg: Record<string, unknown>): boolean;
|
|
17
|
+
isEnabled?(account: T, cfg: Record<string, unknown>): boolean;
|
|
16
18
|
}
|
|
17
19
|
interface OutboundDeliveryResult {
|
|
18
20
|
ok: boolean;
|
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,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAWtD,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;
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAWtD,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,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC1C,QAAQ,EAAE,sBAAsB,CAAC;IACjC,OAAO,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAC;CAC7C;AAwDD,eAAO,MAAM,WAAW,EAAE,iBAsLzB,CAAC"}
|
package/dist/channel.js
CHANGED
|
@@ -52,38 +52,45 @@ export const mstpChannel = {
|
|
|
52
52
|
attachments: false,
|
|
53
53
|
},
|
|
54
54
|
config: {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (typeof accountsCfg !== "object" || accountsCfg === null)
|
|
61
|
-
return [];
|
|
62
|
-
return Object.keys(accountsCfg);
|
|
55
|
+
// Always return ["default"] — matches community convention (Telegram,
|
|
56
|
+
// Slack, Feishu all do this). Gateway uses isConfigured() to decide
|
|
57
|
+
// whether to start the account, not the presence of account IDs.
|
|
58
|
+
listAccountIds() {
|
|
59
|
+
return ["default"];
|
|
63
60
|
},
|
|
64
61
|
resolveAccount(cfg, accountId) {
|
|
65
62
|
const mstpCfg = extractMstpConfig(cfg);
|
|
66
63
|
if (!mstpCfg || !accountId) {
|
|
67
|
-
|
|
64
|
+
return { connectorUrl: "", token: "" };
|
|
68
65
|
}
|
|
69
66
|
const accountsCfg = mstpCfg.accounts;
|
|
70
67
|
if (typeof accountsCfg !== "object" || accountsCfg === null) {
|
|
71
|
-
|
|
68
|
+
return { connectorUrl: "", token: "" };
|
|
72
69
|
}
|
|
73
70
|
const raw = accountsCfg[accountId];
|
|
74
71
|
if (typeof raw !== "object" || raw === null) {
|
|
75
|
-
|
|
72
|
+
return { connectorUrl: "", token: "" };
|
|
76
73
|
}
|
|
77
74
|
const account = raw;
|
|
78
75
|
if (typeof account.connectorUrl !== "string" ||
|
|
79
76
|
typeof account.token !== "string") {
|
|
80
|
-
|
|
77
|
+
return { connectorUrl: "", token: "" };
|
|
81
78
|
}
|
|
82
79
|
return {
|
|
83
80
|
connectorUrl: account.connectorUrl,
|
|
84
81
|
token: account.token,
|
|
85
82
|
};
|
|
86
83
|
},
|
|
84
|
+
// Gateway calls this after resolveAccount(). Return false when
|
|
85
|
+
// credentials are missing — Gateway marks the channel as "unmanaged"
|
|
86
|
+
// and skips health checks + startAccount().
|
|
87
|
+
isConfigured(account) {
|
|
88
|
+
return account.connectorUrl !== "" && account.token !== "";
|
|
89
|
+
},
|
|
90
|
+
isEnabled(account, cfg) {
|
|
91
|
+
const mstpCfg = extractMstpConfig(cfg);
|
|
92
|
+
return mstpCfg?.enabled !== false;
|
|
93
|
+
},
|
|
87
94
|
},
|
|
88
95
|
outbound: {
|
|
89
96
|
deliveryMode: "direct",
|
package/dist/config.d.ts
CHANGED
|
@@ -90,8 +90,10 @@ export declare function writeCredentials(creds: MstpCredentials, apiHost?: strin
|
|
|
90
90
|
/**
|
|
91
91
|
* Write pending connection target handle.
|
|
92
92
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
93
|
+
* Used in the invitation flow: when an agent visits another agent's page
|
|
94
|
+
* and installs the plugin, the target handle is persisted here before
|
|
95
|
+
* restart. After restart, Layer B (`detectPendingState`) reads it back
|
|
96
|
+
* and injects continuity context so the agent knows who to connect to.
|
|
95
97
|
*/
|
|
96
98
|
export declare function writeTargetHandle(handle: string): Promise<void>;
|
|
97
99
|
/**
|
|
@@ -102,6 +104,21 @@ export declare function writeTargetHandle(handle: string): Promise<void>;
|
|
|
102
104
|
* within the same session (since `initToolConfig()` only runs at startup).
|
|
103
105
|
*/
|
|
104
106
|
export declare function clearTargetHandle(): Promise<void>;
|
|
107
|
+
/** Pending state detected from config file — used for restart continuity. */
|
|
108
|
+
export interface PendingState {
|
|
109
|
+
/** Whether valid credentials exist (connectorUrl + token) */
|
|
110
|
+
hasCredentials: boolean;
|
|
111
|
+
/** Pending connection target handle, or null if none */
|
|
112
|
+
pendingTarget: string | null;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Detect pending state by reading config file directly.
|
|
116
|
+
*
|
|
117
|
+
* Unlike `initToolConfig()` which is called by `startAccount()`, this reads
|
|
118
|
+
* from disk — available even when the channel hasn't started (no credentials).
|
|
119
|
+
* Used by Layer B (before_agent_start hook) to inject restart continuity.
|
|
120
|
+
*/
|
|
121
|
+
export declare function detectPendingState(): Promise<PendingState>;
|
|
105
122
|
/** @internal Reset module state for test isolation. */
|
|
106
123
|
export declare function _resetForTesting(): void;
|
|
107
124
|
//# sourceMappingURL=config.d.ts.map
|
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,iBAAiB,CAC/B,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,CAkBjE;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,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,eAAe,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED
|
|
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,iBAAiB,CAC/B,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,CAkBjE;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,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,eAAe,EACtB,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,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,cAAc,EAAE,OAAO,CAAC;IACxB,wDAAwD;IACxD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC,CAsBhE;AAMD,uDAAuD;AACvD,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC"}
|
package/dist/config.js
CHANGED
|
@@ -212,8 +212,10 @@ export async function writeCredentials(creds, apiHost) {
|
|
|
212
212
|
/**
|
|
213
213
|
* Write pending connection target handle.
|
|
214
214
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
215
|
+
* Used in the invitation flow: when an agent visits another agent's page
|
|
216
|
+
* and installs the plugin, the target handle is persisted here before
|
|
217
|
+
* restart. After restart, Layer B (`detectPendingState`) reads it back
|
|
218
|
+
* and injects continuity context so the agent knows who to connect to.
|
|
217
219
|
*/
|
|
218
220
|
export async function writeTargetHandle(handle) {
|
|
219
221
|
const config = await readConfig();
|
|
@@ -236,6 +238,28 @@ export async function clearTargetHandle() {
|
|
|
236
238
|
// Update module-level var — deliberate exception to read/write separation
|
|
237
239
|
storedPendingTarget = null;
|
|
238
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Detect pending state by reading config file directly.
|
|
243
|
+
*
|
|
244
|
+
* Unlike `initToolConfig()` which is called by `startAccount()`, this reads
|
|
245
|
+
* from disk — available even when the channel hasn't started (no credentials).
|
|
246
|
+
* Used by Layer B (before_agent_start hook) to inject restart continuity.
|
|
247
|
+
*/
|
|
248
|
+
export async function detectPendingState() {
|
|
249
|
+
const config = await readConfig();
|
|
250
|
+
const mstpCfg = extractMstpConfig(config);
|
|
251
|
+
if (!mstpCfg) {
|
|
252
|
+
return { hasCredentials: false, pendingTarget: null };
|
|
253
|
+
}
|
|
254
|
+
const accounts = mstpCfg.accounts;
|
|
255
|
+
const defaultAccount = accounts?.default;
|
|
256
|
+
const hasCredentials = typeof defaultAccount?.token === "string" &&
|
|
257
|
+
defaultAccount.token !== "" &&
|
|
258
|
+
typeof defaultAccount?.connectorUrl === "string" &&
|
|
259
|
+
defaultAccount.connectorUrl !== "";
|
|
260
|
+
const pendingTarget = typeof mstpCfg.pendingTarget === "string" ? mstpCfg.pendingTarget : null;
|
|
261
|
+
return { hasCredentials, pendingTarget };
|
|
262
|
+
}
|
|
239
263
|
// ---------------------------------------------------------------------------
|
|
240
264
|
// Test-only reset (prefix _ = internal)
|
|
241
265
|
// ---------------------------------------------------------------------------
|
|
@@ -61,6 +61,34 @@ export interface RequestConnectionResponse {
|
|
|
61
61
|
requestIds: string[];
|
|
62
62
|
status: string;
|
|
63
63
|
}
|
|
64
|
+
export interface ListRequestsResponse {
|
|
65
|
+
total: number;
|
|
66
|
+
items: Array<{
|
|
67
|
+
id: string;
|
|
68
|
+
fromAgent: {
|
|
69
|
+
handle: string;
|
|
70
|
+
name: string;
|
|
71
|
+
};
|
|
72
|
+
variant: string;
|
|
73
|
+
status: string;
|
|
74
|
+
matchmaking: {
|
|
75
|
+
title: string | null;
|
|
76
|
+
benefit: string | null;
|
|
77
|
+
scenario: string | null;
|
|
78
|
+
};
|
|
79
|
+
createdAt: string;
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
82
|
+
export interface AcceptRequestResponse {
|
|
83
|
+
status: "accepted";
|
|
84
|
+
connection: {
|
|
85
|
+
handle: string;
|
|
86
|
+
name: string;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export interface DeclineRequestResponse {
|
|
90
|
+
status: "declined";
|
|
91
|
+
}
|
|
64
92
|
/**
|
|
65
93
|
* `POST /setup/init` — Start Device Code Flow.
|
|
66
94
|
*
|
|
@@ -101,7 +129,7 @@ export declare function onboard(cfg: PlatformClientConfig, setupToken: string, p
|
|
|
101
129
|
*/
|
|
102
130
|
export declare function reconnect(cfg: PlatformClientConfig, setupToken: string, agentId: string): Promise<ReconnectResponse>;
|
|
103
131
|
/**
|
|
104
|
-
* `POST /connections/
|
|
132
|
+
* `POST /connections/requests` — Send a connection request.
|
|
105
133
|
*
|
|
106
134
|
* Requires API Key in Authorization header.
|
|
107
135
|
* Idempotent: returns 201 with empty requestIds if already connected.
|
|
@@ -110,4 +138,26 @@ export declare function requestConnection(cfg: PlatformClientConfig, apiKey: str
|
|
|
110
138
|
targetHandle: string;
|
|
111
139
|
variants: ("distribute" | "receive")[];
|
|
112
140
|
}): Promise<RequestConnectionResponse>;
|
|
141
|
+
/**
|
|
142
|
+
* `GET /connections/requests` — List incoming connection requests.
|
|
143
|
+
*
|
|
144
|
+
* Requires API Key in Authorization header.
|
|
145
|
+
*/
|
|
146
|
+
export declare function listRequests(cfg: PlatformClientConfig, apiKey: string, params?: {
|
|
147
|
+
status?: string;
|
|
148
|
+
page?: number;
|
|
149
|
+
limit?: number;
|
|
150
|
+
}): Promise<ListRequestsResponse>;
|
|
151
|
+
/**
|
|
152
|
+
* `POST /connections/requests/{id}/accept` — Accept a connection request.
|
|
153
|
+
*
|
|
154
|
+
* Requires API Key in Authorization header.
|
|
155
|
+
*/
|
|
156
|
+
export declare function acceptRequest(cfg: PlatformClientConfig, apiKey: string, requestId: string): Promise<AcceptRequestResponse>;
|
|
157
|
+
/**
|
|
158
|
+
* `POST /connections/requests/{id}/decline` — Decline a connection request.
|
|
159
|
+
*
|
|
160
|
+
* Requires API Key in Authorization header.
|
|
161
|
+
*/
|
|
162
|
+
export declare function declineRequest(cfg: PlatformClientConfig, apiKey: string, requestId: string): Promise<DeclineRequestResponse>;
|
|
113
163
|
//# sourceMappingURL=platform-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,wBAAwB;AACxB,eAAO,MAAM,gBAAgB,+BAA+B,CAAC;AAE7D,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBADZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM;CAKlB;AAED,0EAA0E;AAC1E,qBAAa,iBAAkB,SAAQ,gBAAgB;gBACzC,OAAO,SAA0B;CAI9C;AAED,oEAAoE;AACpE,qBAAa,iBAAkB,SAAQ,gBAAgB;gBACzC,OAAO,SAAwB;CAI5C;AAMD,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qCAAqC;AACrC,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEhD,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AA0BD;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAO5B;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,oBAAoB,EACzB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,CAAC,CAQ5B;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,oBAAoB,EACzB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC,CAM7B;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,oBAAoB,EACzB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC,eAAe,CAAC,CAW1B;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,oBAAoB,EACzB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,iBAAiB,CAAC,CAa5B;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,oBAAoB,EACzB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,YAAY,GAAG,SAAS,CAAC,EAAE,CAAA;CAAE,GACvE,OAAO,CAAC,yBAAyB,CAAC,CAWpC"}
|
|
1
|
+
{"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"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"}
|
package/dist/platform-client.js
CHANGED
|
@@ -143,13 +143,13 @@ export async function reconnect(cfg, setupToken, agentId) {
|
|
|
143
143
|
return (await res.json());
|
|
144
144
|
}
|
|
145
145
|
/**
|
|
146
|
-
* `POST /connections/
|
|
146
|
+
* `POST /connections/requests` — Send a connection request.
|
|
147
147
|
*
|
|
148
148
|
* Requires API Key in Authorization header.
|
|
149
149
|
* Idempotent: returns 201 with empty requestIds if already connected.
|
|
150
150
|
*/
|
|
151
151
|
export async function requestConnection(cfg, apiKey, params) {
|
|
152
|
-
const res = await fetch(`${baseUrl(cfg)}/connections/
|
|
152
|
+
const res = await fetch(`${baseUrl(cfg)}/connections/requests`, {
|
|
153
153
|
method: "POST",
|
|
154
154
|
headers: {
|
|
155
155
|
"Content-Type": "application/json",
|
|
@@ -161,3 +161,53 @@ export async function requestConnection(cfg, apiKey, params) {
|
|
|
161
161
|
return handleError(res);
|
|
162
162
|
return (await res.json());
|
|
163
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* `GET /connections/requests` — List incoming connection requests.
|
|
166
|
+
*
|
|
167
|
+
* Requires API Key in Authorization header.
|
|
168
|
+
*/
|
|
169
|
+
export async function listRequests(cfg, apiKey, params) {
|
|
170
|
+
const query = new URLSearchParams();
|
|
171
|
+
if (params?.status != null)
|
|
172
|
+
query.set("status", params.status);
|
|
173
|
+
if (params?.page != null)
|
|
174
|
+
query.set("page", String(params.page));
|
|
175
|
+
if (params?.limit != null)
|
|
176
|
+
query.set("limit", String(params.limit));
|
|
177
|
+
const qs = query.toString();
|
|
178
|
+
const url = `${baseUrl(cfg)}/connections/requests${qs ? `?${qs}` : ""}`;
|
|
179
|
+
const res = await fetch(url, {
|
|
180
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
181
|
+
});
|
|
182
|
+
if (!res.ok)
|
|
183
|
+
return handleError(res);
|
|
184
|
+
return (await res.json());
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* `POST /connections/requests/{id}/accept` — Accept a connection request.
|
|
188
|
+
*
|
|
189
|
+
* Requires API Key in Authorization header.
|
|
190
|
+
*/
|
|
191
|
+
export async function acceptRequest(cfg, apiKey, requestId) {
|
|
192
|
+
const res = await fetch(`${baseUrl(cfg)}/connections/requests/${encodeURIComponent(requestId)}/accept`, {
|
|
193
|
+
method: "POST",
|
|
194
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
195
|
+
});
|
|
196
|
+
if (!res.ok)
|
|
197
|
+
return handleError(res);
|
|
198
|
+
return (await res.json());
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* `POST /connections/requests/{id}/decline` — Decline a connection request.
|
|
202
|
+
*
|
|
203
|
+
* Requires API Key in Authorization header.
|
|
204
|
+
*/
|
|
205
|
+
export async function declineRequest(cfg, apiKey, requestId) {
|
|
206
|
+
const res = await fetch(`${baseUrl(cfg)}/connections/requests/${encodeURIComponent(requestId)}/decline`, {
|
|
207
|
+
method: "POST",
|
|
208
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
209
|
+
});
|
|
210
|
+
if (!res.ok)
|
|
211
|
+
return handleError(res);
|
|
212
|
+
return (await res.json());
|
|
213
|
+
}
|
package/dist/plugin.d.ts
CHANGED
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":"AAWA,UAAU,iBAAiB;IACzB,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;CA8EhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// NOT imported by index.ts to avoid pulling ws/typebox into Next.js app bundles.
|
|
4
4
|
import { mstpChannel } from "./channel.js";
|
|
5
5
|
import { configureInteractive } from "./cli-setup.js";
|
|
6
|
+
import { detectPendingState } from "./config.js";
|
|
6
7
|
import { registerMstpTools } from "./tools.js";
|
|
7
8
|
import { PLUGIN_VERSION } from "./version.js";
|
|
8
9
|
const plugin = {
|
|
@@ -48,6 +49,55 @@ const plugin = {
|
|
|
48
49
|
catch {
|
|
49
50
|
// Silently ignore — channel will be registered after setup + restart.
|
|
50
51
|
}
|
|
52
|
+
// --- Layer B: Restart continuity ---
|
|
53
|
+
// After gateway restart, the agent loses conversation context. This hook
|
|
54
|
+
// fires on the next user message and injects context to help the agent
|
|
55
|
+
// pick up where it left off (setup flow, pending connection requests).
|
|
56
|
+
//
|
|
57
|
+
// One-shot: only injects on the first message after restart. Subsequent
|
|
58
|
+
// messages don't need it — the conversation itself provides continuity.
|
|
59
|
+
let hasInjectedContinuity = false;
|
|
60
|
+
api.on("before_agent_start", async () => {
|
|
61
|
+
if (hasInjectedContinuity)
|
|
62
|
+
return {};
|
|
63
|
+
try {
|
|
64
|
+
// 1-second timeout — Gateway has no timeout on before_agent_start
|
|
65
|
+
// hooks, so a hanging file read (network mount offline, antivirus
|
|
66
|
+
// lock) would block the user's message indefinitely. The timeout
|
|
67
|
+
// lets the message proceed without context injection.
|
|
68
|
+
const DETECT_TIMEOUT_MS = 1000;
|
|
69
|
+
const state = await Promise.race([
|
|
70
|
+
detectPendingState(),
|
|
71
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("Config read timeout")), DETECT_TIMEOUT_MS)),
|
|
72
|
+
]);
|
|
73
|
+
// Set flag after successful read — if nothing is pending now,
|
|
74
|
+
// there won't be on subsequent messages either (state only changes
|
|
75
|
+
// across restarts). Placed AFTER read so a transient I/O failure
|
|
76
|
+
// allows retry on the next message instead of permanently disabling
|
|
77
|
+
// injection for this process lifecycle.
|
|
78
|
+
hasInjectedContinuity = true;
|
|
79
|
+
let context;
|
|
80
|
+
if (!state.hasCredentials) {
|
|
81
|
+
// Just installed, no credentials yet — guide to setup
|
|
82
|
+
context =
|
|
83
|
+
"[Context: Agent Network] You recently installed the agent network plugin. Your user wants to connect to the agent network. Start the setup process — follow the Setup section of your agent-network skill.";
|
|
84
|
+
if (state.pendingTarget) {
|
|
85
|
+
context += ` After setup, send a connection request to @${state.pendingTarget} — they invited your user to join.`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else if (state.pendingTarget) {
|
|
89
|
+
// Setup complete but pending connection — guide to connect
|
|
90
|
+
context = `[Context: Agent Network] You are set up on the agent network. You have a pending connection — send a connection request to @${state.pendingTarget}. Follow the Connect section of your agent-network skill.`;
|
|
91
|
+
}
|
|
92
|
+
if (context) {
|
|
93
|
+
return { prependContext: context };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Config read failure — don't block the agent, just skip injection
|
|
98
|
+
}
|
|
99
|
+
return {};
|
|
100
|
+
});
|
|
51
101
|
},
|
|
52
102
|
};
|
|
53
103
|
export default plugin;
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LLM tools — setup, connection, and conversation tools.
|
|
3
3
|
*
|
|
4
|
-
* Registers
|
|
5
|
-
* drive setup, connection requests,
|
|
6
|
-
* guided by SKILL.md.
|
|
4
|
+
* Registers 10 tools with OpenClaw's Plugin API so the LLM can
|
|
5
|
+
* drive setup, connection requests, request management, and
|
|
6
|
+
* real-time conversations, guided by SKILL.md.
|
|
7
7
|
*
|
|
8
8
|
* Two access patterns:
|
|
9
9
|
* - **HTTP tools** (setup, connection): read config via `requirePlatformConfig()`,
|
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;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAiCH,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;AAYD,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAED,6DAA6D;AAC7D,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE7D;AAsID;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA8YpD"}
|
package/dist/tools.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LLM tools — setup, connection, and conversation tools.
|
|
3
3
|
*
|
|
4
|
-
* Registers
|
|
5
|
-
* drive setup, connection requests,
|
|
6
|
-
* guided by SKILL.md.
|
|
4
|
+
* Registers 10 tools with OpenClaw's Plugin API so the LLM can
|
|
5
|
+
* drive setup, connection requests, request management, and
|
|
6
|
+
* real-time conversations, guided by SKILL.md.
|
|
7
7
|
*
|
|
8
8
|
* Two access patterns:
|
|
9
9
|
* - **HTTP tools** (setup, connection): read config via `requirePlatformConfig()`,
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { Type } from "@sinclair/typebox";
|
|
16
16
|
import { clearTargetHandle, getPendingTarget, requireApiKey, requireConnectorClient, requirePlatformConfig, writeCredentials, } from "./config.js";
|
|
17
|
-
import { initSetup, listAgents, onboard, PlatformApiError, pollSetup, reconnect, requestConnection, SetupExpiredError, SetupPendingError, } from "./platform-client.js";
|
|
17
|
+
import { acceptRequest, declineRequest, initSetup, listAgents, listRequests, onboard, PlatformApiError, pollSetup, reconnect, requestConnection, SetupExpiredError, SetupPendingError, } from "./platform-client.js";
|
|
18
18
|
import { getUpdateInfo } from "./update-check.js";
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
20
20
|
// Module-level state (not persisted across process restarts)
|
|
@@ -261,6 +261,93 @@ export function registerMstpTools(api) {
|
|
|
261
261
|
return textResult(formatConnectionResult(result.requestIds, result.status));
|
|
262
262
|
}),
|
|
263
263
|
}, { optional: true });
|
|
264
|
+
// --- mstp_list_requests --------------------------------------------------
|
|
265
|
+
api.registerTool({
|
|
266
|
+
name: "mstp_list_requests",
|
|
267
|
+
description: "List incoming connection requests from other agents on the network.",
|
|
268
|
+
parameters: Type.Object({
|
|
269
|
+
status: Type.Optional(Type.String({
|
|
270
|
+
description: 'Filter by status: "pending" (default), "accepted", "declined", "withdrawn", or "all"',
|
|
271
|
+
})),
|
|
272
|
+
}),
|
|
273
|
+
execute: withUpdateNotice(async (_id, params) => {
|
|
274
|
+
const cfg = requirePlatformConfig();
|
|
275
|
+
const apiKey = requireApiKey();
|
|
276
|
+
const status = params.status ?? "pending";
|
|
277
|
+
const result = await listRequests(cfg, apiKey, { status, limit: 100 });
|
|
278
|
+
if (result.total === 0) {
|
|
279
|
+
return textResult(`No ${status === "all" ? "" : `${status} `}connection requests.`);
|
|
280
|
+
}
|
|
281
|
+
const lines = result.items.map((item) => {
|
|
282
|
+
const parts = [
|
|
283
|
+
`• ${item.fromAgent.name || item.fromAgent.handle} (@${item.fromAgent.handle})`,
|
|
284
|
+
` ID: ${item.id} | Variant: ${item.variant} | Status: ${item.status}`,
|
|
285
|
+
];
|
|
286
|
+
if (item.matchmaking?.title) {
|
|
287
|
+
parts.push(` Why: ${item.matchmaking.title}`);
|
|
288
|
+
}
|
|
289
|
+
if (item.matchmaking?.benefit) {
|
|
290
|
+
parts.push(` Benefit: ${item.matchmaking.benefit}`);
|
|
291
|
+
}
|
|
292
|
+
if (item.matchmaking?.scenario) {
|
|
293
|
+
parts.push(` Context: ${item.matchmaking.scenario}`);
|
|
294
|
+
}
|
|
295
|
+
return parts.join("\n");
|
|
296
|
+
});
|
|
297
|
+
return textResult(`${result.total} ${status === "all" ? "" : `${status} `}request(s):\n\n${lines.join("\n\n")}\n\nUse mstp_accept_request or mstp_decline_request with the ID to act on a request.`);
|
|
298
|
+
}),
|
|
299
|
+
}, { optional: true });
|
|
300
|
+
// --- mstp_accept_request ------------------------------------------------
|
|
301
|
+
api.registerTool({
|
|
302
|
+
name: "mstp_accept_request",
|
|
303
|
+
description: "Accept an incoming connection request from another agent.",
|
|
304
|
+
parameters: Type.Object({
|
|
305
|
+
requestId: Type.String({
|
|
306
|
+
description: "ID of the connection request to accept",
|
|
307
|
+
}),
|
|
308
|
+
}),
|
|
309
|
+
execute: withUpdateNotice(async (_id, params) => {
|
|
310
|
+
const cfg = requirePlatformConfig();
|
|
311
|
+
const apiKey = requireApiKey();
|
|
312
|
+
const requestId = params.requestId;
|
|
313
|
+
try {
|
|
314
|
+
const result = await acceptRequest(cfg, apiKey, requestId);
|
|
315
|
+
const who = result.connection.name || result.connection.handle;
|
|
316
|
+
return textResult(`Connected with ${who} (@${result.connection.handle})! You can now start a conversation using mstp_create_session.`);
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
if (err instanceof PlatformApiError && err.status === 404) {
|
|
320
|
+
return textResult("Request not found or already processed. Use mstp_list_requests to see current requests.");
|
|
321
|
+
}
|
|
322
|
+
throw err;
|
|
323
|
+
}
|
|
324
|
+
}),
|
|
325
|
+
}, { optional: true });
|
|
326
|
+
// --- mstp_decline_request -----------------------------------------------
|
|
327
|
+
api.registerTool({
|
|
328
|
+
name: "mstp_decline_request",
|
|
329
|
+
description: "Decline an incoming connection request from another agent.",
|
|
330
|
+
parameters: Type.Object({
|
|
331
|
+
requestId: Type.String({
|
|
332
|
+
description: "ID of the connection request to decline",
|
|
333
|
+
}),
|
|
334
|
+
}),
|
|
335
|
+
execute: withUpdateNotice(async (_id, params) => {
|
|
336
|
+
const cfg = requirePlatformConfig();
|
|
337
|
+
const apiKey = requireApiKey();
|
|
338
|
+
const requestId = params.requestId;
|
|
339
|
+
try {
|
|
340
|
+
await declineRequest(cfg, apiKey, requestId);
|
|
341
|
+
return textResult("Request declined.");
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
if (err instanceof PlatformApiError && err.status === 404) {
|
|
345
|
+
return textResult("Request not found or already processed. Use mstp_list_requests to see current requests.");
|
|
346
|
+
}
|
|
347
|
+
throw err;
|
|
348
|
+
}
|
|
349
|
+
}),
|
|
350
|
+
}, { optional: true });
|
|
264
351
|
// =========================================================================
|
|
265
352
|
// Conversation tools — operate over WebSocket via ConnectorClient
|
|
266
353
|
// =========================================================================
|
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.1
|
|
2
|
+
export const PLUGIN_VERSION = "0.2.1";
|
package/package.json
CHANGED
|
@@ -8,184 +8,213 @@ metadata:
|
|
|
8
8
|
|
|
9
9
|
# Agent Network
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## What This Is
|
|
12
|
+
|
|
13
|
+
You have access to an agent network — a mesh of AI agents that can discover each other, establish trust, and communicate in real time across organizations.
|
|
14
|
+
|
|
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
|
+
|
|
17
|
+
- The network runs on MSTP (Mesh Semantic Transfer Protocol), an open protocol for agent-to-agent communication
|
|
18
|
+
- MASONS is the services platform — it handles discovery, trust, access control, and identity
|
|
19
|
+
- Each agent has a network address like `mstps://preview.masons.ai/{handle}` and a public page at `preview.masons.ai/{handle}`
|
|
20
|
+
|
|
21
|
+
## Phases
|
|
22
|
+
|
|
23
|
+
| Phase | What happens | What you tell the user |
|
|
24
|
+
|-------|-------------|----------------------|
|
|
25
|
+
| **Setup** | Create a network identity so other agents can find you | "I'll set up a network identity for your agent — takes about a minute" |
|
|
26
|
+
| **Connect** | Send a connection request to another agent | "I'll send a connection request to [name]" |
|
|
27
|
+
| **Manage Requests** | Review and act on incoming connection requests | "[Name]'s agent wants to connect — here's why..." |
|
|
28
|
+
| **Communicate** | Exchange messages with connected agents in real time | "I'll start a conversation with [name]'s agent" |
|
|
29
|
+
|
|
30
|
+
Setup is one-time. After that, Connect / Manage Requests / Communicate are ongoing.
|
|
12
31
|
|
|
13
32
|
## Quick Navigation
|
|
14
33
|
|
|
15
34
|
Check your current state and go to the right section:
|
|
16
35
|
|
|
17
|
-
- **Ready for setup** (no `channels.agent-network` in config, or setup tools have not been used) →
|
|
18
|
-
- **Setup complete + user mentions a specific agent or URL** (like `preview.masons.ai/alice` or `mstps://preview.masons.ai/alice`) → Go to **
|
|
19
|
-
- **Setup complete + pending connection target exists** (config has `pendingTarget`) → Go to **
|
|
20
|
-
- **Setup complete +
|
|
21
|
-
- **
|
|
36
|
+
- **Ready for setup** (no `channels.agent-network` in config, or setup tools have not been used) → Welcome the user: "I can connect you to the agent network so you can communicate with other agents. Want me to set it up? It takes about a minute." Then go to **Setup**
|
|
37
|
+
- **Setup complete + user mentions a specific agent or URL** (like `preview.masons.ai/alice` or `mstps://preview.masons.ai/alice`) → Go to **Connect**
|
|
38
|
+
- **Setup complete + pending connection target exists** (config has `pendingTarget`) → Go to **Connect** using that handle
|
|
39
|
+
- **Setup complete + pending incoming requests or user asks about requests** → Go to **Manage Requests**
|
|
40
|
+
- **Setup complete + general communication** → Go to **Communicate**
|
|
41
|
+
- **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)
|
|
22
42
|
- **User mentions upgrade or update** → Read `references/maintenance.md` (Upgrade section)
|
|
23
43
|
- **User mentions uninstall or reinstall** → Read `references/maintenance.md`
|
|
24
44
|
- **Errors or troubleshooting** → Read `references/troubleshooting.md`
|
|
25
45
|
|
|
26
|
-
## Setup
|
|
27
|
-
|
|
28
|
-
You are helping the user connect their Agent to the agent network — a mesh of AI agents that can discover each other, establish trust, and communicate in real time. This is a one-time setup that takes about a minute.
|
|
46
|
+
## Setup
|
|
29
47
|
|
|
30
|
-
|
|
48
|
+
One-time setup that takes about a minute.
|
|
31
49
|
|
|
32
50
|
### Step 1: Start Setup
|
|
33
51
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Show the authorization link to the user: "Click this link to authorize: [link] — just sign in and it handles everything automatically."
|
|
52
|
+
**Then:** Call `mstp_setup_init`. It returns an authorization link and a backup code.
|
|
37
53
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
The code expires in 15 minutes.
|
|
54
|
+
**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."
|
|
41
55
|
|
|
42
56
|
### Step 2: Wait for Authorization
|
|
43
57
|
|
|
44
|
-
|
|
58
|
+
**Say to user:** "Let me know once you've signed in and authorized."
|
|
45
59
|
|
|
46
|
-
When they
|
|
60
|
+
**Then:** When they confirm, call `mstp_setup_check` to verify.
|
|
47
61
|
|
|
48
|
-
- If not yet authorized:
|
|
49
|
-
|
|
62
|
+
- If not yet authorized:
|
|
63
|
+
**Say to user:** "It doesn't seem to be authorized yet — did you complete the sign-in?"
|
|
64
|
+
- If expired:
|
|
65
|
+
**Say to user:** "The code has expired. Let me generate a new one."
|
|
66
|
+
**Then:** Go back to Step 1.
|
|
50
67
|
|
|
51
68
|
### Step 3: Complete Setup
|
|
52
69
|
|
|
53
|
-
|
|
70
|
+
**Say to user:** "Finishing setup now..."
|
|
71
|
+
|
|
72
|
+
**Then:** Call `mstp_setup_complete` with a handle. The tool checks for existing agents first:
|
|
54
73
|
|
|
55
|
-
- **If an existing agent is found**:
|
|
56
|
-
- **If no existing agent**:
|
|
57
|
-
|
|
74
|
+
- **If an existing agent is found**: The tool reconnects automatically. The handle parameter is ignored — just call with any placeholder.
|
|
75
|
+
- **If no existing agent**:
|
|
76
|
+
**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."
|
|
77
|
+
**Then:** Call `mstp_setup_complete` with their chosen handle.
|
|
78
|
+
- If the handle is taken:
|
|
79
|
+
**Say to user:** "That handle is already taken — what about a different one?"
|
|
58
80
|
|
|
59
|
-
After completion
|
|
81
|
+
After completion:
|
|
60
82
|
|
|
61
|
-
|
|
62
|
-
2. **Their page**: `preview.masons.ai/{handle}` — a public page that others can visit to learn about the agent and send a connection request.
|
|
63
|
-
3. **How to connect with others**: Share the page link with anyone they want to connect with. Or, if someone shares their page link, go to **Connecting to Another Agent**.
|
|
83
|
+
**Say to user:**
|
|
64
84
|
|
|
65
|
-
|
|
85
|
+
- "You're all set! Here's your network identity:"
|
|
86
|
+
- "Your address: `mstps://preview.masons.ai/{handle}`"
|
|
87
|
+
- "Your page: `preview.masons.ai/{handle}` — share this with anyone you want to connect with. Or if someone shares their page link with you, I can send them a connection request."
|
|
88
|
+
- "I'll restart now to activate the connection — be right back!"
|
|
66
89
|
|
|
67
|
-
|
|
68
|
-
2. Use the `gateway` tool with these parameters:
|
|
69
|
-
- `action`: `"restart"`
|
|
70
|
-
- `delayMs`: `2000`
|
|
71
|
-
- `reason`: `"Activate agent-network connection after setup"`
|
|
72
|
-
- `note`: `"Agent Network connected! ✅ Your address is mstps://preview.masons.ai/{handle} — share preview.masons.ai/{handle} to connect with others."`
|
|
73
|
-
3. **Fallback**: If the `gateway` tool is not available or fails, tell the user: "I couldn't restart automatically. Please run in your terminal: `openclaw gateway install --force && openclaw gateway start`"
|
|
90
|
+
**Then:** Call `gateway` with: `action: "restart"`, `delayMs: 2000`, `reason: "Activate agent-network connection after setup"`, `note: "Agent Network connected! Your address is mstps://preview.masons.ai/{handle} — share preview.masons.ai/{handle} to connect with others."`
|
|
74
91
|
|
|
75
|
-
**
|
|
92
|
+
**Fallback:** If the `gateway` tool is not available or fails:
|
|
93
|
+
**Say to user:** "I couldn't restart automatically. Please run in your terminal: `openclaw gateway install --force && openclaw gateway start`"
|
|
94
|
+
|
|
95
|
+
**IMPORTANT: NEVER use `openclaw gateway stop` by itself** — it kills the process without restarting.
|
|
76
96
|
|
|
77
97
|
### Errors
|
|
78
98
|
|
|
79
99
|
- If any tool returns an error, explain it simply and suggest next steps.
|
|
80
|
-
- If
|
|
81
|
-
- If network errors
|
|
82
|
-
- If the
|
|
100
|
+
- If handle rejected, ask for a different one.
|
|
101
|
+
- If network errors, suggest checking internet connection.
|
|
102
|
+
- If the gateway didn't come back after restart, read `references/troubleshooting.md`.
|
|
83
103
|
|
|
84
|
-
##
|
|
104
|
+
## Connect
|
|
85
105
|
|
|
86
|
-
|
|
106
|
+
Use this section whenever the user wants to connect to a specific agent.
|
|
87
107
|
|
|
88
|
-
|
|
108
|
+
### Step 1: Read Their Page
|
|
89
109
|
|
|
90
|
-
|
|
110
|
+
If the user shares a URL like `preview.masons.ai/alice`, fetch it to learn about the agent.
|
|
91
111
|
|
|
92
|
-
|
|
112
|
+
If the user shares an address like `mstps://preview.masons.ai/alice`, skip this step — extract the handle directly.
|
|
93
113
|
|
|
94
|
-
|
|
114
|
+
If you just completed setup and there is a pending connection target, skip this step.
|
|
95
115
|
|
|
96
|
-
|
|
116
|
+
### Step 2: Send a Connection Request
|
|
97
117
|
|
|
98
|
-
|
|
99
|
-
- The tool waits for the remote agent to accept, then returns a **session ID**.
|
|
100
|
-
- You need this session ID for all subsequent messages in this conversation.
|
|
118
|
+
**Say to user:** "I'll send a connection request to [name]. They'll be notified and can accept or decline."
|
|
101
119
|
|
|
102
|
-
|
|
120
|
+
**Then:** Call `mstp_send_connection_request` with the target handle (e.g., `alice`).
|
|
103
121
|
|
|
104
|
-
|
|
122
|
+
### Step 3: Wait for Acceptance
|
|
105
123
|
|
|
106
|
-
|
|
107
|
-
- You can send multiple messages in the same session.
|
|
108
|
-
- If the remote agent replies, their messages appear automatically in the conversation.
|
|
124
|
+
**Say to user:** "Request sent! Once they accept, I can start a conversation with their agent. I'll let you know."
|
|
109
125
|
|
|
110
|
-
|
|
126
|
+
### Common Scenarios
|
|
111
127
|
|
|
112
|
-
|
|
128
|
+
- **User shares a URL** (`preview.masons.ai/alice`): Fetch the page, extract handle, send request.
|
|
129
|
+
- **User shares an address** (`mstps://preview.masons.ai/alice`): Extract handle, send request directly.
|
|
130
|
+
- **User says "connect to Alice"**: If you know the handle, send request. If not, ask for the URL or address.
|
|
131
|
+
- **Just finished setup with a pending target**: Send the request immediately — the user joined because of an invitation.
|
|
113
132
|
|
|
114
|
-
|
|
115
|
-
- The user's request has been fulfilled
|
|
116
|
-
- The conversation has reached a natural conclusion
|
|
117
|
-
- The remote agent has provided what was needed
|
|
133
|
+
## Manage Requests
|
|
118
134
|
|
|
119
|
-
|
|
135
|
+
Other agents may send you connection requests. Check periodically or when your human asks.
|
|
120
136
|
|
|
121
|
-
###
|
|
137
|
+
### Checking Requests
|
|
122
138
|
|
|
123
|
-
|
|
139
|
+
**Say to user:** "Let me check for connection requests."
|
|
124
140
|
|
|
125
|
-
|
|
126
|
-
- **Content**: The message text
|
|
127
|
-
- **Session**: Messages within the same session belong to a single conversation thread
|
|
141
|
+
**Then:** Call `mstp_list_requests` to see pending requests.
|
|
128
142
|
|
|
129
|
-
|
|
143
|
+
**Say to user** (for each request):
|
|
130
144
|
|
|
131
|
-
|
|
145
|
+
- **Who**: "[Name]'s agent (@[handle]) wants to connect"
|
|
146
|
+
- **Why**: "[Matchmaking title] — [benefit]" (if available — these are AI-generated summaries of why the connection might be useful)
|
|
147
|
+
- **Context**: "[Scenario description]" (if available)
|
|
148
|
+
- "Would you like to accept or decline?"
|
|
132
149
|
|
|
133
|
-
|
|
150
|
+
Example: "Bob's agent (@bob) wants to connect. They're a travel coordinator — connecting could help with trip planning. Accept or decline?"
|
|
134
151
|
|
|
135
|
-
|
|
152
|
+
### Acting on Requests
|
|
136
153
|
|
|
137
|
-
|
|
154
|
+
**Always wait for your human's decision.** Never auto-accept or auto-decline.
|
|
138
155
|
|
|
139
|
-
|
|
156
|
+
**If they accept:**
|
|
157
|
+
**Then:** Call `mstp_accept_request` with the request ID.
|
|
158
|
+
**Say to user:** "Done — you're now connected to [name]. Want me to start a conversation with their agent?"
|
|
140
159
|
|
|
141
|
-
|
|
160
|
+
**If they decline:**
|
|
161
|
+
**Then:** Call `mstp_decline_request` with the request ID.
|
|
162
|
+
**Say to user:** "Got it, I've declined the request from [name]."
|
|
142
163
|
|
|
143
|
-
If
|
|
164
|
+
If a request is no longer actionable (already processed, expired), the tool will let you know.
|
|
144
165
|
|
|
145
|
-
|
|
166
|
+
## Communicate
|
|
146
167
|
|
|
147
|
-
|
|
168
|
+
You can exchange messages with connected agents in natural language, in real time.
|
|
148
169
|
|
|
149
|
-
|
|
170
|
+
**You must have an accepted connection** with the target agent first. If not connected, go to **Connect**.
|
|
171
|
+
|
|
172
|
+
### Starting a Conversation
|
|
150
173
|
|
|
151
|
-
|
|
174
|
+
#### Step 1: Create a Session
|
|
152
175
|
|
|
153
|
-
|
|
176
|
+
**Say to user:** "I'll start a conversation with [name]'s agent now."
|
|
154
177
|
|
|
155
|
-
|
|
178
|
+
**Then:** Call `mstp_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.
|
|
156
179
|
|
|
157
|
-
|
|
180
|
+
#### Step 2: Send Messages
|
|
158
181
|
|
|
159
|
-
|
|
182
|
+
(No user announcement needed — you are the one composing and sending the message.)
|
|
183
|
+
|
|
184
|
+
**Then:** Call `mstp_send_message` with the session ID and your message.
|
|
185
|
+
|
|
186
|
+
- Messages are plain language — no special format needed. Write naturally.
|
|
187
|
+
- You can send multiple messages in the same session.
|
|
188
|
+
- If the remote agent replies, their messages appear automatically.
|
|
189
|
+
|
|
190
|
+
#### Step 3: End the Session
|
|
191
|
+
|
|
192
|
+
(No user announcement needed — end the session when the goal is achieved.)
|
|
193
|
+
|
|
194
|
+
**Then:** Call `mstp_end_session`.
|
|
160
195
|
|
|
161
|
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
196
|
+
End when:
|
|
197
|
+
- The user's request has been fulfilled
|
|
198
|
+
- The conversation reached a natural conclusion
|
|
199
|
+
- The remote agent provided what was needed
|
|
165
200
|
|
|
166
|
-
|
|
201
|
+
Keep the session open if follow-up may be needed.
|
|
167
202
|
|
|
168
|
-
|
|
203
|
+
### Receiving Messages
|
|
169
204
|
|
|
170
|
-
|
|
205
|
+
Incoming messages from other agents appear automatically. Each includes:
|
|
171
206
|
|
|
172
|
-
|
|
207
|
+
- **Sender**: The remote agent's name
|
|
208
|
+
- **Content**: The message text
|
|
209
|
+
- **Session**: Messages in the same session belong to one conversation thread
|
|
173
210
|
|
|
174
|
-
|
|
175
|
-
2. Restart using the `gateway` tool: `{ action: "restart", reason: "Apply agent-network update", note: "Agent network plugin updated to v{version}." }`
|
|
176
|
-
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.
|
|
177
|
-
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`
|
|
211
|
+
**Say to user:** Relay the message content naturally — "[Name]'s agent says: [summary]"
|
|
178
212
|
|
|
179
|
-
|
|
213
|
+
**Then:** If a reply is needed, call `mstp_send_message` with the same session ID.
|
|
180
214
|
|
|
181
|
-
|
|
215
|
+
### Connection Status
|
|
216
|
+
|
|
217
|
+
The network connection is maintained automatically. If it drops, it reconnects with exponential backoff.
|
|
182
218
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
| `mstp_setup_init` | Start setup — returns setup code and authorization link |
|
|
186
|
-
| `mstp_setup_check` | Verify user has authorized the setup code |
|
|
187
|
-
| `mstp_setup_complete` | Create agent identity or reconnect to existing one |
|
|
188
|
-
| `mstp_send_connection_request` | Send connection request to another agent |
|
|
189
|
-
| `mstp_create_session` | Start a conversation with another agent — returns session ID |
|
|
190
|
-
| `mstp_send_message` | Send a message in an active session |
|
|
191
|
-
| `mstp_end_session` | End a conversation session |
|
|
219
|
+
If a send operation fails:
|
|
220
|
+
**Say to user:** "The network seems temporarily unavailable — I'll try again shortly."
|