zeitlich 0.2.36 → 0.2.38
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 +146 -92
- package/dist/{activities-BVI2lTwr.d.ts → activities-BKhMtKDd.d.ts} +4 -2
- package/dist/{activities-hd4aNnZE.d.cts → activities-CDcwkRZs.d.cts} +4 -2
- package/dist/adapters/sandbox/bedrock/index.cjs +17 -14
- package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/index.d.cts +7 -6
- package/dist/adapters/sandbox/bedrock/index.d.ts +7 -6
- package/dist/adapters/sandbox/bedrock/index.js +17 -14
- package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
- package/dist/adapters/sandbox/bedrock/workflow.cjs +2 -0
- package/dist/adapters/sandbox/bedrock/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
- package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
- package/dist/adapters/sandbox/bedrock/workflow.js +2 -0
- package/dist/adapters/sandbox/bedrock/workflow.js.map +1 -1
- package/dist/adapters/sandbox/daytona/index.cjs +11 -3
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +5 -4
- package/dist/adapters/sandbox/daytona/index.d.ts +5 -4
- package/dist/adapters/sandbox/daytona/index.js +11 -3
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.cjs +2 -0
- package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/daytona/workflow.js +2 -0
- package/dist/adapters/sandbox/daytona/workflow.js.map +1 -1
- package/dist/adapters/sandbox/e2b/index.cjs +73 -12
- package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/index.d.cts +26 -4
- package/dist/adapters/sandbox/e2b/index.d.ts +26 -4
- package/dist/adapters/sandbox/e2b/index.js +73 -12
- package/dist/adapters/sandbox/e2b/index.js.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.cjs +2 -0
- package/dist/adapters/sandbox/e2b/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/e2b/workflow.js +2 -0
- package/dist/adapters/sandbox/e2b/workflow.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs +8 -3
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +5 -4
- package/dist/adapters/sandbox/inmemory/index.d.ts +5 -4
- package/dist/adapters/sandbox/inmemory/index.js +8 -3
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.cjs +2 -0
- package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.js +2 -0
- package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -1
- package/dist/adapters/thread/anthropic/index.cjs +94 -39
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +5 -5
- package/dist/adapters/thread/anthropic/index.d.ts +5 -5
- package/dist/adapters/thread/anthropic/index.js +94 -39
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.cjs +7 -2
- package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
- package/dist/adapters/thread/anthropic/workflow.js +7 -2
- package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.cjs +77 -28
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +5 -5
- package/dist/adapters/thread/google-genai/index.d.ts +5 -5
- package/dist/adapters/thread/google-genai/index.js +77 -28
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.cjs +7 -2
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +5 -5
- package/dist/adapters/thread/google-genai/workflow.d.ts +5 -5
- package/dist/adapters/thread/google-genai/workflow.js +7 -2
- package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
- package/dist/adapters/thread/langchain/index.cjs +57 -10
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +5 -5
- package/dist/adapters/thread/langchain/index.d.ts +5 -5
- package/dist/adapters/thread/langchain/index.js +57 -10
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.cjs +7 -2
- package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
- package/dist/adapters/thread/langchain/workflow.js +7 -2
- package/dist/adapters/thread/langchain/workflow.js.map +1 -1
- package/dist/index.cjs +322 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -14
- package/dist/index.d.ts +20 -14
- package/dist/index.js +323 -147
- package/dist/index.js.map +1 -1
- package/dist/{proxy-BjdFGPTm.d.ts → proxy-CUlKSvZS.d.ts} +1 -1
- package/dist/{proxy-7RnVaPdJ.d.cts → proxy-D_3x7RN4.d.cts} +1 -1
- package/dist/{thread-manager-CbpiGq1L.d.ts → thread-manager-CVu7o2cs.d.ts} +4 -2
- package/dist/{thread-manager-DzXm9eeI.d.cts → thread-manager-HSwyh28L.d.cts} +4 -2
- package/dist/{thread-manager-BBzNgQWH.d.cts → thread-manager-c1gPopAG.d.ts} +4 -2
- package/dist/{thread-manager-DjN5JYul.d.ts → thread-manager-wGi-LqIP.d.cts} +4 -2
- package/dist/{types-Mc_4BCfT.d.cts → types-BH_IRryz.d.ts} +10 -1
- package/dist/{types-yiXmqedU.d.ts → types-BaOw4hKI.d.cts} +10 -1
- package/dist/{types-DQ1l_gXL.d.cts → types-C06FwR96.d.cts} +121 -17
- package/dist/{types-wiGLvxWf.d.ts → types-DAsQ21Rt.d.ts} +1 -1
- package/dist/{types-CADc5V_P.d.ts → types-DNr31FzL.d.ts} +121 -17
- package/dist/{types-CBH54cwr.d.cts → types-lm8tMNJQ.d.cts} +1 -1
- package/dist/{types-DxCpFNv_.d.cts → types-yx0LzPGn.d.cts} +44 -5
- package/dist/{types-DxCpFNv_.d.ts → types-yx0LzPGn.d.ts} +44 -5
- package/dist/{workflow-DhtWRovz.d.cts → workflow-CSCkpwAL.d.ts} +2 -2
- package/dist/{workflow-P2pTSfKu.d.ts → workflow-DuvMZ8Vm.d.cts} +2 -2
- package/dist/workflow.cjs +274 -130
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3 -3
- package/dist/workflow.d.ts +3 -3
- package/dist/workflow.js +275 -131
- package/dist/workflow.js.map +1 -1
- package/package.json +2 -2
- package/src/adapters/sandbox/bedrock/filesystem.ts +6 -12
- package/src/adapters/sandbox/bedrock/index.ts +22 -11
- package/src/adapters/sandbox/bedrock/proxy.ts +2 -0
- package/src/adapters/sandbox/daytona/index.ts +18 -3
- package/src/adapters/sandbox/daytona/proxy.ts +2 -0
- package/src/adapters/sandbox/e2b/filesystem.ts +5 -4
- package/src/adapters/sandbox/e2b/index.ts +87 -14
- package/src/adapters/sandbox/e2b/proxy.ts +2 -0
- package/src/adapters/sandbox/e2b/types.ts +16 -0
- package/src/adapters/sandbox/inmemory/index.ts +17 -3
- package/src/adapters/sandbox/inmemory/proxy.ts +2 -0
- package/src/adapters/thread/anthropic/activities.ts +58 -26
- package/src/adapters/thread/anthropic/model-invoker.ts +18 -7
- package/src/adapters/thread/anthropic/proxy.ts +6 -2
- package/src/adapters/thread/anthropic/thread-manager.test.ts +26 -7
- package/src/adapters/thread/anthropic/thread-manager.ts +63 -46
- package/src/adapters/thread/google-genai/activities.ts +20 -2
- package/src/adapters/thread/google-genai/model-invoker.ts +27 -7
- package/src/adapters/thread/google-genai/proxy.ts +6 -2
- package/src/adapters/thread/google-genai/thread-manager.test.ts +13 -3
- package/src/adapters/thread/google-genai/thread-manager.ts +57 -33
- package/src/adapters/thread/langchain/activities.ts +55 -24
- package/src/adapters/thread/langchain/hooks.test.ts +36 -49
- package/src/adapters/thread/langchain/hooks.ts +18 -5
- package/src/adapters/thread/langchain/model-invoker.ts +5 -4
- package/src/adapters/thread/langchain/proxy.ts +6 -2
- package/src/adapters/thread/langchain/thread-manager.test.ts +5 -1
- package/src/adapters/thread/langchain/thread-manager.ts +23 -9
- package/src/index.ts +4 -1
- package/src/lib/activity.ts +16 -6
- package/src/lib/hooks/types.ts +6 -6
- package/src/lib/lifecycle.ts +18 -3
- package/src/lib/model/proxy.ts +2 -2
- package/src/lib/model/types.ts +10 -0
- package/src/lib/observability/hooks.ts +4 -5
- package/src/lib/observability/index.ts +1 -4
- package/src/lib/sandbox/manager.ts +45 -20
- package/src/lib/sandbox/node-fs.ts +3 -6
- package/src/lib/sandbox/sandbox.test.ts +36 -3
- package/src/lib/sandbox/tree.integration.test.ts +10 -3
- package/src/lib/sandbox/types.ts +60 -6
- package/src/lib/session/session-edge-cases.integration.test.ts +316 -14
- package/src/lib/session/session.integration.test.ts +161 -1
- package/src/lib/session/session.ts +106 -21
- package/src/lib/session/types.ts +25 -5
- package/src/lib/skills/fs-provider.ts +12 -8
- package/src/lib/skills/handler.ts +1 -1
- package/src/lib/skills/parse.ts +3 -1
- package/src/lib/skills/register.ts +1 -3
- package/src/lib/skills/skills.integration.test.ts +25 -15
- package/src/lib/state/manager.integration.test.ts +12 -2
- package/src/lib/subagent/define.ts +1 -1
- package/src/lib/subagent/handler.ts +186 -71
- package/src/lib/subagent/index.ts +1 -5
- package/src/lib/subagent/register.ts +3 -2
- package/src/lib/subagent/signals.ts +1 -10
- package/src/lib/subagent/subagent.integration.test.ts +526 -248
- package/src/lib/subagent/tool.ts +4 -3
- package/src/lib/subagent/types.ts +50 -20
- package/src/lib/subagent/workflow.ts +9 -49
- package/src/lib/thread/id.test.ts +1 -1
- package/src/lib/thread/id.ts +1 -2
- package/src/lib/thread/manager.ts +18 -0
- package/src/lib/thread/proxy.ts +4 -4
- package/src/lib/thread/types.ts +20 -3
- package/src/lib/tool-router/index.ts +3 -5
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +93 -1
- package/src/lib/tool-router/router.integration.test.ts +12 -0
- package/src/lib/tool-router/router.ts +90 -16
- package/src/lib/tool-router/types.ts +45 -4
- package/src/lib/tool-router/with-sandbox.ts +19 -5
- package/src/lib/virtual-fs/filesystem.ts +1 -1
- package/src/lib/virtual-fs/index.ts +5 -1
- package/src/lib/virtual-fs/mutations.ts +2 -4
- package/src/lib/virtual-fs/queries.ts +9 -5
- package/src/lib/virtual-fs/types.ts +4 -1
- package/src/lib/virtual-fs/virtual-fs.test.ts +9 -11
- package/src/lib/workflow.test.ts +7 -4
- package/src/lib/workflow.ts +1 -5
- package/src/tools/ask-user-question/tool.ts +1 -3
- package/src/tools/glob/handler.ts +1 -4
- package/src/tools/task-get/handler.ts +4 -5
- package/src/tools/task-list/handler.ts +1 -4
- package/src/tools/task-update/handler.ts +4 -5
- package/src/workflow.ts +22 -7
- package/tsup.config.ts +9 -6
- package/src/lib/.env +0 -1
- package/src/tools/bash/.env +0 -1
package/dist/workflow.cjs
CHANGED
|
@@ -113,7 +113,7 @@ function createToolRouter(options) {
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
-
async function processToolCall(toolCall, turn, sandboxId) {
|
|
116
|
+
async function processToolCall(toolCall, turn, sandboxId, onRewindRequested) {
|
|
117
117
|
const startTime = Date.now();
|
|
118
118
|
const tool = toolMap.get(toolCall.name);
|
|
119
119
|
const preResult = await runPreHooks(toolCall, tool, turn);
|
|
@@ -128,7 +128,7 @@ function createToolRouter(options) {
|
|
|
128
128
|
reason: "Skipped by PreToolUse hook"
|
|
129
129
|
})
|
|
130
130
|
});
|
|
131
|
-
return
|
|
131
|
+
return { kind: "skipped" };
|
|
132
132
|
}
|
|
133
133
|
const effectiveArgs = preResult.args;
|
|
134
134
|
workflow.log.debug("tool call dispatched", {
|
|
@@ -140,6 +140,7 @@ function createToolRouter(options) {
|
|
|
140
140
|
let content;
|
|
141
141
|
let resultAppended = false;
|
|
142
142
|
let metadata;
|
|
143
|
+
let rewindRequested = false;
|
|
143
144
|
try {
|
|
144
145
|
if (tool) {
|
|
145
146
|
const routerContext = {
|
|
@@ -157,11 +158,15 @@ function createToolRouter(options) {
|
|
|
157
158
|
content = response.toolResponse;
|
|
158
159
|
resultAppended = response.resultAppended === true;
|
|
159
160
|
metadata = response.metadata;
|
|
161
|
+
rewindRequested = response.rewind === true;
|
|
160
162
|
} else {
|
|
161
163
|
result = { error: `Unknown tool: ${toolCall.name}` };
|
|
162
164
|
content = JSON.stringify(result, null, 2);
|
|
163
165
|
}
|
|
164
166
|
} catch (error) {
|
|
167
|
+
if (workflow.isCancellation(error)) {
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
165
170
|
workflow.log.warn("tool call failed", {
|
|
166
171
|
toolName: toolCall.name,
|
|
167
172
|
toolCallId: toolCall.id,
|
|
@@ -179,6 +184,15 @@ function createToolRouter(options) {
|
|
|
179
184
|
result = recovery.result;
|
|
180
185
|
content = recovery.content;
|
|
181
186
|
}
|
|
187
|
+
if (rewindRequested) {
|
|
188
|
+
const signal = {
|
|
189
|
+
toolCallId: toolCall.id,
|
|
190
|
+
toolName: toolCall.name
|
|
191
|
+
};
|
|
192
|
+
workflow.log.info("tool requested rewind", { ...signal });
|
|
193
|
+
onRewindRequested?.(signal);
|
|
194
|
+
return { kind: "rewind", signal };
|
|
195
|
+
}
|
|
182
196
|
if (!resultAppended) {
|
|
183
197
|
const config = {
|
|
184
198
|
threadId: options.threadId,
|
|
@@ -215,7 +229,7 @@ function createToolRouter(options) {
|
|
|
215
229
|
turn,
|
|
216
230
|
durationMs
|
|
217
231
|
);
|
|
218
|
-
return toolResult;
|
|
232
|
+
return { kind: "result", value: toolResult };
|
|
219
233
|
}
|
|
220
234
|
return {
|
|
221
235
|
hasTools() {
|
|
@@ -250,27 +264,59 @@ function createToolRouter(options) {
|
|
|
250
264
|
}));
|
|
251
265
|
},
|
|
252
266
|
async processToolCalls(toolCalls, context) {
|
|
267
|
+
const attachRewind = (arr, rewind) => {
|
|
268
|
+
if (rewind) {
|
|
269
|
+
arr.rewind = rewind;
|
|
270
|
+
}
|
|
271
|
+
return arr;
|
|
272
|
+
};
|
|
253
273
|
if (toolCalls.length === 0) {
|
|
254
|
-
return [];
|
|
274
|
+
return attachRewind([], void 0);
|
|
255
275
|
}
|
|
256
276
|
const turn = context?.turn ?? 0;
|
|
257
277
|
const sandboxId = context?.sandboxId;
|
|
278
|
+
let rewindSignal;
|
|
258
279
|
if (options.parallel) {
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
280
|
+
const scope = new workflow.CancellationScope({ cancellable: true });
|
|
281
|
+
const onRewindRequested = (signal) => {
|
|
282
|
+
if (!rewindSignal) {
|
|
283
|
+
rewindSignal = signal;
|
|
284
|
+
scope.cancel();
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
const outcomes = await scope.run(
|
|
288
|
+
async () => Promise.allSettled(
|
|
289
|
+
toolCalls.map(
|
|
290
|
+
(tc) => processToolCall(tc, turn, sandboxId, onRewindRequested)
|
|
291
|
+
)
|
|
292
|
+
)
|
|
264
293
|
);
|
|
294
|
+
const results2 = [];
|
|
295
|
+
for (const outcome of outcomes) {
|
|
296
|
+
if (outcome.status === "rejected") {
|
|
297
|
+
if (workflow.isCancellation(outcome.reason)) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
throw outcome.reason;
|
|
301
|
+
}
|
|
302
|
+
if (outcome.value.kind === "result") {
|
|
303
|
+
results2.push(outcome.value.value);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return attachRewind(results2, rewindSignal);
|
|
265
307
|
}
|
|
266
308
|
const results = [];
|
|
267
309
|
for (const toolCall of toolCalls) {
|
|
268
|
-
const
|
|
269
|
-
if (
|
|
270
|
-
|
|
310
|
+
const outcome = await processToolCall(toolCall, turn, sandboxId);
|
|
311
|
+
if (outcome.kind === "rewind") {
|
|
312
|
+
rewindSignal = outcome.signal;
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
if (outcome.kind === "result") {
|
|
316
|
+
results.push(outcome.value);
|
|
271
317
|
}
|
|
272
318
|
}
|
|
273
|
-
return results;
|
|
319
|
+
return attachRewind(results, rewindSignal);
|
|
274
320
|
},
|
|
275
321
|
async processToolCallsByName(toolCalls, toolName, handler, context) {
|
|
276
322
|
const matchingCalls = toolCalls.filter((tc) => tc.name === toolName);
|
|
@@ -391,9 +437,7 @@ function createSubagentTool(subagents) {
|
|
|
391
437
|
schema
|
|
392
438
|
};
|
|
393
439
|
}
|
|
394
|
-
var childResultSignal = workflow.defineSignal("childResult");
|
|
395
440
|
var childSandboxReadySignal = workflow.defineSignal("childSandboxReady");
|
|
396
|
-
var destroySandboxSignal = workflow.defineSignal("destroySandbox");
|
|
397
441
|
|
|
398
442
|
// src/lib/subagent/handler.ts
|
|
399
443
|
function resolveSandboxConfig(config) {
|
|
@@ -417,25 +461,27 @@ function resolveSandboxConfig(config) {
|
|
|
417
461
|
}
|
|
418
462
|
function createSubagentHandler(subagents) {
|
|
419
463
|
const { taskQueue: parentTaskQueue } = workflow.workflowInfo();
|
|
420
|
-
const
|
|
464
|
+
const agentSandboxOps = /* @__PURE__ */ new Map();
|
|
465
|
+
for (const cfg of subagents) {
|
|
466
|
+
if (cfg.sandbox && cfg.sandbox !== "none") {
|
|
467
|
+
agentSandboxOps.set(cfg.agentName, cfg.sandbox.proxy(cfg.agentName));
|
|
468
|
+
}
|
|
469
|
+
}
|
|
421
470
|
const pendingDestroys = /* @__PURE__ */ new Map();
|
|
422
471
|
const threadSandboxes = /* @__PURE__ */ new Map();
|
|
423
472
|
const persistentSandboxes = /* @__PURE__ */ new Map();
|
|
424
473
|
const persistentSandboxCreating = /* @__PURE__ */ new Set();
|
|
425
474
|
const lazyCreatorAgent = /* @__PURE__ */ new Map();
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
workflow.setHandler(
|
|
430
|
-
|
|
431
|
-
(
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
persistentSandboxes.set(agentName, sandboxId);
|
|
435
|
-
lazyCreatorAgent.delete(childWorkflowId);
|
|
436
|
-
}
|
|
475
|
+
const threadSnapshots = /* @__PURE__ */ new Map();
|
|
476
|
+
const persistentBaseSnapshot = /* @__PURE__ */ new Map();
|
|
477
|
+
const persistentBaseSnapshotCreating = /* @__PURE__ */ new Set();
|
|
478
|
+
workflow.setHandler(childSandboxReadySignal, ({ childWorkflowId, sandboxId }) => {
|
|
479
|
+
const agentName = lazyCreatorAgent.get(childWorkflowId);
|
|
480
|
+
if (agentName && !persistentSandboxes.has(agentName)) {
|
|
481
|
+
persistentSandboxes.set(agentName, sandboxId);
|
|
482
|
+
lazyCreatorAgent.delete(childWorkflowId);
|
|
437
483
|
}
|
|
438
|
-
);
|
|
484
|
+
});
|
|
439
485
|
const handler = async (args, context) => {
|
|
440
486
|
const config = subagents.find((s) => s.agentName === args.subagent);
|
|
441
487
|
if (!config) {
|
|
@@ -446,6 +492,12 @@ function createSubagentHandler(subagents) {
|
|
|
446
492
|
const childWorkflowId = `${args.subagent}-${getShortId()}`;
|
|
447
493
|
const { sandboxId: parentSandboxId } = context;
|
|
448
494
|
const sandboxCfg = resolveSandboxConfig(config.sandbox);
|
|
495
|
+
if (sandboxCfg.source !== "none" && !agentSandboxOps.has(config.agentName)) {
|
|
496
|
+
throw workflow.ApplicationFailure.create({
|
|
497
|
+
message: `Subagent "${config.agentName}" uses a sandbox but no \`sandbox.proxy\` is configured on its SubagentConfig`,
|
|
498
|
+
nonRetryable: true
|
|
499
|
+
});
|
|
500
|
+
}
|
|
449
501
|
if (sandboxCfg.source === "inherit" && !parentSandboxId) {
|
|
450
502
|
throw new Error(
|
|
451
503
|
`Subagent "${config.agentName}" is configured with sandbox: "inherit" but the parent has no sandbox`
|
|
@@ -464,12 +516,39 @@ function createSubagentHandler(subagents) {
|
|
|
464
516
|
let sandbox;
|
|
465
517
|
let sandboxShutdownOverride;
|
|
466
518
|
let isLazyCreator = false;
|
|
519
|
+
let isSnapshotBaseCreator = false;
|
|
467
520
|
if (sandboxCfg.source === "inherit" && parentSandboxId) {
|
|
468
521
|
if (sandboxCfg.continuation === "fork") {
|
|
469
522
|
sandbox = { mode: "fork", sandboxId: parentSandboxId };
|
|
523
|
+
} else if (sandboxCfg.continuation === "snapshot") {
|
|
524
|
+
throw new Error(
|
|
525
|
+
`Subagent "${config.agentName}" has sandbox source "inherit" with continuation "snapshot" \u2014 snapshot continuation is only supported for source "own"`
|
|
526
|
+
);
|
|
470
527
|
} else {
|
|
471
528
|
sandbox = { mode: "inherit", sandboxId: parentSandboxId };
|
|
472
529
|
}
|
|
530
|
+
} else if (sandboxCfg.source === "own" && sandboxCfg.continuation === "snapshot") {
|
|
531
|
+
const isLazy = sandboxCfg.init === "once";
|
|
532
|
+
let baseSnap;
|
|
533
|
+
if (continuationThreadId) {
|
|
534
|
+
baseSnap = threadSnapshots.get(continuationThreadId)?.snapshot;
|
|
535
|
+
}
|
|
536
|
+
if (!baseSnap && isLazy) {
|
|
537
|
+
baseSnap = persistentBaseSnapshot.get(config.agentName);
|
|
538
|
+
if (!baseSnap) {
|
|
539
|
+
if (persistentBaseSnapshotCreating.has(config.agentName)) {
|
|
540
|
+
await workflow.condition(() => persistentBaseSnapshot.has(config.agentName));
|
|
541
|
+
baseSnap = persistentBaseSnapshot.get(config.agentName);
|
|
542
|
+
} else {
|
|
543
|
+
persistentBaseSnapshotCreating.add(config.agentName);
|
|
544
|
+
isSnapshotBaseCreator = true;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
if (baseSnap) {
|
|
549
|
+
sandbox = { mode: "from-snapshot", snapshot: baseSnap };
|
|
550
|
+
}
|
|
551
|
+
sandboxShutdownOverride = "snapshot";
|
|
473
552
|
} else if (sandboxCfg.source === "own") {
|
|
474
553
|
const isLazy = sandboxCfg.init === "once";
|
|
475
554
|
let baseSandboxId;
|
|
@@ -520,31 +599,8 @@ function createSubagentHandler(subagents) {
|
|
|
520
599
|
threadMode,
|
|
521
600
|
sandboxSource: sandboxCfg.source
|
|
522
601
|
});
|
|
523
|
-
const
|
|
602
|
+
const childResult = await workflow.executeChild(config.workflow, childOpts);
|
|
524
603
|
const effectiveShutdown = sandboxShutdownOverride ?? sandboxCfg.shutdown ?? "destroy";
|
|
525
|
-
if (effectiveShutdown === "pause-until-parent-close" || effectiveShutdown === "keep-until-parent-close") {
|
|
526
|
-
const key = isLazyCreator ? `persistent:${config.agentName}` : childWorkflowId;
|
|
527
|
-
pendingDestroys.set(key, childHandle);
|
|
528
|
-
}
|
|
529
|
-
await Promise.race([
|
|
530
|
-
workflow.condition(() => childResults.has(childWorkflowId)),
|
|
531
|
-
childHandle.result()
|
|
532
|
-
]);
|
|
533
|
-
if (!childResults.has(childWorkflowId)) {
|
|
534
|
-
await workflow.condition(() => childResults.has(childWorkflowId));
|
|
535
|
-
}
|
|
536
|
-
const childResult = childResults.get(childWorkflowId);
|
|
537
|
-
childResults.delete(childWorkflowId);
|
|
538
|
-
if (!childResult) {
|
|
539
|
-
workflow.log.warn("subagent returned no result", {
|
|
540
|
-
subagent: config.agentName,
|
|
541
|
-
childWorkflowId
|
|
542
|
-
});
|
|
543
|
-
return {
|
|
544
|
-
toolResponse: "Subagent workflow did not signal a result",
|
|
545
|
-
data: null
|
|
546
|
-
};
|
|
547
|
-
}
|
|
548
604
|
workflow.log.info("subagent completed", {
|
|
549
605
|
subagent: config.agentName,
|
|
550
606
|
childWorkflowId,
|
|
@@ -556,19 +612,42 @@ function createSubagentHandler(subagents) {
|
|
|
556
612
|
usage,
|
|
557
613
|
threadId: childThreadId,
|
|
558
614
|
sandboxId: childSandboxId,
|
|
615
|
+
snapshot: childSnapshot,
|
|
616
|
+
baseSnapshot: childBaseSnapshot,
|
|
559
617
|
metadata
|
|
560
618
|
} = childResult;
|
|
561
619
|
if (childSandboxId) {
|
|
562
|
-
if (sandboxCfg.source === "own" && sandboxCfg.init === "once" && !persistentSandboxes.has(config.agentName)) {
|
|
620
|
+
if (sandboxCfg.source === "own" && sandboxCfg.init === "once" && sandboxCfg.continuation !== "snapshot" && !persistentSandboxes.has(config.agentName)) {
|
|
563
621
|
persistentSandboxes.set(config.agentName, childSandboxId);
|
|
564
|
-
} else if (allowsContinuation && childThreadId) {
|
|
622
|
+
} else if (allowsContinuation && childThreadId && sandboxCfg.source === "own" && sandboxCfg.continuation !== "snapshot") {
|
|
565
623
|
threadSandboxes.set(childThreadId, childSandboxId);
|
|
566
624
|
}
|
|
567
625
|
}
|
|
626
|
+
if (childSandboxId && (effectiveShutdown === "pause-until-parent-close" || effectiveShutdown === "keep-until-parent-close")) {
|
|
627
|
+
const key = isLazyCreator ? `persistent:${config.agentName}` : childWorkflowId;
|
|
628
|
+
pendingDestroys.set(key, {
|
|
629
|
+
agentName: config.agentName,
|
|
630
|
+
sandboxId: childSandboxId
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
if (sandboxCfg.source === "own" && sandboxCfg.continuation === "snapshot") {
|
|
634
|
+
if (childSnapshot && childThreadId) {
|
|
635
|
+
threadSnapshots.set(childThreadId, {
|
|
636
|
+
agentName: config.agentName,
|
|
637
|
+
snapshot: childSnapshot
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
if (isSnapshotBaseCreator && childBaseSnapshot && !persistentBaseSnapshot.has(config.agentName)) {
|
|
641
|
+
persistentBaseSnapshot.set(config.agentName, childBaseSnapshot);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
568
644
|
if (isLazyCreator) {
|
|
569
645
|
persistentSandboxCreating.delete(config.agentName);
|
|
570
646
|
lazyCreatorAgent.delete(childWorkflowId);
|
|
571
647
|
}
|
|
648
|
+
if (isSnapshotBaseCreator) {
|
|
649
|
+
persistentBaseSnapshotCreating.delete(config.agentName);
|
|
650
|
+
}
|
|
572
651
|
if (!toolResponse) {
|
|
573
652
|
return {
|
|
574
653
|
toolResponse: "Subagent workflow returned no response",
|
|
@@ -604,22 +683,60 @@ function createSubagentHandler(subagents) {
|
|
|
604
683
|
};
|
|
605
684
|
};
|
|
606
685
|
const destroySubagentSandboxes = async () => {
|
|
607
|
-
const
|
|
686
|
+
const entries = [...pendingDestroys.values()];
|
|
608
687
|
pendingDestroys.clear();
|
|
609
688
|
await Promise.all(
|
|
610
|
-
|
|
689
|
+
entries.map(async ({ agentName, sandboxId }) => {
|
|
690
|
+
const ops = agentSandboxOps.get(agentName);
|
|
691
|
+
if (!ops) {
|
|
692
|
+
workflow.log.warn(
|
|
693
|
+
"Skipping sandbox destroy \u2014 no sandbox.proxy registered for agent",
|
|
694
|
+
{ agentName, sandboxId }
|
|
695
|
+
);
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
try {
|
|
699
|
+
await ops.destroySandbox(sandboxId);
|
|
700
|
+
} catch (err) {
|
|
701
|
+
workflow.log.warn("Failed to destroy subagent sandbox", {
|
|
702
|
+
agentName,
|
|
703
|
+
sandboxId,
|
|
704
|
+
error: err
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
})
|
|
708
|
+
);
|
|
709
|
+
};
|
|
710
|
+
const cleanupSubagentSnapshots = async () => {
|
|
711
|
+
const tagged = [];
|
|
712
|
+
for (const entry of threadSnapshots.values()) tagged.push(entry);
|
|
713
|
+
for (const [agentName, snapshot] of persistentBaseSnapshot.entries()) {
|
|
714
|
+
tagged.push({ agentName, snapshot });
|
|
715
|
+
}
|
|
716
|
+
threadSnapshots.clear();
|
|
717
|
+
persistentBaseSnapshot.clear();
|
|
718
|
+
await Promise.all(
|
|
719
|
+
tagged.map(async ({ agentName, snapshot }) => {
|
|
720
|
+
const ops = agentSandboxOps.get(agentName);
|
|
721
|
+
if (!ops) {
|
|
722
|
+
workflow.log.warn(
|
|
723
|
+
"Skipping snapshot delete \u2014 no sandbox.proxy registered for agent",
|
|
724
|
+
{ agentName }
|
|
725
|
+
);
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
611
728
|
try {
|
|
612
|
-
await
|
|
613
|
-
await handle.result();
|
|
729
|
+
await ops.deleteSandboxSnapshot(snapshot);
|
|
614
730
|
} catch (err) {
|
|
615
|
-
workflow.log.warn("Failed to
|
|
731
|
+
workflow.log.warn("Failed to delete subagent snapshot", {
|
|
732
|
+
agentName,
|
|
616
733
|
error: err
|
|
617
734
|
});
|
|
618
735
|
}
|
|
619
736
|
})
|
|
620
737
|
);
|
|
621
738
|
};
|
|
622
|
-
return { handler, destroySubagentSandboxes };
|
|
739
|
+
return { handler, destroySubagentSandboxes, cleanupSubagentSnapshots };
|
|
623
740
|
}
|
|
624
741
|
|
|
625
742
|
// src/lib/subagent/register.ts
|
|
@@ -633,7 +750,7 @@ function buildSubagentRegistration(subagents) {
|
|
|
633
750
|
if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
|
|
634
751
|
}
|
|
635
752
|
const resolveSubagentName = (args) => args.subagent;
|
|
636
|
-
const { handler, destroySubagentSandboxes } = createSubagentHandler(subagents);
|
|
753
|
+
const { handler, destroySubagentSandboxes, cleanupSubagentSnapshots } = createSubagentHandler(subagents);
|
|
637
754
|
const registration = {
|
|
638
755
|
name: SUBAGENT_TOOL_NAME,
|
|
639
756
|
enabled: () => getEnabled().length > 0,
|
|
@@ -657,7 +774,7 @@ function buildSubagentRegistration(subagents) {
|
|
|
657
774
|
}
|
|
658
775
|
}
|
|
659
776
|
};
|
|
660
|
-
return { registration, destroySubagentSandboxes };
|
|
777
|
+
return { registration, destroySubagentSandboxes, cleanupSubagentSnapshots };
|
|
661
778
|
}
|
|
662
779
|
var READ_SKILL_TOOL_NAME = "ReadSkill";
|
|
663
780
|
function buildReadSkillDescription(skills) {
|
|
@@ -730,9 +847,7 @@ function validateSkillNames(skills) {
|
|
|
730
847
|
const names = skills.map((s) => s.name);
|
|
731
848
|
const dupes = names.filter((n, i) => names.indexOf(n) !== i);
|
|
732
849
|
if (dupes.length > 0) {
|
|
733
|
-
throw new Error(
|
|
734
|
-
`Duplicate skill names: ${[...new Set(dupes)].join(", ")}`
|
|
735
|
-
);
|
|
850
|
+
throw new Error(`Duplicate skill names: ${[...new Set(dupes)].join(", ")}`);
|
|
736
851
|
}
|
|
737
852
|
}
|
|
738
853
|
function buildSkillRegistration(skills) {
|
|
@@ -798,15 +913,18 @@ async function createSession({
|
|
|
798
913
|
initializeThread,
|
|
799
914
|
appendSystemMessage,
|
|
800
915
|
appendAgentMessage,
|
|
801
|
-
forkThread
|
|
916
|
+
forkThread,
|
|
917
|
+
truncateThread
|
|
802
918
|
} = threadOps;
|
|
803
919
|
const plugins = [];
|
|
804
920
|
let destroySubagentSandboxes;
|
|
921
|
+
let cleanupSubagentSnapshots;
|
|
805
922
|
if (subagents) {
|
|
806
923
|
const result = buildSubagentRegistration(subagents);
|
|
807
924
|
if (result) {
|
|
808
925
|
plugins.push(result.registration);
|
|
809
926
|
destroySubagentSandboxes = result.destroySubagentSandboxes;
|
|
927
|
+
cleanupSubagentSnapshots = result.cleanupSubagentSnapshots;
|
|
810
928
|
}
|
|
811
929
|
}
|
|
812
930
|
if (skills) {
|
|
@@ -859,6 +977,9 @@ async function createSession({
|
|
|
859
977
|
const sandboxMode = sandboxInit?.mode;
|
|
860
978
|
let sandboxId;
|
|
861
979
|
let sandboxOwned = false;
|
|
980
|
+
let baseSnapshot;
|
|
981
|
+
let exitSnapshot;
|
|
982
|
+
let freshlyCreated = false;
|
|
862
983
|
if (sandboxMode === "inherit") {
|
|
863
984
|
const inheritInit = sandboxInit;
|
|
864
985
|
sandboxId = inheritInit.sandboxId;
|
|
@@ -887,8 +1008,23 @@ async function createSession({
|
|
|
887
1008
|
nonRetryable: true
|
|
888
1009
|
});
|
|
889
1010
|
}
|
|
1011
|
+
const forkInit = sandboxInit;
|
|
890
1012
|
sandboxId = await sandboxOps.forkSandbox(
|
|
891
|
-
|
|
1013
|
+
forkInit.sandboxId,
|
|
1014
|
+
forkInit.options
|
|
1015
|
+
);
|
|
1016
|
+
sandboxOwned = true;
|
|
1017
|
+
} else if (sandboxMode === "from-snapshot") {
|
|
1018
|
+
if (!sandboxOps) {
|
|
1019
|
+
throw workflow.ApplicationFailure.create({
|
|
1020
|
+
message: "No sandboxOps provided \u2014 cannot restore sandbox",
|
|
1021
|
+
nonRetryable: true
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
const restoreInit = sandboxInit;
|
|
1025
|
+
sandboxId = await sandboxOps.restoreSandbox(
|
|
1026
|
+
restoreInit.snapshot,
|
|
1027
|
+
restoreInit.options
|
|
892
1028
|
);
|
|
893
1029
|
sandboxOwned = true;
|
|
894
1030
|
} else if (sandboxOps) {
|
|
@@ -899,9 +1035,13 @@ async function createSession({
|
|
|
899
1035
|
if (result) {
|
|
900
1036
|
sandboxId = result.sandboxId;
|
|
901
1037
|
sandboxOwned = true;
|
|
1038
|
+
freshlyCreated = true;
|
|
902
1039
|
}
|
|
903
1040
|
}
|
|
904
|
-
if (sandboxId &&
|
|
1041
|
+
if (sandboxId && sandboxOwned && freshlyCreated && sandboxShutdown === "snapshot" && sandboxOps) {
|
|
1042
|
+
baseSnapshot = await sandboxOps.snapshotSandbox(sandboxId);
|
|
1043
|
+
}
|
|
1044
|
+
if (sandboxId && sandboxOwned && onSandboxReady) {
|
|
905
1045
|
onSandboxReady(sandboxId);
|
|
906
1046
|
}
|
|
907
1047
|
if (virtualFsConfig) {
|
|
@@ -967,18 +1107,25 @@ async function createSession({
|
|
|
967
1107
|
threadKey
|
|
968
1108
|
);
|
|
969
1109
|
let exitReason = "completed";
|
|
1110
|
+
let finalMessage = null;
|
|
970
1111
|
try {
|
|
971
1112
|
while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
|
|
972
1113
|
stateManager.incrementTurns();
|
|
973
1114
|
const currentTurn = stateManager.getTurns();
|
|
974
1115
|
workflow.log.debug("turn started", { agentName, threadId, turn: currentTurn });
|
|
975
1116
|
stateManager.setTools(toolRouter.getToolDefinitions());
|
|
976
|
-
const {
|
|
1117
|
+
const {
|
|
1118
|
+
message,
|
|
1119
|
+
rawToolCalls,
|
|
1120
|
+
usage,
|
|
1121
|
+
threadLengthAtCall
|
|
1122
|
+
} = await runAgent({
|
|
977
1123
|
threadId,
|
|
978
1124
|
threadKey,
|
|
979
1125
|
agentName,
|
|
980
1126
|
metadata
|
|
981
1127
|
});
|
|
1128
|
+
const preAssistantLength = threadLengthAtCall;
|
|
982
1129
|
await appendAgentMessage(threadId, workflow.uuid4(), message, threadKey);
|
|
983
1130
|
if (usage) {
|
|
984
1131
|
stateManager.updateUsage(usage);
|
|
@@ -993,21 +1140,8 @@ async function createSession({
|
|
|
993
1140
|
if (!toolRouter.hasTools() || rawToolCalls.length === 0) {
|
|
994
1141
|
stateManager.complete();
|
|
995
1142
|
exitReason = "completed";
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
threadId,
|
|
999
|
-
exitReason,
|
|
1000
|
-
turns: currentTurn,
|
|
1001
|
-
durationMs: Date.now() - sessionStartMs,
|
|
1002
|
-
usage: stateManager.getTotalUsage()
|
|
1003
|
-
});
|
|
1004
|
-
return {
|
|
1005
|
-
threadId,
|
|
1006
|
-
finalMessage: message,
|
|
1007
|
-
exitReason,
|
|
1008
|
-
usage: stateManager.getTotalUsage(),
|
|
1009
|
-
sandboxId
|
|
1010
|
-
};
|
|
1143
|
+
finalMessage = message;
|
|
1144
|
+
break;
|
|
1011
1145
|
}
|
|
1012
1146
|
const parsedToolCalls = [];
|
|
1013
1147
|
for (const tc of rawToolCalls) {
|
|
@@ -1037,6 +1171,24 @@ async function createSession({
|
|
|
1037
1171
|
stateManager.updateUsage(result.usage);
|
|
1038
1172
|
}
|
|
1039
1173
|
}
|
|
1174
|
+
const rewind = toolCallResults.rewind;
|
|
1175
|
+
if (rewind) {
|
|
1176
|
+
workflow.log.info("rewinding turn", {
|
|
1177
|
+
agentName,
|
|
1178
|
+
threadId,
|
|
1179
|
+
turn: currentTurn,
|
|
1180
|
+
toolCallId: rewind.toolCallId,
|
|
1181
|
+
toolName: rewind.toolName
|
|
1182
|
+
});
|
|
1183
|
+
if (preAssistantLength === void 0) {
|
|
1184
|
+
throw workflow.ApplicationFailure.create({
|
|
1185
|
+
message: "Rewind requested but runAgent did not report `threadLengthAtCall`; the adapter must populate it to support rewinds.",
|
|
1186
|
+
nonRetryable: true
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
await truncateThread(threadId, preAssistantLength, threadKey);
|
|
1190
|
+
continue;
|
|
1191
|
+
}
|
|
1040
1192
|
if (stateManager.getStatus() === "WAITING_FOR_INPUT") {
|
|
1041
1193
|
const conditionMet = await workflow.condition(
|
|
1042
1194
|
() => stateManager.getStatus() === "RUNNING",
|
|
@@ -1079,11 +1231,21 @@ async function createSession({
|
|
|
1079
1231
|
case "pause-until-parent-close":
|
|
1080
1232
|
await sandboxOps.pauseSandbox(sandboxId);
|
|
1081
1233
|
break;
|
|
1234
|
+
case "keep":
|
|
1235
|
+
case "keep-until-parent-close":
|
|
1236
|
+
break;
|
|
1237
|
+
case "snapshot":
|
|
1238
|
+
exitSnapshot = await sandboxOps.snapshotSandbox(sandboxId);
|
|
1239
|
+
await sandboxOps.destroySandbox(sandboxId);
|
|
1240
|
+
break;
|
|
1082
1241
|
}
|
|
1083
1242
|
}
|
|
1084
1243
|
if (destroySubagentSandboxes) {
|
|
1085
1244
|
await destroySubagentSandboxes();
|
|
1086
1245
|
}
|
|
1246
|
+
if (cleanupSubagentSnapshots) {
|
|
1247
|
+
await cleanupSubagentSnapshots();
|
|
1248
|
+
}
|
|
1087
1249
|
}
|
|
1088
1250
|
workflow.log.info("session ended", {
|
|
1089
1251
|
agentName,
|
|
@@ -1091,14 +1253,18 @@ async function createSession({
|
|
|
1091
1253
|
exitReason,
|
|
1092
1254
|
turns: stateManager.getTurns(),
|
|
1093
1255
|
durationMs: Date.now() - sessionStartMs,
|
|
1094
|
-
usage: stateManager.getTotalUsage()
|
|
1256
|
+
usage: stateManager.getTotalUsage(),
|
|
1257
|
+
...baseSnapshot && { hasBaseSnapshot: true },
|
|
1258
|
+
...exitSnapshot && { hasExitSnapshot: true }
|
|
1095
1259
|
});
|
|
1096
1260
|
return {
|
|
1097
1261
|
threadId,
|
|
1098
|
-
finalMessage
|
|
1262
|
+
finalMessage,
|
|
1099
1263
|
exitReason,
|
|
1100
1264
|
usage: stateManager.getTotalUsage(),
|
|
1101
|
-
sandboxId
|
|
1265
|
+
sandboxId,
|
|
1266
|
+
...baseSnapshot && { baseSnapshot },
|
|
1267
|
+
...exitSnapshot && { snapshot: exitSnapshot }
|
|
1102
1268
|
};
|
|
1103
1269
|
}
|
|
1104
1270
|
};
|
|
@@ -1309,44 +1475,16 @@ function defineSubagentWorkflow(config, fn) {
|
|
|
1309
1475
|
...workflowInput.thread && { thread: workflowInput.thread },
|
|
1310
1476
|
...workflowInput.sandbox && { sandbox: workflowInput.sandbox },
|
|
1311
1477
|
onSandboxReady: (sandboxId) => {
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1478
|
+
const isReuse = workflowInput.sandbox?.mode === "continue";
|
|
1479
|
+
if (!isReuse) {
|
|
1480
|
+
void parentHandle.signal(childSandboxReadySignal, {
|
|
1481
|
+
childWorkflowId: workflow.workflowInfo().workflowId,
|
|
1482
|
+
sandboxId
|
|
1483
|
+
});
|
|
1484
|
+
}
|
|
1316
1485
|
}
|
|
1317
1486
|
};
|
|
1318
|
-
|
|
1319
|
-
prompt,
|
|
1320
|
-
sessionInput,
|
|
1321
|
-
context ?? {}
|
|
1322
|
-
);
|
|
1323
|
-
if (effectiveShutdown === "pause-until-parent-close" || effectiveShutdown === "keep-until-parent-close") {
|
|
1324
|
-
if (!destroySandbox) {
|
|
1325
|
-
throw workflow.ApplicationFailure.create({
|
|
1326
|
-
message: `Subagent "${config.name}" has sandboxShutdown="${effectiveShutdown}" but fn did not return a destroySandbox callback`,
|
|
1327
|
-
nonRetryable: true
|
|
1328
|
-
});
|
|
1329
|
-
}
|
|
1330
|
-
if (!result.sandboxId) {
|
|
1331
|
-
throw workflow.ApplicationFailure.create({
|
|
1332
|
-
message: `Subagent "${config.name}" has sandboxShutdown="${effectiveShutdown}" but fn did not return a sandboxId`,
|
|
1333
|
-
nonRetryable: true
|
|
1334
|
-
});
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
await parentHandle.signal(childResultSignal, {
|
|
1338
|
-
childWorkflowId: workflow.workflowInfo().workflowId,
|
|
1339
|
-
result
|
|
1340
|
-
});
|
|
1341
|
-
if (destroySandbox) {
|
|
1342
|
-
let destroyRequested = false;
|
|
1343
|
-
workflow.setHandler(destroySandboxSignal, () => {
|
|
1344
|
-
destroyRequested = true;
|
|
1345
|
-
});
|
|
1346
|
-
await workflow.condition(() => destroyRequested);
|
|
1347
|
-
await destroySandbox();
|
|
1348
|
-
}
|
|
1349
|
-
return result;
|
|
1487
|
+
return fn(prompt, sessionInput, context ?? {});
|
|
1350
1488
|
};
|
|
1351
1489
|
Object.defineProperty(workflow$1, "name", { value: config.name });
|
|
1352
1490
|
return Object.assign(workflow$1, {
|
|
@@ -1456,9 +1594,7 @@ function applyVirtualTreeMutations(stateManager, mutations) {
|
|
|
1456
1594
|
tree = tree.filter((e) => e.path !== m.path);
|
|
1457
1595
|
break;
|
|
1458
1596
|
case "update":
|
|
1459
|
-
tree = tree.map(
|
|
1460
|
-
(e) => e.path === m.path ? { ...e, ...m.entry } : e
|
|
1461
|
-
);
|
|
1597
|
+
tree = tree.map((e) => e.path === m.path ? { ...e, ...m.entry } : e);
|
|
1462
1598
|
break;
|
|
1463
1599
|
}
|
|
1464
1600
|
}
|
|
@@ -1517,7 +1653,9 @@ function formatVirtualFileTree(entries, opts = {}) {
|
|
|
1517
1653
|
// src/lib/virtual-fs/queries.ts
|
|
1518
1654
|
function hasFileWithMimeType(stateManager, pattern) {
|
|
1519
1655
|
const tree = stateManager.get("fileTree");
|
|
1520
|
-
const matchers = (Array.isArray(pattern) ? pattern : [pattern]).map(
|
|
1656
|
+
const matchers = (Array.isArray(pattern) ? pattern : [pattern]).map(
|
|
1657
|
+
buildMatcher
|
|
1658
|
+
);
|
|
1521
1659
|
return tree.some((entry) => {
|
|
1522
1660
|
const meta = entry.metadata;
|
|
1523
1661
|
const mime = meta?.mimeType;
|
|
@@ -1578,7 +1716,9 @@ function proxyVirtualFsOps(scope, options) {
|
|
|
1578
1716
|
// src/lib/skills/parse.ts
|
|
1579
1717
|
function parseSkillFile(raw) {
|
|
1580
1718
|
const trimmed = raw.replace(/^\uFEFF/, "");
|
|
1581
|
-
const match = trimmed.match(
|
|
1719
|
+
const match = trimmed.match(
|
|
1720
|
+
/^---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*\r?\n?([\s\S]*)$/
|
|
1721
|
+
);
|
|
1582
1722
|
if (!match) {
|
|
1583
1723
|
throw new Error(
|
|
1584
1724
|
"SKILL.md must start with YAML frontmatter delimited by ---"
|
|
@@ -1850,7 +1990,9 @@ function createTaskGetHandler(stateManager) {
|
|
|
1850
1990
|
const task = stateManager.getTask(args.taskId) ?? null;
|
|
1851
1991
|
if (!task) {
|
|
1852
1992
|
return {
|
|
1853
|
-
toolResponse: JSON.stringify({
|
|
1993
|
+
toolResponse: JSON.stringify({
|
|
1994
|
+
error: `Task not found: ${args.taskId}`
|
|
1995
|
+
}),
|
|
1854
1996
|
data: null
|
|
1855
1997
|
};
|
|
1856
1998
|
}
|
|
@@ -1893,7 +2035,9 @@ function createTaskUpdateHandler(stateManager) {
|
|
|
1893
2035
|
const task = stateManager.getTask(args.taskId);
|
|
1894
2036
|
if (!task) {
|
|
1895
2037
|
return {
|
|
1896
|
-
toolResponse: JSON.stringify({
|
|
2038
|
+
toolResponse: JSON.stringify({
|
|
2039
|
+
error: `Task not found: ${args.taskId}`
|
|
2040
|
+
}),
|
|
1897
2041
|
data: null
|
|
1898
2042
|
};
|
|
1899
2043
|
}
|