@multi-agent-protocol/sdk 0.0.5 → 0.0.7
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 +164 -5
- package/dist/{index-DMcRbXOS.d.cts → index-BQXp4_rd.d.cts} +543 -12
- package/dist/{index-DMcRbXOS.d.ts → index-BQXp4_rd.d.ts} +543 -12
- package/dist/index.cjs +774 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +520 -12
- package/dist/index.d.ts +520 -12
- package/dist/index.js +773 -5
- package/dist/index.js.map +1 -1
- package/dist/testing.cjs +442 -8
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +442 -8
- package/dist/testing.js.map +1 -1
- package/package.json +7 -4
package/dist/testing.cjs
CHANGED
|
@@ -1,8 +1,88 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var agenticMesh = require('agentic-mesh');
|
|
3
4
|
var ulid = require('ulid');
|
|
4
5
|
var events = require('events');
|
|
5
6
|
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
12
|
+
var __export = (target, all) => {
|
|
13
|
+
for (var name in all)
|
|
14
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/stream/agentic-mesh.ts
|
|
18
|
+
var agentic_mesh_exports = {};
|
|
19
|
+
__export(agentic_mesh_exports, {
|
|
20
|
+
agenticMeshStream: () => agenticMeshStream
|
|
21
|
+
});
|
|
22
|
+
async function agenticMeshStream(config) {
|
|
23
|
+
if (!config.transport.active) {
|
|
24
|
+
await config.transport.start();
|
|
25
|
+
}
|
|
26
|
+
const connected = await config.transport.connect(config.peer);
|
|
27
|
+
if (!connected) {
|
|
28
|
+
throw new Error(`Failed to connect to peer: ${config.peer.peerId}`);
|
|
29
|
+
}
|
|
30
|
+
const streamId = `map-${config.localPeerId}-${Date.now()}`;
|
|
31
|
+
const tunnelStream = new agenticMesh.TunnelStream({
|
|
32
|
+
transport: config.transport,
|
|
33
|
+
peerId: config.peer.peerId,
|
|
34
|
+
streamId
|
|
35
|
+
});
|
|
36
|
+
await tunnelStream.open();
|
|
37
|
+
return tunnelStreamToMapStream(tunnelStream);
|
|
38
|
+
}
|
|
39
|
+
function tunnelStreamToMapStream(tunnel) {
|
|
40
|
+
let readingAborted = false;
|
|
41
|
+
const readable = new ReadableStream({
|
|
42
|
+
async start(controller) {
|
|
43
|
+
try {
|
|
44
|
+
for await (const frame of tunnel) {
|
|
45
|
+
if (readingAborted) break;
|
|
46
|
+
controller.enqueue(frame);
|
|
47
|
+
}
|
|
48
|
+
if (!readingAborted) {
|
|
49
|
+
controller.close();
|
|
50
|
+
}
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (!readingAborted) {
|
|
53
|
+
controller.error(error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
cancel() {
|
|
58
|
+
readingAborted = true;
|
|
59
|
+
tunnel.close().catch(() => {
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const writable = new WritableStream({
|
|
64
|
+
async write(message) {
|
|
65
|
+
if (!tunnel.isOpen) {
|
|
66
|
+
throw new Error("Stream is not open");
|
|
67
|
+
}
|
|
68
|
+
await tunnel.write(message);
|
|
69
|
+
},
|
|
70
|
+
async close() {
|
|
71
|
+
await tunnel.close();
|
|
72
|
+
},
|
|
73
|
+
abort() {
|
|
74
|
+
readingAborted = true;
|
|
75
|
+
tunnel.close().catch(() => {
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return { readable, writable };
|
|
80
|
+
}
|
|
81
|
+
var init_agentic_mesh = __esm({
|
|
82
|
+
"src/stream/agentic-mesh.ts"() {
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
6
86
|
// src/jsonrpc/index.ts
|
|
7
87
|
function isRequest(message) {
|
|
8
88
|
return typeof message === "object" && message !== null && "jsonrpc" in message && message.jsonrpc === "2.0" && "id" in message && "method" in message;
|
|
@@ -112,6 +192,10 @@ var SESSION_METHODS = {
|
|
|
112
192
|
SESSION_LOAD: "map/session/load",
|
|
113
193
|
SESSION_CLOSE: "map/session/close"
|
|
114
194
|
};
|
|
195
|
+
var AUTH_METHODS = {
|
|
196
|
+
AUTHENTICATE: "map/authenticate",
|
|
197
|
+
AUTH_REFRESH: "map/auth/refresh"
|
|
198
|
+
};
|
|
115
199
|
var PERMISSION_METHODS = {
|
|
116
200
|
PERMISSIONS_UPDATE: "map/permissions/update"
|
|
117
201
|
};
|
|
@@ -122,8 +206,7 @@ var NOTIFICATION_METHODS = {
|
|
|
122
206
|
EVENT: "map/event",
|
|
123
207
|
MESSAGE: "map/message",
|
|
124
208
|
/** Client acknowledges received events (for backpressure) */
|
|
125
|
-
SUBSCRIBE_ACK: "map/subscribe.ack"
|
|
126
|
-
};
|
|
209
|
+
SUBSCRIBE_ACK: "map/subscribe.ack"};
|
|
127
210
|
var PROTOCOL_ERROR_CODES = {
|
|
128
211
|
PARSE_ERROR: -32700,
|
|
129
212
|
INVALID_REQUEST: -32600,
|
|
@@ -135,7 +218,10 @@ var AUTH_ERROR_CODES = {
|
|
|
135
218
|
AUTH_REQUIRED: 1e3,
|
|
136
219
|
AUTH_FAILED: 1001,
|
|
137
220
|
TOKEN_EXPIRED: 1002,
|
|
138
|
-
PERMISSION_DENIED: 1003
|
|
221
|
+
PERMISSION_DENIED: 1003,
|
|
222
|
+
INSUFFICIENT_SCOPE: 1004,
|
|
223
|
+
METHOD_NOT_SUPPORTED: 1005,
|
|
224
|
+
INVALID_CREDENTIALS: 1006
|
|
139
225
|
};
|
|
140
226
|
var ROUTING_ERROR_CODES = {
|
|
141
227
|
ADDRESS_NOT_FOUND: 2e3,
|
|
@@ -274,6 +360,27 @@ var MAPRequestError = class _MAPRequestError extends Error {
|
|
|
274
360
|
{ category: "auth" }
|
|
275
361
|
);
|
|
276
362
|
}
|
|
363
|
+
static insufficientScope(required) {
|
|
364
|
+
return new _MAPRequestError(
|
|
365
|
+
AUTH_ERROR_CODES.INSUFFICIENT_SCOPE,
|
|
366
|
+
required ? `Insufficient scope: ${required}` : "Insufficient scope",
|
|
367
|
+
{ category: "auth" }
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
static methodNotSupported(method) {
|
|
371
|
+
return new _MAPRequestError(
|
|
372
|
+
AUTH_ERROR_CODES.METHOD_NOT_SUPPORTED,
|
|
373
|
+
`Authentication method not supported: ${method}`,
|
|
374
|
+
{ category: "auth" }
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
static invalidCredentials(details) {
|
|
378
|
+
return new _MAPRequestError(
|
|
379
|
+
AUTH_ERROR_CODES.INVALID_CREDENTIALS,
|
|
380
|
+
details ?? "Invalid credentials",
|
|
381
|
+
{ category: "auth" }
|
|
382
|
+
);
|
|
383
|
+
}
|
|
277
384
|
// ==========================================================================
|
|
278
385
|
// Routing Errors (2xxx)
|
|
279
386
|
// ==========================================================================
|
|
@@ -1853,11 +1960,6 @@ var TestServer = class {
|
|
|
1853
1960
|
return false;
|
|
1854
1961
|
}
|
|
1855
1962
|
}
|
|
1856
|
-
if (filter.agents?.length && event.source) {
|
|
1857
|
-
if (!filter.agents.includes(event.source)) {
|
|
1858
|
-
return false;
|
|
1859
|
-
}
|
|
1860
|
-
}
|
|
1861
1963
|
if (filter.fromAgents?.length && event.source) {
|
|
1862
1964
|
if (!filter.fromAgents.includes(event.source)) {
|
|
1863
1965
|
return false;
|
|
@@ -2045,6 +2147,7 @@ var TestServer = class {
|
|
|
2045
2147
|
};
|
|
2046
2148
|
|
|
2047
2149
|
// src/stream/index.ts
|
|
2150
|
+
init_agentic_mesh();
|
|
2048
2151
|
function websocketStream(ws) {
|
|
2049
2152
|
const messageQueue = [];
|
|
2050
2153
|
let messageResolver = null;
|
|
@@ -3115,6 +3218,33 @@ var ACPStreamConnection = class extends events.EventEmitter {
|
|
|
3115
3218
|
});
|
|
3116
3219
|
}
|
|
3117
3220
|
// ===========================================================================
|
|
3221
|
+
// Extension Methods
|
|
3222
|
+
// ===========================================================================
|
|
3223
|
+
/**
|
|
3224
|
+
* Call an ACP extension method on the target agent.
|
|
3225
|
+
*
|
|
3226
|
+
* Extension methods are prefixed with "_" (e.g., "_macro/spawnAgent").
|
|
3227
|
+
* The agent must support the extension for this to succeed.
|
|
3228
|
+
*
|
|
3229
|
+
* @param method - The extension method name (e.g., "_macro/spawnAgent")
|
|
3230
|
+
* @param params - Parameters to pass to the extension method
|
|
3231
|
+
* @returns The result from the extension method
|
|
3232
|
+
*
|
|
3233
|
+
* @example
|
|
3234
|
+
* ```typescript
|
|
3235
|
+
* const result = await acp.callExtension("_macro/spawnAgent", {
|
|
3236
|
+
* task: "Implement feature X",
|
|
3237
|
+
* cwd: "/project"
|
|
3238
|
+
* });
|
|
3239
|
+
* ```
|
|
3240
|
+
*/
|
|
3241
|
+
async callExtension(method, params) {
|
|
3242
|
+
if (!this.#initialized) {
|
|
3243
|
+
throw new Error("Must call initialize() before callExtension()");
|
|
3244
|
+
}
|
|
3245
|
+
return this.#sendRequest(method, params);
|
|
3246
|
+
}
|
|
3247
|
+
// ===========================================================================
|
|
3118
3248
|
// Lifecycle
|
|
3119
3249
|
// ===========================================================================
|
|
3120
3250
|
/**
|
|
@@ -3153,6 +3283,8 @@ var ClientConnection = class _ClientConnection {
|
|
|
3153
3283
|
#connected = false;
|
|
3154
3284
|
#lastConnectOptions;
|
|
3155
3285
|
#isReconnecting = false;
|
|
3286
|
+
#lastResumeToken;
|
|
3287
|
+
#onTokenExpiring;
|
|
3156
3288
|
constructor(stream, options = {}) {
|
|
3157
3289
|
this.#connection = new BaseConnection(stream, options);
|
|
3158
3290
|
this.#options = options;
|
|
@@ -3218,11 +3350,70 @@ var ClientConnection = class _ClientConnection {
|
|
|
3218
3350
|
await client.connect({ auth: options?.auth });
|
|
3219
3351
|
return client;
|
|
3220
3352
|
}
|
|
3353
|
+
/**
|
|
3354
|
+
* Connect to a MAP server via agentic-mesh transport.
|
|
3355
|
+
*
|
|
3356
|
+
* Handles:
|
|
3357
|
+
* - Dynamic import of agentic-mesh (optional peer dependency)
|
|
3358
|
+
* - Stream creation over encrypted mesh tunnel
|
|
3359
|
+
* - Auto-configuration of createStream for reconnection
|
|
3360
|
+
* - Initial MAP protocol connect handshake
|
|
3361
|
+
*
|
|
3362
|
+
* Requires `agentic-mesh` to be installed as a peer dependency.
|
|
3363
|
+
*
|
|
3364
|
+
* @param options - Mesh connection options
|
|
3365
|
+
* @returns Connected ClientConnection instance
|
|
3366
|
+
*
|
|
3367
|
+
* @example
|
|
3368
|
+
* ```typescript
|
|
3369
|
+
* import { createNebulaTransport } from 'agentic-mesh';
|
|
3370
|
+
*
|
|
3371
|
+
* const transport = createNebulaTransport({
|
|
3372
|
+
* configPath: '/etc/nebula/config.yml',
|
|
3373
|
+
* });
|
|
3374
|
+
*
|
|
3375
|
+
* const client = await ClientConnection.connectMesh({
|
|
3376
|
+
* transport,
|
|
3377
|
+
* peer: { peerId: 'server', address: '10.0.0.1', port: 4242 },
|
|
3378
|
+
* localPeerId: 'my-client',
|
|
3379
|
+
* name: 'MeshClient',
|
|
3380
|
+
* reconnection: true
|
|
3381
|
+
* });
|
|
3382
|
+
*
|
|
3383
|
+
* const agents = await client.listAgents();
|
|
3384
|
+
* ```
|
|
3385
|
+
*/
|
|
3386
|
+
static async connectMesh(options) {
|
|
3387
|
+
const { agenticMeshStream: agenticMeshStream2 } = await Promise.resolve().then(() => (init_agentic_mesh(), agentic_mesh_exports));
|
|
3388
|
+
const streamConfig = {
|
|
3389
|
+
transport: options.transport,
|
|
3390
|
+
peer: options.peer,
|
|
3391
|
+
localPeerId: options.localPeerId,
|
|
3392
|
+
timeout: options.timeout
|
|
3393
|
+
};
|
|
3394
|
+
const stream = await agenticMeshStream2(streamConfig);
|
|
3395
|
+
const createStream = async () => agenticMeshStream2(streamConfig);
|
|
3396
|
+
const reconnection = options.reconnection === true ? { enabled: true } : typeof options.reconnection === "object" ? options.reconnection : void 0;
|
|
3397
|
+
const client = new _ClientConnection(stream, {
|
|
3398
|
+
name: options.name,
|
|
3399
|
+
capabilities: options.capabilities,
|
|
3400
|
+
createStream,
|
|
3401
|
+
reconnection
|
|
3402
|
+
});
|
|
3403
|
+
await client.connect({ auth: options.auth });
|
|
3404
|
+
return client;
|
|
3405
|
+
}
|
|
3221
3406
|
// ===========================================================================
|
|
3222
3407
|
// Connection Lifecycle
|
|
3223
3408
|
// ===========================================================================
|
|
3224
3409
|
/**
|
|
3225
3410
|
* Connect to the MAP system
|
|
3411
|
+
*
|
|
3412
|
+
* @param options - Connection options
|
|
3413
|
+
* @param options.sessionId - Specific session ID to use
|
|
3414
|
+
* @param options.resumeToken - Token to resume a previously disconnected session
|
|
3415
|
+
* @param options.auth - Authentication credentials
|
|
3416
|
+
* @param options.onTokenExpiring - Callback invoked before token expires for proactive refresh
|
|
3226
3417
|
*/
|
|
3227
3418
|
async connect(options) {
|
|
3228
3419
|
const params = {
|
|
@@ -3238,10 +3429,134 @@ var ClientConnection = class _ClientConnection {
|
|
|
3238
3429
|
this.#sessionId = result.sessionId;
|
|
3239
3430
|
this.#serverCapabilities = result.capabilities;
|
|
3240
3431
|
this.#connected = true;
|
|
3432
|
+
if (result.resumeToken) {
|
|
3433
|
+
this.#lastResumeToken = result.resumeToken;
|
|
3434
|
+
}
|
|
3435
|
+
if (options?.onTokenExpiring) {
|
|
3436
|
+
this.#onTokenExpiring = options.onTokenExpiring;
|
|
3437
|
+
this.#setupTokenExpiryMonitoring(result);
|
|
3438
|
+
}
|
|
3241
3439
|
this.#connection._transitionTo("connected");
|
|
3242
3440
|
this.#lastConnectOptions = options;
|
|
3243
3441
|
return result;
|
|
3244
3442
|
}
|
|
3443
|
+
/**
|
|
3444
|
+
* Get the resume token for this session.
|
|
3445
|
+
* Can be used to reconnect and restore session state after disconnection.
|
|
3446
|
+
*
|
|
3447
|
+
* @returns The resume token, or undefined if not available
|
|
3448
|
+
*/
|
|
3449
|
+
getResumeToken() {
|
|
3450
|
+
return this.#lastResumeToken;
|
|
3451
|
+
}
|
|
3452
|
+
/**
|
|
3453
|
+
* Reconnect to the server, optionally using a resume token to restore session.
|
|
3454
|
+
*
|
|
3455
|
+
* @param resumeToken - Token to resume previous session. If not provided, uses the last known token.
|
|
3456
|
+
* @returns Connect response result
|
|
3457
|
+
*
|
|
3458
|
+
* @example
|
|
3459
|
+
* ```typescript
|
|
3460
|
+
* // Save token before disconnect
|
|
3461
|
+
* const token = await client.disconnect();
|
|
3462
|
+
*
|
|
3463
|
+
* // Later, reconnect with the token
|
|
3464
|
+
* const result = await client.reconnect(token);
|
|
3465
|
+
* console.log('Reconnected:', result.reconnected);
|
|
3466
|
+
* ```
|
|
3467
|
+
*/
|
|
3468
|
+
async reconnect(resumeToken) {
|
|
3469
|
+
const tokenToUse = resumeToken ?? this.#lastResumeToken;
|
|
3470
|
+
return this.connect({
|
|
3471
|
+
...this.#lastConnectOptions,
|
|
3472
|
+
resumeToken: tokenToUse
|
|
3473
|
+
});
|
|
3474
|
+
}
|
|
3475
|
+
/**
|
|
3476
|
+
* Set up monitoring for token expiration
|
|
3477
|
+
*/
|
|
3478
|
+
#setupTokenExpiryMonitoring(connectResult) {
|
|
3479
|
+
const principal = connectResult.principal;
|
|
3480
|
+
if (!principal?.expiresAt || !this.#onTokenExpiring) {
|
|
3481
|
+
return;
|
|
3482
|
+
}
|
|
3483
|
+
const expiresAt = principal.expiresAt;
|
|
3484
|
+
const now = Date.now();
|
|
3485
|
+
const warningTime = expiresAt - 6e4;
|
|
3486
|
+
const delay = warningTime - now;
|
|
3487
|
+
if (delay > 0) {
|
|
3488
|
+
setTimeout(async () => {
|
|
3489
|
+
if (!this.#connected || !this.#onTokenExpiring) return;
|
|
3490
|
+
try {
|
|
3491
|
+
const newCredentials = await this.#onTokenExpiring(expiresAt);
|
|
3492
|
+
if (newCredentials) {
|
|
3493
|
+
const refreshResult = await this.refreshAuth({
|
|
3494
|
+
method: newCredentials.method,
|
|
3495
|
+
credential: newCredentials.credential
|
|
3496
|
+
});
|
|
3497
|
+
if (refreshResult.success && refreshResult.principal?.expiresAt) {
|
|
3498
|
+
this.#setupTokenExpiryMonitoring({
|
|
3499
|
+
...connectResult,
|
|
3500
|
+
principal: refreshResult.principal
|
|
3501
|
+
});
|
|
3502
|
+
}
|
|
3503
|
+
}
|
|
3504
|
+
} catch {
|
|
3505
|
+
}
|
|
3506
|
+
}, delay);
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
/**
|
|
3510
|
+
* Authenticate with the server after connection.
|
|
3511
|
+
*
|
|
3512
|
+
* Use this when the server returns `authRequired` in the connect response,
|
|
3513
|
+
* indicating that authentication is needed before accessing protected resources.
|
|
3514
|
+
*
|
|
3515
|
+
* @param auth - Authentication credentials
|
|
3516
|
+
* @returns Authentication result with principal if successful
|
|
3517
|
+
*
|
|
3518
|
+
* @example
|
|
3519
|
+
* ```typescript
|
|
3520
|
+
* const connectResult = await client.connect();
|
|
3521
|
+
*
|
|
3522
|
+
* if (connectResult.authRequired) {
|
|
3523
|
+
* const authResult = await client.authenticate({
|
|
3524
|
+
* method: 'api-key',
|
|
3525
|
+
* credential: process.env.API_KEY,
|
|
3526
|
+
* });
|
|
3527
|
+
*
|
|
3528
|
+
* if (authResult.success) {
|
|
3529
|
+
* console.log('Authenticated as:', authResult.principal?.id);
|
|
3530
|
+
* }
|
|
3531
|
+
* }
|
|
3532
|
+
* ```
|
|
3533
|
+
*/
|
|
3534
|
+
async authenticate(auth) {
|
|
3535
|
+
const params = {
|
|
3536
|
+
method: auth.method,
|
|
3537
|
+
credential: auth.credential
|
|
3538
|
+
};
|
|
3539
|
+
const result = await this.#connection.sendRequest(AUTH_METHODS.AUTHENTICATE, params);
|
|
3540
|
+
if (result.success && result.sessionId) {
|
|
3541
|
+
this.#sessionId = result.sessionId;
|
|
3542
|
+
}
|
|
3543
|
+
return result;
|
|
3544
|
+
}
|
|
3545
|
+
/**
|
|
3546
|
+
* Refresh authentication credentials.
|
|
3547
|
+
*
|
|
3548
|
+
* Use this to update credentials before they expire for long-lived connections.
|
|
3549
|
+
*
|
|
3550
|
+
* @param auth - New authentication credentials
|
|
3551
|
+
* @returns Updated principal information
|
|
3552
|
+
*/
|
|
3553
|
+
async refreshAuth(auth) {
|
|
3554
|
+
const params = {
|
|
3555
|
+
method: auth.method,
|
|
3556
|
+
credential: auth.credential
|
|
3557
|
+
};
|
|
3558
|
+
return this.#connection.sendRequest(AUTH_METHODS.AUTH_REFRESH, params);
|
|
3559
|
+
}
|
|
3245
3560
|
/**
|
|
3246
3561
|
* Disconnect from the MAP system
|
|
3247
3562
|
* @param reason - Optional reason for disconnecting
|
|
@@ -3256,6 +3571,9 @@ var ClientConnection = class _ClientConnection {
|
|
|
3256
3571
|
reason ? { reason } : void 0
|
|
3257
3572
|
);
|
|
3258
3573
|
resumeToken = result.resumeToken;
|
|
3574
|
+
if (resumeToken) {
|
|
3575
|
+
this.#lastResumeToken = resumeToken;
|
|
3576
|
+
}
|
|
3259
3577
|
} finally {
|
|
3260
3578
|
for (const stream of this.#acpStreams.values()) {
|
|
3261
3579
|
await stream.close();
|
|
@@ -4140,6 +4458,66 @@ var AgentConnection = class _AgentConnection {
|
|
|
4140
4458
|
await agent.connect({ auth: options?.auth });
|
|
4141
4459
|
return agent;
|
|
4142
4460
|
}
|
|
4461
|
+
/**
|
|
4462
|
+
* Connect and register an agent via agentic-mesh transport.
|
|
4463
|
+
*
|
|
4464
|
+
* Handles:
|
|
4465
|
+
* - Dynamic import of agentic-mesh (optional peer dependency)
|
|
4466
|
+
* - Stream creation over encrypted mesh tunnel
|
|
4467
|
+
* - Auto-configuration of createStream for reconnection
|
|
4468
|
+
* - Initial MAP protocol connect handshake
|
|
4469
|
+
* - Agent registration
|
|
4470
|
+
*
|
|
4471
|
+
* Requires `agentic-mesh` to be installed as a peer dependency.
|
|
4472
|
+
*
|
|
4473
|
+
* @param options - Mesh connection and agent options
|
|
4474
|
+
* @returns Connected and registered AgentConnection instance
|
|
4475
|
+
*
|
|
4476
|
+
* @example
|
|
4477
|
+
* ```typescript
|
|
4478
|
+
* import { createNebulaTransport } from 'agentic-mesh';
|
|
4479
|
+
*
|
|
4480
|
+
* const transport = createNebulaTransport({
|
|
4481
|
+
* configPath: '/etc/nebula/config.yml',
|
|
4482
|
+
* });
|
|
4483
|
+
*
|
|
4484
|
+
* const agent = await AgentConnection.connectMesh({
|
|
4485
|
+
* transport,
|
|
4486
|
+
* peer: { peerId: 'server', address: '10.0.0.1', port: 4242 },
|
|
4487
|
+
* localPeerId: 'my-agent',
|
|
4488
|
+
* name: 'MeshWorker',
|
|
4489
|
+
* role: 'processor',
|
|
4490
|
+
* reconnection: true
|
|
4491
|
+
* });
|
|
4492
|
+
*
|
|
4493
|
+
* agent.onMessage(handleMessage);
|
|
4494
|
+
* await agent.busy();
|
|
4495
|
+
* ```
|
|
4496
|
+
*/
|
|
4497
|
+
static async connectMesh(options) {
|
|
4498
|
+
const { agenticMeshStream: agenticMeshStream2 } = await Promise.resolve().then(() => (init_agentic_mesh(), agentic_mesh_exports));
|
|
4499
|
+
const streamConfig = {
|
|
4500
|
+
transport: options.transport,
|
|
4501
|
+
peer: options.peer,
|
|
4502
|
+
localPeerId: options.localPeerId,
|
|
4503
|
+
timeout: options.timeout
|
|
4504
|
+
};
|
|
4505
|
+
const stream = await agenticMeshStream2(streamConfig);
|
|
4506
|
+
const createStream = async () => agenticMeshStream2(streamConfig);
|
|
4507
|
+
const reconnection = options.reconnection === true ? { enabled: true } : typeof options.reconnection === "object" ? options.reconnection : void 0;
|
|
4508
|
+
const agent = new _AgentConnection(stream, {
|
|
4509
|
+
name: options.name,
|
|
4510
|
+
role: options.role,
|
|
4511
|
+
capabilities: options.capabilities,
|
|
4512
|
+
visibility: options.visibility,
|
|
4513
|
+
parent: options.parent,
|
|
4514
|
+
scopes: options.scopes,
|
|
4515
|
+
createStream,
|
|
4516
|
+
reconnection
|
|
4517
|
+
});
|
|
4518
|
+
await agent.connect({ auth: options.auth });
|
|
4519
|
+
return agent;
|
|
4520
|
+
}
|
|
4143
4521
|
// ===========================================================================
|
|
4144
4522
|
// Connection Lifecycle
|
|
4145
4523
|
// ===========================================================================
|
|
@@ -4176,6 +4554,62 @@ var AgentConnection = class _AgentConnection {
|
|
|
4176
4554
|
this.#connection._transitionTo("connected");
|
|
4177
4555
|
return { connection: connectResult, agent: registerResult.agent };
|
|
4178
4556
|
}
|
|
4557
|
+
/**
|
|
4558
|
+
* Authenticate with the server after connection.
|
|
4559
|
+
*
|
|
4560
|
+
* Use this when the server returns `authRequired` in the connect response,
|
|
4561
|
+
* indicating that authentication is needed before registering or accessing
|
|
4562
|
+
* protected resources.
|
|
4563
|
+
*
|
|
4564
|
+
* @param auth - Authentication credentials
|
|
4565
|
+
* @returns Authentication result with principal if successful
|
|
4566
|
+
*
|
|
4567
|
+
* @example
|
|
4568
|
+
* ```typescript
|
|
4569
|
+
* const agent = new AgentConnection(stream, { name: 'MyAgent' });
|
|
4570
|
+
*
|
|
4571
|
+
* // First connect to get auth requirements
|
|
4572
|
+
* const connectResult = await agent.connectOnly();
|
|
4573
|
+
*
|
|
4574
|
+
* if (connectResult.authRequired) {
|
|
4575
|
+
* const authResult = await agent.authenticate({
|
|
4576
|
+
* method: 'api-key',
|
|
4577
|
+
* token: process.env.AGENT_API_KEY,
|
|
4578
|
+
* });
|
|
4579
|
+
*
|
|
4580
|
+
* if (authResult.success) {
|
|
4581
|
+
* // Now register the agent
|
|
4582
|
+
* await agent.register({ name: 'MyAgent', role: 'worker' });
|
|
4583
|
+
* }
|
|
4584
|
+
* }
|
|
4585
|
+
* ```
|
|
4586
|
+
*/
|
|
4587
|
+
async authenticate(auth) {
|
|
4588
|
+
const params = {
|
|
4589
|
+
method: auth.method,
|
|
4590
|
+
credential: auth.token
|
|
4591
|
+
};
|
|
4592
|
+
const result = await this.#connection.sendRequest(AUTH_METHODS.AUTHENTICATE, params);
|
|
4593
|
+
if (result.success && result.sessionId) {
|
|
4594
|
+
this.#sessionId = result.sessionId;
|
|
4595
|
+
}
|
|
4596
|
+
return result;
|
|
4597
|
+
}
|
|
4598
|
+
/**
|
|
4599
|
+
* Refresh authentication credentials.
|
|
4600
|
+
*
|
|
4601
|
+
* Use this to update credentials before they expire for long-lived connections.
|
|
4602
|
+
*
|
|
4603
|
+
* @param auth - New authentication credentials
|
|
4604
|
+
* @returns Updated principal information
|
|
4605
|
+
*/
|
|
4606
|
+
async refreshAuth(auth) {
|
|
4607
|
+
const params = {
|
|
4608
|
+
method: auth.method,
|
|
4609
|
+
credential: auth.token
|
|
4610
|
+
};
|
|
4611
|
+
return this.#connection.sendRequest(AUTH_METHODS.AUTH_REFRESH, params);
|
|
4612
|
+
}
|
|
4179
4613
|
/**
|
|
4180
4614
|
* Disconnect from the MAP system
|
|
4181
4615
|
* @param reason - Optional reason for disconnecting
|