@blaxel/core 0.2.36-dev.185 → 0.2.36-dev.190

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.
Files changed (172) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -0
  2. package/dist/{common → cjs/common}/settings.js +2 -2
  3. package/dist/{tools → cjs/types/tools}/index.d.ts +1 -0
  4. package/dist/esm/.tsbuildinfo +1 -0
  5. package/dist/esm/agents/index.js +104 -0
  6. package/dist/esm/authentication/apikey.js +20 -0
  7. package/dist/esm/authentication/clientcredentials.js +81 -0
  8. package/dist/esm/authentication/credentials.js +13 -0
  9. package/dist/esm/authentication/deviceMode.js +66 -0
  10. package/dist/esm/authentication/index.js +56 -0
  11. package/dist/esm/authentication/types.js +1 -0
  12. package/dist/esm/cache/index.js +20 -0
  13. package/dist/esm/client/authentication.js +11 -0
  14. package/dist/esm/client/client.gen.js +5 -0
  15. package/dist/esm/client/client.js +1 -0
  16. package/dist/esm/client/index.js +3 -0
  17. package/dist/esm/client/interceptors.js +14 -0
  18. package/dist/esm/client/sdk.gen.js +1649 -0
  19. package/dist/esm/client/types.gen.js +3 -0
  20. package/dist/esm/common/autoload.js +23 -0
  21. package/dist/esm/common/env.js +36 -0
  22. package/dist/esm/common/errors.js +14 -0
  23. package/dist/esm/common/internal.js +182 -0
  24. package/dist/esm/common/internal.test.js +37 -0
  25. package/dist/esm/common/logger.js +65 -0
  26. package/dist/esm/common/node.js +20 -0
  27. package/dist/esm/common/settings.js +167 -0
  28. package/dist/esm/index.browser.test.js +10 -0
  29. package/dist/esm/index.js +17 -0
  30. package/dist/esm/jobs/index.js +3 -0
  31. package/dist/esm/jobs/jobs.js +86 -0
  32. package/dist/esm/jobs/start.js +62 -0
  33. package/dist/esm/jobs/types.js +1 -0
  34. package/dist/esm/mcp/client.js +243 -0
  35. package/dist/esm/mcp/index.js +2 -0
  36. package/dist/esm/mcp/server.js +176 -0
  37. package/dist/esm/models/index.js +25 -0
  38. package/dist/esm/package.json +1 -0
  39. package/dist/esm/sandbox/action.js +79 -0
  40. package/dist/esm/sandbox/client/client.gen.js +3 -0
  41. package/dist/esm/sandbox/client/index.js +3 -0
  42. package/dist/esm/sandbox/client/sdk.gen.js +270 -0
  43. package/dist/esm/sandbox/client/types.gen.js +2 -0
  44. package/dist/esm/sandbox/filesystem/filesystem.js +272 -0
  45. package/dist/esm/sandbox/filesystem/index.js +2 -0
  46. package/dist/esm/sandbox/filesystem/types.js +1 -0
  47. package/dist/esm/sandbox/index.js +7 -0
  48. package/dist/esm/sandbox/network/index.js +1 -0
  49. package/dist/esm/sandbox/network/network.js +6 -0
  50. package/dist/esm/sandbox/preview.js +141 -0
  51. package/dist/esm/sandbox/process/index.js +1 -0
  52. package/dist/esm/sandbox/process/process.js +185 -0
  53. package/dist/esm/sandbox/sandbox.js +174 -0
  54. package/dist/esm/sandbox/session.js +119 -0
  55. package/dist/esm/sandbox/types.js +76 -0
  56. package/dist/esm/telemetry/telemetry.js +74 -0
  57. package/dist/esm/tools/index.js +44 -0
  58. package/dist/esm/tools/mcpTool.js +213 -0
  59. package/dist/esm/tools/types.js +1 -0
  60. package/dist/esm/tools/zodSchema.js +43 -0
  61. package/dist/esm/volume/index.js +109 -0
  62. package/package.json +17 -30
  63. /package/dist/{agents → cjs/agents}/index.js +0 -0
  64. /package/dist/{authentication → cjs/authentication}/apikey.js +0 -0
  65. /package/dist/{authentication → cjs/authentication}/clientcredentials.js +0 -0
  66. /package/dist/{authentication → cjs/authentication}/credentials.js +0 -0
  67. /package/dist/{authentication → cjs/authentication}/deviceMode.js +0 -0
  68. /package/dist/{authentication → cjs/authentication}/index.js +0 -0
  69. /package/dist/{authentication → cjs/authentication}/types.js +0 -0
  70. /package/dist/{cache → cjs/cache}/index.js +0 -0
  71. /package/dist/{client → cjs/client}/authentication.js +0 -0
  72. /package/dist/{client → cjs/client}/client.gen.js +0 -0
  73. /package/dist/{client → cjs/client}/client.js +0 -0
  74. /package/dist/{client → cjs/client}/index.js +0 -0
  75. /package/dist/{client → cjs/client}/interceptors.js +0 -0
  76. /package/dist/{client → cjs/client}/sdk.gen.js +0 -0
  77. /package/dist/{client → cjs/client}/types.gen.js +0 -0
  78. /package/dist/{common → cjs/common}/autoload.js +0 -0
  79. /package/dist/{common → cjs/common}/env.js +0 -0
  80. /package/dist/{common → cjs/common}/errors.js +0 -0
  81. /package/dist/{common → cjs/common}/internal.js +0 -0
  82. /package/dist/{common → cjs/common}/internal.test.js +0 -0
  83. /package/dist/{common → cjs/common}/logger.js +0 -0
  84. /package/dist/{common → cjs/common}/node.js +0 -0
  85. /package/dist/{index.browser.test.js → cjs/index.browser.test.js} +0 -0
  86. /package/dist/{index.js → cjs/index.js} +0 -0
  87. /package/dist/{jobs → cjs/jobs}/index.js +0 -0
  88. /package/dist/{jobs → cjs/jobs}/jobs.js +0 -0
  89. /package/dist/{jobs → cjs/jobs}/start.js +0 -0
  90. /package/dist/{jobs → cjs/jobs}/types.js +0 -0
  91. /package/dist/{mcp → cjs/mcp}/client.js +0 -0
  92. /package/dist/{mcp → cjs/mcp}/index.js +0 -0
  93. /package/dist/{mcp → cjs/mcp}/server.js +0 -0
  94. /package/dist/{models → cjs/models}/index.js +0 -0
  95. /package/dist/{sandbox → cjs/sandbox}/action.js +0 -0
  96. /package/dist/{sandbox → cjs/sandbox}/client/client.gen.js +0 -0
  97. /package/dist/{sandbox → cjs/sandbox}/client/index.js +0 -0
  98. /package/dist/{sandbox → cjs/sandbox}/client/sdk.gen.js +0 -0
  99. /package/dist/{sandbox → cjs/sandbox}/client/types.gen.js +0 -0
  100. /package/dist/{sandbox → cjs/sandbox}/filesystem/filesystem.js +0 -0
  101. /package/dist/{sandbox → cjs/sandbox}/filesystem/index.js +0 -0
  102. /package/dist/{sandbox → cjs/sandbox}/filesystem/types.js +0 -0
  103. /package/dist/{sandbox → cjs/sandbox}/index.js +0 -0
  104. /package/dist/{sandbox → cjs/sandbox}/network/index.js +0 -0
  105. /package/dist/{sandbox → cjs/sandbox}/network/network.js +0 -0
  106. /package/dist/{sandbox → cjs/sandbox}/preview.js +0 -0
  107. /package/dist/{sandbox → cjs/sandbox}/process/index.js +0 -0
  108. /package/dist/{sandbox → cjs/sandbox}/process/process.js +0 -0
  109. /package/dist/{sandbox → cjs/sandbox}/sandbox.js +0 -0
  110. /package/dist/{sandbox → cjs/sandbox}/session.js +0 -0
  111. /package/dist/{sandbox → cjs/sandbox}/types.js +0 -0
  112. /package/dist/{telemetry → cjs/telemetry}/telemetry.js +0 -0
  113. /package/dist/{tools → cjs/tools}/index.js +0 -0
  114. /package/dist/{tools → cjs/tools}/mcpTool.js +0 -0
  115. /package/dist/{tools → cjs/tools}/types.js +0 -0
  116. /package/dist/{tools → cjs/tools}/zodSchema.js +0 -0
  117. /package/dist/{agents → cjs/types/agents}/index.d.ts +0 -0
  118. /package/dist/{authentication → cjs/types/authentication}/apikey.d.ts +0 -0
  119. /package/dist/{authentication → cjs/types/authentication}/clientcredentials.d.ts +0 -0
  120. /package/dist/{authentication → cjs/types/authentication}/credentials.d.ts +0 -0
  121. /package/dist/{authentication → cjs/types/authentication}/deviceMode.d.ts +0 -0
  122. /package/dist/{authentication → cjs/types/authentication}/index.d.ts +0 -0
  123. /package/dist/{authentication → cjs/types/authentication}/types.d.ts +0 -0
  124. /package/dist/{cache → cjs/types/cache}/index.d.ts +0 -0
  125. /package/dist/{client → cjs/types/client}/authentication.d.ts +0 -0
  126. /package/dist/{client → cjs/types/client}/client.d.ts +0 -0
  127. /package/dist/{client → cjs/types/client}/client.gen.d.ts +0 -0
  128. /package/dist/{client → cjs/types/client}/index.d.ts +0 -0
  129. /package/dist/{client → cjs/types/client}/interceptors.d.ts +0 -0
  130. /package/dist/{client → cjs/types/client}/sdk.gen.d.ts +0 -0
  131. /package/dist/{client → cjs/types/client}/types.gen.d.ts +0 -0
  132. /package/dist/{common → cjs/types/common}/autoload.d.ts +0 -0
  133. /package/dist/{common → cjs/types/common}/env.d.ts +0 -0
  134. /package/dist/{common → cjs/types/common}/errors.d.ts +0 -0
  135. /package/dist/{common → cjs/types/common}/internal.d.ts +0 -0
  136. /package/dist/{common → cjs/types/common}/internal.test.d.ts +0 -0
  137. /package/dist/{common → cjs/types/common}/logger.d.ts +0 -0
  138. /package/dist/{common → cjs/types/common}/node.d.ts +0 -0
  139. /package/dist/{common → cjs/types/common}/settings.d.ts +0 -0
  140. /package/dist/{index.browser.test.d.ts → cjs/types/index.browser.test.d.ts} +0 -0
  141. /package/dist/{index.d.ts → cjs/types/index.d.ts} +0 -0
  142. /package/dist/{jobs → cjs/types/jobs}/index.d.ts +0 -0
  143. /package/dist/{jobs → cjs/types/jobs}/jobs.d.ts +0 -0
  144. /package/dist/{jobs → cjs/types/jobs}/start.d.ts +0 -0
  145. /package/dist/{jobs → cjs/types/jobs}/types.d.ts +0 -0
  146. /package/dist/{mcp → cjs/types/mcp}/client.d.ts +0 -0
  147. /package/dist/{mcp → cjs/types/mcp}/index.d.ts +0 -0
  148. /package/dist/{mcp → cjs/types/mcp}/server.d.ts +0 -0
  149. /package/dist/{models → cjs/types/models}/index.d.ts +0 -0
  150. /package/dist/{sandbox → cjs/types/sandbox}/action.d.ts +0 -0
  151. /package/dist/{sandbox → cjs/types/sandbox}/client/client.gen.d.ts +0 -0
  152. /package/dist/{sandbox → cjs/types/sandbox}/client/index.d.ts +0 -0
  153. /package/dist/{sandbox → cjs/types/sandbox}/client/sdk.gen.d.ts +0 -0
  154. /package/dist/{sandbox → cjs/types/sandbox}/client/types.gen.d.ts +0 -0
  155. /package/dist/{sandbox → cjs/types/sandbox}/filesystem/filesystem.d.ts +0 -0
  156. /package/dist/{sandbox → cjs/types/sandbox}/filesystem/index.d.ts +0 -0
  157. /package/dist/{sandbox → cjs/types/sandbox}/filesystem/types.d.ts +0 -0
  158. /package/dist/{sandbox → cjs/types/sandbox}/index.d.ts +0 -0
  159. /package/dist/{sandbox → cjs/types/sandbox}/network/index.d.ts +0 -0
  160. /package/dist/{sandbox → cjs/types/sandbox}/network/network.d.ts +0 -0
  161. /package/dist/{sandbox → cjs/types/sandbox}/preview.d.ts +0 -0
  162. /package/dist/{sandbox → cjs/types/sandbox}/process/index.d.ts +0 -0
  163. /package/dist/{sandbox → cjs/types/sandbox}/process/process.d.ts +0 -0
  164. /package/dist/{sandbox → cjs/types/sandbox}/sandbox.d.ts +0 -0
  165. /package/dist/{sandbox → cjs/types/sandbox}/session.d.ts +0 -0
  166. /package/dist/{sandbox → cjs/types/sandbox}/types.d.ts +0 -0
  167. /package/dist/{telemetry → cjs/types/telemetry}/telemetry.d.ts +0 -0
  168. /package/dist/{tools → cjs/types/tools}/mcpTool.d.ts +0 -0
  169. /package/dist/{tools → cjs/types/tools}/types.d.ts +0 -0
  170. /package/dist/{tools → cjs/types/tools}/zodSchema.d.ts +0 -0
  171. /package/dist/{volume → cjs/types/volume}/index.d.ts +0 -0
  172. /package/dist/{volume → cjs/volume}/index.js +0 -0
@@ -0,0 +1,62 @@
1
+ import { authenticate } from '../common/autoload.js';
2
+ import { env } from '../common/env.js';
3
+ import { flush } from '../telemetry/telemetry.js';
4
+ class BlJobWrapper {
5
+ async getArguments() {
6
+ if (!env.BL_EXECUTION_DATA_URL) {
7
+ const args = this.parseCommandLineArgs();
8
+ return args;
9
+ }
10
+ const response = await fetch(env.BL_EXECUTION_DATA_URL);
11
+ const data = await response.json();
12
+ return data.tasks[this.index] ?? {};
13
+ }
14
+ parseCommandLineArgs() {
15
+ const args = process.argv.slice(2);
16
+ const result = {};
17
+ for (let i = 0; i < args.length; i++) {
18
+ const arg = args[i];
19
+ if (arg.startsWith('--')) {
20
+ const key = arg.slice(2);
21
+ const value = args[i + 1];
22
+ if (value && !value.startsWith('--')) {
23
+ result[key] = value;
24
+ i++;
25
+ }
26
+ else {
27
+ result[key] = 'true';
28
+ }
29
+ }
30
+ }
31
+ return result;
32
+ }
33
+ get indexKey() {
34
+ return env.BL_TASK_KEY ?? "TASK_INDEX";
35
+ }
36
+ get index() {
37
+ return env[this.indexKey] ? Number(env[this.indexKey]) : 0;
38
+ }
39
+ /*
40
+ Run a job defined in a function, it's run in the current process
41
+ */
42
+ async start(func) {
43
+ await authenticate();
44
+ const parsedArgs = await this.getArguments();
45
+ await func(parsedArgs);
46
+ }
47
+ }
48
+ export const blStartJob = (func) => {
49
+ const job = new BlJobWrapper();
50
+ job.start(func).then(async () => {
51
+ try {
52
+ await flush();
53
+ }
54
+ catch (error) {
55
+ console.error('Error flushing telemetry:', error);
56
+ }
57
+ process.exit(0);
58
+ }).catch((error) => {
59
+ console.error('Job execution failed:', error);
60
+ process.exit(1);
61
+ });
62
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,243 @@
1
+ import { JSONRPCMessageSchema, } from "@modelcontextprotocol/sdk/types.js";
2
+ import { logger } from "../common/logger.js";
3
+ import { settings } from "../common/settings.js";
4
+ // Detect environment
5
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
6
+ const isBrowser = typeof globalThis !== "undefined" && globalThis.window !== undefined;
7
+ // Conditional import for Node.js WebSocket
8
+ let NodeWebSocket;
9
+ if (!isBrowser) {
10
+ try {
11
+ // Dynamic import for Node.js environment
12
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports
13
+ NodeWebSocket = require("ws");
14
+ }
15
+ catch {
16
+ console.warn("ws is not available in this environment");
17
+ // ws is not available
18
+ }
19
+ }
20
+ //const SUBPROTOCOL = "mcp";
21
+ // Helper function to wait
22
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
23
+ /**
24
+ * Client transport for WebSocket: this will connect to a server over the WebSocket protocol.
25
+ * Works in both browser and Node.js environments.
26
+ */
27
+ export class BlaxelMcpClientTransport {
28
+ _socket;
29
+ _url;
30
+ _headers;
31
+ _isBrowser;
32
+ _retry_max;
33
+ _retry_delay;
34
+ onclose;
35
+ onerror;
36
+ onmessage;
37
+ constructor(url, headers, options) {
38
+ this._url = new URL(url.replace("http", "ws"));
39
+ this._retry_max = options?.retry?.max ?? 3;
40
+ this._retry_delay = options?.retry?.delay ?? 1000;
41
+ this._headers = headers ?? {};
42
+ this._isBrowser = isBrowser;
43
+ }
44
+ async start() {
45
+ if (this._socket) {
46
+ throw new Error("Blaxel already started! If using Client class, note that connect() calls start() automatically.");
47
+ }
48
+ let attempts = 0;
49
+ const maxAttempts = Math.max(1, this._retry_max + 1); // Ensure at least 1 attempt
50
+ while (attempts < maxAttempts) {
51
+ try {
52
+ await this._connect();
53
+ return;
54
+ }
55
+ catch (error) {
56
+ attempts++;
57
+ if (error instanceof Error) {
58
+ logger.warn(error.stack ?? error.message);
59
+ }
60
+ if (attempts >= maxAttempts) {
61
+ throw error;
62
+ }
63
+ logger.debug(`WebSocket connection attempt ${attempts} failed, retrying in ${this._retry_delay}ms...`);
64
+ await delay(this._retry_delay);
65
+ }
66
+ }
67
+ }
68
+ _connect() {
69
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
70
+ return new Promise((resolve, reject) => {
71
+ try {
72
+ if (this._isBrowser) {
73
+ // Use native browser WebSocket
74
+ const url = `${this._url.toString()}?token=${settings.token}`;
75
+ this._socket = new WebSocket(url);
76
+ }
77
+ else {
78
+ // Use Node.js WebSocket
79
+ if (!NodeWebSocket) {
80
+ throw new Error("WebSocket library not available in Node.js environment");
81
+ }
82
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
83
+ this._socket = new NodeWebSocket(this._url, {
84
+ //protocols: SUBPROTOCOL,
85
+ headers: this._headers,
86
+ });
87
+ }
88
+ this._socket.onerror = (event) => {
89
+ // Log websocket error with meaningful information instead of raw event
90
+ const errorInfo = {
91
+ type: 'WebSocket Error',
92
+ url: this._url.toString(),
93
+ readyState: this._socket?.readyState,
94
+ browser: this._isBrowser,
95
+ // Extract any available error details from the event
96
+ eventType: event && typeof event === 'object' && 'type' in event
97
+ ? String(event.type)
98
+ : 'unknown',
99
+ // Browser events might have different properties than Node.js
100
+ message: this._isBrowser && event && typeof event === 'object' && 'message' in event
101
+ ? String(event.message)
102
+ : undefined,
103
+ error: !this._isBrowser && event && typeof event === 'object' && 'error' in event
104
+ ? String(event.error)
105
+ : undefined
106
+ };
107
+ logger.error('WebSocket connection error', errorInfo);
108
+ const error = this._isBrowser
109
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
110
+ ? new Error(`WebSocket error: ${event.message}`)
111
+ : "error" in event
112
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
113
+ ? event.error
114
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
115
+ : new Error(`WebSocket error: ${event.message}`);
116
+ reject(error);
117
+ this.onerror?.(error);
118
+ };
119
+ this._socket.onopen = () => {
120
+ resolve();
121
+ };
122
+ this._socket.onclose = () => {
123
+ this.onclose?.();
124
+ this._socket = undefined;
125
+ };
126
+ this._socket.onmessage = (event) => {
127
+ let message;
128
+ try {
129
+ let dataString;
130
+ if (this._isBrowser) {
131
+ // Browser WebSocket MessageEvent
132
+ const browserEvent = event;
133
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
134
+ dataString = typeof browserEvent.data === "string"
135
+ ? browserEvent.data
136
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
137
+ : browserEvent.data.toString();
138
+ }
139
+ else {
140
+ // Node.js WebSocket MessageEvent
141
+ const nodeEvent = event;
142
+ if (typeof nodeEvent.data === "string") {
143
+ dataString = nodeEvent.data;
144
+ }
145
+ else if (nodeEvent.data instanceof Buffer) {
146
+ dataString = nodeEvent.data.toString("utf-8");
147
+ }
148
+ else {
149
+ throw new Error("Unsupported data type for event.data");
150
+ }
151
+ }
152
+ message = JSONRPCMessageSchema.parse(JSON.parse(dataString));
153
+ }
154
+ catch (error) {
155
+ logger.error(`Error parsing message: ${
156
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
157
+ typeof event.data === "object"
158
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
159
+ ? JSON.stringify(event.data)
160
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
161
+ : event.data}`);
162
+ this.onerror?.(error);
163
+ return;
164
+ }
165
+ this.onmessage?.(message);
166
+ };
167
+ }
168
+ catch (error) {
169
+ if (error instanceof Error && error.message.includes("ws does not work in the browser")) {
170
+ this._isBrowser = true;
171
+ return this._connect().then(resolve).catch(reject);
172
+ }
173
+ reject(error);
174
+ }
175
+ });
176
+ }
177
+ get isConnected() {
178
+ if (!this._socket)
179
+ return false;
180
+ if (this._isBrowser) {
181
+ return this._socket.readyState === 1; // WebSocket.OPEN = 1
182
+ }
183
+ else {
184
+ return this._socket.readyState === 1; // WebSocket.OPEN = 1
185
+ }
186
+ }
187
+ async close() {
188
+ this._socket?.close();
189
+ this._socket = undefined;
190
+ this.onclose?.();
191
+ return Promise.resolve();
192
+ }
193
+ async send(message) {
194
+ let attempts = 0;
195
+ const maxAttempts = Math.max(1, this._retry_max + 1); // Ensure at least 1 attempt
196
+ while (attempts < maxAttempts) {
197
+ try {
198
+ if (!this._socket || !this.isConnected) {
199
+ if (!this._socket) {
200
+ // Only try to start if socket doesn't exist
201
+ await this.start();
202
+ }
203
+ else {
204
+ throw new Error("WebSocket is not in OPEN state");
205
+ }
206
+ }
207
+ await new Promise((resolve, reject) => {
208
+ try {
209
+ const messageStr = JSON.stringify(message);
210
+ if (this._isBrowser) {
211
+ // Browser WebSocket
212
+ this._socket?.send(messageStr);
213
+ resolve();
214
+ }
215
+ else {
216
+ // Node.js WebSocket
217
+ this._socket?.send(messageStr, (error) => {
218
+ if (error) {
219
+ reject(error);
220
+ }
221
+ else {
222
+ resolve();
223
+ }
224
+ });
225
+ }
226
+ }
227
+ catch (error) {
228
+ reject(error);
229
+ }
230
+ });
231
+ return;
232
+ }
233
+ catch (error) {
234
+ attempts++;
235
+ if (attempts >= maxAttempts) {
236
+ throw error;
237
+ }
238
+ logger.warn(`WebSocket send attempt ${attempts} failed, retrying in ${this._retry_delay}ms...`);
239
+ await delay(this._retry_delay);
240
+ }
241
+ }
242
+ }
243
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./client.js";
2
+ export * from "./server.js";
@@ -0,0 +1,176 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ import WebSocket, { WebSocketServer } from "ws";
3
+ import { env } from "../common/env.js";
4
+ import { logger } from "../common/logger.js";
5
+ import { startSpan } from "../telemetry/telemetry.js";
6
+ const spans = new Map();
7
+ export class BlaxelMcpServerTransport {
8
+ port;
9
+ wss;
10
+ clients = new Map();
11
+ onclose;
12
+ onerror;
13
+ messageHandler;
14
+ onconnection;
15
+ ondisconnection;
16
+ set onmessage(handler) {
17
+ this.messageHandler = handler
18
+ ? (msg, clientId) => {
19
+ if (!("id" in msg)) {
20
+ return handler(msg);
21
+ }
22
+ return handler({
23
+ ...msg,
24
+ id: clientId + ":" + msg.id,
25
+ });
26
+ }
27
+ : undefined;
28
+ }
29
+ constructor(port) {
30
+ this.port = port ?? parseInt(env.BL_SERVER_PORT ?? "8080", 10);
31
+ this.wss = new WebSocketServer({ port: this.port });
32
+ }
33
+ async start() {
34
+ logger.info("Starting WebSocket Server on port " + this.port);
35
+ this.wss.on("connection", (ws) => {
36
+ const clientId = uuidv4();
37
+ this.clients.set(clientId, {
38
+ ws,
39
+ });
40
+ this.onconnection?.(clientId);
41
+ ws.on("message", (data) => {
42
+ const span = startSpan("message", {
43
+ attributes: {
44
+ "mcp.client.id": clientId,
45
+ "span.type": "mcp.message",
46
+ },
47
+ isRoot: false,
48
+ });
49
+ try {
50
+ const msg = JSON.parse(data.toString());
51
+ this.messageHandler?.(msg, clientId);
52
+ if ("method" in msg && "id" in msg && "params" in msg) {
53
+ span.setAttributes({
54
+ "mcp.message.parsed": true,
55
+ "mcp.method": msg.method,
56
+ "mcp.messageId": msg.id,
57
+ "mcp.toolName": msg.params?.name,
58
+ });
59
+ spans.set(clientId + ":" + msg.id, span);
60
+ }
61
+ // Handle msg.id safely
62
+ const msgId = msg.id ? String(msg.id) : "";
63
+ const [cId, parsedMsgId] = msgId.split(":");
64
+ msg.id = parsedMsgId ? parseInt(parsedMsgId) : undefined;
65
+ // Use optional chaining for safe access
66
+ const client = this.clients.get(cId ?? "");
67
+ if (client?.ws?.readyState === WebSocket.OPEN) {
68
+ const msgSpan = spans.get(cId + ":" + (msg.id ?? ""));
69
+ try {
70
+ client.ws.send(JSON.stringify(msg));
71
+ if (msgSpan) {
72
+ msgSpan.setAttributes({
73
+ "mcp.message.response_sent": true,
74
+ });
75
+ }
76
+ }
77
+ catch (err) {
78
+ if (msgSpan) {
79
+ msgSpan.setStatus("error"); // Error status
80
+ msgSpan.recordException(err);
81
+ }
82
+ throw err;
83
+ }
84
+ finally {
85
+ if (msgSpan) {
86
+ msgSpan.end();
87
+ }
88
+ }
89
+ }
90
+ else {
91
+ this.clients.delete(cId);
92
+ this.ondisconnection?.(cId);
93
+ }
94
+ }
95
+ catch (err) {
96
+ if (err instanceof Error) {
97
+ span.setStatus("error"); // Error status
98
+ span.recordException(err);
99
+ this.onerror?.(err);
100
+ }
101
+ else {
102
+ this.onerror?.(new Error(`Failed to parse message: ${String(err)}`));
103
+ }
104
+ span.end();
105
+ }
106
+ });
107
+ ws.on("close", () => {
108
+ this.clients.delete(clientId);
109
+ this.ondisconnection?.(clientId);
110
+ });
111
+ ws.on("error", (err) => {
112
+ this.onerror?.(err);
113
+ });
114
+ });
115
+ return Promise.resolve();
116
+ }
117
+ async send(msg) {
118
+ const [cId, msgId] = msg.id ? String(msg.id).split(":") : [];
119
+ msg.id = parseInt(msgId);
120
+ const data = JSON.stringify(msg);
121
+ const deadClients = [];
122
+ if (cId) {
123
+ // Send to specific client
124
+ const client = this.clients.get(cId);
125
+ if (client?.ws?.readyState === WebSocket.OPEN) {
126
+ const msgSpan = spans.get(cId + ":" + msg.id);
127
+ try {
128
+ client.ws.send(data);
129
+ if (msgSpan) {
130
+ msgSpan.setAttributes({
131
+ "mcp.message.response_sent": true,
132
+ });
133
+ }
134
+ }
135
+ catch (err) {
136
+ if (msgSpan) {
137
+ msgSpan.setStatus("error"); // Error status
138
+ msgSpan.recordException(err);
139
+ }
140
+ throw err;
141
+ }
142
+ finally {
143
+ if (msgSpan) {
144
+ msgSpan.end();
145
+ }
146
+ }
147
+ }
148
+ else {
149
+ this.clients.delete(cId);
150
+ this.ondisconnection?.(cId);
151
+ }
152
+ }
153
+ for (const [id, client] of this.clients.entries()) {
154
+ if (client.ws.readyState !== WebSocket.OPEN) {
155
+ deadClients.push(id);
156
+ }
157
+ }
158
+ // Cleanup dead clients
159
+ deadClients.forEach((id) => {
160
+ this.clients.delete(id);
161
+ this.ondisconnection?.(id);
162
+ });
163
+ return Promise.resolve();
164
+ }
165
+ async broadcast(msg) {
166
+ return this.send(msg);
167
+ }
168
+ async close() {
169
+ return new Promise((resolve) => {
170
+ this.wss.close(() => {
171
+ this.clients.clear();
172
+ resolve();
173
+ });
174
+ });
175
+ }
176
+ }
@@ -0,0 +1,25 @@
1
+ import { findFromCache } from "../cache/index.js";
2
+ import { getModel } from "../client/sdk.gen.js";
3
+ export class BLModel {
4
+ modelName;
5
+ options;
6
+ constructor(modelName, options) {
7
+ this.modelName = modelName;
8
+ this.options = options || {};
9
+ }
10
+ }
11
+ export const blModel = (modelName, options) => {
12
+ return new BLModel(modelName, options);
13
+ };
14
+ export const getModelMetadata = async (model) => {
15
+ const cacheData = await findFromCache("Model", model);
16
+ if (cacheData) {
17
+ return cacheData;
18
+ }
19
+ const { data } = await getModel({
20
+ path: {
21
+ modelName: model,
22
+ },
23
+ });
24
+ return data || null;
25
+ };
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,79 @@
1
+ import { createClient } from "@hey-api/client-fetch";
2
+ import { getForcedUrl, getGlobalUniqueHash } from "../common/internal.js";
3
+ import { settings } from "../common/settings.js";
4
+ import { client as defaultClient } from "./client/client.gen.js";
5
+ export class ResponseError extends Error {
6
+ response;
7
+ data;
8
+ error;
9
+ constructor(response, data, error) {
10
+ let dataError = {};
11
+ if (data && typeof data === 'object' && 'error' in data) {
12
+ dataError = data;
13
+ }
14
+ if (error && typeof error === 'object' && 'error' in error) {
15
+ dataError['error'] = error.error;
16
+ }
17
+ if (response.status) {
18
+ dataError['status'] = response.status;
19
+ }
20
+ if (response.statusText) {
21
+ dataError['statusText'] = response.statusText;
22
+ }
23
+ super(JSON.stringify(dataError));
24
+ this.response = response;
25
+ this.data = data;
26
+ this.error = error;
27
+ }
28
+ }
29
+ export class SandboxAction {
30
+ sandbox;
31
+ constructor(sandbox) {
32
+ this.sandbox = sandbox;
33
+ }
34
+ get name() {
35
+ return this.sandbox.metadata?.name ?? "";
36
+ }
37
+ get fallbackUrl() {
38
+ if (this.externalUrl != this.url) {
39
+ return this.externalUrl;
40
+ }
41
+ return null;
42
+ }
43
+ get externalUrl() {
44
+ return `${settings.runUrl}/${settings.workspace}/sandboxes/${this.name}`;
45
+ }
46
+ get internalUrl() {
47
+ const hash = getGlobalUniqueHash(settings.workspace, "sandbox", this.name);
48
+ return `${settings.runInternalProtocol}://bl-${settings.env}-${hash}.${settings.runInternalHostname}`;
49
+ }
50
+ get client() {
51
+ if (this.sandbox.forceUrl) {
52
+ return createClient({
53
+ baseUrl: this.sandbox.forceUrl,
54
+ headers: this.sandbox.headers,
55
+ });
56
+ }
57
+ return defaultClient;
58
+ }
59
+ get forcedUrl() {
60
+ if (this.sandbox.forceUrl)
61
+ return this.sandbox.forceUrl;
62
+ return getForcedUrl('sandbox', this.name);
63
+ }
64
+ get url() {
65
+ if (this.forcedUrl) {
66
+ const url = this.forcedUrl.toString();
67
+ return url.endsWith('/') ? url.slice(0, -1) : url;
68
+ }
69
+ // Uncomment and use this when agent and mcp are available in mk3
70
+ // Update all requests made in this package to use fallbackUrl when internalUrl is not working
71
+ // if (settings.runInternalHostname) return this.internalUrl;
72
+ return this.externalUrl;
73
+ }
74
+ handleResponseError(response, data, error) {
75
+ if (!response.ok || !data) {
76
+ throw new ResponseError(response, data, error);
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,3 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+ import { createClient, createConfig } from '@hey-api/client-fetch';
3
+ export const client = createClient(createConfig());
@@ -0,0 +1,3 @@
1
+ // This file is auto-generated by @hey-api/openapi-ts
2
+ export * from './types.gen.js';
3
+ export * from './sdk.gen.js';