zeitlich 0.2.37 → 0.2.39
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 -0
- package/dist/{activities-Bb-nAjwQ.d.ts → activities-Bmu7XnaG.d.ts} +4 -4
- package/dist/{activities-vkI4_3CC.d.cts → activities-ByBFLvm2.d.cts} +4 -4
- package/dist/adapter-id-BB-mmrts.d.cts +17 -0
- package/dist/adapter-id-BB-mmrts.d.ts +17 -0
- package/dist/adapter-id-CMwVrVqv.d.cts +17 -0
- package/dist/adapter-id-CMwVrVqv.d.ts +17 -0
- package/dist/adapter-id-CbY2zeSt.d.cts +17 -0
- package/dist/adapter-id-CbY2zeSt.d.ts +17 -0
- package/dist/adapters/sandbox/bedrock/index.cjs +3 -3
- package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/index.d.cts +6 -6
- package/dist/adapters/sandbox/bedrock/index.d.ts +6 -6
- package/dist/adapters/sandbox/bedrock/index.js +3 -3
- package/dist/adapters/sandbox/bedrock/index.js.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/daytona/index.cjs +3 -3
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +4 -4
- package/dist/adapters/sandbox/daytona/index.d.ts +4 -4
- package/dist/adapters/sandbox/daytona/index.js +3 -3
- package/dist/adapters/sandbox/daytona/index.js.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/e2b/index.cjs +26 -14
- package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/index.d.cts +24 -4
- package/dist/adapters/sandbox/e2b/index.d.ts +24 -4
- package/dist/adapters/sandbox/e2b/index.js +26 -14
- package/dist/adapters/sandbox/e2b/index.js.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/inmemory/index.cjs +3 -3
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +4 -4
- package/dist/adapters/sandbox/inmemory/index.d.ts +4 -4
- package/dist/adapters/sandbox/inmemory/index.js +3 -3
- package/dist/adapters/sandbox/inmemory/index.js.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/thread/anthropic/index.cjs +150 -13
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +9 -8
- package/dist/adapters/thread/anthropic/index.d.ts +9 -8
- package/dist/adapters/thread/anthropic/index.js +150 -14
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.cjs +9 -3
- package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +6 -5
- package/dist/adapters/thread/anthropic/workflow.d.ts +6 -5
- package/dist/adapters/thread/anthropic/workflow.js +9 -4
- package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.cjs +154 -13
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +6 -5
- package/dist/adapters/thread/google-genai/index.d.ts +6 -5
- package/dist/adapters/thread/google-genai/index.js +154 -14
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.cjs +9 -3
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +6 -5
- package/dist/adapters/thread/google-genai/workflow.d.ts +6 -5
- package/dist/adapters/thread/google-genai/workflow.js +9 -4
- package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
- package/dist/adapters/thread/index.cjs +16 -0
- package/dist/adapters/thread/index.cjs.map +1 -0
- package/dist/adapters/thread/index.d.cts +34 -0
- package/dist/adapters/thread/index.d.ts +34 -0
- package/dist/adapters/thread/index.js +12 -0
- package/dist/adapters/thread/index.js.map +1 -0
- package/dist/adapters/thread/langchain/index.cjs +149 -14
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +9 -8
- package/dist/adapters/thread/langchain/index.d.ts +9 -8
- package/dist/adapters/thread/langchain/index.js +149 -15
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.cjs +9 -3
- package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +6 -5
- package/dist/adapters/thread/langchain/workflow.d.ts +6 -5
- package/dist/adapters/thread/langchain/workflow.js +9 -4
- package/dist/adapters/thread/langchain/workflow.js.map +1 -1
- package/dist/index.cjs +367 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +365 -61
- package/dist/index.js.map +1 -1
- package/dist/{proxy-DEtowJyd.d.cts → proxy-BAKzNGRq.d.cts} +1 -1
- package/dist/{proxy-0smGKvx8.d.ts → proxy-DO_MXbY4.d.ts} +1 -1
- package/dist/{thread-manager-C-C4pI2z.d.ts → thread-manager-CcRXasqs.d.ts} +2 -2
- package/dist/{thread-manager-D4vgzYrh.d.cts → thread-manager-ClwSaUnj.d.cts} +2 -2
- package/dist/{thread-manager-3fszQih4.d.ts → thread-manager-D-7lp1JK.d.ts} +2 -2
- package/dist/{thread-manager-CzYln2OC.d.cts → thread-manager-Y8Ucf0Tf.d.cts} +2 -2
- package/dist/{types-CPKDl-y_.d.ts → types-Bcbiq8iv.d.cts} +195 -22
- package/dist/{types-CNuWnvy9.d.ts → types-DAsQ21Rt.d.ts} +1 -1
- package/dist/{types-B37hKoWA.d.ts → types-DpHTX-iO.d.ts} +58 -1
- package/dist/{types-BO7Yju20.d.cts → types-Dt8-HBBT.d.ts} +195 -22
- package/dist/{types-D08CXPh8.d.cts → types-hFFi-Zd9.d.cts} +58 -1
- package/dist/{types-DWEUmYAJ.d.cts → types-lm8tMNJQ.d.cts} +1 -1
- package/dist/{types-tQL9njTu.d.cts → types-yx0LzPGn.d.cts} +21 -7
- package/dist/{types-tQL9njTu.d.ts → types-yx0LzPGn.d.ts} +21 -7
- package/dist/{workflow-CjXHbZZc.d.ts → workflow-Bmf9EtDW.d.ts} +83 -3
- package/dist/{workflow-Do_lzJpT.d.cts → workflow-Bx9utBwb.d.cts} +83 -3
- package/dist/workflow.cjs +266 -39
- 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 +264 -41
- package/dist/workflow.js.map +1 -1
- package/package.json +12 -2
- package/src/adapters/sandbox/bedrock/index.ts +12 -3
- package/src/adapters/sandbox/daytona/index.ts +12 -3
- package/src/adapters/sandbox/e2b/index.ts +36 -14
- package/src/adapters/sandbox/e2b/types.ts +16 -0
- package/src/adapters/sandbox/inmemory/index.ts +12 -3
- package/src/adapters/thread/adapter-id.test.ts +42 -0
- package/src/adapters/thread/anthropic/activities.ts +40 -5
- package/src/adapters/thread/anthropic/adapter-id.ts +16 -0
- package/src/adapters/thread/anthropic/fork-transform.test.ts +291 -0
- package/src/adapters/thread/anthropic/index.ts +3 -0
- package/src/adapters/thread/anthropic/model-invoker.ts +7 -1
- package/src/adapters/thread/anthropic/proxy.ts +3 -2
- package/src/adapters/thread/anthropic/thread-manager.ts +27 -1
- package/src/adapters/thread/google-genai/activities.ts +44 -5
- package/src/adapters/thread/google-genai/adapter-id.ts +16 -0
- package/src/adapters/thread/google-genai/fork-transform.test.ts +149 -0
- package/src/adapters/thread/google-genai/index.ts +3 -0
- package/src/adapters/thread/google-genai/model-invoker.ts +8 -2
- package/src/adapters/thread/google-genai/proxy.ts +3 -2
- package/src/adapters/thread/google-genai/thread-manager.ts +27 -1
- package/src/adapters/thread/index.ts +39 -0
- package/src/adapters/thread/langchain/activities.ts +40 -5
- package/src/adapters/thread/langchain/adapter-id.ts +16 -0
- package/src/adapters/thread/langchain/fork-transform.test.ts +142 -0
- package/src/adapters/thread/langchain/index.ts +3 -0
- package/src/adapters/thread/langchain/model-invoker.ts +7 -1
- package/src/adapters/thread/langchain/proxy.ts +3 -2
- package/src/adapters/thread/langchain/thread-manager.ts +27 -1
- package/src/lib/lifecycle.ts +14 -5
- package/src/lib/model/types.ts +7 -0
- package/src/lib/sandbox/manager.ts +26 -18
- package/src/lib/sandbox/types.ts +27 -7
- package/src/lib/session/session-edge-cases.integration.test.ts +336 -4
- package/src/lib/session/session.integration.test.ts +192 -2
- package/src/lib/session/session.ts +102 -8
- package/src/lib/session/types.ts +66 -3
- package/src/lib/state/index.ts +1 -0
- package/src/lib/state/manager.integration.test.ts +109 -0
- package/src/lib/state/manager.ts +38 -8
- package/src/lib/state/types.ts +25 -0
- package/src/lib/subagent/handler.ts +124 -11
- package/src/lib/subagent/index.ts +5 -1
- package/src/lib/subagent/subagent.integration.test.ts +628 -104
- package/src/lib/subagent/types.ts +63 -14
- package/src/lib/subagent/workflow.ts +29 -2
- package/src/lib/thread/index.ts +5 -0
- package/src/lib/thread/keys.test.ts +101 -0
- package/src/lib/thread/keys.ts +94 -0
- package/src/lib/thread/manager.test.ts +139 -0
- package/src/lib/thread/manager.ts +105 -9
- package/src/lib/thread/proxy.ts +3 -0
- package/src/lib/thread/types.ts +64 -1
- package/src/lib/tool-router/index.ts +2 -0
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +92 -0
- package/src/lib/tool-router/router.integration.test.ts +12 -0
- package/src/lib/tool-router/router.ts +89 -16
- package/src/lib/tool-router/types.ts +42 -1
- package/src/lib/types.ts +12 -0
- package/src/workflow.ts +14 -1
- package/tsup.config.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineSignal, uuid4, setHandler, defineUpdate, ApplicationFailure, log, condition, defineQuery, proxySinks, workflowInfo, proxyActivities, getExternalWorkflowHandle, executeChild } from '@temporalio/workflow';
|
|
1
|
+
import { defineSignal, CancellationScope, isCancellation, uuid4, setHandler, defineUpdate, ApplicationFailure, log, condition, defineQuery, proxySinks, workflowInfo, proxyActivities, getExternalWorkflowHandle, executeChild } from '@temporalio/workflow';
|
|
2
2
|
import z14, { z } from 'zod';
|
|
3
3
|
import { randomUUID, randomFillSync } from 'crypto';
|
|
4
4
|
import { ApplicationFailure as ApplicationFailure$1 } from '@temporalio/common';
|
|
@@ -111,7 +111,7 @@ function createToolRouter(options) {
|
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
-
async function processToolCall(toolCall, turn, sandboxId) {
|
|
114
|
+
async function processToolCall(toolCall, turn, sandboxId, onRewindRequested) {
|
|
115
115
|
const startTime = Date.now();
|
|
116
116
|
const tool = toolMap.get(toolCall.name);
|
|
117
117
|
const preResult = await runPreHooks(toolCall, tool, turn);
|
|
@@ -126,7 +126,7 @@ function createToolRouter(options) {
|
|
|
126
126
|
reason: "Skipped by PreToolUse hook"
|
|
127
127
|
})
|
|
128
128
|
});
|
|
129
|
-
return
|
|
129
|
+
return { kind: "skipped" };
|
|
130
130
|
}
|
|
131
131
|
const effectiveArgs = preResult.args;
|
|
132
132
|
log.debug("tool call dispatched", {
|
|
@@ -138,6 +138,7 @@ function createToolRouter(options) {
|
|
|
138
138
|
let content;
|
|
139
139
|
let resultAppended = false;
|
|
140
140
|
let metadata;
|
|
141
|
+
let rewindRequested = false;
|
|
141
142
|
try {
|
|
142
143
|
if (tool) {
|
|
143
144
|
const routerContext = {
|
|
@@ -155,11 +156,15 @@ function createToolRouter(options) {
|
|
|
155
156
|
content = response.toolResponse;
|
|
156
157
|
resultAppended = response.resultAppended === true;
|
|
157
158
|
metadata = response.metadata;
|
|
159
|
+
rewindRequested = response.rewind === true;
|
|
158
160
|
} else {
|
|
159
161
|
result = { error: `Unknown tool: ${toolCall.name}` };
|
|
160
162
|
content = JSON.stringify(result, null, 2);
|
|
161
163
|
}
|
|
162
164
|
} catch (error) {
|
|
165
|
+
if (isCancellation(error)) {
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
163
168
|
log.warn("tool call failed", {
|
|
164
169
|
toolName: toolCall.name,
|
|
165
170
|
toolCallId: toolCall.id,
|
|
@@ -177,6 +182,15 @@ function createToolRouter(options) {
|
|
|
177
182
|
result = recovery.result;
|
|
178
183
|
content = recovery.content;
|
|
179
184
|
}
|
|
185
|
+
if (rewindRequested) {
|
|
186
|
+
const signal = {
|
|
187
|
+
toolCallId: toolCall.id,
|
|
188
|
+
toolName: toolCall.name
|
|
189
|
+
};
|
|
190
|
+
log.info("tool requested rewind", { ...signal });
|
|
191
|
+
onRewindRequested?.(signal);
|
|
192
|
+
return { kind: "rewind", signal };
|
|
193
|
+
}
|
|
180
194
|
if (!resultAppended) {
|
|
181
195
|
const config = {
|
|
182
196
|
threadId: options.threadId,
|
|
@@ -213,7 +227,7 @@ function createToolRouter(options) {
|
|
|
213
227
|
turn,
|
|
214
228
|
durationMs
|
|
215
229
|
);
|
|
216
|
-
return toolResult;
|
|
230
|
+
return { kind: "result", value: toolResult };
|
|
217
231
|
}
|
|
218
232
|
return {
|
|
219
233
|
hasTools() {
|
|
@@ -248,27 +262,59 @@ function createToolRouter(options) {
|
|
|
248
262
|
}));
|
|
249
263
|
},
|
|
250
264
|
async processToolCalls(toolCalls, context) {
|
|
265
|
+
const attachRewind = (arr, rewind) => {
|
|
266
|
+
if (rewind) {
|
|
267
|
+
arr.rewind = rewind;
|
|
268
|
+
}
|
|
269
|
+
return arr;
|
|
270
|
+
};
|
|
251
271
|
if (toolCalls.length === 0) {
|
|
252
|
-
return [];
|
|
272
|
+
return attachRewind([], void 0);
|
|
253
273
|
}
|
|
254
274
|
const turn = context?.turn ?? 0;
|
|
255
275
|
const sandboxId = context?.sandboxId;
|
|
276
|
+
let rewindSignal;
|
|
256
277
|
if (options.parallel) {
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
278
|
+
const scope = new CancellationScope({ cancellable: true });
|
|
279
|
+
const onRewindRequested = (signal) => {
|
|
280
|
+
if (!rewindSignal) {
|
|
281
|
+
rewindSignal = signal;
|
|
282
|
+
scope.cancel();
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
const outcomes = await scope.run(
|
|
286
|
+
async () => Promise.allSettled(
|
|
287
|
+
toolCalls.map(
|
|
288
|
+
(tc) => processToolCall(tc, turn, sandboxId, onRewindRequested)
|
|
289
|
+
)
|
|
290
|
+
)
|
|
262
291
|
);
|
|
292
|
+
const results2 = [];
|
|
293
|
+
for (const outcome of outcomes) {
|
|
294
|
+
if (outcome.status === "rejected") {
|
|
295
|
+
if (isCancellation(outcome.reason)) {
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
throw outcome.reason;
|
|
299
|
+
}
|
|
300
|
+
if (outcome.value.kind === "result") {
|
|
301
|
+
results2.push(outcome.value.value);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return attachRewind(results2, rewindSignal);
|
|
263
305
|
}
|
|
264
306
|
const results = [];
|
|
265
307
|
for (const toolCall of toolCalls) {
|
|
266
|
-
const
|
|
267
|
-
if (
|
|
268
|
-
|
|
308
|
+
const outcome = await processToolCall(toolCall, turn, sandboxId);
|
|
309
|
+
if (outcome.kind === "rewind") {
|
|
310
|
+
rewindSignal = outcome.signal;
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
if (outcome.kind === "result") {
|
|
314
|
+
results.push(outcome.value);
|
|
269
315
|
}
|
|
270
316
|
}
|
|
271
|
-
return results;
|
|
317
|
+
return attachRewind(results, rewindSignal);
|
|
272
318
|
},
|
|
273
319
|
async processToolCallsByName(toolCalls, toolName, handler, context) {
|
|
274
320
|
const matchingCalls = toolCalls.filter((tc) => tc.name === toolName);
|
|
@@ -392,6 +438,7 @@ function createSubagentTool(subagents) {
|
|
|
392
438
|
var childSandboxReadySignal = defineSignal("childSandboxReady");
|
|
393
439
|
|
|
394
440
|
// src/lib/subagent/handler.ts
|
|
441
|
+
var DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT = "1h";
|
|
395
442
|
function resolveSandboxConfig(config) {
|
|
396
443
|
if (!config || config === "none") {
|
|
397
444
|
return { source: "none", init: "per-call", continuation: "fork" };
|
|
@@ -423,17 +470,28 @@ function createSubagentHandler(subagents) {
|
|
|
423
470
|
const threadSandboxes = /* @__PURE__ */ new Map();
|
|
424
471
|
const persistentSandboxes = /* @__PURE__ */ new Map();
|
|
425
472
|
const persistentSandboxCreating = /* @__PURE__ */ new Set();
|
|
473
|
+
const persistentSandboxCreationError = /* @__PURE__ */ new Map();
|
|
426
474
|
const lazyCreatorAgent = /* @__PURE__ */ new Map();
|
|
475
|
+
const snapshotBaseCreatorAgent = /* @__PURE__ */ new Map();
|
|
427
476
|
const threadSnapshots = /* @__PURE__ */ new Map();
|
|
428
477
|
const persistentBaseSnapshot = /* @__PURE__ */ new Map();
|
|
429
478
|
const persistentBaseSnapshotCreating = /* @__PURE__ */ new Set();
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
lazyCreatorAgent.
|
|
479
|
+
const persistentBaseSnapshotCreationError = /* @__PURE__ */ new Map();
|
|
480
|
+
setHandler(
|
|
481
|
+
childSandboxReadySignal,
|
|
482
|
+
({ childWorkflowId, sandboxId, baseSnapshot }) => {
|
|
483
|
+
const lazyAgent = lazyCreatorAgent.get(childWorkflowId);
|
|
484
|
+
if (lazyAgent && !persistentSandboxes.has(lazyAgent)) {
|
|
485
|
+
persistentSandboxes.set(lazyAgent, sandboxId);
|
|
486
|
+
lazyCreatorAgent.delete(childWorkflowId);
|
|
487
|
+
}
|
|
488
|
+
const snapAgent = snapshotBaseCreatorAgent.get(childWorkflowId);
|
|
489
|
+
if (snapAgent && baseSnapshot && !persistentBaseSnapshot.has(snapAgent)) {
|
|
490
|
+
persistentBaseSnapshot.set(snapAgent, baseSnapshot);
|
|
491
|
+
snapshotBaseCreatorAgent.delete(childWorkflowId);
|
|
492
|
+
}
|
|
435
493
|
}
|
|
436
|
-
|
|
494
|
+
);
|
|
437
495
|
const handler = async (args, context) => {
|
|
438
496
|
const config = subagents.find((s) => s.agentName === args.subagent);
|
|
439
497
|
if (!config) {
|
|
@@ -489,8 +547,20 @@ function createSubagentHandler(subagents) {
|
|
|
489
547
|
baseSnap = persistentBaseSnapshot.get(config.agentName);
|
|
490
548
|
if (!baseSnap) {
|
|
491
549
|
if (persistentBaseSnapshotCreating.has(config.agentName)) {
|
|
492
|
-
await condition(
|
|
550
|
+
await condition(
|
|
551
|
+
() => persistentBaseSnapshot.has(config.agentName) || persistentBaseSnapshotCreationError.has(config.agentName) || !persistentBaseSnapshotCreating.has(config.agentName)
|
|
552
|
+
);
|
|
553
|
+
const creatorErr = persistentBaseSnapshotCreationError.get(
|
|
554
|
+
config.agentName
|
|
555
|
+
);
|
|
556
|
+
if (creatorErr !== void 0) {
|
|
557
|
+
throw creatorErr;
|
|
558
|
+
}
|
|
493
559
|
baseSnap = persistentBaseSnapshot.get(config.agentName);
|
|
560
|
+
if (!baseSnap) {
|
|
561
|
+
persistentBaseSnapshotCreating.add(config.agentName);
|
|
562
|
+
isSnapshotBaseCreator = true;
|
|
563
|
+
}
|
|
494
564
|
} else {
|
|
495
565
|
persistentBaseSnapshotCreating.add(config.agentName);
|
|
496
566
|
isSnapshotBaseCreator = true;
|
|
@@ -508,8 +578,20 @@ function createSubagentHandler(subagents) {
|
|
|
508
578
|
baseSandboxId = persistentSandboxes.get(config.agentName);
|
|
509
579
|
if (!baseSandboxId) {
|
|
510
580
|
if (persistentSandboxCreating.has(config.agentName)) {
|
|
511
|
-
await condition(
|
|
581
|
+
await condition(
|
|
582
|
+
() => persistentSandboxes.has(config.agentName) || persistentSandboxCreationError.has(config.agentName) || !persistentSandboxCreating.has(config.agentName)
|
|
583
|
+
);
|
|
584
|
+
const creatorErr = persistentSandboxCreationError.get(
|
|
585
|
+
config.agentName
|
|
586
|
+
);
|
|
587
|
+
if (creatorErr !== void 0) {
|
|
588
|
+
throw creatorErr;
|
|
589
|
+
}
|
|
512
590
|
baseSandboxId = persistentSandboxes.get(config.agentName);
|
|
591
|
+
if (!baseSandboxId) {
|
|
592
|
+
persistentSandboxCreating.add(config.agentName);
|
|
593
|
+
isLazyCreator = true;
|
|
594
|
+
}
|
|
513
595
|
} else {
|
|
514
596
|
persistentSandboxCreating.add(config.agentName);
|
|
515
597
|
isLazyCreator = true;
|
|
@@ -538,6 +620,12 @@ function createSubagentHandler(subagents) {
|
|
|
538
620
|
};
|
|
539
621
|
const resolvedContext = config.context === void 0 ? void 0 : typeof config.context === "function" ? config.context() : config.context;
|
|
540
622
|
const childOpts = {
|
|
623
|
+
// Apply a bounded run timeout by default so a child workflow that
|
|
624
|
+
// fails to initialize or otherwise never reaches a terminal state
|
|
625
|
+
// cannot hang the parent's `Subagent` tool call forever. Callers can
|
|
626
|
+
// raise, lower, or disable it via `workflowOptions.workflowRunTimeout`.
|
|
627
|
+
workflowRunTimeout: DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT,
|
|
628
|
+
...config.workflowOptions ?? {},
|
|
541
629
|
workflowId: childWorkflowId,
|
|
542
630
|
args: resolvedContext === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, resolvedContext],
|
|
543
631
|
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
@@ -545,13 +633,39 @@ function createSubagentHandler(subagents) {
|
|
|
545
633
|
if (isLazyCreator) {
|
|
546
634
|
lazyCreatorAgent.set(childWorkflowId, config.agentName);
|
|
547
635
|
}
|
|
636
|
+
if (isSnapshotBaseCreator) {
|
|
637
|
+
snapshotBaseCreatorAgent.set(childWorkflowId, config.agentName);
|
|
638
|
+
}
|
|
548
639
|
log.info("subagent spawned", {
|
|
549
640
|
subagent: config.agentName,
|
|
550
641
|
childWorkflowId,
|
|
551
642
|
threadMode,
|
|
552
643
|
sandboxSource: sandboxCfg.source
|
|
553
644
|
});
|
|
554
|
-
|
|
645
|
+
let childResult;
|
|
646
|
+
try {
|
|
647
|
+
childResult = await executeChild(
|
|
648
|
+
config.workflow,
|
|
649
|
+
childOpts
|
|
650
|
+
);
|
|
651
|
+
} catch (err) {
|
|
652
|
+
log.warn("subagent failed", {
|
|
653
|
+
subagent: config.agentName,
|
|
654
|
+
childWorkflowId,
|
|
655
|
+
error: err instanceof Error ? err.message : String(err)
|
|
656
|
+
});
|
|
657
|
+
if (isLazyCreator) {
|
|
658
|
+
persistentSandboxCreating.delete(config.agentName);
|
|
659
|
+
persistentSandboxCreationError.set(config.agentName, err);
|
|
660
|
+
lazyCreatorAgent.delete(childWorkflowId);
|
|
661
|
+
}
|
|
662
|
+
if (isSnapshotBaseCreator) {
|
|
663
|
+
persistentBaseSnapshotCreating.delete(config.agentName);
|
|
664
|
+
persistentBaseSnapshotCreationError.set(config.agentName, err);
|
|
665
|
+
snapshotBaseCreatorAgent.delete(childWorkflowId);
|
|
666
|
+
}
|
|
667
|
+
throw err;
|
|
668
|
+
}
|
|
555
669
|
const effectiveShutdown = sandboxShutdownOverride ?? sandboxCfg.shutdown ?? "destroy";
|
|
556
670
|
log.info("subagent completed", {
|
|
557
671
|
subagent: config.agentName,
|
|
@@ -595,10 +709,13 @@ function createSubagentHandler(subagents) {
|
|
|
595
709
|
}
|
|
596
710
|
if (isLazyCreator) {
|
|
597
711
|
persistentSandboxCreating.delete(config.agentName);
|
|
712
|
+
persistentSandboxCreationError.delete(config.agentName);
|
|
598
713
|
lazyCreatorAgent.delete(childWorkflowId);
|
|
599
714
|
}
|
|
600
715
|
if (isSnapshotBaseCreator) {
|
|
601
716
|
persistentBaseSnapshotCreating.delete(config.agentName);
|
|
717
|
+
persistentBaseSnapshotCreationError.delete(config.agentName);
|
|
718
|
+
snapshotBaseCreatorAgent.delete(childWorkflowId);
|
|
602
719
|
}
|
|
603
720
|
if (!toolResponse) {
|
|
604
721
|
return {
|
|
@@ -841,6 +958,7 @@ async function createSession({
|
|
|
841
958
|
sandbox: sandboxInit,
|
|
842
959
|
sandboxShutdown = "destroy",
|
|
843
960
|
onSandboxReady,
|
|
961
|
+
onSessionExit,
|
|
844
962
|
virtualFs: virtualFsConfig,
|
|
845
963
|
virtualFsOps
|
|
846
964
|
}) {
|
|
@@ -865,7 +983,9 @@ async function createSession({
|
|
|
865
983
|
initializeThread,
|
|
866
984
|
appendSystemMessage,
|
|
867
985
|
appendAgentMessage,
|
|
868
|
-
forkThread
|
|
986
|
+
forkThread,
|
|
987
|
+
loadThreadState,
|
|
988
|
+
saveThreadState
|
|
869
989
|
} = threadOps;
|
|
870
990
|
const plugins = [];
|
|
871
991
|
let destroySubagentSandboxes;
|
|
@@ -959,8 +1079,10 @@ async function createSession({
|
|
|
959
1079
|
nonRetryable: true
|
|
960
1080
|
});
|
|
961
1081
|
}
|
|
1082
|
+
const forkInit = sandboxInit;
|
|
962
1083
|
sandboxId = await sandboxOps.forkSandbox(
|
|
963
|
-
|
|
1084
|
+
forkInit.sandboxId,
|
|
1085
|
+
forkInit.options
|
|
964
1086
|
);
|
|
965
1087
|
sandboxOwned = true;
|
|
966
1088
|
} else if (sandboxMode === "from-snapshot") {
|
|
@@ -970,8 +1092,11 @@ async function createSession({
|
|
|
970
1092
|
nonRetryable: true
|
|
971
1093
|
});
|
|
972
1094
|
}
|
|
973
|
-
const
|
|
974
|
-
sandboxId = await sandboxOps.restoreSandbox(
|
|
1095
|
+
const restoreInit = sandboxInit;
|
|
1096
|
+
sandboxId = await sandboxOps.restoreSandbox(
|
|
1097
|
+
restoreInit.snapshot,
|
|
1098
|
+
restoreInit.options
|
|
1099
|
+
);
|
|
975
1100
|
sandboxOwned = true;
|
|
976
1101
|
} else if (sandboxOps) {
|
|
977
1102
|
const skillFiles = skills ? collectSkillFiles(skills) : void 0;
|
|
@@ -988,7 +1113,10 @@ async function createSession({
|
|
|
988
1113
|
baseSnapshot = await sandboxOps.snapshotSandbox(sandboxId);
|
|
989
1114
|
}
|
|
990
1115
|
if (sandboxId && sandboxOwned && onSandboxReady) {
|
|
991
|
-
onSandboxReady(
|
|
1116
|
+
onSandboxReady({
|
|
1117
|
+
sandboxId,
|
|
1118
|
+
...baseSnapshot && { baseSnapshot }
|
|
1119
|
+
});
|
|
992
1120
|
}
|
|
993
1121
|
if (virtualFsConfig) {
|
|
994
1122
|
if (!virtualFsOps) {
|
|
@@ -1031,9 +1159,20 @@ async function createSession({
|
|
|
1031
1159
|
});
|
|
1032
1160
|
const sessionStartMs = Date.now();
|
|
1033
1161
|
const systemPrompt = stateManager.getSystemPrompt();
|
|
1162
|
+
const rehydrateFromSlice = (slice) => {
|
|
1163
|
+
stateManager.mergeUpdate({
|
|
1164
|
+
tasks: new Map(slice.tasks),
|
|
1165
|
+
...slice.custom
|
|
1166
|
+
});
|
|
1167
|
+
};
|
|
1034
1168
|
if (threadMode === "fork" && sourceThreadId) {
|
|
1035
1169
|
await forkThread(sourceThreadId, threadId, threadKey);
|
|
1036
|
-
|
|
1170
|
+
const forkedSlice = await loadThreadState(threadId, threadKey);
|
|
1171
|
+
if (forkedSlice) rehydrateFromSlice(forkedSlice);
|
|
1172
|
+
} else if (threadMode === "continue") {
|
|
1173
|
+
const continuedSlice = await loadThreadState(threadId, threadKey);
|
|
1174
|
+
if (continuedSlice) rehydrateFromSlice(continuedSlice);
|
|
1175
|
+
} else {
|
|
1037
1176
|
if (appendSystemPrompt) {
|
|
1038
1177
|
if (systemPrompt == null || typeof systemPrompt === "string" && systemPrompt.trim() === "") {
|
|
1039
1178
|
throw ApplicationFailure.create({
|
|
@@ -1055,18 +1194,21 @@ async function createSession({
|
|
|
1055
1194
|
let exitReason = "completed";
|
|
1056
1195
|
let finalMessage = null;
|
|
1057
1196
|
try {
|
|
1197
|
+
let assistantId;
|
|
1058
1198
|
while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
|
|
1059
1199
|
stateManager.incrementTurns();
|
|
1060
1200
|
const currentTurn = stateManager.getTurns();
|
|
1061
1201
|
log.debug("turn started", { agentName, threadId, turn: currentTurn });
|
|
1062
1202
|
stateManager.setTools(toolRouter.getToolDefinitions());
|
|
1203
|
+
assistantId ??= uuid4();
|
|
1063
1204
|
const { message, rawToolCalls, usage } = await runAgent({
|
|
1064
1205
|
threadId,
|
|
1065
1206
|
threadKey,
|
|
1066
1207
|
agentName,
|
|
1067
|
-
metadata
|
|
1208
|
+
metadata,
|
|
1209
|
+
assistantMessageId: assistantId
|
|
1068
1210
|
});
|
|
1069
|
-
await appendAgentMessage(threadId,
|
|
1211
|
+
await appendAgentMessage(threadId, assistantId, message, threadKey);
|
|
1070
1212
|
if (usage) {
|
|
1071
1213
|
stateManager.updateUsage(usage);
|
|
1072
1214
|
}
|
|
@@ -1111,6 +1253,18 @@ async function createSession({
|
|
|
1111
1253
|
stateManager.updateUsage(result.usage);
|
|
1112
1254
|
}
|
|
1113
1255
|
}
|
|
1256
|
+
const rewind = toolCallResults.rewind;
|
|
1257
|
+
if (rewind) {
|
|
1258
|
+
log.info("rewinding turn", {
|
|
1259
|
+
agentName,
|
|
1260
|
+
threadId,
|
|
1261
|
+
turn: currentTurn,
|
|
1262
|
+
toolCallId: rewind.toolCallId,
|
|
1263
|
+
toolName: rewind.toolName
|
|
1264
|
+
});
|
|
1265
|
+
continue;
|
|
1266
|
+
}
|
|
1267
|
+
assistantId = void 0;
|
|
1114
1268
|
if (stateManager.getStatus() === "WAITING_FOR_INPUT") {
|
|
1115
1269
|
const conditionMet = await condition(
|
|
1116
1270
|
() => stateManager.getStatus() === "RUNNING",
|
|
@@ -1143,6 +1297,19 @@ async function createSession({
|
|
|
1143
1297
|
});
|
|
1144
1298
|
throw ApplicationFailure.fromError(error);
|
|
1145
1299
|
} finally {
|
|
1300
|
+
try {
|
|
1301
|
+
await saveThreadState(
|
|
1302
|
+
threadId,
|
|
1303
|
+
stateManager.getPersistedSlice(),
|
|
1304
|
+
threadKey
|
|
1305
|
+
);
|
|
1306
|
+
} catch (persistError) {
|
|
1307
|
+
log.warn("failed to persist thread state", {
|
|
1308
|
+
agentName,
|
|
1309
|
+
threadId,
|
|
1310
|
+
error: persistError instanceof Error ? persistError.message : String(persistError)
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1146
1313
|
await callSessionEnd(exitReason, stateManager.getTurns());
|
|
1147
1314
|
if (sandboxOwned && sandboxId && sandboxOps) {
|
|
1148
1315
|
switch (sandboxShutdown) {
|
|
@@ -1179,6 +1346,12 @@ async function createSession({
|
|
|
1179
1346
|
...baseSnapshot && { hasBaseSnapshot: true },
|
|
1180
1347
|
...exitSnapshot && { hasExitSnapshot: true }
|
|
1181
1348
|
});
|
|
1349
|
+
if (onSessionExit) {
|
|
1350
|
+
onSessionExit({
|
|
1351
|
+
...sandboxId && { sandboxId },
|
|
1352
|
+
...exitSnapshot && { snapshot: exitSnapshot }
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1182
1355
|
return {
|
|
1183
1356
|
threadId,
|
|
1184
1357
|
finalMessage,
|
|
@@ -1207,6 +1380,18 @@ function defineWorkflow(config, fn) {
|
|
|
1207
1380
|
return workflow;
|
|
1208
1381
|
}
|
|
1209
1382
|
|
|
1383
|
+
// src/lib/thread/keys.ts
|
|
1384
|
+
var THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;
|
|
1385
|
+
function getThreadListKey(threadKey, threadId) {
|
|
1386
|
+
return `${threadKey}:thread:${threadId}`;
|
|
1387
|
+
}
|
|
1388
|
+
function getThreadMetaKey(threadKey, threadId) {
|
|
1389
|
+
return `${threadKey}:meta:thread:${threadId}`;
|
|
1390
|
+
}
|
|
1391
|
+
function getThreadStateKey(threadKey, threadId) {
|
|
1392
|
+
return `${threadKey}:state:thread:${threadId}`;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1210
1395
|
// src/lib/types.ts
|
|
1211
1396
|
function isTerminalStatus(status) {
|
|
1212
1397
|
return status === "COMPLETED" || status === "FAILED" || status === "CANCELLED";
|
|
@@ -1226,11 +1411,19 @@ function createAgentStateManager({
|
|
|
1226
1411
|
let systemPrompt = initialState?.systemPrompt;
|
|
1227
1412
|
const tasks = new Map(initialState?.tasks);
|
|
1228
1413
|
const {
|
|
1229
|
-
status:
|
|
1230
|
-
version:
|
|
1231
|
-
turns:
|
|
1232
|
-
tasks:
|
|
1233
|
-
tools:
|
|
1414
|
+
status: _status,
|
|
1415
|
+
version: _version,
|
|
1416
|
+
turns: _turns,
|
|
1417
|
+
tasks: _tasks,
|
|
1418
|
+
tools: _tools,
|
|
1419
|
+
systemPrompt: _systemPrompt,
|
|
1420
|
+
fileTree: _fileTree,
|
|
1421
|
+
inlineFiles: _inlineFiles,
|
|
1422
|
+
virtualFsCtx: _virtualFsCtx,
|
|
1423
|
+
totalInputTokens: _totalInputTokens,
|
|
1424
|
+
totalOutputTokens: _totalOutputTokens,
|
|
1425
|
+
cachedWriteTokens: _cachedWriteTokens,
|
|
1426
|
+
cachedReadTokens: _cachedReadTokens,
|
|
1234
1427
|
...custom
|
|
1235
1428
|
} = initialState ?? {};
|
|
1236
1429
|
const customState = custom;
|
|
@@ -1310,7 +1503,14 @@ function createAgentStateManager({
|
|
|
1310
1503
|
version++;
|
|
1311
1504
|
},
|
|
1312
1505
|
mergeUpdate(update) {
|
|
1313
|
-
|
|
1506
|
+
const { tasks: nextTasks, ...rest } = update;
|
|
1507
|
+
if (nextTasks) {
|
|
1508
|
+
tasks.clear();
|
|
1509
|
+
for (const [id, task] of nextTasks) {
|
|
1510
|
+
tasks.set(id, task);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
Object.assign(customState, rest);
|
|
1314
1514
|
version++;
|
|
1315
1515
|
},
|
|
1316
1516
|
getCurrentState() {
|
|
@@ -1348,6 +1548,12 @@ function createAgentStateManager({
|
|
|
1348
1548
|
}
|
|
1349
1549
|
return deleted;
|
|
1350
1550
|
},
|
|
1551
|
+
getPersistedSlice() {
|
|
1552
|
+
return {
|
|
1553
|
+
tasks: Array.from(tasks.entries()),
|
|
1554
|
+
custom: { ...customState }
|
|
1555
|
+
};
|
|
1556
|
+
},
|
|
1351
1557
|
updateUsage(usage) {
|
|
1352
1558
|
totalInputTokens += usage.inputTokens ?? 0;
|
|
1353
1559
|
totalOutputTokens += usage.outputTokens ?? 0;
|
|
@@ -1469,22 +1675,42 @@ function defineSubagentWorkflow(config, fn) {
|
|
|
1469
1675
|
});
|
|
1470
1676
|
}
|
|
1471
1677
|
const parentHandle = getExternalWorkflowHandle(parent.workflowId);
|
|
1678
|
+
let capturedSandboxId;
|
|
1679
|
+
let capturedSnapshot;
|
|
1680
|
+
let capturedBaseSnapshot;
|
|
1681
|
+
let capturedThreadId;
|
|
1472
1682
|
const sessionInput = {
|
|
1473
1683
|
agentName: config.name,
|
|
1474
1684
|
sandboxShutdown: effectiveShutdown,
|
|
1475
1685
|
...workflowInput.thread && { thread: workflowInput.thread },
|
|
1476
1686
|
...workflowInput.sandbox && { sandbox: workflowInput.sandbox },
|
|
1477
|
-
onSandboxReady: (sandboxId) => {
|
|
1687
|
+
onSandboxReady: ({ sandboxId, baseSnapshot }) => {
|
|
1688
|
+
capturedBaseSnapshot = baseSnapshot;
|
|
1478
1689
|
const isReuse = workflowInput.sandbox?.mode === "continue";
|
|
1479
1690
|
if (!isReuse) {
|
|
1480
1691
|
void parentHandle.signal(childSandboxReadySignal, {
|
|
1481
1692
|
childWorkflowId: workflowInfo().workflowId,
|
|
1482
|
-
sandboxId
|
|
1693
|
+
sandboxId,
|
|
1694
|
+
...baseSnapshot && { baseSnapshot }
|
|
1483
1695
|
});
|
|
1484
1696
|
}
|
|
1697
|
+
},
|
|
1698
|
+
onSessionExit: ({ sandboxId, snapshot, threadId }) => {
|
|
1699
|
+
capturedSandboxId = sandboxId;
|
|
1700
|
+
capturedSnapshot = snapshot;
|
|
1701
|
+
capturedThreadId = threadId;
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1704
|
+
const result = await fn(prompt, sessionInput, context ?? {});
|
|
1705
|
+
return {
|
|
1706
|
+
...result,
|
|
1707
|
+
...capturedThreadId !== void 0 && { threadId: capturedThreadId },
|
|
1708
|
+
...capturedSandboxId !== void 0 && { sandboxId: capturedSandboxId },
|
|
1709
|
+
...capturedSnapshot !== void 0 && { snapshot: capturedSnapshot },
|
|
1710
|
+
...capturedBaseSnapshot !== void 0 && {
|
|
1711
|
+
baseSnapshot: capturedBaseSnapshot
|
|
1485
1712
|
}
|
|
1486
1713
|
};
|
|
1487
|
-
return fn(prompt, sessionInput, context ?? {});
|
|
1488
1714
|
};
|
|
1489
1715
|
Object.defineProperty(workflow, "name", { value: config.name });
|
|
1490
1716
|
return Object.assign(workflow, {
|
|
@@ -2254,7 +2480,6 @@ var FileSystemSkillProvider = class {
|
|
|
2254
2480
|
};
|
|
2255
2481
|
|
|
2256
2482
|
// src/lib/thread/manager.ts
|
|
2257
|
-
var THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;
|
|
2258
2483
|
var APPEND_IDEMPOTENT_SCRIPT = `
|
|
2259
2484
|
if redis.call('EXISTS', KEYS[1]) == 1 then
|
|
2260
2485
|
return 0
|
|
@@ -2266,8 +2491,8 @@ redis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))
|
|
|
2266
2491
|
redis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))
|
|
2267
2492
|
return 1
|
|
2268
2493
|
`;
|
|
2269
|
-
function
|
|
2270
|
-
return
|
|
2494
|
+
function getDedupKey(threadId, id) {
|
|
2495
|
+
return `dedup:${id}:thread:${threadId}`;
|
|
2271
2496
|
}
|
|
2272
2497
|
function createThreadManager(config) {
|
|
2273
2498
|
const {
|
|
@@ -2278,8 +2503,9 @@ function createThreadManager(config) {
|
|
|
2278
2503
|
deserialize = (raw) => JSON.parse(raw),
|
|
2279
2504
|
idOf
|
|
2280
2505
|
} = config;
|
|
2281
|
-
const redisKey =
|
|
2282
|
-
const metaKey =
|
|
2506
|
+
const redisKey = getThreadListKey(key, threadId);
|
|
2507
|
+
const metaKey = getThreadMetaKey(key, threadId);
|
|
2508
|
+
const stateKey = getThreadStateKey(key, threadId);
|
|
2283
2509
|
async function assertThreadExists() {
|
|
2284
2510
|
const exists = await redis.exists(metaKey);
|
|
2285
2511
|
if (!exists) {
|
|
@@ -2301,7 +2527,7 @@ function createThreadManager(config) {
|
|
|
2301
2527
|
await assertThreadExists();
|
|
2302
2528
|
if (idOf) {
|
|
2303
2529
|
const dedupId = messages.map(idOf).join(":");
|
|
2304
|
-
const dedupKey =
|
|
2530
|
+
const dedupKey = getDedupKey(threadId, dedupId);
|
|
2305
2531
|
await redis.eval(
|
|
2306
2532
|
APPEND_IDEMPOTENT_SCRIPT,
|
|
2307
2533
|
2,
|
|
@@ -2318,20 +2544,98 @@ function createThreadManager(config) {
|
|
|
2318
2544
|
async fork(newThreadId) {
|
|
2319
2545
|
await assertThreadExists();
|
|
2320
2546
|
const data = await redis.lrange(redisKey, 0, -1);
|
|
2547
|
+
const stateRaw = await redis.get(stateKey);
|
|
2321
2548
|
const forked = createThreadManager({
|
|
2322
2549
|
...config,
|
|
2323
2550
|
threadId: newThreadId
|
|
2324
2551
|
});
|
|
2325
2552
|
await forked.initialize();
|
|
2326
2553
|
if (data.length > 0) {
|
|
2327
|
-
const newKey =
|
|
2554
|
+
const newKey = getThreadListKey(key, newThreadId);
|
|
2328
2555
|
await redis.rpush(newKey, ...data);
|
|
2329
2556
|
await redis.expire(newKey, THREAD_TTL_SECONDS);
|
|
2330
2557
|
}
|
|
2558
|
+
if (stateRaw != null) {
|
|
2559
|
+
const newStateKey = getThreadStateKey(key, newThreadId);
|
|
2560
|
+
await redis.set(newStateKey, stateRaw, "EX", THREAD_TTL_SECONDS);
|
|
2561
|
+
}
|
|
2331
2562
|
return forked;
|
|
2332
2563
|
},
|
|
2564
|
+
async replaceAll(messages) {
|
|
2565
|
+
await assertThreadExists();
|
|
2566
|
+
if (!idOf) {
|
|
2567
|
+
throw new Error(
|
|
2568
|
+
"replaceAll requires the thread manager to be configured with `idOf`"
|
|
2569
|
+
);
|
|
2570
|
+
}
|
|
2571
|
+
const existing = await redis.lrange(redisKey, 0, -1);
|
|
2572
|
+
const existingIds = existing.map((raw) => idOf(deserialize(raw))).filter((id) => typeof id === "string");
|
|
2573
|
+
await redis.del(redisKey);
|
|
2574
|
+
if (existingIds.length > 0) {
|
|
2575
|
+
await redis.del(
|
|
2576
|
+
...existingIds.map((id) => getDedupKey(threadId, id))
|
|
2577
|
+
);
|
|
2578
|
+
}
|
|
2579
|
+
if (messages.length > 0) {
|
|
2580
|
+
await redis.rpush(redisKey, ...messages.map(serialize));
|
|
2581
|
+
await redis.expire(redisKey, THREAD_TTL_SECONDS);
|
|
2582
|
+
}
|
|
2583
|
+
await redis.expire(metaKey, THREAD_TTL_SECONDS);
|
|
2584
|
+
},
|
|
2333
2585
|
async delete() {
|
|
2334
|
-
await redis.del(redisKey, metaKey);
|
|
2586
|
+
await redis.del(redisKey, metaKey, stateKey);
|
|
2587
|
+
},
|
|
2588
|
+
async loadState() {
|
|
2589
|
+
const raw = await redis.get(stateKey);
|
|
2590
|
+
if (raw == null) return null;
|
|
2591
|
+
return JSON.parse(raw);
|
|
2592
|
+
},
|
|
2593
|
+
async saveState(state) {
|
|
2594
|
+
await assertThreadExists();
|
|
2595
|
+
await redis.set(
|
|
2596
|
+
stateKey,
|
|
2597
|
+
JSON.stringify(state),
|
|
2598
|
+
"EX",
|
|
2599
|
+
THREAD_TTL_SECONDS
|
|
2600
|
+
);
|
|
2601
|
+
},
|
|
2602
|
+
async deleteState() {
|
|
2603
|
+
await redis.del(stateKey);
|
|
2604
|
+
},
|
|
2605
|
+
async length() {
|
|
2606
|
+
await assertThreadExists();
|
|
2607
|
+
return redis.llen(redisKey);
|
|
2608
|
+
},
|
|
2609
|
+
async truncateFromId(messageId) {
|
|
2610
|
+
await assertThreadExists();
|
|
2611
|
+
if (!idOf) {
|
|
2612
|
+
throw new Error(
|
|
2613
|
+
"truncateFromId requires the thread manager to be configured with `idOf`"
|
|
2614
|
+
);
|
|
2615
|
+
}
|
|
2616
|
+
const data = await redis.lrange(redisKey, 0, -1);
|
|
2617
|
+
let idx = -1;
|
|
2618
|
+
const removedIds = [];
|
|
2619
|
+
for (let i = 0; i < data.length; i++) {
|
|
2620
|
+
const raw = data[i];
|
|
2621
|
+
if (raw === void 0) continue;
|
|
2622
|
+
const id = idOf(deserialize(raw));
|
|
2623
|
+
if (idx === -1 && id === messageId) idx = i;
|
|
2624
|
+
if (idx !== -1) removedIds.push(id);
|
|
2625
|
+
}
|
|
2626
|
+
if (idx === -1) return;
|
|
2627
|
+
if (idx === 0) {
|
|
2628
|
+
await redis.del(redisKey);
|
|
2629
|
+
await redis.expire(metaKey, THREAD_TTL_SECONDS);
|
|
2630
|
+
} else {
|
|
2631
|
+
await redis.ltrim(redisKey, 0, idx - 1);
|
|
2632
|
+
await redis.expire(redisKey, THREAD_TTL_SECONDS);
|
|
2633
|
+
}
|
|
2634
|
+
if (removedIds.length > 0) {
|
|
2635
|
+
await redis.del(
|
|
2636
|
+
...removedIds.map((id) => getDedupKey(threadId, id))
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2335
2639
|
}
|
|
2336
2640
|
};
|
|
2337
2641
|
}
|
|
@@ -2418,18 +2722,18 @@ var SandboxManager = class {
|
|
|
2418
2722
|
async resume(id) {
|
|
2419
2723
|
await this.provider.resume(id);
|
|
2420
2724
|
}
|
|
2421
|
-
async snapshot(id) {
|
|
2422
|
-
return this.provider.snapshot(id);
|
|
2725
|
+
async snapshot(id, options) {
|
|
2726
|
+
return this.provider.snapshot(id, options);
|
|
2423
2727
|
}
|
|
2424
|
-
async restore(snapshot) {
|
|
2425
|
-
const sandbox = await this.provider.restore(snapshot);
|
|
2728
|
+
async restore(snapshot, options) {
|
|
2729
|
+
const sandbox = await this.provider.restore(snapshot, options);
|
|
2426
2730
|
return sandbox.id;
|
|
2427
2731
|
}
|
|
2428
2732
|
async deleteSnapshot(snapshot) {
|
|
2429
2733
|
await this.provider.deleteSnapshot(snapshot);
|
|
2430
2734
|
}
|
|
2431
|
-
async fork(sandboxId) {
|
|
2432
|
-
const sandbox = await this.provider.fork(sandboxId);
|
|
2735
|
+
async fork(sandboxId, options) {
|
|
2736
|
+
const sandbox = await this.provider.fork(sandboxId, options);
|
|
2433
2737
|
return sandbox.id;
|
|
2434
2738
|
}
|
|
2435
2739
|
/**
|
|
@@ -2467,17 +2771,17 @@ var SandboxManager = class {
|
|
|
2467
2771
|
resumeSandbox: async (sandboxId) => {
|
|
2468
2772
|
await this.resume(sandboxId);
|
|
2469
2773
|
},
|
|
2470
|
-
snapshotSandbox: async (sandboxId) => {
|
|
2471
|
-
return this.snapshot(sandboxId);
|
|
2774
|
+
snapshotSandbox: async (sandboxId, options) => {
|
|
2775
|
+
return this.snapshot(sandboxId, options);
|
|
2472
2776
|
},
|
|
2473
|
-
restoreSandbox: async (snapshot) => {
|
|
2474
|
-
return this.restore(snapshot);
|
|
2777
|
+
restoreSandbox: async (snapshot, options) => {
|
|
2778
|
+
return this.restore(snapshot, options);
|
|
2475
2779
|
},
|
|
2476
2780
|
deleteSandboxSnapshot: async (snapshot) => {
|
|
2477
2781
|
await this.deleteSnapshot(snapshot);
|
|
2478
2782
|
},
|
|
2479
|
-
forkSandbox: async (sandboxId) => {
|
|
2480
|
-
return this.fork(sandboxId);
|
|
2783
|
+
forkSandbox: async (sandboxId, options) => {
|
|
2784
|
+
return this.fork(sandboxId, options);
|
|
2481
2785
|
}
|
|
2482
2786
|
};
|
|
2483
2787
|
const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
@@ -3146,6 +3450,6 @@ var toTree = async (fs, opts = {}) => {
|
|
|
3146
3450
|
return base + subtree;
|
|
3147
3451
|
};
|
|
3148
3452
|
|
|
3149
|
-
export { FileSystemSkillProvider, NodeFsSandboxFileSystem, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, VirtualFileSystem, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, composeHooks, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createObservabilityHooks, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createToolRouter, createVirtualFsActivities, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, filesWithMimeType, formatVirtualFileTree, getActivityContext, getShortId, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyRunAgent, proxyVirtualFsOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler, writeFileTool };
|
|
3453
|
+
export { DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, FileSystemSkillProvider, NodeFsSandboxFileSystem, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, THREAD_TTL_SECONDS, VirtualFileSystem, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, composeHooks, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createObservabilityHooks, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createToolRouter, createVirtualFsActivities, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, filesWithMimeType, formatVirtualFileTree, getActivityContext, getShortId, getThreadListKey, getThreadMetaKey, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyRunAgent, proxyVirtualFsOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler, writeFileTool };
|
|
3150
3454
|
//# sourceMappingURL=index.js.map
|
|
3151
3455
|
//# sourceMappingURL=index.js.map
|