@agentstep/agent-sdk 0.4.13 → 0.4.15
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/auth/middleware.js +11 -6
- package/dist/auth/passthrough.js +9 -0
- package/dist/backends/claude/args.js +6 -6
- package/dist/backends/claude/index.js +8 -8
- package/dist/backends/claude/wrapper-script.js +1 -1
- package/dist/backends/codex/auth.js +6 -6
- package/dist/backends/codex/index.js +13 -13
- package/dist/backends/codex/setup.js +4 -4
- package/dist/backends/codex/wrapper-script.js +1 -1
- package/dist/backends/factory/auth.js +6 -6
- package/dist/backends/factory/index.js +14 -14
- package/dist/backends/factory/setup.js +4 -4
- package/dist/backends/factory/wrapper-script.js +1 -1
- package/dist/backends/gemini/auth.js +6 -6
- package/dist/backends/gemini/index.js +13 -13
- package/dist/backends/gemini/setup.js +4 -4
- package/dist/backends/gemini/wrapper-script.js +1 -1
- package/dist/backends/opencode/auth.js +6 -6
- package/dist/backends/opencode/index.js +11 -11
- package/dist/backends/opencode/setup.js +4 -4
- package/dist/backends/opencode/wrapper-script.js +1 -1
- package/dist/backends/pi/auth.js +6 -6
- package/dist/backends/pi/index.js +14 -14
- package/dist/backends/pi/setup.js +4 -4
- package/dist/backends/pi/wrapper-script.js +1 -1
- package/dist/backends/registry.js +30 -30
- package/dist/{chunk-5GDMWWYD.js → chunk-2BDD6OHG.js} +10 -2
- package/dist/{chunk-7YYEE7XR.js → chunk-2BZ2XKJU.js} +5 -5
- package/dist/{chunk-OHYPVKTP.js → chunk-3LG7DRJL.js} +4 -4
- package/dist/{chunk-ZA4JVJJE.js → chunk-3PLJHZFD.js} +1 -1
- package/dist/{chunk-ME6IR4T6.js → chunk-3W6KEDQE.js} +4 -4
- package/dist/{chunk-PMEF3X3C.js → chunk-46LBKEBE.js} +2 -2
- package/dist/{chunk-XLMHG3KR.js → chunk-5DHH2PGR.js} +50 -47
- package/dist/{chunk-6QDHS2MR.js → chunk-5GIZLWWF.js} +1 -1
- package/dist/{chunk-DZDWNOEY.js → chunk-5GZEX4HV.js} +1 -1
- package/dist/{chunk-V364DYC3.js → chunk-5XF65N7J.js} +1 -1
- package/dist/{chunk-6UXT3RG5.js → chunk-64ZLFLMN.js} +4 -4
- package/dist/{chunk-JMDS2RJJ.js → chunk-66CJ6LMV.js} +1 -1
- package/dist/{chunk-2FWZ247V.js → chunk-6IWTDQJN.js} +9 -4
- package/dist/{chunk-TQHS4W74.js → chunk-6OL43KT2.js} +1 -1
- package/dist/{chunk-JZ5RFO77.js → chunk-7LQN7NVU.js} +5 -5
- package/dist/{chunk-X3U7IVTN.js → chunk-7OAMTB47.js} +2 -2
- package/dist/{chunk-I3AP3LEY.js → chunk-ACKMNK3C.js} +7 -7
- package/dist/{chunk-IJEZAD5O.js → chunk-ADK2TYO4.js} +2 -2
- package/dist/{chunk-CX4VNHL6.js → chunk-AH7DAJU5.js} +74 -32
- package/dist/{chunk-5ZRGJTR3.js → chunk-AM7F65IC.js} +10 -10
- package/dist/{chunk-MXRGQRFX.js → chunk-BMPB7XJH.js} +6 -6
- package/dist/{chunk-V7OXXKAL.js → chunk-BZ6HFTHU.js} +1 -1
- package/dist/{chunk-TSYQ4XKJ.js → chunk-CDCLICKM.js} +2 -2
- package/dist/{chunk-FXLGGDLM.js → chunk-CE45WWNZ.js} +4 -4
- package/dist/{chunk-QKRWCXDU.js → chunk-CGSUJZ56.js} +1 -1
- package/dist/{chunk-3WJMUX5B.js → chunk-DO4WVWW7.js} +1 -1
- package/dist/{chunk-AKRE4OEL.js → chunk-EFOIR7R3.js} +5 -3
- package/dist/{chunk-M4RE42AY.js → chunk-ENOKSV57.js} +3 -3
- package/dist/{chunk-RTS2QUZB.js → chunk-EO5ZTIP7.js} +20 -11
- package/dist/{chunk-3NZQBGUJ.js → chunk-F2SDCOHG.js} +18 -18
- package/dist/{chunk-FB6FOIAY.js → chunk-FB4OSWM2.js} +1 -1
- package/dist/{chunk-2PKJSOXX.js → chunk-FCULDJQO.js} +1 -1
- package/dist/{chunk-Q4XYK6FF.js → chunk-GJBKDPQD.js} +5 -5
- package/dist/{chunk-7TW4LHPM.js → chunk-HECQRMDR.js} +2 -2
- package/dist/{chunk-XLVCC4IB.js → chunk-HWWCVD2R.js} +7 -7
- package/dist/{chunk-MBLMAWSE.js → chunk-I5ZA45YL.js} +7 -7
- package/dist/{chunk-X7W6S3TE.js → chunk-IU457W7Q.js} +5 -5
- package/dist/{chunk-HWTECG57.js → chunk-J4TYHQQG.js} +1 -1
- package/dist/{chunk-Y2SC7HU5.js → chunk-JDBXIJKG.js} +4 -4
- package/dist/{chunk-FDY5BA67.js → chunk-JDELTTHV.js} +1 -1
- package/dist/{chunk-BAH4JSTO.js → chunk-JEI7I3EH.js} +3 -3
- package/dist/{chunk-CKPGSS76.js → chunk-JK5TPJHH.js} +1 -1
- package/dist/{chunk-WUNJJNOV.js → chunk-JKUR5MIM.js} +4 -4
- package/dist/{chunk-4BYPJFC5.js → chunk-JOAEFGXZ.js} +62 -54
- package/dist/{chunk-NHY4Q6LS.js → chunk-JOZK6G5O.js} +14 -14
- package/dist/{chunk-5A6E4F5D.js → chunk-JSLEB2ED.js} +2 -1
- package/dist/{chunk-3KDZP45U.js → chunk-K7KLJ2UJ.js} +13 -10
- package/dist/{chunk-LP7AQJCU.js → chunk-KGARPQA4.js} +3 -3
- package/dist/{chunk-6A74MTSB.js → chunk-L6CUSDUF.js} +3 -3
- package/dist/{chunk-N5CUDEUJ.js → chunk-LHHBOQUR.js} +2 -2
- package/dist/{chunk-4FHRWC4H.js → chunk-LJF4GWPJ.js} +5 -5
- package/dist/{chunk-RL6XEYOD.js → chunk-MHQXDTJB.js} +1 -1
- package/dist/{chunk-UX6I36QR.js → chunk-NDQ6CQ7B.js} +122 -122
- package/dist/{chunk-7BGILLYC.js → chunk-NIOWKTIF.js} +2 -2
- package/dist/{chunk-KDAZ5TBL.js → chunk-NK2RCTFI.js} +8 -8
- package/dist/{chunk-OXREXXAQ.js → chunk-NUINUAXO.js} +2 -2
- package/dist/{chunk-XTZ5RQDF.js → chunk-NUO56TF7.js} +4 -4
- package/dist/{chunk-ZIV74JWW.js → chunk-NXRJ7Z4G.js} +2 -2
- package/dist/{chunk-AHHH4PYB.js → chunk-O45IQUWS.js} +3 -3
- package/dist/{chunk-UXZSRUXD.js → chunk-ORU5GQ4Z.js} +2 -2
- package/dist/{chunk-QYFD2OBI.js → chunk-OWTXN2FU.js} +1 -1
- package/dist/{chunk-V4P46OHG.js → chunk-P7P2NWZD.js} +5 -5
- package/dist/{chunk-MAW3HLIO.js → chunk-PB7LR2AG.js} +2 -2
- package/dist/{chunk-KEV4OMRF.js → chunk-PNYCULIF.js} +9 -9
- package/dist/{chunk-VVH5DQ2C.js → chunk-PWWRWR75.js} +42 -3
- package/dist/{chunk-G5RQN53K.js → chunk-PZWVTEL2.js} +1 -1
- package/dist/{chunk-OGONPLTA.js → chunk-QFUJDBET.js} +6 -6
- package/dist/{chunk-Q5KHBU7P.js → chunk-QH57EOKP.js} +12 -4
- package/dist/{chunk-6ZJ6X6H7.js → chunk-QLWA4MJ5.js} +15 -4
- package/dist/{chunk-2QGVGXIT.js → chunk-QQDSHL27.js} +4 -4
- package/dist/{chunk-J4NKW3L5.js → chunk-QYSDP6V5.js} +5 -5
- package/dist/{chunk-ETGRQMFJ.js → chunk-R45W644X.js} +1 -1
- package/dist/{chunk-LPWEFC55.js → chunk-R5OZHLAD.js} +2 -2
- package/dist/{chunk-DFE7VZWD.js → chunk-RMEX55EU.js} +4 -4
- package/dist/{chunk-TY7XTT5N.js → chunk-RZXRMPF4.js} +1 -1
- package/dist/{chunk-D5XOXR3A.js → chunk-S3SKODVV.js} +4 -4
- package/dist/{chunk-CU5GUNFW.js → chunk-S6AM7WVH.js} +2 -2
- package/dist/{chunk-YOFB6CO5.js → chunk-SDLNBA53.js} +7 -7
- package/dist/{chunk-JFY6EH24.js → chunk-SIKTYKVO.js} +15 -15
- package/dist/{chunk-7XFIUYFM.js → chunk-SWIP7JBQ.js} +4 -4
- package/dist/{chunk-XNK2KUTI.js → chunk-SXE7H3VK.js} +2 -2
- package/dist/{chunk-OQWHKEYE.js → chunk-TFK6TCMC.js} +3 -3
- package/dist/{chunk-TV2VE2LX.js → chunk-TWPTR2C2.js} +2 -2
- package/dist/{chunk-3MNDEAPX.js → chunk-UJDAT42X.js} +8 -8
- package/dist/{chunk-UN3LHCWQ.js → chunk-VIGJQU6V.js} +3 -3
- package/dist/{chunk-4INVRCRD.js → chunk-VO7BDPYU.js} +2 -2
- package/dist/{chunk-UVCPCX74.js → chunk-VS7AMAMU.js} +8 -8
- package/dist/chunk-W6WKXFHN.js +39 -0
- package/dist/{chunk-3EGA6TEL.js → chunk-WPEGSLXX.js} +1 -1
- package/dist/{chunk-YM2LYRYY.js → chunk-WRWTK455.js} +3 -3
- package/dist/{chunk-W3M3ME6B.js → chunk-XG4UIGDH.js} +5 -5
- package/dist/{chunk-TH54MJMX.js → chunk-XPKY3Z54.js} +1 -1
- package/dist/{chunk-BM34UHSS.js → chunk-Y27R572J.js} +6 -5
- package/dist/{chunk-6BDLNY5J.js → chunk-Y4X3QY2S.js} +2 -2
- package/dist/{chunk-U4F4JSME.js → chunk-Y6ZY23HE.js} +3 -3
- package/dist/{chunk-KZGAZPNV.js → chunk-YGAHGTVZ.js} +3 -3
- package/dist/{chunk-H74BPBKE.js → chunk-YSUPRYX2.js} +5 -5
- package/dist/{chunk-HERWBOQ7.js → chunk-ZLUBNJEO.js} +5 -5
- package/dist/{chunk-Y5553CX6.js → chunk-ZP5VMV5O.js} +4 -4
- package/dist/config/index.js +5 -5
- package/dist/containers/client.js +6 -6
- package/dist/containers/exec.js +6 -6
- package/dist/containers/lifecycle.js +47 -47
- package/dist/containers/pool.js +3 -3
- package/dist/containers/setup.js +9 -9
- package/dist/db/agents.js +6 -6
- package/dist/db/api_keys.js +5 -5
- package/dist/db/audit.js +3 -3
- package/dist/db/batch.js +10 -10
- package/dist/db/client.js +2 -2
- package/dist/db/credentials.js +3 -3
- package/dist/db/drizzle.js +4 -4
- package/dist/db/environments.js +6 -6
- package/dist/db/events.js +5 -5
- package/dist/db/files.js +5 -5
- package/dist/db/memory.js +5 -5
- package/dist/db/migrations.js +1 -1
- package/dist/db/proxy.js +5 -5
- package/dist/db/schema.js +1 -1
- package/dist/db/session-resources.js +5 -5
- package/dist/db/sessions.js +9 -9
- package/dist/db/sync.js +5 -5
- package/dist/db/tenants.js +3 -3
- package/dist/db/traces.js +5 -5
- package/dist/db/upstream_keys.js +3 -3
- package/dist/db/vaults.js +6 -6
- package/dist/handlers/agents.js +60 -59
- package/dist/handlers/api_keys.js +61 -59
- package/dist/handlers/audit.js +61 -59
- package/dist/handlers/batch.js +61 -59
- package/dist/handlers/credentials.js +61 -59
- package/dist/handlers/environments.js +61 -60
- package/dist/handlers/events.js +64 -63
- package/dist/handlers/files.js +61 -59
- package/dist/handlers/index.js +125 -124
- package/dist/handlers/license.js +60 -58
- package/dist/handlers/memory.js +61 -59
- package/dist/handlers/metrics.js +60 -58
- package/dist/handlers/models.js +61 -59
- package/dist/handlers/openapi.js +3 -3
- package/dist/handlers/providers.js +60 -58
- package/dist/handlers/resources.js +60 -58
- package/dist/handlers/sessions.js +63 -62
- package/dist/handlers/settings.js +60 -58
- package/dist/handlers/skills-write.js +60 -58
- package/dist/handlers/skills.js +61 -59
- package/dist/handlers/stream.js +60 -59
- package/dist/handlers/tenants.js +61 -59
- package/dist/handlers/threads.js +60 -58
- package/dist/handlers/traces.js +61 -59
- package/dist/handlers/ui.js +1 -1
- package/dist/handlers/upstream_keys.js +63 -61
- package/dist/handlers/vaults.js +60 -58
- package/dist/handlers/whoami.js +60 -58
- package/dist/http.js +59 -57
- package/dist/index.js +81 -78
- package/dist/init.js +55 -55
- package/dist/lib/model-registry.js +6 -6
- package/dist/lib/skills-cache.js +6 -6
- package/dist/observability/otlp.js +12 -12
- package/dist/observability/redactor.js +8 -8
- package/dist/openapi/schemas.js +1 -1
- package/dist/openapi/spec.js +2 -2
- package/dist/providers/fly.js +5 -5
- package/dist/providers/modal.js +5 -5
- package/dist/providers/registry.js +1 -1
- package/dist/providers/resolve-secrets.js +7 -7
- package/dist/providers/sprites.js +7 -7
- package/dist/providers/upstream-keys.js +11 -11
- package/dist/providers/vercel.js +5 -5
- package/dist/proxy/forward.js +6 -6
- package/dist/queue/index.js +6 -6
- package/dist/sessions/bus.js +10 -10
- package/dist/sessions/driver.js +48 -48
- package/dist/sessions/grader.js +5 -5
- package/dist/sessions/secrets.js +8 -8
- package/dist/sessions/sweeper.js +44 -44
- package/dist/sessions/threads.js +52 -52
- package/dist/shutdown.js +45 -45
- package/dist/sync/anthropic.js +10 -10
- package/dist/sync/container-file-sync.js +27 -15
- package/dist/sync/file-sync.js +19 -19
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/backends/claude/wrapper-script.ts
|
|
2
2
|
var CLAUDE_WRAPPER_PATH = "/tmp/.claude-wrapper";
|
|
3
|
-
var
|
|
3
|
+
var SANDBOX_WRAPPER_SCRIPT = `#!/bin/sh
|
|
4
4
|
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
|
|
5
5
|
# V8 bytecode cache: Node.js caches compiled JS to disk.
|
|
6
6
|
# First run builds cache (~55s). Subsequent runs skip V8 compilation (~8s startup).
|
|
@@ -31,13 +31,13 @@ EXIT_CODE=$?
|
|
|
31
31
|
rm -f "$PROMPT_FILE"
|
|
32
32
|
exit $EXIT_CODE
|
|
33
33
|
`;
|
|
34
|
-
async function installClaudeWrapper(
|
|
35
|
-
console.log(`[wrapper] writing ${CLAUDE_WRAPPER_PATH} to ${
|
|
36
|
-
const result = await provider.exec(
|
|
34
|
+
async function installClaudeWrapper(sandboxName, provider) {
|
|
35
|
+
console.log(`[wrapper] writing ${CLAUDE_WRAPPER_PATH} to ${sandboxName} (${SANDBOX_WRAPPER_SCRIPT.length} bytes)`);
|
|
36
|
+
const result = await provider.exec(sandboxName, [
|
|
37
37
|
"sh",
|
|
38
38
|
"-c",
|
|
39
39
|
`cat > ${CLAUDE_WRAPPER_PATH} && chmod +x ${CLAUDE_WRAPPER_PATH} && echo OK`
|
|
40
|
-
], { stdin:
|
|
40
|
+
], { stdin: SANDBOX_WRAPPER_SCRIPT });
|
|
41
41
|
console.log(`[wrapper] result: exit=${result.exit_code} stdout="${result.stdout.trim()}" stderr="${result.stderr.trim()}"`);
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/backends/pi/wrapper-script.ts
|
|
2
2
|
var PI_WRAPPER_PATH = "/tmp/.pi-wrapper";
|
|
3
|
-
var
|
|
3
|
+
var SANDBOX_WRAPPER_SCRIPT = [
|
|
4
4
|
"#!/bin/bash",
|
|
5
5
|
'while IFS= read -r line; do [ -z "$line" ] && break; export "$line"; done',
|
|
6
6
|
'exec pi "$@"'
|
|
7
7
|
].join("\n");
|
|
8
|
-
async function installPiWrapper(
|
|
9
|
-
const escaped =
|
|
10
|
-
await provider.exec(
|
|
8
|
+
async function installPiWrapper(sandboxName, provider) {
|
|
9
|
+
const escaped = SANDBOX_WRAPPER_SCRIPT.replace(/'/g, "'\\''");
|
|
10
|
+
await provider.exec(sandboxName, [
|
|
11
11
|
"bash",
|
|
12
12
|
"-c",
|
|
13
13
|
`printf '%s' '${escaped}' > ${PI_WRAPPER_PATH} && chmod +x ${PI_WRAPPER_PATH}`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_TENANT_ID
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JDELTTHV.js";
|
|
4
4
|
import {
|
|
5
5
|
init_ids,
|
|
6
6
|
newId
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
getDrizzle,
|
|
10
10
|
init_drizzle
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-SXE7H3VK.js";
|
|
12
12
|
import {
|
|
13
13
|
schema_exports
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-LHHBOQUR.js";
|
|
15
15
|
import {
|
|
16
16
|
init_clock,
|
|
17
17
|
nowMs,
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
jsonOk,
|
|
8
8
|
routeWrap
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6IWTDQJN.js";
|
|
10
10
|
import {
|
|
11
11
|
createVault,
|
|
12
12
|
deleteEntry,
|
|
@@ -16,14 +16,14 @@ import {
|
|
|
16
16
|
listEntries,
|
|
17
17
|
listVaults,
|
|
18
18
|
setEntry
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-VIGJQU6V.js";
|
|
20
20
|
import {
|
|
21
21
|
getAgent
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-JEI7I3EH.js";
|
|
23
23
|
import {
|
|
24
24
|
getDb,
|
|
25
25
|
init_client
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-5GZEX4HV.js";
|
|
27
27
|
import {
|
|
28
28
|
badRequest,
|
|
29
29
|
conflict,
|
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveVaultSecrets
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DO4WVWW7.js";
|
|
4
4
|
import {
|
|
5
5
|
dockerProvider
|
|
6
6
|
} from "./chunk-RMZRSYIJ.js";
|
|
7
7
|
import {
|
|
8
8
|
appendEvent
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BMPB7XJH.js";
|
|
10
10
|
import {
|
|
11
|
-
|
|
11
|
+
getSession,
|
|
12
|
+
getSessionRow,
|
|
13
|
+
setSessionSandbox
|
|
14
|
+
} from "./chunk-I5ZA45YL.js";
|
|
15
|
+
import {
|
|
16
|
+
deleteSprite,
|
|
17
|
+
listSprites
|
|
18
|
+
} from "./chunk-XPKY3Z54.js";
|
|
19
|
+
import {
|
|
20
|
+
allSessionSandboxes,
|
|
12
21
|
countInEnv,
|
|
13
22
|
register,
|
|
14
23
|
unregister
|
|
15
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-EFOIR7R3.js";
|
|
16
25
|
import {
|
|
17
26
|
resolveContainerProvider
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import {
|
|
20
|
-
getSession,
|
|
21
|
-
getSessionRow,
|
|
22
|
-
setSessionSprite
|
|
23
|
-
} from "./chunk-MBLMAWSE.js";
|
|
27
|
+
} from "./chunk-JSLEB2ED.js";
|
|
24
28
|
import {
|
|
25
29
|
getEnvironment,
|
|
26
30
|
getEnvironmentRow
|
|
27
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-NUO56TF7.js";
|
|
28
32
|
import {
|
|
29
33
|
getAgent
|
|
30
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-JEI7I3EH.js";
|
|
31
35
|
import {
|
|
32
36
|
resolveBackend
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
import {
|
|
35
|
-
deleteSprite,
|
|
36
|
-
listSprites
|
|
37
|
-
} from "./chunk-TH54MJMX.js";
|
|
37
|
+
} from "./chunk-QFUJDBET.js";
|
|
38
38
|
import {
|
|
39
39
|
getConfig
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-QH57EOKP.js";
|
|
41
41
|
import {
|
|
42
42
|
init_clock,
|
|
43
43
|
nowMs
|
|
@@ -51,8 +51,8 @@ init_clock();
|
|
|
51
51
|
var lcLog = (...args) => {
|
|
52
52
|
if (process.env.DEBUG_LIFECYCLE === "1") console.log(...args);
|
|
53
53
|
};
|
|
54
|
-
var
|
|
55
|
-
async function installSkills(
|
|
54
|
+
var SANDBOX_NAME_PREFIX = "ca-sess-";
|
|
55
|
+
async function installSkills(sandboxName, provider, skills, engine) {
|
|
56
56
|
if (!skills || skills.length === 0) return;
|
|
57
57
|
const SAFE_NAME_RE = /^[a-zA-Z0-9_.-]+$/;
|
|
58
58
|
const safeSkills = skills.filter((s) => {
|
|
@@ -63,33 +63,33 @@ async function installSkills(spriteName, provider, skills, engine) {
|
|
|
63
63
|
return true;
|
|
64
64
|
});
|
|
65
65
|
if (engine === "claude") {
|
|
66
|
-
await provider.exec(
|
|
66
|
+
await provider.exec(sandboxName, ["mkdir", "-p", "/home/agent/.claude/skills"]);
|
|
67
67
|
for (const skill of safeSkills) {
|
|
68
68
|
const dirPath = `/home/agent/.claude/skills/${skill.name}`;
|
|
69
69
|
const filePath = `${dirPath}/SKILL.md`;
|
|
70
|
-
await provider.exec(
|
|
71
|
-
await provider.exec(
|
|
70
|
+
await provider.exec(sandboxName, ["mkdir", "-p", dirPath]);
|
|
71
|
+
await provider.exec(sandboxName, ["sh", "-c", 'cat > "$1"', "sh", filePath], {
|
|
72
72
|
stdin: skill.content
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
-
await provider.exec(
|
|
76
|
+
await provider.exec(sandboxName, ["mkdir", "-p", "/home/agent/.agents/skills"]);
|
|
77
77
|
for (const skill of safeSkills) {
|
|
78
78
|
const dirPath = `/home/agent/.agents/skills/${skill.name}`;
|
|
79
79
|
const filePath = `${dirPath}/SKILL.md`;
|
|
80
|
-
await provider.exec(
|
|
81
|
-
await provider.exec(
|
|
80
|
+
await provider.exec(sandboxName, ["mkdir", "-p", dirPath]);
|
|
81
|
+
await provider.exec(sandboxName, ["sh", "-c", 'cat > "$1"', "sh", filePath], {
|
|
82
82
|
stdin: skill.content
|
|
83
83
|
});
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
function
|
|
87
|
-
return `${
|
|
86
|
+
function deriveSandboxName(sessionId) {
|
|
87
|
+
return `${SANDBOX_NAME_PREFIX}${sessionId.replace(/^sess_/, "").toLowerCase()}`;
|
|
88
88
|
}
|
|
89
89
|
async function acquireForFirstTurn(sessionId) {
|
|
90
90
|
const row = getSessionRow(sessionId);
|
|
91
91
|
if (!row) throw new ApiError(404, "not_found_error", `session not found: ${sessionId}`);
|
|
92
|
-
if (row.
|
|
92
|
+
if (row.sandbox_name) return row.sandbox_name;
|
|
93
93
|
const env = getEnvironmentRow(row.environment_id);
|
|
94
94
|
if (!env) throw new ApiError(404, "not_found_error", "environment not found");
|
|
95
95
|
if (env.state !== "ready") {
|
|
@@ -99,8 +99,8 @@ async function acquireForFirstTurn(sessionId) {
|
|
|
99
99
|
`environment is not ready (state=${env.state})`
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
|
-
if (countInEnv(env.id) >= getConfig().
|
|
103
|
-
throw new ApiError(503, "server_busy", "env
|
|
102
|
+
if (countInEnv(env.id) >= getConfig().maxSandboxesPerEnv) {
|
|
103
|
+
throw new ApiError(503, "server_busy", "env sandbox pool exhausted");
|
|
104
104
|
}
|
|
105
105
|
const agent = getAgent(row.agent_id, row.agent_version);
|
|
106
106
|
if (!agent) {
|
|
@@ -125,10 +125,18 @@ async function acquireForFirstTurn(sessionId) {
|
|
|
125
125
|
create: (opts) => provider.create({ ...opts, secrets }),
|
|
126
126
|
delete: (n, s) => provider.delete(n, s ?? secrets)
|
|
127
127
|
} : provider;
|
|
128
|
-
const name =
|
|
128
|
+
const name = deriveSandboxName(sessionId);
|
|
129
129
|
lcLog(`[lifecycle] ${sessionId} creating container via ${sp.name}...`);
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
try {
|
|
131
|
+
await sp.create({ name });
|
|
132
|
+
lcLog(`[lifecycle] ${sessionId} container created: ${name}`);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (String(err).includes("already exists")) {
|
|
135
|
+
lcLog(`[lifecycle] ${sessionId} container ${name} already exists, reusing`);
|
|
136
|
+
} else {
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
132
140
|
const needsSlowPrep = backend.name !== "claude";
|
|
133
141
|
if (needsSlowPrep) {
|
|
134
142
|
appendEvent(sessionId, {
|
|
@@ -140,7 +148,7 @@ async function acquireForFirstTurn(sessionId) {
|
|
|
140
148
|
}
|
|
141
149
|
try {
|
|
142
150
|
lcLog(`[lifecycle] ${sessionId} installing ${backend.name} engine on container...`);
|
|
143
|
-
await backend.
|
|
151
|
+
await backend.prepareOnSandbox(name, sp);
|
|
144
152
|
lcLog(`[lifecycle] ${sessionId} engine installed`);
|
|
145
153
|
if (agent.engine === "claude") {
|
|
146
154
|
const customTools = agent.tools.filter(
|
|
@@ -214,17 +222,17 @@ async function acquireForFirstTurn(sessionId) {
|
|
|
214
222
|
}
|
|
215
223
|
}
|
|
216
224
|
register({
|
|
217
|
-
|
|
225
|
+
sandboxName: name,
|
|
218
226
|
envId: env.id,
|
|
219
227
|
sessionId,
|
|
220
228
|
createdAt: nowMs(),
|
|
221
229
|
vaultSecrets: Object.keys(secrets).length > 0 ? secrets : void 0
|
|
222
230
|
});
|
|
223
|
-
|
|
231
|
+
setSessionSandbox(sessionId, name);
|
|
224
232
|
return name;
|
|
225
233
|
}
|
|
226
|
-
async function provisionResources(
|
|
227
|
-
await provider.exec(
|
|
234
|
+
async function provisionResources(sandboxName, resources, provider) {
|
|
235
|
+
await provider.exec(sandboxName, ["mkdir", "-p", "/mnt/session/resources", "/mnt/session/uploads", "/mnt/session/outputs"]);
|
|
228
236
|
const MAX_RESOURCE_BYTES = 50 * 1024 * 1024;
|
|
229
237
|
const SAFE_PATH_RE = /^[a-zA-Z0-9_./\-]+$/;
|
|
230
238
|
function sanitizeMountPath(p) {
|
|
@@ -251,11 +259,11 @@ async function provisionResources(spriteName, resources, provider) {
|
|
|
251
259
|
}
|
|
252
260
|
const dir = mountTarget.substring(0, mountTarget.lastIndexOf("/"));
|
|
253
261
|
if (dir) {
|
|
254
|
-
await provider.exec(
|
|
262
|
+
await provider.exec(sandboxName, ["mkdir", "-p", dir]);
|
|
255
263
|
}
|
|
256
264
|
const writeTo = async (target, content) => {
|
|
257
|
-
await provider.exec(
|
|
258
|
-
await provider.exec(
|
|
265
|
+
await provider.exec(sandboxName, ["sh", "-c", 'cat > "$1"', "sh", target], { stdin: content });
|
|
266
|
+
await provider.exec(sandboxName, ["chmod", "a-w", target]);
|
|
259
267
|
};
|
|
260
268
|
if (r.type === "uri" && r.uri) {
|
|
261
269
|
try {
|
|
@@ -315,9 +323,9 @@ async function provisionResources(spriteName, resources, provider) {
|
|
|
315
323
|
gitArgs.push("--branch", safeBranch);
|
|
316
324
|
}
|
|
317
325
|
gitArgs.push("--", r.repository_url, repoDir);
|
|
318
|
-
const result = await provider.exec(
|
|
326
|
+
const result = await provider.exec(sandboxName, gitArgs, { timeoutMs: 12e4 });
|
|
319
327
|
if (safeCommit && result.exit_code === 0) {
|
|
320
|
-
await provider.exec(
|
|
328
|
+
await provider.exec(sandboxName, ["git", "-C", repoDir, "checkout", safeCommit], { timeoutMs: 3e4 });
|
|
321
329
|
}
|
|
322
330
|
if (result.exit_code !== 0) {
|
|
323
331
|
console.warn(`[lifecycle] git clone failed for ${r.repository_url}: ${result.stderr.slice(0, 200)}`);
|
|
@@ -331,7 +339,7 @@ async function provisionResources(spriteName, resources, provider) {
|
|
|
331
339
|
async function releaseSession(sessionId) {
|
|
332
340
|
const entry = unregister(sessionId);
|
|
333
341
|
const row = getSessionRow(sessionId);
|
|
334
|
-
const name = entry?.
|
|
342
|
+
const name = entry?.sandboxName ?? row?.sandbox_name ?? null;
|
|
335
343
|
if (name) {
|
|
336
344
|
const envObj = row ? getEnvironment(row.environment_id) : null;
|
|
337
345
|
const provider = await resolveContainerProvider(envObj?.config?.provider);
|
|
@@ -339,18 +347,18 @@ async function releaseSession(sessionId) {
|
|
|
339
347
|
console.warn(`releaseSession: failed to delete container ${name}:`, err);
|
|
340
348
|
});
|
|
341
349
|
}
|
|
342
|
-
if (row?.
|
|
350
|
+
if (row?.sandbox_name) setSessionSandbox(sessionId, null);
|
|
343
351
|
}
|
|
344
|
-
async function
|
|
352
|
+
async function reconcileOrphanSandboxes() {
|
|
345
353
|
let deleted = 0;
|
|
346
354
|
let kept = 0;
|
|
347
355
|
const liveNames = new Set(
|
|
348
|
-
|
|
356
|
+
allSessionSandboxes().map((e) => e.sandboxName).filter(Boolean)
|
|
349
357
|
);
|
|
350
358
|
let token;
|
|
351
359
|
for (; ; ) {
|
|
352
360
|
const res = await listSprites({
|
|
353
|
-
prefix:
|
|
361
|
+
prefix: SANDBOX_NAME_PREFIX,
|
|
354
362
|
max_results: 100,
|
|
355
363
|
continuation_token: token
|
|
356
364
|
});
|
|
@@ -369,13 +377,13 @@ async function reconcileOrphans() {
|
|
|
369
377
|
}
|
|
370
378
|
return { deleted, kept };
|
|
371
379
|
}
|
|
372
|
-
async function
|
|
380
|
+
async function reconcileDockerOrphanSandboxes() {
|
|
373
381
|
let deleted = 0;
|
|
374
382
|
let kept = 0;
|
|
375
383
|
const liveNames = new Set(
|
|
376
|
-
|
|
384
|
+
allSessionSandboxes().map((e) => e.sandboxName).filter(Boolean)
|
|
377
385
|
);
|
|
378
|
-
const containers = await dockerProvider.list({ prefix:
|
|
386
|
+
const containers = await dockerProvider.list({ prefix: SANDBOX_NAME_PREFIX });
|
|
379
387
|
for (const c of containers) {
|
|
380
388
|
if (liveNames.has(c.name)) {
|
|
381
389
|
kept++;
|
|
@@ -393,6 +401,6 @@ export {
|
|
|
393
401
|
acquireForFirstTurn,
|
|
394
402
|
provisionResources,
|
|
395
403
|
releaseSession,
|
|
396
|
-
|
|
397
|
-
|
|
404
|
+
reconcileOrphanSandboxes,
|
|
405
|
+
reconcileDockerOrphanSandboxes
|
|
398
406
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
syncAndCreateSession
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZP5VMV5O.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveRemoteSessionId,
|
|
6
6
|
upsertSync
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YGAHGTVZ.js";
|
|
8
8
|
import {
|
|
9
9
|
assertResourceTenant,
|
|
10
10
|
tenantFilter
|
|
@@ -12,16 +12,16 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
interruptSession
|
|
14
14
|
} from "./chunk-DC2UMEQH.js";
|
|
15
|
-
import {
|
|
16
|
-
forwardToAnthropic
|
|
17
|
-
} from "./chunk-6ZJ6X6H7.js";
|
|
18
15
|
import {
|
|
19
16
|
kickoffEnvironmentSetup
|
|
20
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-SDLNBA53.js";
|
|
21
18
|
import {
|
|
22
19
|
jsonOk,
|
|
23
20
|
routeWrap
|
|
24
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-6IWTDQJN.js";
|
|
22
|
+
import {
|
|
23
|
+
forwardToAnthropic
|
|
24
|
+
} from "./chunk-QLWA4MJ5.js";
|
|
25
25
|
import {
|
|
26
26
|
errors_exports,
|
|
27
27
|
init_errors
|
|
@@ -31,18 +31,18 @@ import {
|
|
|
31
31
|
isProxied,
|
|
32
32
|
markProxied,
|
|
33
33
|
unmarkProxied
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-NIOWKTIF.js";
|
|
35
35
|
import {
|
|
36
36
|
dropActor,
|
|
37
37
|
getActor
|
|
38
38
|
} from "./chunk-LAWTTG2E.js";
|
|
39
39
|
import {
|
|
40
40
|
releaseSession
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-JOAEFGXZ.js";
|
|
42
42
|
import {
|
|
43
43
|
appendEvent,
|
|
44
44
|
dropEmitter
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-BMPB7XJH.js";
|
|
46
46
|
import {
|
|
47
47
|
archiveSession,
|
|
48
48
|
createSession,
|
|
@@ -50,13 +50,13 @@ import {
|
|
|
50
50
|
listSessions,
|
|
51
51
|
updateSessionMutable,
|
|
52
52
|
updateSessionStatus
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-I5ZA45YL.js";
|
|
54
54
|
import {
|
|
55
55
|
getEnvironment
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-NUO56TF7.js";
|
|
57
57
|
import {
|
|
58
58
|
getAgent
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-JEI7I3EH.js";
|
|
60
60
|
import {
|
|
61
61
|
init_clock,
|
|
62
62
|
nowMs
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
import {
|
|
65
65
|
getDb,
|
|
66
66
|
init_client
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-5GZEX4HV.js";
|
|
68
68
|
import {
|
|
69
69
|
badRequest,
|
|
70
70
|
notFound
|
|
@@ -14,7 +14,8 @@ var PROVIDERS = {
|
|
|
14
14
|
anthropic: async () => (await import("./providers/anthropic.js")).anthropicProvider
|
|
15
15
|
};
|
|
16
16
|
async function resolveContainerProvider(providerName) {
|
|
17
|
-
|
|
17
|
+
if (!providerName) throw new Error("No container provider specified \u2014 set provider in the environment config");
|
|
18
|
+
const key = providerName;
|
|
18
19
|
const loader = PROVIDERS[key];
|
|
19
20
|
if (!loader) throw new Error(`Unknown provider: "${key}". Available: ${Object.keys(PROVIDERS).join(", ")}`);
|
|
20
21
|
return loader();
|
|
@@ -3,25 +3,25 @@ import {
|
|
|
3
3
|
resolveCreateTenant,
|
|
4
4
|
tenantFilter
|
|
5
5
|
} from "./chunk-23UKWXJH.js";
|
|
6
|
-
import {
|
|
7
|
-
forwardToAnthropic
|
|
8
|
-
} from "./chunk-6ZJ6X6H7.js";
|
|
9
6
|
import {
|
|
10
7
|
kickoffEnvironmentSetup
|
|
11
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SDLNBA53.js";
|
|
12
9
|
import {
|
|
13
10
|
jsonOk,
|
|
14
11
|
routeWrap
|
|
15
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-6IWTDQJN.js";
|
|
13
|
+
import {
|
|
14
|
+
forwardToAnthropic
|
|
15
|
+
} from "./chunk-QLWA4MJ5.js";
|
|
16
16
|
import {
|
|
17
17
|
getProxiedTenantId,
|
|
18
18
|
isProxied,
|
|
19
19
|
markProxied,
|
|
20
20
|
unmarkProxied
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-NIOWKTIF.js";
|
|
22
22
|
import {
|
|
23
23
|
resolveContainerProvider
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-JSLEB2ED.js";
|
|
25
25
|
import {
|
|
26
26
|
archiveEnvironment,
|
|
27
27
|
createEnvironment,
|
|
@@ -30,11 +30,11 @@ import {
|
|
|
30
30
|
hasSessionsAttached,
|
|
31
31
|
listEnvironments,
|
|
32
32
|
updateEnvironment
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-NUO56TF7.js";
|
|
34
34
|
import {
|
|
35
35
|
getDb,
|
|
36
36
|
init_client
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-5GZEX4HV.js";
|
|
38
38
|
import {
|
|
39
39
|
badRequest,
|
|
40
40
|
conflict,
|
|
@@ -123,7 +123,10 @@ function handleCreateEnvironment(request) {
|
|
|
123
123
|
if (existingEnvs.some((e) => e.name === parsed.data.name)) {
|
|
124
124
|
throw conflict(`Environment with name "${parsed.data.name}" already exists`);
|
|
125
125
|
}
|
|
126
|
-
const providerName = parsed.data.config.provider
|
|
126
|
+
const providerName = parsed.data.config.provider;
|
|
127
|
+
if (!providerName) {
|
|
128
|
+
throw badRequest("config.provider is required \u2014 specify a sandbox provider (e.g. docker, apple-container)");
|
|
129
|
+
}
|
|
127
130
|
const CLOUD_PROVIDERS = /* @__PURE__ */ new Set(["sprites", "e2b", "vercel", "daytona", "fly", "modal", "anthropic"]);
|
|
128
131
|
if (!CLOUD_PROVIDERS.has(providerName)) {
|
|
129
132
|
const provider = await resolveContainerProvider(providerName);
|
|
@@ -12,15 +12,15 @@ import {
|
|
|
12
12
|
listMemories,
|
|
13
13
|
listMemoryStores,
|
|
14
14
|
updateMemory
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-NUINUAXO.js";
|
|
16
16
|
import {
|
|
17
17
|
jsonOk,
|
|
18
18
|
routeWrap
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-6IWTDQJN.js";
|
|
20
20
|
import {
|
|
21
21
|
getDb,
|
|
22
22
|
init_client
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-5GZEX4HV.js";
|
|
24
24
|
import {
|
|
25
25
|
badRequest,
|
|
26
26
|
conflict,
|
|
@@ -11,18 +11,18 @@ import {
|
|
|
11
11
|
getFileRecord,
|
|
12
12
|
listFiles,
|
|
13
13
|
updateFileStoragePath
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-NXRJ7Z4G.js";
|
|
15
15
|
import {
|
|
16
16
|
assertResourceTenant
|
|
17
17
|
} from "./chunk-23UKWXJH.js";
|
|
18
18
|
import {
|
|
19
19
|
jsonOk,
|
|
20
20
|
routeWrap
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-6IWTDQJN.js";
|
|
22
22
|
import {
|
|
23
23
|
getDb,
|
|
24
24
|
init_client
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-5GZEX4HV.js";
|
|
26
26
|
import {
|
|
27
27
|
badRequest,
|
|
28
28
|
notFound
|
|
@@ -94,7 +94,7 @@ var init_schema = __esm({
|
|
|
94
94
|
metadata_json: text("metadata_json").notNull().default("{}"),
|
|
95
95
|
state: text("state").notNull().default("preparing"),
|
|
96
96
|
state_message: text("state_message"),
|
|
97
|
-
|
|
97
|
+
template_sandbox: text("template_sandbox"),
|
|
98
98
|
checkpoint_id: text("checkpoint_id"),
|
|
99
99
|
// v0.5 ALTER TABLE addition:
|
|
100
100
|
tenant_id: text("tenant_id"),
|
|
@@ -106,7 +106,7 @@ var init_schema = __esm({
|
|
|
106
106
|
agent_id: text("agent_id").notNull(),
|
|
107
107
|
agent_version: integer("agent_version").notNull(),
|
|
108
108
|
environment_id: text("environment_id").notNull(),
|
|
109
|
-
|
|
109
|
+
sandbox_name: text("sandbox_name"),
|
|
110
110
|
claude_session_id: text("claude_session_id"),
|
|
111
111
|
status: text("status").notNull().default("idle"),
|
|
112
112
|
stop_reason: text("stop_reason"),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QH57EOKP.js";
|
|
4
4
|
import {
|
|
5
5
|
ApiError
|
|
6
6
|
} from "./chunk-EZYKRG4W.js";
|
|
@@ -16,7 +16,7 @@ function authHeaders(tokenOverride) {
|
|
|
16
16
|
}
|
|
17
17
|
return { Authorization: `Bearer ${token}` };
|
|
18
18
|
}
|
|
19
|
-
async function startExec(
|
|
19
|
+
async function startExec(sandboxName, opts) {
|
|
20
20
|
const params = new URLSearchParams();
|
|
21
21
|
for (const c of opts.argv) params.append("cmd", c);
|
|
22
22
|
if (opts.stdin != null) params.set("stdin", "true");
|
|
@@ -31,7 +31,7 @@ async function startExec(spriteName, opts) {
|
|
|
31
31
|
else opts.signal.addEventListener("abort", () => localAbort.abort(opts.signal.reason));
|
|
32
32
|
}
|
|
33
33
|
const res = await fetch(
|
|
34
|
-
`${api()}/v1/sprites/${encodeURIComponent(
|
|
34
|
+
`${api()}/v1/sprites/${encodeURIComponent(sandboxName)}/exec?${params.toString()}`,
|
|
35
35
|
{
|
|
36
36
|
method: "POST",
|
|
37
37
|
headers: authHeaders(opts.secrets?.SPRITE_TOKEN),
|
|
@@ -45,12 +45,12 @@ async function startExec(spriteName, opts) {
|
|
|
45
45
|
throw new ApiError(
|
|
46
46
|
502,
|
|
47
47
|
"server_error",
|
|
48
|
-
`
|
|
48
|
+
`sandbox exec failed (${res.status}): ${text.slice(0, 300)}`
|
|
49
49
|
);
|
|
50
50
|
}
|
|
51
51
|
if (!res.body) {
|
|
52
52
|
clearTimeout(timeoutId);
|
|
53
|
-
throw new ApiError(502, "server_error", "
|
|
53
|
+
throw new ApiError(502, "server_error", "sandbox exec returned no body");
|
|
54
54
|
}
|
|
55
55
|
let exitResolve = () => {
|
|
56
56
|
};
|