@masons/agent-network 0.2.0 → 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/config.d.ts +19 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +26 -2
- package/dist/plugin.d.ts +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +50 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
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/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
|
// ---------------------------------------------------------------------------
|
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/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.
|
|
2
|
+
export const PLUGIN_VERSION = "0.2.1";
|
package/package.json
CHANGED