@blaxel/core 0.2.40 → 0.2.41-preview.91

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,6 +1,6 @@
1
1
  import { settings } from "../../common/settings.js";
2
2
  import { SandboxAction } from "../action.js";
3
- import { deleteFilesystemByPath, getFilesystemByPath, getWatchFilesystemByPath, putFilesystemByPath } from "../client/index.js";
3
+ import { deleteFilesystemByPath, getFilesystemByPath, getWatchFilesystemByPath, putFilesystemByPath, postProcess } from "../client/index.js";
4
4
  export class SandboxFileSystem extends SandboxAction {
5
5
  constructor(sandbox) {
6
6
  super(sandbox);
@@ -131,53 +131,20 @@ export class SandboxFileSystem extends SandboxAction {
131
131
  async cp(source, destination) {
132
132
  source = this.formatPath(source);
133
133
  destination = this.formatPath(destination);
134
- const { response, data, error } = await getFilesystemByPath({
135
- path: { path: source },
134
+ const process = {
135
+ command: `cp -r "${source}" "${destination}"`
136
+ };
137
+ const { response, data, error } = await postProcess({
138
+ body: process,
136
139
  baseUrl: this.url,
137
140
  client: this.client,
138
141
  });
139
142
  this.handleResponseError(response, data, error);
140
- if (data && ('files' in data || 'subdirectories' in data)) {
141
- // Create destination directory
142
- await this.mkdir(destination);
143
- // Process subdirectories in batches of 5
144
- const subdirectories = data.subdirectories || [];
145
- for (let i = 0; i < subdirectories.length; i += 5) {
146
- const batch = subdirectories.slice(i, i + 5);
147
- await Promise.all(batch.map(async (subdir) => {
148
- const sourcePath = subdir.path || `${source}/${subdir.path}`;
149
- const destPath = `${destination}/${subdir.path}`;
150
- await this.cp(sourcePath, destPath);
151
- }));
152
- }
153
- // Process files in batches of 10
154
- const files = data.files || [];
155
- for (let i = 0; i < files.length; i += 10) {
156
- const batch = files.slice(i, i + 10);
157
- await Promise.all(batch.map(async (file) => {
158
- const sourcePath = file.path || `${source}/${file.path}`;
159
- const destPath = `${destination}/${file.path}`;
160
- const fileContent = await this.read(sourcePath);
161
- if (typeof fileContent === 'string') {
162
- await this.write(destPath, fileContent);
163
- }
164
- }));
165
- }
166
- return {
167
- message: "Directory copied successfully",
168
- source,
169
- destination,
170
- };
171
- }
172
- else if (data && 'content' in data) {
173
- await this.write(destination, data.content);
174
- return {
175
- message: "File copied successfully",
176
- source,
177
- destination,
178
- };
179
- }
180
- throw new Error("Unsupported file type");
143
+ return {
144
+ message: "Files copied",
145
+ source,
146
+ destination,
147
+ };
181
148
  }
182
149
  watch(path, callback, options) {
183
150
  path = this.formatPath(path);
@@ -216,7 +183,11 @@ export class SandboxFileSystem extends SandboxAction {
216
183
  const trimmed = line.trim();
217
184
  if (!trimmed)
218
185
  continue;
219
- const fileEvent = JSON.parse(line.trim());
186
+ // Skip keepalive messages
187
+ if (line.startsWith("[keepalive]")) {
188
+ continue;
189
+ }
190
+ const fileEvent = JSON.parse(trimmed);
220
191
  if (options?.withContent && ["CREATE", "WRITE"].includes(fileEvent.op)) {
221
192
  try {
222
193
  let filePath = "";
@@ -7,6 +7,7 @@ import { authenticate } from "../index.js";
7
7
  import { BlaxelMcpClientTransport } from "../mcp/client.js";
8
8
  import { startSpan } from "../telemetry/telemetry.js";
9
9
  import { schemaToZodSchema } from "./zodSchema.js";
10
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
10
11
  const McpToolCache = new Map();
11
12
  export class McpTool {
12
13
  name;
@@ -16,6 +17,7 @@ export class McpTool {
16
17
  transport;
17
18
  timer;
18
19
  ms;
20
+ transportName;
19
21
  meta;
20
22
  startPromise;
21
23
  constructor(name, options = { ms: 5000 }) {
@@ -73,7 +75,7 @@ export class McpTool {
73
75
  await authenticate();
74
76
  try {
75
77
  logger.debug(`MCP:${this.name}:Connecting::${this.url.toString()}`);
76
- this.transport = new BlaxelMcpClientTransport(this.url.toString(), settings.headers, { retry: { max: 0 } });
78
+ this.transport = await this.getTransport();
77
79
  await this.client.connect(this.transport);
78
80
  logger.debug(`MCP:${this.name}:Connected`);
79
81
  }
@@ -90,7 +92,7 @@ export class McpTool {
90
92
  throw err;
91
93
  }
92
94
  logger.debug(`MCP:${this.name}:Connecting to fallback`);
93
- this.transport = new BlaxelMcpClientTransport(this.fallbackUrl.toString(), settings.headers);
95
+ this.transport = await this.getTransport(this.fallbackUrl);
94
96
  await this.client.connect(this.transport);
95
97
  logger.debug(`MCP:${this.name}:Connected to fallback`);
96
98
  }
@@ -201,6 +203,39 @@ export class McpTool {
201
203
  span.end();
202
204
  }
203
205
  }
206
+ async getTransport(forcedUrl) {
207
+ if (!this.transportName) {
208
+ // Detect transport type dynamically by querying the function's endpoint
209
+ try {
210
+ const testUrl = (forcedUrl || this.url).toString();
211
+ const response = await fetch(testUrl + "/", {
212
+ method: "GET",
213
+ headers: settings.headers,
214
+ });
215
+ const responseText = await response.text();
216
+ if (responseText.toLowerCase().includes("websocket")) {
217
+ this.transportName = "websocket";
218
+ }
219
+ else {
220
+ this.transportName = "http-stream";
221
+ }
222
+ logger.debug(`Detected transport type for ${this.name}: ${this.transportName}`);
223
+ }
224
+ catch (error) {
225
+ // Default to websocket if we can't determine the transport type
226
+ logger.warn(`Failed to detect transport type for ${this.name}: ${error}. Defaulting to websocket.`);
227
+ this.transportName = "websocket";
228
+ }
229
+ }
230
+ const url = forcedUrl || this.url;
231
+ if (this.transportName === "http-stream") {
232
+ url.pathname = url.pathname + "/mcp";
233
+ return new StreamableHTTPClientTransport(url, { requestInit: { headers: settings.headers } });
234
+ }
235
+ else {
236
+ return new BlaxelMcpClientTransport(url.toString(), settings.headers, { retry: { max: 0 } });
237
+ }
238
+ }
204
239
  }
205
240
  export const getMcpTool = async (name, options) => {
206
241
  let tool = McpToolCache.get(name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaxel/core",
3
- "version": "0.2.40",
3
+ "version": "0.2.41-preview.91",
4
4
  "description": "Blaxel Core SDK for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "Blaxel, INC (https://blaxel.ai)",
@@ -63,7 +63,7 @@
63
63
  "vite": "^5.2.0",
64
64
  "vitest": "^1.5.0"
65
65
  },
66
- "commit": "9d887e963254d2a0f1d1d1aaab98198a3aa18b6b",
66
+ "commit": "68b2b0f03efd40f1ae2dcf83d21bfa7312b80282",
67
67
  "scripts": {
68
68
  "lint": "eslint src/",
69
69
  "dev": "tsc --watch",