@blaxel/core 0.2.25-dev.175 → 0.2.25-preview.56
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/mcp/client.d.ts +1 -8
- package/dist/mcp/client.js +13 -35
- package/dist/sandbox/action.js +2 -4
- package/dist/sandbox/sandbox.js +14 -42
- package/dist/tools/mcpTool.js +4 -19
- package/package.json +1 -1
package/dist/mcp/client.d.ts
CHANGED
|
@@ -9,17 +9,10 @@ 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;
|
|
14
12
|
onclose?: () => void;
|
|
15
13
|
onerror?: (error: Error) => void;
|
|
16
14
|
onmessage?: (message: JSONRPCMessage) => void;
|
|
17
|
-
constructor(url: string, headers?: Record<string, string
|
|
18
|
-
retry: {
|
|
19
|
-
max?: number;
|
|
20
|
-
delay?: number;
|
|
21
|
-
};
|
|
22
|
-
});
|
|
15
|
+
constructor(url: string, headers?: Record<string, string>);
|
|
23
16
|
start(): Promise<void>;
|
|
24
17
|
private _connect;
|
|
25
18
|
get isConnected(): boolean;
|
package/dist/mcp/client.js
CHANGED
|
@@ -21,6 +21,8 @@ if (!isBrowser) {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
//const SUBPROTOCOL = "mcp";
|
|
24
|
+
const MAX_RETRIES = 3;
|
|
25
|
+
const RETRY_DELAY_MS = 1000;
|
|
24
26
|
// Helper function to wait
|
|
25
27
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
26
28
|
/**
|
|
@@ -32,15 +34,11 @@ class BlaxelMcpClientTransport {
|
|
|
32
34
|
_url;
|
|
33
35
|
_headers;
|
|
34
36
|
_isBrowser;
|
|
35
|
-
_retry_max;
|
|
36
|
-
_retry_delay;
|
|
37
37
|
onclose;
|
|
38
38
|
onerror;
|
|
39
39
|
onmessage;
|
|
40
|
-
constructor(url, headers
|
|
40
|
+
constructor(url, headers) {
|
|
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;
|
|
44
42
|
this._headers = headers ?? {};
|
|
45
43
|
this._isBrowser = isBrowser;
|
|
46
44
|
}
|
|
@@ -49,22 +47,21 @@ class BlaxelMcpClientTransport {
|
|
|
49
47
|
throw new Error("Blaxel already started! If using Client class, note that connect() calls start() automatically.");
|
|
50
48
|
}
|
|
51
49
|
let attempts = 0;
|
|
52
|
-
|
|
53
|
-
while (attempts < maxAttempts) {
|
|
50
|
+
while (attempts < MAX_RETRIES) {
|
|
54
51
|
try {
|
|
55
52
|
await this._connect();
|
|
56
53
|
return;
|
|
57
54
|
}
|
|
58
55
|
catch (error) {
|
|
59
|
-
attempts++;
|
|
60
56
|
if (error instanceof Error) {
|
|
61
57
|
logger_js_1.logger.warn(error.stack ?? error.message);
|
|
62
58
|
}
|
|
63
|
-
|
|
59
|
+
attempts++;
|
|
60
|
+
if (attempts === MAX_RETRIES) {
|
|
64
61
|
throw error;
|
|
65
62
|
}
|
|
66
|
-
logger_js_1.logger.debug(`WebSocket connection attempt ${attempts} failed, retrying in ${
|
|
67
|
-
await delay(
|
|
63
|
+
logger_js_1.logger.debug(`WebSocket connection attempt ${attempts} failed, retrying in ${RETRY_DELAY_MS}ms...`);
|
|
64
|
+
await delay(RETRY_DELAY_MS);
|
|
68
65
|
}
|
|
69
66
|
}
|
|
70
67
|
}
|
|
@@ -89,25 +86,7 @@ class BlaxelMcpClientTransport {
|
|
|
89
86
|
});
|
|
90
87
|
}
|
|
91
88
|
this._socket.onerror = (event) => {
|
|
92
|
-
|
|
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);
|
|
89
|
+
console.error(event);
|
|
111
90
|
const error = this._isBrowser
|
|
112
91
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
113
92
|
? new Error(`WebSocket error: ${event.message}`)
|
|
@@ -195,8 +174,7 @@ class BlaxelMcpClientTransport {
|
|
|
195
174
|
}
|
|
196
175
|
async send(message) {
|
|
197
176
|
let attempts = 0;
|
|
198
|
-
|
|
199
|
-
while (attempts < maxAttempts) {
|
|
177
|
+
while (attempts < MAX_RETRIES) {
|
|
200
178
|
try {
|
|
201
179
|
if (!this._socket || !this.isConnected) {
|
|
202
180
|
if (!this._socket) {
|
|
@@ -235,11 +213,11 @@ class BlaxelMcpClientTransport {
|
|
|
235
213
|
}
|
|
236
214
|
catch (error) {
|
|
237
215
|
attempts++;
|
|
238
|
-
if (attempts
|
|
216
|
+
if (attempts === MAX_RETRIES) {
|
|
239
217
|
throw error;
|
|
240
218
|
}
|
|
241
|
-
logger_js_1.logger.warn(`WebSocket send attempt ${attempts} failed, retrying in ${
|
|
242
|
-
await delay(
|
|
219
|
+
logger_js_1.logger.warn(`WebSocket send attempt ${attempts} failed, retrying in ${RETRY_DELAY_MS}ms...`);
|
|
220
|
+
await delay(RETRY_DELAY_MS);
|
|
243
221
|
}
|
|
244
222
|
}
|
|
245
223
|
}
|
package/dist/sandbox/action.js
CHANGED
|
@@ -66,10 +66,8 @@ class SandboxAction {
|
|
|
66
66
|
return (0, internal_js_1.getForcedUrl)('sandbox', this.name);
|
|
67
67
|
}
|
|
68
68
|
get url() {
|
|
69
|
-
if (this.forcedUrl)
|
|
70
|
-
|
|
71
|
-
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
72
|
-
}
|
|
69
|
+
if (this.forcedUrl)
|
|
70
|
+
return this.forcedUrl.toString();
|
|
73
71
|
// Uncomment and use this when agent and mcp are available in mk3
|
|
74
72
|
// Update all requests made in this package to use fallbackUrl when internalUrl is not working
|
|
75
73
|
// if (settings.runInternalHostname) return this.internalUrl;
|
package/dist/sandbox/sandbox.js
CHANGED
|
@@ -37,40 +37,9 @@ class SandboxInstance {
|
|
|
37
37
|
get spec() {
|
|
38
38
|
return this.sandbox.spec;
|
|
39
39
|
}
|
|
40
|
+
/* eslint-disable */
|
|
40
41
|
async wait({ maxWait = 60000, interval = 1000 } = {}) {
|
|
41
|
-
|
|
42
|
-
while (this.sandbox.status !== "DEPLOYED") {
|
|
43
|
-
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
44
|
-
try {
|
|
45
|
-
const { data } = await (0, index_js_1.getSandbox)({
|
|
46
|
-
path: {
|
|
47
|
-
sandboxName: this.sandbox.metadata?.name ?? "",
|
|
48
|
-
},
|
|
49
|
-
throwOnError: true,
|
|
50
|
-
});
|
|
51
|
-
logger_js_1.logger.debug(`Waiting for sandbox to be deployed, status: ${data.status}`);
|
|
52
|
-
this.sandbox = data;
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
logger_js_1.logger.error("Could not retrieve sandbox", e);
|
|
56
|
-
}
|
|
57
|
-
if (this.sandbox.status === "FAILED") {
|
|
58
|
-
throw new Error("Sandbox failed to deploy");
|
|
59
|
-
}
|
|
60
|
-
if (Date.now() - startTime > maxWait) {
|
|
61
|
-
throw new Error("Sandbox did not deploy in time");
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (this.sandbox.status === "DEPLOYED") {
|
|
65
|
-
try {
|
|
66
|
-
// This is a hack for sometime receiving a 502,
|
|
67
|
-
// need to remove this once we have a better way to handle this
|
|
68
|
-
await this.fs.ls("/");
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
// pass
|
|
72
|
-
}
|
|
73
|
-
}
|
|
42
|
+
logger_js_1.logger.warn("⚠️ Warning: sandbox.wait() is deprecated. You don't need to wait for the sandbox to be deployed anymore.");
|
|
74
43
|
return this;
|
|
75
44
|
}
|
|
76
45
|
static async create(sandbox) {
|
|
@@ -119,7 +88,10 @@ class SandboxInstance {
|
|
|
119
88
|
body: sandbox,
|
|
120
89
|
throwOnError: true,
|
|
121
90
|
});
|
|
122
|
-
|
|
91
|
+
const instance = new SandboxInstance(data);
|
|
92
|
+
// TODO remove this part once we have a better way to handle this
|
|
93
|
+
// await instance.fs.ls('/')
|
|
94
|
+
return instance;
|
|
123
95
|
}
|
|
124
96
|
static async get(sandboxName) {
|
|
125
97
|
const { data } = await (0, index_js_1.getSandbox)({
|
|
@@ -145,16 +117,16 @@ class SandboxInstance {
|
|
|
145
117
|
}
|
|
146
118
|
static async createIfNotExists(sandbox) {
|
|
147
119
|
try {
|
|
148
|
-
|
|
149
|
-
if (!name) {
|
|
150
|
-
throw new Error("Sandbox name is required");
|
|
151
|
-
}
|
|
152
|
-
const sandboxInstance = await SandboxInstance.get(name);
|
|
153
|
-
return sandboxInstance;
|
|
120
|
+
return await SandboxInstance.create(sandbox);
|
|
154
121
|
}
|
|
155
122
|
catch (e) {
|
|
156
|
-
if (typeof e === "object" && e !== null && "code" in e && e.code ===
|
|
157
|
-
|
|
123
|
+
if (typeof e === "object" && e !== null && "code" in e && (e.code === 409 || e.code === 'SANDBOX_ALREADY_EXISTS')) {
|
|
124
|
+
const name = 'name' in sandbox ? sandbox.name : sandbox.metadata?.name;
|
|
125
|
+
if (!name) {
|
|
126
|
+
throw new Error("Sandbox name is required");
|
|
127
|
+
}
|
|
128
|
+
const sandboxInstance = await SandboxInstance.get(name);
|
|
129
|
+
return sandboxInstance;
|
|
158
130
|
}
|
|
159
131
|
throw e;
|
|
160
132
|
}
|
package/dist/tools/mcpTool.js
CHANGED
|
@@ -74,18 +74,13 @@ 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);
|
|
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(
|
|
84
|
-
error: err.message,
|
|
85
|
-
stack: err.stack,
|
|
86
|
-
mcpName: this.name,
|
|
87
|
-
url: this.url
|
|
88
|
-
});
|
|
83
|
+
logger_js_1.logger.error(err.stack);
|
|
89
84
|
}
|
|
90
85
|
if (!this.fallbackUrl) {
|
|
91
86
|
throw err;
|
|
@@ -112,11 +107,7 @@ class McpTool {
|
|
|
112
107
|
delete this.startPromise;
|
|
113
108
|
this.client.close().catch((err) => {
|
|
114
109
|
if (err instanceof Error) {
|
|
115
|
-
logger_js_1.logger.error(
|
|
116
|
-
error: err.message,
|
|
117
|
-
stack: err.stack,
|
|
118
|
-
mcpName: this.name
|
|
119
|
-
});
|
|
110
|
+
logger_js_1.logger.error(err.stack);
|
|
120
111
|
}
|
|
121
112
|
});
|
|
122
113
|
}, now ? 0 : this.ms);
|
|
@@ -187,13 +178,7 @@ class McpTool {
|
|
|
187
178
|
}
|
|
188
179
|
catch (err) {
|
|
189
180
|
if (err instanceof Error) {
|
|
190
|
-
logger_js_1.logger.error(
|
|
191
|
-
error: err.message,
|
|
192
|
-
stack: err.stack,
|
|
193
|
-
mcpName: this.name,
|
|
194
|
-
toolName,
|
|
195
|
-
args: JSON.stringify(args)
|
|
196
|
-
});
|
|
181
|
+
logger_js_1.logger.error(err.stack);
|
|
197
182
|
}
|
|
198
183
|
throw err;
|
|
199
184
|
}
|