rl-rock 1.2.7 → 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
@@ -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 = {
@@ -1432,6 +1444,53 @@ var LinuxFileSystem = class extends FileSystem {
1432
1444
  }
1433
1445
  };
1434
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
+
1435
1494
  // src/sandbox/network.ts
1436
1495
  var logger4 = initLogger("rock.sandbox.network");
1437
1496
  var SpeedupType = /* @__PURE__ */ ((SpeedupType2) => {
@@ -1835,6 +1894,10 @@ var Sandbox = class extends AbstractSandbox {
1835
1894
  hostName = null;
1836
1895
  hostIp = null;
1837
1896
  cluster;
1897
+ // OSS-related properties
1898
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1899
+ ossBucket = null;
1900
+ ossTokenExpireTime = "";
1838
1901
  // Sub-components
1839
1902
  deploy;
1840
1903
  fs;
@@ -2222,7 +2285,7 @@ var Sandbox = class extends AbstractSandbox {
2222
2285
  async upload(request) {
2223
2286
  return this.uploadByPath(request.sourcePath, request.targetPath);
2224
2287
  }
2225
- async uploadByPath(sourcePath, targetPath) {
2288
+ async uploadByPath(sourcePath, targetPath, uploadMode = "auto") {
2226
2289
  const url = `${this.url}/upload`;
2227
2290
  const headers = this.buildHeaders();
2228
2291
  try {
@@ -2232,6 +2295,13 @@ var Sandbox = class extends AbstractSandbox {
2232
2295
  } catch {
2233
2296
  return { success: false, message: `File not found: ${sourcePath}` };
2234
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
+ }
2235
2305
  const fileBuffer = await fs.readFile(sourcePath);
2236
2306
  const fileName = sourcePath.split("/").pop() ?? "file";
2237
2307
  const response = await HttpUtils.postMultipart(
@@ -2248,6 +2318,136 @@ var Sandbox = class extends AbstractSandbox {
2248
2318
  return { success: false, message: `Upload failed: ${e}` };
2249
2319
  }
2250
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
+ }
2251
2451
  // Close
2252
2452
  async close() {
2253
2453
  await this.stop();
@@ -3191,6 +3391,6 @@ function getVersion() {
3191
3391
  }
3192
3392
  var VERSION = getVersion();
3193
3393
 
3194
- 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 };
3195
3395
  //# sourceMappingURL=index.mjs.map
3196
3396
  //# sourceMappingURL=index.mjs.map