@blaxel/core 0.2.25 → 0.2.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.
@@ -9,10 +9,17 @@ export declare class BlaxelMcpClientTransport implements Transport {
9
9
  private _url;
10
10
  private _headers;
11
11
  private _isBrowser;
12
+ private _retry_max;
13
+ private _retry_delay;
12
14
  onclose?: () => void;
13
15
  onerror?: (error: Error) => void;
14
16
  onmessage?: (message: JSONRPCMessage) => void;
15
- constructor(url: string, headers?: Record<string, string>);
17
+ constructor(url: string, headers?: Record<string, string>, options?: {
18
+ retry: {
19
+ max?: number;
20
+ delay?: number;
21
+ };
22
+ });
16
23
  start(): Promise<void>;
17
24
  private _connect;
18
25
  get isConnected(): boolean;
@@ -21,8 +21,6 @@ if (!isBrowser) {
21
21
  }
22
22
  }
23
23
  //const SUBPROTOCOL = "mcp";
24
- const MAX_RETRIES = 3;
25
- const RETRY_DELAY_MS = 1000;
26
24
  // Helper function to wait
27
25
  const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
28
26
  /**
@@ -34,11 +32,15 @@ class BlaxelMcpClientTransport {
34
32
  _url;
35
33
  _headers;
36
34
  _isBrowser;
35
+ _retry_max;
36
+ _retry_delay;
37
37
  onclose;
38
38
  onerror;
39
39
  onmessage;
40
- constructor(url, headers) {
40
+ constructor(url, headers, options) {
41
41
  this._url = new URL(url.replace("http", "ws"));
42
+ this._retry_max = options?.retry?.max ?? 3;
43
+ this._retry_delay = options?.retry?.delay ?? 1000;
42
44
  this._headers = headers ?? {};
43
45
  this._isBrowser = isBrowser;
44
46
  }
@@ -47,21 +49,22 @@ class BlaxelMcpClientTransport {
47
49
  throw new Error("Blaxel already started! If using Client class, note that connect() calls start() automatically.");
48
50
  }
49
51
  let attempts = 0;
50
- while (attempts < MAX_RETRIES) {
52
+ const maxAttempts = Math.max(1, this._retry_max + 1); // Ensure at least 1 attempt
53
+ while (attempts < maxAttempts) {
51
54
  try {
52
55
  await this._connect();
53
56
  return;
54
57
  }
55
58
  catch (error) {
59
+ attempts++;
56
60
  if (error instanceof Error) {
57
61
  logger_js_1.logger.warn(error.stack ?? error.message);
58
62
  }
59
- attempts++;
60
- if (attempts === MAX_RETRIES) {
63
+ if (attempts >= maxAttempts) {
61
64
  throw error;
62
65
  }
63
- logger_js_1.logger.debug(`WebSocket connection attempt ${attempts} failed, retrying in ${RETRY_DELAY_MS}ms...`);
64
- await delay(RETRY_DELAY_MS);
66
+ logger_js_1.logger.debug(`WebSocket connection attempt ${attempts} failed, retrying in ${this._retry_delay}ms...`);
67
+ await delay(this._retry_delay);
65
68
  }
66
69
  }
67
70
  }
@@ -86,7 +89,25 @@ class BlaxelMcpClientTransport {
86
89
  });
87
90
  }
88
91
  this._socket.onerror = (event) => {
89
- console.error(event);
92
+ // Log websocket error with meaningful information instead of raw event
93
+ const errorInfo = {
94
+ type: 'WebSocket Error',
95
+ url: this._url.toString(),
96
+ readyState: this._socket?.readyState,
97
+ browser: this._isBrowser,
98
+ // Extract any available error details from the event
99
+ eventType: event && typeof event === 'object' && 'type' in event
100
+ ? String(event.type)
101
+ : 'unknown',
102
+ // Browser events might have different properties than Node.js
103
+ message: this._isBrowser && event && typeof event === 'object' && 'message' in event
104
+ ? String(event.message)
105
+ : undefined,
106
+ error: !this._isBrowser && event && typeof event === 'object' && 'error' in event
107
+ ? String(event.error)
108
+ : undefined
109
+ };
110
+ logger_js_1.logger.error('WebSocket connection error', errorInfo);
90
111
  const error = this._isBrowser
91
112
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
92
113
  ? new Error(`WebSocket error: ${event.message}`)
@@ -174,7 +195,8 @@ class BlaxelMcpClientTransport {
174
195
  }
175
196
  async send(message) {
176
197
  let attempts = 0;
177
- while (attempts < MAX_RETRIES) {
198
+ const maxAttempts = Math.max(1, this._retry_max + 1); // Ensure at least 1 attempt
199
+ while (attempts < maxAttempts) {
178
200
  try {
179
201
  if (!this._socket || !this.isConnected) {
180
202
  if (!this._socket) {
@@ -213,11 +235,11 @@ class BlaxelMcpClientTransport {
213
235
  }
214
236
  catch (error) {
215
237
  attempts++;
216
- if (attempts === MAX_RETRIES) {
238
+ if (attempts >= maxAttempts) {
217
239
  throw error;
218
240
  }
219
- logger_js_1.logger.warn(`WebSocket send attempt ${attempts} failed, retrying in ${RETRY_DELAY_MS}ms...`);
220
- await delay(RETRY_DELAY_MS);
241
+ logger_js_1.logger.warn(`WebSocket send attempt ${attempts} failed, retrying in ${this._retry_delay}ms...`);
242
+ await delay(this._retry_delay);
221
243
  }
222
244
  }
223
245
  }
@@ -74,13 +74,18 @@ class McpTool {
74
74
  await (0, index_js_2.authenticate)();
75
75
  try {
76
76
  logger_js_1.logger.debug(`MCP:${this.name}:Connecting::${this.url.toString()}`);
77
- this.transport = new client_js_1.BlaxelMcpClientTransport(this.url.toString(), settings_js_1.settings.headers);
77
+ this.transport = new client_js_1.BlaxelMcpClientTransport(this.url.toString(), settings_js_1.settings.headers, { retry: { max: 0 } });
78
78
  await this.client.connect(this.transport);
79
79
  logger_js_1.logger.debug(`MCP:${this.name}:Connected`);
80
80
  }
81
81
  catch (err) {
82
82
  if (err instanceof Error) {
83
- logger_js_1.logger.error(err.stack);
83
+ logger_js_1.logger.error(`MCP ${this.name} connection failed: ${err.message}`, {
84
+ error: err.message,
85
+ stack: err.stack,
86
+ mcpName: this.name,
87
+ url: this.url
88
+ });
84
89
  }
85
90
  if (!this.fallbackUrl) {
86
91
  throw err;
@@ -107,7 +112,11 @@ class McpTool {
107
112
  delete this.startPromise;
108
113
  this.client.close().catch((err) => {
109
114
  if (err instanceof Error) {
110
- logger_js_1.logger.error(err.stack);
115
+ logger_js_1.logger.error(`MCP ${this.name} close failed: ${err.message}`, {
116
+ error: err.message,
117
+ stack: err.stack,
118
+ mcpName: this.name
119
+ });
111
120
  }
112
121
  });
113
122
  }, now ? 0 : this.ms);
@@ -178,7 +187,13 @@ class McpTool {
178
187
  }
179
188
  catch (err) {
180
189
  if (err instanceof Error) {
181
- logger_js_1.logger.error(err.stack);
190
+ logger_js_1.logger.error(`MCP tool call failed: ${err.message}`, {
191
+ error: err.message,
192
+ stack: err.stack,
193
+ mcpName: this.name,
194
+ toolName,
195
+ args: JSON.stringify(args)
196
+ });
182
197
  }
183
198
  throw err;
184
199
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaxel/core",
3
- "version": "0.2.25",
3
+ "version": "0.2.26",
4
4
  "description": "Blaxel Core SDK for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "Blaxel, INC (https://blaxel.ai)",