@masons/agent-network 0.6.21 → 0.6.23
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 +0 -1
- package/dist/channel-setup.d.ts.map +1 -1
- package/dist/channel-setup.js +20 -13
- package/dist/cli-setup.d.ts.map +1 -1
- package/dist/cli-setup.js +13 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -1
- package/dist/handoff-acceptance.d.ts +11 -0
- package/dist/handoff-acceptance.d.ts.map +1 -0
- package/dist/handoff-acceptance.js +62 -0
- package/dist/handoff.d.ts +0 -1
- package/dist/handoff.d.ts.map +1 -1
- package/dist/handoff.js +4 -19
- package/dist/identity-format.d.ts +6 -0
- package/dist/identity-format.d.ts.map +1 -0
- package/dist/identity-format.js +30 -0
- package/dist/platform-client.d.ts +37 -32
- package/dist/platform-client.d.ts.map +1 -1
- package/dist/platform-client.js +53 -28
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +3 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +239 -102
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/openclaw.plugin.json +2 -1
- package/package.json +1 -1
- package/skills/agent-network/SKILL.md +57 -17
package/dist/channel-setup.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ export interface ChannelSetupResult {
|
|
|
8
8
|
status: "pending" | "completed" | "expired" | "failed";
|
|
9
9
|
handoffUrl?: string;
|
|
10
10
|
expiresAt?: number;
|
|
11
|
-
agentHandle?: string;
|
|
12
11
|
message?: string;
|
|
13
12
|
}
|
|
14
13
|
export declare function getDefaultChannelSetupOptions(): StartChannelSetupOptions;
|
|
@@ -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":"AAeA,UAAU,wBAAwB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IAMnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD,wBAAgB,6BAA6B,IAAI,wBAAwB,CAKxE;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAqC7B;AAED,wBAAgB,qBAAqB,IAAI,kBAAkB,GAAG,IAAI,CAcjE;AAED,wBAAgB,yBAAyB,IAAI,kBAAkB,GAAG,IAAI,CAMrE;AAmFD,wBAAgB,4BAA4B,IAAI,IAAI,CAGnD;AAED,eAAO,MAAM,oBAAoB,QAAqB,CAAC"}
|
package/dist/channel-setup.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import createDebug from "debug";
|
|
2
|
+
import { readExistingConnectorUrl } from "./config.js";
|
|
2
3
|
import { resolveConnectorUrlForSetup } from "./connector-url-boundary.js";
|
|
3
4
|
import { beginBridgeHandoff, completeBridgeHandoff, DEFAULT_IDP_BASE_URL, HANDOFF_TIMEOUT_MS, SetupFlowError, } from "./handoff.js";
|
|
4
|
-
import {
|
|
5
|
+
import { acceptBridgeHandoff } from "./handoff-acceptance.js";
|
|
5
6
|
import { DEFAULT_API_HOST } from "./platform-client.js";
|
|
7
|
+
const dbg = createDebug("agent-network:channel-setup");
|
|
6
8
|
let pendingSetup = null;
|
|
7
9
|
let lastSetupStatus = null;
|
|
8
10
|
export function getDefaultChannelSetupOptions() {
|
|
@@ -59,7 +61,6 @@ export function getChannelSetupStatus() {
|
|
|
59
61
|
return null;
|
|
60
62
|
return {
|
|
61
63
|
status: lastSetupStatus.status,
|
|
62
|
-
agentHandle: lastSetupStatus.agentHandle,
|
|
63
64
|
message: lastSetupStatus.message,
|
|
64
65
|
};
|
|
65
66
|
}
|
|
@@ -88,20 +89,22 @@ async function completePendingSetup(record) {
|
|
|
88
89
|
const handoff = await completeBridgeHandoff(record.session);
|
|
89
90
|
if (pendingSetup !== record)
|
|
90
91
|
return;
|
|
91
|
-
const
|
|
92
|
+
const receipt = await acceptBridgeHandoff({
|
|
93
|
+
handoff,
|
|
94
|
+
apiHost: record.apiHost,
|
|
92
95
|
connectorUrl: record.connectorUrl,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
idpBaseUrl: record.idpBaseUrl,
|
|
97
|
+
pendingTarget: record.invitedBy,
|
|
98
|
+
expiresAt: record.session.expiresAt,
|
|
99
|
+
});
|
|
96
100
|
lastSetupStatus = {
|
|
97
101
|
status: "completed",
|
|
98
|
-
|
|
99
|
-
message: `Setup completed for @${handoff.agent.handle}.`,
|
|
102
|
+
message: receipt,
|
|
100
103
|
finishedAt: Date.now(),
|
|
101
104
|
};
|
|
102
105
|
}
|
|
103
106
|
catch (err) {
|
|
104
|
-
if (pendingSetup !== record)
|
|
107
|
+
if (pendingSetup !== record && !supersedesGenericExpiry(err))
|
|
105
108
|
return;
|
|
106
109
|
lastSetupStatus = {
|
|
107
110
|
status: isExpiryError(err) ? "expired" : "failed",
|
|
@@ -115,6 +118,11 @@ async function completePendingSetup(record) {
|
|
|
115
118
|
}
|
|
116
119
|
}
|
|
117
120
|
}
|
|
121
|
+
function supersedesGenericExpiry(err) {
|
|
122
|
+
return (err instanceof SetupFlowError &&
|
|
123
|
+
pendingSetup === null &&
|
|
124
|
+
lastSetupStatus?.status === "expired");
|
|
125
|
+
}
|
|
118
126
|
function isExpiryError(err) {
|
|
119
127
|
if (!(err instanceof SetupFlowError))
|
|
120
128
|
return false;
|
|
@@ -123,9 +131,8 @@ function isExpiryError(err) {
|
|
|
123
131
|
function safeSetupErrorMessage(err) {
|
|
124
132
|
if (err instanceof SetupFlowError)
|
|
125
133
|
return err.message;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return "Setup failed. Re-run setup.";
|
|
134
|
+
dbg("setup failed with an unexpected error: %O", err);
|
|
135
|
+
return "Setup failed for an unexpected reason; check debug logs.";
|
|
129
136
|
}
|
|
130
137
|
export function _resetChannelSetupForTesting() {
|
|
131
138
|
pendingSetup = null;
|
package/dist/cli-setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-setup.d.ts","sourceRoot":"","sources":["../src/cli-setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-setup.d.ts","sourceRoot":"","sources":["../src/cli-setup.ts"],"names":[],"mappings":"AA8FA,UAAU,eAAe;IACvB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAOD,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAmFD,wBAAsB,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EhE"}
|
package/dist/cli-setup.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { readExistingConnectorUrl
|
|
1
|
+
import { readExistingConnectorUrl } from "./config.js";
|
|
2
2
|
import { ConnectorUrlConfigurationError, resolveConnectorUrlForSetup, } from "./connector-url-boundary.js";
|
|
3
3
|
import { beginBridgeHandoff, completeBridgeHandoff, DEFAULT_IDP_BASE_URL, SetupFlowError, } from "./handoff.js";
|
|
4
|
-
import {
|
|
4
|
+
import { acceptBridgeHandoff } from "./handoff-acceptance.js";
|
|
5
5
|
import { DEFAULT_API_HOST, DEFAULT_CONNECTOR_URL, PlatformApiError, } from "./platform-client.js";
|
|
6
|
-
async function serverBridgeHandoffFlow(apiHost, idpBaseUrl, runtime
|
|
6
|
+
async function serverBridgeHandoffFlow(apiHost, idpBaseUrl, runtime) {
|
|
7
7
|
const session = await beginBridgeHandoff({
|
|
8
8
|
apiHost,
|
|
9
9
|
idpBaseUrl,
|
|
10
|
-
channelInput,
|
|
11
10
|
});
|
|
12
11
|
runtime.writeStdout([
|
|
13
12
|
"",
|
|
@@ -29,7 +28,7 @@ export async function login(ctx) {
|
|
|
29
28
|
: DEFAULT_IDP_BASE_URL;
|
|
30
29
|
let completed;
|
|
31
30
|
try {
|
|
32
|
-
completed = await serverBridgeHandoffFlow(apiHost, idpBaseUrl, ctx.runtime
|
|
31
|
+
completed = await serverBridgeHandoffFlow(apiHost, idpBaseUrl, ctx.runtime);
|
|
33
32
|
}
|
|
34
33
|
catch (err) {
|
|
35
34
|
if (err instanceof SetupFlowError) {
|
|
@@ -61,8 +60,15 @@ export async function login(ctx) {
|
|
|
61
60
|
}
|
|
62
61
|
throw err;
|
|
63
62
|
}
|
|
63
|
+
let receipt;
|
|
64
64
|
try {
|
|
65
|
-
await
|
|
65
|
+
receipt = await acceptBridgeHandoff({
|
|
66
|
+
handoff,
|
|
67
|
+
apiHost,
|
|
68
|
+
connectorUrl,
|
|
69
|
+
idpBaseUrl,
|
|
70
|
+
expiresAt: completed.expiresAt,
|
|
71
|
+
});
|
|
66
72
|
}
|
|
67
73
|
catch (err) {
|
|
68
74
|
if (err instanceof SetupFlowError) {
|
|
@@ -71,5 +77,5 @@ export async function login(ctx) {
|
|
|
71
77
|
}
|
|
72
78
|
throw err;
|
|
73
79
|
}
|
|
74
|
-
ctx.runtime.log(`✓
|
|
80
|
+
ctx.runtime.log(`✓ ${receipt}`);
|
|
75
81
|
}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAoCjD,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAsBD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMhC;AAYD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAyCjE;AAuCD,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAWD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAeD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAOjE;AAQD,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAYD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAE1E;AASD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAKD,wBAAgB,0BAA0B,IAAI,mBAAmB,CAOhE;AASD,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,IAAI,CAEnE;AAgBD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAExD;AAKD,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAQD,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C;AAcD,wBAAgB,qBAAqB,IAAI,oBAAoB,CAE5D;AAKD,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAWD,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAKD,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AASD,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AASD,wBAAgB,sBAAsB,IAAI,eAAe,CAOxD;AASD,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAE3D;AAyBD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAQD,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW5E;AAoBD,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,kBAAkB,EACzB,OAAO,CAAC,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,gBAAgB,CAAC,EAAE,MAAM,IAAI,GAC5B,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAoCjD,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAsBD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMhC;AAYD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAyCjE;AAuCD,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAWD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAeD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAOjE;AAQD,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAYD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAE1E;AASD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAKD,wBAAgB,0BAA0B,IAAI,mBAAmB,CAOhE;AASD,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,IAAI,CAEnE;AAgBD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAExD;AAKD,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAQD,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C;AAcD,wBAAgB,qBAAqB,IAAI,oBAAoB,CAE5D;AAKD,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAWD,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAKD,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AASD,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AASD,wBAAgB,sBAAsB,IAAI,eAAe,CAOxD;AASD,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAE3D;AAyBD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAQD,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW5E;AAoBD,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,kBAAkB,EACzB,OAAO,CAAC,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,gBAAgB,CAAC,EAAE,MAAM,IAAI,GAC5B,OAAO,CAAC,IAAI,CAAC,CA4Cf;AAUD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrE;AASD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CASvD;AAYD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOvD;AAUD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOzD;AAwCD,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAQD,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B1E;AAOD,MAAM,WAAW,YAAY;IAE3B,cAAc,EAAE,OAAO,CAAC;IAExB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B,YAAY,EAAE,OAAO,CAAC;CACvB;AASD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC,CA2BhE;AAOD,wBAAgB,gBAAgB,IAAI,IAAI,CAWvC"}
|
package/dist/config.js
CHANGED
|
@@ -161,7 +161,6 @@ export async function writeCredentials(creds, apiHost, idpBaseUrl, pendingTarget
|
|
|
161
161
|
};
|
|
162
162
|
if (apiHost) {
|
|
163
163
|
section.apiHost = apiHost;
|
|
164
|
-
platformConfig = { apiHost };
|
|
165
164
|
}
|
|
166
165
|
if (idpBaseUrl) {
|
|
167
166
|
section.idpBaseUrl = idpBaseUrl;
|
|
@@ -171,6 +170,9 @@ export async function writeCredentials(creds, apiHost, idpBaseUrl, pendingTarget
|
|
|
171
170
|
}
|
|
172
171
|
await persistConfig(config, assertCanPersist);
|
|
173
172
|
storedApiKey = creds.token;
|
|
173
|
+
if (apiHost) {
|
|
174
|
+
platformConfig = { apiHost };
|
|
175
|
+
}
|
|
174
176
|
if (pendingTarget) {
|
|
175
177
|
storedPendingTarget = pendingTarget;
|
|
176
178
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BridgeHandoffResult } from "./handoff.js";
|
|
2
|
+
export interface AcceptBridgeHandoffOptions {
|
|
3
|
+
handoff: BridgeHandoffResult;
|
|
4
|
+
apiHost: string;
|
|
5
|
+
connectorUrl: string;
|
|
6
|
+
idpBaseUrl: string;
|
|
7
|
+
pendingTarget?: string;
|
|
8
|
+
expiresAt: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function acceptBridgeHandoff(options: AcceptBridgeHandoffOptions): Promise<string>;
|
|
11
|
+
//# sourceMappingURL=handoff-acceptance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff-acceptance.d.ts","sourceRoot":"","sources":["../src/handoff-acceptance.ts"],"names":[],"mappings":"AAgDA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAiCxD,MAAM,WAAW,0BAA0B;IAEzC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IAEnB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import createDebug from "debug";
|
|
2
|
+
import { writeCredentials } from "./config.js";
|
|
3
|
+
import { assertHandoffDeadlineActive, SetupFlowError, } from "./handoff-deadline.js";
|
|
4
|
+
import { classifyIdentityError, formatCanonicalNode, } from "./identity-format.js";
|
|
5
|
+
import { getIdentity, PlatformApiError, PlatformNetworkError, } from "./platform-client.js";
|
|
6
|
+
const dbg = createDebug("agent-network:handoff-acceptance");
|
|
7
|
+
const ACTIVATION_ACTION = "Messaging under this credential activates when the OpenClaw Gateway next starts or restarts.";
|
|
8
|
+
const NOTHING_CHANGED = "Nothing changed — this runtime still uses the credential it had before.";
|
|
9
|
+
export async function acceptBridgeHandoff(options) {
|
|
10
|
+
const node = await refreshCanonicalNode(options);
|
|
11
|
+
const echoed = options.handoff.agent.handle;
|
|
12
|
+
const mismatch = node.handle === echoed
|
|
13
|
+
? undefined
|
|
14
|
+
: `Note: the handoff payload claimed @${echoed}; the network says this credential represents ${node.handle ? `@${node.handle}` : node.mstpAddress}, which is the answer used here.`;
|
|
15
|
+
if (mismatch)
|
|
16
|
+
dbg(mismatch);
|
|
17
|
+
await writeCredentials({ connectorUrl: options.connectorUrl, token: options.handoff.token }, options.apiHost, options.idpBaseUrl, options.pendingTarget, () => assertHandoffDeadlineActive(options.expiresAt));
|
|
18
|
+
return formatAcceptanceReceipt(node, mismatch);
|
|
19
|
+
}
|
|
20
|
+
function formatAcceptanceReceipt(node, mismatch) {
|
|
21
|
+
const lines = [formatCanonicalNode("Accepted", node), ACTIVATION_ACTION];
|
|
22
|
+
if (mismatch)
|
|
23
|
+
lines.push(mismatch);
|
|
24
|
+
return lines.join("\n");
|
|
25
|
+
}
|
|
26
|
+
async function refreshCanonicalNode(options) {
|
|
27
|
+
let node;
|
|
28
|
+
try {
|
|
29
|
+
node = await getIdentity({ apiHost: options.apiHost }, options.handoff.token);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
throw acceptanceFailure(err, options.apiHost);
|
|
33
|
+
}
|
|
34
|
+
if (node === null) {
|
|
35
|
+
throw new SetupFlowError(`The delivered runtime key is valid, but the network reports no active Node for it to represent, so it was not accepted. ${NOTHING_CHANGED} Choose or create an Agent Node in the console, then re-run setup.`);
|
|
36
|
+
}
|
|
37
|
+
return node;
|
|
38
|
+
}
|
|
39
|
+
function acceptanceFailure(err, apiHost) {
|
|
40
|
+
switch (classifyIdentityError(err)) {
|
|
41
|
+
case "credential-refused":
|
|
42
|
+
return new SetupFlowError(`The network rejected the runtime key delivered by the browser${httpStatusSuffix(err)}, so it was not accepted. That is a credential-class refusal — retrying will not change it. ${NOTHING_CHANGED} Re-run setup to authorize a new runtime key.`);
|
|
43
|
+
case "entity-missing":
|
|
44
|
+
return new SetupFlowError(`The delivered runtime key authenticates, but the Node it represents has no backing entity on the network — it is missing or deleted — so it was not accepted. ${NOTHING_CHANGED} Choose or create an Agent Node in the console, then re-run setup.`);
|
|
45
|
+
case "endpoint-absent":
|
|
46
|
+
return new SetupFlowError(`This MASONS Services deployment does not serve the identity endpoint (HTTP 404 for GET /v1/me/identity at ${apiHost}), so the delivered runtime key could not be verified and was not accepted. That is a property of this host — an older or self-hosted apps/api — not an expired link. ${NOTHING_CHANGED} Point setup at a Services deployment that serves the identity endpoint, or upgrade this one, then re-run setup.`);
|
|
47
|
+
case "unavailable":
|
|
48
|
+
return new SetupFlowError(`The network could not confirm which Node the delivered runtime key represents (${unavailableDetail(err)}), so it was not accepted. ${NOTHING_CHANGED} Re-run setup to try again.`);
|
|
49
|
+
default:
|
|
50
|
+
return err;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function httpStatusSuffix(err) {
|
|
54
|
+
return err instanceof PlatformApiError ? ` (HTTP ${err.status})` : "";
|
|
55
|
+
}
|
|
56
|
+
function unavailableDetail(err) {
|
|
57
|
+
if (err instanceof PlatformApiError)
|
|
58
|
+
return `HTTP ${err.status} ${err.code}`;
|
|
59
|
+
if (err instanceof PlatformNetworkError)
|
|
60
|
+
return `${err.code}: ${err.detail}`;
|
|
61
|
+
return "no answer";
|
|
62
|
+
}
|
package/dist/handoff.d.ts
CHANGED
|
@@ -20,7 +20,6 @@ export interface BridgeHandoffSession {
|
|
|
20
20
|
export interface BeginBridgeHandoffOptions {
|
|
21
21
|
apiHost: string;
|
|
22
22
|
idpBaseUrl: string;
|
|
23
|
-
channelInput?: string;
|
|
24
23
|
}
|
|
25
24
|
export declare function beginBridgeHandoff(options: BeginBridgeHandoffOptions): Promise<BridgeHandoffSession>;
|
|
26
25
|
export declare function completeBridgeHandoff(session: BridgeHandoffSession): Promise<BridgeHandoffResult>;
|
package/dist/handoff.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../src/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,aAAa,CAAC;AAQrB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAavD,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../src/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,aAAa,CAAC;AAQrB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAavD,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAWhE,eAAO,MAAM,kBAAkB,QAAiB,CAAC;AA0BjD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAQD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAOhB,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAkD/B;AAKD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CA0C9B"}
|
package/dist/handoff.js
CHANGED
|
@@ -3,9 +3,9 @@ import { assertHandoffDeadlineActive, SetupFlowError, } from "./handoff-deadline
|
|
|
3
3
|
import { apiFetch, PlatformNetworkError } from "./platform-client.js";
|
|
4
4
|
export { SetupFlowError } from "./handoff-deadline.js";
|
|
5
5
|
export const DEFAULT_IDP_BASE_URL = "https://preview.masons.ai";
|
|
6
|
-
const HANDLE_REGEX = /^[a-z][a-z0-9_-]{2,14}$/;
|
|
7
6
|
export const HANDOFF_TIMEOUT_MS = 10 * 60 * 1000;
|
|
8
7
|
const HANDOFF_POLL_INTERVAL_MS = 2000;
|
|
8
|
+
const RUNTIME_KEY_PATTERN = /^masons_rt_v1_[A-Za-z0-9_-]+$/;
|
|
9
9
|
export async function beginBridgeHandoff(options) {
|
|
10
10
|
const { publicKey, privateKey } = generateKeyPairSync("rsa", {
|
|
11
11
|
modulusLength: 2048,
|
|
@@ -39,11 +39,7 @@ export async function beginBridgeHandoff(options) {
|
|
|
39
39
|
const message = err instanceof Error ? err.message : "unknown error";
|
|
40
40
|
throw new SetupFlowError(`Could not reach the setup service at ${apiBase} (${message}). Retry in a moment.`);
|
|
41
41
|
}
|
|
42
|
-
const
|
|
43
|
-
const handoffPath = handle
|
|
44
|
-
? `/console/agents/${encodeURIComponent(handle)}/runtime-keys/handoff`
|
|
45
|
-
: "/console/handoff";
|
|
46
|
-
const handoffUrl = `${options.idpBaseUrl}${handoffPath}?session=${encodeURIComponent(sessionId)}`;
|
|
42
|
+
const handoffUrl = `${options.idpBaseUrl}/console/handoff?session=${encodeURIComponent(sessionId)}`;
|
|
47
43
|
return {
|
|
48
44
|
sessionId,
|
|
49
45
|
handoffUrl,
|
|
@@ -64,10 +60,10 @@ export async function completeBridgeHandoff(session) {
|
|
|
64
60
|
}
|
|
65
61
|
assertHandoffDeadlineActive(session.expiresAt);
|
|
66
62
|
if (typeof payload.token !== "string" ||
|
|
67
|
-
!payload.token
|
|
63
|
+
!RUNTIME_KEY_PATTERN.test(payload.token) ||
|
|
68
64
|
typeof payload.agent?.handle !== "string" ||
|
|
69
65
|
typeof payload.agent?.agentId !== "string") {
|
|
70
|
-
throw new SetupFlowError("Handoff payload
|
|
66
|
+
throw new SetupFlowError("Handoff payload did not match the expected shape. Re-run setup; if it keeps happening, this is a server-side bug worth reporting.");
|
|
71
67
|
}
|
|
72
68
|
return {
|
|
73
69
|
token: payload.token,
|
|
@@ -154,17 +150,6 @@ function normalizeHttpBase(apiHost) {
|
|
|
154
150
|
return trimmed;
|
|
155
151
|
return `https://${trimmed}`;
|
|
156
152
|
}
|
|
157
|
-
function parseHandleFromInput(input) {
|
|
158
|
-
if (typeof input !== "string")
|
|
159
|
-
return undefined;
|
|
160
|
-
const trimmed = input.trim().toLowerCase();
|
|
161
|
-
if (!trimmed.startsWith("@"))
|
|
162
|
-
return undefined;
|
|
163
|
-
const handle = trimmed.slice(1);
|
|
164
|
-
if (!HANDLE_REGEX.test(handle))
|
|
165
|
-
return undefined;
|
|
166
|
-
return handle;
|
|
167
|
-
}
|
|
168
153
|
function sleep(ms) {
|
|
169
154
|
return new Promise((resolve) => {
|
|
170
155
|
setTimeout(resolve, ms);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ConnectionNodeRef } from "./platform-client.js";
|
|
2
|
+
export declare function formatKindLabel(kind: string | undefined): string;
|
|
3
|
+
export declare function formatCanonicalNode(label: string, node: ConnectionNodeRef): string;
|
|
4
|
+
export type IdentityErrorClass = "credential-refused" | "entity-missing" | "endpoint-absent" | "unavailable";
|
|
5
|
+
export declare function classifyIdentityError(err: unknown): IdentityErrorClass | null;
|
|
6
|
+
//# sourceMappingURL=identity-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-format.d.ts","sourceRoot":"","sources":["../src/identity-format.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,sBAAsB,CAAC;AAe9B,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKhE;AAYD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,iBAAiB,GACtB,MAAM,CAKR;AAgBD,MAAM,MAAM,kBAAkB,GAC1B,oBAAoB,GACpB,gBAAgB,GAChB,iBAAiB,GACjB,aAAa,CAAC;AAOlB,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CAU7E"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PlatformApiError, PlatformNetworkError, } from "./platform-client.js";
|
|
2
|
+
export function formatKindLabel(kind) {
|
|
3
|
+
if (!kind)
|
|
4
|
+
return "";
|
|
5
|
+
if (kind === "user")
|
|
6
|
+
return "[Human Node] ";
|
|
7
|
+
if (kind === "agent")
|
|
8
|
+
return "[Agent Node] ";
|
|
9
|
+
return `[Node:${kind}] `;
|
|
10
|
+
}
|
|
11
|
+
export function formatCanonicalNode(label, node) {
|
|
12
|
+
const handlePart = node.handle ? `@${node.handle} — ` : "";
|
|
13
|
+
const canonical = `${label}: ${formatKindLabel(node.kind)}${handlePart}${node.mstpAddress}`;
|
|
14
|
+
if (!node.displayName)
|
|
15
|
+
return canonical;
|
|
16
|
+
return `${canonical}\nDisplay name (presentation supplied by the identity endpoint): ${node.displayName}`;
|
|
17
|
+
}
|
|
18
|
+
export function classifyIdentityError(err) {
|
|
19
|
+
if (err instanceof PlatformApiError) {
|
|
20
|
+
if (err.status === 401 || err.status === 403)
|
|
21
|
+
return "credential-refused";
|
|
22
|
+
if (err.status === 404) {
|
|
23
|
+
return err.code === "not_found" ? "entity-missing" : "endpoint-absent";
|
|
24
|
+
}
|
|
25
|
+
return "unavailable";
|
|
26
|
+
}
|
|
27
|
+
if (err instanceof PlatformNetworkError)
|
|
28
|
+
return "unavailable";
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
@@ -13,10 +13,6 @@ export declare class PlatformNetworkError extends Error {
|
|
|
13
13
|
readonly detail: string;
|
|
14
14
|
constructor(code: "timeout" | "network", detail: string);
|
|
15
15
|
}
|
|
16
|
-
export interface RequestConnectionResponse {
|
|
17
|
-
requestIds: string[];
|
|
18
|
-
status: string;
|
|
19
|
-
}
|
|
20
16
|
export interface ConnectionNodeRef {
|
|
21
17
|
kind: string;
|
|
22
18
|
mstpAddress: string;
|
|
@@ -24,31 +20,43 @@ export interface ConnectionNodeRef {
|
|
|
24
20
|
displayName?: string;
|
|
25
21
|
avatarUrl?: string;
|
|
26
22
|
}
|
|
27
|
-
export
|
|
23
|
+
export type PackagedRequestStatus = "awaiting-your-decision" | "awaiting-counterparty" | "accepted" | "ignored" | "withdrawn";
|
|
24
|
+
export interface PackagedTombstoneCounterparty {
|
|
28
25
|
id: string;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
kind?: string;
|
|
27
|
+
handle?: string;
|
|
28
|
+
mstpAddress?: string;
|
|
29
|
+
tombstone: true;
|
|
30
|
+
}
|
|
31
|
+
export type PackagedCounterparty = ConnectionNodeRef | PackagedTombstoneCounterparty;
|
|
32
|
+
export declare function isPackagedTombstone(c: PackagedCounterparty): c is PackagedTombstoneCounterparty;
|
|
33
|
+
export interface PackagedRequest {
|
|
34
|
+
id: string;
|
|
35
|
+
counterparty: PackagedCounterparty;
|
|
36
|
+
counterpartyProfile?: {
|
|
37
|
+
tagline: string | null;
|
|
38
|
+
} | null;
|
|
39
|
+
status: PackagedRequestStatus;
|
|
40
|
+
shadowed?: true;
|
|
39
41
|
createdAt: string;
|
|
42
|
+
resolvedAt?: string;
|
|
40
43
|
}
|
|
41
44
|
export interface ListRequestsResponse {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
export interface AcceptRequestResponse {
|
|
46
|
-
status: "accepted";
|
|
47
|
-
counterparty: ConnectionNodeRef | null;
|
|
45
|
+
items: PackagedRequest[];
|
|
46
|
+
nextCursor: string | null;
|
|
48
47
|
}
|
|
49
|
-
export interface
|
|
50
|
-
|
|
48
|
+
export interface CreateRequestResult {
|
|
49
|
+
request: PackagedRequest | null;
|
|
50
|
+
created: boolean;
|
|
51
51
|
}
|
|
52
|
+
export type ResolveRequestResult = {
|
|
53
|
+
outcome: "resolved";
|
|
54
|
+
idempotent: boolean;
|
|
55
|
+
request: PackagedRequest | null;
|
|
56
|
+
} | {
|
|
57
|
+
outcome: "already_resolved";
|
|
58
|
+
status: string | null;
|
|
59
|
+
};
|
|
52
60
|
export interface UpdateProfileParams {
|
|
53
61
|
name?: string;
|
|
54
62
|
scope?: string;
|
|
@@ -73,18 +81,15 @@ export interface ListConnectionsResponse {
|
|
|
73
81
|
}>;
|
|
74
82
|
}
|
|
75
83
|
export declare function apiFetch(url: string, init?: RequestInit): Promise<Response>;
|
|
76
|
-
export declare function requestConnection(cfg: PlatformClientConfig, runtimeKey: string,
|
|
77
|
-
targetHandle: string;
|
|
78
|
-
variants: ("distribute" | "receive")[];
|
|
79
|
-
}): Promise<RequestConnectionResponse>;
|
|
84
|
+
export declare function requestConnection(cfg: PlatformClientConfig, runtimeKey: string, targetHandle: string): Promise<CreateRequestResult>;
|
|
80
85
|
export declare function listRequests(cfg: PlatformClientConfig, runtimeKey: string, params?: {
|
|
81
|
-
status?: string;
|
|
82
|
-
direction?: string;
|
|
83
|
-
page?: number;
|
|
84
86
|
limit?: number;
|
|
87
|
+
cursor?: string;
|
|
88
|
+
counterparty?: string;
|
|
85
89
|
}): Promise<ListRequestsResponse>;
|
|
86
|
-
export declare
|
|
87
|
-
export declare
|
|
90
|
+
export declare const acceptRequest: (cfg: PlatformClientConfig, runtimeKey: string, requestId: string) => Promise<ResolveRequestResult>;
|
|
91
|
+
export declare const ignoreRequest: (cfg: PlatformClientConfig, runtimeKey: string, requestId: string) => Promise<ResolveRequestResult>;
|
|
92
|
+
export declare const withdrawRequest: (cfg: PlatformClientConfig, runtimeKey: string, requestId: string) => Promise<ResolveRequestResult>;
|
|
88
93
|
export declare function updateProfile(cfg: PlatformClientConfig, runtimeKey: string, params: UpdateProfileParams): Promise<UpdateProfileResponse>;
|
|
89
94
|
export declare function listConnections(cfg: PlatformClientConfig, runtimeKey: string): Promise<ListConnectionsResponse>;
|
|
90
95
|
export declare function getIdentity(cfg: PlatformClientConfig, runtimeKey: string): Promise<ConnectionNodeRef | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AASxD,eAAO,MAAM,qBAAqB,iDACc,CAAC;AAEjD,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;AAiBD,qBAAa,oBAAqB,SAAQ,KAAK;aAE3B,IAAI,EAAE,SAAS,GAAG,SAAS;aAE3B,MAAM,EAAE,MAAM;gBAFd,IAAI,EAAE,SAAS,GAAG,SAAS,EAE3B,MAAM,EAAE,MAAM;CAKjC;
|
|
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
|
@@ -20,6 +20,9 @@ export class PlatformNetworkError extends Error {
|
|
|
20
20
|
this.name = "PlatformNetworkError";
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
export function isPackagedTombstone(c) {
|
|
24
|
+
return "tombstone" in c && c.tombstone === true;
|
|
25
|
+
}
|
|
23
26
|
function baseUrl(cfg) {
|
|
24
27
|
const trimmed = cfg.apiHost.replace(/\/+$/, "");
|
|
25
28
|
const origin = /^https?:\/\//.test(trimmed) ? trimmed : `https://${trimmed}`;
|
|
@@ -73,31 +76,31 @@ export async function apiFetch(url, init = {}) {
|
|
|
73
76
|
clearTimeout(timer);
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
const REQUESTS_PATH = "/me/connection-requests";
|
|
80
|
+
export async function requestConnection(cfg, runtimeKey, targetHandle) {
|
|
81
|
+
const res = await apiFetch(`${baseUrl(cfg)}${REQUESTS_PATH}`, {
|
|
78
82
|
method: "POST",
|
|
79
83
|
headers: {
|
|
80
84
|
"Content-Type": "application/json",
|
|
81
85
|
Authorization: `Bearer ${runtimeKey}`,
|
|
82
86
|
},
|
|
83
|
-
body: JSON.stringify(
|
|
87
|
+
body: JSON.stringify({ targetHandle }),
|
|
84
88
|
});
|
|
85
89
|
if (!res.ok)
|
|
86
90
|
return handleError(res);
|
|
87
|
-
|
|
91
|
+
const body = (await res.json().catch(() => ({})));
|
|
92
|
+
return { request: body.request ?? null, created: res.status === 201 };
|
|
88
93
|
}
|
|
89
94
|
export async function listRequests(cfg, runtimeKey, params) {
|
|
90
95
|
const query = new URLSearchParams();
|
|
91
|
-
if (params?.status != null)
|
|
92
|
-
query.set("status", params.status);
|
|
93
|
-
if (params?.direction != null)
|
|
94
|
-
query.set("direction", params.direction);
|
|
95
|
-
if (params?.page != null)
|
|
96
|
-
query.set("page", String(params.page));
|
|
97
96
|
if (params?.limit != null)
|
|
98
97
|
query.set("limit", String(params.limit));
|
|
98
|
+
if (params?.cursor != null)
|
|
99
|
+
query.set("cursor", params.cursor);
|
|
100
|
+
if (params?.counterparty != null)
|
|
101
|
+
query.set("counterparty", params.counterparty);
|
|
99
102
|
const qs = query.toString();
|
|
100
|
-
const url = `${baseUrl(cfg)}
|
|
103
|
+
const url = `${baseUrl(cfg)}${REQUESTS_PATH}${qs ? `?${qs}` : ""}`;
|
|
101
104
|
const res = await apiFetch(url, {
|
|
102
105
|
headers: { Authorization: `Bearer ${runtimeKey}` },
|
|
103
106
|
});
|
|
@@ -105,24 +108,34 @@ export async function listRequests(cfg, runtimeKey, params) {
|
|
|
105
108
|
return handleError(res);
|
|
106
109
|
return (await res.json());
|
|
107
110
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
111
|
+
function resolveVerb(verb) {
|
|
112
|
+
return async (cfg, runtimeKey, requestId) => {
|
|
113
|
+
const res = await apiFetch(`${baseUrl(cfg)}${REQUESTS_PATH}/${encodeURIComponent(requestId)}/${verb}`, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: { Authorization: `Bearer ${runtimeKey}` },
|
|
116
|
+
});
|
|
117
|
+
if (res.status === 409) {
|
|
118
|
+
const conflict = (await res.json().catch(() => ({})));
|
|
119
|
+
if (conflict.error === "already_resolved") {
|
|
120
|
+
return {
|
|
121
|
+
outcome: "already_resolved",
|
|
122
|
+
status: typeof conflict.status === "string" ? conflict.status : null,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!res.ok)
|
|
127
|
+
return handleError(res);
|
|
128
|
+
const body = (await res.json().catch(() => ({})));
|
|
129
|
+
return {
|
|
130
|
+
outcome: "resolved",
|
|
131
|
+
idempotent: body.idempotent === true,
|
|
132
|
+
request: body.request ?? null,
|
|
133
|
+
};
|
|
134
|
+
};
|
|
125
135
|
}
|
|
136
|
+
export const acceptRequest = resolveVerb("accept");
|
|
137
|
+
export const ignoreRequest = resolveVerb("ignore");
|
|
138
|
+
export const withdrawRequest = resolveVerb("withdraw");
|
|
126
139
|
export async function updateProfile(cfg, runtimeKey, params) {
|
|
127
140
|
const res = await apiFetch(`${baseUrl(cfg)}/me/profile`, {
|
|
128
141
|
method: "PATCH",
|
|
@@ -154,5 +167,17 @@ export async function getIdentity(cfg, runtimeKey) {
|
|
|
154
167
|
if (!body || body.node === undefined) {
|
|
155
168
|
throw new PlatformApiError(res.status, "malformed_response", "identity response carried no `node` field");
|
|
156
169
|
}
|
|
170
|
+
if (body.node === null)
|
|
171
|
+
return null;
|
|
172
|
+
if (!isNodeRef(body.node)) {
|
|
173
|
+
throw new PlatformApiError(res.status, "malformed_response", "identity response `node` carried no mstpAddress");
|
|
174
|
+
}
|
|
157
175
|
return body.node;
|
|
158
176
|
}
|
|
177
|
+
function isNodeRef(value) {
|
|
178
|
+
return (typeof value === "object" &&
|
|
179
|
+
value !== null &&
|
|
180
|
+
"mstpAddress" in value &&
|
|
181
|
+
typeof value.mstpAddress === "string" &&
|
|
182
|
+
value.mstpAddress.length > 0);
|
|
183
|
+
}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAUrE,OAAO,EACL,kCAAkC,EAEnC,MAAM,oCAAoC,CAAC;AA8D5C,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,mBAAmB,GAAE,mBAAmB,GAAG,IAA+B,GACzE,MAAM,GAAG,SAAS,CA6EpB;AAKD,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CACV,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,IAAI,CAAC;IACR,yBAAyB,CAAC,MAAM,EAAE;QAChC,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,OAAO,kCAAkC,CAAC;KACrD,GAAG,IAAI,CAAC;IACT,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAqCD,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAUrE,OAAO,EACL,kCAAkC,EAEnC,MAAM,oCAAoC,CAAC;AA8D5C,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,mBAAmB,GAAE,mBAAmB,GAAG,IAA+B,GACzE,MAAM,GAAG,SAAS,CA6EpB;AAKD,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CACV,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,IAAI,CAAC;IACR,yBAAyB,CAAC,MAAM,EAAE;QAChC,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,OAAO,kCAAkC,CAAC;KACrD,GAAG,IAAI,CAAC;IACT,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAqCD,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;CAoahC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -143,9 +143,11 @@ const plugin = {
|
|
|
143
143
|
"separate from your owner's conversation; " +
|
|
144
144
|
"masons_note_for_owner(content, from?) — save a note for your owner's next turn. " +
|
|
145
145
|
"Other network tools: masons_list_requests, masons_send_connection_request, " +
|
|
146
|
-
"masons_accept_request,
|
|
146
|
+
"masons_accept_request, masons_list_connections, " +
|
|
147
147
|
"masons_end_conversation (rare one-shot close signal only), " +
|
|
148
148
|
"masons_status (your canonical identity and participation status). " +
|
|
149
|
+
"masons_withdraw_request (take back a connection request you sent). " +
|
|
150
|
+
"masons_ignore_request (set aside a connection request awaiting your decision; silent — the sender is not notified). " +
|
|
149
151
|
"Always try these tools first for network operations. " +
|
|
150
152
|
"If a tool call fails, report the error to your user — do not silently work around it. " +
|
|
151
153
|
"You interact with multiple entities simultaneously — your owner and agents on the network. " +
|