zeitlich 0.2.22 → 0.2.23
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 +242 -59
- package/dist/adapters/sandbox/daytona/index.cjs +4 -1
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +2 -1
- package/dist/adapters/sandbox/daytona/index.d.ts +2 -1
- package/dist/adapters/sandbox/daytona/index.js +4 -1
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.cjs +1 -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 +1 -0
- package/dist/adapters/sandbox/daytona/workflow.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs +16 -2
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +3 -2
- package/dist/adapters/sandbox/inmemory/index.d.ts +3 -2
- package/dist/adapters/sandbox/inmemory/index.js +16 -2
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.cjs +1 -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 +1 -0
- package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -1
- package/dist/adapters/sandbox/virtual/index.cjs +33 -9
- package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
- package/dist/adapters/sandbox/virtual/index.d.cts +6 -5
- package/dist/adapters/sandbox/virtual/index.d.ts +6 -5
- package/dist/adapters/sandbox/virtual/index.js +33 -9
- package/dist/adapters/sandbox/virtual/index.js.map +1 -1
- package/dist/adapters/sandbox/virtual/workflow.cjs +1 -0
- package/dist/adapters/sandbox/virtual/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/virtual/workflow.d.cts +3 -3
- package/dist/adapters/sandbox/virtual/workflow.d.ts +3 -3
- package/dist/adapters/sandbox/virtual/workflow.js +1 -0
- package/dist/adapters/sandbox/virtual/workflow.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +3 -3
- package/dist/adapters/thread/google-genai/index.d.ts +3 -3
- package/dist/adapters/thread/google-genai/workflow.d.cts +3 -3
- package/dist/adapters/thread/google-genai/workflow.d.ts +3 -3
- package/dist/adapters/thread/langchain/index.d.cts +3 -3
- package/dist/adapters/thread/langchain/index.d.ts +3 -3
- package/dist/adapters/thread/langchain/workflow.d.cts +3 -3
- package/dist/adapters/thread/langchain/workflow.d.ts +3 -3
- package/dist/index.cjs +247 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +245 -55
- package/dist/index.js.map +1 -1
- package/dist/{queries-Bw6WEPMw.d.cts → queries-DModcWRy.d.cts} +1 -1
- package/dist/{queries-C27raDaB.d.ts → queries-byD0jr1Y.d.ts} +1 -1
- package/dist/{types-ClsHhtwL.d.cts → types-B50pBPEV.d.ts} +159 -35
- package/dist/{types-YbL7JpEA.d.cts → types-Bll19FZJ.d.cts} +7 -0
- package/dist/{types-YbL7JpEA.d.ts → types-Bll19FZJ.d.ts} +7 -0
- package/dist/{types-BJ8itUAl.d.cts → types-BuXdFhaZ.d.cts} +6 -6
- package/dist/{types-HBosetv3.d.cts → types-ChAMwU3q.d.cts} +2 -0
- package/dist/{types-HBosetv3.d.ts → types-ChAMwU3q.d.ts} +2 -0
- package/dist/{types-C5bkx6kQ.d.ts → types-DQW8l7pY.d.cts} +159 -35
- package/dist/{types-ENYCKFBk.d.ts → types-GZ76HZSj.d.ts} +6 -6
- package/dist/workflow.cjs +241 -57
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +49 -32
- package/dist/workflow.d.ts +49 -32
- package/dist/workflow.js +239 -55
- package/dist/workflow.js.map +1 -1
- package/package.json +2 -2
- package/src/adapters/sandbox/daytona/filesystem.ts +1 -1
- package/src/adapters/sandbox/daytona/index.ts +4 -0
- package/src/adapters/sandbox/daytona/proxy.ts +4 -3
- package/src/adapters/sandbox/e2b/index.ts +5 -0
- package/src/adapters/sandbox/inmemory/index.ts +24 -4
- package/src/adapters/sandbox/inmemory/proxy.ts +2 -2
- package/src/adapters/sandbox/virtual/filesystem.ts +41 -17
- package/src/adapters/sandbox/virtual/provider.ts +4 -0
- package/src/adapters/sandbox/virtual/proxy.ts +1 -0
- package/src/adapters/sandbox/virtual/types.ts +9 -4
- package/src/lib/lifecycle.ts +57 -0
- package/src/lib/sandbox/manager.ts +13 -1
- package/src/lib/sandbox/types.ts +13 -4
- package/src/lib/session/index.ts +1 -0
- package/src/lib/session/session-edge-cases.integration.test.ts +447 -33
- package/src/lib/session/session.integration.test.ts +52 -32
- package/src/lib/session/session.ts +107 -33
- package/src/lib/session/types.ts +55 -16
- package/src/lib/subagent/define.ts +5 -4
- package/src/lib/subagent/handler.ts +139 -14
- package/src/lib/subagent/index.ts +3 -0
- package/src/lib/subagent/register.ts +10 -3
- package/src/lib/subagent/signals.ts +8 -0
- package/src/lib/subagent/subagent.integration.test.ts +853 -150
- package/src/lib/subagent/tool.ts +2 -2
- package/src/lib/subagent/types.ts +77 -19
- package/src/lib/subagent/workflow.ts +83 -12
- package/src/lib/tool-router/router.integration.test.ts +137 -4
- package/src/lib/tool-router/router.ts +13 -3
- package/src/lib/tool-router/types.ts +7 -0
- package/src/lib/workflow.test.ts +89 -21
- package/src/lib/workflow.ts +33 -18
- package/src/workflow.ts +6 -1
package/dist/workflow.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { uuid4, setHandler, defineUpdate, ApplicationFailure, condition, defineQuery, workflowInfo,
|
|
1
|
+
import { defineSignal, uuid4, setHandler, defineUpdate, ApplicationFailure, condition, defineQuery, workflowInfo, getExternalWorkflowHandle, startChild } from '@temporalio/workflow';
|
|
2
2
|
import z14, { z } from 'zod';
|
|
3
3
|
import { ApplicationFailure as ApplicationFailure$1 } from '@temporalio/common';
|
|
4
4
|
|
|
@@ -79,7 +79,12 @@ function createToolRouter(options) {
|
|
|
79
79
|
result: { error: errorStr, suppressed: true }
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
return {
|
|
83
|
+
content: JSON.stringify({
|
|
84
|
+
error: "The tool encountered an error. Please try again or use a different approach."
|
|
85
|
+
}),
|
|
86
|
+
result: { error: errorStr, suppressed: true }
|
|
87
|
+
};
|
|
83
88
|
}
|
|
84
89
|
async function runPostHooks(toolCall, tool, toolResult, effectiveArgs, turn, durationMs) {
|
|
85
90
|
if (tool?.hooks?.onPostToolUse) {
|
|
@@ -88,7 +93,8 @@ function createToolRouter(options) {
|
|
|
88
93
|
result: toolResult.data,
|
|
89
94
|
threadId: options.threadId,
|
|
90
95
|
turn,
|
|
91
|
-
durationMs
|
|
96
|
+
durationMs,
|
|
97
|
+
...toolResult.metadata && { metadata: toolResult.metadata }
|
|
92
98
|
});
|
|
93
99
|
}
|
|
94
100
|
if (options.hooks?.onPostToolUse) {
|
|
@@ -121,6 +127,7 @@ function createToolRouter(options) {
|
|
|
121
127
|
let result;
|
|
122
128
|
let content;
|
|
123
129
|
let resultAppended = false;
|
|
130
|
+
let metadata;
|
|
124
131
|
try {
|
|
125
132
|
if (tool) {
|
|
126
133
|
const routerContext = {
|
|
@@ -136,6 +143,7 @@ function createToolRouter(options) {
|
|
|
136
143
|
result = response.data;
|
|
137
144
|
content = response.toolResponse;
|
|
138
145
|
resultAppended = response.resultAppended === true;
|
|
146
|
+
metadata = response.metadata;
|
|
139
147
|
} else {
|
|
140
148
|
result = { error: `Unknown tool: ${toolCall.name}` };
|
|
141
149
|
content = JSON.stringify(result, null, 2);
|
|
@@ -168,7 +176,8 @@ function createToolRouter(options) {
|
|
|
168
176
|
const toolResult = {
|
|
169
177
|
toolCallId: toolCall.id,
|
|
170
178
|
name: toolCall.name,
|
|
171
|
-
data: result
|
|
179
|
+
data: result,
|
|
180
|
+
...metadata && { metadata }
|
|
172
181
|
};
|
|
173
182
|
await runPostHooks(
|
|
174
183
|
toolCall,
|
|
@@ -272,7 +281,8 @@ function createToolRouter(options) {
|
|
|
272
281
|
return {
|
|
273
282
|
toolCallId: toolCall.id,
|
|
274
283
|
name: toolCall.name,
|
|
275
|
-
data: response.data
|
|
284
|
+
data: response.data,
|
|
285
|
+
...response.metadata && { metadata: response.metadata }
|
|
276
286
|
};
|
|
277
287
|
};
|
|
278
288
|
if (options.parallel) {
|
|
@@ -316,7 +326,7 @@ function getShortId(length = 12) {
|
|
|
316
326
|
var SUBAGENT_TOOL_NAME = "Subagent";
|
|
317
327
|
function buildSubagentDescription(subagents) {
|
|
318
328
|
const subagentList = subagents.map((s) => {
|
|
319
|
-
const continuation = s.
|
|
329
|
+
const continuation = s.thread && s.thread !== "new" ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
|
|
320
330
|
return `## ${s.agentName}
|
|
321
331
|
${s.description}${continuation}`;
|
|
322
332
|
}).join("\n\n");
|
|
@@ -332,7 +342,7 @@ function createSubagentTool(subagents) {
|
|
|
332
342
|
}
|
|
333
343
|
const names = subagents.map((s) => s.agentName);
|
|
334
344
|
const hasThreadContinuation = subagents.some(
|
|
335
|
-
(s) => s.
|
|
345
|
+
(s) => s.thread && s.thread !== "new"
|
|
336
346
|
);
|
|
337
347
|
const baseFields = {
|
|
338
348
|
subagent: z14.enum(names).describe("The type of subagent to launch"),
|
|
@@ -351,9 +361,25 @@ function createSubagentTool(subagents) {
|
|
|
351
361
|
schema
|
|
352
362
|
};
|
|
353
363
|
}
|
|
364
|
+
var childResultSignal = defineSignal("childResult");
|
|
365
|
+
var destroySandboxSignal = defineSignal("destroySandbox");
|
|
366
|
+
|
|
367
|
+
// src/lib/subagent/handler.ts
|
|
368
|
+
function resolveSandboxConfig(config) {
|
|
369
|
+
if (!config || config === "none") return { source: "none" };
|
|
370
|
+
if (config === "inherit") return { source: "inherit" };
|
|
371
|
+
if (config === "own") return { source: "own" };
|
|
372
|
+
return { source: "own", shutdown: config.shutdown };
|
|
373
|
+
}
|
|
354
374
|
function createSubagentHandler(subagents) {
|
|
355
375
|
const { taskQueue: parentTaskQueue } = workflowInfo();
|
|
356
|
-
|
|
376
|
+
const childResults = /* @__PURE__ */ new Map();
|
|
377
|
+
const pendingDestroys = /* @__PURE__ */ new Map();
|
|
378
|
+
const threadSandboxes = /* @__PURE__ */ new Map();
|
|
379
|
+
setHandler(childResultSignal, ({ childWorkflowId, result }) => {
|
|
380
|
+
childResults.set(childWorkflowId, result);
|
|
381
|
+
});
|
|
382
|
+
const handler = async (args, context) => {
|
|
357
383
|
const config = subagents.find((s) => s.agentName === args.subagent);
|
|
358
384
|
if (!config) {
|
|
359
385
|
throw new Error(
|
|
@@ -362,12 +388,32 @@ function createSubagentHandler(subagents) {
|
|
|
362
388
|
}
|
|
363
389
|
const childWorkflowId = `${args.subagent}-${getShortId()}`;
|
|
364
390
|
const { sandboxId: parentSandboxId } = context;
|
|
365
|
-
const
|
|
391
|
+
const sandboxCfg = resolveSandboxConfig(config.sandbox);
|
|
392
|
+
if (sandboxCfg.source === "inherit" && !parentSandboxId) {
|
|
393
|
+
throw new Error(
|
|
394
|
+
`Subagent "${config.agentName}" is configured with sandbox: "inherit" but the parent has no sandbox`
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
const threadMode = config.thread ?? "new";
|
|
398
|
+
const allowsContinuation = threadMode !== "new";
|
|
399
|
+
const continuationThreadId = args.threadId && allowsContinuation ? args.threadId : void 0;
|
|
400
|
+
let thread;
|
|
401
|
+
if (continuationThreadId) {
|
|
402
|
+
thread = { mode: threadMode, threadId: continuationThreadId };
|
|
403
|
+
}
|
|
404
|
+
let sandbox;
|
|
405
|
+
if (sandboxCfg.source === "inherit" && parentSandboxId) {
|
|
406
|
+
sandbox = { mode: "inherit", sandboxId: parentSandboxId };
|
|
407
|
+
} else if (sandboxCfg.source === "own") {
|
|
408
|
+
const prevSbId = continuationThreadId ? threadSandboxes.get(continuationThreadId) : void 0;
|
|
409
|
+
if (prevSbId) {
|
|
410
|
+
sandbox = { mode: "fork", sandboxId: prevSbId };
|
|
411
|
+
}
|
|
412
|
+
}
|
|
366
413
|
const workflowInput = {
|
|
367
|
-
...
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
...inheritSandbox && { sandboxId: parentSandboxId }
|
|
414
|
+
...thread && { thread },
|
|
415
|
+
...sandbox && { sandbox },
|
|
416
|
+
...sandboxCfg.shutdown && { sandboxShutdown: sandboxCfg.shutdown }
|
|
371
417
|
};
|
|
372
418
|
const resolvedContext = config.context === void 0 ? void 0 : typeof config.context === "function" ? config.context() : config.context;
|
|
373
419
|
const childOpts = {
|
|
@@ -375,17 +421,44 @@ function createSubagentHandler(subagents) {
|
|
|
375
421
|
args: resolvedContext === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, resolvedContext],
|
|
376
422
|
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
377
423
|
};
|
|
424
|
+
const childHandle = await startChild(config.workflow, childOpts);
|
|
425
|
+
const usesOwnSandbox = sandboxCfg.source === "own" || allowsContinuation && sandboxCfg.source !== "inherit";
|
|
426
|
+
if (usesOwnSandbox) {
|
|
427
|
+
pendingDestroys.set(childWorkflowId, childHandle);
|
|
428
|
+
}
|
|
429
|
+
await Promise.race([
|
|
430
|
+
condition(() => childResults.has(childWorkflowId)),
|
|
431
|
+
childHandle.result()
|
|
432
|
+
]);
|
|
433
|
+
if (!childResults.has(childWorkflowId)) {
|
|
434
|
+
await condition(() => childResults.has(childWorkflowId));
|
|
435
|
+
}
|
|
436
|
+
const childResult = childResults.get(childWorkflowId);
|
|
437
|
+
childResults.delete(childWorkflowId);
|
|
438
|
+
if (!childResult) {
|
|
439
|
+
return {
|
|
440
|
+
toolResponse: "Subagent workflow did not signal a result",
|
|
441
|
+
data: null
|
|
442
|
+
};
|
|
443
|
+
}
|
|
378
444
|
const {
|
|
379
445
|
toolResponse,
|
|
380
446
|
data,
|
|
381
447
|
usage,
|
|
382
|
-
threadId: childThreadId
|
|
383
|
-
|
|
448
|
+
threadId: childThreadId,
|
|
449
|
+
sandboxId: childSandboxId,
|
|
450
|
+
metadata
|
|
451
|
+
} = childResult;
|
|
452
|
+
if (allowsContinuation && childSandboxId && childThreadId) {
|
|
453
|
+
threadSandboxes.set(childThreadId, childSandboxId);
|
|
454
|
+
}
|
|
384
455
|
if (!toolResponse) {
|
|
385
456
|
return {
|
|
386
457
|
toolResponse: "Subagent workflow returned no response",
|
|
387
458
|
data: null,
|
|
388
|
-
...usage && { usage }
|
|
459
|
+
...usage && { usage },
|
|
460
|
+
...childSandboxId && { sandboxId: childSandboxId },
|
|
461
|
+
...metadata && { metadata }
|
|
389
462
|
};
|
|
390
463
|
}
|
|
391
464
|
const validated = config.resultSchema ? config.resultSchema.safeParse(data) : null;
|
|
@@ -393,11 +466,13 @@ function createSubagentHandler(subagents) {
|
|
|
393
466
|
return {
|
|
394
467
|
toolResponse: `Subagent workflow returned invalid data: ${validated.error.message}`,
|
|
395
468
|
data: null,
|
|
396
|
-
...usage && { usage }
|
|
469
|
+
...usage && { usage },
|
|
470
|
+
...childSandboxId && { sandboxId: childSandboxId },
|
|
471
|
+
...metadata && { metadata }
|
|
397
472
|
};
|
|
398
473
|
}
|
|
399
474
|
let finalToolResponse = toolResponse;
|
|
400
|
-
if (
|
|
475
|
+
if (allowsContinuation && childThreadId) {
|
|
401
476
|
finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
|
|
402
477
|
|
|
403
478
|
[${config.agentName} Thread ID: ${childThreadId}]` : toolResponse;
|
|
@@ -405,9 +480,22 @@ function createSubagentHandler(subagents) {
|
|
|
405
480
|
return {
|
|
406
481
|
toolResponse: finalToolResponse,
|
|
407
482
|
data: validated ? validated.data : data,
|
|
408
|
-
...usage && { usage }
|
|
483
|
+
...usage && { usage },
|
|
484
|
+
...childSandboxId && { sandboxId: childSandboxId },
|
|
485
|
+
...metadata && { metadata }
|
|
409
486
|
};
|
|
410
487
|
};
|
|
488
|
+
const destroySubagentSandboxes = async () => {
|
|
489
|
+
const handles = [...pendingDestroys.values()];
|
|
490
|
+
pendingDestroys.clear();
|
|
491
|
+
await Promise.all(
|
|
492
|
+
handles.map(async (handle) => {
|
|
493
|
+
await handle.signal(destroySandboxSignal);
|
|
494
|
+
await handle.result();
|
|
495
|
+
})
|
|
496
|
+
);
|
|
497
|
+
};
|
|
498
|
+
return { handler, destroySubagentSandboxes };
|
|
411
499
|
}
|
|
412
500
|
|
|
413
501
|
// src/lib/subagent/register.ts
|
|
@@ -421,12 +509,13 @@ function buildSubagentRegistration(subagents) {
|
|
|
421
509
|
if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
|
|
422
510
|
}
|
|
423
511
|
const resolveSubagentName = (args) => args.subagent;
|
|
424
|
-
|
|
512
|
+
const { handler, destroySubagentSandboxes } = createSubagentHandler(subagents);
|
|
513
|
+
const registration = {
|
|
425
514
|
name: SUBAGENT_TOOL_NAME,
|
|
426
515
|
enabled: () => getEnabled().length > 0,
|
|
427
516
|
description: () => createSubagentTool(getEnabled()).description,
|
|
428
517
|
schema: () => createSubagentTool(getEnabled()).schema,
|
|
429
|
-
handler
|
|
518
|
+
handler,
|
|
430
519
|
...subagentHooksMap.size > 0 && {
|
|
431
520
|
hooks: {
|
|
432
521
|
onPreToolUse: async (ctx) => {
|
|
@@ -444,6 +533,7 @@ function buildSubagentRegistration(subagents) {
|
|
|
444
533
|
}
|
|
445
534
|
}
|
|
446
535
|
};
|
|
536
|
+
return { registration, destroySubagentSandboxes };
|
|
447
537
|
}
|
|
448
538
|
var READ_SKILL_TOOL_NAME = "ReadSkill";
|
|
449
539
|
function buildReadSkillDescription(skills) {
|
|
@@ -496,8 +586,7 @@ function buildSkillRegistration(skills) {
|
|
|
496
586
|
handler: createReadSkillHandler(skills)
|
|
497
587
|
};
|
|
498
588
|
}
|
|
499
|
-
|
|
500
|
-
threadId: providedThreadId,
|
|
589
|
+
async function createSession({
|
|
501
590
|
agentName,
|
|
502
591
|
maxTurns = 50,
|
|
503
592
|
metadata = {},
|
|
@@ -510,13 +599,27 @@ var createSession = async ({
|
|
|
510
599
|
processToolsInParallel = true,
|
|
511
600
|
hooks = {},
|
|
512
601
|
appendSystemPrompt = true,
|
|
513
|
-
continueThread = false,
|
|
514
602
|
waitForInputTimeout = "48h",
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
603
|
+
sandboxOps,
|
|
604
|
+
thread: threadInit,
|
|
605
|
+
sandbox: sandboxInit,
|
|
606
|
+
sandboxShutdown = "destroy"
|
|
607
|
+
}) {
|
|
608
|
+
const threadMode = threadInit?.mode ?? "new";
|
|
609
|
+
let threadId;
|
|
610
|
+
let sourceThreadId;
|
|
611
|
+
switch (threadMode) {
|
|
612
|
+
case "new":
|
|
613
|
+
threadId = threadInit?.mode === "new" && threadInit.threadId ? threadInit.threadId : getShortId();
|
|
614
|
+
break;
|
|
615
|
+
case "continue":
|
|
616
|
+
threadId = threadInit.threadId;
|
|
617
|
+
break;
|
|
618
|
+
case "fork":
|
|
619
|
+
sourceThreadId = threadInit.threadId;
|
|
620
|
+
threadId = getShortId();
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
520
623
|
const {
|
|
521
624
|
appendToolResult,
|
|
522
625
|
appendHumanMessage,
|
|
@@ -525,9 +628,13 @@ var createSession = async ({
|
|
|
525
628
|
forkThread
|
|
526
629
|
} = threadOps;
|
|
527
630
|
const plugins = [];
|
|
631
|
+
let destroySubagentSandboxes;
|
|
528
632
|
if (subagents) {
|
|
529
|
-
const
|
|
530
|
-
if (
|
|
633
|
+
const result = buildSubagentRegistration(subagents);
|
|
634
|
+
if (result) {
|
|
635
|
+
plugins.push(result.registration);
|
|
636
|
+
destroySubagentSandboxes = result.destroySubagentSandboxes;
|
|
637
|
+
}
|
|
531
638
|
}
|
|
532
639
|
if (skills) {
|
|
533
640
|
const reg = buildSkillRegistration(skills);
|
|
@@ -575,11 +682,41 @@ var createSession = async ({
|
|
|
575
682
|
stateManager.run();
|
|
576
683
|
}
|
|
577
684
|
);
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
685
|
+
const sandboxMode = sandboxInit?.mode;
|
|
686
|
+
let sandboxId;
|
|
687
|
+
let sandboxOwned = false;
|
|
688
|
+
if (sandboxMode === "inherit") {
|
|
689
|
+
sandboxId = sandboxInit.sandboxId;
|
|
690
|
+
if (!sandboxOps) {
|
|
691
|
+
throw ApplicationFailure.create({
|
|
692
|
+
message: "sandboxId provided but no sandboxOps \u2014 cannot manage sandbox lifecycle",
|
|
693
|
+
nonRetryable: true
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
} else if (sandboxMode === "continue") {
|
|
697
|
+
if (!sandboxOps) {
|
|
698
|
+
throw ApplicationFailure.create({
|
|
699
|
+
message: "No sandboxOps provided \u2014 cannot continue sandbox",
|
|
700
|
+
nonRetryable: true
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
sandboxId = sandboxInit.sandboxId;
|
|
704
|
+
sandboxOwned = true;
|
|
705
|
+
} else if (sandboxMode === "fork") {
|
|
706
|
+
if (!sandboxOps) {
|
|
707
|
+
throw ApplicationFailure.create({
|
|
708
|
+
message: "No sandboxOps provided \u2014 cannot fork sandbox",
|
|
709
|
+
nonRetryable: true
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
sandboxId = await sandboxOps.forkSandbox(
|
|
713
|
+
sandboxInit.sandboxId
|
|
714
|
+
);
|
|
715
|
+
sandboxOwned = true;
|
|
716
|
+
} else if (sandboxOps) {
|
|
717
|
+
const result = await sandboxOps.createSandbox();
|
|
582
718
|
sandboxId = result.sandboxId;
|
|
719
|
+
sandboxOwned = true;
|
|
583
720
|
if (result.stateUpdate) {
|
|
584
721
|
stateManager.mergeUpdate(result.stateUpdate);
|
|
585
722
|
}
|
|
@@ -592,9 +729,9 @@ var createSession = async ({
|
|
|
592
729
|
});
|
|
593
730
|
}
|
|
594
731
|
const systemPrompt = stateManager.getSystemPrompt();
|
|
595
|
-
if (
|
|
732
|
+
if (threadMode === "fork" && sourceThreadId) {
|
|
596
733
|
await forkThread(sourceThreadId, threadId);
|
|
597
|
-
} else {
|
|
734
|
+
} else if (threadMode === "continue") ; else {
|
|
598
735
|
if (appendSystemPrompt) {
|
|
599
736
|
if (!systemPrompt || systemPrompt.trim() === "") {
|
|
600
737
|
throw ApplicationFailure.create({
|
|
@@ -629,7 +766,8 @@ var createSession = async ({
|
|
|
629
766
|
threadId,
|
|
630
767
|
finalMessage: message,
|
|
631
768
|
exitReason,
|
|
632
|
-
usage: stateManager.getTotalUsage()
|
|
769
|
+
usage: stateManager.getTotalUsage(),
|
|
770
|
+
sandboxId
|
|
633
771
|
};
|
|
634
772
|
}
|
|
635
773
|
const parsedToolCalls = [];
|
|
@@ -680,30 +818,40 @@ var createSession = async ({
|
|
|
680
818
|
throw ApplicationFailure.fromError(error);
|
|
681
819
|
} finally {
|
|
682
820
|
await callSessionEnd(exitReason, stateManager.getTurns());
|
|
683
|
-
if (
|
|
684
|
-
|
|
821
|
+
if (sandboxOwned && sandboxId && sandboxOps) {
|
|
822
|
+
switch (sandboxShutdown) {
|
|
823
|
+
case "destroy":
|
|
824
|
+
await sandboxOps.destroySandbox(sandboxId);
|
|
825
|
+
break;
|
|
826
|
+
case "pause":
|
|
827
|
+
case "pause-until-parent-close":
|
|
828
|
+
await sandboxOps.pauseSandbox(sandboxId);
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
if (destroySubagentSandboxes) {
|
|
833
|
+
await destroySubagentSandboxes();
|
|
685
834
|
}
|
|
686
835
|
}
|
|
687
836
|
return {
|
|
688
837
|
threadId,
|
|
689
838
|
finalMessage: null,
|
|
690
839
|
exitReason,
|
|
691
|
-
usage: stateManager.getTotalUsage()
|
|
840
|
+
usage: stateManager.getTotalUsage(),
|
|
841
|
+
sandboxId
|
|
692
842
|
};
|
|
693
843
|
}
|
|
694
844
|
};
|
|
695
|
-
}
|
|
845
|
+
}
|
|
696
846
|
|
|
697
847
|
// src/lib/workflow.ts
|
|
698
848
|
function defineWorkflow(config, fn) {
|
|
699
849
|
const workflow = async (input, workflowInput = {}) => {
|
|
700
850
|
const sessionInput = {
|
|
701
851
|
agentName: config.name,
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
},
|
|
706
|
-
...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
|
|
852
|
+
sandboxShutdown: config.sandboxShutdown ?? "destroy",
|
|
853
|
+
...workflowInput.thread && { thread: workflowInput.thread },
|
|
854
|
+
...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
|
|
707
855
|
};
|
|
708
856
|
return fn(input, sessionInput);
|
|
709
857
|
};
|
|
@@ -884,19 +1032,55 @@ function defineSubagent(definition, overrides) {
|
|
|
884
1032
|
...overrides
|
|
885
1033
|
};
|
|
886
1034
|
}
|
|
887
|
-
|
|
888
|
-
// src/lib/subagent/workflow.ts
|
|
889
1035
|
function defineSubagentWorkflow(config, fn) {
|
|
890
1036
|
const workflow = async (prompt, workflowInput, context) => {
|
|
1037
|
+
const effectiveShutdown = workflowInput.sandboxShutdown ?? config.sandboxShutdown ?? "destroy";
|
|
891
1038
|
const sessionInput = {
|
|
892
1039
|
agentName: config.name,
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
},
|
|
897
|
-
...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
|
|
1040
|
+
sandboxShutdown: effectiveShutdown,
|
|
1041
|
+
...workflowInput.thread && { thread: workflowInput.thread },
|
|
1042
|
+
...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
|
|
898
1043
|
};
|
|
899
|
-
|
|
1044
|
+
const { destroySandbox, ...result } = await fn(
|
|
1045
|
+
prompt,
|
|
1046
|
+
sessionInput,
|
|
1047
|
+
context ?? {}
|
|
1048
|
+
);
|
|
1049
|
+
if (effectiveShutdown === "pause-until-parent-close") {
|
|
1050
|
+
if (!destroySandbox) {
|
|
1051
|
+
throw ApplicationFailure.create({
|
|
1052
|
+
message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a destroySandbox callback`,
|
|
1053
|
+
nonRetryable: true
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
if (!result.sandboxId) {
|
|
1057
|
+
throw ApplicationFailure.create({
|
|
1058
|
+
message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a sandboxId`,
|
|
1059
|
+
nonRetryable: true
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
const { parent } = workflowInfo();
|
|
1064
|
+
if (!parent) {
|
|
1065
|
+
throw ApplicationFailure.create({
|
|
1066
|
+
message: "Subagent workflow called without a parent workflow",
|
|
1067
|
+
nonRetryable: true
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
const parentHandle = getExternalWorkflowHandle(parent.workflowId);
|
|
1071
|
+
await parentHandle.signal(childResultSignal, {
|
|
1072
|
+
childWorkflowId: workflowInfo().workflowId,
|
|
1073
|
+
result
|
|
1074
|
+
});
|
|
1075
|
+
if (destroySandbox) {
|
|
1076
|
+
let destroyRequested = false;
|
|
1077
|
+
setHandler(destroySandboxSignal, () => {
|
|
1078
|
+
destroyRequested = true;
|
|
1079
|
+
});
|
|
1080
|
+
await condition(() => destroyRequested);
|
|
1081
|
+
await destroySandbox();
|
|
1082
|
+
}
|
|
1083
|
+
return result;
|
|
900
1084
|
};
|
|
901
1085
|
Object.defineProperty(workflow, "name", { value: config.name });
|
|
902
1086
|
return Object.assign(workflow, {
|