experimental-agent 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -254
- package/dist/adapter-BigchkkI.d.mts +201 -0
- package/dist/adapter-BigchkkI.d.ts +201 -0
- package/dist/chunk-BFFNCESS.mjs +302 -0
- package/dist/chunk-C4VSUEY2.mjs +72 -0
- package/dist/chunk-DOD4MC5D.mjs +196 -0
- package/dist/chunk-ELWIUJUK.mjs +96 -0
- package/dist/chunk-GKASMIBR.mjs +50 -0
- package/dist/chunk-JO3JDCH5.mjs +107 -0
- package/dist/chunk-MSWINCCM.mjs +128 -0
- package/dist/chunk-RT72C52I.mjs +324 -0
- package/dist/chunk-ZUFJJYC4.mjs +150 -0
- package/dist/{handler-FRUPZ4LX.mjs → docker-QPCLWLYR.mjs} +3 -4
- package/dist/entry-BmQ8FO-5.d.ts +36 -0
- package/dist/entry-CZd9aAwn.d.mts +36 -0
- package/dist/index.d.mts +415 -18
- package/dist/index.d.ts +415 -18
- package/dist/index.js +3036 -5494
- package/dist/index.mjs +3264 -1142
- package/dist/lifecycle-workflow-steps.d.mts +5 -0
- package/dist/lifecycle-workflow-steps.d.ts +5 -0
- package/dist/lifecycle-workflow-steps.js +263 -0
- package/dist/lifecycle-workflow-steps.mjs +9 -0
- package/dist/lifecycle-workflow.d.mts +6 -6
- package/dist/lifecycle-workflow.d.ts +6 -6
- package/dist/lifecycle-workflow.js +192 -905
- package/dist/lifecycle-workflow.mjs +3 -1
- package/dist/local-KJ3BSIFJ.mjs +8 -0
- package/dist/next/loader.d.mts +1 -0
- package/dist/next/loader.d.ts +1 -0
- package/dist/next/loader.js +44 -18
- package/dist/next/loader.mjs +18 -13
- package/dist/next.js +32 -9
- package/dist/next.mjs +6 -4
- package/dist/{process-manager-JDUJDYGU.mjs → process-manager-WQHAIVRB.mjs} +1 -1
- package/dist/sandbox.d.mts +6 -0
- package/dist/sandbox.d.ts +6 -0
- package/dist/sandbox.js +1070 -0
- package/dist/sandbox.mjs +19 -0
- package/dist/steps-BnkRQKlc.d.ts +173 -0
- package/dist/steps-u-mGDbP_.d.mts +173 -0
- package/dist/storage.d.mts +11 -0
- package/dist/storage.d.ts +11 -0
- package/dist/storage.js +234 -0
- package/dist/storage.mjs +12 -0
- package/dist/vercel-QZ6INPMV.mjs +11 -0
- package/package.json +26 -5
- package/dist/agent-workflow.d.mts +0 -30
- package/dist/agent-workflow.d.ts +0 -30
- package/dist/agent-workflow.js +0 -5433
- package/dist/agent-workflow.mjs +0 -14
- package/dist/chunk-AML2VCQS.mjs +0 -1287
- package/dist/chunk-FQ67QZOI.mjs +0 -75
- package/dist/chunk-NO7RHGTH.mjs +0 -2367
- package/dist/chunk-NXDVNJRS.mjs +0 -106
- package/dist/chunk-OZZVS6L5.mjs +0 -139
- package/dist/chunk-QRWGDFFY.mjs +0 -75
- package/dist/chunk-SJVFFE5D.mjs +0 -402
- package/dist/chunk-TAXLUVIC.mjs +0 -1
- package/dist/chunk-TGNVXSMX.mjs +0 -399
- package/dist/chunk-YRYXN7W4.mjs +0 -48
- package/dist/chunk-ZIAHPXOJ.mjs +0 -595
- package/dist/client-BKA7XBGW.mjs +0 -15
- package/dist/client-CEeSFGva.d.mts +0 -2376
- package/dist/client-CEeSFGva.d.ts +0 -2376
- package/dist/docker-FB2MJTHJ.mjs +0 -12
- package/dist/local-fs-handlers-SYOCKTPN.mjs +0 -447
- package/dist/sandbox-UENKQV3T.mjs +0 -21
- package/dist/storage-LSDMRW73.mjs +0 -20
- package/dist/vercel-SD3JTECG.mjs +0 -20
- package/dist/vercel-sdk-I6A4MVAN.mjs +0 -8
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
|
|
2
|
+
import { NetworkPolicy } from '@vercel/sandbox';
|
|
3
|
+
import { UIMessage } from 'ai';
|
|
4
|
+
|
|
5
|
+
type Session = {
|
|
6
|
+
id: string;
|
|
7
|
+
createdAt: number;
|
|
8
|
+
updatedAt: number;
|
|
9
|
+
model: string | null;
|
|
10
|
+
system: string | null;
|
|
11
|
+
sandboxId: string | null;
|
|
12
|
+
lastMessageId: string | null;
|
|
13
|
+
activeTools: string[] | null;
|
|
14
|
+
skillsDir: string[] | null;
|
|
15
|
+
generation: {
|
|
16
|
+
maxSteps?: number;
|
|
17
|
+
temperature?: number;
|
|
18
|
+
topK?: number;
|
|
19
|
+
topP?: number;
|
|
20
|
+
frequencyPenalty?: number;
|
|
21
|
+
presencePenalty?: number;
|
|
22
|
+
maxOutputTokens?: number;
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
} | null;
|
|
25
|
+
};
|
|
26
|
+
type Message = {
|
|
27
|
+
id: string;
|
|
28
|
+
sessionId: string;
|
|
29
|
+
role: "user" | "assistant" | "system";
|
|
30
|
+
createdAt: number;
|
|
31
|
+
startedAt: number | null;
|
|
32
|
+
completedAt: number | null;
|
|
33
|
+
interruptedAt: number | null;
|
|
34
|
+
interruptedLastPart: {
|
|
35
|
+
index: number;
|
|
36
|
+
part: unknown;
|
|
37
|
+
} | null;
|
|
38
|
+
usage: {
|
|
39
|
+
steps: {
|
|
40
|
+
stepIndex: number;
|
|
41
|
+
model: string;
|
|
42
|
+
inputTokens: number;
|
|
43
|
+
outputTokens: number;
|
|
44
|
+
totalTokens: number;
|
|
45
|
+
cacheReadTokens: number;
|
|
46
|
+
cacheWriteTokens: number;
|
|
47
|
+
reasoningTokens: number;
|
|
48
|
+
}[];
|
|
49
|
+
summary: {
|
|
50
|
+
model: string;
|
|
51
|
+
inputTokens: number;
|
|
52
|
+
outputTokens: number;
|
|
53
|
+
totalTokens: number;
|
|
54
|
+
cacheReadTokens: number;
|
|
55
|
+
cacheWriteTokens: number;
|
|
56
|
+
reasoningTokens: number;
|
|
57
|
+
stepCount: number;
|
|
58
|
+
};
|
|
59
|
+
} | null;
|
|
60
|
+
workflowRunId?: string | null;
|
|
61
|
+
};
|
|
62
|
+
type Part = {
|
|
63
|
+
id: string;
|
|
64
|
+
messageId: string;
|
|
65
|
+
sessionId: string;
|
|
66
|
+
index: number;
|
|
67
|
+
part: UIMessage["parts"][number];
|
|
68
|
+
};
|
|
69
|
+
type Sandbox = {
|
|
70
|
+
id: string;
|
|
71
|
+
setup: {
|
|
72
|
+
binding: string;
|
|
73
|
+
version: string | null;
|
|
74
|
+
completedAt: number | null;
|
|
75
|
+
metadata: Record<string, unknown> | null;
|
|
76
|
+
networkPolicy: NetworkPolicy | null;
|
|
77
|
+
};
|
|
78
|
+
createdAt: number | null;
|
|
79
|
+
lastActiveAt: number | null;
|
|
80
|
+
};
|
|
81
|
+
type Setup = {
|
|
82
|
+
version: string;
|
|
83
|
+
snapshotId: string | null;
|
|
84
|
+
createdAt: number;
|
|
85
|
+
lastUsedAt: number | null;
|
|
86
|
+
};
|
|
87
|
+
type SetupSnapshot = Setup;
|
|
88
|
+
|
|
89
|
+
type StorageHandlers = {
|
|
90
|
+
"session.get"(p: {
|
|
91
|
+
id: string;
|
|
92
|
+
}): Promise<Session | null>;
|
|
93
|
+
"session.set"(p: {
|
|
94
|
+
id: string;
|
|
95
|
+
value: Session;
|
|
96
|
+
}): Promise<void>;
|
|
97
|
+
"session.update"(p: {
|
|
98
|
+
id: string;
|
|
99
|
+
updates: Partial<Session>;
|
|
100
|
+
}): Promise<Session>;
|
|
101
|
+
"message.get"(p: {
|
|
102
|
+
id: string;
|
|
103
|
+
}): Promise<Message | null>;
|
|
104
|
+
"message.set"(p: {
|
|
105
|
+
id: string;
|
|
106
|
+
value: Message;
|
|
107
|
+
}): Promise<void>;
|
|
108
|
+
"message.update"(p: {
|
|
109
|
+
id: string;
|
|
110
|
+
updates: Partial<Message>;
|
|
111
|
+
}): Promise<Message>;
|
|
112
|
+
"message.listBySession"(p: {
|
|
113
|
+
sessionId: string;
|
|
114
|
+
}): Promise<Message[]>;
|
|
115
|
+
"part.get"(p: {
|
|
116
|
+
id: string;
|
|
117
|
+
}): Promise<Part | null>;
|
|
118
|
+
"part.set"(p: {
|
|
119
|
+
id: string;
|
|
120
|
+
value: Part;
|
|
121
|
+
}): Promise<void>;
|
|
122
|
+
"part.listBySession"(p: {
|
|
123
|
+
sessionId: string;
|
|
124
|
+
}): Promise<Part[]>;
|
|
125
|
+
"sandbox.get"(p: {
|
|
126
|
+
id: string;
|
|
127
|
+
}): Promise<Sandbox | null>;
|
|
128
|
+
"sandbox.set"(p: {
|
|
129
|
+
id: string;
|
|
130
|
+
value: Sandbox;
|
|
131
|
+
}): Promise<void>;
|
|
132
|
+
"sandbox.update"(p: {
|
|
133
|
+
id: string;
|
|
134
|
+
updates: Partial<Sandbox>;
|
|
135
|
+
}): Promise<Sandbox>;
|
|
136
|
+
"setup.get"(p: {
|
|
137
|
+
id: string;
|
|
138
|
+
}): Promise<Setup | null>;
|
|
139
|
+
"setup.set"(p: {
|
|
140
|
+
id: string;
|
|
141
|
+
value: Setup;
|
|
142
|
+
}): Promise<void>;
|
|
143
|
+
};
|
|
144
|
+
type StorageCall = {
|
|
145
|
+
[K in keyof StorageHandlers]: {
|
|
146
|
+
method: K;
|
|
147
|
+
} & Parameters<StorageHandlers[K]>[0];
|
|
148
|
+
}[keyof StorageHandlers];
|
|
149
|
+
declare class StorageStep {
|
|
150
|
+
event: StorageCall;
|
|
151
|
+
constructor(event: StorageCall);
|
|
152
|
+
static [WORKFLOW_SERIALIZE](instance: StorageStep): {
|
|
153
|
+
event: StorageCall;
|
|
154
|
+
};
|
|
155
|
+
static [WORKFLOW_DESERIALIZE](data: {
|
|
156
|
+
event: StorageCall;
|
|
157
|
+
}): StorageStep;
|
|
158
|
+
on(handlers: StorageHandlers): Promise<any>;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* A single function that handles all storage operations. Intended to be
|
|
162
|
+
* marked with `"use step"` so that its body (and Node.js-dependent
|
|
163
|
+
* imports like database clients) is extracted by the workflow bundler
|
|
164
|
+
* and runs server-side.
|
|
165
|
+
*
|
|
166
|
+
* The step receives a `StorageStep` instance (serializable via
|
|
167
|
+
* `@workflow/serde`) and should call `step.handle({ ... })` with a
|
|
168
|
+
* `StorageHandlers` map.
|
|
169
|
+
*/
|
|
170
|
+
type StorageStepFunction = (store: StorageStep) => Promise<any>;
|
|
171
|
+
interface Storage {
|
|
172
|
+
session: {
|
|
173
|
+
get(key: string): Promise<Session | null>;
|
|
174
|
+
set(key: string, value: Session): Promise<void>;
|
|
175
|
+
update(key: string, updates: Partial<Session>): Promise<Session>;
|
|
176
|
+
};
|
|
177
|
+
message: {
|
|
178
|
+
get(key: string): Promise<Message | null>;
|
|
179
|
+
set(key: string, value: Message): Promise<void>;
|
|
180
|
+
update(key: string, updates: Partial<Message>): Promise<Message>;
|
|
181
|
+
listBySession(sessionId: string): Promise<Message[]>;
|
|
182
|
+
};
|
|
183
|
+
part: {
|
|
184
|
+
get(key: string): Promise<Part | null>;
|
|
185
|
+
set(key: string, value: Part): Promise<void>;
|
|
186
|
+
listBySession(sessionId: string): Promise<Part[]>;
|
|
187
|
+
};
|
|
188
|
+
sandbox: {
|
|
189
|
+
get(key: string): Promise<Sandbox | null>;
|
|
190
|
+
set(key: string, value: Sandbox): Promise<void>;
|
|
191
|
+
update(key: string, updates: Partial<Sandbox>): Promise<Sandbox>;
|
|
192
|
+
};
|
|
193
|
+
setup: {
|
|
194
|
+
get(key: string): Promise<Setup | null>;
|
|
195
|
+
set(key: string, value: Setup): Promise<void>;
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
type StorageInput = StorageHandlers | StorageStepFunction;
|
|
199
|
+
declare function toStorage(h: StorageInput): Storage;
|
|
200
|
+
|
|
201
|
+
export { type Message as M, type Part as P, type StorageHandlers as S, type Sandbox as a, type Session as b, type Setup as c, type SetupSnapshot as d, type Storage as e, type StorageCall as f, StorageStep as g, type StorageStepFunction as h, type StorageInput as i, toStorage as t };
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// src/sandbox/bindings/docker.ts
|
|
2
|
+
import { ulid } from "ulid";
|
|
3
|
+
async function execDocker(args, opts) {
|
|
4
|
+
const { spawn } = await import("child_process");
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
const child = spawn("docker", ["sandbox", ...args], {
|
|
7
|
+
signal: opts?.signal
|
|
8
|
+
});
|
|
9
|
+
let stdout = "";
|
|
10
|
+
let stderr = "";
|
|
11
|
+
child.stdout.on("data", (data) => {
|
|
12
|
+
stdout += data.toString();
|
|
13
|
+
});
|
|
14
|
+
child.stderr.on("data", (data) => {
|
|
15
|
+
stderr += data.toString();
|
|
16
|
+
});
|
|
17
|
+
const timeoutId = opts?.timeoutMs ? setTimeout(() => {
|
|
18
|
+
child.kill("SIGTERM");
|
|
19
|
+
reject(new Error(`docker sandbox ${args[0]} timed out`));
|
|
20
|
+
}, opts.timeoutMs) : void 0;
|
|
21
|
+
child.on("error", (err) => {
|
|
22
|
+
if (timeoutId) {
|
|
23
|
+
clearTimeout(timeoutId);
|
|
24
|
+
}
|
|
25
|
+
reject(err);
|
|
26
|
+
});
|
|
27
|
+
child.on("close", (code) => {
|
|
28
|
+
if (timeoutId) {
|
|
29
|
+
clearTimeout(timeoutId);
|
|
30
|
+
}
|
|
31
|
+
resolve({ stdout, stderr, exitCode: code ?? 0 });
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
var ensurePromises = /* @__PURE__ */ new Map();
|
|
36
|
+
var activeSandboxes = /* @__PURE__ */ new Set();
|
|
37
|
+
var cleanupRegistered = false;
|
|
38
|
+
var _execSync = null;
|
|
39
|
+
async function registerCleanup() {
|
|
40
|
+
if (cleanupRegistered) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
cleanupRegistered = true;
|
|
44
|
+
const cp = await import("child_process");
|
|
45
|
+
_execSync = cp.execSync;
|
|
46
|
+
const cleanup = () => {
|
|
47
|
+
if (!_execSync) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
for (const name of Array.from(activeSandboxes)) {
|
|
51
|
+
try {
|
|
52
|
+
_execSync(`docker sandbox stop ${name}`, {
|
|
53
|
+
timeout: 1e4,
|
|
54
|
+
stdio: "pipe"
|
|
55
|
+
});
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
process.on("exit", cleanup);
|
|
61
|
+
process.on("SIGINT", () => {
|
|
62
|
+
cleanup();
|
|
63
|
+
process.exit(130);
|
|
64
|
+
});
|
|
65
|
+
process.on("SIGTERM", () => {
|
|
66
|
+
cleanup();
|
|
67
|
+
process.exit(143);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async function ensureSandbox(sandboxName) {
|
|
71
|
+
const existing = ensurePromises.get(sandboxName);
|
|
72
|
+
if (existing) {
|
|
73
|
+
return existing;
|
|
74
|
+
}
|
|
75
|
+
const promise = (async () => {
|
|
76
|
+
const ls = await execDocker(["ls", "-q"], { timeoutMs: 1e4 });
|
|
77
|
+
const existingNames = ls.exitCode === 0 ? ls.stdout.split("\n").map((s) => s.trim()).filter(Boolean) : [];
|
|
78
|
+
if (existingNames.includes(sandboxName)) {
|
|
79
|
+
activeSandboxes.add(sandboxName);
|
|
80
|
+
registerCleanup();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const path = await import("path");
|
|
84
|
+
const os = await import("os");
|
|
85
|
+
const fs = await import("fs/promises");
|
|
86
|
+
const workspaceDir = path.join(
|
|
87
|
+
os.tmpdir(),
|
|
88
|
+
"agent-docker-sandbox",
|
|
89
|
+
sandboxName
|
|
90
|
+
);
|
|
91
|
+
await fs.mkdir(workspaceDir, { recursive: true });
|
|
92
|
+
const create = await execDocker(
|
|
93
|
+
["create", "--name", sandboxName, "shell", workspaceDir],
|
|
94
|
+
{ timeoutMs: 6e4 }
|
|
95
|
+
);
|
|
96
|
+
if (create.exitCode !== 0) {
|
|
97
|
+
if (create.stderr.includes("already exists")) {
|
|
98
|
+
activeSandboxes.add(sandboxName);
|
|
99
|
+
registerCleanup();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
throw new Error(
|
|
103
|
+
`Failed to create docker sandbox "${sandboxName}": ${create.stderr}`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
activeSandboxes.add(sandboxName);
|
|
107
|
+
registerCleanup();
|
|
108
|
+
})();
|
|
109
|
+
ensurePromises.set(sandboxName, promise);
|
|
110
|
+
try {
|
|
111
|
+
await promise;
|
|
112
|
+
} catch (e) {
|
|
113
|
+
ensurePromises.delete(sandboxName);
|
|
114
|
+
throw e;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
var DEFAULT_DOCKER_CWD = "/home/agent/workspace";
|
|
118
|
+
var DockerSandboxInstance = class {
|
|
119
|
+
cwd;
|
|
120
|
+
sandboxName;
|
|
121
|
+
processes = /* @__PURE__ */ new Map();
|
|
122
|
+
constructor(sandboxName, cwd) {
|
|
123
|
+
this.sandboxName = sandboxName;
|
|
124
|
+
this.cwd = cwd ?? DEFAULT_DOCKER_CWD;
|
|
125
|
+
}
|
|
126
|
+
async exec(opts) {
|
|
127
|
+
await ensureSandbox(this.sandboxName);
|
|
128
|
+
const { spawn } = await import("child_process");
|
|
129
|
+
const commandId = `command_${ulid()}`;
|
|
130
|
+
const envFlags = opts.env ? Object.entries(opts.env).flatMap(([k, v]) => ["-e", `${k}=${v}`]) : [];
|
|
131
|
+
const cwdFlags = opts.cwd ? ["-w", opts.cwd] : [];
|
|
132
|
+
const baseCmd = opts.sudo ? ["sudo", opts.command, ...opts.args ?? []] : opts.args ? [opts.command, ...opts.args] : [opts.command];
|
|
133
|
+
const fullCmd = baseCmd;
|
|
134
|
+
const child = spawn(
|
|
135
|
+
"docker",
|
|
136
|
+
[
|
|
137
|
+
"sandbox",
|
|
138
|
+
"exec",
|
|
139
|
+
...envFlags,
|
|
140
|
+
...cwdFlags,
|
|
141
|
+
this.sandboxName,
|
|
142
|
+
...fullCmd
|
|
143
|
+
],
|
|
144
|
+
{ signal: opts.signal }
|
|
145
|
+
);
|
|
146
|
+
this.processes.set(commandId, child);
|
|
147
|
+
let stdout = "";
|
|
148
|
+
let stderr = "";
|
|
149
|
+
const logQueue = [];
|
|
150
|
+
let logResolve = null;
|
|
151
|
+
let closed = false;
|
|
152
|
+
child.stdout.on("data", (data) => {
|
|
153
|
+
const str = String(data);
|
|
154
|
+
stdout += str;
|
|
155
|
+
logQueue.push({ stream: "stdout", data: str });
|
|
156
|
+
logResolve?.();
|
|
157
|
+
});
|
|
158
|
+
child.stderr.on("data", (data) => {
|
|
159
|
+
const str = String(data);
|
|
160
|
+
stderr += str;
|
|
161
|
+
logQueue.push({ stream: "stderr", data: str });
|
|
162
|
+
logResolve?.();
|
|
163
|
+
});
|
|
164
|
+
const result = new Promise((resolve, reject) => {
|
|
165
|
+
child.on("error", (err) => {
|
|
166
|
+
this.processes.delete(commandId);
|
|
167
|
+
closed = true;
|
|
168
|
+
logResolve?.();
|
|
169
|
+
reject(err);
|
|
170
|
+
});
|
|
171
|
+
child.on("close", (code) => {
|
|
172
|
+
this.processes.delete(commandId);
|
|
173
|
+
closed = true;
|
|
174
|
+
logResolve?.();
|
|
175
|
+
resolve({ stdout, stderr, exitCode: code ?? 0 });
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
async function* logs() {
|
|
179
|
+
while (!closed || logQueue.length > 0) {
|
|
180
|
+
const entry = logQueue.shift();
|
|
181
|
+
if (entry) {
|
|
182
|
+
yield entry;
|
|
183
|
+
} else if (!closed) {
|
|
184
|
+
await new Promise((r) => {
|
|
185
|
+
logResolve = r;
|
|
186
|
+
});
|
|
187
|
+
logResolve = null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return { commandId, logs, result };
|
|
192
|
+
}
|
|
193
|
+
async readFile(opts) {
|
|
194
|
+
await ensureSandbox(this.sandboxName);
|
|
195
|
+
const result = await execDocker(
|
|
196
|
+
[
|
|
197
|
+
"exec",
|
|
198
|
+
this.sandboxName,
|
|
199
|
+
"bash",
|
|
200
|
+
"-c",
|
|
201
|
+
`base64 '${opts.path.replace(/'/g, "'\\''")}'`
|
|
202
|
+
],
|
|
203
|
+
{ timeoutMs: 3e4, signal: opts.signal }
|
|
204
|
+
);
|
|
205
|
+
if (result.exitCode !== 0) {
|
|
206
|
+
if (result.stderr.includes("No such file") || result.stderr.includes("ENOENT")) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
throw new Error(`readFile failed: ${result.stderr}`);
|
|
210
|
+
}
|
|
211
|
+
return Buffer.from(result.stdout.trim(), "base64");
|
|
212
|
+
}
|
|
213
|
+
async writeFiles(opts) {
|
|
214
|
+
await ensureSandbox(this.sandboxName);
|
|
215
|
+
for (const file of opts.files) {
|
|
216
|
+
const fullPath = opts.destPath ? `${opts.destPath}/${file.path}` : file.path;
|
|
217
|
+
const parentDir = fullPath.substring(0, fullPath.lastIndexOf("/"));
|
|
218
|
+
if (parentDir) {
|
|
219
|
+
await execDocker(["exec", this.sandboxName, "mkdir", "-p", parentDir], {
|
|
220
|
+
signal: opts.signal
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
const b64 = typeof file.content === "string" ? Buffer.from(file.content).toString("base64") : file.content.toString("base64");
|
|
224
|
+
await execDocker(
|
|
225
|
+
[
|
|
226
|
+
"exec",
|
|
227
|
+
this.sandboxName,
|
|
228
|
+
"bash",
|
|
229
|
+
"-c",
|
|
230
|
+
`echo '${b64}' | base64 -d > '${fullPath.replace(/'/g, "'\\''")}'`
|
|
231
|
+
],
|
|
232
|
+
{ signal: opts.signal }
|
|
233
|
+
);
|
|
234
|
+
if (file.path.endsWith(".sh")) {
|
|
235
|
+
await execDocker(["exec", this.sandboxName, "chmod", "+x", fullPath], {
|
|
236
|
+
signal: opts.signal
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// biome-ignore lint/suspicious/useAwait: .
|
|
242
|
+
async getDomain(opts) {
|
|
243
|
+
return `http://localhost:${opts.port}`;
|
|
244
|
+
}
|
|
245
|
+
// biome-ignore lint/suspicious/useAwait: .
|
|
246
|
+
async kill(opts) {
|
|
247
|
+
const child = this.processes.get(opts.commandId);
|
|
248
|
+
if (child) {
|
|
249
|
+
child.kill("SIGTERM");
|
|
250
|
+
this.processes.delete(opts.commandId);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// biome-ignore lint/suspicious/useAwait: .
|
|
254
|
+
async getStatus() {
|
|
255
|
+
return "running";
|
|
256
|
+
}
|
|
257
|
+
async start() {
|
|
258
|
+
await ensureSandbox(this.sandboxName);
|
|
259
|
+
}
|
|
260
|
+
async stop() {
|
|
261
|
+
await execDocker(["stop", this.sandboxName], { timeoutMs: 3e4 });
|
|
262
|
+
activeSandboxes.delete(this.sandboxName);
|
|
263
|
+
ensurePromises.delete(this.sandboxName);
|
|
264
|
+
}
|
|
265
|
+
// biome-ignore lint/suspicious/useAwait: .
|
|
266
|
+
async snapshot() {
|
|
267
|
+
throw new Error("snapshot is not supported for docker sandboxes");
|
|
268
|
+
}
|
|
269
|
+
// biome-ignore lint/suspicious/useAwait: .
|
|
270
|
+
async updateNetworkPolicy() {
|
|
271
|
+
throw new Error(
|
|
272
|
+
"updateNetworkPolicy is not supported for docker sandboxes"
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
function dockerSandbox() {
|
|
277
|
+
return {
|
|
278
|
+
type: "docker",
|
|
279
|
+
async create(opts) {
|
|
280
|
+
const sandboxName = `agent-${ulid()}`;
|
|
281
|
+
const cwd = opts.setup?.config?.cwd;
|
|
282
|
+
await ensureSandbox(sandboxName);
|
|
283
|
+
const instance = new DockerSandboxInstance(sandboxName, cwd);
|
|
284
|
+
if (opts.setup?.run) {
|
|
285
|
+
await opts.setup.run(instance);
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
instance,
|
|
289
|
+
metadata: { sandboxName }
|
|
290
|
+
};
|
|
291
|
+
},
|
|
292
|
+
// biome-ignore lint/suspicious/useAwait: .
|
|
293
|
+
async connect(opts) {
|
|
294
|
+
return new DockerSandboxInstance(opts.metadata.sandboxName);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export {
|
|
300
|
+
dockerSandbox
|
|
301
|
+
};
|
|
302
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NhbmRib3gvYmluZGluZ3MvZG9ja2VyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyB1bGlkIH0gZnJvbSBcInVsaWRcIjtcbmltcG9ydCB0eXBlIHsgRXhlY1Jlc3VsdCwgU2FuZGJveEJpbmRpbmcsIFNhbmRib3hJbnN0YW5jZSB9IGZyb20gXCIuLi9hZGFwdGVyXCI7XG5cbmV4cG9ydCB0eXBlIERvY2tlckJpbmRpbmdDb25maWcgPSB7XG4gIGN3ZD86IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIERvY2tlckJpbmRpbmdNZXRhZGF0YSA9IHtcbiAgc2FuZGJveE5hbWU6IHN0cmluZztcbn07XG5cbi8qKlxuICogUnVuIGEgYGRvY2tlciBzYW5kYm94YCBDTEkgY29tbWFuZCBhbmQgcmV0dXJuIGl0cyBvdXRwdXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGV4ZWNEb2NrZXIoXG4gIGFyZ3M6IHN0cmluZ1tdLFxuICBvcHRzPzogeyB0aW1lb3V0TXM/OiBudW1iZXI7IHNpZ25hbD86IEFib3J0U2lnbmFsIH1cbik6IFByb21pc2U8eyBzdGRvdXQ6IHN0cmluZzsgc3RkZXJyOiBzdHJpbmc7IGV4aXRDb2RlOiBudW1iZXIgfT4ge1xuICBjb25zdCB7IHNwYXduIH0gPSBhd2FpdCBpbXBvcnQoXCJub2RlOmNoaWxkX3Byb2Nlc3NcIik7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2hpbGQgPSBzcGF3bihcImRvY2tlclwiLCBbXCJzYW5kYm94XCIsIC4uLmFyZ3NdLCB7XG4gICAgICBzaWduYWw6IG9wdHM/LnNpZ25hbCxcbiAgICB9KTtcblxuICAgIGxldCBzdGRvdXQgPSBcIlwiO1xuICAgIGxldCBzdGRlcnIgPSBcIlwiO1xuXG4gICAgY2hpbGQuc3Rkb3V0Lm9uKFwiZGF0YVwiLCAoZGF0YTogQnVmZmVyKSA9PiB7XG4gICAgICBzdGRvdXQgKz0gZGF0YS50b1N0cmluZygpO1xuICAgIH0pO1xuICAgIGNoaWxkLnN0ZGVyci5vbihcImRhdGFcIiwgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgc3RkZXJyICs9IGRhdGEudG9TdHJpbmcoKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHRpbWVvdXRJZCA9IG9wdHM/LnRpbWVvdXRNc1xuICAgICAgPyBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBkb2NrZXIgc2FuZGJveCAke2FyZ3NbMF19IHRpbWVkIG91dGApKTtcbiAgICAgICAgfSwgb3B0cy50aW1lb3V0TXMpXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGNoaWxkLm9uKFwiZXJyb3JcIiwgKGVycikgPT4ge1xuICAgICAgaWYgKHRpbWVvdXRJZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIH1cbiAgICAgIHJlamVjdChlcnIpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQub24oXCJjbG9zZVwiLCAoY29kZSkgPT4ge1xuICAgICAgaWYgKHRpbWVvdXRJZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgIH1cbiAgICAgIHJlc29sdmUoeyBzdGRvdXQsIHN0ZGVyciwgZXhpdENvZGU6IGNvZGUgPz8gMCB9KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogVHJhY2sgd2hpY2ggc2FuZGJveGVzIGhhdmUgYmVlbiB2ZXJpZmllZCB0byBleGlzdCBpbiB0aGlzIHByb2Nlc3MuXG4gKiBNYXBzIHNhbmRib3ggbmFtZSAtPiBQcm9taXNlIHNvIGNvbmN1cnJlbnQgY2FsbGVycyB3YWl0IG9uIHRoZSBzYW1lIGNoZWNrLlxuICovXG5jb25zdCBlbnN1cmVQcm9taXNlcyA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPHZvaWQ+PigpO1xuXG4vKipcbiAqIFNhbmRib3hlcyB0aGF0IHRoaXMgcHJvY2VzcyBoYXMgdXNlZC4gU3RvcHBlZCBvbiBwcm9jZXNzIGV4aXQuXG4gKi9cbmNvbnN0IGFjdGl2ZVNhbmRib3hlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG5sZXQgY2xlYW51cFJlZ2lzdGVyZWQgPSBmYWxzZTtcbmxldCBfZXhlY1N5bmM6IHR5cGVvZiBpbXBvcnQoXCJub2RlOmNoaWxkX3Byb2Nlc3NcIikuZXhlY1N5bmMgfCBudWxsID0gbnVsbDtcblxuYXN5bmMgZnVuY3Rpb24gcmVnaXN0ZXJDbGVhbnVwKCkge1xuICBpZiAoY2xlYW51cFJlZ2lzdGVyZWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY2xlYW51cFJlZ2lzdGVyZWQgPSB0cnVlO1xuXG4gIC8vIFByZS1sb2FkIGV4ZWNTeW5jIHNvIHRoZSBzeW5jaHJvbm91cyBleGl0IGhhbmRsZXIgY2FuIHVzZSBpdC5cbiAgY29uc3QgY3AgPSBhd2FpdCBpbXBvcnQoXCJub2RlOmNoaWxkX3Byb2Nlc3NcIik7XG4gIF9leGVjU3luYyA9IGNwLmV4ZWNTeW5jO1xuXG4gIGNvbnN0IGNsZWFudXAgPSAoKSA9PiB7XG4gICAgaWYgKCFfZXhlY1N5bmMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIEFycmF5LmZyb20oYWN0aXZlU2FuZGJveGVzKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgX2V4ZWNTeW5jKGBkb2NrZXIgc2FuZGJveCBzdG9wICR7bmFtZX1gLCB7XG4gICAgICAgICAgdGltZW91dDogMTBfMDAwLFxuICAgICAgICAgIHN0ZGlvOiBcInBpcGVcIixcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gQmVzdC1lZmZvcnQgXHUyMDE0IHNhbmRib3ggbWF5IGFscmVhZHkgYmUgc3RvcHBlZFxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBwcm9jZXNzLm9uKFwiZXhpdFwiLCBjbGVhbnVwKTtcbiAgcHJvY2Vzcy5vbihcIlNJR0lOVFwiLCAoKSA9PiB7XG4gICAgY2xlYW51cCgpO1xuICAgIHByb2Nlc3MuZXhpdCgxMzApO1xuICB9KTtcbiAgcHJvY2Vzcy5vbihcIlNJR1RFUk1cIiwgKCkgPT4ge1xuICAgIGNsZWFudXAoKTtcbiAgICBwcm9jZXNzLmV4aXQoMTQzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogRW5zdXJlIGEgRG9ja2VyIHNhbmRib3ggZXhpc3RzIGZvciB0aGUgZ2l2ZW4gbmFtZS5cbiAqIElmIGl0IGFscmVhZHkgZXhpc3RzIChmcm9tIGEgcHJldmlvdXMgcHJvY2VzcyksIHJldXNlcyBpdC5cbiAqIElmIGl0IGRvZXNuJ3QgZXhpc3QsIGNyZWF0ZXMgaXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGVuc3VyZVNhbmRib3goc2FuZGJveE5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBleGlzdGluZyA9IGVuc3VyZVByb21pc2VzLmdldChzYW5kYm94TmFtZSk7XG4gIGlmIChleGlzdGluZykge1xuICAgIHJldHVybiBleGlzdGluZztcbiAgfVxuXG4gIGNvbnN0IHByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxzID0gYXdhaXQgZXhlY0RvY2tlcihbXCJsc1wiLCBcIi1xXCJdLCB7IHRpbWVvdXRNczogMTBfMDAwIH0pO1xuICAgIGNvbnN0IGV4aXN0aW5nTmFtZXMgPVxuICAgICAgbHMuZXhpdENvZGUgPT09IDBcbiAgICAgICAgPyBscy5zdGRvdXRcbiAgICAgICAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgICAgICAgLm1hcCgocykgPT4gcy50cmltKCkpXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAgIDogW107XG5cbiAgICBpZiAoZXhpc3RpbmdOYW1lcy5pbmNsdWRlcyhzYW5kYm94TmFtZSkpIHtcbiAgICAgIGFjdGl2ZVNhbmRib3hlcy5hZGQoc2FuZGJveE5hbWUpO1xuICAgICAgcmVnaXN0ZXJDbGVhbnVwKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGF0aCA9IGF3YWl0IGltcG9ydChcIm5vZGU6cGF0aFwiKTtcbiAgICBjb25zdCBvcyA9IGF3YWl0IGltcG9ydChcIm5vZGU6b3NcIik7XG4gICAgY29uc3QgZnMgPSBhd2FpdCBpbXBvcnQoXCJub2RlOmZzL3Byb21pc2VzXCIpO1xuXG4gICAgY29uc3Qgd29ya3NwYWNlRGlyID0gcGF0aC5qb2luKFxuICAgICAgb3MudG1wZGlyKCksXG4gICAgICBcImFnZW50LWRvY2tlci1zYW5kYm94XCIsXG4gICAgICBzYW5kYm94TmFtZVxuICAgICk7XG4gICAgYXdhaXQgZnMubWtkaXIod29ya3NwYWNlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICAgIGNvbnN0IGNyZWF0ZSA9IGF3YWl0IGV4ZWNEb2NrZXIoXG4gICAgICBbXCJjcmVhdGVcIiwgXCItLW5hbWVcIiwgc2FuZGJveE5hbWUsIFwic2hlbGxcIiwgd29ya3NwYWNlRGlyXSxcbiAgICAgIHsgdGltZW91dE1zOiA2MF8wMDAgfVxuICAgICk7XG5cbiAgICBpZiAoY3JlYXRlLmV4aXRDb2RlICE9PSAwKSB7XG4gICAgICBpZiAoY3JlYXRlLnN0ZGVyci5pbmNsdWRlcyhcImFscmVhZHkgZXhpc3RzXCIpKSB7XG4gICAgICAgIGFjdGl2ZVNhbmRib3hlcy5hZGQoc2FuZGJveE5hbWUpO1xuICAgICAgICByZWdpc3RlckNsZWFudXAoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGNyZWF0ZSBkb2NrZXIgc2FuZGJveCBcIiR7c2FuZGJveE5hbWV9XCI6ICR7Y3JlYXRlLnN0ZGVycn1gXG4gICAgICApO1xuICAgIH1cblxuICAgIGFjdGl2ZVNhbmRib3hlcy5hZGQoc2FuZGJveE5hbWUpO1xuICAgIHJlZ2lzdGVyQ2xlYW51cCgpO1xuICB9KSgpO1xuXG4gIGVuc3VyZVByb21pc2VzLnNldChzYW5kYm94TmFtZSwgcHJvbWlzZSk7XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCBwcm9taXNlO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZW5zdXJlUHJvbWlzZXMuZGVsZXRlKHNhbmRib3hOYW1lKTtcbiAgICB0aHJvdyBlO1xuICB9XG59XG5cbmNvbnN0IERFRkFVTFRfRE9DS0VSX0NXRCA9IFwiL2hvbWUvYWdlbnQvd29ya3NwYWNlXCI7XG5cbmNsYXNzIERvY2tlclNhbmRib3hJbnN0YW5jZSBpbXBsZW1lbnRzIFNhbmRib3hJbnN0YW5jZSB7XG4gIHJlYWRvbmx5IGN3ZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHNhbmRib3hOYW1lOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvY2Vzc2VzID0gbmV3IE1hcDxcbiAgICBzdHJpbmcsXG4gICAgaW1wb3J0KFwibm9kZTpjaGlsZF9wcm9jZXNzXCIpLkNoaWxkUHJvY2Vzc1xuICA+KCk7XG5cbiAgY29uc3RydWN0b3Ioc2FuZGJveE5hbWU6IHN0cmluZywgY3dkPzogc3RyaW5nKSB7XG4gICAgdGhpcy5zYW5kYm94TmFtZSA9IHNhbmRib3hOYW1lO1xuICAgIHRoaXMuY3dkID0gY3dkID8/IERFRkFVTFRfRE9DS0VSX0NXRDtcbiAgfVxuXG4gIGFzeW5jIGV4ZWMob3B0czoge1xuICAgIGNvbW1hbmQ6IHN0cmluZztcbiAgICBhcmdzPzogc3RyaW5nW107XG4gICAgY3dkPzogc3RyaW5nO1xuICAgIGVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgc3Vkbz86IGJvb2xlYW47XG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIH0pOiBQcm9taXNlPEV4ZWNSZXN1bHQ+IHtcbiAgICBhd2FpdCBlbnN1cmVTYW5kYm94KHRoaXMuc2FuZGJveE5hbWUpO1xuXG4gICAgY29uc3QgeyBzcGF3biB9ID0gYXdhaXQgaW1wb3J0KFwibm9kZTpjaGlsZF9wcm9jZXNzXCIpO1xuICAgIGNvbnN0IGNvbW1hbmRJZCA9IGBjb21tYW5kXyR7dWxpZCgpfWA7XG4gICAgY29uc3QgZW52RmxhZ3MgPSBvcHRzLmVudlxuICAgICAgPyBPYmplY3QuZW50cmllcyhvcHRzLmVudikuZmxhdE1hcCgoW2ssIHZdKSA9PiBbXCItZVwiLCBgJHtrfT0ke3Z9YF0pXG4gICAgICA6IFtdO1xuICAgIGNvbnN0IGN3ZEZsYWdzID0gb3B0cy5jd2QgPyBbXCItd1wiLCBvcHRzLmN3ZF0gOiBbXTtcbiAgICBjb25zdCBiYXNlQ21kID0gb3B0cy5zdWRvXG4gICAgICA/IFtcInN1ZG9cIiwgb3B0cy5jb21tYW5kLCAuLi4ob3B0cy5hcmdzID8/IFtdKV1cbiAgICAgIDogb3B0cy5hcmdzXG4gICAgICAgID8gW29wdHMuY29tbWFuZCwgLi4ub3B0cy5hcmdzXVxuICAgICAgICA6IFtvcHRzLmNvbW1hbmRdO1xuICAgIGNvbnN0IGZ1bGxDbWQgPSBiYXNlQ21kO1xuXG4gICAgY29uc3QgY2hpbGQgPSBzcGF3bihcbiAgICAgIFwiZG9ja2VyXCIsXG4gICAgICBbXG4gICAgICAgIFwic2FuZGJveFwiLFxuICAgICAgICBcImV4ZWNcIixcbiAgICAgICAgLi4uZW52RmxhZ3MsXG4gICAgICAgIC4uLmN3ZEZsYWdzLFxuICAgICAgICB0aGlzLnNhbmRib3hOYW1lLFxuICAgICAgICAuLi5mdWxsQ21kLFxuICAgICAgXSxcbiAgICAgIHsgc2lnbmFsOiBvcHRzLnNpZ25hbCB9XG4gICAgKTtcblxuICAgIHRoaXMucHJvY2Vzc2VzLnNldChjb21tYW5kSWQsIGNoaWxkKTtcblxuICAgIGxldCBzdGRvdXQgPSBcIlwiO1xuICAgIGxldCBzdGRlcnIgPSBcIlwiO1xuICAgIGNvbnN0IGxvZ1F1ZXVlOiB7IHN0cmVhbTogXCJzdGRvdXRcIiB8IFwic3RkZXJyXCI7IGRhdGE6IHN0cmluZyB9W10gPSBbXTtcbiAgICBsZXQgbG9nUmVzb2x2ZTogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGNsb3NlZCA9IGZhbHNlO1xuXG4gICAgY2hpbGQuc3Rkb3V0Lm9uKFwiZGF0YVwiLCAoZGF0YTogc3RyaW5nIHwgQnVmZmVyKSA9PiB7XG4gICAgICBjb25zdCBzdHIgPSBTdHJpbmcoZGF0YSk7XG4gICAgICBzdGRvdXQgKz0gc3RyO1xuICAgICAgbG9nUXVldWUucHVzaCh7IHN0cmVhbTogXCJzdGRvdXRcIiwgZGF0YTogc3RyIH0pO1xuICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgfSk7XG5cbiAgICBjaGlsZC5zdGRlcnIub24oXCJkYXRhXCIsIChkYXRhOiBzdHJpbmcgfCBCdWZmZXIpID0+IHtcbiAgICAgIGNvbnN0IHN0ciA9IFN0cmluZyhkYXRhKTtcbiAgICAgIHN0ZGVyciArPSBzdHI7XG4gICAgICBsb2dRdWV1ZS5wdXNoKHsgc3RyZWFtOiBcInN0ZGVyclwiLCBkYXRhOiBzdHIgfSk7XG4gICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBQcm9taXNlPHtcbiAgICAgIHN0ZG91dDogc3RyaW5nO1xuICAgICAgc3RkZXJyOiBzdHJpbmc7XG4gICAgICBleGl0Q29kZTogbnVtYmVyO1xuICAgIH0+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNoaWxkLm9uKFwiZXJyb3JcIiwgKGVycikgPT4ge1xuICAgICAgICB0aGlzLnByb2Nlc3Nlcy5kZWxldGUoY29tbWFuZElkKTtcbiAgICAgICAgY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfSk7XG5cbiAgICAgIGNoaWxkLm9uKFwiY2xvc2VcIiwgKGNvZGU6IG51bWJlciB8IG51bGwpID0+IHtcbiAgICAgICAgdGhpcy5wcm9jZXNzZXMuZGVsZXRlKGNvbW1hbmRJZCk7XG4gICAgICAgIGNsb3NlZCA9IHRydWU7XG4gICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICByZXNvbHZlKHsgc3Rkb3V0LCBzdGRlcnIsIGV4aXRDb2RlOiBjb2RlID8/IDAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFzeW5jIGZ1bmN0aW9uKiBsb2dzKCk6IEFzeW5jSXRlcmFibGU8e1xuICAgICAgc3RyZWFtOiBcInN0ZG91dFwiIHwgXCJzdGRlcnJcIjtcbiAgICAgIGRhdGE6IHN0cmluZztcbiAgICB9PiB7XG4gICAgICB3aGlsZSAoIWNsb3NlZCB8fCBsb2dRdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGVudHJ5ID0gbG9nUXVldWUuc2hpZnQoKTtcbiAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgeWllbGQgZW50cnk7XG4gICAgICAgIH0gZWxzZSBpZiAoIWNsb3NlZCkge1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyKSA9PiB7XG4gICAgICAgICAgICBsb2dSZXNvbHZlID0gcjtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBsb2dSZXNvbHZlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IGNvbW1hbmRJZCwgbG9ncywgcmVzdWx0IH07XG4gIH1cblxuICBhc3luYyByZWFkRmlsZShvcHRzOiB7XG4gICAgcGF0aDogc3RyaW5nO1xuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICB9KTogUHJvbWlzZTxCdWZmZXIgfCBudWxsPiB7XG4gICAgYXdhaXQgZW5zdXJlU2FuZGJveCh0aGlzLnNhbmRib3hOYW1lKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGV4ZWNEb2NrZXIoXG4gICAgICBbXG4gICAgICAgIFwiZXhlY1wiLFxuICAgICAgICB0aGlzLnNhbmRib3hOYW1lLFxuICAgICAgICBcImJhc2hcIixcbiAgICAgICAgXCItY1wiLFxuICAgICAgICBgYmFzZTY0ICcke29wdHMucGF0aC5yZXBsYWNlKC8nL2csIFwiJ1xcXFwnJ1wiKX0nYCxcbiAgICAgIF0sXG4gICAgICB7IHRpbWVvdXRNczogMzBfMDAwLCBzaWduYWw6IG9wdHMuc2lnbmFsIH1cbiAgICApO1xuXG4gICAgaWYgKHJlc3VsdC5leGl0Q29kZSAhPT0gMCkge1xuICAgICAgaWYgKFxuICAgICAgICByZXN1bHQuc3RkZXJyLmluY2x1ZGVzKFwiTm8gc3VjaCBmaWxlXCIpIHx8XG4gICAgICAgIHJlc3VsdC5zdGRlcnIuaW5jbHVkZXMoXCJFTk9FTlRcIilcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihgcmVhZEZpbGUgZmFpbGVkOiAke3Jlc3VsdC5zdGRlcnJ9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHJlc3VsdC5zdGRvdXQudHJpbSgpLCBcImJhc2U2NFwiKTtcbiAgfVxuXG4gIGFzeW5jIHdyaXRlRmlsZXMob3B0czoge1xuICAgIGZpbGVzOiB7IHBhdGg6IHN0cmluZzsgY29udGVudDogc3RyaW5nIHwgQnVmZmVyIH1bXTtcbiAgICBkZXN0UGF0aDogc3RyaW5nO1xuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgZW5zdXJlU2FuZGJveCh0aGlzLnNhbmRib3hOYW1lKTtcblxuICAgIGZvciAoY29uc3QgZmlsZSBvZiBvcHRzLmZpbGVzKSB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IG9wdHMuZGVzdFBhdGhcbiAgICAgICAgPyBgJHtvcHRzLmRlc3RQYXRofS8ke2ZpbGUucGF0aH1gXG4gICAgICAgIDogZmlsZS5wYXRoO1xuXG4gICAgICAvLyBFbnN1cmUgcGFyZW50IGRpcmVjdG9yeSBleGlzdHNcbiAgICAgIGNvbnN0IHBhcmVudERpciA9IGZ1bGxQYXRoLnN1YnN0cmluZygwLCBmdWxsUGF0aC5sYXN0SW5kZXhPZihcIi9cIikpO1xuICAgICAgaWYgKHBhcmVudERpcikge1xuICAgICAgICBhd2FpdCBleGVjRG9ja2VyKFtcImV4ZWNcIiwgdGhpcy5zYW5kYm94TmFtZSwgXCJta2RpclwiLCBcIi1wXCIsIHBhcmVudERpcl0sIHtcbiAgICAgICAgICBzaWduYWw6IG9wdHMuc2lnbmFsLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gV3JpdGUgdmlhIGJhc2U2NCB0byBoYW5kbGUgYm90aCB0ZXh0IGFuZCBiaW5hcnkgY29udGVudFxuICAgICAgY29uc3QgYjY0ID1cbiAgICAgICAgdHlwZW9mIGZpbGUuY29udGVudCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgID8gQnVmZmVyLmZyb20oZmlsZS5jb250ZW50KS50b1N0cmluZyhcImJhc2U2NFwiKVxuICAgICAgICAgIDogZmlsZS5jb250ZW50LnRvU3RyaW5nKFwiYmFzZTY0XCIpO1xuXG4gICAgICBhd2FpdCBleGVjRG9ja2VyKFxuICAgICAgICBbXG4gICAgICAgICAgXCJleGVjXCIsXG4gICAgICAgICAgdGhpcy5zYW5kYm94TmFtZSxcbiAgICAgICAgICBcImJhc2hcIixcbiAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgYGVjaG8gJyR7YjY0fScgfCBiYXNlNjQgLWQgPiAnJHtmdWxsUGF0aC5yZXBsYWNlKC8nL2csIFwiJ1xcXFwnJ1wiKX0nYCxcbiAgICAgICAgXSxcbiAgICAgICAgeyBzaWduYWw6IG9wdHMuc2lnbmFsIH1cbiAgICAgICk7XG5cbiAgICAgIGlmIChmaWxlLnBhdGguZW5kc1dpdGgoXCIuc2hcIikpIHtcbiAgICAgICAgYXdhaXQgZXhlY0RvY2tlcihbXCJleGVjXCIsIHRoaXMuc2FuZGJveE5hbWUsIFwiY2htb2RcIiwgXCIreFwiLCBmdWxsUGF0aF0sIHtcbiAgICAgICAgICBzaWduYWw6IG9wdHMuc2lnbmFsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL3VzZUF3YWl0OiAuXG4gIGFzeW5jIGdldERvbWFpbihvcHRzOiB7XG4gICAgcG9ydDogbnVtYmVyO1xuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICB9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtvcHRzLnBvcnR9YDtcbiAgfVxuXG4gIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvdXNlQXdhaXQ6IC5cbiAgYXN5bmMga2lsbChvcHRzOiB7IGNvbW1hbmRJZDogc3RyaW5nOyBzaWduYWw/OiBBYm9ydFNpZ25hbCB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2hpbGQgPSB0aGlzLnByb2Nlc3Nlcy5nZXQob3B0cy5jb21tYW5kSWQpO1xuICAgIGlmIChjaGlsZCkge1xuICAgICAgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG4gICAgICB0aGlzLnByb2Nlc3Nlcy5kZWxldGUob3B0cy5jb21tYW5kSWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvdXNlQXdhaXQ6IC5cbiAgYXN5bmMgZ2V0U3RhdHVzKCk6IFByb21pc2U8XG4gICAgXCJwZW5kaW5nXCIgfCBcInJ1bm5pbmdcIiB8IFwic3RvcHBpbmdcIiB8IFwic3RvcHBlZFwiIHwgXCJmYWlsZWRcIlxuICA+IHtcbiAgICAvLyBkb2NrZXIgc2FuZGJveCBDTEkgZG9lc24ndCBleHBvc2Ugc3RhdHVzIFx1MjAxNCBhc3N1bWUgcnVubmluZyBpZiBlbnN1cmVkXG4gICAgcmV0dXJuIFwicnVubmluZ1wiO1xuICB9XG5cbiAgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgZW5zdXJlU2FuZGJveCh0aGlzLnNhbmRib3hOYW1lKTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgZXhlY0RvY2tlcihbXCJzdG9wXCIsIHRoaXMuc2FuZGJveE5hbWVdLCB7IHRpbWVvdXRNczogMzBfMDAwIH0pO1xuICAgIGFjdGl2ZVNhbmRib3hlcy5kZWxldGUodGhpcy5zYW5kYm94TmFtZSk7XG4gICAgZW5zdXJlUHJvbWlzZXMuZGVsZXRlKHRoaXMuc2FuZGJveE5hbWUpO1xuICB9XG5cbiAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy91c2VBd2FpdDogLlxuICBhc3luYyBzbmFwc2hvdCgpOiBQcm9taXNlPHsgc25hcHNob3RJZDogc3RyaW5nIH0+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJzbmFwc2hvdCBpcyBub3Qgc3VwcG9ydGVkIGZvciBkb2NrZXIgc2FuZGJveGVzXCIpO1xuICB9XG5cbiAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy91c2VBd2FpdDogLlxuICBhc3luYyB1cGRhdGVOZXR3b3JrUG9saWN5KCk6IFByb21pc2U8bmV2ZXI+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcInVwZGF0ZU5ldHdvcmtQb2xpY3kgaXMgbm90IHN1cHBvcnRlZCBmb3IgZG9ja2VyIHNhbmRib3hlc1wiXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZG9ja2VyU2FuZGJveCgpOiBTYW5kYm94QmluZGluZzxcbiAgXCJkb2NrZXJcIixcbiAgRG9ja2VyQmluZGluZ0NvbmZpZyxcbiAgRG9ja2VyQmluZGluZ01ldGFkYXRhXG4+IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBcImRvY2tlclwiLFxuICAgIGFzeW5jIGNyZWF0ZShvcHRzKSB7XG4gICAgICBjb25zdCBzYW5kYm94TmFtZSA9IGBhZ2VudC0ke3VsaWQoKX1gO1xuICAgICAgY29uc3QgY3dkID0gb3B0cy5zZXR1cD8uY29uZmlnPy5jd2Q7XG5cbiAgICAgIGF3YWl0IGVuc3VyZVNhbmRib3goc2FuZGJveE5hbWUpO1xuXG4gICAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBEb2NrZXJTYW5kYm94SW5zdGFuY2Uoc2FuZGJveE5hbWUsIGN3ZCk7XG5cbiAgICAgIGlmIChvcHRzLnNldHVwPy5ydW4pIHtcbiAgICAgICAgYXdhaXQgb3B0cy5zZXR1cC5ydW4oaW5zdGFuY2UpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBpbnN0YW5jZSxcbiAgICAgICAgbWV0YWRhdGE6IHsgc2FuZGJveE5hbWUgfSxcbiAgICAgIH07XG4gICAgfSxcblxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvdXNlQXdhaXQ6IC5cbiAgICBhc3luYyBjb25uZWN0KG9wdHMpIHtcbiAgICAgIHJldHVybiBuZXcgRG9ja2VyU2FuZGJveEluc3RhbmNlKG9wdHMubWV0YWRhdGEuc2FuZGJveE5hbWUpO1xuICAgIH0sXG4gIH07XG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQUEsU0FBUyxZQUFZO0FBY3JCLGVBQWUsV0FDYixNQUNBLE1BQytEO0FBQy9ELFFBQU0sRUFBRSxNQUFNLElBQUksTUFBTSxPQUFPLGVBQW9CO0FBQ25ELFNBQU8sSUFBSSxRQUFRLENBQUMsU0FBUyxXQUFXO0FBQ3RDLFVBQU0sUUFBUSxNQUFNLFVBQVUsQ0FBQyxXQUFXLEdBQUcsSUFBSSxHQUFHO0FBQUEsTUFDbEQsUUFBUSxNQUFNO0FBQUEsSUFDaEIsQ0FBQztBQUVELFFBQUksU0FBUztBQUNiLFFBQUksU0FBUztBQUViLFVBQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxTQUFpQjtBQUN4QyxnQkFBVSxLQUFLLFNBQVM7QUFBQSxJQUMxQixDQUFDO0FBQ0QsVUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFNBQWlCO0FBQ3hDLGdCQUFVLEtBQUssU0FBUztBQUFBLElBQzFCLENBQUM7QUFFRCxVQUFNLFlBQVksTUFBTSxZQUNwQixXQUFXLE1BQU07QUFDZixZQUFNLEtBQUssU0FBUztBQUNwQixhQUFPLElBQUksTUFBTSxrQkFBa0IsS0FBSyxDQUFDLENBQUMsWUFBWSxDQUFDO0FBQUEsSUFDekQsR0FBRyxLQUFLLFNBQVMsSUFDakI7QUFFSixVQUFNLEdBQUcsU0FBUyxDQUFDLFFBQVE7QUFDekIsVUFBSSxXQUFXO0FBQ2IscUJBQWEsU0FBUztBQUFBLE1BQ3hCO0FBQ0EsYUFBTyxHQUFHO0FBQUEsSUFDWixDQUFDO0FBRUQsVUFBTSxHQUFHLFNBQVMsQ0FBQyxT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
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/sandbox/process-manager.ts
|
|
2
|
+
var DEFAULT_WAIT_UNTIL = 2e3;
|
|
3
|
+
var createProcessManager = (opts) => {
|
|
4
|
+
const { sandbox } = opts;
|
|
5
|
+
const run = async (runOpts) => {
|
|
6
|
+
const { command, waitUntil = DEFAULT_WAIT_UNTIL } = runOpts;
|
|
7
|
+
const execResult = await sandbox.exec({
|
|
8
|
+
command: "sh",
|
|
9
|
+
args: ["-c", command]
|
|
10
|
+
});
|
|
11
|
+
if (waitUntil === 0) {
|
|
12
|
+
return {
|
|
13
|
+
commandId: execResult.commandId,
|
|
14
|
+
stdout: "",
|
|
15
|
+
stderr: "",
|
|
16
|
+
exitCode: -1,
|
|
17
|
+
status: "running",
|
|
18
|
+
outputDir: ""
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const completed = await raceTimeout(execResult, waitUntil);
|
|
22
|
+
if (!completed) {
|
|
23
|
+
return {
|
|
24
|
+
commandId: execResult.commandId,
|
|
25
|
+
stdout: "",
|
|
26
|
+
stderr: "",
|
|
27
|
+
exitCode: -1,
|
|
28
|
+
status: "running",
|
|
29
|
+
outputDir: ""
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const outputDir = `.agent/bash/${Date.now()}-${execResult.commandId}`;
|
|
33
|
+
writeOutputDir(sandbox, outputDir, completed, command);
|
|
34
|
+
return {
|
|
35
|
+
commandId: execResult.commandId,
|
|
36
|
+
stdout: completed.stdout,
|
|
37
|
+
stderr: completed.stderr,
|
|
38
|
+
exitCode: completed.exitCode,
|
|
39
|
+
status: completed.exitCode === 0 ? "completed" : "failed",
|
|
40
|
+
outputDir
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
return { run };
|
|
44
|
+
};
|
|
45
|
+
async function raceTimeout(execResult, timeoutMs) {
|
|
46
|
+
const TIMED_OUT = /* @__PURE__ */ Symbol("timeout");
|
|
47
|
+
const timer = new Promise(
|
|
48
|
+
(resolve) => setTimeout(() => resolve(TIMED_OUT), timeoutMs)
|
|
49
|
+
);
|
|
50
|
+
const winner = await Promise.race([execResult.result, timer]);
|
|
51
|
+
return winner === TIMED_OUT ? null : winner;
|
|
52
|
+
}
|
|
53
|
+
function writeOutputDir(sandbox, dir, result, command) {
|
|
54
|
+
const files = [
|
|
55
|
+
{ path: "stdout.txt", content: result.stdout },
|
|
56
|
+
{
|
|
57
|
+
path: "metadata.json",
|
|
58
|
+
content: JSON.stringify({ exitCode: result.exitCode, command }, null, 2)
|
|
59
|
+
}
|
|
60
|
+
];
|
|
61
|
+
if (result.stderr) {
|
|
62
|
+
files.push({ path: "stderr.txt", content: result.stderr });
|
|
63
|
+
}
|
|
64
|
+
sandbox.writeFiles({ files, destPath: dir }).catch(() => {
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
DEFAULT_WAIT_UNTIL,
|
|
70
|
+
createProcessManager
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NhbmRib3gvcHJvY2Vzcy1tYW5hZ2VyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgdHlwZSB7IEV4ZWNSZXN1bHQgfSBmcm9tIFwiLi9hZGFwdGVyXCI7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1dBSVRfVU5USUwgPSAyMDAwO1xuXG50eXBlIFNhbmRib3hIYW5kbGUgPSB7XG4gIGV4ZWM6IChvcHRzOiB7IGNvbW1hbmQ6IHN0cmluZzsgYXJncz86IHN0cmluZ1tdIH0pID0+IFByb21pc2U8RXhlY1Jlc3VsdD47XG4gIHdyaXRlRmlsZXM6IChvcHRzOiB7XG4gICAgZmlsZXM6IHsgcGF0aDogc3RyaW5nOyBjb250ZW50OiBzdHJpbmcgfVtdO1xuICAgIGRlc3RQYXRoOiBzdHJpbmc7XG4gIH0pID0+IFByb21pc2U8dm9pZD47XG59O1xuXG50eXBlIEJhc2hSZXN1bHQgPSB7XG4gIGNvbW1hbmRJZDogc3RyaW5nO1xuICBzdGRvdXQ6IHN0cmluZztcbiAgc3RkZXJyOiBzdHJpbmc7XG4gIGV4aXRDb2RlOiBudW1iZXI7XG4gIHN0YXR1czogXCJydW5uaW5nXCIgfCBcImNvbXBsZXRlZFwiIHwgXCJmYWlsZWRcIjtcbiAgb3V0cHV0RGlyOiBzdHJpbmc7XG59O1xuXG50eXBlIFJ1bk9wdGlvbnMgPSB7XG4gIGNvbW1hbmQ6IHN0cmluZztcbiAgd2FpdFVudGlsPzogbnVtYmVyO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVByb2Nlc3NNYW5hZ2VyID0gKG9wdHM6IHsgc2FuZGJveDogU2FuZGJveEhhbmRsZSB9KSA9PiB7XG4gIGNvbnN0IHsgc2FuZGJveCB9ID0gb3B0cztcblxuICBjb25zdCBydW4gPSBhc3luYyAocnVuT3B0czogUnVuT3B0aW9ucyk6IFByb21pc2U8QmFzaFJlc3VsdD4gPT4ge1xuICAgIGNvbnN0IHsgY29tbWFuZCwgd2FpdFVudGlsID0gREVGQVVMVF9XQUlUX1VOVElMIH0gPSBydW5PcHRzO1xuXG4gICAgY29uc3QgZXhlY1Jlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICBjb21tYW5kOiBcInNoXCIsXG4gICAgICBhcmdzOiBbXCItY1wiLCBjb21tYW5kXSxcbiAgICB9KTtcblxuICAgIGlmICh3YWl0VW50aWwgPT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvbW1hbmRJZDogZXhlY1Jlc3VsdC5jb21tYW5kSWQsXG4gICAgICAgIHN0ZG91dDogXCJcIixcbiAgICAgICAgc3RkZXJyOiBcIlwiLFxuICAgICAgICBleGl0Q29kZTogLTEsXG4gICAgICAgIHN0YXR1czogXCJydW5uaW5nXCIsXG4gICAgICAgIG91dHB1dERpcjogXCJcIixcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgY29tcGxldGVkID0gYXdhaXQgcmFjZVRpbWVvdXQoZXhlY1Jlc3VsdCwgd2FpdFVudGlsKTtcblxuICAgIGlmICghY29tcGxldGVkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb21tYW5kSWQ6IGV4ZWNSZXN1bHQuY29tbWFuZElkLFxuICAgICAgICBzdGRvdXQ6IFwiXCIsXG4gICAgICAgIHN0ZGVycjogXCJcIixcbiAgICAgICAgZXhpdENvZGU6IC0xLFxuICAgICAgICBzdGF0dXM6IFwicnVubmluZ1wiLFxuICAgICAgICBvdXRwdXREaXI6IFwiXCIsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dERpciA9IGAuYWdlbnQvYmFzaC8ke0RhdGUubm93KCl9LSR7ZXhlY1Jlc3VsdC5jb21tYW5kSWR9YDtcbiAgICB3cml0ZU91dHB1dERpcihzYW5kYm94LCBvdXRwdXREaXIsIGNvbXBsZXRlZCwgY29tbWFuZCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29tbWFuZElkOiBleGVjUmVzdWx0LmNvbW1hbmRJZCxcbiAgICAgIHN0ZG91dDogY29tcGxldGVkLnN0ZG91dCxcbiAgICAgIHN0ZGVycjogY29tcGxldGVkLnN0ZGVycixcbiAgICAgIGV4aXRDb2RlOiBjb21wbGV0ZWQuZXhpdENvZGUsXG4gICAgICBzdGF0dXM6IGNvbXBsZXRlZC5leGl0Q29kZSA9PT0gMCA/IFwiY29tcGxldGVkXCIgOiBcImZhaWxlZFwiLFxuICAgICAgb3V0cHV0RGlyLFxuICAgIH07XG4gIH07XG5cbiAgcmV0dXJuIHsgcnVuIH07XG59O1xuXG5hc3luYyBmdW5jdGlvbiByYWNlVGltZW91dChcbiAgZXhlY1Jlc3VsdDogRXhlY1Jlc3VsdCxcbiAgdGltZW91dE1zOiBudW1iZXJcbik6IFByb21pc2U8eyBzdGRvdXQ6IHN0cmluZzsgc3RkZXJyOiBzdHJpbmc7IGV4aXRDb2RlOiBudW1iZXIgfSB8IG51bGw+IHtcbiAgY29uc3QgVElNRURfT1VUID0gU3ltYm9sKFwidGltZW91dFwiKTtcbiAgY29uc3QgdGltZXIgPSBuZXcgUHJvbWlzZTx0eXBlb2YgVElNRURfT1VUPigocmVzb2x2ZSkgPT5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUoVElNRURfT1VUKSwgdGltZW91dE1zKVxuICApO1xuICBjb25zdCB3aW5uZXIgPSBhd2FpdCBQcm9taXNlLnJhY2UoW2V4ZWNSZXN1bHQucmVzdWx0LCB0aW1lcl0pO1xuICByZXR1cm4gd2lubmVyID09PSBUSU1FRF9PVVQgPyBudWxsIDogd2lubmVyO1xufVxuXG5mdW5jdGlvbiB3cml0ZU91dHB1dERpcihcbiAgc2FuZGJveDogU2FuZGJveEhhbmRsZSxcbiAgZGlyOiBzdHJpbmcsXG4gIHJlc3VsdDogeyBzdGRvdXQ6IHN0cmluZzsgc3RkZXJyOiBzdHJpbmc7IGV4aXRDb2RlOiBudW1iZXIgfSxcbiAgY29tbWFuZDogc3RyaW5nXG4pOiB2b2lkIHtcbiAgY29uc3QgZmlsZXM6IHsgcGF0aDogc3RyaW5nOyBjb250ZW50OiBzdHJpbmcgfVtdID0gW1xuICAgIHsgcGF0aDogXCJzdGRvdXQudHh0XCIsIGNvbnRlbnQ6IHJlc3VsdC5zdGRvdXQgfSxcbiAgICB7XG4gICAgICBwYXRoOiBcIm1ldGFkYXRhLmpzb25cIixcbiAgICAgIGNvbnRlbnQ6IEpTT04uc3RyaW5naWZ5KHsgZXhpdENvZGU6IHJlc3VsdC5leGl0Q29kZSwgY29tbWFuZCB9LCBudWxsLCAyKSxcbiAgICB9LFxuICBdO1xuICBpZiAocmVzdWx0LnN0ZGVycikge1xuICAgIGZpbGVzLnB1c2goeyBwYXRoOiBcInN0ZGVyci50eHRcIiwgY29udGVudDogcmVzdWx0LnN0ZGVyciB9KTtcbiAgfVxuXG4gIHNhbmRib3gud3JpdGVGaWxlcyh7IGZpbGVzLCBkZXN0UGF0aDogZGlyIH0pLmNhdGNoKCgpID0+IHtcbiAgICAvLyBpbnRlbnRpb25hbCBuby1vcCBcdTIwMTQgb3V0cHV0IGZpbGUgd3JpdGUgaXMgYmVzdC1lZmZvcnRcbiAgfSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBRU8sSUFBTSxxQkFBcUI7QUF3QjNCLElBQU0sdUJBQXVCLENBQUMsU0FBcUM7QUFDeEUsUUFBTSxFQUFFLFFBQVEsSUFBSTtBQUVwQixRQUFNLE1BQU0sT0FBTyxZQUE2QztBQUM5RCxVQUFNLEVBQUUsU0FBUyxZQUFZLG1CQUFtQixJQUFJO0FBRXBELFVBQU0sYUFBYSxNQUFNLFFBQVEsS0FBSztBQUFBLE1BQ3BDLFNBQVM7QUFBQSxNQUNULE1BQU0sQ0FBQyxNQUFNLE9BQU87QUFBQSxJQUN0QixDQUFDO0FBRUQsUUFBSSxjQUFjLEdBQUc7QUFDbkIsYUFBTztBQUFBLFFBQ0wsV0FBVyxXQUFXO0FBQUEsUUFDdEIsUUFBUTtBQUFBLFFBQ1IsUUFBUTtBQUFBLFFBQ1IsVUFBVTtBQUFBLFFBQ1YsUUFBUTtBQUFBLFFBQ1IsV0FBVztBQUFBLE1BQ2I7QUFBQSxJQUNGO0FBRUEsVUFBTSxZQUFZLE1BQU0sWUFBWSxZQUFZLFNBQVM7QUFFekQsUUFBSSxDQUFDLFdBQVc7QUFDZCxhQUFPO0FBQUEsUUFDTCxXQUFXLFdBQVc7QUFBQSxRQUN0QixRQUFRO0FBQUEsUUFDUixRQUFRO0FBQUEsUUFDUixVQUFVO0FBQUEsUUFDVixRQUFRO0FBQUEsUUFDUixXQUFXO0FBQUEsTUFDYjtBQUFBLElBQ0Y7QUFFQSxVQUFNLFlBQVksZUFBZSxLQUFLLElBQUksQ0FBQyxJQUFJLFdBQVcsU0FBUztBQUNuRSxtQkFBZSxTQUFTLFdBQVcsV0FBVyxPQUFPO0FBRXJELFdBQU87QUFBQSxNQUNMLFdBQVcsV0FBVztBQUFBLE1BQ3RCLFFBQVEsVUFBVTtBQUFBLE1BQ2xCLFFBQVEsVUFBVTtBQUFBLE1BQ2xCLFVBQVUsVUFBVTtBQUFBLE1BQ3BCLFFBQVEsVUFBVSxhQUFhLElBQUksY0FBYztBQUFBLE1BQ2pEO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFFQSxTQUFPLEVBQUUsSUFBSTtBQUNmO0FBRUEsZUFBZSxZQUNiLFlBQ0EsV0FDc0U7QUFDdEUsUUFBTSxZQUFZLHVCQUFPLFNBQVM7QUFDbEMsUUFBTSxRQUFRLElBQUk7QUFBQSxJQUEwQixDQUFDLFlBQzNDLFdBQVcsTUFBTSxRQUFRLFNBQVMsR0FBRyxTQUFTO0FBQUEsRUFDaEQ7QUFDQSxRQUFNLFNBQVMsTUFBTSxRQUFRLEtBQUssQ0FBQyxXQUFXLFFBQVEsS0FBSyxDQUFDO0FBQzVELFNBQU8sV0FBVyxZQUFZLE9BQU87QUFDdkM7QUFFQSxTQUFTLGVBQ1AsU0FDQSxLQUNBLFFBQ0EsU0FDTTtBQUNOLFFBQU0sUUFBNkM7QUFBQSxJQUNqRCxFQUFFLE1BQU0sY0FBYyxTQUFTLE9BQU8sT0FBTztBQUFBLElBQzdDO0FBQUEsTUFDRSxNQUFNO0FBQUEsTUFDTixTQUFTLEtBQUssVUFBVSxFQUFFLFVBQVUsT0FBTyxVQUFVLFFBQVEsR0FBRyxNQUFNLENBQUM7QUFBQSxJQUN6RTtBQUFBLEVBQ0Y7QUFDQSxNQUFJLE9BQU8sUUFBUTtBQUNqQixVQUFNLEtBQUssRUFBRSxNQUFNLGNBQWMsU0FBUyxPQUFPLE9BQU8sQ0FBQztBQUFBLEVBQzNEO0FBRUEsVUFBUSxXQUFXLEVBQUUsT0FBTyxVQUFVLElBQUksQ0FBQyxFQUFFLE1BQU0sTUFBTTtBQUFBLEVBRXpELENBQUM7QUFDSDsiLAogICJuYW1lcyI6IFtdCn0K
|