@multi-agent-protocol/sdk 0.0.2 → 0.0.4

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.
@@ -1,4 +1,4 @@
1
- import { P as ParticipantCapabilities, dy as SystemExposure, d as FederationRoutingConfig, S as Stream, aC as BaseConnection, f as SessionId, A as AgentId, m as Agent, l as ScopeId, n as Scope, c as Message, q as Event, j as ParticipantId, L as SubscriptionId, aI as ClientConnectionOptions, aH as ClientConnection, ae as AgentsListRequestParams, ct as ScopesListRequestParams, p as SubscriptionFilter, cR as Subscription, e as EventType, Y as AgentConnectionOptions, X as AgentConnection } from './index-C7XPWnxS.cjs';
1
+ import { P as ParticipantCapabilities, dA as SystemExposure, d as FederationRoutingConfig, S as Stream, aD as BaseConnection, f as SessionId, A as AgentId, m as Agent, l as ScopeId, n as Scope, c as Message, q as Event, j as ParticipantId, L as SubscriptionId, aK as ClientConnectionOptions, aJ as ClientConnection, af as AgentsListRequestParams, cv as ScopesListRequestParams, p as SubscriptionFilter, cT as Subscription, e as EventType, Z as AgentConnectionOptions, Y as AgentConnection } from './index-Z76qC_Us.cjs';
2
2
 
3
3
  /**
4
4
  * Test MAP Server Implementation
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as ParticipantCapabilities, dy as SystemExposure, d as FederationRoutingConfig, S as Stream, aC as BaseConnection, f as SessionId, A as AgentId, m as Agent, l as ScopeId, n as Scope, c as Message, q as Event, j as ParticipantId, L as SubscriptionId, aI as ClientConnectionOptions, aH as ClientConnection, ae as AgentsListRequestParams, ct as ScopesListRequestParams, p as SubscriptionFilter, cR as Subscription, e as EventType, Y as AgentConnectionOptions, X as AgentConnection } from './index-C7XPWnxS.js';
1
+ import { P as ParticipantCapabilities, dA as SystemExposure, d as FederationRoutingConfig, S as Stream, aD as BaseConnection, f as SessionId, A as AgentId, m as Agent, l as ScopeId, n as Scope, c as Message, q as Event, j as ParticipantId, L as SubscriptionId, aK as ClientConnectionOptions, aJ as ClientConnection, af as AgentsListRequestParams, cv as ScopesListRequestParams, p as SubscriptionFilter, cT as Subscription, e as EventType, Z as AgentConnectionOptions, Y as AgentConnection } from './index-Z76qC_Us.js';
2
2
 
3
3
  /**
4
4
  * Test MAP Server Implementation
package/dist/testing.js CHANGED
@@ -2032,6 +2032,211 @@ var TestServer = class {
2032
2032
  }
2033
2033
  };
2034
2034
 
2035
+ // src/stream/index.ts
2036
+ function websocketStream(ws) {
2037
+ const messageQueue = [];
2038
+ let messageResolver = null;
2039
+ let closed = false;
2040
+ let closeError = null;
2041
+ ws.addEventListener("message", (event) => {
2042
+ try {
2043
+ const message = JSON.parse(event.data);
2044
+ if (messageResolver) {
2045
+ messageResolver({ value: message, done: false });
2046
+ messageResolver = null;
2047
+ } else {
2048
+ messageQueue.push(message);
2049
+ }
2050
+ } catch {
2051
+ console.error("MAP: Failed to parse WebSocket message:", event.data);
2052
+ }
2053
+ });
2054
+ ws.addEventListener("close", () => {
2055
+ closed = true;
2056
+ if (messageResolver) {
2057
+ messageResolver({ value: void 0, done: true });
2058
+ messageResolver = null;
2059
+ }
2060
+ });
2061
+ ws.addEventListener("error", () => {
2062
+ closeError = new Error("WebSocket error");
2063
+ closed = true;
2064
+ if (messageResolver) {
2065
+ messageResolver({ value: void 0, done: true });
2066
+ messageResolver = null;
2067
+ }
2068
+ });
2069
+ const readable = new ReadableStream({
2070
+ async pull(controller) {
2071
+ if (messageQueue.length > 0) {
2072
+ controller.enqueue(messageQueue.shift());
2073
+ return;
2074
+ }
2075
+ if (closed) {
2076
+ if (closeError) {
2077
+ controller.error(closeError);
2078
+ } else {
2079
+ controller.close();
2080
+ }
2081
+ return;
2082
+ }
2083
+ await new Promise((resolve) => {
2084
+ messageResolver = resolve;
2085
+ }).then((result) => {
2086
+ if (result.done) {
2087
+ controller.close();
2088
+ } else {
2089
+ controller.enqueue(result.value);
2090
+ }
2091
+ });
2092
+ }
2093
+ });
2094
+ const writable = new WritableStream({
2095
+ async write(message) {
2096
+ if (ws.readyState === WebSocket.CONNECTING) {
2097
+ await new Promise((resolve, reject) => {
2098
+ const onOpen = () => {
2099
+ ws.removeEventListener("error", onError);
2100
+ resolve();
2101
+ };
2102
+ const onError = () => {
2103
+ ws.removeEventListener("open", onOpen);
2104
+ reject(new Error("WebSocket failed to connect"));
2105
+ };
2106
+ ws.addEventListener("open", onOpen, { once: true });
2107
+ ws.addEventListener("error", onError, { once: true });
2108
+ });
2109
+ }
2110
+ if (ws.readyState !== WebSocket.OPEN) {
2111
+ throw new Error("WebSocket is not open");
2112
+ }
2113
+ ws.send(JSON.stringify(message));
2114
+ },
2115
+ close() {
2116
+ ws.close();
2117
+ },
2118
+ abort() {
2119
+ ws.close();
2120
+ }
2121
+ });
2122
+ return { readable, writable };
2123
+ }
2124
+ function waitForOpen(ws, timeoutMs = 1e4) {
2125
+ return new Promise((resolve, reject) => {
2126
+ if (ws.readyState === WebSocket.OPEN) {
2127
+ resolve();
2128
+ return;
2129
+ }
2130
+ const timeout = setTimeout(() => {
2131
+ ws.close();
2132
+ reject(new Error(`WebSocket connection timeout after ${timeoutMs}ms`));
2133
+ }, timeoutMs);
2134
+ const onOpen = () => {
2135
+ clearTimeout(timeout);
2136
+ ws.removeEventListener("error", onError);
2137
+ resolve();
2138
+ };
2139
+ const onError = () => {
2140
+ clearTimeout(timeout);
2141
+ ws.removeEventListener("open", onOpen);
2142
+ reject(new Error("WebSocket connection failed"));
2143
+ };
2144
+ ws.addEventListener("open", onOpen, { once: true });
2145
+ ws.addEventListener("error", onError, { once: true });
2146
+ });
2147
+ }
2148
+ function createStreamPair() {
2149
+ const clientToServer = [];
2150
+ const serverToClient = [];
2151
+ let clientToServerResolver = null;
2152
+ let serverToClientResolver = null;
2153
+ let clientToServerClosed = false;
2154
+ let serverToClientClosed = false;
2155
+ function createReadable(queue, _getResolver, setResolver, isClosed) {
2156
+ return new ReadableStream({
2157
+ async pull(controller) {
2158
+ if (queue.length > 0) {
2159
+ controller.enqueue(queue.shift());
2160
+ return;
2161
+ }
2162
+ if (isClosed()) {
2163
+ controller.close();
2164
+ return;
2165
+ }
2166
+ const message = await new Promise((resolve) => {
2167
+ setResolver((msg) => {
2168
+ setResolver(null);
2169
+ resolve(msg);
2170
+ });
2171
+ });
2172
+ if (message === null) {
2173
+ controller.close();
2174
+ } else {
2175
+ controller.enqueue(message);
2176
+ }
2177
+ }
2178
+ });
2179
+ }
2180
+ function createWritable(queue, getResolver, setClosed) {
2181
+ return new WritableStream({
2182
+ write(message) {
2183
+ const resolver = getResolver();
2184
+ if (resolver) {
2185
+ resolver(message);
2186
+ } else {
2187
+ queue.push(message);
2188
+ }
2189
+ },
2190
+ close() {
2191
+ setClosed();
2192
+ const resolver = getResolver();
2193
+ if (resolver) {
2194
+ resolver(null);
2195
+ }
2196
+ }
2197
+ });
2198
+ }
2199
+ const clientStream = {
2200
+ // Client writes to server
2201
+ writable: createWritable(
2202
+ clientToServer,
2203
+ () => clientToServerResolver,
2204
+ () => {
2205
+ clientToServerClosed = true;
2206
+ }
2207
+ ),
2208
+ // Client reads from server
2209
+ readable: createReadable(
2210
+ serverToClient,
2211
+ () => serverToClientResolver,
2212
+ (r) => {
2213
+ serverToClientResolver = r;
2214
+ },
2215
+ () => serverToClientClosed
2216
+ )
2217
+ };
2218
+ const serverStream = {
2219
+ // Server writes to client
2220
+ writable: createWritable(
2221
+ serverToClient,
2222
+ () => serverToClientResolver,
2223
+ () => {
2224
+ serverToClientClosed = true;
2225
+ }
2226
+ ),
2227
+ // Server reads from client
2228
+ readable: createReadable(
2229
+ clientToServer,
2230
+ () => clientToServerResolver,
2231
+ (r) => {
2232
+ clientToServerResolver = r;
2233
+ },
2234
+ () => clientToServerClosed
2235
+ )
2236
+ };
2237
+ return [clientStream, serverStream];
2238
+ }
2239
+
2035
2240
  // src/subscription/index.ts
2036
2241
  var Subscription = class {
2037
2242
  id;
@@ -2348,7 +2553,7 @@ function createSubscription(id, unsubscribe, options, sendAck) {
2348
2553
  }
2349
2554
 
2350
2555
  // src/connection/client.ts
2351
- var ClientConnection = class {
2556
+ var ClientConnection = class _ClientConnection {
2352
2557
  #connection;
2353
2558
  #subscriptions = /* @__PURE__ */ new Map();
2354
2559
  #subscriptionStates = /* @__PURE__ */ new Map();
@@ -2372,6 +2577,59 @@ var ClientConnection = class {
2372
2577
  }
2373
2578
  }
2374
2579
  // ===========================================================================
2580
+ // Static Factory Methods
2581
+ // ===========================================================================
2582
+ /**
2583
+ * Connect to a MAP server via WebSocket URL.
2584
+ *
2585
+ * Handles:
2586
+ * - WebSocket creation and connection
2587
+ * - Stream wrapping
2588
+ * - Auto-configuration of createStream for reconnection
2589
+ * - Initial MAP protocol connect handshake
2590
+ *
2591
+ * @param url - WebSocket URL (ws:// or wss://)
2592
+ * @param options - Connection options
2593
+ * @returns Connected ClientConnection instance
2594
+ *
2595
+ * @example
2596
+ * ```typescript
2597
+ * const client = await ClientConnection.connect('ws://localhost:8080', {
2598
+ * name: 'MyClient',
2599
+ * reconnection: true
2600
+ * });
2601
+ *
2602
+ * // Already connected, ready to use
2603
+ * const agents = await client.listAgents();
2604
+ * ```
2605
+ */
2606
+ static async connect(url, options) {
2607
+ const parsedUrl = new URL(url);
2608
+ if (!["ws:", "wss:"].includes(parsedUrl.protocol)) {
2609
+ throw new Error(
2610
+ `Unsupported protocol: ${parsedUrl.protocol}. Use ws: or wss:`
2611
+ );
2612
+ }
2613
+ const timeout = options?.connectTimeout ?? 1e4;
2614
+ const ws = new WebSocket(url);
2615
+ await waitForOpen(ws, timeout);
2616
+ const stream = websocketStream(ws);
2617
+ const createStream = async () => {
2618
+ const newWs = new WebSocket(url);
2619
+ await waitForOpen(newWs, timeout);
2620
+ return websocketStream(newWs);
2621
+ };
2622
+ const reconnection = options?.reconnection === true ? { enabled: true } : typeof options?.reconnection === "object" ? options.reconnection : void 0;
2623
+ const client = new _ClientConnection(stream, {
2624
+ name: options?.name,
2625
+ capabilities: options?.capabilities,
2626
+ createStream,
2627
+ reconnection
2628
+ });
2629
+ await client.connect({ auth: options?.auth });
2630
+ return client;
2631
+ }
2632
+ // ===========================================================================
2375
2633
  // Connection Lifecycle
2376
2634
  // ===========================================================================
2377
2635
  /**
@@ -2384,6 +2642,7 @@ var ClientConnection = class {
2384
2642
  name: this.#options.name,
2385
2643
  capabilities: this.#options.capabilities,
2386
2644
  sessionId: options?.sessionId,
2645
+ resumeToken: options?.resumeToken,
2387
2646
  auth: options?.auth
2388
2647
  };
2389
2648
  const result = await this.#connection.sendRequest(CORE_METHODS.CONNECT, params);
@@ -2396,14 +2655,18 @@ var ClientConnection = class {
2396
2655
  }
2397
2656
  /**
2398
2657
  * Disconnect from the MAP system
2658
+ * @param reason - Optional reason for disconnecting
2659
+ * @returns Resume token that can be used to resume this session later
2399
2660
  */
2400
2661
  async disconnect(reason) {
2401
- if (!this.#connected) return;
2662
+ if (!this.#connected) return void 0;
2663
+ let resumeToken;
2402
2664
  try {
2403
- await this.#connection.sendRequest(
2665
+ const result = await this.#connection.sendRequest(
2404
2666
  CORE_METHODS.DISCONNECT,
2405
2667
  reason ? { reason } : void 0
2406
2668
  );
2669
+ resumeToken = result.resumeToken;
2407
2670
  } finally {
2408
2671
  for (const subscription of this.#subscriptions.values()) {
2409
2672
  subscription._close();
@@ -2412,6 +2675,7 @@ var ClientConnection = class {
2412
2675
  await this.#connection.close();
2413
2676
  this.#connected = false;
2414
2677
  }
2678
+ return resumeToken;
2415
2679
  }
2416
2680
  /**
2417
2681
  * Whether the client is connected
@@ -2946,99 +3210,6 @@ var ClientConnection = class {
2946
3210
  }
2947
3211
  };
2948
3212
 
2949
- // src/stream/index.ts
2950
- function createStreamPair() {
2951
- const clientToServer = [];
2952
- const serverToClient = [];
2953
- let clientToServerResolver = null;
2954
- let serverToClientResolver = null;
2955
- let clientToServerClosed = false;
2956
- let serverToClientClosed = false;
2957
- function createReadable(queue, _getResolver, setResolver, isClosed) {
2958
- return new ReadableStream({
2959
- async pull(controller) {
2960
- if (queue.length > 0) {
2961
- controller.enqueue(queue.shift());
2962
- return;
2963
- }
2964
- if (isClosed()) {
2965
- controller.close();
2966
- return;
2967
- }
2968
- const message = await new Promise((resolve) => {
2969
- setResolver((msg) => {
2970
- setResolver(null);
2971
- resolve(msg);
2972
- });
2973
- });
2974
- if (message === null) {
2975
- controller.close();
2976
- } else {
2977
- controller.enqueue(message);
2978
- }
2979
- }
2980
- });
2981
- }
2982
- function createWritable(queue, getResolver, setClosed) {
2983
- return new WritableStream({
2984
- write(message) {
2985
- const resolver = getResolver();
2986
- if (resolver) {
2987
- resolver(message);
2988
- } else {
2989
- queue.push(message);
2990
- }
2991
- },
2992
- close() {
2993
- setClosed();
2994
- const resolver = getResolver();
2995
- if (resolver) {
2996
- resolver(null);
2997
- }
2998
- }
2999
- });
3000
- }
3001
- const clientStream = {
3002
- // Client writes to server
3003
- writable: createWritable(
3004
- clientToServer,
3005
- () => clientToServerResolver,
3006
- () => {
3007
- clientToServerClosed = true;
3008
- }
3009
- ),
3010
- // Client reads from server
3011
- readable: createReadable(
3012
- serverToClient,
3013
- () => serverToClientResolver,
3014
- (r) => {
3015
- serverToClientResolver = r;
3016
- },
3017
- () => serverToClientClosed
3018
- )
3019
- };
3020
- const serverStream = {
3021
- // Server writes to client
3022
- writable: createWritable(
3023
- serverToClient,
3024
- () => serverToClientResolver,
3025
- () => {
3026
- serverToClientClosed = true;
3027
- }
3028
- ),
3029
- // Server reads from client
3030
- readable: createReadable(
3031
- clientToServer,
3032
- () => clientToServerResolver,
3033
- (r) => {
3034
- clientToServerResolver = r;
3035
- },
3036
- () => clientToServerClosed
3037
- )
3038
- };
3039
- return [clientStream, serverStream];
3040
- }
3041
-
3042
3213
  // src/testing/client.ts
3043
3214
  var TestClient = class _TestClient {
3044
3215
  #connection;
@@ -3231,7 +3402,7 @@ var TestClient = class _TestClient {
3231
3402
  };
3232
3403
 
3233
3404
  // src/connection/agent.ts
3234
- var AgentConnection = class {
3405
+ var AgentConnection = class _AgentConnection {
3235
3406
  #connection;
3236
3407
  #subscriptions = /* @__PURE__ */ new Map();
3237
3408
  #options;
@@ -3258,6 +3429,66 @@ var AgentConnection = class {
3258
3429
  }
3259
3430
  }
3260
3431
  // ===========================================================================
3432
+ // Static Factory Methods
3433
+ // ===========================================================================
3434
+ /**
3435
+ * Connect and register an agent via WebSocket URL.
3436
+ *
3437
+ * Handles:
3438
+ * - WebSocket creation and connection
3439
+ * - Stream wrapping
3440
+ * - Auto-configuration of createStream for reconnection
3441
+ * - Initial MAP protocol connect handshake
3442
+ * - Agent registration
3443
+ *
3444
+ * @param url - WebSocket URL (ws:// or wss://)
3445
+ * @param options - Connection and agent options
3446
+ * @returns Connected and registered AgentConnection instance
3447
+ *
3448
+ * @example
3449
+ * ```typescript
3450
+ * const agent = await AgentConnection.connect('ws://localhost:8080', {
3451
+ * name: 'Worker',
3452
+ * role: 'processor',
3453
+ * reconnection: true
3454
+ * });
3455
+ *
3456
+ * // Already registered, ready to work
3457
+ * agent.onMessage(handleMessage);
3458
+ * await agent.busy();
3459
+ * ```
3460
+ */
3461
+ static async connect(url, options) {
3462
+ const parsedUrl = new URL(url);
3463
+ if (!["ws:", "wss:"].includes(parsedUrl.protocol)) {
3464
+ throw new Error(
3465
+ `Unsupported protocol: ${parsedUrl.protocol}. Use ws: or wss:`
3466
+ );
3467
+ }
3468
+ const timeout = options?.connectTimeout ?? 1e4;
3469
+ const ws = new WebSocket(url);
3470
+ await waitForOpen(ws, timeout);
3471
+ const stream = websocketStream(ws);
3472
+ const createStream = async () => {
3473
+ const newWs = new WebSocket(url);
3474
+ await waitForOpen(newWs, timeout);
3475
+ return websocketStream(newWs);
3476
+ };
3477
+ const reconnection = options?.reconnection === true ? { enabled: true } : typeof options?.reconnection === "object" ? options.reconnection : void 0;
3478
+ const agent = new _AgentConnection(stream, {
3479
+ name: options?.name,
3480
+ role: options?.role,
3481
+ capabilities: options?.capabilities,
3482
+ visibility: options?.visibility,
3483
+ parent: options?.parent,
3484
+ scopes: options?.scopes,
3485
+ createStream,
3486
+ reconnection
3487
+ });
3488
+ await agent.connect({ auth: options?.auth });
3489
+ return agent;
3490
+ }
3491
+ // ===========================================================================
3261
3492
  // Connection Lifecycle
3262
3493
  // ===========================================================================
3263
3494
  /**
@@ -3270,6 +3501,7 @@ var AgentConnection = class {
3270
3501
  participantId: options?.agentId,
3271
3502
  name: this.#options.name,
3272
3503
  capabilities: this.#options.capabilities,
3504
+ resumeToken: options?.resumeToken,
3273
3505
  auth: options?.auth
3274
3506
  };
3275
3507
  const connectResult = await this.#connection.sendRequest(CORE_METHODS.CONNECT, connectParams);
@@ -3294,9 +3526,12 @@ var AgentConnection = class {
3294
3526
  }
3295
3527
  /**
3296
3528
  * Disconnect from the MAP system
3529
+ * @param reason - Optional reason for disconnecting
3530
+ * @returns Resume token that can be used to resume this session later
3297
3531
  */
3298
3532
  async disconnect(reason) {
3299
- if (!this.#connected) return;
3533
+ if (!this.#connected) return void 0;
3534
+ let resumeToken;
3300
3535
  try {
3301
3536
  if (this.#agentId) {
3302
3537
  await this.#connection.sendRequest(LIFECYCLE_METHODS.AGENTS_UNREGISTER, {
@@ -3304,10 +3539,11 @@ var AgentConnection = class {
3304
3539
  reason
3305
3540
  });
3306
3541
  }
3307
- await this.#connection.sendRequest(
3542
+ const result = await this.#connection.sendRequest(
3308
3543
  CORE_METHODS.DISCONNECT,
3309
3544
  reason ? { reason } : void 0
3310
3545
  );
3546
+ resumeToken = result.resumeToken;
3311
3547
  } finally {
3312
3548
  for (const subscription of this.#subscriptions.values()) {
3313
3549
  subscription._close();
@@ -3316,6 +3552,7 @@ var AgentConnection = class {
3316
3552
  await this.#connection.close();
3317
3553
  this.#connected = false;
3318
3554
  }
3555
+ return resumeToken;
3319
3556
  }
3320
3557
  /**
3321
3558
  * Whether the agent is connected