@fastgpt-sdk/sandbox-adapter 0.0.36 → 0.0.37
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/adapters/BaseSandboxAdapter.d.ts +3 -1
- package/dist/adapters/OpenSandboxAdapter/index.d.ts +11 -7
- package/dist/adapters/OpenSandboxAdapter/type.d.ts +1 -1
- package/dist/adapters/SealosDevboxAdapter/api.d.ts +2 -2
- package/dist/adapters/SealosDevboxAdapter/index.d.ts +25 -2
- package/dist/adapters/SealosDevboxAdapter/type.d.ts +30 -0
- package/dist/adapters/index.d.ts +3 -3
- package/dist/adapters/ports.d.ts +7 -0
- package/dist/index.cjs +248 -45
- package/dist/index.js +246 -43
- package/dist/interfaces/ISandbox.d.ts +5 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/sandbox.d.ts +45 -0
- package/dist/utils/image.d.ts +3 -0
- package/dist/utils/url.d.ts +2 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ISandbox } from '../interfaces/ISandbox';
|
|
2
2
|
import { CommandPolyfillService } from '../polyfill/CommandPolyfillService';
|
|
3
|
-
import type { ContentReplaceEntry, DirectoryEntry, ExecuteOptions, ExecuteResult, FileDeleteResult, FileInfo, FileReadResult, FileWriteEntry, FileWriteResult, MoveEntry, PermissionEntry, ReadFileOptions, SandboxId, SandboxInfo, SandboxMetrics, SandboxStatus, SearchResult, StreamHandlers } from '../types';
|
|
3
|
+
import type { ContentReplaceEntry, DirectoryEntry, Endpoint, ExecuteOptions, ExecuteResult, FileDeleteResult, FileInfo, FileReadResult, FileWriteEntry, FileWriteResult, MoveEntry, PermissionEntry, ReadFileOptions, SandboxEndpointSelector, SandboxId, SandboxInfo, SandboxMetrics, SandboxProxyService, SandboxProxyTarget, SandboxStatus, SearchResult, StreamHandlers } from '../types';
|
|
4
4
|
/**
|
|
5
5
|
* Abstract base class for all sandbox adapters.
|
|
6
6
|
*
|
|
@@ -37,6 +37,8 @@ export declare abstract class BaseSandboxAdapter implements ISandbox {
|
|
|
37
37
|
waitUntilReady(timeoutMs?: number): Promise<void>;
|
|
38
38
|
waitUntilDeleted(timeoutMs?: number): Promise<void>;
|
|
39
39
|
renewExpiration(_additionalSeconds: number): Promise<void>;
|
|
40
|
+
getEndpoint(_selector: SandboxEndpointSelector): Promise<Endpoint>;
|
|
41
|
+
getProxyTarget(_service?: SandboxProxyService): Promise<SandboxProxyTarget>;
|
|
40
42
|
abstract execute(command: string, options?: ExecuteOptions): Promise<ExecuteResult>;
|
|
41
43
|
executeStream(command: string, handlers: StreamHandlers, options?: ExecuteOptions): Promise<void>;
|
|
42
44
|
executeBackground(_command: string, _options?: ExecuteOptions): Promise<{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Endpoint, ExecuteOptions, ExecuteResult, FileWriteEntry, FileWriteResult, SandboxId, SandboxInfo, SandboxMetrics, StreamHandlers } from '@/types';
|
|
1
|
+
import type { Endpoint, ExecuteOptions, ExecuteResult, FileWriteEntry, FileWriteResult, SandboxEndpointSelector, SandboxId, SandboxInfo, SandboxMetrics, SandboxProxyService, SandboxProxyTarget, StreamHandlers } from '@/types';
|
|
2
2
|
import { BaseSandboxAdapter } from '../BaseSandboxAdapter';
|
|
3
3
|
import type { OpenSandboxConfigType } from './type';
|
|
4
4
|
export type { OpenSandboxConfigType } from './type';
|
|
@@ -23,6 +23,11 @@ export interface OpenSandboxConnectionConfig {
|
|
|
23
23
|
debug?: boolean;
|
|
24
24
|
/** Route execd traffic through the OpenSandbox server proxy */
|
|
25
25
|
useServerProxy?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Rewrite OpenSandbox local endpoint host when sandbox-proxy runs on the host
|
|
28
|
+
* instead of inside Docker/Kubernetes.
|
|
29
|
+
*/
|
|
30
|
+
replaceDockerInternalWithLocalhost?: boolean;
|
|
26
31
|
/**
|
|
27
32
|
* Sandbox runtime type.
|
|
28
33
|
* @default 'docker'
|
|
@@ -65,8 +70,6 @@ export declare class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
65
70
|
private createConnectionConfig;
|
|
66
71
|
private static readonly STATE_MAP;
|
|
67
72
|
private mapStatus;
|
|
68
|
-
private convertImageSpec;
|
|
69
|
-
private parseImageSpec;
|
|
70
73
|
private convertResourceLimits;
|
|
71
74
|
private parseResourceLimits;
|
|
72
75
|
private extractExitCode;
|
|
@@ -85,11 +88,12 @@ export declare class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
85
88
|
*/
|
|
86
89
|
close(): Promise<void>;
|
|
87
90
|
/**
|
|
88
|
-
* Get endpoint information for a
|
|
89
|
-
* @param port The port number to get endpoint for
|
|
90
|
-
* @returns Endpoint with host, port, protocol and url fields
|
|
91
|
+
* Get endpoint information for a provider endpoint or well-known service.
|
|
91
92
|
*/
|
|
92
|
-
getEndpoint(
|
|
93
|
+
getEndpoint(selector: SandboxEndpointSelector): Promise<Endpoint>;
|
|
94
|
+
private getOpenSandboxEndpoint;
|
|
95
|
+
getProxyTarget(service?: SandboxProxyService): Promise<SandboxProxyTarget>;
|
|
96
|
+
private getDirectEndpointOrigin;
|
|
93
97
|
getInfo(): Promise<SandboxInfo | null>;
|
|
94
98
|
renewExpiration(additionalSeconds: number): Promise<void>;
|
|
95
99
|
writeFiles(entries: FileWriteEntry[]): Promise<FileWriteResult[]>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DevboxApiConfig, type DevboxApiResponse, type DevboxInfoData, type DevboxMutationData, type DownloadFileParams, type ExecRequest, type ExecResponseData, type UploadFileParams, type UploadResponseData } from './type';
|
|
1
|
+
import { type DevboxApiConfig, type DevboxApiResponse, type DevboxCreateRequest, type DevboxInfoData, type DevboxMutationData, type DownloadFileParams, type ExecRequest, type ExecResponseData, type UploadFileParams, type UploadResponseData } from './type';
|
|
2
2
|
/**
|
|
3
3
|
* HTTP client for the Sealos Devbox REST API.
|
|
4
4
|
*
|
|
@@ -11,7 +11,7 @@ export declare class DevboxApi {
|
|
|
11
11
|
private url;
|
|
12
12
|
private request;
|
|
13
13
|
/** POST /api/v1/devbox — create a devbox */
|
|
14
|
-
create(
|
|
14
|
+
create(req: DevboxCreateRequest): Promise<DevboxApiResponse<DevboxMutationData>>;
|
|
15
15
|
/** GET /api/v1/devbox/{name} — query devbox info (state + SSH) */
|
|
16
16
|
info(name: string): Promise<DevboxApiResponse<DevboxInfoData>>;
|
|
17
17
|
/** POST /api/v1/devbox/{name}/pause */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExecuteOptions, ExecuteResult, SandboxId, SandboxInfo } from '../../types';
|
|
1
|
+
import type { Endpoint, ExecuteOptions, ExecuteResult, ImageSpec, KubeAccessPolicy, LabelSpec, LifecyclePolicy, SandboxEndpointSelector, SandboxId, SandboxInfo, SandboxProxyService, SandboxProxyTarget } from '../../types';
|
|
2
2
|
import { BaseSandboxAdapter } from '../BaseSandboxAdapter';
|
|
3
3
|
/**
|
|
4
4
|
* Configuration for Sealos Devbox Adapter.
|
|
@@ -9,16 +9,33 @@ export interface SealosDevboxConfig {
|
|
|
9
9
|
/** JWT authentication token */
|
|
10
10
|
token: string;
|
|
11
11
|
sandboxId: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional override for the Sealos httpgate wildcard domain. When omitted,
|
|
14
|
+
* it is derived from gateway.url returned by Devbox Server.
|
|
15
|
+
*/
|
|
16
|
+
httpgateDomain?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface SealosDevboxCreateConfig {
|
|
19
|
+
image?: ImageSpec;
|
|
20
|
+
env?: Record<string, string>;
|
|
21
|
+
labels?: LabelSpec[];
|
|
22
|
+
upstreamID?: string;
|
|
23
|
+
kubeAccess?: KubeAccessPolicy;
|
|
24
|
+
lifecycle?: LifecyclePolicy;
|
|
25
|
+
workingDir?: string;
|
|
12
26
|
}
|
|
13
27
|
export declare class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
14
28
|
private config;
|
|
29
|
+
private createConfig?;
|
|
15
30
|
readonly provider: "sealosdevbox";
|
|
16
31
|
get rootPath(): string;
|
|
17
32
|
private api;
|
|
18
33
|
private _id;
|
|
19
|
-
constructor(config: SealosDevboxConfig);
|
|
34
|
+
constructor(config: SealosDevboxConfig, createConfig?: SealosDevboxCreateConfig | undefined);
|
|
20
35
|
get id(): SandboxId;
|
|
21
36
|
private StatusAdapt;
|
|
37
|
+
private buildCreateRequest;
|
|
38
|
+
private removeUndefined;
|
|
22
39
|
getInfo(): Promise<SandboxInfo | null>;
|
|
23
40
|
ensureRunning(): Promise<void>;
|
|
24
41
|
create(): Promise<void>;
|
|
@@ -26,6 +43,12 @@ export declare class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
26
43
|
start(): Promise<void>;
|
|
27
44
|
delete(): Promise<void>;
|
|
28
45
|
execute(command: string, options?: ExecuteOptions): Promise<ExecuteResult>;
|
|
46
|
+
getEndpoint(selector: SandboxEndpointSelector): Promise<Endpoint>;
|
|
47
|
+
getProxyTarget(service?: SandboxProxyService): Promise<SandboxProxyTarget>;
|
|
48
|
+
private getHttpgateTarget;
|
|
49
|
+
private getGatewayUniqueID;
|
|
50
|
+
private getHttpgateDomain;
|
|
51
|
+
private normalizeHttpgateDomain;
|
|
29
52
|
/**
|
|
30
53
|
* Check if the devbox is ready by querying info endpoint.
|
|
31
54
|
* Ready when spec, status, and phase are all "Running".
|
|
@@ -52,6 +52,23 @@ export interface DevboxMutationData {
|
|
|
52
52
|
state?: string;
|
|
53
53
|
status?: string;
|
|
54
54
|
}
|
|
55
|
+
/** Request body for the create endpoint. */
|
|
56
|
+
export interface DevboxCreateRequest {
|
|
57
|
+
name: string;
|
|
58
|
+
image?: string;
|
|
59
|
+
env?: Record<string, string>;
|
|
60
|
+
labels?: Array<{
|
|
61
|
+
key: string;
|
|
62
|
+
value: string;
|
|
63
|
+
}>;
|
|
64
|
+
upstreamID?: string;
|
|
65
|
+
kubeAccess?: {
|
|
66
|
+
enabled?: boolean;
|
|
67
|
+
roleTemplate?: 'view' | 'edit' | 'admin';
|
|
68
|
+
};
|
|
69
|
+
pauseAt?: string;
|
|
70
|
+
archiveAfterPauseTime?: string;
|
|
71
|
+
}
|
|
55
72
|
/** SSH connection info returned by the info endpoint. */
|
|
56
73
|
export interface DevboxSshInfo {
|
|
57
74
|
user: string;
|
|
@@ -63,14 +80,27 @@ export interface DevboxSshInfo {
|
|
|
63
80
|
privateKeyEncoding: string;
|
|
64
81
|
privateKeyBase64: string;
|
|
65
82
|
}
|
|
83
|
+
/** HTTP gateway info returned by the info endpoint. */
|
|
84
|
+
export interface DevboxGatewayInfo {
|
|
85
|
+
url: string;
|
|
86
|
+
token?: string;
|
|
87
|
+
port?: number;
|
|
88
|
+
uniqueID?: string;
|
|
89
|
+
}
|
|
66
90
|
/** Response data from the GET info endpoint. */
|
|
67
91
|
export interface DevboxInfoData {
|
|
68
92
|
name: string;
|
|
93
|
+
image?: string;
|
|
94
|
+
creationTimestamp?: string;
|
|
69
95
|
deletionTimestamp?: string | null;
|
|
70
96
|
state: {
|
|
71
97
|
phase: `${DevboxPhaseEnum}`;
|
|
72
98
|
};
|
|
73
99
|
ssh: DevboxSshInfo;
|
|
100
|
+
gateway?: DevboxGatewayInfo;
|
|
101
|
+
codeServerGateway?: DevboxGatewayInfo & {
|
|
102
|
+
password?: string;
|
|
103
|
+
};
|
|
74
104
|
}
|
|
75
105
|
/** Response data from the upload endpoint. */
|
|
76
106
|
export interface UploadResponseData {
|
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type SealosDevboxConfig } from './SealosDevboxAdapter';
|
|
1
|
+
import { type SealosDevboxConfig, type SealosDevboxCreateConfig } from './SealosDevboxAdapter';
|
|
2
2
|
import { type OpenSandboxConnectionConfig, type OpenSandboxConfigType } from './OpenSandboxAdapter';
|
|
3
3
|
import { type E2BConfig } from './E2BAdapter';
|
|
4
4
|
import { ISandbox } from '@/interfaces';
|
|
5
5
|
export { SealosDevboxAdapter } from './SealosDevboxAdapter';
|
|
6
|
-
export type { SealosDevboxConfig } from './SealosDevboxAdapter';
|
|
6
|
+
export type { SealosDevboxConfig, SealosDevboxCreateConfig } from './SealosDevboxAdapter';
|
|
7
7
|
export { OpenSandboxAdapter } from './OpenSandboxAdapter';
|
|
8
8
|
export type { OpenSandboxConfigType, OpenSandboxConnectionConfig } from './OpenSandboxAdapter';
|
|
9
9
|
export type { Volume as OpenSandboxVolume } from '@alibaba-group/opensandbox';
|
|
@@ -13,7 +13,7 @@ export type SandboxProviderType = 'opensandbox' | 'sealosdevbox' | 'e2b';
|
|
|
13
13
|
/** Maps each provider name to the ISandbox config type it exposes. */
|
|
14
14
|
interface SandboxConfigMap {
|
|
15
15
|
opensandbox: OpenSandboxConfigType;
|
|
16
|
-
sealosdevbox:
|
|
16
|
+
sealosdevbox: SealosDevboxCreateConfig;
|
|
17
17
|
e2b: undefined;
|
|
18
18
|
}
|
|
19
19
|
/** Resolves the concrete ISandbox type for a given provider. */
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenSandbox exposes execd through this direct endpoint. code-server itself is
|
|
3
|
+
* still reached via execd path proxying at /proxy/8080.
|
|
4
|
+
*/
|
|
5
|
+
export declare const OPEN_SANDBOX_EXECD_PORT = 44772;
|
|
6
|
+
export declare const OPEN_SANDBOX_CODE_SERVER_PORT = 8080;
|
|
7
|
+
export declare const SEALOS_DEVBOX_CODE_SERVER_PORT = 1318;
|
package/dist/index.cjs
CHANGED
|
@@ -4,39 +4,60 @@ var __defProp = Object.defineProperty;
|
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
7
12
|
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
8
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
21
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
22
|
for (let key of __getOwnPropNames(mod))
|
|
11
23
|
if (!__hasOwnProp.call(to, key))
|
|
12
24
|
__defProp(to, key, {
|
|
13
|
-
get: (
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
14
26
|
enumerable: true
|
|
15
27
|
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
16
30
|
return to;
|
|
17
31
|
};
|
|
18
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
19
32
|
var __toCommonJS = (from) => {
|
|
20
|
-
var entry = __moduleCache.get(from), desc;
|
|
33
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
21
34
|
if (entry)
|
|
22
35
|
return entry;
|
|
23
36
|
entry = __defProp({}, "__esModule", { value: true });
|
|
24
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
38
|
+
for (var key of __getOwnPropNames(from))
|
|
39
|
+
if (!__hasOwnProp.call(entry, key))
|
|
40
|
+
__defProp(entry, key, {
|
|
41
|
+
get: __accessProp.bind(from, key),
|
|
42
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
43
|
+
});
|
|
44
|
+
}
|
|
29
45
|
__moduleCache.set(from, entry);
|
|
30
46
|
return entry;
|
|
31
47
|
};
|
|
48
|
+
var __moduleCache;
|
|
32
49
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
50
|
+
var __returnValue = (v) => v;
|
|
51
|
+
function __exportSetter(name, newValue) {
|
|
52
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
53
|
+
}
|
|
33
54
|
var __export = (target, all) => {
|
|
34
55
|
for (var name in all)
|
|
35
56
|
__defProp(target, name, {
|
|
36
57
|
get: all[name],
|
|
37
58
|
enumerable: true,
|
|
38
59
|
configurable: true,
|
|
39
|
-
set: (
|
|
60
|
+
set: __exportSetter.bind(all, name)
|
|
40
61
|
});
|
|
41
62
|
};
|
|
42
63
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -19139,7 +19160,7 @@ var require_frame = __commonJS((exports2, module2) => {
|
|
|
19139
19160
|
var BUFFER_SIZE = 8 * 1024;
|
|
19140
19161
|
var buffer = null;
|
|
19141
19162
|
var bufIdx = BUFFER_SIZE;
|
|
19142
|
-
var randomFillSync = runtimeFeatures.has("crypto") ? require("node:crypto").randomFillSync : function
|
|
19163
|
+
var randomFillSync = runtimeFeatures.has("crypto") ? require("node:crypto").randomFillSync : function randomFillSync2(buffer2, _offset, _size) {
|
|
19143
19164
|
for (let i = 0;i < buffer2.length; ++i) {
|
|
19144
19165
|
buffer2[i] = Math.random() * 255 | 0;
|
|
19145
19166
|
}
|
|
@@ -21083,7 +21104,7 @@ var require_eventsource = __commonJS((exports2, module2) => {
|
|
|
21083
21104
|
|
|
21084
21105
|
// node_modules/undici/index.js
|
|
21085
21106
|
var require_undici = __commonJS((exports2, module2) => {
|
|
21086
|
-
var __filename = "/
|
|
21107
|
+
var __filename = "/Users/sealos/Documents/GitHub/agent-sandbox-adaptor/node_modules/undici/index.js";
|
|
21087
21108
|
var Client = require_client();
|
|
21088
21109
|
var Dispatcher = require_dispatcher();
|
|
21089
21110
|
var Pool = require_pool();
|
|
@@ -21206,7 +21227,7 @@ var require_undici = __commonJS((exports2, module2) => {
|
|
|
21206
21227
|
err.stack = stack ? `${stack}
|
|
21207
21228
|
${captureLines}` : capture.stack;
|
|
21208
21229
|
}
|
|
21209
|
-
module2.exports.fetch = function
|
|
21230
|
+
module2.exports.fetch = function fetch2(init, options = undefined) {
|
|
21210
21231
|
return fetchImpl(init, options).catch((err) => {
|
|
21211
21232
|
appendFetchStackTrace(err, __filename);
|
|
21212
21233
|
throw err;
|
|
@@ -45388,6 +45409,12 @@ class BaseSandboxAdapter {
|
|
|
45388
45409
|
async renewExpiration(_additionalSeconds) {
|
|
45389
45410
|
throw new FeatureNotSupportedError("Sandbox expiration renewal not supported by this provider", "renewExpiration", this.provider);
|
|
45390
45411
|
}
|
|
45412
|
+
async getEndpoint(_selector) {
|
|
45413
|
+
throw new FeatureNotSupportedError("Endpoint resolution not supported by this provider", "getEndpoint", this.provider);
|
|
45414
|
+
}
|
|
45415
|
+
async getProxyTarget(_service = "code-server") {
|
|
45416
|
+
throw new FeatureNotSupportedError("Proxy target resolution not supported by this provider", "getProxyTarget", this.provider);
|
|
45417
|
+
}
|
|
45391
45418
|
async executeStream(command, handlers, options) {
|
|
45392
45419
|
const result = await this.execute(command, options);
|
|
45393
45420
|
if (handlers.onStdout && result.stdout) {
|
|
@@ -45624,10 +45651,10 @@ class DevboxApi {
|
|
|
45624
45651
|
const result = await res.json();
|
|
45625
45652
|
return result;
|
|
45626
45653
|
}
|
|
45627
|
-
async create(
|
|
45654
|
+
async create(req) {
|
|
45628
45655
|
return this.request(this.url("/api/v1/devbox"), {
|
|
45629
45656
|
method: "POST",
|
|
45630
|
-
body: JSON.stringify(
|
|
45657
|
+
body: JSON.stringify(req)
|
|
45631
45658
|
});
|
|
45632
45659
|
}
|
|
45633
45660
|
async info(name) {
|
|
@@ -45685,18 +45712,60 @@ class DevboxApi {
|
|
|
45685
45712
|
}
|
|
45686
45713
|
}
|
|
45687
45714
|
|
|
45715
|
+
// src/adapters/ports.ts
|
|
45716
|
+
var OPEN_SANDBOX_EXECD_PORT = 44772;
|
|
45717
|
+
var OPEN_SANDBOX_CODE_SERVER_PORT = 8080;
|
|
45718
|
+
var SEALOS_DEVBOX_CODE_SERVER_PORT = 1318;
|
|
45719
|
+
|
|
45720
|
+
// src/utils/image.ts
|
|
45721
|
+
function formatImageSpec(image) {
|
|
45722
|
+
const parts = [image.repository];
|
|
45723
|
+
if (image.tag)
|
|
45724
|
+
parts.push(":", image.tag);
|
|
45725
|
+
if (image.digest)
|
|
45726
|
+
parts.push("@", image.digest);
|
|
45727
|
+
return parts.join("");
|
|
45728
|
+
}
|
|
45729
|
+
function parseImageSpec(image) {
|
|
45730
|
+
if (!image)
|
|
45731
|
+
return { repository: "" };
|
|
45732
|
+
const atIndex = image.indexOf("@");
|
|
45733
|
+
if (atIndex > -1) {
|
|
45734
|
+
return { repository: image.slice(0, atIndex), digest: image.slice(atIndex + 1) };
|
|
45735
|
+
}
|
|
45736
|
+
const colonIndex = image.indexOf(":");
|
|
45737
|
+
if (colonIndex > -1) {
|
|
45738
|
+
return { repository: image.slice(0, colonIndex), tag: image.slice(colonIndex + 1) };
|
|
45739
|
+
}
|
|
45740
|
+
return { repository: image };
|
|
45741
|
+
}
|
|
45742
|
+
|
|
45743
|
+
// src/utils/url.ts
|
|
45744
|
+
function normalizePathPrefix(path) {
|
|
45745
|
+
if (!path)
|
|
45746
|
+
return "";
|
|
45747
|
+
const normalized = path.startsWith("/") ? path : `/${path}`;
|
|
45748
|
+
return normalized.length > 1 ? normalized.replace(/\/+$/, "") : "";
|
|
45749
|
+
}
|
|
45750
|
+
function joinUrlPath(url, path) {
|
|
45751
|
+
const normalizedPath = normalizePathPrefix(path);
|
|
45752
|
+
return normalizedPath ? `${url.replace(/\/+$/, "")}${normalizedPath}` : url.replace(/\/+$/, "");
|
|
45753
|
+
}
|
|
45754
|
+
|
|
45688
45755
|
// src/adapters/SealosDevboxAdapter/index.ts
|
|
45689
45756
|
class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
45690
45757
|
config;
|
|
45758
|
+
createConfig;
|
|
45691
45759
|
provider = "sealosdevbox";
|
|
45692
45760
|
get rootPath() {
|
|
45693
45761
|
return "/home/devbox/workspace";
|
|
45694
45762
|
}
|
|
45695
45763
|
api;
|
|
45696
45764
|
_id;
|
|
45697
|
-
constructor(config) {
|
|
45765
|
+
constructor(config, createConfig) {
|
|
45698
45766
|
super();
|
|
45699
45767
|
this.config = config;
|
|
45768
|
+
this.createConfig = createConfig;
|
|
45700
45769
|
this.api = new DevboxApi({ baseUrl: config.baseUrl, token: config.token });
|
|
45701
45770
|
this._id = config.sandboxId;
|
|
45702
45771
|
this.polyfillService = new CommandPolyfillService(this);
|
|
@@ -45721,6 +45790,26 @@ class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
45721
45790
|
return "Error";
|
|
45722
45791
|
}
|
|
45723
45792
|
}
|
|
45793
|
+
buildCreateRequest() {
|
|
45794
|
+
const spec = this.createConfig ?? {};
|
|
45795
|
+
const env = { ...spec.env ?? {} };
|
|
45796
|
+
if (spec.workingDir && !env.CODEX_GATEWAY_CWD) {
|
|
45797
|
+
env.CODEX_GATEWAY_CWD = spec.workingDir;
|
|
45798
|
+
}
|
|
45799
|
+
return this.removeUndefined({
|
|
45800
|
+
name: this._id,
|
|
45801
|
+
image: spec.image ? formatImageSpec(spec.image) : undefined,
|
|
45802
|
+
env: Object.keys(env).length > 0 ? env : undefined,
|
|
45803
|
+
labels: spec.labels,
|
|
45804
|
+
upstreamID: spec.upstreamID,
|
|
45805
|
+
kubeAccess: spec.kubeAccess,
|
|
45806
|
+
pauseAt: spec.lifecycle?.pauseAt,
|
|
45807
|
+
archiveAfterPauseTime: spec.lifecycle?.archiveAfterPauseTime
|
|
45808
|
+
});
|
|
45809
|
+
}
|
|
45810
|
+
removeUndefined(obj) {
|
|
45811
|
+
return Object.fromEntries(Object.entries(obj).filter(([, value]) => value !== undefined));
|
|
45812
|
+
}
|
|
45724
45813
|
async getInfo() {
|
|
45725
45814
|
try {
|
|
45726
45815
|
const res = await this.api.info(this._id);
|
|
@@ -45732,10 +45821,10 @@ class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
45732
45821
|
this._status = { state: this.StatusAdapt(data), message: res.message };
|
|
45733
45822
|
return {
|
|
45734
45823
|
id: data.name,
|
|
45735
|
-
image:
|
|
45824
|
+
image: parseImageSpec(data.image),
|
|
45736
45825
|
entrypoint: [],
|
|
45737
45826
|
status: this._status,
|
|
45738
|
-
createdAt: new Date
|
|
45827
|
+
createdAt: data.creationTimestamp ? new Date(data.creationTimestamp) : new Date
|
|
45739
45828
|
};
|
|
45740
45829
|
} catch (error) {
|
|
45741
45830
|
throw new CommandExecutionError(`Failed to get sandbox info`, "getInfo", error instanceof Error ? error : undefined);
|
|
@@ -45773,7 +45862,10 @@ class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
45773
45862
|
async create() {
|
|
45774
45863
|
try {
|
|
45775
45864
|
this._status = { state: "Creating" };
|
|
45776
|
-
await this.api.create(this.
|
|
45865
|
+
const res = await this.api.create(this.buildCreateRequest());
|
|
45866
|
+
if (res.code !== 200 && res.code !== 201) {
|
|
45867
|
+
throw new Error(res.message || `Devbox create failed with code ${res.code}`);
|
|
45868
|
+
}
|
|
45777
45869
|
await this.waitUntilReady();
|
|
45778
45870
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
45779
45871
|
this._status = { state: "Running" };
|
|
@@ -45829,11 +45921,98 @@ class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
45829
45921
|
throw new CommandExecutionError(`Command execution failed: ${error?.message || error?.code}`, command, error instanceof Error ? error : undefined);
|
|
45830
45922
|
}
|
|
45831
45923
|
}
|
|
45924
|
+
async getEndpoint(selector) {
|
|
45925
|
+
const port = typeof selector === "number" ? selector : SEALOS_DEVBOX_CODE_SERVER_PORT;
|
|
45926
|
+
const target = await this.getHttpgateTarget(port);
|
|
45927
|
+
const url = new URL(target.origin);
|
|
45928
|
+
return {
|
|
45929
|
+
host: url.host,
|
|
45930
|
+
port: target.port,
|
|
45931
|
+
protocol: url.protocol === "https:" ? "https" : "http",
|
|
45932
|
+
url: joinUrlPath(target.origin, target.basePath)
|
|
45933
|
+
};
|
|
45934
|
+
}
|
|
45935
|
+
async getProxyTarget(service = "code-server") {
|
|
45936
|
+
if (service !== "code-server") {
|
|
45937
|
+
throw new FeatureNotSupportedError(`Proxy service "${service}" is not supported by this provider`, "getProxyTarget", this.provider);
|
|
45938
|
+
}
|
|
45939
|
+
const target = await this.getHttpgateTarget(SEALOS_DEVBOX_CODE_SERVER_PORT);
|
|
45940
|
+
return {
|
|
45941
|
+
service,
|
|
45942
|
+
origin: target.origin,
|
|
45943
|
+
basePath: target.basePath,
|
|
45944
|
+
auth: "code-server",
|
|
45945
|
+
...target.password ? { password: target.password } : {}
|
|
45946
|
+
};
|
|
45947
|
+
}
|
|
45948
|
+
async getHttpgateTarget(port) {
|
|
45949
|
+
const res = await this.api.info(this._id);
|
|
45950
|
+
if (res.code !== 200 || !res.data) {
|
|
45951
|
+
throw new ConnectionError(`Failed to get devbox info: ${res.message}`, this.config.baseUrl);
|
|
45952
|
+
}
|
|
45953
|
+
if (port === SEALOS_DEVBOX_CODE_SERVER_PORT) {
|
|
45954
|
+
const gateway2 = res.data.codeServerGateway;
|
|
45955
|
+
if (!gateway2?.url) {
|
|
45956
|
+
throw new ConnectionError("Devbox info does not include codeServerGateway.url; cannot resolve code-server endpoint", this.config.baseUrl);
|
|
45957
|
+
}
|
|
45958
|
+
const codeServerUrl = new URL(gateway2.url);
|
|
45959
|
+
return {
|
|
45960
|
+
origin: codeServerUrl.origin,
|
|
45961
|
+
basePath: normalizePathPrefix(codeServerUrl.pathname),
|
|
45962
|
+
port: gateway2.port ?? port,
|
|
45963
|
+
password: gateway2.password
|
|
45964
|
+
};
|
|
45965
|
+
}
|
|
45966
|
+
const gatewayUrl = res.data.gateway?.url;
|
|
45967
|
+
if (!gatewayUrl) {
|
|
45968
|
+
throw new ConnectionError("Devbox info does not include gateway.url; cannot derive httpgate endpoint", this.config.baseUrl);
|
|
45969
|
+
}
|
|
45970
|
+
const gateway = new URL(gatewayUrl);
|
|
45971
|
+
const uniqueID = this.getGatewayUniqueID(res.data, gateway);
|
|
45972
|
+
const domain = this.getHttpgateDomain(gateway);
|
|
45973
|
+
return {
|
|
45974
|
+
origin: `${gateway.protocol}//devbox-${uniqueID}-${port}.${domain}`,
|
|
45975
|
+
basePath: "",
|
|
45976
|
+
port
|
|
45977
|
+
};
|
|
45978
|
+
}
|
|
45979
|
+
getGatewayUniqueID(data, gateway) {
|
|
45980
|
+
if (data.gateway?.uniqueID)
|
|
45981
|
+
return data.gateway.uniqueID;
|
|
45982
|
+
const parts = gateway.pathname.split("/").filter(Boolean);
|
|
45983
|
+
const uniqueID = parts[parts.length - 1];
|
|
45984
|
+
if (!uniqueID) {
|
|
45985
|
+
throw new ConnectionError("Devbox gateway.url does not include uniqueID; cannot derive httpgate endpoint", this.config.baseUrl);
|
|
45986
|
+
}
|
|
45987
|
+
return uniqueID;
|
|
45988
|
+
}
|
|
45989
|
+
getHttpgateDomain(gateway) {
|
|
45990
|
+
if (this.config.httpgateDomain) {
|
|
45991
|
+
return this.normalizeHttpgateDomain(this.config.httpgateDomain);
|
|
45992
|
+
}
|
|
45993
|
+
const prefix = "devbox-gateway.";
|
|
45994
|
+
if (!gateway.host.startsWith(prefix)) {
|
|
45995
|
+
throw new ConnectionError(`Cannot derive httpgate domain from gateway host "${gateway.host}"`, this.config.baseUrl);
|
|
45996
|
+
}
|
|
45997
|
+
return gateway.host.slice(prefix.length);
|
|
45998
|
+
}
|
|
45999
|
+
normalizeHttpgateDomain(domain) {
|
|
46000
|
+
const trimmed = domain.trim().replace(/^\.+|\.+$/g, "");
|
|
46001
|
+
if (!trimmed) {
|
|
46002
|
+
throw new ConnectionError("httpgateDomain is empty", this.config.baseUrl);
|
|
46003
|
+
}
|
|
46004
|
+
if (trimmed.includes("://")) {
|
|
46005
|
+
return new URL(trimmed).host;
|
|
46006
|
+
}
|
|
46007
|
+
return trimmed;
|
|
46008
|
+
}
|
|
45832
46009
|
async ping() {
|
|
45833
46010
|
try {
|
|
45834
46011
|
const res = await this.api.info(this._id);
|
|
45835
46012
|
if (res.code !== 200)
|
|
45836
46013
|
return false;
|
|
46014
|
+
if (!res.data)
|
|
46015
|
+
return false;
|
|
45837
46016
|
return res.data.state.phase === "Running" /* Running */;
|
|
45838
46017
|
} catch {
|
|
45839
46018
|
return false;
|
|
@@ -47425,7 +47604,7 @@ function createNodeFetch() {
|
|
|
47425
47604
|
const nodeFetch = async (input, init) => {
|
|
47426
47605
|
dispatcherPromise ??= (async () => {
|
|
47427
47606
|
try {
|
|
47428
|
-
const mod = await Promise.resolve().then(() => __toESM(require_undici()));
|
|
47607
|
+
const mod = await Promise.resolve().then(() => __toESM(require_undici(), 1));
|
|
47429
47608
|
const Agent = mod.Agent;
|
|
47430
47609
|
if (!Agent) {
|
|
47431
47610
|
return;
|
|
@@ -48085,27 +48264,6 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48085
48264
|
message: sdkStatus.message
|
|
48086
48265
|
};
|
|
48087
48266
|
}
|
|
48088
|
-
convertImageSpec(image) {
|
|
48089
|
-
const parts = [image.repository];
|
|
48090
|
-
if (image.tag) {
|
|
48091
|
-
parts.push(":", image.tag);
|
|
48092
|
-
}
|
|
48093
|
-
if (image.digest) {
|
|
48094
|
-
parts.push("@", image.digest);
|
|
48095
|
-
}
|
|
48096
|
-
return parts.join("");
|
|
48097
|
-
}
|
|
48098
|
-
parseImageSpec(image) {
|
|
48099
|
-
const atIndex = image.indexOf("@");
|
|
48100
|
-
if (atIndex > -1) {
|
|
48101
|
-
return { repository: image.slice(0, atIndex), digest: image.slice(atIndex + 1) };
|
|
48102
|
-
}
|
|
48103
|
-
const colonIndex = image.indexOf(":");
|
|
48104
|
-
if (colonIndex > -1) {
|
|
48105
|
-
return { repository: image.slice(0, colonIndex), tag: image.slice(colonIndex + 1) };
|
|
48106
|
-
}
|
|
48107
|
-
return { repository: image };
|
|
48108
|
-
}
|
|
48109
48267
|
convertResourceLimits(resourceLimits) {
|
|
48110
48268
|
if (!resourceLimits)
|
|
48111
48269
|
return;
|
|
@@ -48220,7 +48378,7 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48220
48378
|
}
|
|
48221
48379
|
try {
|
|
48222
48380
|
this._status = { state: "Creating" };
|
|
48223
|
-
const image =
|
|
48381
|
+
const image = formatImageSpec(cfg.image);
|
|
48224
48382
|
const resource = this.convertResourceLimits(cfg.resourceLimits);
|
|
48225
48383
|
this.sandbox = await Sandbox.create({
|
|
48226
48384
|
connectionConfig: this._connection,
|
|
@@ -48324,7 +48482,18 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48324
48482
|
async close() {
|
|
48325
48483
|
await this.sandbox.close();
|
|
48326
48484
|
}
|
|
48327
|
-
async getEndpoint(
|
|
48485
|
+
async getEndpoint(selector) {
|
|
48486
|
+
const port = typeof selector === "number" ? selector : OPEN_SANDBOX_EXECD_PORT;
|
|
48487
|
+
const endpoint = await this.getOpenSandboxEndpoint(port);
|
|
48488
|
+
if (selector === "code-server") {
|
|
48489
|
+
return {
|
|
48490
|
+
...endpoint,
|
|
48491
|
+
url: joinUrlPath(endpoint.url, `/proxy/${OPEN_SANDBOX_CODE_SERVER_PORT}`)
|
|
48492
|
+
};
|
|
48493
|
+
}
|
|
48494
|
+
return endpoint;
|
|
48495
|
+
}
|
|
48496
|
+
async getOpenSandboxEndpoint(port) {
|
|
48328
48497
|
const sdkEndpoint = await this.sandbox.getEndpoint(port);
|
|
48329
48498
|
const raw = sdkEndpoint.endpoint;
|
|
48330
48499
|
const colonIdx = raw.lastIndexOf(":");
|
|
@@ -48343,6 +48512,40 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48343
48512
|
url: `https://${raw}`
|
|
48344
48513
|
};
|
|
48345
48514
|
}
|
|
48515
|
+
async getProxyTarget(service = "code-server") {
|
|
48516
|
+
if (service !== "code-server") {
|
|
48517
|
+
throw new FeatureNotSupportedError(`Proxy service "${service}" is not supported by this provider`, "getProxyTarget", this.provider);
|
|
48518
|
+
}
|
|
48519
|
+
return {
|
|
48520
|
+
service,
|
|
48521
|
+
origin: await this.getDirectEndpointOrigin(OPEN_SANDBOX_EXECD_PORT),
|
|
48522
|
+
basePath: `/proxy/${OPEN_SANDBOX_CODE_SERVER_PORT}`,
|
|
48523
|
+
auth: "code-server"
|
|
48524
|
+
};
|
|
48525
|
+
}
|
|
48526
|
+
async getDirectEndpointOrigin(port) {
|
|
48527
|
+
if (!this.id) {
|
|
48528
|
+
throw new SandboxStateError("Sandbox not initialized. Call create() or connect() first.", "UnExist", "Running");
|
|
48529
|
+
}
|
|
48530
|
+
const headers = {
|
|
48531
|
+
...this._connection.headers,
|
|
48532
|
+
Accept: "application/json"
|
|
48533
|
+
};
|
|
48534
|
+
const response = await this._connection.fetch(`${this._connection.getBaseUrl()}/sandboxes/${this.id}/endpoints/${port}?use_server_proxy=false`, { method: "GET", headers });
|
|
48535
|
+
if (!response.ok) {
|
|
48536
|
+
throw new ConnectionError(`OpenSandbox endpoint lookup failed: HTTP ${response.status}`, this.connectionConfig.baseUrl);
|
|
48537
|
+
}
|
|
48538
|
+
const data = await response.json();
|
|
48539
|
+
if (!data.endpoint) {
|
|
48540
|
+
throw new ConnectionError("OpenSandbox returned no endpoint", this.connectionConfig.baseUrl);
|
|
48541
|
+
}
|
|
48542
|
+
let hostPort = data.endpoint.replace(/\/proxy\/\d+\/?$/, "");
|
|
48543
|
+
if (this.connectionConfig.replaceDockerInternalWithLocalhost) {
|
|
48544
|
+
hostPort = hostPort.replace(/^host\.docker\.internal\b/, "localhost");
|
|
48545
|
+
}
|
|
48546
|
+
const url = new URL(/^https?:\/\//.test(hostPort) ? hostPort : `http://${hostPort}`);
|
|
48547
|
+
return url.origin;
|
|
48548
|
+
}
|
|
48346
48549
|
async getInfo() {
|
|
48347
48550
|
if (!this._sandbox) {
|
|
48348
48551
|
return null;
|
|
@@ -48351,7 +48554,7 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48351
48554
|
const info = await this.sandbox.getInfo();
|
|
48352
48555
|
return {
|
|
48353
48556
|
id: info.id,
|
|
48354
|
-
image: typeof info.image === "string" ?
|
|
48557
|
+
image: typeof info.image === "string" ? parseImageSpec(info.image) : ("uri" in info.image) ? parseImageSpec(info.image.uri) : info.image,
|
|
48355
48558
|
entrypoint: info.entrypoint,
|
|
48356
48559
|
metadata: info.metadata,
|
|
48357
48560
|
status: this.mapStatus(info.status),
|
|
@@ -48533,7 +48736,7 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48533
48736
|
}
|
|
48534
48737
|
|
|
48535
48738
|
// src/adapters/E2BAdapter/index.ts
|
|
48536
|
-
var import_code_interpreter = __toESM(require_dist3());
|
|
48739
|
+
var import_code_interpreter = __toESM(require_dist3(), 1);
|
|
48537
48740
|
class E2BAdapter extends BaseSandboxAdapter {
|
|
48538
48741
|
config;
|
|
48539
48742
|
provider = "e2b";
|
|
@@ -48853,7 +49056,7 @@ function createSandbox(provider, config, createConfig) {
|
|
|
48853
49056
|
case "opensandbox":
|
|
48854
49057
|
return new OpenSandboxAdapter(config, createConfig);
|
|
48855
49058
|
case "sealosdevbox":
|
|
48856
|
-
return new SealosDevboxAdapter(config);
|
|
49059
|
+
return new SealosDevboxAdapter(config, createConfig);
|
|
48857
49060
|
case "e2b":
|
|
48858
49061
|
return new E2BAdapter(config);
|
|
48859
49062
|
default:
|
package/dist/index.js
CHANGED
|
@@ -5,39 +5,60 @@ var __defProp = Object.defineProperty;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
8
13
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
9
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
23
|
for (let key of __getOwnPropNames(mod))
|
|
12
24
|
if (!__hasOwnProp.call(to, key))
|
|
13
25
|
__defProp(to, key, {
|
|
14
|
-
get: (
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
15
27
|
enumerable: true
|
|
16
28
|
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
17
31
|
return to;
|
|
18
32
|
};
|
|
19
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
20
33
|
var __toCommonJS = (from) => {
|
|
21
|
-
var entry = __moduleCache.get(from), desc;
|
|
34
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
22
35
|
if (entry)
|
|
23
36
|
return entry;
|
|
24
37
|
entry = __defProp({}, "__esModule", { value: true });
|
|
25
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
39
|
+
for (var key of __getOwnPropNames(from))
|
|
40
|
+
if (!__hasOwnProp.call(entry, key))
|
|
41
|
+
__defProp(entry, key, {
|
|
42
|
+
get: __accessProp.bind(from, key),
|
|
43
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
44
|
+
});
|
|
45
|
+
}
|
|
30
46
|
__moduleCache.set(from, entry);
|
|
31
47
|
return entry;
|
|
32
48
|
};
|
|
49
|
+
var __moduleCache;
|
|
33
50
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
51
|
+
var __returnValue = (v) => v;
|
|
52
|
+
function __exportSetter(name, newValue) {
|
|
53
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
54
|
+
}
|
|
34
55
|
var __export = (target, all) => {
|
|
35
56
|
for (var name in all)
|
|
36
57
|
__defProp(target, name, {
|
|
37
58
|
get: all[name],
|
|
38
59
|
enumerable: true,
|
|
39
60
|
configurable: true,
|
|
40
|
-
set: (
|
|
61
|
+
set: __exportSetter.bind(all, name)
|
|
41
62
|
});
|
|
42
63
|
};
|
|
43
64
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -19141,7 +19162,7 @@ var require_frame = __commonJS((exports, module) => {
|
|
|
19141
19162
|
var BUFFER_SIZE = 8 * 1024;
|
|
19142
19163
|
var buffer = null;
|
|
19143
19164
|
var bufIdx = BUFFER_SIZE;
|
|
19144
|
-
var randomFillSync = runtimeFeatures.has("crypto") ? __require("node:crypto").randomFillSync : function
|
|
19165
|
+
var randomFillSync = runtimeFeatures.has("crypto") ? __require("node:crypto").randomFillSync : function randomFillSync2(buffer2, _offset, _size) {
|
|
19145
19166
|
for (let i = 0;i < buffer2.length; ++i) {
|
|
19146
19167
|
buffer2[i] = Math.random() * 255 | 0;
|
|
19147
19168
|
}
|
|
@@ -21085,7 +21106,7 @@ var require_eventsource = __commonJS((exports, module) => {
|
|
|
21085
21106
|
|
|
21086
21107
|
// node_modules/undici/index.js
|
|
21087
21108
|
var require_undici = __commonJS((exports, module) => {
|
|
21088
|
-
var __filename = "/
|
|
21109
|
+
var __filename = "/Users/sealos/Documents/GitHub/agent-sandbox-adaptor/node_modules/undici/index.js";
|
|
21089
21110
|
var Client = require_client();
|
|
21090
21111
|
var Dispatcher = require_dispatcher();
|
|
21091
21112
|
var Pool = require_pool();
|
|
@@ -21208,7 +21229,7 @@ var require_undici = __commonJS((exports, module) => {
|
|
|
21208
21229
|
err.stack = stack ? `${stack}
|
|
21209
21230
|
${captureLines}` : capture.stack;
|
|
21210
21231
|
}
|
|
21211
|
-
exports.fetch = function
|
|
21232
|
+
exports.fetch = function fetch2(init, options = undefined) {
|
|
21212
21233
|
return fetchImpl(init, options).catch((err) => {
|
|
21213
21234
|
appendFetchStackTrace(err, __filename);
|
|
21214
21235
|
throw err;
|
|
@@ -45372,6 +45393,12 @@ class BaseSandboxAdapter {
|
|
|
45372
45393
|
async renewExpiration(_additionalSeconds) {
|
|
45373
45394
|
throw new FeatureNotSupportedError("Sandbox expiration renewal not supported by this provider", "renewExpiration", this.provider);
|
|
45374
45395
|
}
|
|
45396
|
+
async getEndpoint(_selector) {
|
|
45397
|
+
throw new FeatureNotSupportedError("Endpoint resolution not supported by this provider", "getEndpoint", this.provider);
|
|
45398
|
+
}
|
|
45399
|
+
async getProxyTarget(_service = "code-server") {
|
|
45400
|
+
throw new FeatureNotSupportedError("Proxy target resolution not supported by this provider", "getProxyTarget", this.provider);
|
|
45401
|
+
}
|
|
45375
45402
|
async executeStream(command, handlers, options) {
|
|
45376
45403
|
const result = await this.execute(command, options);
|
|
45377
45404
|
if (handlers.onStdout && result.stdout) {
|
|
@@ -45608,10 +45635,10 @@ class DevboxApi {
|
|
|
45608
45635
|
const result = await res.json();
|
|
45609
45636
|
return result;
|
|
45610
45637
|
}
|
|
45611
|
-
async create(
|
|
45638
|
+
async create(req) {
|
|
45612
45639
|
return this.request(this.url("/api/v1/devbox"), {
|
|
45613
45640
|
method: "POST",
|
|
45614
|
-
body: JSON.stringify(
|
|
45641
|
+
body: JSON.stringify(req)
|
|
45615
45642
|
});
|
|
45616
45643
|
}
|
|
45617
45644
|
async info(name) {
|
|
@@ -45669,18 +45696,60 @@ class DevboxApi {
|
|
|
45669
45696
|
}
|
|
45670
45697
|
}
|
|
45671
45698
|
|
|
45699
|
+
// src/adapters/ports.ts
|
|
45700
|
+
var OPEN_SANDBOX_EXECD_PORT = 44772;
|
|
45701
|
+
var OPEN_SANDBOX_CODE_SERVER_PORT = 8080;
|
|
45702
|
+
var SEALOS_DEVBOX_CODE_SERVER_PORT = 1318;
|
|
45703
|
+
|
|
45704
|
+
// src/utils/image.ts
|
|
45705
|
+
function formatImageSpec(image) {
|
|
45706
|
+
const parts = [image.repository];
|
|
45707
|
+
if (image.tag)
|
|
45708
|
+
parts.push(":", image.tag);
|
|
45709
|
+
if (image.digest)
|
|
45710
|
+
parts.push("@", image.digest);
|
|
45711
|
+
return parts.join("");
|
|
45712
|
+
}
|
|
45713
|
+
function parseImageSpec(image) {
|
|
45714
|
+
if (!image)
|
|
45715
|
+
return { repository: "" };
|
|
45716
|
+
const atIndex = image.indexOf("@");
|
|
45717
|
+
if (atIndex > -1) {
|
|
45718
|
+
return { repository: image.slice(0, atIndex), digest: image.slice(atIndex + 1) };
|
|
45719
|
+
}
|
|
45720
|
+
const colonIndex = image.indexOf(":");
|
|
45721
|
+
if (colonIndex > -1) {
|
|
45722
|
+
return { repository: image.slice(0, colonIndex), tag: image.slice(colonIndex + 1) };
|
|
45723
|
+
}
|
|
45724
|
+
return { repository: image };
|
|
45725
|
+
}
|
|
45726
|
+
|
|
45727
|
+
// src/utils/url.ts
|
|
45728
|
+
function normalizePathPrefix(path) {
|
|
45729
|
+
if (!path)
|
|
45730
|
+
return "";
|
|
45731
|
+
const normalized = path.startsWith("/") ? path : `/${path}`;
|
|
45732
|
+
return normalized.length > 1 ? normalized.replace(/\/+$/, "") : "";
|
|
45733
|
+
}
|
|
45734
|
+
function joinUrlPath(url, path) {
|
|
45735
|
+
const normalizedPath = normalizePathPrefix(path);
|
|
45736
|
+
return normalizedPath ? `${url.replace(/\/+$/, "")}${normalizedPath}` : url.replace(/\/+$/, "");
|
|
45737
|
+
}
|
|
45738
|
+
|
|
45672
45739
|
// src/adapters/SealosDevboxAdapter/index.ts
|
|
45673
45740
|
class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
45674
45741
|
config;
|
|
45742
|
+
createConfig;
|
|
45675
45743
|
provider = "sealosdevbox";
|
|
45676
45744
|
get rootPath() {
|
|
45677
45745
|
return "/home/devbox/workspace";
|
|
45678
45746
|
}
|
|
45679
45747
|
api;
|
|
45680
45748
|
_id;
|
|
45681
|
-
constructor(config) {
|
|
45749
|
+
constructor(config, createConfig) {
|
|
45682
45750
|
super();
|
|
45683
45751
|
this.config = config;
|
|
45752
|
+
this.createConfig = createConfig;
|
|
45684
45753
|
this.api = new DevboxApi({ baseUrl: config.baseUrl, token: config.token });
|
|
45685
45754
|
this._id = config.sandboxId;
|
|
45686
45755
|
this.polyfillService = new CommandPolyfillService(this);
|
|
@@ -45705,6 +45774,26 @@ class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
45705
45774
|
return "Error";
|
|
45706
45775
|
}
|
|
45707
45776
|
}
|
|
45777
|
+
buildCreateRequest() {
|
|
45778
|
+
const spec = this.createConfig ?? {};
|
|
45779
|
+
const env = { ...spec.env ?? {} };
|
|
45780
|
+
if (spec.workingDir && !env.CODEX_GATEWAY_CWD) {
|
|
45781
|
+
env.CODEX_GATEWAY_CWD = spec.workingDir;
|
|
45782
|
+
}
|
|
45783
|
+
return this.removeUndefined({
|
|
45784
|
+
name: this._id,
|
|
45785
|
+
image: spec.image ? formatImageSpec(spec.image) : undefined,
|
|
45786
|
+
env: Object.keys(env).length > 0 ? env : undefined,
|
|
45787
|
+
labels: spec.labels,
|
|
45788
|
+
upstreamID: spec.upstreamID,
|
|
45789
|
+
kubeAccess: spec.kubeAccess,
|
|
45790
|
+
pauseAt: spec.lifecycle?.pauseAt,
|
|
45791
|
+
archiveAfterPauseTime: spec.lifecycle?.archiveAfterPauseTime
|
|
45792
|
+
});
|
|
45793
|
+
}
|
|
45794
|
+
removeUndefined(obj) {
|
|
45795
|
+
return Object.fromEntries(Object.entries(obj).filter(([, value]) => value !== undefined));
|
|
45796
|
+
}
|
|
45708
45797
|
async getInfo() {
|
|
45709
45798
|
try {
|
|
45710
45799
|
const res = await this.api.info(this._id);
|
|
@@ -45716,10 +45805,10 @@ class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
45716
45805
|
this._status = { state: this.StatusAdapt(data), message: res.message };
|
|
45717
45806
|
return {
|
|
45718
45807
|
id: data.name,
|
|
45719
|
-
image:
|
|
45808
|
+
image: parseImageSpec(data.image),
|
|
45720
45809
|
entrypoint: [],
|
|
45721
45810
|
status: this._status,
|
|
45722
|
-
createdAt: new Date
|
|
45811
|
+
createdAt: data.creationTimestamp ? new Date(data.creationTimestamp) : new Date
|
|
45723
45812
|
};
|
|
45724
45813
|
} catch (error) {
|
|
45725
45814
|
throw new CommandExecutionError(`Failed to get sandbox info`, "getInfo", error instanceof Error ? error : undefined);
|
|
@@ -45757,7 +45846,10 @@ class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
45757
45846
|
async create() {
|
|
45758
45847
|
try {
|
|
45759
45848
|
this._status = { state: "Creating" };
|
|
45760
|
-
await this.api.create(this.
|
|
45849
|
+
const res = await this.api.create(this.buildCreateRequest());
|
|
45850
|
+
if (res.code !== 200 && res.code !== 201) {
|
|
45851
|
+
throw new Error(res.message || `Devbox create failed with code ${res.code}`);
|
|
45852
|
+
}
|
|
45761
45853
|
await this.waitUntilReady();
|
|
45762
45854
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
45763
45855
|
this._status = { state: "Running" };
|
|
@@ -45813,11 +45905,98 @@ class SealosDevboxAdapter extends BaseSandboxAdapter {
|
|
|
45813
45905
|
throw new CommandExecutionError(`Command execution failed: ${error?.message || error?.code}`, command, error instanceof Error ? error : undefined);
|
|
45814
45906
|
}
|
|
45815
45907
|
}
|
|
45908
|
+
async getEndpoint(selector) {
|
|
45909
|
+
const port = typeof selector === "number" ? selector : SEALOS_DEVBOX_CODE_SERVER_PORT;
|
|
45910
|
+
const target = await this.getHttpgateTarget(port);
|
|
45911
|
+
const url = new URL(target.origin);
|
|
45912
|
+
return {
|
|
45913
|
+
host: url.host,
|
|
45914
|
+
port: target.port,
|
|
45915
|
+
protocol: url.protocol === "https:" ? "https" : "http",
|
|
45916
|
+
url: joinUrlPath(target.origin, target.basePath)
|
|
45917
|
+
};
|
|
45918
|
+
}
|
|
45919
|
+
async getProxyTarget(service = "code-server") {
|
|
45920
|
+
if (service !== "code-server") {
|
|
45921
|
+
throw new FeatureNotSupportedError(`Proxy service "${service}" is not supported by this provider`, "getProxyTarget", this.provider);
|
|
45922
|
+
}
|
|
45923
|
+
const target = await this.getHttpgateTarget(SEALOS_DEVBOX_CODE_SERVER_PORT);
|
|
45924
|
+
return {
|
|
45925
|
+
service,
|
|
45926
|
+
origin: target.origin,
|
|
45927
|
+
basePath: target.basePath,
|
|
45928
|
+
auth: "code-server",
|
|
45929
|
+
...target.password ? { password: target.password } : {}
|
|
45930
|
+
};
|
|
45931
|
+
}
|
|
45932
|
+
async getHttpgateTarget(port) {
|
|
45933
|
+
const res = await this.api.info(this._id);
|
|
45934
|
+
if (res.code !== 200 || !res.data) {
|
|
45935
|
+
throw new ConnectionError(`Failed to get devbox info: ${res.message}`, this.config.baseUrl);
|
|
45936
|
+
}
|
|
45937
|
+
if (port === SEALOS_DEVBOX_CODE_SERVER_PORT) {
|
|
45938
|
+
const gateway2 = res.data.codeServerGateway;
|
|
45939
|
+
if (!gateway2?.url) {
|
|
45940
|
+
throw new ConnectionError("Devbox info does not include codeServerGateway.url; cannot resolve code-server endpoint", this.config.baseUrl);
|
|
45941
|
+
}
|
|
45942
|
+
const codeServerUrl = new URL(gateway2.url);
|
|
45943
|
+
return {
|
|
45944
|
+
origin: codeServerUrl.origin,
|
|
45945
|
+
basePath: normalizePathPrefix(codeServerUrl.pathname),
|
|
45946
|
+
port: gateway2.port ?? port,
|
|
45947
|
+
password: gateway2.password
|
|
45948
|
+
};
|
|
45949
|
+
}
|
|
45950
|
+
const gatewayUrl = res.data.gateway?.url;
|
|
45951
|
+
if (!gatewayUrl) {
|
|
45952
|
+
throw new ConnectionError("Devbox info does not include gateway.url; cannot derive httpgate endpoint", this.config.baseUrl);
|
|
45953
|
+
}
|
|
45954
|
+
const gateway = new URL(gatewayUrl);
|
|
45955
|
+
const uniqueID = this.getGatewayUniqueID(res.data, gateway);
|
|
45956
|
+
const domain = this.getHttpgateDomain(gateway);
|
|
45957
|
+
return {
|
|
45958
|
+
origin: `${gateway.protocol}//devbox-${uniqueID}-${port}.${domain}`,
|
|
45959
|
+
basePath: "",
|
|
45960
|
+
port
|
|
45961
|
+
};
|
|
45962
|
+
}
|
|
45963
|
+
getGatewayUniqueID(data, gateway) {
|
|
45964
|
+
if (data.gateway?.uniqueID)
|
|
45965
|
+
return data.gateway.uniqueID;
|
|
45966
|
+
const parts = gateway.pathname.split("/").filter(Boolean);
|
|
45967
|
+
const uniqueID = parts[parts.length - 1];
|
|
45968
|
+
if (!uniqueID) {
|
|
45969
|
+
throw new ConnectionError("Devbox gateway.url does not include uniqueID; cannot derive httpgate endpoint", this.config.baseUrl);
|
|
45970
|
+
}
|
|
45971
|
+
return uniqueID;
|
|
45972
|
+
}
|
|
45973
|
+
getHttpgateDomain(gateway) {
|
|
45974
|
+
if (this.config.httpgateDomain) {
|
|
45975
|
+
return this.normalizeHttpgateDomain(this.config.httpgateDomain);
|
|
45976
|
+
}
|
|
45977
|
+
const prefix = "devbox-gateway.";
|
|
45978
|
+
if (!gateway.host.startsWith(prefix)) {
|
|
45979
|
+
throw new ConnectionError(`Cannot derive httpgate domain from gateway host "${gateway.host}"`, this.config.baseUrl);
|
|
45980
|
+
}
|
|
45981
|
+
return gateway.host.slice(prefix.length);
|
|
45982
|
+
}
|
|
45983
|
+
normalizeHttpgateDomain(domain) {
|
|
45984
|
+
const trimmed = domain.trim().replace(/^\.+|\.+$/g, "");
|
|
45985
|
+
if (!trimmed) {
|
|
45986
|
+
throw new ConnectionError("httpgateDomain is empty", this.config.baseUrl);
|
|
45987
|
+
}
|
|
45988
|
+
if (trimmed.includes("://")) {
|
|
45989
|
+
return new URL(trimmed).host;
|
|
45990
|
+
}
|
|
45991
|
+
return trimmed;
|
|
45992
|
+
}
|
|
45816
45993
|
async ping() {
|
|
45817
45994
|
try {
|
|
45818
45995
|
const res = await this.api.info(this._id);
|
|
45819
45996
|
if (res.code !== 200)
|
|
45820
45997
|
return false;
|
|
45998
|
+
if (!res.data)
|
|
45999
|
+
return false;
|
|
45821
46000
|
return res.data.state.phase === "Running" /* Running */;
|
|
45822
46001
|
} catch {
|
|
45823
46002
|
return false;
|
|
@@ -48069,27 +48248,6 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48069
48248
|
message: sdkStatus.message
|
|
48070
48249
|
};
|
|
48071
48250
|
}
|
|
48072
|
-
convertImageSpec(image) {
|
|
48073
|
-
const parts = [image.repository];
|
|
48074
|
-
if (image.tag) {
|
|
48075
|
-
parts.push(":", image.tag);
|
|
48076
|
-
}
|
|
48077
|
-
if (image.digest) {
|
|
48078
|
-
parts.push("@", image.digest);
|
|
48079
|
-
}
|
|
48080
|
-
return parts.join("");
|
|
48081
|
-
}
|
|
48082
|
-
parseImageSpec(image) {
|
|
48083
|
-
const atIndex = image.indexOf("@");
|
|
48084
|
-
if (atIndex > -1) {
|
|
48085
|
-
return { repository: image.slice(0, atIndex), digest: image.slice(atIndex + 1) };
|
|
48086
|
-
}
|
|
48087
|
-
const colonIndex = image.indexOf(":");
|
|
48088
|
-
if (colonIndex > -1) {
|
|
48089
|
-
return { repository: image.slice(0, colonIndex), tag: image.slice(colonIndex + 1) };
|
|
48090
|
-
}
|
|
48091
|
-
return { repository: image };
|
|
48092
|
-
}
|
|
48093
48251
|
convertResourceLimits(resourceLimits) {
|
|
48094
48252
|
if (!resourceLimits)
|
|
48095
48253
|
return;
|
|
@@ -48204,7 +48362,7 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48204
48362
|
}
|
|
48205
48363
|
try {
|
|
48206
48364
|
this._status = { state: "Creating" };
|
|
48207
|
-
const image =
|
|
48365
|
+
const image = formatImageSpec(cfg.image);
|
|
48208
48366
|
const resource = this.convertResourceLimits(cfg.resourceLimits);
|
|
48209
48367
|
this.sandbox = await Sandbox.create({
|
|
48210
48368
|
connectionConfig: this._connection,
|
|
@@ -48308,7 +48466,18 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48308
48466
|
async close() {
|
|
48309
48467
|
await this.sandbox.close();
|
|
48310
48468
|
}
|
|
48311
|
-
async getEndpoint(
|
|
48469
|
+
async getEndpoint(selector) {
|
|
48470
|
+
const port = typeof selector === "number" ? selector : OPEN_SANDBOX_EXECD_PORT;
|
|
48471
|
+
const endpoint = await this.getOpenSandboxEndpoint(port);
|
|
48472
|
+
if (selector === "code-server") {
|
|
48473
|
+
return {
|
|
48474
|
+
...endpoint,
|
|
48475
|
+
url: joinUrlPath(endpoint.url, `/proxy/${OPEN_SANDBOX_CODE_SERVER_PORT}`)
|
|
48476
|
+
};
|
|
48477
|
+
}
|
|
48478
|
+
return endpoint;
|
|
48479
|
+
}
|
|
48480
|
+
async getOpenSandboxEndpoint(port) {
|
|
48312
48481
|
const sdkEndpoint = await this.sandbox.getEndpoint(port);
|
|
48313
48482
|
const raw = sdkEndpoint.endpoint;
|
|
48314
48483
|
const colonIdx = raw.lastIndexOf(":");
|
|
@@ -48327,6 +48496,40 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48327
48496
|
url: `https://${raw}`
|
|
48328
48497
|
};
|
|
48329
48498
|
}
|
|
48499
|
+
async getProxyTarget(service = "code-server") {
|
|
48500
|
+
if (service !== "code-server") {
|
|
48501
|
+
throw new FeatureNotSupportedError(`Proxy service "${service}" is not supported by this provider`, "getProxyTarget", this.provider);
|
|
48502
|
+
}
|
|
48503
|
+
return {
|
|
48504
|
+
service,
|
|
48505
|
+
origin: await this.getDirectEndpointOrigin(OPEN_SANDBOX_EXECD_PORT),
|
|
48506
|
+
basePath: `/proxy/${OPEN_SANDBOX_CODE_SERVER_PORT}`,
|
|
48507
|
+
auth: "code-server"
|
|
48508
|
+
};
|
|
48509
|
+
}
|
|
48510
|
+
async getDirectEndpointOrigin(port) {
|
|
48511
|
+
if (!this.id) {
|
|
48512
|
+
throw new SandboxStateError("Sandbox not initialized. Call create() or connect() first.", "UnExist", "Running");
|
|
48513
|
+
}
|
|
48514
|
+
const headers = {
|
|
48515
|
+
...this._connection.headers,
|
|
48516
|
+
Accept: "application/json"
|
|
48517
|
+
};
|
|
48518
|
+
const response = await this._connection.fetch(`${this._connection.getBaseUrl()}/sandboxes/${this.id}/endpoints/${port}?use_server_proxy=false`, { method: "GET", headers });
|
|
48519
|
+
if (!response.ok) {
|
|
48520
|
+
throw new ConnectionError(`OpenSandbox endpoint lookup failed: HTTP ${response.status}`, this.connectionConfig.baseUrl);
|
|
48521
|
+
}
|
|
48522
|
+
const data = await response.json();
|
|
48523
|
+
if (!data.endpoint) {
|
|
48524
|
+
throw new ConnectionError("OpenSandbox returned no endpoint", this.connectionConfig.baseUrl);
|
|
48525
|
+
}
|
|
48526
|
+
let hostPort = data.endpoint.replace(/\/proxy\/\d+\/?$/, "");
|
|
48527
|
+
if (this.connectionConfig.replaceDockerInternalWithLocalhost) {
|
|
48528
|
+
hostPort = hostPort.replace(/^host\.docker\.internal\b/, "localhost");
|
|
48529
|
+
}
|
|
48530
|
+
const url = new URL(/^https?:\/\//.test(hostPort) ? hostPort : `http://${hostPort}`);
|
|
48531
|
+
return url.origin;
|
|
48532
|
+
}
|
|
48330
48533
|
async getInfo() {
|
|
48331
48534
|
if (!this._sandbox) {
|
|
48332
48535
|
return null;
|
|
@@ -48335,7 +48538,7 @@ class OpenSandboxAdapter extends BaseSandboxAdapter {
|
|
|
48335
48538
|
const info = await this.sandbox.getInfo();
|
|
48336
48539
|
return {
|
|
48337
48540
|
id: info.id,
|
|
48338
|
-
image: typeof info.image === "string" ?
|
|
48541
|
+
image: typeof info.image === "string" ? parseImageSpec(info.image) : ("uri" in info.image) ? parseImageSpec(info.image.uri) : info.image,
|
|
48339
48542
|
entrypoint: info.entrypoint,
|
|
48340
48543
|
metadata: info.metadata,
|
|
48341
48544
|
status: this.mapStatus(info.status),
|
|
@@ -48837,7 +49040,7 @@ function createSandbox(provider, config, createConfig) {
|
|
|
48837
49040
|
case "opensandbox":
|
|
48838
49041
|
return new OpenSandboxAdapter(config, createConfig);
|
|
48839
49042
|
case "sealosdevbox":
|
|
48840
|
-
return new SealosDevboxAdapter(config);
|
|
49043
|
+
return new SealosDevboxAdapter(config, createConfig);
|
|
48841
49044
|
case "e2b":
|
|
48842
49045
|
return new E2BAdapter(config);
|
|
48843
49046
|
default:
|
|
@@ -2,6 +2,7 @@ import type { ICommandExecution } from './ICommandExecution';
|
|
|
2
2
|
import type { IFileSystem } from './IFileSystem';
|
|
3
3
|
import type { IHealthCheck } from './IHealthCheck';
|
|
4
4
|
import type { ISandboxLifecycle } from './ISandboxLifecycle';
|
|
5
|
+
import type { Endpoint, SandboxEndpointSelector, SandboxProxyService, SandboxProxyTarget } from '../types';
|
|
5
6
|
/**
|
|
6
7
|
* Unified sandbox interface.
|
|
7
8
|
* Composes all sandbox behaviors into a single interface.
|
|
@@ -15,4 +16,8 @@ import type { ISandboxLifecycle } from './ISandboxLifecycle';
|
|
|
15
16
|
export interface ISandbox extends ISandboxLifecycle, ICommandExecution, IFileSystem, IHealthCheck {
|
|
16
17
|
/** Provider name (e.g., 'opensandbox') */
|
|
17
18
|
readonly provider: string;
|
|
19
|
+
/** Resolve an endpoint exposed by the sandbox provider. */
|
|
20
|
+
getEndpoint(selector: SandboxEndpointSelector): Promise<Endpoint>;
|
|
21
|
+
/** Resolve the upstream target used by FastGPT sandbox-proxy. */
|
|
22
|
+
getProxyTarget(service?: SandboxProxyService): Promise<SandboxProxyTarget>;
|
|
18
23
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export type { BackgroundExecution, ExecuteOptions, ExecuteResult, OutputMessage, StreamHandlers } from './execution';
|
|
2
2
|
export type { ContentReplaceEntry, DirectoryEntry, FileDeleteResult, FileInfo, FileReadResult, FileWriteEntry, FileWriteResult, MoveEntry, PermissionEntry, ReadFileOptions, SearchResult } from './filesystem';
|
|
3
|
-
export type { Endpoint, ImageSpec, NetworkPolicy, ResourceLimits, SandboxId, SandboxInfo, SandboxMetrics, SandboxState, SandboxStatus } from './sandbox';
|
|
3
|
+
export type { Endpoint, ImageSpec, KubeAccessPolicy, LabelSpec, LifecyclePolicy, NetworkPolicy, ResourceLimits, SandboxCreateSpec, SandboxEndpointSelector, SandboxId, SandboxInfo, SandboxMetrics, SandboxProxyService, SandboxProxyTarget, SandboxState, SandboxStatus } from './sandbox';
|
package/dist/types/sandbox.d.ts
CHANGED
|
@@ -37,6 +37,18 @@ export interface NetworkPolicy {
|
|
|
37
37
|
allowEgress?: boolean;
|
|
38
38
|
allowedHosts?: string[];
|
|
39
39
|
}
|
|
40
|
+
export interface LabelSpec {
|
|
41
|
+
key: string;
|
|
42
|
+
value: string;
|
|
43
|
+
}
|
|
44
|
+
export interface LifecyclePolicy {
|
|
45
|
+
pauseAt?: string;
|
|
46
|
+
archiveAfterPauseTime?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface KubeAccessPolicy {
|
|
49
|
+
enabled?: boolean;
|
|
50
|
+
roleTemplate?: 'view' | 'edit' | 'admin';
|
|
51
|
+
}
|
|
40
52
|
/**
|
|
41
53
|
* Information about a sandbox.
|
|
42
54
|
*/
|
|
@@ -69,3 +81,36 @@ export interface Endpoint {
|
|
|
69
81
|
protocol: 'http' | 'https';
|
|
70
82
|
url: string;
|
|
71
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* App-facing create spec shared by callers that choose a provider at runtime.
|
|
86
|
+
* Individual adapters should map only the fields their backend actually supports.
|
|
87
|
+
*/
|
|
88
|
+
export interface SandboxCreateSpec {
|
|
89
|
+
image?: ImageSpec;
|
|
90
|
+
entrypoint?: string[];
|
|
91
|
+
timeout?: number;
|
|
92
|
+
timeoutSeconds?: number | null;
|
|
93
|
+
resourceLimits?: ResourceLimits;
|
|
94
|
+
env?: Record<string, string>;
|
|
95
|
+
metadata?: Record<string, unknown>;
|
|
96
|
+
labels?: LabelSpec[];
|
|
97
|
+
lifecycle?: LifecyclePolicy;
|
|
98
|
+
kubeAccess?: KubeAccessPolicy;
|
|
99
|
+
networkPolicy?: NetworkPolicy;
|
|
100
|
+
volumes?: unknown[];
|
|
101
|
+
workingDir?: string;
|
|
102
|
+
upstreamID?: string;
|
|
103
|
+
extensions?: Record<string, unknown>;
|
|
104
|
+
skipHealthCheck?: boolean;
|
|
105
|
+
readyTimeoutSeconds?: number;
|
|
106
|
+
healthCheckPollingInterval?: number;
|
|
107
|
+
}
|
|
108
|
+
export type SandboxProxyService = 'code-server';
|
|
109
|
+
export type SandboxEndpointSelector = number | SandboxProxyService;
|
|
110
|
+
export interface SandboxProxyTarget {
|
|
111
|
+
service: SandboxProxyService;
|
|
112
|
+
origin: string;
|
|
113
|
+
basePath: string;
|
|
114
|
+
auth: 'code-server';
|
|
115
|
+
password?: string;
|
|
116
|
+
}
|
package/package.json
CHANGED