@deepagents/context 4.1.0 → 4.2.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 +6 -2
- package/dist/browser.js.map +2 -2
- package/dist/index.js +438 -33
- package/dist/index.js.map +4 -4
- package/dist/lib/agent.d.ts.map +1 -1
- package/dist/lib/engine.d.ts +8 -1
- package/dist/lib/engine.d.ts.map +1 -1
- package/dist/lib/fragments/message/user.d.ts +12 -0
- package/dist/lib/fragments/message/user.d.ts.map +1 -1
- package/dist/lib/sandbox/agent-os-sandbox.d.ts +2 -2
- package/dist/lib/sandbox/agent-os-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/apple-container-sandbox.d.ts +8 -0
- package/dist/lib/sandbox/apple-container-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/bash-meta.d.ts +0 -3
- package/dist/lib/sandbox/bash-meta.d.ts.map +1 -1
- package/dist/lib/sandbox/bash-tool.d.ts +3 -3
- package/dist/lib/sandbox/bash-tool.d.ts.map +1 -1
- package/dist/lib/sandbox/container-engine.d.ts +2 -1
- package/dist/lib/sandbox/container-engine.d.ts.map +1 -1
- package/dist/lib/sandbox/container-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/daytona-sandbox.d.ts +2 -2
- package/dist/lib/sandbox/daytona-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/index.d.ts +1 -0
- package/dist/lib/sandbox/index.d.ts.map +1 -1
- package/dist/lib/sandbox/microsandbox-sandbox.d.ts +93 -0
- package/dist/lib/sandbox/microsandbox-sandbox.d.ts.map +1 -0
- package/dist/lib/sandbox/types.d.ts +19 -0
- package/dist/lib/sandbox/types.d.ts.map +1 -1
- package/dist/lib/sandbox/virtual-sandbox.d.ts +2 -2
- package/dist/lib/sandbox/virtual-sandbox.d.ts.map +1 -1
- package/package.json +13 -8
package/dist/index.js
CHANGED
|
@@ -1595,6 +1595,7 @@ var Agent = class _Agent {
|
|
|
1595
1595
|
),
|
|
1596
1596
|
toolChoice: this.#options.toolChoice,
|
|
1597
1597
|
onStepFinish: (step) => {
|
|
1598
|
+
if (!this.#options.logging) return;
|
|
1598
1599
|
const toolCall2 = step.toolCalls.at(-1);
|
|
1599
1600
|
if (toolCall2) {
|
|
1600
1601
|
console.log(
|
|
@@ -1672,6 +1673,7 @@ var Agent = class _Agent {
|
|
|
1672
1673
|
experimental_context: contextVariables,
|
|
1673
1674
|
toolChoice: this.#options.toolChoice,
|
|
1674
1675
|
onStepFinish: (step) => {
|
|
1676
|
+
if (!this.#options.logging) return;
|
|
1675
1677
|
const toolCall2 = step.toolCalls.at(-1);
|
|
1676
1678
|
if (toolCall2) {
|
|
1677
1679
|
console.log(
|
|
@@ -1932,7 +1934,10 @@ function wrapToolsWithOutputReminders(tools, context) {
|
|
|
1932
1934
|
execute: async (input, options) => {
|
|
1933
1935
|
const result = await execute.call(toolDef, input, options);
|
|
1934
1936
|
if (isAsyncIterable(result)) return result;
|
|
1935
|
-
return context.applyToolOutputReminders(result
|
|
1937
|
+
return context.applyToolOutputReminders(result, {
|
|
1938
|
+
toolName: name,
|
|
1939
|
+
input
|
|
1940
|
+
});
|
|
1936
1941
|
},
|
|
1937
1942
|
toModelOutput: (args) => {
|
|
1938
1943
|
const project = (output) => originalToModelOutput ? originalToModelOutput({
|
|
@@ -3916,6 +3921,10 @@ var ContextEngine = class _ContextEngine {
|
|
|
3916
3921
|
* return the (possibly wrapped) output.
|
|
3917
3922
|
*
|
|
3918
3923
|
* Called by the agent's tool wrapper right after each `execute()` resolves.
|
|
3924
|
+
* The wrapper passes the executing `call`, surfaced as
|
|
3925
|
+
* {@link WhenContext.executingTool}, so a predicate can gate on the live
|
|
3926
|
+
* tool's name/input/result — the only point at which the call being wrapped
|
|
3927
|
+
* is observable.
|
|
3919
3928
|
* The store keeps the wrapped value with a host-only marker; the model-facing
|
|
3920
3929
|
* projection strips that marker while preserving `result` + `systemReminder`.
|
|
3921
3930
|
*
|
|
@@ -3924,17 +3933,22 @@ var ContextEngine = class _ContextEngine {
|
|
|
3924
3933
|
* (e.g. asTool forks that set a pending user without saving), so the output
|
|
3925
3934
|
* passes through untouched.
|
|
3926
3935
|
*/
|
|
3927
|
-
async applyToolOutputReminders(output) {
|
|
3936
|
+
async applyToolOutputReminders(output, call) {
|
|
3928
3937
|
const configs = this.#remindersFor("tool-output");
|
|
3929
3938
|
if (configs.length === 0) return output;
|
|
3930
3939
|
await this.#ensureInitialized();
|
|
3931
3940
|
const chain = await this.#getChainContext();
|
|
3932
3941
|
const currentMessage = chain.lastMessage;
|
|
3933
3942
|
if (!currentMessage) return output;
|
|
3934
|
-
const
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3943
|
+
const whenCtx = this.#buildWhenCtx(chain, currentMessage);
|
|
3944
|
+
if (call) {
|
|
3945
|
+
whenCtx.executingTool = {
|
|
3946
|
+
name: call.toolName,
|
|
3947
|
+
input: call.input,
|
|
3948
|
+
output
|
|
3949
|
+
};
|
|
3950
|
+
}
|
|
3951
|
+
const matched = await evaluateFiredReminders(configs, whenCtx);
|
|
3938
3952
|
if (matched.length === 0) return output;
|
|
3939
3953
|
return applyRemindersToToolOutput(
|
|
3940
3954
|
output,
|
|
@@ -6132,14 +6146,15 @@ function bindAbort(signal, onAbort) {
|
|
|
6132
6146
|
}
|
|
6133
6147
|
async function createAgentOsSandbox(options = {}) {
|
|
6134
6148
|
const { AgentOs } = await importAgentOs();
|
|
6149
|
+
const { readiness, ...kernelOptions } = options;
|
|
6135
6150
|
let os;
|
|
6136
6151
|
try {
|
|
6137
|
-
os = await AgentOs.create(
|
|
6152
|
+
os = await AgentOs.create(kernelOptions);
|
|
6138
6153
|
} catch (error) {
|
|
6139
6154
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
6140
6155
|
throw new AgentOsCreationError(err.message, err);
|
|
6141
6156
|
}
|
|
6142
|
-
|
|
6157
|
+
const sandbox = {
|
|
6143
6158
|
async executeCommand(command, { signal } = {}) {
|
|
6144
6159
|
if (signal?.aborted) {
|
|
6145
6160
|
return { stdout: "", stderr: "", exitCode: SIGKILL_EXIT_CODE };
|
|
@@ -6219,6 +6234,16 @@ async function createAgentOsSandbox(options = {}) {
|
|
|
6219
6234
|
return this.dispose();
|
|
6220
6235
|
}
|
|
6221
6236
|
};
|
|
6237
|
+
if (readiness) {
|
|
6238
|
+
try {
|
|
6239
|
+
await readiness(sandbox);
|
|
6240
|
+
} catch (error) {
|
|
6241
|
+
await sandbox.dispose().catch(() => {
|
|
6242
|
+
});
|
|
6243
|
+
throw error;
|
|
6244
|
+
}
|
|
6245
|
+
}
|
|
6246
|
+
return sandbox;
|
|
6222
6247
|
}
|
|
6223
6248
|
async function useAgentOsSandbox(options, fn) {
|
|
6224
6249
|
const sandbox = await createAgentOsSandbox(options);
|
|
@@ -6672,7 +6697,17 @@ var ContainerSandboxStrategy = class {
|
|
|
6672
6697
|
await this.cleanupCreatedVolumesAfterFailure(error);
|
|
6673
6698
|
throw error;
|
|
6674
6699
|
}
|
|
6675
|
-
|
|
6700
|
+
const sandbox = this.createSandboxMethods();
|
|
6701
|
+
if (this.opts.readiness) {
|
|
6702
|
+
try {
|
|
6703
|
+
await this.opts.readiness(sandbox);
|
|
6704
|
+
} catch (error) {
|
|
6705
|
+
await sandbox.dispose().catch(() => {
|
|
6706
|
+
});
|
|
6707
|
+
throw error;
|
|
6708
|
+
}
|
|
6709
|
+
}
|
|
6710
|
+
return sandbox;
|
|
6676
6711
|
}
|
|
6677
6712
|
namedContainerId() {
|
|
6678
6713
|
return `sandbox-${this.name}`;
|
|
@@ -7045,15 +7080,13 @@ function isAppleContainerfileOptions(opts) {
|
|
|
7045
7080
|
}
|
|
7046
7081
|
function buildMountArg(volume) {
|
|
7047
7082
|
const readOnly = volume.readOnly !== false;
|
|
7048
|
-
|
|
7083
|
+
if (volume.type === "volume") {
|
|
7084
|
+
return `${volume.name}:${volume.containerPath}${readOnly ? ":ro" : ""}`;
|
|
7085
|
+
}
|
|
7086
|
+
const parts = [
|
|
7049
7087
|
"type=bind",
|
|
7050
7088
|
`source=${volume.hostPath}`,
|
|
7051
7089
|
`target=${volume.containerPath}`
|
|
7052
|
-
] : [
|
|
7053
|
-
// Named volumes mount as virtiofs; `container` has no `type=volume`.
|
|
7054
|
-
"type=virtiofs",
|
|
7055
|
-
`source=${volume.name}`,
|
|
7056
|
-
`target=${volume.containerPath}`
|
|
7057
7090
|
];
|
|
7058
7091
|
if (readOnly) {
|
|
7059
7092
|
parts.push("readonly");
|
|
@@ -7073,8 +7106,9 @@ function safeParseArray(stdout) {
|
|
|
7073
7106
|
}
|
|
7074
7107
|
}
|
|
7075
7108
|
function readContainerStatus(entry) {
|
|
7109
|
+
const raw = entry?.status;
|
|
7076
7110
|
const status = String(
|
|
7077
|
-
|
|
7111
|
+
(typeof raw === "object" && raw !== null ? raw.state : raw) ?? ""
|
|
7078
7112
|
).toLowerCase();
|
|
7079
7113
|
if (status === "running" || status === "booted") return "running";
|
|
7080
7114
|
if (status === "stopped") return "stopped";
|
|
@@ -7104,7 +7138,10 @@ var appleEngine = {
|
|
|
7104
7138
|
args.push("--env", `${key}=${value}`);
|
|
7105
7139
|
}
|
|
7106
7140
|
for (const volume of opts.volumes ?? []) {
|
|
7107
|
-
args.push(
|
|
7141
|
+
args.push(
|
|
7142
|
+
volume.type === "volume" ? "--volume" : "--mount",
|
|
7143
|
+
buildMountArg(volume)
|
|
7144
|
+
);
|
|
7108
7145
|
}
|
|
7109
7146
|
args.push(image);
|
|
7110
7147
|
if (opts.command === void 0) {
|
|
@@ -7356,12 +7393,6 @@ function useBashMeta() {
|
|
|
7356
7393
|
return {
|
|
7357
7394
|
setHidden(patch) {
|
|
7358
7395
|
state.hidden = { ...state.hidden, ...patch };
|
|
7359
|
-
},
|
|
7360
|
-
setReminder(text) {
|
|
7361
|
-
state.reminder = text;
|
|
7362
|
-
},
|
|
7363
|
-
clearReminder() {
|
|
7364
|
-
state.reminder = void 0;
|
|
7365
7396
|
}
|
|
7366
7397
|
};
|
|
7367
7398
|
}
|
|
@@ -7571,14 +7602,8 @@ async function createBashTool(options) {
|
|
|
7571
7602
|
const result = await originalExecute({ command }, execOptions);
|
|
7572
7603
|
const state = readBashMeta();
|
|
7573
7604
|
if (!state) return result;
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
if (!hasHidden && !hasReminder) return result;
|
|
7577
|
-
return {
|
|
7578
|
-
...result,
|
|
7579
|
-
...hasHidden ? { meta: state.hidden } : {},
|
|
7580
|
-
...hasReminder ? { reminder: state.reminder } : {}
|
|
7581
|
-
};
|
|
7605
|
+
if (Object.keys(state.hidden).length === 0) return result;
|
|
7606
|
+
return { ...result, meta: state.hidden };
|
|
7582
7607
|
})
|
|
7583
7608
|
);
|
|
7584
7609
|
},
|
|
@@ -7752,10 +7777,20 @@ async function createDaytonaSandbox(client, options = {}) {
|
|
|
7752
7777
|
} catch (error) {
|
|
7753
7778
|
throw normalizeDaytonaError(error, sdk);
|
|
7754
7779
|
}
|
|
7755
|
-
|
|
7780
|
+
const backend = createDaytonaSandboxMethods({
|
|
7756
7781
|
sandbox,
|
|
7757
7782
|
commandTimeout: options.commandTimeout
|
|
7758
7783
|
});
|
|
7784
|
+
if (options.readiness) {
|
|
7785
|
+
try {
|
|
7786
|
+
await options.readiness(backend);
|
|
7787
|
+
} catch (error) {
|
|
7788
|
+
await backend.dispose().catch(() => {
|
|
7789
|
+
});
|
|
7790
|
+
throw error;
|
|
7791
|
+
}
|
|
7792
|
+
}
|
|
7793
|
+
return backend;
|
|
7759
7794
|
}
|
|
7760
7795
|
var UNRECOVERABLE_SANDBOX_STATES = /* @__PURE__ */ new Set([
|
|
7761
7796
|
"error",
|
|
@@ -9233,6 +9268,359 @@ function formatVersion(version) {
|
|
|
9233
9268
|
return /^[<>=!~]/.test(version) ? version : `==${version}`;
|
|
9234
9269
|
}
|
|
9235
9270
|
|
|
9271
|
+
// packages/context/src/lib/sandbox/microsandbox-sandbox.ts
|
|
9272
|
+
import "bash-tool";
|
|
9273
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
9274
|
+
var MICROSANDBOX_DEFAULT_DESTINATION = "/workspace";
|
|
9275
|
+
var MICROSANDBOX_DEFAULT_IMAGE = "alpine";
|
|
9276
|
+
var MICROSANDBOX_MAX_NAME_BYTES = 128;
|
|
9277
|
+
var COMMAND_TIMEOUT_EXIT_CODE = 124;
|
|
9278
|
+
var MicrosandboxSandboxError = class extends Error {
|
|
9279
|
+
constructor(message2, cause) {
|
|
9280
|
+
super(message2);
|
|
9281
|
+
this.name = "MicrosandboxSandboxError";
|
|
9282
|
+
this.cause = cause;
|
|
9283
|
+
}
|
|
9284
|
+
};
|
|
9285
|
+
var MicrosandboxNotAvailableError = class extends MicrosandboxSandboxError {
|
|
9286
|
+
constructor(cause) {
|
|
9287
|
+
super(
|
|
9288
|
+
"microsandbox is not installed or its runtime is unavailable. Install it with: npm install microsandbox (requires Node >= 22 and hardware virtualization: Apple silicon, Linux with KVM, or Windows with WHP)",
|
|
9289
|
+
cause
|
|
9290
|
+
);
|
|
9291
|
+
this.name = "MicrosandboxNotAvailableError";
|
|
9292
|
+
}
|
|
9293
|
+
};
|
|
9294
|
+
var MicrosandboxCreationError = class extends MicrosandboxSandboxError {
|
|
9295
|
+
constructor(message2, cause) {
|
|
9296
|
+
super(`Failed to create microsandbox: ${message2}`, cause);
|
|
9297
|
+
this.name = "MicrosandboxCreationError";
|
|
9298
|
+
}
|
|
9299
|
+
};
|
|
9300
|
+
var MicrosandboxCommandError = class extends MicrosandboxSandboxError {
|
|
9301
|
+
constructor(message2, cause) {
|
|
9302
|
+
super(message2, cause);
|
|
9303
|
+
this.name = "MicrosandboxCommandError";
|
|
9304
|
+
}
|
|
9305
|
+
};
|
|
9306
|
+
async function createMicrosandboxSandbox(options = {}) {
|
|
9307
|
+
validateMicrosandboxOptions(options);
|
|
9308
|
+
const sdk = await importMicrosandbox();
|
|
9309
|
+
const ephemeral = options.name === void 0;
|
|
9310
|
+
const name = options.name ?? `deepagents-msb-${randomUUID3()}`;
|
|
9311
|
+
const workdir = options.workdir ?? MICROSANDBOX_DEFAULT_DESTINATION;
|
|
9312
|
+
let vm;
|
|
9313
|
+
try {
|
|
9314
|
+
vm = await acquireSandbox(sdk, { ...options, name, ephemeral, workdir });
|
|
9315
|
+
await vm.fs().mkdir(workdir);
|
|
9316
|
+
} catch (error) {
|
|
9317
|
+
throw normalizeMicrosandboxError(error, sdk);
|
|
9318
|
+
}
|
|
9319
|
+
const backend = createMicrosandboxMethods({
|
|
9320
|
+
sdk,
|
|
9321
|
+
vm,
|
|
9322
|
+
name,
|
|
9323
|
+
ephemeral,
|
|
9324
|
+
commandTimeout: options.commandTimeout
|
|
9325
|
+
});
|
|
9326
|
+
if (options.readiness) {
|
|
9327
|
+
try {
|
|
9328
|
+
await options.readiness(backend);
|
|
9329
|
+
} catch (error) {
|
|
9330
|
+
await backend.dispose().catch(() => {
|
|
9331
|
+
});
|
|
9332
|
+
throw error;
|
|
9333
|
+
}
|
|
9334
|
+
}
|
|
9335
|
+
return backend;
|
|
9336
|
+
}
|
|
9337
|
+
async function importMicrosandbox() {
|
|
9338
|
+
try {
|
|
9339
|
+
return await import("microsandbox");
|
|
9340
|
+
} catch (error) {
|
|
9341
|
+
throw new MicrosandboxNotAvailableError(toError2(error));
|
|
9342
|
+
}
|
|
9343
|
+
}
|
|
9344
|
+
async function acquireSandbox(sdk, options) {
|
|
9345
|
+
if (options.ephemeral || options.replace) {
|
|
9346
|
+
return buildSandbox(sdk, options);
|
|
9347
|
+
}
|
|
9348
|
+
let handle;
|
|
9349
|
+
try {
|
|
9350
|
+
handle = await sdk.Sandbox.get(options.name);
|
|
9351
|
+
} catch (error) {
|
|
9352
|
+
if (error instanceof sdk.SandboxNotFoundError) {
|
|
9353
|
+
return createFreshSandbox(sdk, options);
|
|
9354
|
+
}
|
|
9355
|
+
throw error;
|
|
9356
|
+
}
|
|
9357
|
+
if (handle.status === "running") {
|
|
9358
|
+
return handle.connect();
|
|
9359
|
+
}
|
|
9360
|
+
if (handle.status === "draining") {
|
|
9361
|
+
await handle.waitUntilStopped();
|
|
9362
|
+
}
|
|
9363
|
+
try {
|
|
9364
|
+
return await handle.start();
|
|
9365
|
+
} catch {
|
|
9366
|
+
await sdk.Sandbox.remove(options.name).catch(() => {
|
|
9367
|
+
});
|
|
9368
|
+
return buildSandbox(sdk, options);
|
|
9369
|
+
}
|
|
9370
|
+
}
|
|
9371
|
+
async function createFreshSandbox(sdk, options) {
|
|
9372
|
+
try {
|
|
9373
|
+
return await buildSandbox(sdk, options);
|
|
9374
|
+
} catch (error) {
|
|
9375
|
+
if (error instanceof sdk.SandboxAlreadyExistsError) {
|
|
9376
|
+
const handle = await sdk.Sandbox.get(options.name);
|
|
9377
|
+
return handle.status === "running" ? handle.connect() : handle.start();
|
|
9378
|
+
}
|
|
9379
|
+
throw error;
|
|
9380
|
+
}
|
|
9381
|
+
}
|
|
9382
|
+
function buildSandbox(sdk, options) {
|
|
9383
|
+
let builder = sdk.Sandbox.builder(options.name).image(options.image ?? MICROSANDBOX_DEFAULT_IMAGE).patch((patch) => patch.mkdir(options.workdir)).workdir(options.workdir);
|
|
9384
|
+
if (options.ephemeral) builder = builder.ephemeral(true);
|
|
9385
|
+
if (options.replace) builder = builder.replace();
|
|
9386
|
+
if (options.cpus !== void 0) builder = builder.cpus(options.cpus);
|
|
9387
|
+
if (options.memory !== void 0) builder = builder.memory(options.memory);
|
|
9388
|
+
if (options.env) builder = builder.envs(options.env);
|
|
9389
|
+
if (options.configure) builder = options.configure(builder);
|
|
9390
|
+
return builder.create();
|
|
9391
|
+
}
|
|
9392
|
+
function normalizeMicrosandboxError(error, sdk) {
|
|
9393
|
+
const err = toError2(error);
|
|
9394
|
+
if (err instanceof sdk.LibkrunfwNotFoundError) {
|
|
9395
|
+
return new MicrosandboxNotAvailableError(err);
|
|
9396
|
+
}
|
|
9397
|
+
if (err instanceof sdk.MicrosandboxError) {
|
|
9398
|
+
return err;
|
|
9399
|
+
}
|
|
9400
|
+
return new MicrosandboxCreationError(err.message, err);
|
|
9401
|
+
}
|
|
9402
|
+
function validateMicrosandboxOptions(options) {
|
|
9403
|
+
if (options.name !== void 0 && Buffer.byteLength(options.name, "utf-8") > MICROSANDBOX_MAX_NAME_BYTES) {
|
|
9404
|
+
throw new MicrosandboxSandboxError(
|
|
9405
|
+
`Microsandbox names are limited to ${MICROSANDBOX_MAX_NAME_BYTES} UTF-8 bytes.`
|
|
9406
|
+
);
|
|
9407
|
+
}
|
|
9408
|
+
if (options.replace && options.name === void 0) {
|
|
9409
|
+
throw new MicrosandboxSandboxError(
|
|
9410
|
+
'Microsandbox options can only include "replace" together with "name" \u2014 an unnamed sandbox is always created fresh.'
|
|
9411
|
+
);
|
|
9412
|
+
}
|
|
9413
|
+
}
|
|
9414
|
+
function createMicrosandboxMethods(args) {
|
|
9415
|
+
const { sdk, vm, name, ephemeral, commandTimeout } = args;
|
|
9416
|
+
const spawn7 = (command, options = {}) => {
|
|
9417
|
+
return spawnMicrosandboxProcess(sdk, vm, command, {
|
|
9418
|
+
...options,
|
|
9419
|
+
commandTimeout
|
|
9420
|
+
});
|
|
9421
|
+
};
|
|
9422
|
+
return {
|
|
9423
|
+
// `executeCommand` lowers onto the same streaming pump as `spawn` so a
|
|
9424
|
+
// single code path supports real cancellation. Cooperative abort (abandon
|
|
9425
|
+
// the promise, Daytona-style) is not an option here: the SDK is an
|
|
9426
|
+
// in-process native binding, so an abandoned exec keeps the guest process
|
|
9427
|
+
// and its libuv handle alive.
|
|
9428
|
+
async executeCommand(command, options) {
|
|
9429
|
+
const proc = spawn7(command, { signal: options?.signal });
|
|
9430
|
+
const [stdout, stderr, info] = await Promise.all([
|
|
9431
|
+
readAllText(proc.stdout),
|
|
9432
|
+
readAllText(proc.stderr),
|
|
9433
|
+
proc.exit
|
|
9434
|
+
]);
|
|
9435
|
+
if (info.signal === "SIGKILL") {
|
|
9436
|
+
return abortedCommandResult2();
|
|
9437
|
+
}
|
|
9438
|
+
return { stdout, stderr, exitCode: info.code ?? 1 };
|
|
9439
|
+
},
|
|
9440
|
+
spawn: spawn7,
|
|
9441
|
+
async readFile(path5) {
|
|
9442
|
+
try {
|
|
9443
|
+
return await vm.fs().readToString(path5);
|
|
9444
|
+
} catch (error) {
|
|
9445
|
+
throw new MicrosandboxCommandError(
|
|
9446
|
+
`Failed to read file "${path5}": ${toError2(error).message}`,
|
|
9447
|
+
toError2(error)
|
|
9448
|
+
);
|
|
9449
|
+
}
|
|
9450
|
+
},
|
|
9451
|
+
async writeFiles(files) {
|
|
9452
|
+
try {
|
|
9453
|
+
const fs2 = vm.fs();
|
|
9454
|
+
for (const dir of uniqueParentDirectories2(files.map((f) => f.path))) {
|
|
9455
|
+
await fs2.mkdir(dir);
|
|
9456
|
+
}
|
|
9457
|
+
for (const file of files) {
|
|
9458
|
+
await fs2.write(file.path, file.content);
|
|
9459
|
+
}
|
|
9460
|
+
} catch (error) {
|
|
9461
|
+
const err = toError2(error);
|
|
9462
|
+
throw new MicrosandboxCommandError(
|
|
9463
|
+
`Failed to write files: ${err.message}`,
|
|
9464
|
+
err
|
|
9465
|
+
);
|
|
9466
|
+
}
|
|
9467
|
+
},
|
|
9468
|
+
async dispose() {
|
|
9469
|
+
try {
|
|
9470
|
+
await vm.stop();
|
|
9471
|
+
} catch {
|
|
9472
|
+
}
|
|
9473
|
+
if (ephemeral) {
|
|
9474
|
+
await sdk.Sandbox.remove(name).catch(() => {
|
|
9475
|
+
});
|
|
9476
|
+
}
|
|
9477
|
+
},
|
|
9478
|
+
[Symbol.asyncDispose]() {
|
|
9479
|
+
return this.dispose();
|
|
9480
|
+
}
|
|
9481
|
+
};
|
|
9482
|
+
}
|
|
9483
|
+
function spawnMicrosandboxProcess(sdk, vm, command, options) {
|
|
9484
|
+
const stdout = createByteReadable();
|
|
9485
|
+
const stderr = createByteReadable();
|
|
9486
|
+
const exit = pumpExecStream({ sdk, vm, command, options, stdout, stderr });
|
|
9487
|
+
return { stdout: stdout.stream, stderr: stderr.stream, exit };
|
|
9488
|
+
}
|
|
9489
|
+
async function pumpExecStream(args) {
|
|
9490
|
+
const { sdk, vm, command, options, stdout, stderr } = args;
|
|
9491
|
+
const { signal } = options;
|
|
9492
|
+
let handle;
|
|
9493
|
+
let aborted = signal?.aborted ?? false;
|
|
9494
|
+
let timedOut = false;
|
|
9495
|
+
let timeoutTimer;
|
|
9496
|
+
const abort = () => {
|
|
9497
|
+
aborted = true;
|
|
9498
|
+
handle?.kill().catch(() => {
|
|
9499
|
+
});
|
|
9500
|
+
};
|
|
9501
|
+
if (aborted) {
|
|
9502
|
+
stdout.close();
|
|
9503
|
+
stderr.close();
|
|
9504
|
+
return abortedExitInfo2();
|
|
9505
|
+
}
|
|
9506
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
9507
|
+
try {
|
|
9508
|
+
handle = await vm.execStreamWith("sh", (builder) => {
|
|
9509
|
+
builder.args(["-lc", command]).stdinNull();
|
|
9510
|
+
if (options.cwd) builder.cwd(options.cwd);
|
|
9511
|
+
if (options.env) builder.envs(options.env);
|
|
9512
|
+
return builder;
|
|
9513
|
+
});
|
|
9514
|
+
if (aborted) {
|
|
9515
|
+
return abortedExitInfo2();
|
|
9516
|
+
}
|
|
9517
|
+
if (options.commandTimeout) {
|
|
9518
|
+
const startedHandle = handle;
|
|
9519
|
+
timeoutTimer = setTimeout(() => {
|
|
9520
|
+
timedOut = true;
|
|
9521
|
+
startedHandle.kill().catch(() => {
|
|
9522
|
+
});
|
|
9523
|
+
}, options.commandTimeout);
|
|
9524
|
+
timeoutTimer.unref();
|
|
9525
|
+
}
|
|
9526
|
+
let code = null;
|
|
9527
|
+
for await (const event of handle) {
|
|
9528
|
+
if (event.kind === "stdout") stdout.enqueue(event.data);
|
|
9529
|
+
else if (event.kind === "stderr") stderr.enqueue(event.data);
|
|
9530
|
+
else if (event.kind === "exited") code = event.code;
|
|
9531
|
+
}
|
|
9532
|
+
if (aborted) {
|
|
9533
|
+
return abortedExitInfo2();
|
|
9534
|
+
}
|
|
9535
|
+
if (timedOut) {
|
|
9536
|
+
stderr.enqueue(new TextEncoder().encode("Command timed out"));
|
|
9537
|
+
return { code: COMMAND_TIMEOUT_EXIT_CODE, signal: null, success: false };
|
|
9538
|
+
}
|
|
9539
|
+
return { code, signal: null, success: code === 0 };
|
|
9540
|
+
} catch (error) {
|
|
9541
|
+
if (aborted) {
|
|
9542
|
+
return abortedExitInfo2();
|
|
9543
|
+
}
|
|
9544
|
+
if (timedOut || error instanceof sdk.ExecTimeoutError) {
|
|
9545
|
+
stderr.enqueue(new TextEncoder().encode("Command timed out"));
|
|
9546
|
+
return { code: COMMAND_TIMEOUT_EXIT_CODE, signal: null, success: false };
|
|
9547
|
+
}
|
|
9548
|
+
const err = toError2(error);
|
|
9549
|
+
stdout.error(err);
|
|
9550
|
+
stderr.error(err);
|
|
9551
|
+
throw err;
|
|
9552
|
+
} finally {
|
|
9553
|
+
clearTimeout(timeoutTimer);
|
|
9554
|
+
signal?.removeEventListener("abort", abort);
|
|
9555
|
+
stdout.close();
|
|
9556
|
+
stderr.close();
|
|
9557
|
+
await handle?.[Symbol.asyncDispose]();
|
|
9558
|
+
}
|
|
9559
|
+
}
|
|
9560
|
+
function createByteReadable() {
|
|
9561
|
+
let controller;
|
|
9562
|
+
let closed = false;
|
|
9563
|
+
return {
|
|
9564
|
+
stream: new ReadableStream({
|
|
9565
|
+
start(streamController) {
|
|
9566
|
+
controller = streamController;
|
|
9567
|
+
},
|
|
9568
|
+
cancel() {
|
|
9569
|
+
closed = true;
|
|
9570
|
+
}
|
|
9571
|
+
}),
|
|
9572
|
+
enqueue(chunk) {
|
|
9573
|
+
if (closed || chunk.length === 0) return;
|
|
9574
|
+
controller?.enqueue(chunk);
|
|
9575
|
+
},
|
|
9576
|
+
close() {
|
|
9577
|
+
if (closed) return;
|
|
9578
|
+
closed = true;
|
|
9579
|
+
controller?.close();
|
|
9580
|
+
},
|
|
9581
|
+
error(error) {
|
|
9582
|
+
if (closed) return;
|
|
9583
|
+
closed = true;
|
|
9584
|
+
controller?.error(error);
|
|
9585
|
+
}
|
|
9586
|
+
};
|
|
9587
|
+
}
|
|
9588
|
+
async function readAllText(stream) {
|
|
9589
|
+
const decoder2 = new TextDecoder();
|
|
9590
|
+
let text = "";
|
|
9591
|
+
for await (const chunk of stream) {
|
|
9592
|
+
text += decoder2.decode(chunk, { stream: true });
|
|
9593
|
+
}
|
|
9594
|
+
return text + decoder2.decode();
|
|
9595
|
+
}
|
|
9596
|
+
function abortedCommandResult2() {
|
|
9597
|
+
return {
|
|
9598
|
+
stdout: "",
|
|
9599
|
+
stderr: "Command aborted",
|
|
9600
|
+
exitCode: 1
|
|
9601
|
+
};
|
|
9602
|
+
}
|
|
9603
|
+
function abortedExitInfo2() {
|
|
9604
|
+
return {
|
|
9605
|
+
code: null,
|
|
9606
|
+
signal: "SIGKILL",
|
|
9607
|
+
success: false
|
|
9608
|
+
};
|
|
9609
|
+
}
|
|
9610
|
+
function uniqueParentDirectories2(paths) {
|
|
9611
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
9612
|
+
for (const path5 of paths) {
|
|
9613
|
+
const index = path5.lastIndexOf("/");
|
|
9614
|
+
if (index > 0) {
|
|
9615
|
+
dirs.add(path5.slice(0, index));
|
|
9616
|
+
}
|
|
9617
|
+
}
|
|
9618
|
+
return [...dirs];
|
|
9619
|
+
}
|
|
9620
|
+
function toError2(error) {
|
|
9621
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
9622
|
+
}
|
|
9623
|
+
|
|
9236
9624
|
// packages/context/src/lib/sandbox/subcommand.ts
|
|
9237
9625
|
import {
|
|
9238
9626
|
defineCommand as defineCommand2,
|
|
@@ -9314,7 +9702,7 @@ async function createVirtualSandbox(options) {
|
|
|
9314
9702
|
env: options.env,
|
|
9315
9703
|
customCommands: options.customCommands
|
|
9316
9704
|
});
|
|
9317
|
-
|
|
9705
|
+
const sandbox = {
|
|
9318
9706
|
async executeCommand(command, options2) {
|
|
9319
9707
|
const result = await bash.exec(
|
|
9320
9708
|
command,
|
|
@@ -9343,6 +9731,16 @@ async function createVirtualSandbox(options) {
|
|
|
9343
9731
|
return this.dispose();
|
|
9344
9732
|
}
|
|
9345
9733
|
};
|
|
9734
|
+
if (options.readiness) {
|
|
9735
|
+
try {
|
|
9736
|
+
await options.readiness(sandbox);
|
|
9737
|
+
} catch (error) {
|
|
9738
|
+
await sandbox.dispose().catch(() => {
|
|
9739
|
+
});
|
|
9740
|
+
throw error;
|
|
9741
|
+
}
|
|
9742
|
+
}
|
|
9743
|
+
return sandbox;
|
|
9346
9744
|
}
|
|
9347
9745
|
|
|
9348
9746
|
// packages/context/src/lib/skills/fragments.ts
|
|
@@ -12581,7 +12979,12 @@ export {
|
|
|
12581
12979
|
Installer,
|
|
12582
12980
|
IterableResolver,
|
|
12583
12981
|
LOCALE_METADATA_KEY,
|
|
12982
|
+
MICROSANDBOX_DEFAULT_DESTINATION,
|
|
12584
12983
|
MarkdownRenderer,
|
|
12984
|
+
MicrosandboxCommandError,
|
|
12985
|
+
MicrosandboxCreationError,
|
|
12986
|
+
MicrosandboxNotAvailableError,
|
|
12987
|
+
MicrosandboxSandboxError,
|
|
12585
12988
|
MissingRuntimeError,
|
|
12586
12989
|
ModelsRegistry,
|
|
12587
12990
|
NpmInstaller,
|
|
@@ -12618,6 +13021,7 @@ export {
|
|
|
12618
13021
|
analogy,
|
|
12619
13022
|
and,
|
|
12620
13023
|
anyToolCalled,
|
|
13024
|
+
appleEngine,
|
|
12621
13025
|
applyInlineReminder,
|
|
12622
13026
|
applyPartReminder,
|
|
12623
13027
|
applyReminderToMessage,
|
|
@@ -12647,6 +13051,7 @@ export {
|
|
|
12647
13051
|
createDaytonaSandbox,
|
|
12648
13052
|
createDockerSandbox,
|
|
12649
13053
|
createInstallerContext,
|
|
13054
|
+
createMicrosandboxSandbox,
|
|
12650
13055
|
createRepairToolCall,
|
|
12651
13056
|
createVirtualSandbox,
|
|
12652
13057
|
dateReminder,
|