rl-rock 1.2.5 → 1.2.7

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.js CHANGED
@@ -6,9 +6,10 @@ var zod = require('zod');
6
6
  var axios = require('axios');
7
7
  var https = require('https');
8
8
  var tsCaseConvert = require('ts-case-convert');
9
- var os = require('os');
10
9
  var winston = require('winston');
10
+ var os = require('os');
11
11
  var crypto = require('crypto');
12
+ var promises = require('fs/promises');
12
13
 
13
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
15
 
@@ -178,14 +179,6 @@ var RunMode = {
178
179
  NORMAL: "normal",
179
180
  NOHUP: "nohup"
180
181
  };
181
- var Constants = class {
182
- static BASE_URL_PRODUCT = "";
183
- static BASE_URL_ALIYUN = "";
184
- static BASE_URL_INNER = "";
185
- static BASE_URL_PRE = "";
186
- static BASE_URL_LOCAL = "";
187
- static REQUEST_TIMEOUT_SECONDS = 180;
188
- };
189
182
  var PID_PREFIX = "__ROCK_PID_START__";
190
183
  var PID_SUFFIX = "__ROCK_PID_END__";
191
184
 
@@ -263,6 +256,10 @@ var objectToCamel = tsCaseConvert.objectToCamel;
263
256
  var objectToSnake = tsCaseConvert.objectToSnake;
264
257
 
265
258
  // src/utils/http.ts
259
+ var sharedHttpsAgent = new https__default.default.Agent({
260
+ rejectUnauthorized: true,
261
+ keepAlive: true
262
+ });
266
263
  var HttpUtils = class {
267
264
  static defaultTimeout = 3e5;
268
265
  // 5 minutes
@@ -277,9 +274,7 @@ var HttpUtils = class {
277
274
  "Content-Type": "application/json",
278
275
  ...config?.headers
279
276
  },
280
- httpsAgent: new https__default.default.Agent({
281
- rejectUnauthorized: true
282
- })
277
+ httpsAgent: sharedHttpsAgent
283
278
  });
284
279
  }
285
280
  /**
@@ -308,9 +303,6 @@ var HttpUtils = class {
308
303
  }
309
304
  return httpResponse;
310
305
  } catch (error) {
311
- if (error instanceof axios.AxiosError) {
312
- throw new Error(`Failed to POST ${url}: ${error.message}`);
313
- }
314
306
  throw error;
315
307
  }
316
308
  }
@@ -335,9 +327,6 @@ var HttpUtils = class {
335
327
  }
336
328
  return httpResponse;
337
329
  } catch (error) {
338
- if (error instanceof axios.AxiosError) {
339
- throw new Error(`Failed to GET ${url}: ${error.message}`);
340
- }
341
330
  throw error;
342
331
  }
343
332
  }
@@ -417,9 +406,6 @@ var HttpUtils = class {
417
406
  }
418
407
  return httpResponse;
419
408
  } catch (error) {
420
- if (error instanceof axios.AxiosError) {
421
- throw new Error(`Failed to POST multipart ${url}: ${error.message}`);
422
- }
423
409
  throw error;
424
410
  }
425
411
  }
@@ -503,43 +489,12 @@ function withRetry(fn, options = {}) {
503
489
  });
504
490
  }
505
491
 
506
- // src/utils/deprecated.ts
507
- function deprecated(reason = "") {
508
- return function(target, propertyKey, descriptor) {
509
- const originalMethod = descriptor.value;
510
- descriptor.value = function(...args) {
511
- console.warn(
512
- `${String(propertyKey)} is deprecated. ${reason}`
513
- );
514
- return originalMethod.apply(this, args);
515
- };
516
- return descriptor;
517
- };
518
- }
519
- function deprecatedClass(reason = "") {
520
- return function(constructor) {
521
- return class extends constructor {
522
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
523
- constructor(...args) {
524
- console.warn(`${constructor.name} is deprecated. ${reason}`);
525
- super(...args);
526
- }
527
- };
528
- };
529
- }
530
-
531
492
  // src/utils/system.ts
532
493
  function isNode() {
533
494
  return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
534
495
  }
535
- function isBrowser() {
536
- return typeof globalThis !== "undefined" && "window" in globalThis && typeof globalThis.window !== "undefined";
537
- }
538
496
  function getEnv(key, defaultValue) {
539
- if (isNode()) {
540
- return process.env[key] ?? defaultValue;
541
- }
542
- return defaultValue;
497
+ return process.env[key] ?? defaultValue;
543
498
  }
544
499
  function getRequiredEnv(key) {
545
500
  const value = getEnv(key);
@@ -549,10 +504,7 @@ function getRequiredEnv(key) {
549
504
  return value;
550
505
  }
551
506
  function isEnvSet(key) {
552
- if (isNode()) {
553
- return key in process.env;
554
- }
555
- return false;
507
+ return key in process.env;
556
508
  }
557
509
  var envVars = {
558
510
  // Logging
@@ -565,25 +517,117 @@ var envVars = {
565
517
  get ROCK_LOGGING_LEVEL() {
566
518
  return getEnv("ROCK_LOGGING_LEVEL", "INFO");
567
519
  },
520
+ // Service
521
+ get ROCK_SERVICE_STATUS_DIR() {
522
+ return getEnv("ROCK_SERVICE_STATUS_DIR", "/data/service_status");
523
+ },
524
+ get ROCK_SCHEDULER_STATUS_DIR() {
525
+ return getEnv("ROCK_SCHEDULER_STATUS_DIR", "/data/scheduler_status");
526
+ },
527
+ // Config
528
+ get ROCK_CONFIG() {
529
+ return getEnv("ROCK_CONFIG");
530
+ },
531
+ get ROCK_CONFIG_DIR_NAME() {
532
+ return getEnv("ROCK_CONFIG_DIR_NAME", "rock-conf");
533
+ },
568
534
  // Base URLs
569
535
  get ROCK_BASE_URL() {
570
536
  return getEnv("ROCK_BASE_URL", "http://localhost:8080");
571
537
  },
538
+ get ROCK_WORKER_ROCKLET_PORT() {
539
+ const val = getEnv("ROCK_WORKER_ROCKLET_PORT");
540
+ return val ? parseInt(val, 10) : void 0;
541
+ },
572
542
  get ROCK_SANDBOX_STARTUP_TIMEOUT_SECONDS() {
573
543
  return parseInt(getEnv("ROCK_SANDBOX_STARTUP_TIMEOUT_SECONDS", "180"), 10);
574
544
  },
545
+ get ROCK_CODE_SANDBOX_BASE_URL() {
546
+ return getEnv("ROCK_CODE_SANDBOX_BASE_URL", "");
547
+ },
575
548
  // EnvHub
576
549
  get ROCK_ENVHUB_BASE_URL() {
577
550
  return getEnv("ROCK_ENVHUB_BASE_URL", "http://localhost:8081");
578
551
  },
552
+ get ROCK_ENVHUB_DEFAULT_DOCKER_IMAGE() {
553
+ return getEnv("ROCK_ENVHUB_DEFAULT_DOCKER_IMAGE", "python:3.11");
554
+ },
555
+ get ROCK_ENVHUB_DB_URL() {
556
+ return getEnv(
557
+ "ROCK_ENVHUB_DB_URL",
558
+ `sqlite:///${path.join(os.homedir(), ".rock", "rock_envs.db")}`
559
+ );
560
+ },
561
+ // Auto clear
562
+ get ROCK_DEFAULT_AUTO_CLEAR_TIME_MINUTES() {
563
+ return parseInt(getEnv("ROCK_DEFAULT_AUTO_CLEAR_TIME_MINUTES", "360"), 10);
564
+ },
565
+ // Ray
566
+ get ROCK_RAY_NAMESPACE() {
567
+ return getEnv("ROCK_RAY_NAMESPACE", "xrl-sandbox");
568
+ },
569
+ get ROCK_SANDBOX_EXPIRE_TIME_KEY() {
570
+ return getEnv("ROCK_SANDBOX_EXPIRE_TIME_KEY", "expire_time");
571
+ },
572
+ get ROCK_SANDBOX_AUTO_CLEAR_TIME_KEY() {
573
+ return getEnv("ROCK_SANDBOX_AUTO_CLEAR_TIME_KEY", "auto_clear_time");
574
+ },
575
+ // Timezone
576
+ get ROCK_TIME_ZONE() {
577
+ return getEnv("ROCK_TIME_ZONE", "Asia/Shanghai");
578
+ },
579
+ // OSS
580
+ get ROCK_OSS_ENABLE() {
581
+ return getEnv("ROCK_OSS_ENABLE", "false")?.toLowerCase() === "true";
582
+ },
583
+ get ROCK_OSS_BUCKET_ENDPOINT() {
584
+ return getEnv("ROCK_OSS_BUCKET_ENDPOINT");
585
+ },
586
+ get ROCK_OSS_BUCKET_NAME() {
587
+ return getEnv("ROCK_OSS_BUCKET_NAME");
588
+ },
589
+ get ROCK_OSS_BUCKET_REGION() {
590
+ return getEnv("ROCK_OSS_BUCKET_REGION");
591
+ },
579
592
  // Pip
580
593
  get ROCK_PIP_INDEX_URL() {
581
- return getEnv("ROCK_PIP_INDEX_URL", "https://mirrors.aliyun.com/pypi/simple/");
594
+ return getEnv("ROCK_PIP_INDEX_URL", "https://pypi.org/simple/");
595
+ },
596
+ // Monitor
597
+ get ROCK_MONITOR_ENABLE() {
598
+ return getEnv("ROCK_MONITOR_ENABLE", "false")?.toLowerCase() === "true";
599
+ },
600
+ // Project
601
+ get ROCK_PROJECT_ROOT() {
602
+ return getEnv("ROCK_PROJECT_ROOT", process.cwd());
603
+ },
604
+ get ROCK_WORKER_ENV_TYPE() {
605
+ return getEnv("ROCK_WORKER_ENV_TYPE", "local");
606
+ },
607
+ get ROCK_PYTHON_ENV_PATH() {
608
+ return getEnv("ROCK_PYTHON_ENV_PATH", process.cwd());
609
+ },
610
+ // Admin
611
+ get ROCK_ADMIN_ENV() {
612
+ return getEnv("ROCK_ADMIN_ENV", "dev");
613
+ },
614
+ get ROCK_ADMIN_ROLE() {
615
+ return getEnv("ROCK_ADMIN_ROLE", "write");
616
+ },
617
+ // CLI
618
+ get ROCK_CLI_LOAD_PATHS() {
619
+ return getEnv("ROCK_CLI_LOAD_PATHS", "");
620
+ },
621
+ get ROCK_CLI_DEFAULT_CONFIG_PATH() {
622
+ return getEnv("ROCK_CLI_DEFAULT_CONFIG_PATH", path.join(os.homedir(), ".rock", "config.ini"));
582
623
  },
583
624
  // Model Service
584
625
  get ROCK_MODEL_SERVICE_DATA_DIR() {
585
626
  return getEnv("ROCK_MODEL_SERVICE_DATA_DIR", "/data/logs");
586
627
  },
628
+ get ROCK_MODEL_SERVICE_TRAJ_APPEND_MODE() {
629
+ return getEnv("ROCK_MODEL_SERVICE_TRAJ_APPEND_MODE", "false")?.toLowerCase() === "true";
630
+ },
587
631
  // RuntimeEnv
588
632
  get ROCK_RTENV_PYTHON_V31114_INSTALL_CMD() {
589
633
  return getEnv(
@@ -612,11 +656,167 @@ var envVars = {
612
656
  return [];
613
657
  }
614
658
  },
659
+ get ROCK_AGENT_IFLOW_CLI_INSTALL_CMD() {
660
+ return getEnv("ROCK_AGENT_IFLOW_CLI_INSTALL_CMD", "npm i -g @iflow-ai/iflow-cli@latest");
661
+ },
615
662
  get ROCK_MODEL_SERVICE_INSTALL_CMD() {
616
663
  return getEnv("ROCK_MODEL_SERVICE_INSTALL_CMD", "pip install rl_rock[model-service]");
617
- }};
664
+ },
665
+ // Doccuum
666
+ get ROCK_DOCUUM_INSTALL_URL() {
667
+ return getEnv(
668
+ "ROCK_DOCUUM_INSTALL_URL",
669
+ "https://raw.githubusercontent.com/stepchowfun/docuum/main/install.sh"
670
+ );
671
+ },
672
+ // ========== Sandbox Defaults ==========
673
+ // Sandbox configuration defaults - allow users to override via environment variables
674
+ get ROCK_DEFAULT_IMAGE() {
675
+ return getEnv("ROCK_DEFAULT_IMAGE", "python:3.11");
676
+ },
677
+ get ROCK_DEFAULT_MEMORY() {
678
+ return getEnv("ROCK_DEFAULT_MEMORY", "8g");
679
+ },
680
+ get ROCK_DEFAULT_CPUS() {
681
+ return parseFloat(getEnv("ROCK_DEFAULT_CPUS", "2"));
682
+ },
683
+ get ROCK_DEFAULT_CLUSTER() {
684
+ return getEnv("ROCK_DEFAULT_CLUSTER", "zb");
685
+ },
686
+ get ROCK_DEFAULT_AUTO_CLEAR_SECONDS() {
687
+ return parseInt(getEnv("ROCK_DEFAULT_AUTO_CLEAR_SECONDS", "300"), 10);
688
+ },
689
+ // ========== SandboxGroup Defaults ==========
690
+ get ROCK_DEFAULT_GROUP_SIZE() {
691
+ return parseInt(getEnv("ROCK_DEFAULT_GROUP_SIZE", "2"), 10);
692
+ },
693
+ get ROCK_DEFAULT_START_CONCURRENCY() {
694
+ return parseInt(getEnv("ROCK_DEFAULT_START_CONCURRENCY", "2"), 10);
695
+ },
696
+ get ROCK_DEFAULT_START_RETRY_TIMES() {
697
+ return parseInt(getEnv("ROCK_DEFAULT_START_RETRY_TIMES", "3"), 10);
698
+ },
699
+ // ========== Client Timeouts (in seconds) ==========
700
+ get ROCK_DEFAULT_ARUN_TIMEOUT() {
701
+ return parseInt(getEnv("ROCK_DEFAULT_ARUN_TIMEOUT", "300"), 10);
702
+ },
703
+ get ROCK_DEFAULT_NOHUP_WAIT_TIMEOUT() {
704
+ return parseInt(getEnv("ROCK_DEFAULT_NOHUP_WAIT_TIMEOUT", "300"), 10);
705
+ },
706
+ get ROCK_DEFAULT_NOHUP_WAIT_INTERVAL() {
707
+ return parseInt(getEnv("ROCK_DEFAULT_NOHUP_WAIT_INTERVAL", "10"), 10);
708
+ },
709
+ get ROCK_DEFAULT_STATUS_CHECK_INTERVAL() {
710
+ return parseInt(getEnv("ROCK_DEFAULT_STATUS_CHECK_INTERVAL", "3"), 10);
711
+ }
712
+ };
713
+ var levels = {
714
+ error: 0,
715
+ warn: 1,
716
+ info: 2,
717
+ http: 3,
718
+ debug: 4
719
+ };
720
+ var colors = {
721
+ error: "red",
722
+ warn: "yellow",
723
+ info: "green",
724
+ http: "magenta",
725
+ debug: "cyan"
726
+ };
727
+ winston__default.default.addColors(colors);
728
+ var consoleFormat = winston__default.default.format.combine(
729
+ winston__default.default.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS" }),
730
+ winston__default.default.format.colorize({ all: true }),
731
+ winston__default.default.format.printf((info) => {
732
+ const { timestamp, level, message, ...meta } = info;
733
+ const metaStr = Object.keys(meta).length ? JSON.stringify(meta) : "";
734
+ return `${timestamp} ${level}: ${message} ${metaStr}`;
735
+ })
736
+ );
737
+ var fileFormat = winston__default.default.format.combine(
738
+ winston__default.default.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS" }),
739
+ winston__default.default.format.json()
740
+ );
741
+ function getLogLevel() {
742
+ const level = envVars.ROCK_LOGGING_LEVEL.toLowerCase();
743
+ if (level in levels) {
744
+ return level;
745
+ }
746
+ return "info";
747
+ }
748
+ var loggerContainer = new winston__default.default.Container();
749
+ function initLogger(name = "rock", fileName) {
750
+ if (loggerContainer.has(name)) {
751
+ return loggerContainer.get(name);
752
+ }
753
+ const transports = [];
754
+ const logLevel = getLogLevel();
755
+ const logPath = envVars.ROCK_LOGGING_PATH;
756
+ const logFileName = envVars.ROCK_LOGGING_FILE_NAME;
757
+ if (logPath) {
758
+ if (!fs.existsSync(logPath)) {
759
+ fs.mkdirSync(logPath, { recursive: true });
760
+ }
761
+ transports.push(
762
+ new winston__default.default.transports.File({
763
+ filename: path.join(logPath, logFileName),
764
+ format: fileFormat,
765
+ level: logLevel
766
+ })
767
+ );
768
+ } else {
769
+ transports.push(
770
+ new winston__default.default.transports.Console({
771
+ format: consoleFormat,
772
+ level: logLevel
773
+ })
774
+ );
775
+ }
776
+ const logger13 = loggerContainer.add(name, {
777
+ levels,
778
+ defaultMeta: { service: name },
779
+ transports
780
+ });
781
+ return logger13;
782
+ }
783
+ initLogger("rock");
618
784
 
619
- // src/envhub/schema.ts
785
+ // src/utils/deprecated.ts
786
+ var warnedKeys = /* @__PURE__ */ new Set();
787
+ function getLogger() {
788
+ return initLogger("rock.deprecated");
789
+ }
790
+ function warnOnce(key, message) {
791
+ if (warnedKeys.has(key)) {
792
+ return;
793
+ }
794
+ getLogger().warn(message);
795
+ warnedKeys.add(key);
796
+ }
797
+ function deprecated(reason = "") {
798
+ return function(target, propertyKey, descriptor) {
799
+ const originalMethod = descriptor.value;
800
+ const key = String(propertyKey);
801
+ descriptor.value = function(...args) {
802
+ warnOnce(key, `${key} is deprecated. ${reason}`);
803
+ return originalMethod.apply(this, args);
804
+ };
805
+ return descriptor;
806
+ };
807
+ }
808
+ function deprecatedClass(reason = "") {
809
+ return function(constructor) {
810
+ const key = constructor.name;
811
+ return class extends constructor {
812
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
813
+ constructor(...args) {
814
+ warnOnce(key, `${key} is deprecated. ${reason}`);
815
+ super(...args);
816
+ }
817
+ };
818
+ };
819
+ }
620
820
  var EnvHubClientConfigSchema = zod.z.object({
621
821
  baseUrl: zod.z.string().default(envVars.ROCK_ENVHUB_BASE_URL)
622
822
  });
@@ -745,104 +945,51 @@ var EnvHubClient = class {
745
945
  }
746
946
  }
747
947
  };
748
- var levels = {
749
- error: 0,
750
- warn: 1,
751
- info: 2,
752
- http: 3,
753
- debug: 4
754
- };
755
- var colors = {
756
- error: "red",
757
- warn: "yellow",
758
- info: "green",
759
- http: "magenta",
760
- debug: "cyan"
761
- };
762
- winston__default.default.addColors(colors);
763
- var consoleFormat = winston__default.default.format.combine(
764
- winston__default.default.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS" }),
765
- winston__default.default.format.colorize({ all: true }),
766
- winston__default.default.format.printf((info) => {
767
- const { timestamp, level, message, ...meta } = info;
768
- const metaStr = Object.keys(meta).length ? JSON.stringify(meta) : "";
769
- return `${timestamp} ${level}: ${message} ${metaStr}`;
770
- })
771
- );
772
- var fileFormat = winston__default.default.format.combine(
773
- winston__default.default.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS" }),
774
- winston__default.default.format.json()
775
- );
776
- function getLogLevel() {
777
- const level = envVars.ROCK_LOGGING_LEVEL.toLowerCase();
778
- if (level in levels) {
779
- return level;
780
- }
781
- return "info";
782
- }
783
- var loggerCache = /* @__PURE__ */ new Map();
784
- function initLogger(name = "rock", fileName) {
785
- if (loggerCache.has(name)) {
786
- return loggerCache.get(name);
787
- }
788
- const transports = [];
789
- const logLevel = getLogLevel();
790
- const logPath = envVars.ROCK_LOGGING_PATH;
791
- const logFileName = envVars.ROCK_LOGGING_FILE_NAME;
792
- if (logPath) {
793
- if (!fs.existsSync(logPath)) {
794
- fs.mkdirSync(logPath, { recursive: true });
795
- }
796
- transports.push(
797
- new winston__default.default.transports.File({
798
- filename: path.join(logPath, logFileName),
799
- format: fileFormat,
800
- level: logLevel
801
- })
802
- );
803
- } else {
804
- transports.push(
805
- new winston__default.default.transports.Console({
806
- format: consoleFormat,
807
- level: logLevel
808
- })
809
- );
810
- }
811
- const logger13 = winston__default.default.createLogger({
812
- levels,
813
- defaultMeta: { service: name },
814
- transports
815
- });
816
- loggerCache.set(name, logger13);
817
- return logger13;
818
- }
819
- initLogger("rock");
820
948
 
821
949
  // src/envs/rock_env.ts
822
950
  var logger = initLogger("rock.envs");
823
- var RockEnv = class {
951
+ var RockEnv = class _RockEnv {
824
952
  envId;
825
953
  sandboxId = null;
826
954
  isClosed = false;
827
- client;
828
955
  constructor(config) {
829
956
  this.envId = config.envId;
830
- this.client = axios__default.default.create({
831
- baseURL: envVars.ROCK_BASE_URL,
832
- timeout: 3e5,
833
- headers: { "Content-Type": "application/json" }
834
- });
957
+ }
958
+ /**
959
+ * Create and initialize a RockEnv instance
960
+ *
961
+ * @param config - Environment configuration
962
+ * @returns Initialized RockEnv instance
963
+ */
964
+ static async create(config) {
965
+ const env = new _RockEnv(config);
835
966
  try {
836
- this.initializeEnvironment();
967
+ await env.initializeEnvironment();
837
968
  } catch (e) {
838
969
  throw new Error(`Failed to initialize environment: ${e}`);
839
970
  }
971
+ return env;
972
+ }
973
+ /**
974
+ * Get the sandbox ID
975
+ */
976
+ getSandboxId() {
977
+ return this.sandboxId;
840
978
  }
841
979
  /**
842
980
  * Initialize environment instance
843
981
  */
844
- initializeEnvironment() {
982
+ async initializeEnvironment() {
845
983
  logger.debug(`Initializing environment: ${this.envId}`);
984
+ const response = await HttpUtils.post(
985
+ `${envVars.ROCK_BASE_URL}/apis/v1/envs/gem/make`,
986
+ { "Content-Type": "application/json" },
987
+ { envId: this.envId }
988
+ );
989
+ this.sandboxId = response.result?.sandboxId ?? null;
990
+ if (!this.sandboxId) {
991
+ throw new Error("Failed to get environment instance ID");
992
+ }
846
993
  }
847
994
  /**
848
995
  * Execute an action step
@@ -852,19 +999,12 @@ var RockEnv = class {
852
999
  */
853
1000
  async step(action) {
854
1001
  this.ensureNotClosed();
855
- const params = {
856
- sandbox_id: this.sandboxId,
857
- action
858
- };
859
- try {
860
- const response = await this.client.post(
861
- "/apis/v1/envs/gem/step",
862
- params
863
- );
864
- return this.parseStepResult(response.data);
865
- } catch (e) {
866
- throw new Error(`Failed to execute step with action ${action}: ${e}`);
867
- }
1002
+ const response = await HttpUtils.post(
1003
+ `${envVars.ROCK_BASE_URL}/apis/v1/envs/gem/step`,
1004
+ { "Content-Type": "application/json" },
1005
+ { sandboxId: this.sandboxId, action }
1006
+ );
1007
+ return this.parseStepResult(response.result);
868
1008
  }
869
1009
  /**
870
1010
  * Reset environment to initial state
@@ -874,19 +1014,16 @@ var RockEnv = class {
874
1014
  */
875
1015
  async reset(seed) {
876
1016
  this.ensureNotClosed();
877
- const params = { sandbox_id: this.sandboxId };
1017
+ const params = { sandboxId: this.sandboxId };
878
1018
  if (seed !== void 0) {
879
1019
  params.seed = seed;
880
1020
  }
881
- try {
882
- const response = await this.client.post(
883
- "/apis/v1/envs/gem/reset",
884
- params
885
- );
886
- return this.parseResetResult(response.data);
887
- } catch (e) {
888
- throw new Error(`Failed to reset environment: ${e}`);
889
- }
1021
+ const response = await HttpUtils.post(
1022
+ `${envVars.ROCK_BASE_URL}/apis/v1/envs/gem/reset`,
1023
+ { "Content-Type": "application/json" },
1024
+ params
1025
+ );
1026
+ return this.parseResetResult(response.result);
890
1027
  }
891
1028
  /**
892
1029
  * Close environment and clean up resources
@@ -896,9 +1033,11 @@ var RockEnv = class {
896
1033
  return;
897
1034
  }
898
1035
  try {
899
- await this.client.post("/apis/v1/envs/gem/close", {
900
- sandbox_id: this.sandboxId
901
- });
1036
+ await HttpUtils.post(
1037
+ `${envVars.ROCK_BASE_URL}/apis/v1/envs/gem/close`,
1038
+ { "Content-Type": "application/json" },
1039
+ { sandboxId: this.sandboxId }
1040
+ );
902
1041
  } catch (e) {
903
1042
  throw new Error(`Failed to close environment: ${e}`);
904
1043
  } finally {
@@ -910,6 +1049,9 @@ var RockEnv = class {
910
1049
  * Parse step result from API response
911
1050
  */
912
1051
  parseStepResult(data) {
1052
+ if (!data) {
1053
+ throw new Error("Invalid step result: no data");
1054
+ }
913
1055
  return [
914
1056
  data.observation,
915
1057
  data.reward,
@@ -922,6 +1064,9 @@ var RockEnv = class {
922
1064
  * Parse reset result from API response
923
1065
  */
924
1066
  parseResetResult(data) {
1067
+ if (!data) {
1068
+ throw new Error("Invalid reset result: no data");
1069
+ }
925
1070
  return [data.observation, data.info];
926
1071
  }
927
1072
  /**
@@ -935,30 +1080,30 @@ var RockEnv = class {
935
1080
  };
936
1081
 
937
1082
  // src/envs/registration.ts
938
- function make(envId, options) {
939
- return new RockEnv({ envId, ...options });
1083
+ async function make(envId, options) {
1084
+ return RockEnv.create({ envId, ...options });
940
1085
  }
941
1086
  var BaseConfigSchema = zod.z.object({
942
- baseUrl: zod.z.string().default(envVars.ROCK_BASE_URL),
1087
+ baseUrl: zod.z.string().default(() => envVars.ROCK_BASE_URL),
943
1088
  xrlAuthorization: zod.z.string().optional(),
944
1089
  extraHeaders: zod.z.record(zod.z.string()).default({})
945
1090
  });
946
1091
  var SandboxConfigSchema = BaseConfigSchema.extend({
947
- image: zod.z.string().default("python:3.11"),
948
- autoClearSeconds: zod.z.number().default(300),
1092
+ image: zod.z.string().default(() => envVars.ROCK_DEFAULT_IMAGE),
1093
+ autoClearSeconds: zod.z.number().default(() => envVars.ROCK_DEFAULT_AUTO_CLEAR_SECONDS),
949
1094
  routeKey: zod.z.string().optional(),
950
- startupTimeout: zod.z.number().default(envVars.ROCK_SANDBOX_STARTUP_TIMEOUT_SECONDS),
951
- memory: zod.z.string().default("8g"),
952
- cpus: zod.z.number().default(2),
1095
+ startupTimeout: zod.z.number().default(() => envVars.ROCK_SANDBOX_STARTUP_TIMEOUT_SECONDS),
1096
+ memory: zod.z.string().default(() => envVars.ROCK_DEFAULT_MEMORY),
1097
+ cpus: zod.z.number().default(() => envVars.ROCK_DEFAULT_CPUS),
953
1098
  userId: zod.z.string().optional(),
954
1099
  experimentId: zod.z.string().optional(),
955
- cluster: zod.z.string().default("zb"),
1100
+ cluster: zod.z.string().default(() => envVars.ROCK_DEFAULT_CLUSTER),
956
1101
  namespace: zod.z.string().optional()
957
1102
  });
958
1103
  var SandboxGroupConfigSchema = SandboxConfigSchema.extend({
959
- size: zod.z.number().default(2),
960
- startConcurrency: zod.z.number().default(2),
961
- startRetryTimes: zod.z.number().default(3)
1104
+ size: zod.z.number().default(() => envVars.ROCK_DEFAULT_GROUP_SIZE),
1105
+ startConcurrency: zod.z.number().default(() => envVars.ROCK_DEFAULT_START_CONCURRENCY),
1106
+ startRetryTimes: zod.z.number().default(() => envVars.ROCK_DEFAULT_START_RETRY_TIMES)
962
1107
  });
963
1108
  function createSandboxConfig(config) {
964
1109
  return SandboxConfigSchema.parse(config ?? {});
@@ -1031,14 +1176,6 @@ var Deploy = class {
1031
1176
  }
1032
1177
  };
1033
1178
 
1034
- // src/sandbox/types.ts
1035
- var SpeedupType = /* @__PURE__ */ ((SpeedupType2) => {
1036
- SpeedupType2["APT"] = "apt";
1037
- SpeedupType2["PIP"] = "pip";
1038
- SpeedupType2["GITHUB"] = "github";
1039
- return SpeedupType2;
1040
- })(SpeedupType || {});
1041
-
1042
1179
  // src/utils/shell.ts
1043
1180
  function shellQuote(str) {
1044
1181
  if (str === "") {
@@ -1301,6 +1438,12 @@ var LinuxFileSystem = class extends FileSystem {
1301
1438
 
1302
1439
  // src/sandbox/network.ts
1303
1440
  var logger4 = initLogger("rock.sandbox.network");
1441
+ var SpeedupType = /* @__PURE__ */ ((SpeedupType2) => {
1442
+ SpeedupType2["APT"] = "apt";
1443
+ SpeedupType2["PIP"] = "pip";
1444
+ SpeedupType2["GITHUB"] = "github";
1445
+ return SpeedupType2;
1446
+ })(SpeedupType || {});
1304
1447
  var Network = class {
1305
1448
  sandbox;
1306
1449
  constructor(sandbox) {
@@ -1940,13 +2083,6 @@ var Sandbox = class extends AbstractSandbox {
1940
2083
  } = options;
1941
2084
  const sessionName = session ?? "default";
1942
2085
  if (mode === "normal") {
1943
- try {
1944
- await this.createSession({ session: sessionName, startupSource: [], envEnable: false });
1945
- } catch (e) {
1946
- if (String(e).includes("already exists")) ; else {
1947
- throw e;
1948
- }
1949
- }
1950
2086
  return this.runInSession({ command: cmd, session: sessionName, timeout });
1951
2087
  }
1952
2088
  return this.arunWithNohup(cmd, options);
@@ -1986,13 +2122,12 @@ var Sandbox = class extends AbstractSandbox {
1986
2122
  outputFile
1987
2123
  } = options;
1988
2124
  const timestamp = Date.now();
1989
- const tmpSession = session ?? `bash-${timestamp}`;
1990
- try {
2125
+ let tmpSession;
2126
+ if (session === void 0 || session === null) {
2127
+ tmpSession = `bash-${timestamp}`;
1991
2128
  await this.createSession({ session: tmpSession, startupSource: [], envEnable: false });
1992
- } catch (e) {
1993
- if (!String(e).includes("already exists")) {
1994
- throw e;
1995
- }
2129
+ } else {
2130
+ tmpSession = session;
1996
2131
  }
1997
2132
  const tmpFile = outputFile ?? `/tmp/tmp_${timestamp}.out`;
1998
2133
  const nohupCommand = `nohup ${cmd} < /dev/null > ${tmpFile} 2>&1 & echo __ROCK_PID_START__$!__ROCK_PID_END__;disown`;
@@ -2095,11 +2230,13 @@ var Sandbox = class extends AbstractSandbox {
2095
2230
  const url = `${this.url}/upload`;
2096
2231
  const headers = this.buildHeaders();
2097
2232
  try {
2098
- const fs = await import('fs');
2099
- if (!fs.existsSync(sourcePath)) {
2233
+ const fs = await import('fs/promises');
2234
+ try {
2235
+ await fs.access(sourcePath);
2236
+ } catch {
2100
2237
  return { success: false, message: `File not found: ${sourcePath}` };
2101
2238
  }
2102
- const fileBuffer = fs.readFileSync(sourcePath);
2239
+ const fileBuffer = await fs.readFile(sourcePath);
2103
2240
  const fileName = sourcePath.split("/").pop() ?? "file";
2104
2241
  const response = await HttpUtils.postMultipart(
2105
2242
  url,
@@ -2207,7 +2344,7 @@ var ModelClient = class {
2207
2344
  const content = this.constructResponse(lastResponse, index);
2208
2345
  const lastResponseLine = await this.readLastResponseLine();
2209
2346
  if (lastResponseLine === null) {
2210
- this.appendResponse(content);
2347
+ await this.appendResponse(content);
2211
2348
  return;
2212
2349
  }
2213
2350
  const { meta } = this.parseResponseLine(lastResponseLine);
@@ -2219,7 +2356,7 @@ var ModelClient = class {
2219
2356
  logger9.debug(`response index ${index} already exists, skip`);
2220
2357
  return;
2221
2358
  }
2222
- this.appendResponse(content);
2359
+ await this.appendResponse(content);
2223
2360
  }
2224
2361
  /**
2225
2362
  * Pop request from log file
@@ -2251,8 +2388,13 @@ var ModelClient = class {
2251
2388
  logger9.debug(`Last request is not the index ${index} we want, waiting...`);
2252
2389
  await sleep(1e3);
2253
2390
  } catch (e) {
2254
- if (e instanceof Error && e.message.includes("aborted")) {
2255
- throw e;
2391
+ if (e instanceof Error) {
2392
+ if (e.message.includes("aborted")) {
2393
+ throw e;
2394
+ }
2395
+ if (e.message.includes("Invalid request line format")) {
2396
+ throw e;
2397
+ }
2256
2398
  }
2257
2399
  logger9.debug(`Error reading request: ${e}, waiting...`);
2258
2400
  await sleep(1e3);
@@ -2280,7 +2422,7 @@ var ModelClient = class {
2280
2422
  await sleep(1e3);
2281
2423
  continue;
2282
2424
  }
2283
- const content = fs.readFileSync(this.logFile, "utf-8");
2425
+ const content = await promises.readFile(this.logFile, "utf-8");
2284
2426
  const lines = content.split("\n").filter((l) => l.trim());
2285
2427
  if (lines.length === 0) {
2286
2428
  logger9.debug(`Log file ${this.logFile} is empty, waiting for the first request...`);
@@ -2294,21 +2436,31 @@ var ModelClient = class {
2294
2436
  if (lineContent.includes(SESSION_END_MARKER)) {
2295
2437
  return { requestJson: SESSION_END_MARKER, meta: {} };
2296
2438
  }
2297
- const parts = lineContent.split(REQUEST_END_MARKER);
2298
- const metaJson = parts[1] ?? "";
2299
- const requestJson = parts[0]?.split(REQUEST_START_MARKER)[1] ?? "";
2300
- const meta = JSON.parse(metaJson);
2301
- return { requestJson, meta };
2439
+ try {
2440
+ const parts = lineContent.split(REQUEST_END_MARKER);
2441
+ const metaJson = parts[1] ?? "";
2442
+ const requestJson = parts[0]?.split(REQUEST_START_MARKER)[1] ?? "";
2443
+ const meta = JSON.parse(metaJson);
2444
+ return { requestJson, meta };
2445
+ } catch (e) {
2446
+ logger9.error(`Failed to parse request line: ${lineContent}, error: ${e}`);
2447
+ throw new Error(`Invalid request line format: ${e}`);
2448
+ }
2302
2449
  }
2303
2450
  parseResponseLine(lineContent) {
2304
- const parts = lineContent.split(RESPONSE_END_MARKER);
2305
- const metaJson = parts[1] ?? "";
2306
- const responseJson = parts[0]?.split(RESPONSE_START_MARKER)[1] ?? "";
2307
- const meta = JSON.parse(metaJson);
2308
- return { responseJson, meta };
2451
+ try {
2452
+ const parts = lineContent.split(RESPONSE_END_MARKER);
2453
+ const metaJson = parts[1] ?? "";
2454
+ const responseJson = parts[0]?.split(RESPONSE_START_MARKER)[1] ?? "";
2455
+ const meta = JSON.parse(metaJson);
2456
+ return { responseJson, meta };
2457
+ } catch (e) {
2458
+ logger9.error(`Failed to parse response line: ${lineContent}, error: ${e}`);
2459
+ throw new Error(`Invalid response line format: ${e}`);
2460
+ }
2309
2461
  }
2310
2462
  async readLastRequestLine() {
2311
- const content = fs.readFileSync(this.logFile, "utf-8");
2463
+ const content = await promises.readFile(this.logFile, "utf-8");
2312
2464
  const lines = content.split("\n").filter((l) => l.trim());
2313
2465
  for (let i = lines.length - 1; i >= 0; i--) {
2314
2466
  const line = lines[i];
@@ -2319,7 +2471,7 @@ var ModelClient = class {
2319
2471
  throw new Error(`No request found in log file ${this.logFile}`);
2320
2472
  }
2321
2473
  async readLastResponseLine() {
2322
- const content = fs.readFileSync(this.logFile, "utf-8");
2474
+ const content = await promises.readFile(this.logFile, "utf-8");
2323
2475
  const lines = content.split("\n").filter((l) => l.trim());
2324
2476
  for (let i = lines.length - 1; i >= 0; i--) {
2325
2477
  const line = lines[i];
@@ -2329,8 +2481,8 @@ var ModelClient = class {
2329
2481
  }
2330
2482
  return null;
2331
2483
  }
2332
- appendResponse(content) {
2333
- fs.appendFileSync(this.logFile, content);
2484
+ async appendResponse(content) {
2485
+ await promises.appendFile(this.logFile, content);
2334
2486
  }
2335
2487
  constructResponse(lastResponse, index) {
2336
2488
  const meta = {
@@ -3059,7 +3211,6 @@ exports.Codes = Codes;
3059
3211
  exports.CommandResponseSchema = CommandResponseSchema;
3060
3212
  exports.CommandRockError = CommandRockError;
3061
3213
  exports.CommandSchema = CommandSchema;
3062
- exports.Constants = Constants;
3063
3214
  exports.CreateBashSessionRequestSchema = CreateBashSessionRequestSchema;
3064
3215
  exports.CreateSessionResponseSchema = CreateSessionResponseSchema;
3065
3216
  exports.DefaultAgent = DefaultAgent;
@@ -3124,7 +3275,6 @@ exports.getDefaultPipIndexUrl = getDefaultPipIndexUrl;
3124
3275
  exports.getEnv = getEnv;
3125
3276
  exports.getReasonPhrase = getReasonPhrase;
3126
3277
  exports.getRequiredEnv = getRequiredEnv;
3127
- exports.isBrowser = isBrowser;
3128
3278
  exports.isClientError = isClientError;
3129
3279
  exports.isCommandError = isCommandError;
3130
3280
  exports.isEnvSet = isEnvSet;