rl-rock 1.2.1

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 ADDED
@@ -0,0 +1,1950 @@
1
+ import { z } from 'zod';
2
+ import axios3, { AxiosError } from 'axios';
3
+ import https from 'https';
4
+ import 'os';
5
+ import { join, resolve } from 'path';
6
+ import winston from 'winston';
7
+ import { existsSync, mkdirSync, statSync, readFileSync, appendFileSync } from 'fs';
8
+ import { randomUUID } from 'crypto';
9
+ import { spawn } from 'child_process';
10
+
11
+ // src/types/codes.ts
12
+ var Codes = /* @__PURE__ */ ((Codes2) => {
13
+ Codes2[Codes2["OK"] = 2e3] = "OK";
14
+ Codes2[Codes2["BAD_REQUEST"] = 4e3] = "BAD_REQUEST";
15
+ Codes2[Codes2["INTERNAL_SERVER_ERROR"] = 5e3] = "INTERNAL_SERVER_ERROR";
16
+ Codes2[Codes2["COMMAND_ERROR"] = 6e3] = "COMMAND_ERROR";
17
+ return Codes2;
18
+ })(Codes || {});
19
+ var ReasonPhrases = {
20
+ [2e3 /* OK */]: "OK",
21
+ [4e3 /* BAD_REQUEST */]: "Bad Request",
22
+ [5e3 /* INTERNAL_SERVER_ERROR */]: "Internal Server Error",
23
+ [6e3 /* COMMAND_ERROR */]: "Command Error"
24
+ };
25
+ function getReasonPhrase(code) {
26
+ return ReasonPhrases[code] ?? "";
27
+ }
28
+ function isSuccess(code) {
29
+ return code >= 2e3 && code <= 2999;
30
+ }
31
+ function isClientError(code) {
32
+ return code >= 4e3 && code <= 4999;
33
+ }
34
+ function isServerError(code) {
35
+ return code >= 5e3 && code <= 5999;
36
+ }
37
+ function isCommandError(code) {
38
+ return code >= 6e3 && code <= 6999;
39
+ }
40
+ function isError(code) {
41
+ return code >= 4e3 && code <= 6999;
42
+ }
43
+ var CommandSchema = z.object({
44
+ command: z.union([z.string(), z.array(z.string())]),
45
+ timeout: z.number().optional().default(1200),
46
+ env: z.record(z.string()).optional(),
47
+ cwd: z.string().optional()
48
+ });
49
+ var CreateBashSessionRequestSchema = z.object({
50
+ session: z.string().default("default"),
51
+ startupSource: z.array(z.string()).default([]),
52
+ envEnable: z.boolean().default(false),
53
+ env: z.record(z.string()).optional(),
54
+ remoteUser: z.string().optional()
55
+ });
56
+ var BashActionSchema = z.object({
57
+ command: z.string(),
58
+ session: z.string().default("default"),
59
+ timeout: z.number().optional(),
60
+ check: z.enum(["silent", "raise", "ignore"]).default("raise")
61
+ });
62
+ var WriteFileRequestSchema = z.object({
63
+ content: z.string(),
64
+ path: z.string()
65
+ });
66
+ var ReadFileRequestSchema = z.object({
67
+ path: z.string(),
68
+ encoding: z.string().optional(),
69
+ errors: z.string().optional()
70
+ });
71
+ var UploadRequestSchema = z.object({
72
+ sourcePath: z.string(),
73
+ targetPath: z.string()
74
+ });
75
+ var CloseSessionRequestSchema = z.object({
76
+ session: z.string().default("default")
77
+ });
78
+ var ChownRequestSchema = z.object({
79
+ remoteUser: z.string(),
80
+ paths: z.array(z.string()).default([]),
81
+ recursive: z.boolean().default(false)
82
+ });
83
+ var ChmodRequestSchema = z.object({
84
+ paths: z.array(z.string()).default([]),
85
+ mode: z.string().default("755"),
86
+ recursive: z.boolean().default(false)
87
+ });
88
+ var SandboxResponseSchema = z.object({
89
+ code: z.nativeEnum(Codes).optional(),
90
+ exitCode: z.number().optional(),
91
+ failureReason: z.string().optional()
92
+ });
93
+ var IsAliveResponseSchema = z.object({
94
+ isAlive: z.boolean(),
95
+ message: z.string().default("")
96
+ });
97
+ var SandboxStatusResponseSchema = z.object({
98
+ sandboxId: z.string().optional(),
99
+ status: z.record(z.unknown()).optional(),
100
+ portMapping: z.record(z.unknown()).optional(),
101
+ hostName: z.string().optional(),
102
+ hostIp: z.string().optional(),
103
+ isAlive: z.boolean().default(true),
104
+ image: z.string().optional(),
105
+ gatewayVersion: z.string().optional(),
106
+ sweRexVersion: z.string().optional(),
107
+ userId: z.string().optional(),
108
+ experimentId: z.string().optional(),
109
+ namespace: z.string().optional(),
110
+ cpus: z.number().optional(),
111
+ memory: z.string().optional()
112
+ });
113
+ var CommandResponseSchema = z.object({
114
+ stdout: z.string().default(""),
115
+ stderr: z.string().default(""),
116
+ exitCode: z.number().optional()
117
+ });
118
+ var WriteFileResponseSchema = z.object({
119
+ success: z.boolean().default(false),
120
+ message: z.string().default("")
121
+ });
122
+ var ReadFileResponseSchema = z.object({
123
+ content: z.string().default("")
124
+ });
125
+ var UploadResponseSchema = z.object({
126
+ success: z.boolean().default(false),
127
+ message: z.string().default(""),
128
+ fileName: z.string().optional()
129
+ });
130
+ var ObservationSchema = z.object({
131
+ output: z.string().default(""),
132
+ exitCode: z.number().optional(),
133
+ failureReason: z.string().default(""),
134
+ expectString: z.string().default("")
135
+ });
136
+ var CreateSessionResponseSchema = z.object({
137
+ output: z.string().default("")
138
+ });
139
+ var CloseSessionResponseSchema = z.object({});
140
+ var CloseResponseSchema = z.object({});
141
+ var ChownResponseSchema = z.object({
142
+ success: z.boolean().default(false),
143
+ message: z.string().default("")
144
+ });
145
+ var ChmodResponseSchema = z.object({
146
+ success: z.boolean().default(false),
147
+ message: z.string().default("")
148
+ });
149
+ var ExecuteBashSessionResponseSchema = z.object({
150
+ success: z.boolean().default(false),
151
+ message: z.string().default("")
152
+ });
153
+ var OssSetupResponseSchema = z.object({
154
+ success: z.boolean().default(false),
155
+ message: z.string().default("")
156
+ });
157
+
158
+ // src/common/constants.ts
159
+ var RunMode = {
160
+ NORMAL: "normal",
161
+ NOHUP: "nohup"
162
+ };
163
+ var Constants = class {
164
+ static BASE_URL_PRODUCT = "";
165
+ static BASE_URL_ALIYUN = "";
166
+ static BASE_URL_INNER = "";
167
+ static BASE_URL_PRE = "";
168
+ static BASE_URL_LOCAL = "";
169
+ static REQUEST_TIMEOUT_SECONDS = 180;
170
+ };
171
+ var PID_PREFIX = "__ROCK_PID_START__";
172
+ var PID_SUFFIX = "__ROCK_PID_END__";
173
+
174
+ // src/common/exceptions.ts
175
+ var RockException = class extends Error {
176
+ _code = null;
177
+ constructor(message, code) {
178
+ super(message);
179
+ this.name = "RockException";
180
+ this._code = code ?? null;
181
+ }
182
+ get code() {
183
+ return this._code;
184
+ }
185
+ };
186
+ var InvalidParameterRockException = class extends RockException {
187
+ constructor(message) {
188
+ super(message);
189
+ this.name = "InvalidParameterRockException";
190
+ }
191
+ };
192
+ var BadRequestRockError = class extends RockException {
193
+ constructor(message, code = 4e3 /* BAD_REQUEST */) {
194
+ super(message, code);
195
+ this.name = "BadRequestRockError";
196
+ }
197
+ };
198
+ var InternalServerRockError = class extends RockException {
199
+ constructor(message, code = 5e3 /* INTERNAL_SERVER_ERROR */) {
200
+ super(message, code);
201
+ this.name = "InternalServerRockError";
202
+ }
203
+ };
204
+ var CommandRockError = class extends RockException {
205
+ constructor(message, code = 6e3 /* COMMAND_ERROR */) {
206
+ super(message, code);
207
+ this.name = "CommandRockError";
208
+ }
209
+ };
210
+ function raiseForCode(code, message) {
211
+ if (code === null || code === void 0 || isSuccessCode(code)) {
212
+ return;
213
+ }
214
+ if (isClientErrorCode(code)) {
215
+ throw new BadRequestRockError(message, code);
216
+ }
217
+ if (isServerErrorCode(code)) {
218
+ throw new InternalServerRockError(message, code);
219
+ }
220
+ if (isCommandErrorCode(code)) {
221
+ throw new CommandRockError(message, code);
222
+ }
223
+ throw new RockException(message, code);
224
+ }
225
+ function fromRockException(e) {
226
+ return {
227
+ code: e.code ?? void 0,
228
+ exitCode: 1,
229
+ failureReason: e.message
230
+ };
231
+ }
232
+ function isSuccessCode(code) {
233
+ return code >= 2e3 && code <= 2999;
234
+ }
235
+ function isClientErrorCode(code) {
236
+ return code >= 4e3 && code <= 4999;
237
+ }
238
+ function isServerErrorCode(code) {
239
+ return code >= 5e3 && code <= 5999;
240
+ }
241
+ function isCommandErrorCode(code) {
242
+ return code >= 6e3 && code <= 6999;
243
+ }
244
+ var HttpUtils = class {
245
+ static defaultTimeout = 3e5;
246
+ // 5 minutes
247
+ static defaultConnectTimeout = 3e5;
248
+ /**
249
+ * Create axios instance with default config
250
+ */
251
+ static createClient(config) {
252
+ return axios3.create({
253
+ timeout: config?.timeout ?? this.defaultTimeout,
254
+ headers: {
255
+ "Content-Type": "application/json",
256
+ ...config?.headers
257
+ },
258
+ httpsAgent: new https.Agent({
259
+ rejectUnauthorized: true
260
+ })
261
+ });
262
+ }
263
+ /**
264
+ * Send POST request
265
+ */
266
+ static async post(url, headers, data, readTimeout) {
267
+ const client = this.createClient({
268
+ timeout: readTimeout ?? this.defaultTimeout,
269
+ headers
270
+ });
271
+ try {
272
+ const response = await client.post(url, data);
273
+ return response.data;
274
+ } catch (error) {
275
+ if (error instanceof AxiosError) {
276
+ throw new Error(`Failed to POST ${url}: ${error.message}`);
277
+ }
278
+ throw error;
279
+ }
280
+ }
281
+ /**
282
+ * Send GET request
283
+ */
284
+ static async get(url, headers) {
285
+ const client = this.createClient({ headers });
286
+ try {
287
+ const response = await client.get(url);
288
+ return response.data;
289
+ } catch (error) {
290
+ if (error instanceof AxiosError) {
291
+ throw new Error(`Failed to GET ${url}: ${error.message}`);
292
+ }
293
+ throw error;
294
+ }
295
+ }
296
+ /**
297
+ * Send multipart/form-data request
298
+ */
299
+ static async postMultipart(url, headers, data, files) {
300
+ const formData = new FormData();
301
+ if (data) {
302
+ for (const [key, value] of Object.entries(data)) {
303
+ if (value !== void 0 && value !== null) {
304
+ formData.append(key, String(value));
305
+ }
306
+ }
307
+ }
308
+ if (files) {
309
+ for (const [fieldName, fileData] of Object.entries(files)) {
310
+ if (fileData !== void 0 && fileData !== null) {
311
+ if (Array.isArray(fileData)) {
312
+ const [filename, content, contentType] = fileData;
313
+ const blob = new Blob([content], { type: contentType });
314
+ formData.append(fieldName, blob, filename);
315
+ } else if (fileData instanceof Buffer) {
316
+ const blob = new Blob([fileData], { type: "application/octet-stream" });
317
+ formData.append(fieldName, blob, "file");
318
+ } else if (fileData instanceof File) {
319
+ formData.append(fieldName, fileData);
320
+ }
321
+ }
322
+ }
323
+ }
324
+ const client = this.createClient({
325
+ headers: {
326
+ ...headers,
327
+ "Content-Type": "multipart/form-data"
328
+ }
329
+ });
330
+ try {
331
+ const response = await client.post(url, formData);
332
+ return response.data;
333
+ } catch (error) {
334
+ if (error instanceof AxiosError) {
335
+ throw new Error(`Failed to POST multipart ${url}: ${error.message}`);
336
+ }
337
+ throw error;
338
+ }
339
+ }
340
+ /**
341
+ * Guess MIME type from filename
342
+ */
343
+ static guessContentType(filename) {
344
+ const ext = filename.split(".").pop()?.toLowerCase();
345
+ const mimeTypes = {
346
+ txt: "text/plain",
347
+ html: "text/html",
348
+ css: "text/css",
349
+ js: "application/javascript",
350
+ json: "application/json",
351
+ xml: "application/xml",
352
+ pdf: "application/pdf",
353
+ zip: "application/zip",
354
+ tar: "application/x-tar",
355
+ gz: "application/gzip",
356
+ png: "image/png",
357
+ jpg: "image/jpeg",
358
+ jpeg: "image/jpeg",
359
+ gif: "image/gif",
360
+ svg: "image/svg+xml"
361
+ };
362
+ return mimeTypes[ext ?? ""] ?? "application/octet-stream";
363
+ }
364
+ };
365
+
366
+ // src/utils/retry.ts
367
+ function retryAsync(fn, options = {}) {
368
+ const {
369
+ maxAttempts = 3,
370
+ delaySeconds = 1,
371
+ backoff = 1,
372
+ jitter = false
373
+ } = options;
374
+ return retryAsyncImpl(fn, {
375
+ maxAttempts,
376
+ delaySeconds,
377
+ backoff,
378
+ jitter
379
+ });
380
+ }
381
+ async function retryAsyncImpl(fn, options) {
382
+ const { maxAttempts, delaySeconds, backoff, jitter } = options;
383
+ let lastError = null;
384
+ let currentDelay = delaySeconds;
385
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
386
+ try {
387
+ return await fn();
388
+ } catch (e) {
389
+ lastError = e instanceof Error ? e : new Error(String(e));
390
+ if (attempt === maxAttempts) {
391
+ break;
392
+ }
393
+ let sleepTime = currentDelay;
394
+ if (jitter) {
395
+ sleepTime = Math.random() * currentDelay * 2;
396
+ }
397
+ await sleep(sleepTime * 1e3);
398
+ currentDelay *= backoff;
399
+ }
400
+ }
401
+ throw lastError ?? new Error("All retry attempts failed");
402
+ }
403
+ function sleep(ms) {
404
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
405
+ }
406
+ function withRetry(fn, options = {}) {
407
+ return (async (...args) => {
408
+ return retryAsync(() => fn(...args), options);
409
+ });
410
+ }
411
+
412
+ // src/utils/deprecated.ts
413
+ function deprecated(reason = "") {
414
+ return function(target, propertyKey, descriptor) {
415
+ const originalMethod = descriptor.value;
416
+ descriptor.value = function(...args) {
417
+ console.warn(
418
+ `${String(propertyKey)} is deprecated. ${reason}`
419
+ );
420
+ return originalMethod.apply(this, args);
421
+ };
422
+ return descriptor;
423
+ };
424
+ }
425
+ function deprecatedClass(reason = "") {
426
+ return function(constructor) {
427
+ return class extends constructor {
428
+ constructor(...args) {
429
+ console.warn(`${constructor.name} is deprecated. ${reason}`);
430
+ super(...args);
431
+ }
432
+ };
433
+ };
434
+ }
435
+
436
+ // src/utils/system.ts
437
+ function isNode() {
438
+ return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
439
+ }
440
+ function isBrowser() {
441
+ return typeof globalThis !== "undefined" && "window" in globalThis && typeof globalThis.window !== "undefined";
442
+ }
443
+ function getEnv(key, defaultValue) {
444
+ if (isNode()) {
445
+ return process.env[key] ?? defaultValue;
446
+ }
447
+ return defaultValue;
448
+ }
449
+ function getRequiredEnv(key) {
450
+ const value = getEnv(key);
451
+ if (value === void 0) {
452
+ throw new Error(`Required environment variable ${key} is not set`);
453
+ }
454
+ return value;
455
+ }
456
+ function isEnvSet(key) {
457
+ if (isNode()) {
458
+ return key in process.env;
459
+ }
460
+ return false;
461
+ }
462
+ var envVars = {
463
+ // Logging
464
+ get ROCK_LOGGING_PATH() {
465
+ return getEnv("ROCK_LOGGING_PATH");
466
+ },
467
+ get ROCK_LOGGING_FILE_NAME() {
468
+ return getEnv("ROCK_LOGGING_FILE_NAME", "rocklet.log");
469
+ },
470
+ get ROCK_LOGGING_LEVEL() {
471
+ return getEnv("ROCK_LOGGING_LEVEL", "INFO");
472
+ },
473
+ // Base URLs
474
+ get ROCK_BASE_URL() {
475
+ return getEnv("ROCK_BASE_URL", "http://localhost:8080");
476
+ },
477
+ get ROCK_SANDBOX_STARTUP_TIMEOUT_SECONDS() {
478
+ return parseInt(getEnv("ROCK_SANDBOX_STARTUP_TIMEOUT_SECONDS", "180"), 10);
479
+ },
480
+ // EnvHub
481
+ get ROCK_ENVHUB_BASE_URL() {
482
+ return getEnv("ROCK_ENVHUB_BASE_URL", "http://localhost:8081");
483
+ },
484
+ // Model Service
485
+ get ROCK_MODEL_SERVICE_DATA_DIR() {
486
+ return getEnv("ROCK_MODEL_SERVICE_DATA_DIR", "/data/logs");
487
+ }};
488
+
489
+ // src/envhub/schema.ts
490
+ var EnvHubClientConfigSchema = z.object({
491
+ baseUrl: z.string().default(envVars.ROCK_ENVHUB_BASE_URL)
492
+ });
493
+ var RockEnvInfoSchema = z.object({
494
+ envName: z.string(),
495
+ image: z.string(),
496
+ owner: z.string().default(""),
497
+ createAt: z.string().default(""),
498
+ updateAt: z.string().default(""),
499
+ description: z.string().default(""),
500
+ tags: z.array(z.string()).default([]),
501
+ extraSpec: z.record(z.unknown()).optional()
502
+ });
503
+ function createRockEnvInfo(data) {
504
+ return RockEnvInfoSchema.parse({
505
+ envName: data.env_name ?? data.envName,
506
+ image: data.image,
507
+ owner: data.owner ?? "",
508
+ createAt: data.create_at ?? data.createAt ?? "",
509
+ updateAt: data.update_at ?? data.updateAt ?? "",
510
+ description: data.description ?? "",
511
+ tags: data.tags ?? [],
512
+ extraSpec: data.extra_spec ?? data.extraSpec
513
+ });
514
+ }
515
+ function rockEnvInfoToDict(env) {
516
+ return {
517
+ env_name: env.envName,
518
+ image: env.image,
519
+ owner: env.owner,
520
+ create_at: env.createAt,
521
+ update_at: env.updateAt,
522
+ description: env.description,
523
+ tags: env.tags,
524
+ extra_spec: env.extraSpec
525
+ };
526
+ }
527
+
528
+ // src/envhub/client.ts
529
+ var EnvHubError = class extends Error {
530
+ constructor(message) {
531
+ super(message);
532
+ this.name = "EnvHubError";
533
+ }
534
+ };
535
+ var EnvHubClient = class {
536
+ config;
537
+ baseUrl;
538
+ headers;
539
+ constructor(config) {
540
+ this.config = EnvHubClientConfigSchema.parse(config ?? {});
541
+ this.baseUrl = this.config.baseUrl;
542
+ this.headers = { "Content-Type": "application/json" };
543
+ }
544
+ /**
545
+ * Register or update an environment
546
+ */
547
+ async register(options) {
548
+ const url = `${this.baseUrl}/env/register`;
549
+ const payload = {
550
+ env_name: options.envName,
551
+ image: options.image,
552
+ owner: options.owner ?? "",
553
+ description: options.description ?? "",
554
+ tags: options.tags ?? [],
555
+ extra_spec: options.extraSpec
556
+ };
557
+ try {
558
+ const response = await HttpUtils.post(
559
+ url,
560
+ this.headers,
561
+ payload
562
+ );
563
+ return createRockEnvInfo(response);
564
+ } catch (e) {
565
+ throw new EnvHubError(`Failed to register environment: ${e}`);
566
+ }
567
+ }
568
+ /**
569
+ * Get environment by name
570
+ */
571
+ async getEnv(envName) {
572
+ const url = `${this.baseUrl}/env/get`;
573
+ const payload = { env_name: envName };
574
+ try {
575
+ const response = await HttpUtils.post(
576
+ url,
577
+ this.headers,
578
+ payload
579
+ );
580
+ return createRockEnvInfo(response);
581
+ } catch (e) {
582
+ throw new EnvHubError(`Failed to get environment ${envName}: ${e}`);
583
+ }
584
+ }
585
+ /**
586
+ * List environments
587
+ */
588
+ async listEnvs(options) {
589
+ const url = `${this.baseUrl}/env/list`;
590
+ const payload = {
591
+ owner: options?.owner,
592
+ tags: options?.tags
593
+ };
594
+ try {
595
+ const response = await HttpUtils.post(
596
+ url,
597
+ this.headers,
598
+ payload
599
+ );
600
+ const envsData = response.envs ?? [];
601
+ return envsData.map((envData) => createRockEnvInfo(envData));
602
+ } catch (e) {
603
+ throw new EnvHubError(`Failed to list environments: ${e}`);
604
+ }
605
+ }
606
+ /**
607
+ * Delete environment
608
+ */
609
+ async deleteEnv(envName) {
610
+ const url = `${this.baseUrl}/env/delete`;
611
+ const payload = { env_name: envName };
612
+ try {
613
+ await HttpUtils.post(url, this.headers, payload);
614
+ return true;
615
+ } catch (e) {
616
+ const errorMessage = e instanceof Error ? e.message : String(e);
617
+ if (errorMessage.includes("404")) {
618
+ return false;
619
+ }
620
+ throw new EnvHubError(`Failed to delete environment ${envName}: ${e}`);
621
+ }
622
+ }
623
+ /**
624
+ * Health check
625
+ */
626
+ async healthCheck() {
627
+ const url = `${this.baseUrl}/health`;
628
+ try {
629
+ const response = await HttpUtils.get(
630
+ url,
631
+ this.headers
632
+ );
633
+ return response;
634
+ } catch (e) {
635
+ throw new EnvHubError(`Failed to health check: ${e}`);
636
+ }
637
+ }
638
+ };
639
+ var levels = {
640
+ error: 0,
641
+ warn: 1,
642
+ info: 2,
643
+ http: 3,
644
+ debug: 4
645
+ };
646
+ var colors = {
647
+ error: "red",
648
+ warn: "yellow",
649
+ info: "green",
650
+ http: "magenta",
651
+ debug: "cyan"
652
+ };
653
+ winston.addColors(colors);
654
+ var consoleFormat = winston.format.combine(
655
+ winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS" }),
656
+ winston.format.colorize({ all: true }),
657
+ winston.format.printf((info) => {
658
+ const { timestamp, level, message, ...meta } = info;
659
+ const metaStr = Object.keys(meta).length ? JSON.stringify(meta) : "";
660
+ return `${timestamp} ${level}: ${message} ${metaStr}`;
661
+ })
662
+ );
663
+ var fileFormat = winston.format.combine(
664
+ winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss.SSS" }),
665
+ winston.format.json()
666
+ );
667
+ function getLogLevel() {
668
+ const level = envVars.ROCK_LOGGING_LEVEL.toUpperCase();
669
+ if (level in levels) {
670
+ return level.toLowerCase();
671
+ }
672
+ return "info";
673
+ }
674
+ var loggerCache = /* @__PURE__ */ new Map();
675
+ function initLogger(name = "rock", fileName) {
676
+ if (loggerCache.has(name)) {
677
+ return loggerCache.get(name);
678
+ }
679
+ const transports = [];
680
+ const logLevel = getLogLevel();
681
+ const logPath = envVars.ROCK_LOGGING_PATH;
682
+ const logFileName = envVars.ROCK_LOGGING_FILE_NAME;
683
+ if (logPath) {
684
+ if (!existsSync(logPath)) {
685
+ mkdirSync(logPath, { recursive: true });
686
+ }
687
+ transports.push(
688
+ new winston.transports.File({
689
+ filename: join(logPath, logFileName),
690
+ format: fileFormat,
691
+ level: logLevel
692
+ })
693
+ );
694
+ } else {
695
+ transports.push(
696
+ new winston.transports.Console({
697
+ format: consoleFormat,
698
+ level: logLevel
699
+ })
700
+ );
701
+ }
702
+ const logger11 = winston.createLogger({
703
+ levels,
704
+ defaultMeta: { service: name },
705
+ transports
706
+ });
707
+ loggerCache.set(name, logger11);
708
+ return logger11;
709
+ }
710
+ initLogger("rock");
711
+
712
+ // src/envs/rock_env.ts
713
+ var logger = initLogger("rock.envs");
714
+ var RockEnv = class {
715
+ envId;
716
+ sandboxId = null;
717
+ isClosed = false;
718
+ client;
719
+ constructor(config) {
720
+ this.envId = config.envId;
721
+ this.client = axios3.create({
722
+ baseURL: envVars.ROCK_BASE_URL,
723
+ timeout: 3e5,
724
+ headers: { "Content-Type": "application/json" }
725
+ });
726
+ try {
727
+ this.initializeEnvironment();
728
+ } catch (e) {
729
+ throw new Error(`Failed to initialize environment: ${e}`);
730
+ }
731
+ }
732
+ /**
733
+ * Initialize environment instance
734
+ */
735
+ initializeEnvironment() {
736
+ logger.debug(`Initializing environment: ${this.envId}`);
737
+ }
738
+ /**
739
+ * Execute an action step
740
+ *
741
+ * @param action - Action ID to execute
742
+ * @returns Tuple containing observation, reward, terminated, truncated, info
743
+ */
744
+ async step(action) {
745
+ this.ensureNotClosed();
746
+ const params = {
747
+ sandbox_id: this.sandboxId,
748
+ action
749
+ };
750
+ try {
751
+ const response = await this.client.post(
752
+ "/apis/v1/envs/gem/step",
753
+ params
754
+ );
755
+ return this.parseStepResult(response.data);
756
+ } catch (e) {
757
+ throw new Error(`Failed to execute step with action ${action}: ${e}`);
758
+ }
759
+ }
760
+ /**
761
+ * Reset environment to initial state
762
+ *
763
+ * @param seed - Optional random seed
764
+ * @returns Tuple containing initial observation and info
765
+ */
766
+ async reset(seed) {
767
+ this.ensureNotClosed();
768
+ const params = { sandbox_id: this.sandboxId };
769
+ if (seed !== void 0) {
770
+ params.seed = seed;
771
+ }
772
+ try {
773
+ const response = await this.client.post(
774
+ "/apis/v1/envs/gem/reset",
775
+ params
776
+ );
777
+ return this.parseResetResult(response.data);
778
+ } catch (e) {
779
+ throw new Error(`Failed to reset environment: ${e}`);
780
+ }
781
+ }
782
+ /**
783
+ * Close environment and clean up resources
784
+ */
785
+ async close() {
786
+ if (this.isClosed || !this.sandboxId) {
787
+ return;
788
+ }
789
+ try {
790
+ await this.client.post("/apis/v1/envs/gem/close", {
791
+ sandbox_id: this.sandboxId
792
+ });
793
+ } catch (e) {
794
+ throw new Error(`Failed to close environment: ${e}`);
795
+ } finally {
796
+ this.isClosed = true;
797
+ this.sandboxId = null;
798
+ }
799
+ }
800
+ /**
801
+ * Parse step result from API response
802
+ */
803
+ parseStepResult(data) {
804
+ return [
805
+ data.observation,
806
+ data.reward,
807
+ data.terminated,
808
+ data.truncated,
809
+ data.info
810
+ ];
811
+ }
812
+ /**
813
+ * Parse reset result from API response
814
+ */
815
+ parseResetResult(data) {
816
+ return [data.observation, data.info];
817
+ }
818
+ /**
819
+ * Ensure environment is not closed
820
+ */
821
+ ensureNotClosed() {
822
+ if (this.isClosed) {
823
+ throw new Error("Environment is closed");
824
+ }
825
+ }
826
+ };
827
+
828
+ // src/envs/registration.ts
829
+ function make(envId, options) {
830
+ return new RockEnv({ envId, ...options });
831
+ }
832
+ var BaseConfigSchema = z.object({
833
+ baseUrl: z.string().default(envVars.ROCK_BASE_URL),
834
+ xrlAuthorization: z.string().optional(),
835
+ extraHeaders: z.record(z.string()).default({})
836
+ });
837
+ var SandboxConfigSchema = BaseConfigSchema.extend({
838
+ image: z.string().default("python:3.11"),
839
+ autoClearSeconds: z.number().default(300),
840
+ routeKey: z.string().optional(),
841
+ startupTimeout: z.number().default(envVars.ROCK_SANDBOX_STARTUP_TIMEOUT_SECONDS),
842
+ memory: z.string().default("8g"),
843
+ cpus: z.number().default(2),
844
+ userId: z.string().optional(),
845
+ experimentId: z.string().optional(),
846
+ cluster: z.string().default("zb"),
847
+ namespace: z.string().optional()
848
+ });
849
+ var SandboxGroupConfigSchema = SandboxConfigSchema.extend({
850
+ size: z.number().default(2),
851
+ startConcurrency: z.number().default(2),
852
+ startRetryTimes: z.number().default(3)
853
+ });
854
+ function createSandboxConfig(config) {
855
+ return SandboxConfigSchema.parse(config ?? {});
856
+ }
857
+ function createSandboxGroupConfig(config) {
858
+ return SandboxGroupConfigSchema.parse(config ?? {});
859
+ }
860
+ var logger2 = initLogger("rock.sandbox.deploy");
861
+ var Deploy = class {
862
+ sandbox;
863
+ workingDir = null;
864
+ constructor(sandbox) {
865
+ this.sandbox = sandbox;
866
+ }
867
+ /**
868
+ * Get the current working directory
869
+ */
870
+ getWorkingDir() {
871
+ return this.workingDir;
872
+ }
873
+ /**
874
+ * Deploy local directory to sandbox
875
+ *
876
+ * @param localPath - Local directory path
877
+ * @param targetPath - Target path in sandbox (optional)
878
+ * @returns The target path in sandbox
879
+ */
880
+ async deployWorkingDir(localPath, targetPath) {
881
+ const localAbs = resolve(localPath);
882
+ if (!existsSync(localAbs)) {
883
+ throw new Error(`local_path not found: ${localAbs}`);
884
+ }
885
+ const stats = statSync(localAbs);
886
+ if (!stats.isDirectory()) {
887
+ throw new Error(`local_path must be a directory: ${localAbs}`);
888
+ }
889
+ const target = targetPath ?? `/tmp/rock_workdir_${randomUUID().replace(/-/g, "")}`;
890
+ const sandboxId = this.sandbox.getSandboxId();
891
+ logger2.info(`[${sandboxId}] Deploying working_dir: ${localAbs} -> ${target}`);
892
+ const uploadResult = await this.sandbox.getFs().uploadDir(localAbs, target);
893
+ if (uploadResult.exitCode !== 0) {
894
+ throw new Error(`Failed to upload directory: ${uploadResult.failureReason}`);
895
+ }
896
+ this.workingDir = target;
897
+ logger2.info(`[${sandboxId}] working_dir deployed: ${target}`);
898
+ return target;
899
+ }
900
+ /**
901
+ * Format command template supporting ${} and <<>> syntax
902
+ *
903
+ * @param template - Template string with placeholders
904
+ * @param kwargs - Additional substitution variables
905
+ * @returns Formatted string
906
+ */
907
+ format(template, kwargs = {}) {
908
+ const subs = {
909
+ ...kwargs,
910
+ ...this.workingDir ? { working_dir: this.workingDir } : {}
911
+ };
912
+ let result = template;
913
+ for (const key of Object.keys(subs)) {
914
+ result = result.replace(new RegExp(`<<${key}>>`, "g"), `\${${key}}`);
915
+ }
916
+ for (const [key, value] of Object.entries(subs)) {
917
+ if (value !== void 0) {
918
+ result = result.replace(new RegExp(`\\$\\{${key}\\}`, "g"), value);
919
+ }
920
+ }
921
+ return result;
922
+ }
923
+ };
924
+
925
+ // src/sandbox/file_system.ts
926
+ var logger3 = initLogger("rock.sandbox.fs");
927
+ var FileSystem = class {
928
+ sandbox;
929
+ constructor(sandbox) {
930
+ this.sandbox = sandbox;
931
+ }
932
+ };
933
+ var LinuxFileSystem = class extends FileSystem {
934
+ constructor(sandbox) {
935
+ super(sandbox);
936
+ }
937
+ async chown(request) {
938
+ const { paths, recursive, remoteUser } = request;
939
+ if (!paths || paths.length === 0) {
940
+ throw new Error("paths is empty");
941
+ }
942
+ const command = ["chown"];
943
+ if (recursive) {
944
+ command.push("-R");
945
+ }
946
+ command.push(`${remoteUser}:${remoteUser}`, ...paths);
947
+ logger3.info(`chown command: ${command.join(" ")}`);
948
+ const response = await this.sandbox.execute({ command, timeout: 300 });
949
+ if (response.exitCode !== 0) {
950
+ return { success: false, message: JSON.stringify(response) };
951
+ }
952
+ return { success: true, message: JSON.stringify(response) };
953
+ }
954
+ async chmod(request) {
955
+ const { paths, recursive, mode } = request;
956
+ if (!paths || paths.length === 0) {
957
+ throw new Error("paths is empty");
958
+ }
959
+ const command = ["chmod"];
960
+ if (recursive) {
961
+ command.push("-R");
962
+ }
963
+ command.push(mode, ...paths);
964
+ logger3.info(`chmod command: ${command.join(" ")}`);
965
+ const response = await this.sandbox.execute({ command, timeout: 300 });
966
+ if (response.exitCode !== 0) {
967
+ return { success: false, message: JSON.stringify(response) };
968
+ }
969
+ return { success: true, message: JSON.stringify(response) };
970
+ }
971
+ async uploadDir(sourceDir, targetDir, extractTimeout = 600) {
972
+ logger3.info(`uploadDir: ${sourceDir} -> ${targetDir}`);
973
+ return {
974
+ output: `uploaded ${sourceDir} -> ${targetDir}`,
975
+ exitCode: 0,
976
+ failureReason: "",
977
+ expectString: ""
978
+ };
979
+ }
980
+ };
981
+
982
+ // src/sandbox/types.ts
983
+ var SpeedupType = /* @__PURE__ */ ((SpeedupType2) => {
984
+ SpeedupType2["APT"] = "apt";
985
+ SpeedupType2["PIP"] = "pip";
986
+ SpeedupType2["GITHUB"] = "github";
987
+ return SpeedupType2;
988
+ })(SpeedupType || {});
989
+
990
+ // src/sandbox/network.ts
991
+ var logger4 = initLogger("rock.sandbox.network");
992
+ var Network = class {
993
+ sandbox;
994
+ constructor(sandbox) {
995
+ this.sandbox = sandbox;
996
+ }
997
+ /**
998
+ * Configure acceleration for package managers or network resources
999
+ *
1000
+ * @param speedupType - Type of speedup configuration
1001
+ * @param speedupValue - Speedup value (mirror URL or IP address)
1002
+ * @param timeout - Execution timeout in seconds
1003
+ * @returns Observation with execution result
1004
+ */
1005
+ async speedup(speedupType, speedupValue, timeout = 300) {
1006
+ const sandboxId = this.sandbox.getSandboxId();
1007
+ logger4.info(
1008
+ `[${sandboxId}] Configuring ${speedupType} speedup: ${speedupValue}`
1009
+ );
1010
+ let command;
1011
+ switch (speedupType) {
1012
+ case "apt" /* APT */:
1013
+ command = this.buildAptSpeedupCommand(speedupValue);
1014
+ break;
1015
+ case "pip" /* PIP */:
1016
+ command = this.buildPipSpeedupCommand(speedupValue);
1017
+ break;
1018
+ case "github" /* GITHUB */:
1019
+ command = this.buildGithubSpeedupCommand(speedupValue);
1020
+ break;
1021
+ default:
1022
+ throw new Error(`Unsupported speedup type: ${speedupType}`);
1023
+ }
1024
+ const result = await this.sandbox.arun(command, {
1025
+ mode: "nohup",
1026
+ waitTimeout: timeout
1027
+ });
1028
+ return result;
1029
+ }
1030
+ buildAptSpeedupCommand(mirrorUrl) {
1031
+ return `cat > /etc/apt/sources.list << 'EOF'
1032
+ deb ${mirrorUrl} $(lsb_release -cs) main restricted universe multiverse
1033
+ deb ${mirrorUrl} $(lsb_release -cs)-updates main restricted universe multiverse
1034
+ deb ${mirrorUrl} $(lsb_release -cs)-backports main restricted universe multiverse
1035
+ deb ${mirrorUrl} $(lsb_release -cs)-security main restricted universe multiverse
1036
+ EOF
1037
+ apt-get update`;
1038
+ }
1039
+ buildPipSpeedupCommand(mirrorUrl) {
1040
+ const safeUrl = mirrorUrl.replace(/'/g, "'\\''");
1041
+ return `mkdir -p ~/.pip && cat > ~/.pip/pip.conf << 'EOF'
1042
+ [global]
1043
+ index-url = ${safeUrl}
1044
+ trusted-host = $(echo ${safeUrl} | sed 's|https\\?://||' | cut -d'/' -f1)
1045
+ EOF`;
1046
+ }
1047
+ buildGithubSpeedupCommand(ipAddress) {
1048
+ return `echo "${ipAddress} github.com" >> /etc/hosts`;
1049
+ }
1050
+ };
1051
+
1052
+ // src/sandbox/process.ts
1053
+ var logger5 = initLogger("rock.sandbox.process");
1054
+ var Process = class {
1055
+ sandbox;
1056
+ constructor(sandbox) {
1057
+ this.sandbox = sandbox;
1058
+ }
1059
+ /**
1060
+ * Execute a script in the sandbox
1061
+ *
1062
+ * @param scriptContent - The script content to execute
1063
+ * @param scriptName - Optional custom script name
1064
+ * @param waitTimeout - Maximum time to wait for script completion
1065
+ * @param waitInterval - Interval between process checks
1066
+ * @param cleanup - Whether to delete the script file after execution
1067
+ * @returns Observation with execution result
1068
+ */
1069
+ async executeScript(options) {
1070
+ const {
1071
+ scriptContent,
1072
+ scriptName,
1073
+ waitTimeout = 300,
1074
+ cleanup = true
1075
+ } = options;
1076
+ const sandboxId = this.sandbox.getSandboxId();
1077
+ const timestamp = Date.now();
1078
+ const name = scriptName ?? `script_${timestamp}.sh`;
1079
+ const scriptPath = `/tmp/${name}`;
1080
+ try {
1081
+ logger5.info(`[${sandboxId}] Uploading script to ${scriptPath}`);
1082
+ const writeResult = await this.sandbox.write_file({
1083
+ content: scriptContent,
1084
+ path: scriptPath
1085
+ });
1086
+ if (!writeResult.success) {
1087
+ const errorMsg = `Failed to upload script: ${writeResult.message}`;
1088
+ logger5.error(errorMsg);
1089
+ return { output: errorMsg, exitCode: 1, failureReason: "Script upload failed", expectString: "" };
1090
+ }
1091
+ logger5.info(`[${sandboxId}] Executing script: ${scriptPath} (timeout=${waitTimeout}s)`);
1092
+ const result = await this.sandbox.arun(`bash ${scriptPath}`, {
1093
+ mode: "nohup",
1094
+ waitTimeout
1095
+ });
1096
+ return result;
1097
+ } catch (e) {
1098
+ const errorMsg = `Script execution failed: ${e}`;
1099
+ logger5.error(errorMsg);
1100
+ return { output: errorMsg, exitCode: 1, failureReason: errorMsg, expectString: "" };
1101
+ } finally {
1102
+ if (cleanup) {
1103
+ try {
1104
+ logger5.info(`[${sandboxId}] Cleaning up script: ${scriptPath}`);
1105
+ await this.sandbox.execute({ command: ["rm", "-f", scriptPath], timeout: 30 });
1106
+ } catch (e) {
1107
+ logger5.warn(`Failed to cleanup script ${scriptPath}: ${e}`);
1108
+ }
1109
+ }
1110
+ }
1111
+ }
1112
+ };
1113
+
1114
+ // src/sandbox/remote_user.ts
1115
+ var logger6 = initLogger("rock.sandbox.user");
1116
+ var RemoteUser = class {
1117
+ sandbox;
1118
+ currentUser = "root";
1119
+ constructor(sandbox) {
1120
+ this.sandbox = sandbox;
1121
+ }
1122
+ getCurrentUser() {
1123
+ return this.currentUser;
1124
+ }
1125
+ };
1126
+ var LinuxRemoteUser = class extends RemoteUser {
1127
+ constructor(sandbox) {
1128
+ super(sandbox);
1129
+ }
1130
+ async createRemoteUser(userName) {
1131
+ try {
1132
+ if (await this.isUserExist(userName)) {
1133
+ return true;
1134
+ }
1135
+ const response = await this.sandbox.execute({
1136
+ command: ["useradd", "-m", "-s", "/bin/bash", userName],
1137
+ timeout: 30
1138
+ });
1139
+ logger6.info(`user add execute response: ${JSON.stringify(response)}`);
1140
+ if (response.exitCode !== 0) {
1141
+ return false;
1142
+ }
1143
+ return true;
1144
+ } catch (e) {
1145
+ logger6.error("create_remote_user failed", e);
1146
+ throw e;
1147
+ }
1148
+ }
1149
+ async isUserExist(userName) {
1150
+ try {
1151
+ const response = await this.sandbox.execute({
1152
+ command: ["id", userName],
1153
+ timeout: 30
1154
+ });
1155
+ if (response.exitCode === 0) {
1156
+ logger6.info(`user ${userName} already exists`);
1157
+ return true;
1158
+ }
1159
+ return false;
1160
+ } catch (e) {
1161
+ logger6.info(`is_user_exist exception: ${e}`);
1162
+ throw e;
1163
+ }
1164
+ }
1165
+ };
1166
+
1167
+ // src/sandbox/utils.ts
1168
+ var logger7 = initLogger("rock.sandbox.utils");
1169
+ function getCallerLoggerName() {
1170
+ const stack = new Error().stack;
1171
+ if (!stack) return "unknown";
1172
+ const lines = stack.split("\n");
1173
+ for (let i = 2; i < lines.length; i++) {
1174
+ const line = lines[i];
1175
+ if (line && !line.includes("utils.ts")) {
1176
+ const match = line.match(/at\s+(?:(?:async\s+)?(?:\w+\.)?(\w+)|(\w+))/);
1177
+ if (match) {
1178
+ return match[1] ?? match[2] ?? "unknown";
1179
+ }
1180
+ }
1181
+ }
1182
+ return "unknown";
1183
+ }
1184
+ function withTimeLogging(operationName) {
1185
+ return function(target, propertyKey, descriptor) {
1186
+ const originalMethod = descriptor.value;
1187
+ descriptor.value = async function(...args) {
1188
+ const startTime = Date.now();
1189
+ const name = getCallerLoggerName();
1190
+ const log = initLogger(name);
1191
+ log.debug(`${operationName} started`);
1192
+ try {
1193
+ const result = await originalMethod.apply(this, args);
1194
+ const elapsed = Date.now() - startTime;
1195
+ log.info(`${operationName} completed (elapsed: ${elapsed / 1e3}s)`);
1196
+ return result;
1197
+ } catch (e) {
1198
+ const elapsed = Date.now() - startTime;
1199
+ log.error(`${operationName} failed: ${e} (elapsed: ${elapsed / 1e3}s)`);
1200
+ throw e;
1201
+ }
1202
+ };
1203
+ return descriptor;
1204
+ };
1205
+ }
1206
+ async function arunWithRetry(sandbox, cmd, session, mode, options = {}) {
1207
+ const {
1208
+ waitTimeout = 300,
1209
+ waitInterval = 10,
1210
+ maxAttempts = 3,
1211
+ errorMsg = "Command failed"
1212
+ } = options;
1213
+ let lastError = null;
1214
+ let currentDelay = 5e3;
1215
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
1216
+ try {
1217
+ const result = await sandbox.arun(cmd, {
1218
+ session,
1219
+ mode,
1220
+ waitTimeout,
1221
+ waitInterval
1222
+ });
1223
+ if (result.exitCode !== 0) {
1224
+ throw new Error(
1225
+ `${errorMsg} with exit code: ${result.exitCode}, output: ${result.output}`
1226
+ );
1227
+ }
1228
+ return result;
1229
+ } catch (e) {
1230
+ lastError = e instanceof Error ? e : new Error(String(e));
1231
+ logger7.warn(`Attempt ${attempt}/${maxAttempts} failed: ${lastError.message}`);
1232
+ if (attempt < maxAttempts) {
1233
+ await sleep(currentDelay);
1234
+ currentDelay *= 2;
1235
+ }
1236
+ }
1237
+ }
1238
+ throw lastError ?? new Error(`${errorMsg}: all attempts failed`);
1239
+ }
1240
+ function extractNohupPid(output) {
1241
+ const PID_PREFIX2 = "__ROCK_PID_START__";
1242
+ const PID_SUFFIX2 = "__ROCK_PID_END__";
1243
+ const pattern = new RegExp(`${PID_PREFIX2}(\\d+)${PID_SUFFIX2}`);
1244
+ const match = output.match(pattern);
1245
+ if (match?.[1]) {
1246
+ return parseInt(match[1], 10);
1247
+ }
1248
+ return null;
1249
+ }
1250
+
1251
+ // src/sandbox/client.ts
1252
+ var logger8 = initLogger("rock.sandbox");
1253
+ var AbstractSandbox = class {
1254
+ };
1255
+ var Sandbox = class extends AbstractSandbox {
1256
+ config;
1257
+ url;
1258
+ routeKey;
1259
+ sandboxId = null;
1260
+ hostName = null;
1261
+ hostIp = null;
1262
+ cluster;
1263
+ // Sub-components
1264
+ deploy;
1265
+ fs;
1266
+ network;
1267
+ process;
1268
+ remoteUser;
1269
+ constructor(config = {}) {
1270
+ super();
1271
+ this.config = createSandboxConfig(config);
1272
+ this.url = `${this.config.baseUrl}/apis/envs/sandbox/v1`;
1273
+ this.routeKey = this.config.routeKey ?? randomUUID().replace(/-/g, "");
1274
+ this.cluster = this.config.cluster;
1275
+ this.deploy = new Deploy(this);
1276
+ this.fs = new LinuxFileSystem(this);
1277
+ this.network = new Network(this);
1278
+ this.process = new Process(this);
1279
+ this.remoteUser = new LinuxRemoteUser(this);
1280
+ }
1281
+ // Getters
1282
+ getSandboxId() {
1283
+ if (!this.sandboxId) {
1284
+ throw new Error("Sandbox not started");
1285
+ }
1286
+ return this.sandboxId;
1287
+ }
1288
+ getHostName() {
1289
+ return this.hostName;
1290
+ }
1291
+ getHostIp() {
1292
+ return this.hostIp;
1293
+ }
1294
+ getCluster() {
1295
+ return this.cluster;
1296
+ }
1297
+ getUrl() {
1298
+ return this.url;
1299
+ }
1300
+ getFs() {
1301
+ return this.fs;
1302
+ }
1303
+ getNetwork() {
1304
+ return this.network;
1305
+ }
1306
+ getProcess() {
1307
+ return this.process;
1308
+ }
1309
+ getRemoteUser() {
1310
+ return this.remoteUser;
1311
+ }
1312
+ getDeploy() {
1313
+ return this.deploy;
1314
+ }
1315
+ getConfig() {
1316
+ return this.config;
1317
+ }
1318
+ // Build headers
1319
+ buildHeaders() {
1320
+ const headers = {
1321
+ "ROUTE-KEY": this.routeKey,
1322
+ "X-Cluster": this.cluster
1323
+ };
1324
+ if (this.config.extraHeaders) {
1325
+ Object.assign(headers, this.config.extraHeaders);
1326
+ }
1327
+ this.addUserDefinedTags(headers);
1328
+ return headers;
1329
+ }
1330
+ addUserDefinedTags(headers) {
1331
+ if (this.config.userId) {
1332
+ headers["X-User-Id"] = this.config.userId;
1333
+ }
1334
+ if (this.config.experimentId) {
1335
+ headers["X-Experiment-Id"] = this.config.experimentId;
1336
+ }
1337
+ if (this.config.namespace) {
1338
+ headers["X-Namespace"] = this.config.namespace;
1339
+ }
1340
+ }
1341
+ // Lifecycle methods
1342
+ async start() {
1343
+ const url = `${this.url}/start_async`;
1344
+ const headers = this.buildHeaders();
1345
+ const data = {
1346
+ image: this.config.image,
1347
+ auto_clear_time: this.config.autoClearSeconds / 60,
1348
+ auto_clear_time_minutes: this.config.autoClearSeconds / 60,
1349
+ startup_timeout: this.config.startupTimeout,
1350
+ memory: this.config.memory,
1351
+ cpus: this.config.cpus
1352
+ };
1353
+ try {
1354
+ const response = await HttpUtils.post(
1355
+ url,
1356
+ headers,
1357
+ data
1358
+ );
1359
+ logger8.debug(`Start sandbox response: ${JSON.stringify(response)}`);
1360
+ if (response.status !== "Success") {
1361
+ throw new Error(`Failed to start sandbox: ${JSON.stringify(response)}`);
1362
+ }
1363
+ this.sandboxId = response.result?.sandbox_id ?? null;
1364
+ this.hostName = response.result?.host_name ?? null;
1365
+ this.hostIp = response.result?.host_ip ?? null;
1366
+ const startTime = Date.now();
1367
+ while (Date.now() - startTime < this.config.startupTimeout * 1e3) {
1368
+ const status = await this.getStatus();
1369
+ if (status.isAlive) {
1370
+ return;
1371
+ }
1372
+ await sleep(3e3);
1373
+ }
1374
+ throw new Error(`Failed to start sandbox within ${this.config.startupTimeout}s`);
1375
+ } catch (e) {
1376
+ throw new Error(`Failed to start sandbox: ${e}`);
1377
+ }
1378
+ }
1379
+ async stop() {
1380
+ if (!this.sandboxId) return;
1381
+ try {
1382
+ const url = `${this.url}/stop`;
1383
+ const headers = this.buildHeaders();
1384
+ await HttpUtils.post(url, headers, { sandbox_id: this.sandboxId });
1385
+ } catch (e) {
1386
+ logger8.warn(`Failed to stop sandbox, IGNORE: ${e}`);
1387
+ }
1388
+ }
1389
+ async isAlive() {
1390
+ try {
1391
+ const status = await this.getStatus();
1392
+ return {
1393
+ isAlive: status.isAlive,
1394
+ message: status.hostName ?? ""
1395
+ };
1396
+ } catch (e) {
1397
+ throw new Error(`Failed to get is alive: ${e}`);
1398
+ }
1399
+ }
1400
+ async getStatus() {
1401
+ const url = `${this.url}/get_status?sandbox_id=${this.sandboxId}`;
1402
+ const headers = this.buildHeaders();
1403
+ const response = await HttpUtils.get(url, headers);
1404
+ if (response.status !== "Success") {
1405
+ throw new Error(`Failed to get status: ${JSON.stringify(response)}`);
1406
+ }
1407
+ return response.result;
1408
+ }
1409
+ // Command execution
1410
+ async execute(command) {
1411
+ const url = `${this.url}/execute`;
1412
+ const headers = this.buildHeaders();
1413
+ const data = {
1414
+ command: command.command,
1415
+ sandbox_id: this.sandboxId,
1416
+ timeout: command.timeout,
1417
+ cwd: command.cwd,
1418
+ env: command.env
1419
+ };
1420
+ try {
1421
+ const response = await HttpUtils.post(
1422
+ url,
1423
+ headers,
1424
+ data
1425
+ );
1426
+ if (response.status !== "Success") {
1427
+ throw new Error(`Failed to execute command: ${JSON.stringify(response)}`);
1428
+ }
1429
+ return response.result;
1430
+ } catch (e) {
1431
+ throw new Error(`Failed to execute command: ${e}`);
1432
+ }
1433
+ }
1434
+ // Session management
1435
+ async createSession(request) {
1436
+ const url = `${this.url}/create_session`;
1437
+ const headers = this.buildHeaders();
1438
+ const data = {
1439
+ sandbox_id: this.sandboxId,
1440
+ ...request
1441
+ };
1442
+ try {
1443
+ const response = await HttpUtils.post(
1444
+ url,
1445
+ headers,
1446
+ data
1447
+ );
1448
+ if (response.status !== "Success") {
1449
+ throw new Error(`Failed to create session: ${JSON.stringify(response)}`);
1450
+ }
1451
+ return response.result;
1452
+ } catch (e) {
1453
+ throw new Error(`Failed to create session: ${e}`);
1454
+ }
1455
+ }
1456
+ async closeSession(request) {
1457
+ const url = `${this.url}/close_session`;
1458
+ const headers = this.buildHeaders();
1459
+ const data = {
1460
+ sandbox_id: this.sandboxId,
1461
+ ...request
1462
+ };
1463
+ try {
1464
+ const response = await HttpUtils.post(
1465
+ url,
1466
+ headers,
1467
+ data
1468
+ );
1469
+ if (response.status !== "Success") {
1470
+ throw new Error(`Failed to close session: ${JSON.stringify(response)}`);
1471
+ }
1472
+ return response.result ?? {};
1473
+ } catch (e) {
1474
+ throw new Error(`Failed to close session: ${e}`);
1475
+ }
1476
+ }
1477
+ // Run command in session
1478
+ async arun(cmd, options = {}) {
1479
+ const {
1480
+ session,
1481
+ mode = "normal",
1482
+ waitTimeout = 300,
1483
+ waitInterval = 10
1484
+ } = options;
1485
+ if (mode === "normal") {
1486
+ return this.runInSession({ command: cmd, session: session ?? "default" });
1487
+ }
1488
+ return this.arunWithNohup(cmd, options);
1489
+ }
1490
+ async runInSession(action) {
1491
+ const url = `${this.url}/run_in_session`;
1492
+ const headers = this.buildHeaders();
1493
+ const data = {
1494
+ action_type: "bash",
1495
+ session: action.session,
1496
+ command: action.command,
1497
+ sandbox_id: this.sandboxId,
1498
+ timeout: action.timeout
1499
+ };
1500
+ try {
1501
+ const response = await HttpUtils.post(
1502
+ url,
1503
+ headers,
1504
+ data,
1505
+ action.timeout
1506
+ );
1507
+ if (response.status !== "Success") {
1508
+ throw new Error(`Failed to execute command: ${JSON.stringify(response)}`);
1509
+ }
1510
+ return response.result;
1511
+ } catch (e) {
1512
+ throw new Error(`Failed to run in session: ${e}`);
1513
+ }
1514
+ }
1515
+ async arunWithNohup(cmd, options) {
1516
+ const {
1517
+ session,
1518
+ waitTimeout = 300,
1519
+ waitInterval = 10,
1520
+ responseLimitedBytesInNohup,
1521
+ ignoreOutput = false,
1522
+ outputFile
1523
+ } = options;
1524
+ const timestamp = Date.now();
1525
+ const tmpSession = session ?? `bash-${timestamp}`;
1526
+ if (!session) {
1527
+ await this.createSession({ session: tmpSession, startupSource: [], envEnable: false });
1528
+ }
1529
+ const tmpFile = outputFile ?? `/tmp/tmp_${timestamp}.out`;
1530
+ const nohupCommand = `nohup ${cmd} < /dev/null > ${tmpFile} 2>&1 & echo __ROCK_PID_START__$!__ROCK_PID_END__;disown`;
1531
+ const response = await this.runInSession({
1532
+ command: nohupCommand,
1533
+ session: tmpSession,
1534
+ timeout: 30
1535
+ });
1536
+ if (response.exitCode !== 0) {
1537
+ return response;
1538
+ }
1539
+ const pid = extractNohupPid(response.output);
1540
+ if (!pid) {
1541
+ return {
1542
+ output: "Failed to submit command, nohup failed to extract PID",
1543
+ exitCode: 1,
1544
+ failureReason: "PID extraction failed",
1545
+ expectString: ""
1546
+ };
1547
+ }
1548
+ const success = await this.waitForProcessCompletion(pid, tmpSession, waitTimeout, waitInterval);
1549
+ if (ignoreOutput) {
1550
+ return {
1551
+ output: `Command executed in nohup mode. Output file: ${tmpFile}`,
1552
+ exitCode: success ? 0 : 1,
1553
+ failureReason: success ? "" : "Process did not complete successfully",
1554
+ expectString: ""
1555
+ };
1556
+ }
1557
+ const readCmd = responseLimitedBytesInNohup ? `head -c ${responseLimitedBytesInNohup} ${tmpFile}` : `cat ${tmpFile}`;
1558
+ const outputResult = await this.runInSession({
1559
+ command: readCmd,
1560
+ session: tmpSession
1561
+ });
1562
+ return {
1563
+ output: outputResult.output,
1564
+ exitCode: success ? 0 : 1,
1565
+ failureReason: success ? "" : "Process did not complete successfully",
1566
+ expectString: ""
1567
+ };
1568
+ }
1569
+ async waitForProcessCompletion(pid, session, waitTimeout, waitInterval) {
1570
+ const startTime = Date.now();
1571
+ const checkInterval = Math.max(5, waitInterval);
1572
+ const effectiveInterval = Math.min(checkInterval * 2, waitTimeout);
1573
+ while (Date.now() - startTime < waitTimeout * 1e3) {
1574
+ try {
1575
+ await this.runInSession({
1576
+ command: `kill -0 ${pid}`,
1577
+ session,
1578
+ timeout: effectiveInterval
1579
+ });
1580
+ await sleep(checkInterval * 1e3);
1581
+ } catch {
1582
+ return true;
1583
+ }
1584
+ }
1585
+ return false;
1586
+ }
1587
+ // File operations
1588
+ async write_file(request) {
1589
+ const url = `${this.url}/write_file`;
1590
+ const headers = this.buildHeaders();
1591
+ const data = {
1592
+ content: request.content,
1593
+ path: request.path,
1594
+ sandbox_id: this.sandboxId
1595
+ };
1596
+ const response = await HttpUtils.post(url, headers, data);
1597
+ if (response.status !== "Success") {
1598
+ return { success: false, message: `Failed to write file ${request.path}` };
1599
+ }
1600
+ return { success: true, message: `Successfully write content to file ${request.path}` };
1601
+ }
1602
+ async read_file(request) {
1603
+ const url = `${this.url}/read_file`;
1604
+ const headers = this.buildHeaders();
1605
+ const data = {
1606
+ path: request.path,
1607
+ encoding: request.encoding,
1608
+ errors: request.errors,
1609
+ sandbox_id: this.sandboxId
1610
+ };
1611
+ const response = await HttpUtils.post(
1612
+ url,
1613
+ headers,
1614
+ data
1615
+ );
1616
+ return { content: response.result?.content ?? "" };
1617
+ }
1618
+ // Upload
1619
+ async upload(request) {
1620
+ return this.uploadByPath(request.sourcePath, request.targetPath);
1621
+ }
1622
+ async uploadByPath(sourcePath, targetPath) {
1623
+ const url = `${this.url}/upload`;
1624
+ const headers = this.buildHeaders();
1625
+ try {
1626
+ const fs = await import('fs');
1627
+ if (!fs.existsSync(sourcePath)) {
1628
+ return { success: false, message: `File not found: ${sourcePath}` };
1629
+ }
1630
+ const fileBuffer = fs.readFileSync(sourcePath);
1631
+ const fileName = sourcePath.split("/").pop() ?? "file";
1632
+ const response = await HttpUtils.postMultipart(
1633
+ url,
1634
+ headers,
1635
+ { target_path: targetPath, sandbox_id: this.sandboxId ?? "" },
1636
+ { file: [fileName, fileBuffer, "application/octet-stream"] }
1637
+ );
1638
+ if (response.status !== "Success") {
1639
+ return { success: false, message: "Upload failed" };
1640
+ }
1641
+ return { success: true, message: `Successfully uploaded file ${fileName} to ${targetPath}` };
1642
+ } catch (e) {
1643
+ return { success: false, message: `Upload failed: ${e}` };
1644
+ }
1645
+ }
1646
+ // Close
1647
+ async close() {
1648
+ await this.stop();
1649
+ }
1650
+ toString() {
1651
+ return `Sandbox(sandboxId=${this.sandboxId}, hostName=${this.hostName}, image=${this.config.image}, cluster=${this.cluster})`;
1652
+ }
1653
+ };
1654
+ var SandboxGroup = class {
1655
+ config;
1656
+ sandboxList;
1657
+ constructor(config = {}) {
1658
+ this.config = createSandboxGroupConfig(config);
1659
+ this.sandboxList = Array.from(
1660
+ { length: this.config.size },
1661
+ () => new Sandbox(this.config)
1662
+ );
1663
+ }
1664
+ getSandboxList() {
1665
+ return this.sandboxList;
1666
+ }
1667
+ async start() {
1668
+ const concurrency = this.config.startConcurrency;
1669
+ const retryTimes = this.config.startRetryTimes;
1670
+ const startSandbox = async (index, sandbox) => {
1671
+ logger8.info(`Starting sandbox ${index} with ${sandbox.getConfig().image}...`);
1672
+ for (let attempt = 0; attempt < retryTimes; attempt++) {
1673
+ try {
1674
+ await sandbox.start();
1675
+ return;
1676
+ } catch (e) {
1677
+ if (attempt === retryTimes - 1) {
1678
+ logger8.error(`Failed to start sandbox after ${retryTimes} attempts: ${e}`);
1679
+ throw e;
1680
+ }
1681
+ logger8.warn(`Failed to start sandbox (attempt ${attempt + 1}/${retryTimes}): ${e}, retrying...`);
1682
+ await sleep(1e3);
1683
+ }
1684
+ }
1685
+ };
1686
+ for (let i = 0; i < this.sandboxList.length; i += concurrency) {
1687
+ const batch = this.sandboxList.slice(i, i + concurrency);
1688
+ const promises = batch.map((sandbox, idx) => startSandbox(i + idx, sandbox));
1689
+ await Promise.all(promises);
1690
+ }
1691
+ logger8.info(`Successfully started ${this.sandboxList.length} sandboxes`);
1692
+ }
1693
+ async stop() {
1694
+ const promises = this.sandboxList.map((sandbox) => sandbox.stop());
1695
+ await Promise.allSettled(promises);
1696
+ logger8.info(`Stopped ${this.sandboxList.length} sandboxes`);
1697
+ }
1698
+ };
1699
+ var logger9 = initLogger("rock.model.client");
1700
+ var REQUEST_START_MARKER = "__REQUEST_START__";
1701
+ var REQUEST_END_MARKER = "__REQUEST_END__";
1702
+ var RESPONSE_START_MARKER = "__RESPONSE_START__";
1703
+ var RESPONSE_END_MARKER = "__RESPONSE_END__";
1704
+ var SESSION_END_MARKER = "__SESSION_END__";
1705
+ var ModelClient = class {
1706
+ logFile;
1707
+ constructor(config) {
1708
+ this.logFile = config?.logFileName ?? envVars.ROCK_MODEL_SERVICE_DATA_DIR + "/model.log";
1709
+ }
1710
+ /**
1711
+ * Anti-call LLM - input is response, output is next request
1712
+ */
1713
+ async antiCallLlm(index, lastResponse) {
1714
+ if (index < 0) {
1715
+ throw new Error("index must be greater than 0");
1716
+ }
1717
+ if (index === 0) {
1718
+ if (lastResponse !== void 0) {
1719
+ throw new Error("lastResponse must be undefined when index is 0");
1720
+ }
1721
+ await this.waitForFirstRequest();
1722
+ return this.popRequest(index + 1);
1723
+ }
1724
+ if (lastResponse === void 0) {
1725
+ throw new Error("lastResponse must not be undefined when index is greater than 0");
1726
+ }
1727
+ await this.pushResponse(index, lastResponse);
1728
+ return this.popRequest(index + 1);
1729
+ }
1730
+ /**
1731
+ * Push response to log file
1732
+ */
1733
+ async pushResponse(index, lastResponse) {
1734
+ const content = this.constructResponse(lastResponse, index);
1735
+ const lastResponseLine = await this.readLastResponseLine();
1736
+ if (lastResponseLine === null) {
1737
+ this.appendResponse(content);
1738
+ return;
1739
+ }
1740
+ const { meta } = this.parseResponseLine(lastResponseLine);
1741
+ const lastResponseIndex = meta.index;
1742
+ if (index < lastResponseIndex) {
1743
+ throw new Error(`index ${index} must not be smaller than last_response_index ${lastResponseIndex}`);
1744
+ }
1745
+ if (index === lastResponseIndex) {
1746
+ logger9.debug(`response index ${index} already exists, skip`);
1747
+ return;
1748
+ }
1749
+ this.appendResponse(content);
1750
+ }
1751
+ /**
1752
+ * Pop request from log file
1753
+ */
1754
+ async popRequest(index) {
1755
+ while (true) {
1756
+ const lastRequestLine = await this.readLastRequestLine();
1757
+ const { requestJson, meta } = this.parseRequestLine(lastRequestLine);
1758
+ if (requestJson === SESSION_END_MARKER) {
1759
+ return SESSION_END_MARKER;
1760
+ }
1761
+ if (meta.index === index) {
1762
+ return requestJson;
1763
+ }
1764
+ logger9.debug(`Last request is not the index ${index} we want, waiting...`);
1765
+ await this.sleep(1e3);
1766
+ }
1767
+ }
1768
+ /**
1769
+ * Wait for first request
1770
+ */
1771
+ async waitForFirstRequest() {
1772
+ while (true) {
1773
+ if (!existsSync(this.logFile)) {
1774
+ logger9.debug(`Log file ${this.logFile} not found, waiting...`);
1775
+ await this.sleep(1e3);
1776
+ continue;
1777
+ }
1778
+ const content = readFileSync(this.logFile, "utf-8");
1779
+ const lines = content.split("\n").filter((l) => l.trim());
1780
+ if (lines.length === 0) {
1781
+ logger9.debug(`Log file ${this.logFile} is empty, waiting for the first request...`);
1782
+ await this.sleep(1e3);
1783
+ continue;
1784
+ }
1785
+ return;
1786
+ }
1787
+ }
1788
+ parseRequestLine(lineContent) {
1789
+ if (lineContent.includes(SESSION_END_MARKER)) {
1790
+ return { requestJson: SESSION_END_MARKER, meta: {} };
1791
+ }
1792
+ const parts = lineContent.split(REQUEST_END_MARKER);
1793
+ const metaJson = parts[1] ?? "";
1794
+ const requestJson = parts[0]?.split(REQUEST_START_MARKER)[1] ?? "";
1795
+ const meta = JSON.parse(metaJson);
1796
+ return { requestJson, meta };
1797
+ }
1798
+ parseResponseLine(lineContent) {
1799
+ const parts = lineContent.split(RESPONSE_END_MARKER);
1800
+ const metaJson = parts[1] ?? "";
1801
+ const responseJson = parts[0]?.split(RESPONSE_START_MARKER)[1] ?? "";
1802
+ const meta = JSON.parse(metaJson);
1803
+ return { responseJson, meta };
1804
+ }
1805
+ async readLastRequestLine() {
1806
+ const content = readFileSync(this.logFile, "utf-8");
1807
+ const lines = content.split("\n").filter((l) => l.trim());
1808
+ for (let i = lines.length - 1; i >= 0; i--) {
1809
+ const line = lines[i];
1810
+ if (line && (line.includes(REQUEST_START_MARKER) || line.includes(SESSION_END_MARKER))) {
1811
+ return line;
1812
+ }
1813
+ }
1814
+ throw new Error(`No request found in log file ${this.logFile}`);
1815
+ }
1816
+ async readLastResponseLine() {
1817
+ const content = readFileSync(this.logFile, "utf-8");
1818
+ const lines = content.split("\n").filter((l) => l.trim());
1819
+ for (let i = lines.length - 1; i >= 0; i--) {
1820
+ const line = lines[i];
1821
+ if (line && line.includes(RESPONSE_START_MARKER)) {
1822
+ return line;
1823
+ }
1824
+ }
1825
+ return null;
1826
+ }
1827
+ appendResponse(content) {
1828
+ appendFileSync(this.logFile, content);
1829
+ }
1830
+ constructResponse(lastResponse, index) {
1831
+ const meta = {
1832
+ timestamp: Date.now(),
1833
+ index
1834
+ };
1835
+ const metaJson = JSON.stringify(meta);
1836
+ return `${RESPONSE_START_MARKER}${lastResponse}${RESPONSE_END_MARKER}${metaJson}
1837
+ `;
1838
+ }
1839
+ sleep(ms) {
1840
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
1841
+ }
1842
+ };
1843
+ initLogger("rock.model.service");
1844
+ var ModelService = class {
1845
+ process = null;
1846
+ /**
1847
+ * Start sandbox service
1848
+ */
1849
+ startSandboxService(config = {}) {
1850
+ const {
1851
+ modelServiceType = "local",
1852
+ configFile,
1853
+ host,
1854
+ port,
1855
+ proxyBaseUrl,
1856
+ retryableStatusCodes,
1857
+ requestTimeout
1858
+ } = config;
1859
+ const cmd = ["node", "main.js", "--type", modelServiceType];
1860
+ if (configFile) {
1861
+ cmd.push("--config-file", configFile);
1862
+ }
1863
+ if (host) {
1864
+ cmd.push("--host", host);
1865
+ }
1866
+ if (port) {
1867
+ cmd.push("--port", String(port));
1868
+ }
1869
+ if (proxyBaseUrl) {
1870
+ cmd.push("--proxy-base-url", proxyBaseUrl);
1871
+ }
1872
+ if (retryableStatusCodes) {
1873
+ cmd.push("--retryable-status-codes", retryableStatusCodes);
1874
+ }
1875
+ if (requestTimeout) {
1876
+ cmd.push("--request-timeout", String(requestTimeout));
1877
+ }
1878
+ const command = cmd[0] ?? "node";
1879
+ this.process = spawn(command, cmd.slice(1), {
1880
+ cwd: resolve(__dirname, "server"),
1881
+ stdio: "inherit"
1882
+ });
1883
+ if (!this.process) {
1884
+ throw new Error("Failed to spawn model service process");
1885
+ }
1886
+ return this.process;
1887
+ }
1888
+ /**
1889
+ * Start and wait for service to be available
1890
+ */
1891
+ async start(config = {}) {
1892
+ const { timeoutSeconds = 30, ...serviceConfig } = config;
1893
+ const process2 = this.startSandboxService(serviceConfig);
1894
+ const pid = process2.pid?.toString();
1895
+ if (!pid) {
1896
+ throw new Error("Failed to start model service");
1897
+ }
1898
+ const success = await this.waitServiceAvailable(
1899
+ timeoutSeconds,
1900
+ serviceConfig.host ?? "127.0.0.1",
1901
+ serviceConfig.port ?? 8080
1902
+ );
1903
+ if (!success) {
1904
+ await this.stop(pid);
1905
+ throw new Error("Model service start failed");
1906
+ }
1907
+ return pid;
1908
+ }
1909
+ /**
1910
+ * Start watching agent
1911
+ */
1912
+ async startWatchAgent(agentPid, host = "127.0.0.1", port = 8080) {
1913
+ await axios3.post(`http://${host}:${port}/v1/agent/watch`, { pid: agentPid });
1914
+ }
1915
+ /**
1916
+ * Stop service
1917
+ */
1918
+ async stop(pid) {
1919
+ const { execSync } = await import('child_process');
1920
+ try {
1921
+ execSync(`kill -9 ${pid}`);
1922
+ } catch {
1923
+ }
1924
+ }
1925
+ /**
1926
+ * Wait for service to be available
1927
+ */
1928
+ async waitServiceAvailable(timeoutSeconds, host, port) {
1929
+ const startTime = Date.now();
1930
+ while ((Date.now() - startTime) / 1e3 < timeoutSeconds) {
1931
+ try {
1932
+ await axios3.get(`http://${host}:${port}/health`);
1933
+ return true;
1934
+ } catch {
1935
+ await this.sleep(1e3);
1936
+ }
1937
+ }
1938
+ return false;
1939
+ }
1940
+ sleep(ms) {
1941
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
1942
+ }
1943
+ };
1944
+
1945
+ // src/index.ts
1946
+ var VERSION = "1.2.1";
1947
+
1948
+ export { BadRequestRockError, BashActionSchema, ChmodRequestSchema, ChmodResponseSchema, ChownRequestSchema, ChownResponseSchema, CloseResponseSchema, CloseSessionRequestSchema, CloseSessionResponseSchema, Codes, CommandResponseSchema, CommandRockError, CommandSchema, Constants, CreateBashSessionRequestSchema, CreateSessionResponseSchema, Deploy, EnvHubClient, EnvHubClientConfigSchema, EnvHubError, ExecuteBashSessionResponseSchema, HttpUtils, InternalServerRockError, InvalidParameterRockException, IsAliveResponseSchema, LinuxFileSystem, LinuxRemoteUser, ModelClient, ModelService, Network, ObservationSchema, OssSetupResponseSchema, PID_PREFIX, PID_SUFFIX, Process, ReadFileRequestSchema, ReadFileResponseSchema, ReasonPhrases, RockEnv, RockEnvInfoSchema, RockException, RunMode, Sandbox, SandboxConfigSchema, SandboxGroup, SandboxGroupConfigSchema, SandboxResponseSchema, SandboxStatusResponseSchema, SpeedupType, UploadRequestSchema, UploadResponseSchema, VERSION, WriteFileRequestSchema, WriteFileResponseSchema, arunWithRetry, createRockEnvInfo, createSandboxConfig, createSandboxGroupConfig, deprecated, deprecatedClass, extractNohupPid as extractNohupPidFromSandbox, fromRockException, getEnv, getReasonPhrase, getRequiredEnv, isBrowser, isClientError, isCommandError, isEnvSet, isError, isNode, isServerError, isSuccess, make, raiseForCode, retryAsync, rockEnvInfoToDict, sleep, withRetry, withTimeLogging };
1949
+ //# sourceMappingURL=index.mjs.map
1950
+ //# sourceMappingURL=index.mjs.map