@deepagents/context 6.0.0 → 6.1.2
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 +5 -2
- package/dist/index.js +263 -32
- package/dist/index.js.map +3 -3
- package/dist/lib/chat.d.ts +2 -2
- package/dist/lib/chat.d.ts.map +1 -1
- package/dist/lib/engine.d.ts.map +1 -1
- package/dist/lib/sandbox/agent-os-sandbox.d.ts +1 -1
- package/dist/lib/sandbox/agent-os-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/apple-container-sandbox.d.ts +3 -3
- package/dist/lib/sandbox/apple-container-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/bash-tool.d.ts.map +1 -1
- package/dist/lib/sandbox/container-sandbox.d.ts +1 -0
- package/dist/lib/sandbox/container-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/daytona-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/docker-sandbox.d.ts +3 -3
- package/dist/lib/sandbox/docker-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/microsandbox-sandbox.d.ts +3 -3
- package/dist/lib/sandbox/microsandbox-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/shell-quote.d.ts +1 -1
- package/dist/lib/sandbox/strace/index.d.ts +3 -3
- package/dist/lib/sandbox/strace/index.d.ts.map +1 -1
- package/dist/lib/sandbox/strace/index.js +2 -2
- package/dist/lib/sandbox/strace/index.js.map +2 -2
- package/dist/lib/sandbox/types.d.ts +5 -0
- package/dist/lib/sandbox/types.d.ts.map +1 -1
- package/dist/lib/sandbox/virtual-sandbox.d.ts +2 -1
- package/dist/lib/sandbox/virtual-sandbox.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -32,6 +32,8 @@ with `createVirtualSandbox()`, `createDockerSandbox()`,
|
|
|
32
32
|
`createDaytonaSandbox(client, options)`, or `createAgentOsSandbox()` depending
|
|
33
33
|
on whether commands should run in memory, Docker, Apple Container lightweight
|
|
34
34
|
VMs, Microsandbox microVMs, managed Daytona sandboxes, or Agent OS.
|
|
35
|
+
Virtual sandboxes can opt into in-process JavaScript execution with
|
|
36
|
+
`createVirtualSandbox({ javascript: true, ... })`.
|
|
35
37
|
|
|
36
38
|
See the docs for the full API surface:
|
|
37
39
|
|
|
@@ -315,8 +317,9 @@ points.
|
|
|
315
317
|
For `target: 'tool-output'`, use `toolOutput(...)` or inspect
|
|
316
318
|
`ctx.toolOutcome`. The outcome is available after a tool reaches
|
|
317
319
|
`output-available`, `output-error`, or `output-denied`, but before the next model
|
|
318
|
-
generation. Assistant-history predicates such as `toolCalled(...)`
|
|
319
|
-
|
|
320
|
+
generation. Assistant-history predicates such as `toolCalled(...)` describe
|
|
321
|
+
tool parts visible in the current assistant segment; use `toolOutput(...)` when
|
|
322
|
+
you need the raw outcome currently being evaluated.
|
|
320
323
|
|
|
321
324
|
```ts
|
|
322
325
|
import {
|
package/dist/index.js
CHANGED
|
@@ -840,6 +840,7 @@ import { getErrorMessage } from "@ai-sdk/provider";
|
|
|
840
840
|
import {
|
|
841
841
|
convertToModelMessages as convertToModelMessages2,
|
|
842
842
|
generateId as generateId5,
|
|
843
|
+
isStaticToolUIPart as isStaticToolUIPart2,
|
|
843
844
|
validateUIMessages
|
|
844
845
|
} from "ai";
|
|
845
846
|
|
|
@@ -3959,6 +3960,58 @@ function toolOutcomesFromStep(content) {
|
|
|
3959
3960
|
}
|
|
3960
3961
|
return outcomes;
|
|
3961
3962
|
}
|
|
3963
|
+
function terminalToolPartsFromStep(content) {
|
|
3964
|
+
return content.flatMap((part) => {
|
|
3965
|
+
if (part.type === "tool-result" && part.dynamic !== true) {
|
|
3966
|
+
return [
|
|
3967
|
+
{
|
|
3968
|
+
type: `tool-${part.toolName}`,
|
|
3969
|
+
toolCallId: part.toolCallId,
|
|
3970
|
+
state: "output-available",
|
|
3971
|
+
input: part.input,
|
|
3972
|
+
output: part.output === void 0 ? null : part.output
|
|
3973
|
+
}
|
|
3974
|
+
];
|
|
3975
|
+
}
|
|
3976
|
+
if (part.type === "tool-error" && part.dynamic !== true) {
|
|
3977
|
+
return [
|
|
3978
|
+
{
|
|
3979
|
+
type: `tool-${part.toolName}`,
|
|
3980
|
+
toolCallId: part.toolCallId,
|
|
3981
|
+
state: "output-error",
|
|
3982
|
+
input: part.input,
|
|
3983
|
+
errorText: getErrorMessage(part.error)
|
|
3984
|
+
}
|
|
3985
|
+
];
|
|
3986
|
+
}
|
|
3987
|
+
if (part.type === "tool-approval-response" && part.approved === false && part.toolCall.dynamic !== true) {
|
|
3988
|
+
return [
|
|
3989
|
+
{
|
|
3990
|
+
type: `tool-${part.toolCall.toolName}`,
|
|
3991
|
+
toolCallId: part.toolCall.toolCallId,
|
|
3992
|
+
state: "output-denied",
|
|
3993
|
+
input: part.toolCall.input,
|
|
3994
|
+
approval: {
|
|
3995
|
+
id: part.approvalId,
|
|
3996
|
+
approved: false,
|
|
3997
|
+
...part.reason === void 0 ? {} : { reason: part.reason }
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
4000
|
+
];
|
|
4001
|
+
}
|
|
4002
|
+
return [];
|
|
4003
|
+
});
|
|
4004
|
+
}
|
|
4005
|
+
function mergeTerminalToolParts(message2, liveParts) {
|
|
4006
|
+
const remaining = new Map(liveParts);
|
|
4007
|
+
const parts = message2.parts.map((part) => {
|
|
4008
|
+
if (!isStaticToolUIPart2(part)) return part;
|
|
4009
|
+
remaining.delete(part.toolCallId);
|
|
4010
|
+
return part;
|
|
4011
|
+
});
|
|
4012
|
+
parts.push(...remaining.values());
|
|
4013
|
+
return { ...message2, parts };
|
|
4014
|
+
}
|
|
3962
4015
|
var ContextEngine = class _ContextEngine {
|
|
3963
4016
|
/** Non-message fragments (role, hints, etc.) - not persisted in graph */
|
|
3964
4017
|
#fragments = [];
|
|
@@ -4371,12 +4424,24 @@ var ContextEngine = class _ContextEngine {
|
|
|
4371
4424
|
const enableSteer = options.steer ?? true;
|
|
4372
4425
|
const session = {
|
|
4373
4426
|
firedOnceIds: /* @__PURE__ */ new Set(),
|
|
4374
|
-
|
|
4427
|
+
terminalToolParts: /* @__PURE__ */ new Map(),
|
|
4428
|
+
segments: [],
|
|
4429
|
+
initialStepStarts: null,
|
|
4430
|
+
stepOffset: 0,
|
|
4431
|
+
lastStepNumber: null
|
|
4375
4432
|
};
|
|
4376
4433
|
this.#currentReminderSession = session;
|
|
4377
4434
|
return async ({ steps, stepNumber, messages }) => {
|
|
4435
|
+
if (stepNumber === 0 && session.lastStepNumber !== null) {
|
|
4436
|
+
session.stepOffset += session.lastStepNumber + 1;
|
|
4437
|
+
}
|
|
4438
|
+
session.lastStepNumber = stepNumber;
|
|
4439
|
+
const completedSteps = session.stepOffset + stepNumber;
|
|
4378
4440
|
const priorStep = stepNumber >= 1 ? steps[stepNumber - 1] : void 0;
|
|
4379
4441
|
const hasSafeBoundary = (priorStep?.content?.length ?? 0) > 0;
|
|
4442
|
+
for (const part of terminalToolPartsFromStep(priorStep?.content ?? [])) {
|
|
4443
|
+
session.terminalToolParts.set(part.toolCallId, part);
|
|
4444
|
+
}
|
|
4380
4445
|
const canFire = enableSteer && hasSafeBoundary;
|
|
4381
4446
|
const steerConfigs = canFire ? this.#remindersFor("steer") : [];
|
|
4382
4447
|
const outcomes = toolOutcomesFromStep(steps.at(-1)?.content ?? []);
|
|
@@ -4435,18 +4500,24 @@ var ContextEngine = class _ContextEngine {
|
|
|
4435
4500
|
"createPrepareStep: expected an assistant message at chain head."
|
|
4436
4501
|
);
|
|
4437
4502
|
}
|
|
4438
|
-
const currentSegmentId =
|
|
4503
|
+
const currentSegmentId = head.id;
|
|
4439
4504
|
const currentSegment = await this.#store.getMessage(currentSegmentId);
|
|
4440
4505
|
if (!currentSegment || currentSegment.name !== "assistant") {
|
|
4441
4506
|
throw new Error(
|
|
4442
4507
|
"createPrepareStep: expected the open assistant segment to be persisted."
|
|
4443
4508
|
);
|
|
4444
4509
|
}
|
|
4445
|
-
|
|
4510
|
+
requireUIMessage(
|
|
4446
4511
|
currentSegment.data,
|
|
4447
4512
|
`Stored assistant message "${currentSegment.id}"`
|
|
4448
4513
|
);
|
|
4449
4514
|
const nextSegmentId = generateId5();
|
|
4515
|
+
if (session.segments.length === 0) {
|
|
4516
|
+
session.segments.push({
|
|
4517
|
+
id: currentSegmentId,
|
|
4518
|
+
startStep: 0
|
|
4519
|
+
});
|
|
4520
|
+
}
|
|
4450
4521
|
for (const input of inputs) this.set(user(input));
|
|
4451
4522
|
this.set(
|
|
4452
4523
|
assistant({
|
|
@@ -4456,8 +4527,11 @@ var ContextEngine = class _ContextEngine {
|
|
|
4456
4527
|
})
|
|
4457
4528
|
);
|
|
4458
4529
|
await this.save({ branch: false });
|
|
4459
|
-
session.
|
|
4460
|
-
|
|
4530
|
+
session.segments.push({
|
|
4531
|
+
id: nextSegmentId,
|
|
4532
|
+
startStep: completedSteps
|
|
4533
|
+
});
|
|
4534
|
+
session.terminalToolParts.clear();
|
|
4461
4535
|
return {
|
|
4462
4536
|
messages: [...messages, ...inputModel]
|
|
4463
4537
|
};
|
|
@@ -4482,14 +4556,81 @@ var ContextEngine = class _ContextEngine {
|
|
|
4482
4556
|
);
|
|
4483
4557
|
}
|
|
4484
4558
|
const session = this.#currentReminderSession;
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4559
|
+
let id = head.id;
|
|
4560
|
+
let parts = message2.parts;
|
|
4561
|
+
if (session) {
|
|
4562
|
+
if (session.initialStepStarts === null) {
|
|
4563
|
+
const initialId = session.segments[0]?.id ?? head.id;
|
|
4564
|
+
const initial = await this.#store.getMessage(initialId);
|
|
4565
|
+
if (!initial || initial.name !== "assistant") {
|
|
4566
|
+
throw new Error(
|
|
4567
|
+
`writeAssistantSegment: initial segment "${initialId}" was not found`
|
|
4568
|
+
);
|
|
4569
|
+
}
|
|
4570
|
+
session.initialStepStarts = requireUIMessage(
|
|
4571
|
+
initial.data,
|
|
4572
|
+
`Stored assistant message "${initial.id}"`
|
|
4573
|
+
).parts.filter((part) => part.type === "step-start").length;
|
|
4574
|
+
}
|
|
4575
|
+
const streamStepStarts = message2.parts.flatMap(
|
|
4576
|
+
(part, index) => part.type === "step-start" ? [index] : []
|
|
4577
|
+
);
|
|
4578
|
+
const completedSteps = streamStepStarts.length - session.initialStepStarts;
|
|
4579
|
+
if (completedSteps < 0) {
|
|
4580
|
+
throw new Error(
|
|
4581
|
+
"writeAssistantSegment: response lost an existing step boundary"
|
|
4582
|
+
);
|
|
4583
|
+
}
|
|
4584
|
+
const segmentIndex = session.segments.findLastIndex(
|
|
4585
|
+
(candidate) => candidate.startStep < completedSteps
|
|
4586
|
+
);
|
|
4587
|
+
if (segmentIndex >= 0) {
|
|
4588
|
+
const segment = session.segments[segmentIndex];
|
|
4589
|
+
id = segment.id;
|
|
4590
|
+
if (segmentIndex > 0) {
|
|
4591
|
+
const start = streamStepStarts[session.initialStepStarts + segment.startStep];
|
|
4592
|
+
if (start === void 0) {
|
|
4593
|
+
throw new Error(
|
|
4594
|
+
`writeAssistantSegment: response is missing step ${segment.startStep + 1}`
|
|
4595
|
+
);
|
|
4596
|
+
}
|
|
4597
|
+
parts = message2.parts.slice(start);
|
|
4598
|
+
}
|
|
4599
|
+
} else {
|
|
4600
|
+
const lastSegment = session.segments.at(-1);
|
|
4601
|
+
if (lastSegment) {
|
|
4602
|
+
id = lastSegment.id;
|
|
4603
|
+
parts = [];
|
|
4604
|
+
}
|
|
4605
|
+
}
|
|
4606
|
+
}
|
|
4607
|
+
const fragment2 = assistant({
|
|
4608
|
+
...message2,
|
|
4609
|
+
id,
|
|
4610
|
+
parts
|
|
4611
|
+
});
|
|
4612
|
+
if (!session) {
|
|
4613
|
+
this.set(fragment2);
|
|
4614
|
+
await this.save({ branch: false });
|
|
4615
|
+
return;
|
|
4616
|
+
}
|
|
4617
|
+
const stored = await this.#store.getMessage(id);
|
|
4618
|
+
if (!stored) {
|
|
4619
|
+
throw new Error(
|
|
4620
|
+
`writeAssistantSegment: reserved segment "${id}" was not found`
|
|
4621
|
+
);
|
|
4622
|
+
}
|
|
4623
|
+
if (!fragment2.codec) {
|
|
4624
|
+
throw new Error("writeAssistantSegment: assistant codec is missing");
|
|
4625
|
+
}
|
|
4626
|
+
await this.#store.addMessages([
|
|
4627
|
+
{
|
|
4628
|
+
...stored,
|
|
4629
|
+
name: fragment2.name,
|
|
4630
|
+
type: fragment2.type,
|
|
4631
|
+
data: fragment2.codec.encode()
|
|
4632
|
+
}
|
|
4633
|
+
]);
|
|
4493
4634
|
}
|
|
4494
4635
|
#remindersFor(target) {
|
|
4495
4636
|
return this.#fragments.filter(isConditionalReminder).map((fragment2) => fragment2.metadata.reminder).filter((config) => config.target === target);
|
|
@@ -4590,8 +4731,16 @@ var ContextEngine = class _ContextEngine {
|
|
|
4590
4731
|
"steer reminders require a user message earlier in the turn"
|
|
4591
4732
|
);
|
|
4592
4733
|
}
|
|
4734
|
+
const lastAssistantMessage = chain.lastAssistantMessage;
|
|
4735
|
+
if (!lastAssistantMessage) {
|
|
4736
|
+
throw new Error("steer reminders require a completed assistant step");
|
|
4737
|
+
}
|
|
4593
4738
|
return {
|
|
4594
4739
|
...this.#buildWhenCtx(chain, currentMessage),
|
|
4740
|
+
lastAssistantMessage: mergeTerminalToolParts(
|
|
4741
|
+
lastAssistantMessage,
|
|
4742
|
+
session.terminalToolParts
|
|
4743
|
+
),
|
|
4595
4744
|
sandbox,
|
|
4596
4745
|
firedOnceIds: /* @__PURE__ */ new Set([...chain.firedOnceIds, ...session.firedOnceIds])
|
|
4597
4746
|
};
|
|
@@ -6557,7 +6706,7 @@ function startKernelProcess(os, command, options) {
|
|
|
6557
6706
|
const stderr = new PassThrough();
|
|
6558
6707
|
const onStdout = (chunk) => stdout.write(chunk);
|
|
6559
6708
|
const onStderr = (chunk) => stderr.write(chunk);
|
|
6560
|
-
const { pid } = os.spawn("
|
|
6709
|
+
const { pid } = os.spawn("bash", ["-lc", command], {
|
|
6561
6710
|
...options,
|
|
6562
6711
|
onStdout,
|
|
6563
6712
|
onStderr
|
|
@@ -6610,6 +6759,25 @@ async function createAgentOsSandbox(options = {}) {
|
|
|
6610
6759
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
6611
6760
|
throw new AgentOsCreationError(err.message, err);
|
|
6612
6761
|
}
|
|
6762
|
+
try {
|
|
6763
|
+
const probe = startKernelProcess(os, ":", {});
|
|
6764
|
+
const [, stderr, exitCode] = await Promise.all([
|
|
6765
|
+
readAll(probe.stdout),
|
|
6766
|
+
readAll(probe.stderr),
|
|
6767
|
+
probe.exit
|
|
6768
|
+
]);
|
|
6769
|
+
if (exitCode !== 0) {
|
|
6770
|
+
throw new Error(stderr.trim() || `exit code ${exitCode}`);
|
|
6771
|
+
}
|
|
6772
|
+
} catch (error) {
|
|
6773
|
+
await os.dispose().catch(() => {
|
|
6774
|
+
});
|
|
6775
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
6776
|
+
throw new AgentOsCreationError(
|
|
6777
|
+
`Bash is required to execute sandbox commands but could not be started: ${err.message}`,
|
|
6778
|
+
err
|
|
6779
|
+
);
|
|
6780
|
+
}
|
|
6613
6781
|
const sandbox = {
|
|
6614
6782
|
async executeCommand(command, { signal } = {}) {
|
|
6615
6783
|
if (signal?.aborted) {
|
|
@@ -7143,6 +7311,7 @@ var ContainerSandboxStrategy = class {
|
|
|
7143
7311
|
await this.engine.ensureWorkdir(this.context.containerId, this.workdir);
|
|
7144
7312
|
await this.configure();
|
|
7145
7313
|
}
|
|
7314
|
+
await this.assertBashAvailable();
|
|
7146
7315
|
} catch (error) {
|
|
7147
7316
|
if (acquired && !acquired.attached) {
|
|
7148
7317
|
await this.stopContainer(acquired.containerId);
|
|
@@ -7441,6 +7610,15 @@ var ContainerSandboxStrategy = class {
|
|
|
7441
7610
|
};
|
|
7442
7611
|
}
|
|
7443
7612
|
}
|
|
7613
|
+
async assertBashAvailable() {
|
|
7614
|
+
const result = await this.exec(":");
|
|
7615
|
+
if (result.exitCode === 0) return;
|
|
7616
|
+
const detail = result.stderr.trim() || result.stdout.trim();
|
|
7617
|
+
throw this.engine.errors.generic(
|
|
7618
|
+
`Bash is required to execute sandbox commands but could not be started${detail ? `: ${detail}` : "."}`,
|
|
7619
|
+
this.context.containerId
|
|
7620
|
+
);
|
|
7621
|
+
}
|
|
7444
7622
|
spawnProcess(command, options) {
|
|
7445
7623
|
const child = childSpawn(
|
|
7446
7624
|
this.engine.cli,
|
|
@@ -7632,7 +7810,7 @@ var appleEngine = {
|
|
|
7632
7810
|
flags.push("--env", `${key}=${value}`);
|
|
7633
7811
|
}
|
|
7634
7812
|
}
|
|
7635
|
-
return ["exec", ...flags, containerId, "
|
|
7813
|
+
return ["exec", ...flags, containerId, "bash", "-lc", command];
|
|
7636
7814
|
},
|
|
7637
7815
|
inspectArgs(containerId) {
|
|
7638
7816
|
return ["inspect", containerId];
|
|
@@ -7661,9 +7839,15 @@ var appleEngine = {
|
|
|
7661
7839
|
return /already exists/i.test(message2);
|
|
7662
7840
|
},
|
|
7663
7841
|
async ensureWorkdir(containerId, workdir) {
|
|
7664
|
-
await spawn3(CLI, [
|
|
7842
|
+
await spawn3(CLI, [
|
|
7843
|
+
"exec",
|
|
7844
|
+
containerId,
|
|
7845
|
+
"bash",
|
|
7846
|
+
"-lc",
|
|
7847
|
+
`mkdir -p ${shellQuote(workdir)}`
|
|
7848
|
+
]);
|
|
7665
7849
|
},
|
|
7666
|
-
defaultImage: "docker.io/library/
|
|
7850
|
+
defaultImage: "docker.io/library/bash:5.3-alpine3.24",
|
|
7667
7851
|
createInstallerContext: createAppleInstallerContext,
|
|
7668
7852
|
async imageExists(tag) {
|
|
7669
7853
|
try {
|
|
@@ -7878,6 +8062,7 @@ var KNOWN_TOOLS = /* @__PURE__ */ new Set([
|
|
|
7878
8062
|
"head",
|
|
7879
8063
|
"html-to-markdown",
|
|
7880
8064
|
"iconv",
|
|
8065
|
+
"js-exec",
|
|
7881
8066
|
"join",
|
|
7882
8067
|
"jq",
|
|
7883
8068
|
"node",
|
|
@@ -8022,6 +8207,7 @@ async function createToolPrompt(sandbox, filenames, customPrompt) {
|
|
|
8022
8207
|
const available = new Set(
|
|
8023
8208
|
result.stdout.split("\n").filter((entry) => KNOWN_TOOLS.has(entry))
|
|
8024
8209
|
);
|
|
8210
|
+
if (available.has("js-exec")) available.delete("node");
|
|
8025
8211
|
if (available.size === 0) return "";
|
|
8026
8212
|
const lines = [
|
|
8027
8213
|
`Available tools: ${[...available].sort().join(", ")}, and more`
|
|
@@ -8311,6 +8497,7 @@ async function createDaytonaSandbox(client, options = {}) {
|
|
|
8311
8497
|
} catch (error) {
|
|
8312
8498
|
throw normalizeDaytonaError(error, sdk);
|
|
8313
8499
|
}
|
|
8500
|
+
await assertDaytonaBash(sandbox, options.commandTimeout);
|
|
8314
8501
|
const backend = createDaytonaSandboxMethods({
|
|
8315
8502
|
sandbox,
|
|
8316
8503
|
commandTimeout: options.commandTimeout
|
|
@@ -8326,6 +8513,24 @@ async function createDaytonaSandbox(client, options = {}) {
|
|
|
8326
8513
|
}
|
|
8327
8514
|
return backend;
|
|
8328
8515
|
}
|
|
8516
|
+
async function assertDaytonaBash(sandbox, commandTimeout) {
|
|
8517
|
+
try {
|
|
8518
|
+
const result = await sandbox.process.executeCommand(
|
|
8519
|
+
"bash -lc ':'",
|
|
8520
|
+
void 0,
|
|
8521
|
+
void 0,
|
|
8522
|
+
commandTimeout
|
|
8523
|
+
);
|
|
8524
|
+
if (result.exitCode === void 0 || result.exitCode === 0) return;
|
|
8525
|
+
throw new Error(result.result || `exit code ${result.exitCode}`);
|
|
8526
|
+
} catch (error) {
|
|
8527
|
+
const err = toError(error);
|
|
8528
|
+
throw new DaytonaCreationError(
|
|
8529
|
+
`Bash is required to execute sandbox commands but could not be started: ${err.message}`,
|
|
8530
|
+
err
|
|
8531
|
+
);
|
|
8532
|
+
}
|
|
8533
|
+
}
|
|
8329
8534
|
var UNRECOVERABLE_SANDBOX_STATES = /* @__PURE__ */ new Set([
|
|
8330
8535
|
"error",
|
|
8331
8536
|
"build_failed",
|
|
@@ -8462,7 +8667,7 @@ function createDaytonaSandboxMethods(args) {
|
|
|
8462
8667
|
return abortedCommandResult();
|
|
8463
8668
|
}
|
|
8464
8669
|
const response = await sandbox.process.executeCommand(
|
|
8465
|
-
command
|
|
8670
|
+
`bash -lc ${shellQuote(command)}`,
|
|
8466
8671
|
void 0,
|
|
8467
8672
|
void 0,
|
|
8468
8673
|
commandTimeout
|
|
@@ -8704,13 +8909,13 @@ function buildSessionCommand(command, options) {
|
|
|
8704
8909
|
const env = options.env ?? {};
|
|
8705
8910
|
const entries = Object.entries(env);
|
|
8706
8911
|
if (entries.length === 0) {
|
|
8707
|
-
return `
|
|
8912
|
+
return `bash -lc ${shellQuote(`${cwdPrefix}${command}`)}`;
|
|
8708
8913
|
}
|
|
8709
8914
|
for (const [key] of entries) {
|
|
8710
8915
|
validateEnvKey(key);
|
|
8711
8916
|
}
|
|
8712
8917
|
const exports = entries.map(([key, value]) => `export ${key}=${shellQuote(value)}`).join("; ");
|
|
8713
|
-
return `
|
|
8918
|
+
return `bash -lc ${shellQuote(`${exports}; ${cwdPrefix}${command}`)}`;
|
|
8714
8919
|
}
|
|
8715
8920
|
function validateEnvKey(key) {
|
|
8716
8921
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
@@ -8950,7 +9155,7 @@ var dockerEngine = {
|
|
|
8950
9155
|
flags.push("-e", `${key}=${value}`);
|
|
8951
9156
|
}
|
|
8952
9157
|
}
|
|
8953
|
-
return ["exec", ...flags, containerId, "
|
|
9158
|
+
return ["exec", ...flags, containerId, "bash", "-lc", command];
|
|
8954
9159
|
},
|
|
8955
9160
|
inspectArgs(containerId) {
|
|
8956
9161
|
return [
|
|
@@ -8993,7 +9198,7 @@ var dockerEngine = {
|
|
|
8993
9198
|
},
|
|
8994
9199
|
async ensureWorkdir() {
|
|
8995
9200
|
},
|
|
8996
|
-
defaultImage: "
|
|
9201
|
+
defaultImage: "bash:5.3-alpine3.24",
|
|
8997
9202
|
createInstallerContext,
|
|
8998
9203
|
async imageExists(tag) {
|
|
8999
9204
|
try {
|
|
@@ -9103,8 +9308,8 @@ var ComposeStrategy = class extends ContainerSandboxStrategy {
|
|
|
9103
9308
|
"exec",
|
|
9104
9309
|
"-T",
|
|
9105
9310
|
this.service,
|
|
9106
|
-
"
|
|
9107
|
-
"-
|
|
9311
|
+
"bash",
|
|
9312
|
+
"-lc",
|
|
9108
9313
|
command
|
|
9109
9314
|
],
|
|
9110
9315
|
{ signal: options?.signal }
|
|
@@ -9130,8 +9335,8 @@ var ComposeStrategy = class extends ContainerSandboxStrategy {
|
|
|
9130
9335
|
"-T",
|
|
9131
9336
|
...buildDockerExecFlags(options),
|
|
9132
9337
|
this.service,
|
|
9133
|
-
"
|
|
9134
|
-
"-
|
|
9338
|
+
"bash",
|
|
9339
|
+
"-lc",
|
|
9135
9340
|
command
|
|
9136
9341
|
]);
|
|
9137
9342
|
return toSandboxProcess(child, options?.signal);
|
|
@@ -9189,10 +9394,10 @@ import spawn6 from "nano-spawn";
|
|
|
9189
9394
|
import { posix as posix2 } from "node:path";
|
|
9190
9395
|
var STRACE_FLAGS = "-f -y -qq -e trace=%file,write,pwrite64,writev";
|
|
9191
9396
|
function buildStraceCommand(command, traceFile, traceDir) {
|
|
9192
|
-
return `mkdir -p ${shellQuote(traceDir)} 2>/dev/null; strace ${STRACE_FLAGS} -o ${shellQuote(traceFile)} --
|
|
9397
|
+
return `mkdir -p ${shellQuote(traceDir)} 2>/dev/null; strace ${STRACE_FLAGS} -o ${shellQuote(traceFile)} -- bash -lc ${shellQuote(command)}`;
|
|
9193
9398
|
}
|
|
9194
9399
|
function buildTracedCommand(command, traceFile, traceDir, sentinel) {
|
|
9195
|
-
return `mkdir -p ${shellQuote(traceDir)} 2>/dev/null; strace ${STRACE_FLAGS} -o ${shellQuote(traceFile)} --
|
|
9400
|
+
return `mkdir -p ${shellQuote(traceDir)} 2>/dev/null; strace ${STRACE_FLAGS} -o ${shellQuote(traceFile)} -- bash -lc ${shellQuote(command)}; __dat_rc=$?; printf '\\n%s\\n' ${shellQuote(sentinel)}; base64 ${shellQuote(traceFile)} 2>/dev/null; rm -f ${shellQuote(traceFile)} 2>/dev/null; exit $__dat_rc`;
|
|
9196
9401
|
}
|
|
9197
9402
|
function splitTracedOutput(stdout, sentinel) {
|
|
9198
9403
|
const marker = `
|
|
@@ -9815,7 +10020,7 @@ function formatVersion(version) {
|
|
|
9815
10020
|
// packages/context/src/lib/sandbox/microsandbox-sandbox.ts
|
|
9816
10021
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
9817
10022
|
var MICROSANDBOX_DEFAULT_DESTINATION = "/workspace";
|
|
9818
|
-
var MICROSANDBOX_DEFAULT_IMAGE = "
|
|
10023
|
+
var MICROSANDBOX_DEFAULT_IMAGE = "bash:5.3-alpine3.24";
|
|
9819
10024
|
var MICROSANDBOX_MAX_NAME_BYTES = 128;
|
|
9820
10025
|
var COMMAND_TIMEOUT_EXIT_CODE = 124;
|
|
9821
10026
|
var MicrosandboxSandboxError = class extends Error {
|
|
@@ -9855,8 +10060,17 @@ async function createMicrosandboxSandbox(options = {}) {
|
|
|
9855
10060
|
let vm;
|
|
9856
10061
|
try {
|
|
9857
10062
|
vm = await acquireSandbox(sdk, { ...options, name, ephemeral, workdir });
|
|
10063
|
+
} catch (error) {
|
|
10064
|
+
throw normalizeMicrosandboxError(error, sdk);
|
|
10065
|
+
}
|
|
10066
|
+
try {
|
|
9858
10067
|
await vm.fs().mkdir(workdir);
|
|
10068
|
+
await assertMicrosandboxBash(vm);
|
|
9859
10069
|
} catch (error) {
|
|
10070
|
+
await vm.stop().catch(() => {
|
|
10071
|
+
});
|
|
10072
|
+
if (ephemeral) await sdk.Sandbox.remove(name).catch(() => {
|
|
10073
|
+
});
|
|
9860
10074
|
throw normalizeMicrosandboxError(error, sdk);
|
|
9861
10075
|
}
|
|
9862
10076
|
const backend = createMicrosandboxMethods({
|
|
@@ -9930,10 +10144,24 @@ function buildSandbox(sdk, options) {
|
|
|
9930
10144
|
if (options.memory !== void 0) builder = builder.memory(options.memory);
|
|
9931
10145
|
if (options.env) builder = builder.envs(options.env);
|
|
9932
10146
|
if (options.configure) builder = options.configure(builder);
|
|
9933
|
-
return builder.create();
|
|
10147
|
+
return builder.shell("bash").create();
|
|
10148
|
+
}
|
|
10149
|
+
async function assertMicrosandboxBash(vm) {
|
|
10150
|
+
try {
|
|
10151
|
+
const result = await vm.exec("bash", ["-lc", ":"]);
|
|
10152
|
+
if (result.code === 0) return;
|
|
10153
|
+
throw new Error(result.stderr() || `exit code ${result.code}`);
|
|
10154
|
+
} catch (error) {
|
|
10155
|
+
const err = toError2(error);
|
|
10156
|
+
throw new MicrosandboxCreationError(
|
|
10157
|
+
`Bash is required to execute sandbox commands but could not be started: ${err.message}`,
|
|
10158
|
+
err
|
|
10159
|
+
);
|
|
10160
|
+
}
|
|
9934
10161
|
}
|
|
9935
10162
|
function normalizeMicrosandboxError(error, sdk) {
|
|
9936
10163
|
const err = toError2(error);
|
|
10164
|
+
if (err instanceof MicrosandboxSandboxError) return err;
|
|
9937
10165
|
if (err instanceof sdk.LibkrunfwNotFoundError) {
|
|
9938
10166
|
return new MicrosandboxNotAvailableError(err);
|
|
9939
10167
|
}
|
|
@@ -10048,7 +10276,7 @@ async function pumpExecStream(args) {
|
|
|
10048
10276
|
}
|
|
10049
10277
|
signal?.addEventListener("abort", abort, { once: true });
|
|
10050
10278
|
try {
|
|
10051
|
-
handle = await vm.execStreamWith("
|
|
10279
|
+
handle = await vm.execStreamWith("bash", (builder) => {
|
|
10052
10280
|
builder.args(["-lc", command]).stdinNull();
|
|
10053
10281
|
if (options.cwd) builder.cwd(options.cwd);
|
|
10054
10282
|
if (options.env) builder.envs(options.env);
|
|
@@ -10237,12 +10465,15 @@ function buildSubcommandRepair(name, subcommands) {
|
|
|
10237
10465
|
}
|
|
10238
10466
|
|
|
10239
10467
|
// packages/context/src/lib/sandbox/virtual-sandbox.ts
|
|
10240
|
-
import {
|
|
10468
|
+
import {
|
|
10469
|
+
Bash
|
|
10470
|
+
} from "just-bash";
|
|
10241
10471
|
async function createVirtualSandbox(options) {
|
|
10242
10472
|
const bash = new Bash({
|
|
10243
10473
|
fs: options.fs,
|
|
10244
10474
|
cwd: options.cwd,
|
|
10245
10475
|
env: options.env,
|
|
10476
|
+
javascript: options.javascript,
|
|
10246
10477
|
customCommands: options.customCommands
|
|
10247
10478
|
});
|
|
10248
10479
|
const sandbox = {
|