@deepagents/context 2.1.0 → 2.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 +18 -14
- package/dist/browser.js +37 -2
- package/dist/browser.js.map +3 -3
- package/dist/index.js +828 -106
- package/dist/index.js.map +4 -4
- package/dist/lib/guardrail.d.ts +2 -6
- package/dist/lib/guardrail.d.ts.map +1 -1
- package/dist/lib/sandbox/abort.d.ts.map +1 -1
- package/dist/lib/sandbox/agent-os-sandbox.d.ts +5 -1
- package/dist/lib/sandbox/agent-os-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/daytona-sandbox.d.ts +63 -0
- package/dist/lib/sandbox/daytona-sandbox.d.ts.map +1 -0
- package/dist/lib/sandbox/docker-sandbox-errors.d.ts +9 -4
- package/dist/lib/sandbox/docker-sandbox-errors.d.ts.map +1 -1
- package/dist/lib/sandbox/docker-sandbox.d.ts +1 -1
- package/dist/lib/sandbox/docker-sandbox.d.ts.map +1 -1
- package/dist/lib/sandbox/file-events.d.ts +10 -1
- package/dist/lib/sandbox/file-events.d.ts.map +1 -1
- package/dist/lib/sandbox/index.d.ts +1 -1
- package/dist/lib/sandbox/index.d.ts.map +1 -1
- package/dist/lib/sandbox/installers/bin.d.ts +40 -0
- package/dist/lib/sandbox/installers/bin.d.ts.map +1 -0
- package/dist/lib/sandbox/installers/index.d.ts +1 -0
- package/dist/lib/sandbox/installers/index.d.ts.map +1 -1
- package/dist/lib/save/save-pipeline.d.ts.map +1 -1
- package/dist/lib/skills/fragments.d.ts +2 -2
- package/dist/lib/store/sqlite.store.d.ts +1 -0
- package/dist/lib/store/sqlite.store.d.ts.map +1 -1
- package/dist/lib/store/store.d.ts +8 -0
- package/dist/lib/store/store.d.ts.map +1 -1
- package/dist/lib/stream/postgres.stream-store.d.ts.map +1 -1
- package/dist/lib/stream/sqlite.stream-store.d.ts.map +1 -1
- package/dist/lib/stream/stream-manager.d.ts +1 -1
- package/dist/lib/stream/stream-manager.d.ts.map +1 -1
- package/dist/lib/stream/stream-store.d.ts +8 -1
- package/dist/lib/stream/stream-store.d.ts.map +1 -1
- package/dist/lib/stream/types.d.ts +7 -0
- package/dist/lib/stream/types.d.ts.map +1 -0
- package/dist/lib/stream-buffer.d.ts.map +1 -1
- package/package.json +6 -2
- package/dist/lib/sandbox/container-tool.d.ts +0 -190
- package/dist/lib/sandbox/container-tool.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -2623,6 +2623,8 @@ var SavePipeline = class {
|
|
|
2623
2623
|
async persist() {
|
|
2624
2624
|
let parentId = this.#engine.getActiveBranch().headMessageId;
|
|
2625
2625
|
const now = Date.now();
|
|
2626
|
+
const messages = [];
|
|
2627
|
+
const pendingMessagesById = /* @__PURE__ */ new Map();
|
|
2626
2628
|
for (const fragment2 of this.#pending) {
|
|
2627
2629
|
if (!fragment2.codec) {
|
|
2628
2630
|
throw new Error(`Fragment "${fragment2.name}" is missing codec.`);
|
|
@@ -2630,7 +2632,7 @@ var SavePipeline = class {
|
|
|
2630
2632
|
const msgId = fragment2.id ?? crypto.randomUUID();
|
|
2631
2633
|
let msgParentId = parentId;
|
|
2632
2634
|
if (!this.#shouldBranch && msgId === parentId) {
|
|
2633
|
-
const existing = await this.#engine.store.getMessage(msgId);
|
|
2635
|
+
const existing = pendingMessagesById.get(msgId) ?? await this.#engine.store.getMessage(msgId);
|
|
2634
2636
|
if (existing) msgParentId = existing.parentId;
|
|
2635
2637
|
}
|
|
2636
2638
|
const messageData = {
|
|
@@ -2642,7 +2644,8 @@ var SavePipeline = class {
|
|
|
2642
2644
|
data: fragment2.codec.encode(),
|
|
2643
2645
|
createdAt: now
|
|
2644
2646
|
};
|
|
2645
|
-
|
|
2647
|
+
messages.push(messageData);
|
|
2648
|
+
pendingMessagesById.set(messageData.id, messageData);
|
|
2646
2649
|
parentId = messageData.id;
|
|
2647
2650
|
}
|
|
2648
2651
|
if (parentId === null) {
|
|
@@ -2650,6 +2653,7 @@ var SavePipeline = class {
|
|
|
2650
2653
|
"Pipeline persisted no messages but pending was not empty"
|
|
2651
2654
|
);
|
|
2652
2655
|
}
|
|
2656
|
+
await this.#engine.store.addMessages(messages);
|
|
2653
2657
|
await this.#engine.commitHead(parentId);
|
|
2654
2658
|
return { headMessageId: parentId };
|
|
2655
2659
|
}
|
|
@@ -2765,6 +2769,18 @@ var ddl_sqlite_default = "-- Context Store DDL for SQLite\n-- This schema implem
|
|
|
2765
2769
|
|
|
2766
2770
|
// packages/context/src/lib/store/store.ts
|
|
2767
2771
|
var ContextStore = class {
|
|
2772
|
+
/**
|
|
2773
|
+
* Add multiple messages to the graph.
|
|
2774
|
+
*
|
|
2775
|
+
* Stores can override this for atomic/batched persistence. The default keeps
|
|
2776
|
+
* the single-message contract for implementations that do not need a custom
|
|
2777
|
+
* batch path.
|
|
2778
|
+
*/
|
|
2779
|
+
async addMessages(messages) {
|
|
2780
|
+
for (const message2 of messages) {
|
|
2781
|
+
await this.addMessage(message2);
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2768
2784
|
};
|
|
2769
2785
|
|
|
2770
2786
|
// packages/context/src/lib/store/sqlite.store.ts
|
|
@@ -2972,7 +2988,7 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2972
2988
|
// ==========================================================================
|
|
2973
2989
|
// Message Operations (Graph Nodes)
|
|
2974
2990
|
// ==========================================================================
|
|
2975
|
-
|
|
2991
|
+
#insertMessage(message2) {
|
|
2976
2992
|
if (message2.parentId === message2.id) {
|
|
2977
2993
|
throw new Error(`Message ${message2.id} cannot be its own parent`);
|
|
2978
2994
|
}
|
|
@@ -2999,6 +3015,17 @@ var SqliteContextStore = class extends ContextStore {
|
|
|
2999
3015
|
VALUES (?, ?, ?, ?)`
|
|
3000
3016
|
).run(message2.id, message2.chatId, message2.name, content);
|
|
3001
3017
|
}
|
|
3018
|
+
async addMessage(message2) {
|
|
3019
|
+
this.#insertMessage(message2);
|
|
3020
|
+
}
|
|
3021
|
+
async addMessages(messages) {
|
|
3022
|
+
if (messages.length === 0) return;
|
|
3023
|
+
this.#useTransaction(() => {
|
|
3024
|
+
for (const message2 of messages) {
|
|
3025
|
+
this.#insertMessage(message2);
|
|
3026
|
+
}
|
|
3027
|
+
});
|
|
3028
|
+
}
|
|
3002
3029
|
async getMessage(messageId) {
|
|
3003
3030
|
const row = this.#stmt("SELECT * FROM messages WHERE id = ?").get(
|
|
3004
3031
|
messageId
|
|
@@ -5836,7 +5863,7 @@ function runWithAbortSignal(signal, fn) {
|
|
|
5836
5863
|
return ambientAbortSignal.run(signal, fn);
|
|
5837
5864
|
}
|
|
5838
5865
|
function withAbortSignal(sandbox) {
|
|
5839
|
-
|
|
5866
|
+
const decorated = {
|
|
5840
5867
|
...sandbox,
|
|
5841
5868
|
async executeCommand(command, options) {
|
|
5842
5869
|
const signal = options?.signal ?? ambientAbortSignal.getStore();
|
|
@@ -5846,11 +5873,20 @@ function withAbortSignal(sandbox) {
|
|
|
5846
5873
|
);
|
|
5847
5874
|
}
|
|
5848
5875
|
};
|
|
5876
|
+
if (sandbox.spawn) {
|
|
5877
|
+
const innerSpawn = sandbox.spawn.bind(sandbox);
|
|
5878
|
+
decorated.spawn = (command, options) => {
|
|
5879
|
+
const signal = options?.signal ?? ambientAbortSignal.getStore();
|
|
5880
|
+
return innerSpawn(command, signal ? { ...options, signal } : options);
|
|
5881
|
+
};
|
|
5882
|
+
}
|
|
5883
|
+
return decorated;
|
|
5849
5884
|
}
|
|
5850
5885
|
|
|
5851
5886
|
// packages/context/src/lib/sandbox/agent-os-sandbox.ts
|
|
5852
5887
|
import "bash-tool";
|
|
5853
|
-
|
|
5888
|
+
import { PassThrough, Readable } from "node:stream";
|
|
5889
|
+
var decoder = new TextDecoder();
|
|
5854
5890
|
var AgentOsSandboxError = class extends Error {
|
|
5855
5891
|
constructor(message2) {
|
|
5856
5892
|
super(message2);
|
|
@@ -5882,6 +5918,49 @@ async function importAgentOs() {
|
|
|
5882
5918
|
);
|
|
5883
5919
|
}
|
|
5884
5920
|
}
|
|
5921
|
+
var SIGKILL_EXIT_CODE = 9;
|
|
5922
|
+
function startKernelProcess(os, command, options) {
|
|
5923
|
+
const { pid } = os.spawn("sh", ["-c", command], options);
|
|
5924
|
+
const stdout = new PassThrough();
|
|
5925
|
+
const stderr = new PassThrough();
|
|
5926
|
+
const unsubOut = os.onProcessStdout(pid, (chunk) => stdout.write(chunk));
|
|
5927
|
+
const unsubErr = os.onProcessStderr(pid, (chunk) => stderr.write(chunk));
|
|
5928
|
+
let killSignalled = false;
|
|
5929
|
+
const exit = os.waitProcess(pid).finally(() => {
|
|
5930
|
+
unsubOut();
|
|
5931
|
+
unsubErr();
|
|
5932
|
+
stdout.end();
|
|
5933
|
+
stderr.end();
|
|
5934
|
+
});
|
|
5935
|
+
return {
|
|
5936
|
+
pid,
|
|
5937
|
+
stdout,
|
|
5938
|
+
stderr,
|
|
5939
|
+
exit,
|
|
5940
|
+
kill: () => {
|
|
5941
|
+
if (killSignalled) return;
|
|
5942
|
+
killSignalled = true;
|
|
5943
|
+
os.killProcess(pid);
|
|
5944
|
+
},
|
|
5945
|
+
wasKilled: (exitCode) => killSignalled && exitCode === SIGKILL_EXIT_CODE
|
|
5946
|
+
};
|
|
5947
|
+
}
|
|
5948
|
+
async function readAll(stream) {
|
|
5949
|
+
const chunks = [];
|
|
5950
|
+
for await (const chunk of stream) chunks.push(chunk);
|
|
5951
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
5952
|
+
}
|
|
5953
|
+
function bindAbort(signal, onAbort) {
|
|
5954
|
+
if (!signal) return () => {
|
|
5955
|
+
};
|
|
5956
|
+
if (signal.aborted) {
|
|
5957
|
+
onAbort();
|
|
5958
|
+
return () => {
|
|
5959
|
+
};
|
|
5960
|
+
}
|
|
5961
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
5962
|
+
return () => signal.removeEventListener("abort", onAbort);
|
|
5963
|
+
}
|
|
5885
5964
|
async function createAgentOsSandbox(options = {}) {
|
|
5886
5965
|
const { AgentOs } = await importAgentOs();
|
|
5887
5966
|
let os;
|
|
@@ -5892,27 +5971,56 @@ async function createAgentOsSandbox(options = {}) {
|
|
|
5892
5971
|
throw new AgentOsCreationError(err.message, err);
|
|
5893
5972
|
}
|
|
5894
5973
|
return {
|
|
5895
|
-
async executeCommand(command) {
|
|
5974
|
+
async executeCommand(command, { signal } = {}) {
|
|
5975
|
+
if (signal?.aborted) {
|
|
5976
|
+
return { stdout: "", stderr: "", exitCode: SIGKILL_EXIT_CODE };
|
|
5977
|
+
}
|
|
5978
|
+
const proc = startKernelProcess(os, command, {});
|
|
5979
|
+
const unbind = bindAbort(signal, proc.kill);
|
|
5896
5980
|
try {
|
|
5897
|
-
const
|
|
5981
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
5982
|
+
readAll(proc.stdout),
|
|
5983
|
+
readAll(proc.stderr),
|
|
5984
|
+
proc.exit
|
|
5985
|
+
]);
|
|
5986
|
+
return { stdout, stderr, exitCode };
|
|
5987
|
+
} finally {
|
|
5988
|
+
unbind();
|
|
5989
|
+
}
|
|
5990
|
+
},
|
|
5991
|
+
spawn(command, { signal, env, cwd } = {}) {
|
|
5992
|
+
if (signal?.aborted) {
|
|
5993
|
+
const empty = () => new ReadableStream({ start: (c) => c.close() });
|
|
5898
5994
|
return {
|
|
5899
|
-
stdout:
|
|
5900
|
-
stderr:
|
|
5901
|
-
|
|
5995
|
+
stdout: empty(),
|
|
5996
|
+
stderr: empty(),
|
|
5997
|
+
exit: Promise.resolve({
|
|
5998
|
+
code: null,
|
|
5999
|
+
signal: "SIGKILL",
|
|
6000
|
+
success: false
|
|
6001
|
+
})
|
|
5902
6002
|
};
|
|
5903
|
-
}
|
|
5904
|
-
|
|
6003
|
+
}
|
|
6004
|
+
const proc = startKernelProcess(os, command, { env, cwd });
|
|
6005
|
+
const unbind = bindAbort(signal, proc.kill);
|
|
6006
|
+
const exit = proc.exit.then((code) => {
|
|
6007
|
+
const killed = proc.wasKilled(code);
|
|
5905
6008
|
return {
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
6009
|
+
code: killed ? null : code,
|
|
6010
|
+
signal: killed ? "SIGKILL" : null,
|
|
6011
|
+
success: !killed && code === 0
|
|
5909
6012
|
};
|
|
5910
|
-
}
|
|
6013
|
+
}).finally(unbind);
|
|
6014
|
+
return {
|
|
6015
|
+
stdout: Readable.toWeb(proc.stdout),
|
|
6016
|
+
stderr: Readable.toWeb(proc.stderr),
|
|
6017
|
+
exit
|
|
6018
|
+
};
|
|
5911
6019
|
},
|
|
5912
6020
|
async readFile(path5) {
|
|
5913
6021
|
try {
|
|
5914
6022
|
const bytes = await os.readFile(path5);
|
|
5915
|
-
return
|
|
6023
|
+
return decoder.decode(bytes);
|
|
5916
6024
|
} catch (error) {
|
|
5917
6025
|
throw new Error(
|
|
5918
6026
|
`Failed to read file "${path5}": ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -6017,6 +6125,28 @@ async function snapshot(execute, destination) {
|
|
|
6017
6125
|
}
|
|
6018
6126
|
return snap;
|
|
6019
6127
|
}
|
|
6128
|
+
function lazyReadable(innerPromise) {
|
|
6129
|
+
let reader = null;
|
|
6130
|
+
return new ReadableStream({
|
|
6131
|
+
async pull(controller) {
|
|
6132
|
+
if (!reader) {
|
|
6133
|
+
const inner = await innerPromise;
|
|
6134
|
+
reader = inner.getReader();
|
|
6135
|
+
}
|
|
6136
|
+
const { done, value } = await reader.read();
|
|
6137
|
+
if (done) controller.close();
|
|
6138
|
+
else controller.enqueue(value);
|
|
6139
|
+
},
|
|
6140
|
+
async cancel(reason) {
|
|
6141
|
+
if (reader) {
|
|
6142
|
+
await reader.cancel(reason);
|
|
6143
|
+
} else {
|
|
6144
|
+
const inner = await innerPromise;
|
|
6145
|
+
await inner.cancel(reason);
|
|
6146
|
+
}
|
|
6147
|
+
}
|
|
6148
|
+
});
|
|
6149
|
+
}
|
|
6020
6150
|
function diff(before, after) {
|
|
6021
6151
|
const events = [];
|
|
6022
6152
|
const ts = Date.now();
|
|
@@ -6074,6 +6204,41 @@ function observeSandboxFileEvents(sandbox, options) {
|
|
|
6074
6204
|
},
|
|
6075
6205
|
dispose: sandbox.dispose.bind(sandbox)
|
|
6076
6206
|
};
|
|
6207
|
+
if (sandbox.spawn) {
|
|
6208
|
+
const innerSpawn = sandbox.spawn.bind(sandbox);
|
|
6209
|
+
decorated.spawn = (command, options2) => {
|
|
6210
|
+
const started = (async () => {
|
|
6211
|
+
const before = await snapshot(innerExecute, destination).catch(
|
|
6212
|
+
() => /* @__PURE__ */ new Map()
|
|
6213
|
+
);
|
|
6214
|
+
const child = innerSpawn(command, options2);
|
|
6215
|
+
return { before, child };
|
|
6216
|
+
})();
|
|
6217
|
+
const exit = (async () => {
|
|
6218
|
+
const { before, child } = await started;
|
|
6219
|
+
try {
|
|
6220
|
+
return await child.exit;
|
|
6221
|
+
} finally {
|
|
6222
|
+
try {
|
|
6223
|
+
const after = await snapshot(innerExecute, destination);
|
|
6224
|
+
buffer.push(...diff(before, after));
|
|
6225
|
+
} catch {
|
|
6226
|
+
}
|
|
6227
|
+
}
|
|
6228
|
+
})();
|
|
6229
|
+
const stdoutPromise = started.then((s) => s.child.stdout);
|
|
6230
|
+
const stderrPromise = started.then((s) => s.child.stderr);
|
|
6231
|
+
stdoutPromise.catch(() => {
|
|
6232
|
+
});
|
|
6233
|
+
stderrPromise.catch(() => {
|
|
6234
|
+
});
|
|
6235
|
+
return {
|
|
6236
|
+
stdout: lazyReadable(stdoutPromise),
|
|
6237
|
+
stderr: lazyReadable(stderrPromise),
|
|
6238
|
+
exit
|
|
6239
|
+
};
|
|
6240
|
+
};
|
|
6241
|
+
}
|
|
6077
6242
|
return {
|
|
6078
6243
|
sandbox: decorated,
|
|
6079
6244
|
drain() {
|
|
@@ -6406,13 +6571,513 @@ function resolveRealCwd(ctx) {
|
|
|
6406
6571
|
return realCwd;
|
|
6407
6572
|
}
|
|
6408
6573
|
|
|
6574
|
+
// packages/context/src/lib/sandbox/daytona-sandbox.ts
|
|
6575
|
+
import "bash-tool";
|
|
6576
|
+
import { randomUUID } from "node:crypto";
|
|
6577
|
+
import { createRequire } from "node:module";
|
|
6578
|
+
var DAYTONA_DEFAULT_DESTINATION = "/home/daytona";
|
|
6579
|
+
var DAYTONA_EXIT_POLL_INTERVAL_MS = 250;
|
|
6580
|
+
var DAYTONA_EXIT_POLL_TIMEOUT_MS = 3e4;
|
|
6581
|
+
var requireOptional = createRequire(import.meta.url);
|
|
6582
|
+
var DaytonaSandboxError = class extends Error {
|
|
6583
|
+
constructor(message2, cause) {
|
|
6584
|
+
super(message2);
|
|
6585
|
+
this.name = "DaytonaSandboxError";
|
|
6586
|
+
this.cause = cause;
|
|
6587
|
+
}
|
|
6588
|
+
};
|
|
6589
|
+
var DaytonaNotAvailableError = class extends DaytonaSandboxError {
|
|
6590
|
+
constructor(cause) {
|
|
6591
|
+
super(
|
|
6592
|
+
"@daytona/sdk is not installed. Install it with: npm install @daytona/sdk",
|
|
6593
|
+
cause
|
|
6594
|
+
);
|
|
6595
|
+
this.name = "DaytonaNotAvailableError";
|
|
6596
|
+
}
|
|
6597
|
+
};
|
|
6598
|
+
var DaytonaCreationError = class extends DaytonaSandboxError {
|
|
6599
|
+
constructor(message2, cause) {
|
|
6600
|
+
super(`Failed to create Daytona sandbox: ${message2}`, cause);
|
|
6601
|
+
this.name = "DaytonaCreationError";
|
|
6602
|
+
}
|
|
6603
|
+
};
|
|
6604
|
+
var DaytonaCommandError = class extends DaytonaSandboxError {
|
|
6605
|
+
constructor(message2, cause) {
|
|
6606
|
+
super(message2, cause);
|
|
6607
|
+
this.name = "DaytonaCommandError";
|
|
6608
|
+
}
|
|
6609
|
+
};
|
|
6610
|
+
async function createDaytonaSandbox(options = {}) {
|
|
6611
|
+
validateDaytonaOptions(options);
|
|
6612
|
+
const { Daytona } = await importDaytonaSdk();
|
|
6613
|
+
let client;
|
|
6614
|
+
try {
|
|
6615
|
+
client = new Daytona(createDaytonaConfig(options));
|
|
6616
|
+
} catch (error) {
|
|
6617
|
+
const err = toError(error);
|
|
6618
|
+
throw new DaytonaCreationError(err.message, err);
|
|
6619
|
+
}
|
|
6620
|
+
const attached = options.sandboxId !== void 0;
|
|
6621
|
+
const deleteOnDispose = options.deleteOnDispose ?? !attached;
|
|
6622
|
+
let sandbox;
|
|
6623
|
+
try {
|
|
6624
|
+
sandbox = attached ? await client.get(options.sandboxId) : await client.create(createDaytonaParams(options), {
|
|
6625
|
+
timeout: options.createTimeout,
|
|
6626
|
+
onSnapshotCreateLogs: options.onSnapshotCreateLogs
|
|
6627
|
+
});
|
|
6628
|
+
if (attached && sandbox.state && sandbox.state !== "started") {
|
|
6629
|
+
await sandbox.start?.(options.startTimeout ?? options.createTimeout);
|
|
6630
|
+
}
|
|
6631
|
+
} catch (error) {
|
|
6632
|
+
const err = toError(error);
|
|
6633
|
+
throw new DaytonaCreationError(err.message, err);
|
|
6634
|
+
}
|
|
6635
|
+
return createDaytonaSandboxMethods({
|
|
6636
|
+
client,
|
|
6637
|
+
sandbox,
|
|
6638
|
+
commandTimeout: options.commandTimeout,
|
|
6639
|
+
deleteOnDispose,
|
|
6640
|
+
deleteTimeout: options.deleteTimeout
|
|
6641
|
+
});
|
|
6642
|
+
}
|
|
6643
|
+
async function importDaytonaSdk() {
|
|
6644
|
+
try {
|
|
6645
|
+
const mod = requireOptional("@daytona/sdk");
|
|
6646
|
+
if (typeof mod.Daytona !== "function") {
|
|
6647
|
+
throw new DaytonaSandboxError(
|
|
6648
|
+
"@daytona/sdk did not export a Daytona constructor"
|
|
6649
|
+
);
|
|
6650
|
+
}
|
|
6651
|
+
return { Daytona: mod.Daytona };
|
|
6652
|
+
} catch (error) {
|
|
6653
|
+
if (error instanceof DaytonaSandboxError) {
|
|
6654
|
+
throw error;
|
|
6655
|
+
}
|
|
6656
|
+
const err = toError(error);
|
|
6657
|
+
if (isMissingDaytonaSdk(err)) {
|
|
6658
|
+
throw new DaytonaNotAvailableError(err);
|
|
6659
|
+
}
|
|
6660
|
+
throw err;
|
|
6661
|
+
}
|
|
6662
|
+
}
|
|
6663
|
+
function createDaytonaConfig(options) {
|
|
6664
|
+
return compactObject({
|
|
6665
|
+
apiKey: options.apiKey,
|
|
6666
|
+
jwtToken: options.jwtToken,
|
|
6667
|
+
organizationId: options.organizationId,
|
|
6668
|
+
apiUrl: options.apiUrl,
|
|
6669
|
+
target: options.target,
|
|
6670
|
+
otelEnabled: options.otelEnabled,
|
|
6671
|
+
_experimental: options.experimental
|
|
6672
|
+
});
|
|
6673
|
+
}
|
|
6674
|
+
function createDaytonaParams(options) {
|
|
6675
|
+
const base = compactObject({
|
|
6676
|
+
name: options.name,
|
|
6677
|
+
user: options.user,
|
|
6678
|
+
language: options.language,
|
|
6679
|
+
envVars: options.envVars,
|
|
6680
|
+
labels: options.labels,
|
|
6681
|
+
public: options.public,
|
|
6682
|
+
autoStopInterval: options.autoStopInterval,
|
|
6683
|
+
autoArchiveInterval: options.autoArchiveInterval,
|
|
6684
|
+
autoDeleteInterval: options.autoDeleteInterval,
|
|
6685
|
+
volumes: options.volumes,
|
|
6686
|
+
networkBlockAll: options.networkBlockAll,
|
|
6687
|
+
networkAllowList: options.networkAllowList,
|
|
6688
|
+
ephemeral: options.ephemeral
|
|
6689
|
+
});
|
|
6690
|
+
if (options.image) {
|
|
6691
|
+
return compactObject({
|
|
6692
|
+
...base,
|
|
6693
|
+
image: options.image,
|
|
6694
|
+
resources: options.resources
|
|
6695
|
+
});
|
|
6696
|
+
}
|
|
6697
|
+
const params = compactObject({
|
|
6698
|
+
...base,
|
|
6699
|
+
snapshot: options.snapshot
|
|
6700
|
+
});
|
|
6701
|
+
return Object.keys(params).length > 0 ? params : void 0;
|
|
6702
|
+
}
|
|
6703
|
+
function validateDaytonaOptions(options) {
|
|
6704
|
+
if (options.image && options.snapshot) {
|
|
6705
|
+
throw new DaytonaSandboxError(
|
|
6706
|
+
'Daytona sandbox options cannot include both "image" and "snapshot". Choose one environment source.'
|
|
6707
|
+
);
|
|
6708
|
+
}
|
|
6709
|
+
if (options.resources && !options.image) {
|
|
6710
|
+
throw new DaytonaSandboxError(
|
|
6711
|
+
'Daytona sandbox options can only include "resources" when creating from "image". The Daytona SDK does not apply resources during default or snapshot creation.'
|
|
6712
|
+
);
|
|
6713
|
+
}
|
|
6714
|
+
if (!options.sandboxId) {
|
|
6715
|
+
return;
|
|
6716
|
+
}
|
|
6717
|
+
const creationOnlyFields = [
|
|
6718
|
+
"name",
|
|
6719
|
+
"user",
|
|
6720
|
+
"snapshot",
|
|
6721
|
+
"image",
|
|
6722
|
+
"language",
|
|
6723
|
+
"envVars",
|
|
6724
|
+
"labels",
|
|
6725
|
+
"public",
|
|
6726
|
+
"resources",
|
|
6727
|
+
"volumes",
|
|
6728
|
+
"networkAllowList",
|
|
6729
|
+
"networkBlockAll",
|
|
6730
|
+
"autoStopInterval",
|
|
6731
|
+
"autoArchiveInterval",
|
|
6732
|
+
"autoDeleteInterval",
|
|
6733
|
+
"ephemeral",
|
|
6734
|
+
"onSnapshotCreateLogs"
|
|
6735
|
+
];
|
|
6736
|
+
const present = creationOnlyFields.filter((field) => {
|
|
6737
|
+
return options[field] !== void 0;
|
|
6738
|
+
});
|
|
6739
|
+
if (present.length > 0) {
|
|
6740
|
+
throw new DaytonaSandboxError(
|
|
6741
|
+
`Daytona sandbox options cannot combine "sandboxId" with creation options: ${present.join(", ")}`
|
|
6742
|
+
);
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
function createDaytonaSandboxMethods(args) {
|
|
6746
|
+
const { client, sandbox, commandTimeout, deleteOnDispose, deleteTimeout } = args;
|
|
6747
|
+
let disposed = false;
|
|
6748
|
+
const executeCommand = async (command, options) => {
|
|
6749
|
+
if (options?.signal?.aborted) {
|
|
6750
|
+
return abortedCommandResult();
|
|
6751
|
+
}
|
|
6752
|
+
let aborted = false;
|
|
6753
|
+
const abort = () => {
|
|
6754
|
+
aborted = true;
|
|
6755
|
+
};
|
|
6756
|
+
options?.signal?.addEventListener("abort", abort, { once: true });
|
|
6757
|
+
try {
|
|
6758
|
+
if (aborted || options?.signal?.aborted) {
|
|
6759
|
+
return abortedCommandResult();
|
|
6760
|
+
}
|
|
6761
|
+
const response = await sandbox.process.executeCommand(
|
|
6762
|
+
command,
|
|
6763
|
+
void 0,
|
|
6764
|
+
void 0,
|
|
6765
|
+
commandTimeout
|
|
6766
|
+
);
|
|
6767
|
+
if (aborted) return abortedCommandResult();
|
|
6768
|
+
return {
|
|
6769
|
+
stdout: response.result ?? response.artifacts?.stdout ?? "",
|
|
6770
|
+
stderr: "",
|
|
6771
|
+
exitCode: response.exitCode ?? 0
|
|
6772
|
+
};
|
|
6773
|
+
} catch (error) {
|
|
6774
|
+
if (aborted) return abortedCommandResult();
|
|
6775
|
+
const err = error;
|
|
6776
|
+
return {
|
|
6777
|
+
stdout: err.stdout ?? "",
|
|
6778
|
+
stderr: err.stderr ?? err.message ?? String(error),
|
|
6779
|
+
exitCode: err.exitCode ?? 1
|
|
6780
|
+
};
|
|
6781
|
+
} finally {
|
|
6782
|
+
options?.signal?.removeEventListener("abort", abort);
|
|
6783
|
+
}
|
|
6784
|
+
};
|
|
6785
|
+
return {
|
|
6786
|
+
executeCommand,
|
|
6787
|
+
spawn(command, options) {
|
|
6788
|
+
return spawnDaytonaProcess(sandbox, command, {
|
|
6789
|
+
...options,
|
|
6790
|
+
commandTimeout
|
|
6791
|
+
});
|
|
6792
|
+
},
|
|
6793
|
+
async readFile(path5) {
|
|
6794
|
+
try {
|
|
6795
|
+
const bytes = await sandbox.fs.downloadFile(path5);
|
|
6796
|
+
return Buffer.from(bytes).toString("utf-8");
|
|
6797
|
+
} catch (error) {
|
|
6798
|
+
throw new DaytonaCommandError(
|
|
6799
|
+
`Failed to read file "${path5}": ${toError(error).message}`,
|
|
6800
|
+
toError(error)
|
|
6801
|
+
);
|
|
6802
|
+
}
|
|
6803
|
+
},
|
|
6804
|
+
async writeFiles(files) {
|
|
6805
|
+
try {
|
|
6806
|
+
for (const dir of uniqueParentDirectories(files.map((f) => f.path))) {
|
|
6807
|
+
const result = await executeCommand(`mkdir -p ${shellQuote2(dir)}`);
|
|
6808
|
+
if (result.exitCode !== 0) {
|
|
6809
|
+
throw new DaytonaCommandError(
|
|
6810
|
+
`Failed to create directory "${dir}": ${result.stderr}`
|
|
6811
|
+
);
|
|
6812
|
+
}
|
|
6813
|
+
}
|
|
6814
|
+
await sandbox.fs.uploadFiles(
|
|
6815
|
+
files.map((file) => ({
|
|
6816
|
+
source: Buffer.from(file.content),
|
|
6817
|
+
destination: file.path
|
|
6818
|
+
}))
|
|
6819
|
+
);
|
|
6820
|
+
} catch (error) {
|
|
6821
|
+
if (error instanceof DaytonaSandboxError) throw error;
|
|
6822
|
+
const err = toError(error);
|
|
6823
|
+
throw new DaytonaCommandError(
|
|
6824
|
+
`Failed to write files: ${err.message}`,
|
|
6825
|
+
err
|
|
6826
|
+
);
|
|
6827
|
+
}
|
|
6828
|
+
},
|
|
6829
|
+
async dispose() {
|
|
6830
|
+
if (disposed) return;
|
|
6831
|
+
disposed = true;
|
|
6832
|
+
try {
|
|
6833
|
+
if (deleteOnDispose) {
|
|
6834
|
+
if (sandbox.delete) await sandbox.delete(deleteTimeout);
|
|
6835
|
+
else if (client.delete) await client.delete(sandbox, deleteTimeout);
|
|
6836
|
+
}
|
|
6837
|
+
} finally {
|
|
6838
|
+
await client[Symbol.asyncDispose]?.().catch(() => {
|
|
6839
|
+
});
|
|
6840
|
+
}
|
|
6841
|
+
}
|
|
6842
|
+
};
|
|
6843
|
+
}
|
|
6844
|
+
function spawnDaytonaProcess(sandbox, command, options = {}) {
|
|
6845
|
+
const sessionId = createSessionId("spawn");
|
|
6846
|
+
const stdout = createTextReadable();
|
|
6847
|
+
const stderr = createTextReadable();
|
|
6848
|
+
const exit = runSpawnedSession({
|
|
6849
|
+
sandbox,
|
|
6850
|
+
sessionId,
|
|
6851
|
+
command: buildSessionCommand(command, options),
|
|
6852
|
+
signal: options.signal,
|
|
6853
|
+
commandTimeout: options.commandTimeout,
|
|
6854
|
+
stdout,
|
|
6855
|
+
stderr
|
|
6856
|
+
});
|
|
6857
|
+
return {
|
|
6858
|
+
stdout: stdout.stream,
|
|
6859
|
+
stderr: stderr.stream,
|
|
6860
|
+
exit
|
|
6861
|
+
};
|
|
6862
|
+
}
|
|
6863
|
+
async function runSpawnedSession(args) {
|
|
6864
|
+
const {
|
|
6865
|
+
sandbox,
|
|
6866
|
+
sessionId,
|
|
6867
|
+
command,
|
|
6868
|
+
signal,
|
|
6869
|
+
commandTimeout,
|
|
6870
|
+
stdout,
|
|
6871
|
+
stderr
|
|
6872
|
+
} = args;
|
|
6873
|
+
let sessionCreated = false;
|
|
6874
|
+
let aborted = signal?.aborted ?? false;
|
|
6875
|
+
let resolveAbort;
|
|
6876
|
+
const abortPromise = new Promise((resolve4) => {
|
|
6877
|
+
resolveAbort = () => resolve4("aborted");
|
|
6878
|
+
});
|
|
6879
|
+
const abort = () => {
|
|
6880
|
+
aborted = true;
|
|
6881
|
+
resolveAbort?.();
|
|
6882
|
+
if (sessionCreated) {
|
|
6883
|
+
sandbox.process.deleteSession(sessionId).catch(() => {
|
|
6884
|
+
});
|
|
6885
|
+
}
|
|
6886
|
+
};
|
|
6887
|
+
if (signal) {
|
|
6888
|
+
if (signal.aborted) abort();
|
|
6889
|
+
else signal.addEventListener("abort", abort, { once: true });
|
|
6890
|
+
}
|
|
6891
|
+
try {
|
|
6892
|
+
await sandbox.process.createSession(sessionId);
|
|
6893
|
+
sessionCreated = true;
|
|
6894
|
+
if (aborted) return abortedExitInfo();
|
|
6895
|
+
const response = await sandbox.process.executeSessionCommand(
|
|
6896
|
+
sessionId,
|
|
6897
|
+
{
|
|
6898
|
+
command,
|
|
6899
|
+
runAsync: true,
|
|
6900
|
+
suppressInputEcho: true
|
|
6901
|
+
},
|
|
6902
|
+
commandTimeout
|
|
6903
|
+
);
|
|
6904
|
+
const commandId = response.cmdId;
|
|
6905
|
+
if (!commandId) {
|
|
6906
|
+
throw new DaytonaCommandError(
|
|
6907
|
+
"Daytona did not return a command id for the spawned session command."
|
|
6908
|
+
);
|
|
6909
|
+
}
|
|
6910
|
+
if (aborted) return abortedExitInfo();
|
|
6911
|
+
const logsTask = sandbox.process.getSessionCommandLogs(
|
|
6912
|
+
sessionId,
|
|
6913
|
+
commandId,
|
|
6914
|
+
(chunk) => stdout.enqueue(chunk),
|
|
6915
|
+
(chunk) => stderr.enqueue(chunk)
|
|
6916
|
+
);
|
|
6917
|
+
logsTask.catch(() => {
|
|
6918
|
+
});
|
|
6919
|
+
const winner = await Promise.race([
|
|
6920
|
+
logsTask.then(() => "logs"),
|
|
6921
|
+
abortPromise
|
|
6922
|
+
]);
|
|
6923
|
+
if (winner === "aborted") {
|
|
6924
|
+
await sandbox.process.deleteSession(sessionId).catch(() => {
|
|
6925
|
+
});
|
|
6926
|
+
return abortedExitInfo();
|
|
6927
|
+
}
|
|
6928
|
+
await logsTask;
|
|
6929
|
+
const code = await waitForSessionCommandExitCode({
|
|
6930
|
+
sandbox,
|
|
6931
|
+
sessionId,
|
|
6932
|
+
commandId,
|
|
6933
|
+
timeoutMs: sessionExitPollTimeoutMs(commandTimeout),
|
|
6934
|
+
isAborted: () => aborted
|
|
6935
|
+
});
|
|
6936
|
+
return { code, signal: null, success: code === 0 };
|
|
6937
|
+
} catch (error) {
|
|
6938
|
+
if (aborted) return abortedExitInfo();
|
|
6939
|
+
const err = toError(error);
|
|
6940
|
+
stdout.error(err);
|
|
6941
|
+
stderr.error(err);
|
|
6942
|
+
throw err;
|
|
6943
|
+
} finally {
|
|
6944
|
+
if (signal) {
|
|
6945
|
+
signal.removeEventListener("abort", abort);
|
|
6946
|
+
}
|
|
6947
|
+
stdout.close();
|
|
6948
|
+
stderr.close();
|
|
6949
|
+
if (sessionCreated) {
|
|
6950
|
+
await sandbox.process.deleteSession(sessionId).catch(() => {
|
|
6951
|
+
});
|
|
6952
|
+
}
|
|
6953
|
+
}
|
|
6954
|
+
}
|
|
6955
|
+
async function waitForSessionCommandExitCode(args) {
|
|
6956
|
+
const { sandbox, sessionId, commandId, timeoutMs, isAborted } = args;
|
|
6957
|
+
const deadline = Date.now() + timeoutMs;
|
|
6958
|
+
while (true) {
|
|
6959
|
+
if (isAborted()) throw new DaytonaCommandError("Daytona command aborted.");
|
|
6960
|
+
const info = await sandbox.process.getSessionCommand(sessionId, commandId);
|
|
6961
|
+
if (typeof info.exitCode === "number") {
|
|
6962
|
+
return info.exitCode;
|
|
6963
|
+
}
|
|
6964
|
+
if (Date.now() >= deadline) {
|
|
6965
|
+
throw new DaytonaCommandError(
|
|
6966
|
+
`Daytona session command "${commandId}" logs closed before an exit code became available.`
|
|
6967
|
+
);
|
|
6968
|
+
}
|
|
6969
|
+
await delay(DAYTONA_EXIT_POLL_INTERVAL_MS);
|
|
6970
|
+
}
|
|
6971
|
+
}
|
|
6972
|
+
function sessionExitPollTimeoutMs(commandTimeout) {
|
|
6973
|
+
if (commandTimeout === void 0 || commandTimeout === 0) {
|
|
6974
|
+
return DAYTONA_EXIT_POLL_TIMEOUT_MS;
|
|
6975
|
+
}
|
|
6976
|
+
return Math.max(commandTimeout * 1e3, DAYTONA_EXIT_POLL_TIMEOUT_MS);
|
|
6977
|
+
}
|
|
6978
|
+
function delay(ms) {
|
|
6979
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
6980
|
+
}
|
|
6981
|
+
function createTextReadable() {
|
|
6982
|
+
const encoder = new TextEncoder();
|
|
6983
|
+
let controller;
|
|
6984
|
+
let closed = false;
|
|
6985
|
+
return {
|
|
6986
|
+
stream: new ReadableStream({
|
|
6987
|
+
start(streamController) {
|
|
6988
|
+
controller = streamController;
|
|
6989
|
+
}
|
|
6990
|
+
}),
|
|
6991
|
+
enqueue(chunk) {
|
|
6992
|
+
if (closed || !chunk) return;
|
|
6993
|
+
controller?.enqueue(encoder.encode(chunk));
|
|
6994
|
+
},
|
|
6995
|
+
close() {
|
|
6996
|
+
if (closed) return;
|
|
6997
|
+
closed = true;
|
|
6998
|
+
controller?.close();
|
|
6999
|
+
},
|
|
7000
|
+
error(error) {
|
|
7001
|
+
if (closed) return;
|
|
7002
|
+
closed = true;
|
|
7003
|
+
controller?.error(error);
|
|
7004
|
+
}
|
|
7005
|
+
};
|
|
7006
|
+
}
|
|
7007
|
+
function buildSessionCommand(command, options) {
|
|
7008
|
+
const cwdPrefix = options.cwd ? `cd ${shellQuote2(options.cwd)} && ` : "";
|
|
7009
|
+
const env = options.env ?? {};
|
|
7010
|
+
const entries = Object.entries(env);
|
|
7011
|
+
if (entries.length === 0) {
|
|
7012
|
+
return `sh -lc ${shellQuote2(`${cwdPrefix}${command}`)}`;
|
|
7013
|
+
}
|
|
7014
|
+
for (const [key] of entries) {
|
|
7015
|
+
validateEnvKey(key);
|
|
7016
|
+
}
|
|
7017
|
+
const exports = entries.map(([key, value]) => `export ${key}=${shellQuote2(value)}`).join("; ");
|
|
7018
|
+
return `sh -lc ${shellQuote2(`${exports}; ${cwdPrefix}${command}`)}`;
|
|
7019
|
+
}
|
|
7020
|
+
function validateEnvKey(key) {
|
|
7021
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
7022
|
+
throw new DaytonaSandboxError(
|
|
7023
|
+
`Invalid environment variable key: "${key}". Use shell-compatible environment variable names.`
|
|
7024
|
+
);
|
|
7025
|
+
}
|
|
7026
|
+
}
|
|
7027
|
+
function createSessionId(kind) {
|
|
7028
|
+
return `deepagents-${kind}-${randomUUID()}`;
|
|
7029
|
+
}
|
|
7030
|
+
function abortedCommandResult() {
|
|
7031
|
+
return {
|
|
7032
|
+
stdout: "",
|
|
7033
|
+
stderr: "Command aborted",
|
|
7034
|
+
exitCode: 1
|
|
7035
|
+
};
|
|
7036
|
+
}
|
|
7037
|
+
function abortedExitInfo() {
|
|
7038
|
+
return {
|
|
7039
|
+
code: null,
|
|
7040
|
+
signal: "SIGKILL",
|
|
7041
|
+
success: false
|
|
7042
|
+
};
|
|
7043
|
+
}
|
|
7044
|
+
function shellQuote2(value) {
|
|
7045
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
7046
|
+
}
|
|
7047
|
+
function uniqueParentDirectories(paths) {
|
|
7048
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
7049
|
+
for (const path5 of paths) {
|
|
7050
|
+
const index = path5.lastIndexOf("/");
|
|
7051
|
+
if (index > 0) {
|
|
7052
|
+
dirs.add(path5.slice(0, index));
|
|
7053
|
+
}
|
|
7054
|
+
}
|
|
7055
|
+
return [...dirs];
|
|
7056
|
+
}
|
|
7057
|
+
function compactObject(input) {
|
|
7058
|
+
const output = {};
|
|
7059
|
+
for (const [key, value] of Object.entries(input)) {
|
|
7060
|
+
if (value !== void 0) {
|
|
7061
|
+
output[key] = value;
|
|
7062
|
+
}
|
|
7063
|
+
}
|
|
7064
|
+
return output;
|
|
7065
|
+
}
|
|
7066
|
+
function isMissingDaytonaSdk(error) {
|
|
7067
|
+
const maybeCode = error.code;
|
|
7068
|
+
return maybeCode === "ERR_MODULE_NOT_FOUND" || maybeCode === "MODULE_NOT_FOUND" || error.message.includes("@daytona/sdk");
|
|
7069
|
+
}
|
|
7070
|
+
function toError(error) {
|
|
7071
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
7072
|
+
}
|
|
7073
|
+
|
|
6409
7074
|
// packages/context/src/lib/sandbox/docker-sandbox.ts
|
|
6410
7075
|
import "bash-tool";
|
|
6411
7076
|
import spawn3 from "nano-spawn";
|
|
6412
7077
|
import { spawn as childSpawn } from "node:child_process";
|
|
6413
7078
|
import { createHash } from "node:crypto";
|
|
6414
7079
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
6415
|
-
import { Readable } from "node:stream";
|
|
7080
|
+
import { Readable as Readable2 } from "node:stream";
|
|
6416
7081
|
|
|
6417
7082
|
// packages/context/src/lib/sandbox/docker-sandbox-errors.ts
|
|
6418
7083
|
var DockerSandboxError = class extends Error {
|
|
@@ -6559,7 +7224,7 @@ function isDebianBased(image) {
|
|
|
6559
7224
|
const debianPatterns = ["debian", "ubuntu", "node", "python"];
|
|
6560
7225
|
return debianPatterns.some((pattern) => lower.includes(pattern));
|
|
6561
7226
|
}
|
|
6562
|
-
function
|
|
7227
|
+
function shellQuote3(s) {
|
|
6563
7228
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
6564
7229
|
}
|
|
6565
7230
|
function createInstallerContext(containerId, image) {
|
|
@@ -6607,7 +7272,7 @@ function createInstallerContext(containerId, image) {
|
|
|
6607
7272
|
};
|
|
6608
7273
|
const installPackages = async (packages) => {
|
|
6609
7274
|
if (packages.length === 0) return;
|
|
6610
|
-
const quoted = packages.map(
|
|
7275
|
+
const quoted = packages.map(shellQuote3).join(" ");
|
|
6611
7276
|
let cmd;
|
|
6612
7277
|
if (packageManager === "apt-get") {
|
|
6613
7278
|
cmd = aptUpdated ? `apt-get install -y ${quoted}` : `apt-get update && apt-get install -y ${quoted}`;
|
|
@@ -6629,7 +7294,7 @@ function createInstallerContext(containerId, image) {
|
|
|
6629
7294
|
const ensureTool = async (checkName, installName) => {
|
|
6630
7295
|
const cacheKey = installName ?? checkName;
|
|
6631
7296
|
if (ensuredTools.has(cacheKey)) return;
|
|
6632
|
-
const check = await exec(`which ${
|
|
7297
|
+
const check = await exec(`which ${shellQuote3(checkName)}`);
|
|
6633
7298
|
if (check.exitCode === 0) {
|
|
6634
7299
|
ensuredTools.add(cacheKey);
|
|
6635
7300
|
return;
|
|
@@ -6666,7 +7331,7 @@ var DockerSandboxStrategy = class {
|
|
|
6666
7331
|
constructor(args = {}) {
|
|
6667
7332
|
const { volumes = [], resources = {}, env = {}, name } = args;
|
|
6668
7333
|
for (const key of Object.keys(env)) {
|
|
6669
|
-
|
|
7334
|
+
validateEnvKey2(key);
|
|
6670
7335
|
}
|
|
6671
7336
|
if (name !== void 0 && !CONTAINER_NAME_PATTERN.test(name)) {
|
|
6672
7337
|
throw new DockerSandboxError(
|
|
@@ -7071,7 +7736,7 @@ var DockerSandboxStrategy = class {
|
|
|
7071
7736
|
return sandbox;
|
|
7072
7737
|
}
|
|
7073
7738
|
};
|
|
7074
|
-
function
|
|
7739
|
+
function validateEnvKey2(key) {
|
|
7075
7740
|
if (key.length === 0 || key.includes("=")) {
|
|
7076
7741
|
throw new DockerSandboxError(`Invalid environment variable key: "${key}"`);
|
|
7077
7742
|
}
|
|
@@ -7083,7 +7748,7 @@ function buildDockerExecFlags(options) {
|
|
|
7083
7748
|
}
|
|
7084
7749
|
if (options?.env) {
|
|
7085
7750
|
for (const [key, value] of Object.entries(options.env)) {
|
|
7086
|
-
|
|
7751
|
+
validateEnvKey2(key);
|
|
7087
7752
|
flags.push("-e", `${key}=${value}`);
|
|
7088
7753
|
}
|
|
7089
7754
|
}
|
|
@@ -7100,8 +7765,8 @@ function toSandboxProcess(child, abortSignal) {
|
|
|
7100
7765
|
else abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
7101
7766
|
}
|
|
7102
7767
|
return {
|
|
7103
|
-
stdout:
|
|
7104
|
-
stderr:
|
|
7768
|
+
stdout: Readable2.toWeb(child.stdout),
|
|
7769
|
+
stderr: Readable2.toWeb(child.stderr),
|
|
7105
7770
|
exit: new Promise((resolve4, reject) => {
|
|
7106
7771
|
const settle = () => {
|
|
7107
7772
|
child.removeListener("exit", onExitEvent);
|
|
@@ -7347,60 +8012,6 @@ async function useSandbox(options, fn) {
|
|
|
7347
8012
|
}
|
|
7348
8013
|
}
|
|
7349
8014
|
|
|
7350
|
-
// packages/context/src/lib/sandbox/container-tool.ts
|
|
7351
|
-
async function createContainerTool(options = {}) {
|
|
7352
|
-
let sandboxOptions;
|
|
7353
|
-
let bashOptions;
|
|
7354
|
-
let skillInputs = [];
|
|
7355
|
-
if (isComposeOptions(options)) {
|
|
7356
|
-
const { compose, service, resources, skills: skills2 = [], ...rest } = options;
|
|
7357
|
-
sandboxOptions = { compose, service, resources };
|
|
7358
|
-
bashOptions = rest;
|
|
7359
|
-
skillInputs = skills2;
|
|
7360
|
-
} else if (isDockerfileOptions(options)) {
|
|
7361
|
-
const {
|
|
7362
|
-
dockerfile,
|
|
7363
|
-
context,
|
|
7364
|
-
volumes,
|
|
7365
|
-
resources,
|
|
7366
|
-
env,
|
|
7367
|
-
name,
|
|
7368
|
-
skills: skills2 = [],
|
|
7369
|
-
...rest
|
|
7370
|
-
} = options;
|
|
7371
|
-
sandboxOptions = { dockerfile, context, volumes, resources, env, name };
|
|
7372
|
-
bashOptions = rest;
|
|
7373
|
-
skillInputs = skills2;
|
|
7374
|
-
} else {
|
|
7375
|
-
const {
|
|
7376
|
-
image,
|
|
7377
|
-
installers,
|
|
7378
|
-
volumes,
|
|
7379
|
-
resources,
|
|
7380
|
-
env,
|
|
7381
|
-
name,
|
|
7382
|
-
skills: skills2 = [],
|
|
7383
|
-
...rest
|
|
7384
|
-
} = options;
|
|
7385
|
-
sandboxOptions = { image, installers, volumes, resources, env, name };
|
|
7386
|
-
bashOptions = rest;
|
|
7387
|
-
skillInputs = skills2;
|
|
7388
|
-
}
|
|
7389
|
-
const backend = await createDockerSandbox(sandboxOptions);
|
|
7390
|
-
const toolkit = await createBashTool({
|
|
7391
|
-
...bashOptions,
|
|
7392
|
-
sandbox: backend,
|
|
7393
|
-
skills: skillInputs
|
|
7394
|
-
});
|
|
7395
|
-
return {
|
|
7396
|
-
bash: toolkit.bash,
|
|
7397
|
-
tools: toolkit.tools,
|
|
7398
|
-
sandbox: toolkit.sandbox,
|
|
7399
|
-
skills: toolkit.skills,
|
|
7400
|
-
drainFileEvents: toolkit.drainFileEvents
|
|
7401
|
-
};
|
|
7402
|
-
}
|
|
7403
|
-
|
|
7404
8015
|
// packages/context/src/lib/sandbox/installers/package-manager.ts
|
|
7405
8016
|
var PackageInstaller = class extends Installer {
|
|
7406
8017
|
kind;
|
|
@@ -7473,9 +8084,9 @@ async function downloadAndInstall(ctx, name, url, binaryPath, source = "url") {
|
|
|
7473
8084
|
function buildTarGzInstallCmd(name, url, binaryPathInArchive) {
|
|
7474
8085
|
return `
|
|
7475
8086
|
set -e
|
|
7476
|
-
NAME=${
|
|
7477
|
-
URL=${
|
|
7478
|
-
BIN_IN_ARCHIVE=${
|
|
8087
|
+
NAME=${shellQuote3(name)}
|
|
8088
|
+
URL=${shellQuote3(url)}
|
|
8089
|
+
BIN_IN_ARCHIVE=${shellQuote3(binaryPathInArchive)}
|
|
7479
8090
|
TMPDIR=$(mktemp -d)
|
|
7480
8091
|
cd "$TMPDIR"
|
|
7481
8092
|
curl -fsSL "$URL" -o archive.tar.gz
|
|
@@ -7494,8 +8105,8 @@ function buildTarGzInstallCmd(name, url, binaryPathInArchive) {
|
|
|
7494
8105
|
}
|
|
7495
8106
|
function buildRawInstallCmd(name, url) {
|
|
7496
8107
|
return `
|
|
7497
|
-
NAME=${
|
|
7498
|
-
URL=${
|
|
8108
|
+
NAME=${shellQuote3(name)}
|
|
8109
|
+
URL=${shellQuote3(url)}
|
|
7499
8110
|
curl -fsSL "$URL" -o "/usr/local/bin/$NAME"
|
|
7500
8111
|
chmod +x "/usr/local/bin/$NAME"
|
|
7501
8112
|
`;
|
|
@@ -7548,6 +8159,59 @@ async function ensureNodeRuntime(ctx, ensure) {
|
|
|
7548
8159
|
}
|
|
7549
8160
|
}
|
|
7550
8161
|
|
|
8162
|
+
// packages/context/src/lib/sandbox/installers/bin.ts
|
|
8163
|
+
import { basename, posix } from "node:path";
|
|
8164
|
+
var NOT_FOUND_EXIT = 11;
|
|
8165
|
+
var CHMOD_FAILED_EXIT = 12;
|
|
8166
|
+
var BinInstaller = class extends Installer {
|
|
8167
|
+
kind;
|
|
8168
|
+
binary;
|
|
8169
|
+
options;
|
|
8170
|
+
#name;
|
|
8171
|
+
#target;
|
|
8172
|
+
constructor(binary, options = {}) {
|
|
8173
|
+
super();
|
|
8174
|
+
this.binary = binary;
|
|
8175
|
+
this.options = options;
|
|
8176
|
+
this.#name = resolveName(binary, options);
|
|
8177
|
+
this.#target = options.target ?? posix.join("/usr/local/bin", this.#name);
|
|
8178
|
+
this.kind = `bin:${this.#name}`;
|
|
8179
|
+
}
|
|
8180
|
+
async install(ctx) {
|
|
8181
|
+
const b = shellQuote3(this.binary);
|
|
8182
|
+
const t = shellQuote3(this.#target);
|
|
8183
|
+
const dir = shellQuote3(posix.dirname(this.#target));
|
|
8184
|
+
const result = await ctx.exec(
|
|
8185
|
+
`test -f ${b} || { echo "binary not found at ${this.binary}" >&2; exit ${NOT_FOUND_EXIT}; }; if ! test -x ${b}; then chmod +x ${b} || exit ${CHMOD_FAILED_EXIT}; fi; mkdir -p ${dir} && ln -sf ${b} ${t}`
|
|
8186
|
+
);
|
|
8187
|
+
if (result.exitCode === 0) return;
|
|
8188
|
+
throw new InstallError({
|
|
8189
|
+
target: this.#name,
|
|
8190
|
+
source: "bin",
|
|
8191
|
+
reason: explainFailure(result.exitCode, result.stderr, this.binary),
|
|
8192
|
+
containerId: ctx.containerId
|
|
8193
|
+
});
|
|
8194
|
+
}
|
|
8195
|
+
};
|
|
8196
|
+
function bin(binary, options) {
|
|
8197
|
+
return new BinInstaller(binary, options);
|
|
8198
|
+
}
|
|
8199
|
+
function explainFailure(exitCode, stderr, binary) {
|
|
8200
|
+
if (exitCode === NOT_FOUND_EXIT) {
|
|
8201
|
+
return `binary not found at ${binary}`;
|
|
8202
|
+
}
|
|
8203
|
+
if (exitCode === CHMOD_FAILED_EXIT && /read-only file system/i.test(stderr)) {
|
|
8204
|
+
return `${binary} is not executable and the bind mount is read-only \u2014 run \`chmod +x\` on the host, or mount with \`readOnly: false\`. (${stderr.trim()})`;
|
|
8205
|
+
}
|
|
8206
|
+
return stderr || `bin installer failed with exit code ${exitCode}`;
|
|
8207
|
+
}
|
|
8208
|
+
function resolveName(binary, options) {
|
|
8209
|
+
if (options.name) return options.name;
|
|
8210
|
+
const base = basename(binary);
|
|
8211
|
+
const dot = base.lastIndexOf(".");
|
|
8212
|
+
return dot > 0 ? base.slice(0, dot) : base;
|
|
8213
|
+
}
|
|
8214
|
+
|
|
7551
8215
|
// packages/context/src/lib/sandbox/installers/pip.ts
|
|
7552
8216
|
var PYTHON_BINARIES = ["python3", "pip3"];
|
|
7553
8217
|
var PipInstaller = class extends Installer {
|
|
@@ -7811,7 +8475,7 @@ function soul() {
|
|
|
7811
8475
|
}
|
|
7812
8476
|
|
|
7813
8477
|
// packages/context/src/lib/store/postgres.store.ts
|
|
7814
|
-
import { createRequire } from "node:module";
|
|
8478
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
7815
8479
|
|
|
7816
8480
|
// packages/context/src/lib/store/ddl.postgres.ts
|
|
7817
8481
|
function storeDDL(schema) {
|
|
@@ -7923,7 +8587,7 @@ var PostgresContextStore = class _PostgresContextStore extends ContextStore {
|
|
|
7923
8587
|
}
|
|
7924
8588
|
static #requirePg() {
|
|
7925
8589
|
try {
|
|
7926
|
-
const require2 =
|
|
8590
|
+
const require2 = createRequire2(import.meta.url);
|
|
7927
8591
|
return require2("pg");
|
|
7928
8592
|
} catch {
|
|
7929
8593
|
throw new Error(
|
|
@@ -8519,7 +9183,7 @@ var PostgresContextStore = class _PostgresContextStore extends ContextStore {
|
|
|
8519
9183
|
};
|
|
8520
9184
|
|
|
8521
9185
|
// packages/context/src/lib/store/sqlserver.store.ts
|
|
8522
|
-
import { createRequire as
|
|
9186
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
8523
9187
|
|
|
8524
9188
|
// packages/context/src/lib/store/ddl.sqlserver.ts
|
|
8525
9189
|
function storeDDL2(schema) {
|
|
@@ -8661,7 +9325,7 @@ var SqlServerContextStore = class _SqlServerContextStore extends ContextStore {
|
|
|
8661
9325
|
}
|
|
8662
9326
|
static #requireMssql() {
|
|
8663
9327
|
try {
|
|
8664
|
-
const require2 =
|
|
9328
|
+
const require2 = createRequire3(import.meta.url);
|
|
8665
9329
|
return require2("mssql");
|
|
8666
9330
|
} catch {
|
|
8667
9331
|
throw new Error(
|
|
@@ -9371,11 +10035,12 @@ async function persistedWriter(options) {
|
|
|
9371
10035
|
} = options;
|
|
9372
10036
|
let seq = 0;
|
|
9373
10037
|
let buffer = [];
|
|
10038
|
+
let failedByErrorChunk = false;
|
|
9374
10039
|
async function flush() {
|
|
9375
10040
|
if (buffer.length === 0) return;
|
|
9376
10041
|
const batch = buffer;
|
|
9377
10042
|
buffer = [];
|
|
9378
|
-
await
|
|
10043
|
+
await appendBatch(batch);
|
|
9379
10044
|
}
|
|
9380
10045
|
function makeChunk(part) {
|
|
9381
10046
|
return {
|
|
@@ -9385,9 +10050,19 @@ async function persistedWriter(options) {
|
|
|
9385
10050
|
createdAt: Date.now()
|
|
9386
10051
|
};
|
|
9387
10052
|
}
|
|
10053
|
+
function isStreamErrorPart(part) {
|
|
10054
|
+
return part.type === "error";
|
|
10055
|
+
}
|
|
10056
|
+
async function appendBatch(batch) {
|
|
10057
|
+
const hasErrorPart = !failedByErrorChunk && batch.map((chunk) => chunk.data).some(isStreamErrorPart);
|
|
10058
|
+
await store2.appendChunks(batch);
|
|
10059
|
+
if (hasErrorPart) {
|
|
10060
|
+
failedByErrorChunk = true;
|
|
10061
|
+
}
|
|
10062
|
+
}
|
|
9388
10063
|
async function persistChunk(chunk) {
|
|
9389
10064
|
if (strategy === "immediate") {
|
|
9390
|
-
await
|
|
10065
|
+
await appendBatch([chunk]);
|
|
9391
10066
|
} else {
|
|
9392
10067
|
buffer.push(chunk);
|
|
9393
10068
|
if (buffer.length >= flushSize) {
|
|
@@ -9417,10 +10092,12 @@ async function persistedWriter(options) {
|
|
|
9417
10092
|
flush,
|
|
9418
10093
|
async complete() {
|
|
9419
10094
|
await flush();
|
|
10095
|
+
if (failedByErrorChunk) return;
|
|
9420
10096
|
await store2.updateStreamStatus(streamId, "completed");
|
|
9421
10097
|
},
|
|
9422
10098
|
async fail(error) {
|
|
9423
10099
|
await flush();
|
|
10100
|
+
if (failedByErrorChunk) return;
|
|
9424
10101
|
await store2.updateStreamStatus(streamId, "failed", { error });
|
|
9425
10102
|
},
|
|
9426
10103
|
async cleanup() {
|
|
@@ -9430,7 +10107,7 @@ async function persistedWriter(options) {
|
|
|
9430
10107
|
}
|
|
9431
10108
|
|
|
9432
10109
|
// packages/context/src/lib/stream/polling-change-source.ts
|
|
9433
|
-
import { setTimeout as
|
|
10110
|
+
import { setTimeout as delay2 } from "node:timers/promises";
|
|
9434
10111
|
|
|
9435
10112
|
// packages/context/src/lib/stream/polling-policy.ts
|
|
9436
10113
|
var DEFAULT_WATCH_POLLING = {
|
|
@@ -9475,7 +10152,7 @@ function nextAdaptivePollingDelay(state) {
|
|
|
9475
10152
|
state.config.minMs,
|
|
9476
10153
|
state.config.maxMs
|
|
9477
10154
|
);
|
|
9478
|
-
const
|
|
10155
|
+
const delay3 = applyJitter(
|
|
9479
10156
|
current,
|
|
9480
10157
|
state.config.jitterRatio,
|
|
9481
10158
|
state.config.minMs,
|
|
@@ -9486,7 +10163,7 @@ function nextAdaptivePollingDelay(state) {
|
|
|
9486
10163
|
state.config.minMs,
|
|
9487
10164
|
state.config.maxMs
|
|
9488
10165
|
);
|
|
9489
|
-
return
|
|
10166
|
+
return delay3;
|
|
9490
10167
|
}
|
|
9491
10168
|
function normalizeAdaptivePolling(polling, fallback) {
|
|
9492
10169
|
const merged = {
|
|
@@ -9586,7 +10263,7 @@ function isTerminal(status) {
|
|
|
9586
10263
|
return status !== "queued" && status !== "running";
|
|
9587
10264
|
}
|
|
9588
10265
|
function waitForDelay(ms, signal) {
|
|
9589
|
-
return
|
|
10266
|
+
return delay2(ms, true, { signal }).catch((err) => {
|
|
9590
10267
|
if (signal.aborted) return false;
|
|
9591
10268
|
throw err;
|
|
9592
10269
|
});
|
|
@@ -9638,7 +10315,7 @@ function asStaticWordPartText(parts, options = {}) {
|
|
|
9638
10315
|
}
|
|
9639
10316
|
|
|
9640
10317
|
// packages/context/src/lib/stream/postgres-notify-change-source.ts
|
|
9641
|
-
import { createRequire as
|
|
10318
|
+
import { createRequire as createRequire4 } from "node:module";
|
|
9642
10319
|
|
|
9643
10320
|
// packages/context/src/lib/stream/ddl.stream.postgres-notify.ts
|
|
9644
10321
|
var DEFAULT_POSTGRES_STREAM_CHANGES_CHANNEL = "deepagents_stream_changes";
|
|
@@ -9740,7 +10417,7 @@ var PostgresNotifyChangeSource = class _PostgresNotifyChangeSource {
|
|
|
9740
10417
|
}
|
|
9741
10418
|
static #requirePg() {
|
|
9742
10419
|
try {
|
|
9743
|
-
const require2 =
|
|
10420
|
+
const require2 = createRequire4(import.meta.url);
|
|
9744
10421
|
return require2("pg");
|
|
9745
10422
|
} catch {
|
|
9746
10423
|
throw new Error(
|
|
@@ -9995,7 +10672,7 @@ function assertIdentifier(value, label) {
|
|
|
9995
10672
|
}
|
|
9996
10673
|
|
|
9997
10674
|
// packages/context/src/lib/stream/postgres.stream-store.ts
|
|
9998
|
-
import { createRequire as
|
|
10675
|
+
import { createRequire as createRequire5 } from "node:module";
|
|
9999
10676
|
|
|
10000
10677
|
// packages/context/src/lib/stream/ddl.stream.postgres.ts
|
|
10001
10678
|
function postgresStreamDDL(schema) {
|
|
@@ -10031,6 +10708,15 @@ CREATE INDEX IF NOT EXISTS "idx_${schema}_streams_status_created_at_id"
|
|
|
10031
10708
|
}
|
|
10032
10709
|
|
|
10033
10710
|
// packages/context/src/lib/stream/stream-store.ts
|
|
10711
|
+
function collectStreamFailures(chunks) {
|
|
10712
|
+
const failures = /* @__PURE__ */ new Map();
|
|
10713
|
+
for (const chunk of chunks) {
|
|
10714
|
+
if (chunk.data.type === "error" && !failures.has(chunk.streamId)) {
|
|
10715
|
+
failures.set(chunk.streamId, chunk.data.errorText);
|
|
10716
|
+
}
|
|
10717
|
+
}
|
|
10718
|
+
return [...failures].map(([streamId, error]) => ({ streamId, error }));
|
|
10719
|
+
}
|
|
10034
10720
|
var StreamStore = class {
|
|
10035
10721
|
async listRunningStreamIds() {
|
|
10036
10722
|
return this.listStreamIds({ status: "running" });
|
|
@@ -10060,7 +10746,7 @@ var PostgresStreamStore = class _PostgresStreamStore extends StreamStore {
|
|
|
10060
10746
|
}
|
|
10061
10747
|
static #requirePg() {
|
|
10062
10748
|
try {
|
|
10063
|
-
const require2 =
|
|
10749
|
+
const require2 = createRequire5(import.meta.url);
|
|
10064
10750
|
return require2("pg");
|
|
10065
10751
|
} catch {
|
|
10066
10752
|
throw new Error(
|
|
@@ -10214,13 +10900,31 @@ var PostgresStreamStore = class _PostgresStreamStore extends StreamStore {
|
|
|
10214
10900
|
data: chunk.data,
|
|
10215
10901
|
created_at: chunk.createdAt
|
|
10216
10902
|
}));
|
|
10217
|
-
|
|
10218
|
-
|
|
10903
|
+
const params = [JSON.stringify(rows)];
|
|
10904
|
+
const insertSql = `INSERT INTO ${this.#t("stream_chunks")} (stream_id, seq, data, created_at)
|
|
10219
10905
|
SELECT stream_id, seq, data, created_at
|
|
10220
10906
|
FROM jsonb_to_recordset($1::jsonb)
|
|
10221
|
-
AS rows(stream_id TEXT, seq INTEGER, data JSONB, created_at BIGINT)
|
|
10222
|
-
|
|
10223
|
-
)
|
|
10907
|
+
AS rows(stream_id TEXT, seq INTEGER, data JSONB, created_at BIGINT)`;
|
|
10908
|
+
const failures = collectStreamFailures(chunks);
|
|
10909
|
+
if (failures.length === 0) {
|
|
10910
|
+
await this.#query(insertSql, params);
|
|
10911
|
+
return;
|
|
10912
|
+
}
|
|
10913
|
+
await this.#useTransaction(async (client) => {
|
|
10914
|
+
await client.query(insertSql, params);
|
|
10915
|
+
const failedAt = Date.now();
|
|
10916
|
+
for (const failure of failures) {
|
|
10917
|
+
const result = await client.query(
|
|
10918
|
+
`UPDATE ${this.#t("streams")}
|
|
10919
|
+
SET status = $1, finished_at = $2, error = $3
|
|
10920
|
+
WHERE id = $4`,
|
|
10921
|
+
["failed", failedAt, failure.error, failure.streamId]
|
|
10922
|
+
);
|
|
10923
|
+
if (result.rowCount !== 1) {
|
|
10924
|
+
throw new Error(`Stream "${failure.streamId}" not found`);
|
|
10925
|
+
}
|
|
10926
|
+
}
|
|
10927
|
+
});
|
|
10224
10928
|
}
|
|
10225
10929
|
async getChunks(streamId, fromSeq, limit) {
|
|
10226
10930
|
const params = [streamId];
|
|
@@ -10467,6 +11171,7 @@ var SqliteStreamStore = class extends StreamStore {
|
|
|
10467
11171
|
}
|
|
10468
11172
|
async appendChunks(chunks) {
|
|
10469
11173
|
if (chunks.length === 0) return;
|
|
11174
|
+
const failures = collectStreamFailures(chunks);
|
|
10470
11175
|
this.#db.exec("BEGIN TRANSACTION");
|
|
10471
11176
|
try {
|
|
10472
11177
|
for (const chunk of chunks) {
|
|
@@ -10480,6 +11185,15 @@ var SqliteStreamStore = class extends StreamStore {
|
|
|
10480
11185
|
chunk.createdAt
|
|
10481
11186
|
);
|
|
10482
11187
|
}
|
|
11188
|
+
const failedAt = Date.now();
|
|
11189
|
+
for (const failure of failures) {
|
|
11190
|
+
const result = this.#stmt(
|
|
11191
|
+
"UPDATE streams SET status = ?, finishedAt = ?, error = ? WHERE id = ?"
|
|
11192
|
+
).run("failed", failedAt, failure.error, failure.streamId);
|
|
11193
|
+
if (result.changes !== 1) {
|
|
11194
|
+
throw new Error(`Stream "${failure.streamId}" not found`);
|
|
11195
|
+
}
|
|
11196
|
+
}
|
|
10483
11197
|
this.#db.exec("COMMIT");
|
|
10484
11198
|
} catch (error) {
|
|
10485
11199
|
this.#db.exec("ROLLBACK");
|
|
@@ -10881,14 +11595,20 @@ export {
|
|
|
10881
11595
|
AsyncResolver,
|
|
10882
11596
|
BM25Classifier,
|
|
10883
11597
|
BashException,
|
|
11598
|
+
BinInstaller,
|
|
10884
11599
|
ComposeStartError,
|
|
10885
11600
|
ComposeStrategy,
|
|
10886
11601
|
ContainerCreationError,
|
|
10887
11602
|
ContextEngine,
|
|
10888
11603
|
ContextRenderer,
|
|
10889
11604
|
ContextStore,
|
|
11605
|
+
DAYTONA_DEFAULT_DESTINATION,
|
|
10890
11606
|
DEFAULT_CANCEL_POLLING,
|
|
10891
11607
|
DEFAULT_WATCH_POLLING,
|
|
11608
|
+
DaytonaCommandError,
|
|
11609
|
+
DaytonaCreationError,
|
|
11610
|
+
DaytonaNotAvailableError,
|
|
11611
|
+
DaytonaSandboxError,
|
|
10892
11612
|
DockerNotAvailableError,
|
|
10893
11613
|
DockerSandboxError,
|
|
10894
11614
|
DockerSandboxStrategy,
|
|
@@ -10950,11 +11670,13 @@ export {
|
|
|
10950
11670
|
assertCountSpec,
|
|
10951
11671
|
assistant,
|
|
10952
11672
|
assistantText,
|
|
11673
|
+
bin,
|
|
10953
11674
|
buildSubcommandRepair,
|
|
10954
11675
|
chat,
|
|
10955
11676
|
checkCount,
|
|
10956
11677
|
clarification,
|
|
10957
11678
|
classifies,
|
|
11679
|
+
collectStreamFailures,
|
|
10958
11680
|
contentIncludes,
|
|
10959
11681
|
contentMatches,
|
|
10960
11682
|
contentPattern,
|
|
@@ -10963,7 +11685,7 @@ export {
|
|
|
10963
11685
|
createAgentOsSandbox,
|
|
10964
11686
|
createBashTool,
|
|
10965
11687
|
createBinaryBridges,
|
|
10966
|
-
|
|
11688
|
+
createDaytonaSandbox,
|
|
10967
11689
|
createDockerSandbox,
|
|
10968
11690
|
createInstallerContext,
|
|
10969
11691
|
createRepairToolCall,
|
|
@@ -11054,7 +11776,7 @@ export {
|
|
|
11054
11776
|
seasonChanged,
|
|
11055
11777
|
seasonReminder,
|
|
11056
11778
|
selfCritique,
|
|
11057
|
-
|
|
11779
|
+
shellQuote3 as shellQuote,
|
|
11058
11780
|
skills,
|
|
11059
11781
|
skillsReminder,
|
|
11060
11782
|
socraticPrompting,
|