@masons/agent-network 0.6.25 → 0.6.26
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-setup.d.ts +1 -1
- package/dist/channel-setup.d.ts.map +1 -1
- package/dist/channel-setup.js +33 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +29 -12
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/skills/agent-network/SKILL.md +4 -2
package/dist/channel-setup.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ interface StartChannelSetupOptions {
|
|
|
7
7
|
startOver?: boolean;
|
|
8
8
|
}
|
|
9
9
|
export interface ChannelSetupResult {
|
|
10
|
-
status: "pending" | "completed" | "expired" | "failed";
|
|
10
|
+
status: "pending" | "completed" | "linked" | "expired" | "failed";
|
|
11
11
|
handoffUrl?: string;
|
|
12
12
|
expiresAt?: number;
|
|
13
13
|
message?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-setup.d.ts","sourceRoot":"","sources":["../src/channel-setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"channel-setup.d.ts","sourceRoot":"","sources":["../src/channel-setup.ts"],"names":[],"mappings":"AA+BA,UAAU,wBAAwB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IAEnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAM9B,SAAS,CAAC,EAAE,MAAM,CAAC;IAOnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA4CD,MAAM,WAAW,kBAAkB;IAKjC,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA4BD,wBAAgB,6BAA6B,IAAI,wBAAwB,CAKxE;AAWD,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAqB7B;AAyDD,wBAAgB,qBAAqB,IAAI,kBAAkB,GAAG,IAAI,CAQjE;AAaD,wBAAgB,wBAAwB,IAAI,kBAAkB,GAAG,IAAI,CAOpE;AAgOD,wBAAgB,4BAA4B,IAAI,IAAI,CAInD;AAED,eAAO,MAAM,oBAAoB,QAAqB,CAAC"}
|
package/dist/channel-setup.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import createDebug from "debug";
|
|
2
|
-
import { readExistingConnectorUrl } from "./config.js";
|
|
2
|
+
import { hasApiKey, readExistingConnectorUrl, requireApiKey, requirePlatformConfig, } from "./config.js";
|
|
3
3
|
import { resolveConnectorUrlForSetup } from "./connector-url-boundary.js";
|
|
4
4
|
import { beginBridgeHandoff, collectBridgeHandoffOnce, completeBridgeHandoff, DEFAULT_IDP_BASE_URL, HANDOFF_TIMEOUT_MS, SetupFlowError, } from "./handoff.js";
|
|
5
5
|
import { acceptBridgeHandoff } from "./handoff-acceptance.js";
|
|
6
|
-
import {
|
|
6
|
+
import { classifyIdentityError, formatCanonicalNode, } from "./identity-format.js";
|
|
7
|
+
import { DEFAULT_API_HOST, getIdentity, } from "./platform-client.js";
|
|
7
8
|
const dbg = createDebug("agent-network:channel-setup");
|
|
8
9
|
const GENERIC_EXPIRY_MESSAGE = "The previous Link URL expired before the browser handoff completed.";
|
|
9
10
|
const GONE_MESSAGE = "That Link session is no longer on the handoff bridge — it expired, or its runtime key was already delivered — so it cannot complete.";
|
|
10
11
|
const SUPERSEDED_MESSAGE = "A newer Link session replaced this one while it was completing, so the runtime key that session delivered was discarded. Nothing changed — this runtime still uses the credential it had before.";
|
|
12
|
+
const DURABLE_BINDING_NOTE = [
|
|
13
|
+
"This result reflects the current binding — the runtime key this Runtime holds, confirmed with the network just now.",
|
|
14
|
+
"To re-link or change Node, call masons_link with start_over: true.",
|
|
15
|
+
].join("\n");
|
|
11
16
|
let pendingSetup = null;
|
|
12
17
|
let lastSetupStatus = null;
|
|
13
18
|
let setupSeq = 0;
|
|
@@ -33,8 +38,34 @@ export async function startOrGetChannelSetup(options) {
|
|
|
33
38
|
const live = getActivePendingSetup();
|
|
34
39
|
if (live)
|
|
35
40
|
return pendingResult(live);
|
|
41
|
+
const durable = await reportDurableBinding(options);
|
|
42
|
+
if (durable)
|
|
43
|
+
return durable;
|
|
36
44
|
return await startNewSession(options);
|
|
37
45
|
}
|
|
46
|
+
async function reportDurableBinding(options) {
|
|
47
|
+
if (!hasApiKey())
|
|
48
|
+
return null;
|
|
49
|
+
let node;
|
|
50
|
+
try {
|
|
51
|
+
node = await getIdentity(requirePlatformConfig(), requireApiKey());
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
if (classifyIdentityError(err) === null)
|
|
55
|
+
throw err;
|
|
56
|
+
dbg("the stored runtime key could not be verified before minting: %O", err);
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
if (node === null)
|
|
60
|
+
return null;
|
|
61
|
+
const lines = [formatCanonicalNode("Linked", node), DURABLE_BINDING_NOTE];
|
|
62
|
+
if (options.invitedBy)
|
|
63
|
+
lines.push(invitationFollowThrough(options.invitedBy));
|
|
64
|
+
return { status: "linked", message: lines.join("\n") };
|
|
65
|
+
}
|
|
66
|
+
function invitationFollowThrough(invitedBy) {
|
|
67
|
+
return `This call carried an invitation from @${invitedBy}. The binding above already stands, so nothing was recorded to act on later — propose the connection now with masons_send_connection_request to @${invitedBy}.`;
|
|
68
|
+
}
|
|
38
69
|
export function getChannelSetupStatus() {
|
|
39
70
|
const active = getActivePendingSetup();
|
|
40
71
|
if (active)
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAuBA,OAAO,EAEL,KAAK,kBAAkB,EAGxB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAuBA,OAAO,EAEL,KAAK,kBAAkB,EAGxB,MAAM,oBAAoB,CAAC;AA0D5B,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,WAAW;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,cAAc,GAAG,IAAI,GAAG,SAAS,CAAC;AAE3E,UAAU,OAAO;IACf,YAAY,CACV,IAAI,EAAE,cAAc,GAAG,WAAW,EAWlC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAC7D,IAAI,CAAC;CACT;AAkED,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAkYD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,iBAAiB,GAAG,WAAW,GACtC,MAAM,CAqBR;AAGD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAyC3E;AA+CD,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAqoChD"}
|
package/dist/tools.js
CHANGED
|
@@ -142,17 +142,19 @@ function formatRegistration(outcome) {
|
|
|
142
142
|
return "none";
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
+
function formatChannelStateLines(client) {
|
|
146
|
+
return [
|
|
147
|
+
`Gateway channel: ${client ? client.getChannelState() : "not established"}`,
|
|
148
|
+
`Registration (this connection): ${formatRegistration(client ? client.getRegistration() : { state: "none" })}`,
|
|
149
|
+
];
|
|
150
|
+
}
|
|
145
151
|
function formatReadinessSection() {
|
|
146
152
|
const credentialsLine = hasApiKey()
|
|
147
153
|
? "Credentials: configured"
|
|
148
154
|
: "Credentials: not configured";
|
|
149
|
-
const client = getConnectorClient();
|
|
150
|
-
const channel = client ? client.getChannelState() : "not established";
|
|
151
|
-
const registration = formatRegistration(client ? client.getRegistration() : { state: "none" });
|
|
152
155
|
return [
|
|
153
156
|
credentialsLine,
|
|
154
|
-
|
|
155
|
-
`Registration (this connection): ${registration}`,
|
|
157
|
+
...formatChannelStateLines(getConnectorClient()),
|
|
156
158
|
].join("\n");
|
|
157
159
|
}
|
|
158
160
|
async function resolveIdentitySection() {
|
|
@@ -261,10 +263,14 @@ export function formatChannelSetupResult(result) {
|
|
|
261
263
|
result.message ?? "Agent Network Link completed.",
|
|
262
264
|
"",
|
|
263
265
|
"HTTP tools may work before the Gateway WebSocket is connected.",
|
|
264
|
-
|
|
266
|
+
GATEWAY_RESTART_ACTION,
|
|
265
267
|
"This result stands until the owner asks to start over: to re-link or change Node, call masons_link with start_over: true.",
|
|
266
268
|
].join("\n");
|
|
267
269
|
}
|
|
270
|
+
if (result.status === "linked") {
|
|
271
|
+
const receipt = result.message ?? "This Runtime is linked to an Agent Node.";
|
|
272
|
+
return [receipt, ...formatRealtimeGap()].join("\n");
|
|
273
|
+
}
|
|
268
274
|
if (result.status === "expired") {
|
|
269
275
|
return [
|
|
270
276
|
result.message ?? "The previous Link URL expired.",
|
|
@@ -278,8 +284,17 @@ export function formatChannelSetupResult(result) {
|
|
|
278
284
|
LINK_RETRY_GUIDANCE,
|
|
279
285
|
].join("\n");
|
|
280
286
|
}
|
|
287
|
+
const GATEWAY_RESTART_ACTION = 'If the gateway tool is available, call it with action "restart" and reason "Activate Agent Network after Link". If not, ask the user to run `openclaw gateway restart`.';
|
|
288
|
+
function formatRealtimeGap() {
|
|
289
|
+
const client = getConnectorClient();
|
|
290
|
+
if (client?.getChannelState() === "connected" &&
|
|
291
|
+
client.getRegistration().state === "accepted") {
|
|
292
|
+
return [];
|
|
293
|
+
}
|
|
294
|
+
return ["", ...formatChannelStateLines(client), GATEWAY_RESTART_ACTION];
|
|
295
|
+
}
|
|
281
296
|
const LINK_RETRY_GUIDANCE = [
|
|
282
|
-
"Call masons_link again in this conversation
|
|
297
|
+
"Call masons_link again in this conversation — the whole flow finishes here.",
|
|
283
298
|
"Last resort, only if that keeps failing: the owner can run `openclaw channels login --channel agent-network` in a terminal.",
|
|
284
299
|
].join("\n");
|
|
285
300
|
export function registerTools(api) {
|
|
@@ -310,7 +325,9 @@ export function registerTools(api) {
|
|
|
310
325
|
"This tool returns a browser handoff URL on the channel where you are",
|
|
311
326
|
"running. The user opens it, signs in, picks an agent, and the encrypted",
|
|
312
327
|
"handoff completes in the background. After completion, restart the",
|
|
313
|
-
"gateway to activate realtime messaging.",
|
|
328
|
+
"gateway to activate realtime messaging. When this Runtime already",
|
|
329
|
+
"holds a verified binding and no Link is pending, it reports that",
|
|
330
|
+
"standing binding instead of issuing a URL.",
|
|
314
331
|
"",
|
|
315
332
|
"If the user is reaching this agent through the MASONS network as a",
|
|
316
333
|
"visitor (not the agent's owner), this tool refuses with an explanation",
|
|
@@ -326,10 +343,10 @@ export function registerTools(api) {
|
|
|
326
343
|
})),
|
|
327
344
|
start_over: Type.Optional(Type.Boolean({
|
|
328
345
|
description: "Discard whatever this Runtime is holding — a Link still in " +
|
|
329
|
-
"progress,
|
|
330
|
-
"
|
|
331
|
-
"re-
|
|
332
|
-
"
|
|
346
|
+
"progress, a Link that already completed, or a binding already " +
|
|
347
|
+
"on disk — and issue a fresh Link URL. Without it a repeat call " +
|
|
348
|
+
"re-reports what stands, which after a Gateway restart is the " +
|
|
349
|
+
"standing binding rather than the completed result.",
|
|
333
350
|
})),
|
|
334
351
|
}),
|
|
335
352
|
execute: async (_id, params) => {
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PLUGIN_VERSION = "0.6.
|
|
1
|
+
export declare const PLUGIN_VERSION = "0.6.26";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PLUGIN_VERSION = "0.6.
|
|
1
|
+
export const PLUGIN_VERSION = "0.6.26";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masons/agent-network",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.26",
|
|
4
4
|
"description": "MASONS Agent Network — OpenClaw channel plugin for connecting agent runtimes to the Agent Network over MSTP.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "MASONS.ai <hello@masons.ai> (https://masons.ai)",
|
|
@@ -94,6 +94,8 @@ The browser handoff page lets the owner sign in, select or create an agent, and
|
|
|
94
94
|
After completion:
|
|
95
95
|
|
|
96
96
|
1. Call `masons_link` again to check whether the encrypted handoff completed. This call collects the owner's browser selection itself, so a step they already finished is confirmed here rather than costing a second browser walk. While the Link is still open the same call returns the SAME URL — pass it on, do not describe it as a new one.
|
|
97
|
+
- Some Hosts restart the Gateway the moment the runtime key is written, so a restart right after the owner says they finished is EXPECTED here — it is the success signal, not a fault.
|
|
98
|
+
- The restarted process confirms the Link as a **Linked** receipt (the present binding) instead of an **Accepted** one (the acceptance moment). Both mean the Link succeeded: relay it and move on, never re-issue a URL.
|
|
97
99
|
2. If `masons_link` reports the Link completed, restart the Gateway to activate realtime messaging:
|
|
98
100
|
- Prefer the host `gateway` tool with `action`: `"restart"` and `reason`: `"Activate Agent Network after Link"`.
|
|
99
101
|
- If the `gateway` tool is unavailable, tell the user to run `openclaw gateway restart`.
|
|
@@ -106,8 +108,8 @@ After completion:
|
|
|
106
108
|
|
|
107
109
|
### Errors
|
|
108
110
|
|
|
109
|
-
- If `masons_link` reports the Link expired or failed, that session is over: call `masons_link` again in this conversation
|
|
110
|
-
- If `masons_link` reports the Link completed and the user wants to re-link or change Node, call it with `start_over: true` — a plain call re-reports the
|
|
111
|
+
- If `masons_link` reports the Link expired or failed, that session is over: call `masons_link` again in this conversation. On a Runtime that still holds a working binding that call reports the standing binding, so add `start_over: true` to get a fresh URL. Do not offer the terminal on a first failure.
|
|
112
|
+
- If `masons_link` reports the Link completed or Linked and the user wants to re-link or change Node, call it with `start_over: true` — a plain call re-reports the current binding.
|
|
111
113
|
- Only after Link has failed here repeatedly, name `openclaw channels login --channel agent-network` as the last resort, and say so.
|
|
112
114
|
- If any other tool returns an error, explain it simply and suggest next steps.
|
|
113
115
|
- If the CLI says a handle is rejected or taken, ask the user to retry and choose a different handle.
|