rl-rock 1.2.6 → 1.3.0

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/index.mjs CHANGED
@@ -2,7 +2,7 @@ import path, { join, resolve, basename } from 'path';
2
2
  import { fileURLToPath } from 'url';
3
3
  import { existsSync, mkdirSync, readFileSync, statSync, mkdtempSync, rmSync } from 'fs';
4
4
  import { z } from 'zod';
5
- import axios, { AxiosError } from 'axios';
5
+ import axios from 'axios';
6
6
  import https from 'https';
7
7
  import { objectToCamel as objectToCamel$1, objectToSnake as objectToSnake$1 } from 'ts-case-convert';
8
8
  import winston from 'winston';
@@ -75,9 +75,11 @@ var ReadFileRequestSchema = z.object({
75
75
  encoding: z.string().optional(),
76
76
  errors: z.string().optional()
77
77
  });
78
+ var UploadModeSchema = z.enum(["auto", "direct", "oss"]);
78
79
  var UploadRequestSchema = z.object({
79
80
  sourcePath: z.string(),
80
- targetPath: z.string()
81
+ targetPath: z.string(),
82
+ uploadMode: UploadModeSchema.optional()
81
83
  });
82
84
  var CloseSessionRequestSchema = z.object({
83
85
  session: z.string().default("default")
@@ -169,6 +171,16 @@ var OssSetupResponseSchema = z.object({
169
171
  success: z.boolean().default(false),
170
172
  message: z.string().default("")
171
173
  });
174
+ var DownloadFileResponseSchema = z.object({
175
+ success: z.boolean().default(false),
176
+ message: z.string().default("")
177
+ });
178
+ var OssCredentialsSchema = z.object({
179
+ accessKeyId: z.string(),
180
+ accessKeySecret: z.string(),
181
+ securityToken: z.string(),
182
+ expiration: z.string()
183
+ });
172
184
 
173
185
  // src/common/constants.ts
174
186
  var RunMode = {
@@ -299,9 +311,6 @@ var HttpUtils = class {
299
311
  }
300
312
  return httpResponse;
301
313
  } catch (error) {
302
- if (error instanceof AxiosError) {
303
- throw new Error(`Failed to POST ${url}: ${error.message}`);
304
- }
305
314
  throw error;
306
315
  }
307
316
  }
@@ -326,9 +335,6 @@ var HttpUtils = class {
326
335
  }
327
336
  return httpResponse;
328
337
  } catch (error) {
329
- if (error instanceof AxiosError) {
330
- throw new Error(`Failed to GET ${url}: ${error.message}`);
331
- }
332
338
  throw error;
333
339
  }
334
340
  }
@@ -408,9 +414,6 @@ var HttpUtils = class {
408
414
  }
409
415
  return httpResponse;
410
416
  } catch (error) {
411
- if (error instanceof AxiosError) {
412
- throw new Error(`Failed to POST multipart ${url}: ${error.message}`);
413
- }
414
417
  throw error;
415
418
  }
416
419
  }
@@ -1441,6 +1444,53 @@ var LinuxFileSystem = class extends FileSystem {
1441
1444
  }
1442
1445
  };
1443
1446
 
1447
+ // src/sandbox/constants.ts
1448
+ var ENSURE_OSSUTIL_SCRIPT = `#!/bin/bash
1449
+ set -e
1450
+
1451
+ # Check downloader
1452
+ if command -v wget >/dev/null 2>&1; then
1453
+ DOWNLOADER="wget"
1454
+ elif command -v curl >/dev/null 2>&1; then
1455
+ DOWNLOADER="curl"
1456
+ else
1457
+ echo "ERROR: neither wget nor curl is available. Please install one first." >&2
1458
+ exit 1
1459
+ fi
1460
+
1461
+ # Check unzip
1462
+ if ! command -v unzip >/dev/null 2>&1; then
1463
+ echo "ERROR: unzip is not available. Please install unzip first." >&2
1464
+ exit 1
1465
+ fi
1466
+
1467
+ # Skip if already installed
1468
+ if command -v ossutil >/dev/null 2>&1; then
1469
+ echo "ossutil already installed, skipping."
1470
+ exit 0
1471
+ fi
1472
+
1473
+ # Download
1474
+ cd /tmp
1475
+ if [ "$DOWNLOADER" = "wget" ]; then
1476
+ wget -q https://gosspublic.alicdn.com/ossutil/v2/2.2.1/ossutil-2.2.1-linux-amd64.zip -O /tmp/ossutil.zip
1477
+ else
1478
+ curl -sL -o /tmp/ossutil.zip https://gosspublic.alicdn.com/ossutil/v2/2.2.1/ossutil-2.2.1-linux-amd64.zip
1479
+ fi
1480
+
1481
+ # Extract and install
1482
+ unzip -o -q ossutil.zip
1483
+ chmod 755 /tmp/ossutil-2.2.1-linux-amd64/ossutil
1484
+ mkdir -p /usr/local/bin
1485
+ mv /tmp/ossutil-2.2.1-linux-amd64/ossutil /usr/local/bin/
1486
+
1487
+ # Cleanup
1488
+ rm -rf /tmp/ossutil.zip /tmp/ossutil-2.2.1-linux-amd64
1489
+
1490
+ # Verify
1491
+ ossutil version
1492
+ `;
1493
+
1444
1494
  // src/sandbox/network.ts
1445
1495
  var logger4 = initLogger("rock.sandbox.network");
1446
1496
  var SpeedupType = /* @__PURE__ */ ((SpeedupType2) => {
@@ -1844,6 +1894,10 @@ var Sandbox = class extends AbstractSandbox {
1844
1894
  hostName = null;
1845
1895
  hostIp = null;
1846
1896
  cluster;
1897
+ // OSS-related properties
1898
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1899
+ ossBucket = null;
1900
+ ossTokenExpireTime = "";
1847
1901
  // Sub-components
1848
1902
  deploy;
1849
1903
  fs;
@@ -2231,7 +2285,7 @@ var Sandbox = class extends AbstractSandbox {
2231
2285
  async upload(request) {
2232
2286
  return this.uploadByPath(request.sourcePath, request.targetPath);
2233
2287
  }
2234
- async uploadByPath(sourcePath, targetPath) {
2288
+ async uploadByPath(sourcePath, targetPath, uploadMode = "auto") {
2235
2289
  const url = `${this.url}/upload`;
2236
2290
  const headers = this.buildHeaders();
2237
2291
  try {
@@ -2241,6 +2295,13 @@ var Sandbox = class extends AbstractSandbox {
2241
2295
  } catch {
2242
2296
  return { success: false, message: `File not found: ${sourcePath}` };
2243
2297
  }
2298
+ const stats = await fs.stat(sourcePath);
2299
+ const fileSize = stats.size;
2300
+ const ossEnabled = envVars.ROCK_OSS_ENABLE;
2301
+ const ossThreshold = 1024 * 1024;
2302
+ if (uploadMode === "oss" || uploadMode === "auto" && ossEnabled && fileSize > ossThreshold) {
2303
+ return this.uploadViaOss(sourcePath, targetPath);
2304
+ }
2244
2305
  const fileBuffer = await fs.readFile(sourcePath);
2245
2306
  const fileName = sourcePath.split("/").pop() ?? "file";
2246
2307
  const response = await HttpUtils.postMultipart(
@@ -2257,6 +2318,136 @@ var Sandbox = class extends AbstractSandbox {
2257
2318
  return { success: false, message: `Upload failed: ${e}` };
2258
2319
  }
2259
2320
  }
2321
+ /**
2322
+ * Get OSS STS credentials from sandbox
2323
+ */
2324
+ async getOssStsCredentials() {
2325
+ const url = `${this.url}/get_token`;
2326
+ const headers = this.buildHeaders();
2327
+ const response = await HttpUtils.get(url, headers);
2328
+ if (response.status !== "Success") {
2329
+ throw new Error(`Failed to get OSS STS token: ${JSON.stringify(response)}`);
2330
+ }
2331
+ const credentials = OssCredentialsSchema.parse(response.result);
2332
+ this.ossTokenExpireTime = credentials.expiration;
2333
+ return credentials;
2334
+ }
2335
+ /**
2336
+ * Check if OSS token is expired (with 5-minute buffer)
2337
+ */
2338
+ isTokenExpired() {
2339
+ if (!this.ossTokenExpireTime) {
2340
+ return true;
2341
+ }
2342
+ try {
2343
+ const expireTime = new Date(this.ossTokenExpireTime);
2344
+ const currentTime = /* @__PURE__ */ new Date();
2345
+ const bufferMs = 5 * 60 * 1e3;
2346
+ return currentTime.getTime() >= expireTime.getTime() - bufferMs;
2347
+ } catch {
2348
+ return true;
2349
+ }
2350
+ }
2351
+ /**
2352
+ * Download file from sandbox via OSS
2353
+ */
2354
+ async downloadFile(remotePath, localPath) {
2355
+ if (!envVars.ROCK_OSS_ENABLE) {
2356
+ return {
2357
+ success: false,
2358
+ message: "OSS download is not enabled. Please set ROCK_OSS_ENABLE=true"
2359
+ };
2360
+ }
2361
+ try {
2362
+ if (!remotePath || remotePath.trim() === "") {
2363
+ return { success: false, message: "Remote path is required" };
2364
+ }
2365
+ const checkResult = await this.execute({ command: ["test", "-f", remotePath], timeout: 60 });
2366
+ if (checkResult.exitCode !== 0) {
2367
+ return { success: false, message: `Remote file does not exist: ${remotePath}` };
2368
+ }
2369
+ if (this.ossBucket === null || this.isTokenExpired()) {
2370
+ await this.setupOss();
2371
+ }
2372
+ if (!this.ossBucket) {
2373
+ return { success: false, message: "Failed to setup OSS bucket" };
2374
+ }
2375
+ await this.arun(ENSURE_OSSUTIL_SCRIPT, { mode: "nohup", waitTimeout: 300 });
2376
+ const timestamp = Date.now();
2377
+ const fileName = remotePath.split("/").pop() ?? "file";
2378
+ const objectName = `download-${timestamp}-${fileName}`;
2379
+ const credentials = await this.getOssStsCredentials();
2380
+ const bucketName = envVars.ROCK_OSS_BUCKET_NAME ?? "";
2381
+ const region = envVars.ROCK_OSS_BUCKET_REGION ?? "";
2382
+ const endpoint = `https://oss-${region}.aliyuncs.com`;
2383
+ const ossutilConfigCmd = `ossutil config -e ${endpoint} -i ${credentials.accessKeyId} -k ${credentials.accessKeySecret} -t ${credentials.securityToken} -b ${bucketName}`;
2384
+ await this.arun(ossutilConfigCmd, { mode: "nohup", waitTimeout: 60 });
2385
+ const uploadToOssCmd = `ossutil cp ${remotePath} oss://${bucketName}/${objectName}`;
2386
+ const uploadResult = await this.arun(uploadToOssCmd, { mode: "nohup", waitTimeout: 600 });
2387
+ if (uploadResult.exitCode !== 0) {
2388
+ return { success: false, message: `Sandbox to OSS upload failed: ${uploadResult.output}` };
2389
+ }
2390
+ const result = await this.ossBucket.get(objectName, localPath);
2391
+ try {
2392
+ await this.ossBucket.delete(objectName);
2393
+ } catch {
2394
+ }
2395
+ return { success: true, message: `Successfully downloaded ${remotePath} to ${localPath}` };
2396
+ } catch (e) {
2397
+ return { success: false, message: `Download failed: ${e}` };
2398
+ }
2399
+ }
2400
+ /**
2401
+ * Upload file via OSS (internal method)
2402
+ */
2403
+ async uploadViaOss(sourcePath, targetPath) {
2404
+ try {
2405
+ if (this.ossBucket === null || this.isTokenExpired()) {
2406
+ await this.setupOss();
2407
+ }
2408
+ if (!this.ossBucket) {
2409
+ return { success: false, message: "Failed to setup OSS bucket" };
2410
+ }
2411
+ const timestamp = Date.now();
2412
+ const fileName = sourcePath.split("/").pop() ?? "file";
2413
+ const objectName = `${timestamp}-${fileName}`;
2414
+ await this.ossBucket.put(objectName, sourcePath);
2415
+ const signedUrl = this.ossBucket.signatureUrl(objectName, 600);
2416
+ const downloadCmd = `wget -c -O '${targetPath}' '${signedUrl}'`;
2417
+ await this.arun(downloadCmd, { mode: "nohup", waitTimeout: 600 });
2418
+ const checkResult = await this.execute({ command: ["test", "-f", targetPath], timeout: 60 });
2419
+ if (checkResult.exitCode !== 0) {
2420
+ return { success: false, message: "Sandbox download phase failed" };
2421
+ }
2422
+ return { success: true, message: `Successfully uploaded file ${fileName} to ${targetPath} via OSS` };
2423
+ } catch (e) {
2424
+ return { success: false, message: `OSS upload failed: ${e}` };
2425
+ }
2426
+ }
2427
+ /**
2428
+ * Setup OSS bucket with STS credentials
2429
+ */
2430
+ async setupOss() {
2431
+ const credentials = await this.getOssStsCredentials();
2432
+ const OSS = (await import('ali-oss')).default;
2433
+ this.ossBucket = new OSS({
2434
+ region: envVars.ROCK_OSS_BUCKET_REGION ?? "",
2435
+ accessKeyId: credentials.accessKeyId,
2436
+ accessKeySecret: credentials.accessKeySecret,
2437
+ stsToken: credentials.securityToken,
2438
+ bucket: envVars.ROCK_OSS_BUCKET_NAME ?? "",
2439
+ refreshSTSToken: async () => {
2440
+ const newCreds = await this.getOssStsCredentials();
2441
+ return {
2442
+ accessKeyId: newCreds.accessKeyId,
2443
+ accessKeySecret: newCreds.accessKeySecret,
2444
+ stsToken: newCreds.securityToken
2445
+ };
2446
+ },
2447
+ refreshSTSTokenInterval: 3e5
2448
+ // 5 minutes
2449
+ });
2450
+ }
2260
2451
  // Close
2261
2452
  async close() {
2262
2453
  await this.stop();
@@ -3200,6 +3391,6 @@ function getVersion() {
3200
3391
  }
3201
3392
  var VERSION = getVersion();
3202
3393
 
3203
- export { Agent, AgentBashCommandSchema, AgentConfigSchema, BadRequestRockError, BashActionSchema, ChmodRequestSchema, ChmodResponseSchema, ChownRequestSchema, ChownResponseSchema, CloseResponseSchema, CloseSessionRequestSchema, CloseSessionResponseSchema, Codes, CommandResponseSchema, CommandRockError, CommandSchema, CreateBashSessionRequestSchema, CreateSessionResponseSchema, DefaultAgent, DefaultAgentConfigSchema, Deploy, EnvHubClient, EnvHubClientConfigSchema, EnvHubError, ExecuteBashSessionResponseSchema, HttpUtils, InternalServerRockError, InvalidParameterRockException, IsAliveResponseSchema, LinuxFileSystem, LinuxRemoteUser, ModelClient, ModelService, ModelServiceConfigSchema, NODE_DEFAULT_VERSION, Network, NodeRuntimeEnv, NodeRuntimeEnvConfigSchema, ObservationSchema, OssSetupResponseSchema, PID_PREFIX, PID_SUFFIX, Process, PythonRuntimeEnv, PythonRuntimeEnvConfigSchema, ReadFileRequestSchema, ReadFileResponseSchema, ReasonPhrases, RockAgentConfigSchema, RockEnv, RockEnvInfoSchema, RockException, RunMode, RuntimeEnv, RuntimeEnvConfigSchema, Sandbox, SandboxConfigSchema, SandboxGroup, SandboxGroupConfigSchema, SandboxResponseSchema, SandboxStatusResponseSchema, SpeedupType, UploadRequestSchema, UploadResponseSchema, VERSION, WriteFileRequestSchema, WriteFileResponseSchema, arunWithRetry, createRockEnvInfo, createRuntimeEnvId, createSandboxConfig, createSandboxGroupConfig, deprecated, deprecatedClass, extractNohupPid as extractNohupPidFromSandbox, fromRockException, getDefaultPipIndexUrl, getEnv, getReasonPhrase, getRequiredEnv, isClientError, isCommandError, isEnvSet, isError, isNode, isServerError, isSuccess, make, raiseForCode, retryAsync, sleep, withRetry, withTimeLogging };
3394
+ export { Agent, AgentBashCommandSchema, AgentConfigSchema, BadRequestRockError, BashActionSchema, ChmodRequestSchema, ChmodResponseSchema, ChownRequestSchema, ChownResponseSchema, CloseResponseSchema, CloseSessionRequestSchema, CloseSessionResponseSchema, Codes, CommandResponseSchema, CommandRockError, CommandSchema, CreateBashSessionRequestSchema, CreateSessionResponseSchema, DefaultAgent, DefaultAgentConfigSchema, Deploy, DownloadFileResponseSchema, EnvHubClient, EnvHubClientConfigSchema, EnvHubError, ExecuteBashSessionResponseSchema, HttpUtils, InternalServerRockError, InvalidParameterRockException, IsAliveResponseSchema, LinuxFileSystem, LinuxRemoteUser, ModelClient, ModelService, ModelServiceConfigSchema, NODE_DEFAULT_VERSION, Network, NodeRuntimeEnv, NodeRuntimeEnvConfigSchema, ObservationSchema, OssCredentialsSchema, OssSetupResponseSchema, PID_PREFIX, PID_SUFFIX, Process, PythonRuntimeEnv, PythonRuntimeEnvConfigSchema, ReadFileRequestSchema, ReadFileResponseSchema, ReasonPhrases, RockAgentConfigSchema, RockEnv, RockEnvInfoSchema, RockException, RunMode, RuntimeEnv, RuntimeEnvConfigSchema, Sandbox, SandboxConfigSchema, SandboxGroup, SandboxGroupConfigSchema, SandboxResponseSchema, SandboxStatusResponseSchema, SpeedupType, UploadModeSchema, UploadRequestSchema, UploadResponseSchema, VERSION, WriteFileRequestSchema, WriteFileResponseSchema, arunWithRetry, createRockEnvInfo, createRuntimeEnvId, createSandboxConfig, createSandboxGroupConfig, deprecated, deprecatedClass, extractNohupPid as extractNohupPidFromSandbox, fromRockException, getDefaultPipIndexUrl, getEnv, getReasonPhrase, getRequiredEnv, isClientError, isCommandError, isEnvSet, isError, isNode, isServerError, isSuccess, make, raiseForCode, retryAsync, sleep, withRetry, withTimeLogging };
3204
3395
  //# sourceMappingURL=index.mjs.map
3205
3396
  //# sourceMappingURL=index.mjs.map