zeitlich 0.2.38 → 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-BKhMtKDd.d.ts → activities-Bmu7XnaG.d.ts} +4 -6
- package/dist/{activities-CDcwkRZs.d.cts → activities-ByBFLvm2.d.cts} +4 -6
- 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/thread/anthropic/index.cjs +140 -23
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +8 -7
- package/dist/adapters/thread/anthropic/index.d.ts +8 -7
- package/dist/adapters/thread/anthropic/index.js +140 -24
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.cjs +8 -3
- package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -4
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -4
- package/dist/adapters/thread/anthropic/workflow.js +8 -4
- package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.cjs +140 -23
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +5 -4
- package/dist/adapters/thread/google-genai/index.d.ts +5 -4
- package/dist/adapters/thread/google-genai/index.js +140 -24
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.cjs +8 -3
- package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +5 -4
- package/dist/adapters/thread/google-genai/workflow.d.ts +5 -4
- package/dist/adapters/thread/google-genai/workflow.js +8 -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 +139 -24
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +8 -7
- package/dist/adapters/thread/langchain/index.d.ts +8 -7
- package/dist/adapters/thread/langchain/index.js +139 -25
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.cjs +8 -3
- package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -4
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -4
- package/dist/adapters/thread/langchain/workflow.js +8 -4
- package/dist/adapters/thread/langchain/workflow.js.map +1 -1
- package/dist/index.cjs +266 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +263 -49
- package/dist/index.js.map +1 -1
- package/dist/{proxy-D_3x7RN4.d.cts → proxy-BAKzNGRq.d.cts} +1 -1
- package/dist/{proxy-CUlKSvZS.d.ts → proxy-DO_MXbY4.d.ts} +1 -1
- package/dist/{thread-manager-CVu7o2cs.d.ts → thread-manager-CcRXasqs.d.ts} +2 -4
- package/dist/{thread-manager-HSwyh28L.d.cts → thread-manager-ClwSaUnj.d.cts} +2 -4
- package/dist/{thread-manager-c1gPopAG.d.ts → thread-manager-D-7lp1JK.d.ts} +2 -4
- package/dist/{thread-manager-wGi-LqIP.d.cts → thread-manager-Y8Ucf0Tf.d.cts} +2 -4
- package/dist/{types-C06FwR96.d.cts → types-Bcbiq8iv.d.cts} +162 -44
- package/dist/{types-BH_IRryz.d.ts → types-DpHTX-iO.d.ts} +54 -6
- package/dist/{types-DNr31FzL.d.ts → types-Dt8-HBBT.d.ts} +162 -44
- package/dist/{types-BaOw4hKI.d.cts → types-hFFi-Zd9.d.cts} +54 -6
- package/dist/{workflow-CSCkpwAL.d.ts → workflow-Bmf9EtDW.d.ts} +82 -2
- package/dist/{workflow-DuvMZ8Vm.d.cts → workflow-Bx9utBwb.d.cts} +82 -2
- package/dist/workflow.cjs +188 -37
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +2 -2
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +185 -38
- package/dist/workflow.js.map +1 -1
- package/package.json +11 -1
- package/src/adapters/thread/adapter-id.test.ts +42 -0
- package/src/adapters/thread/anthropic/activities.ts +33 -7
- 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 +8 -4
- package/src/adapters/thread/anthropic/proxy.ts +3 -2
- package/src/adapters/thread/anthropic/thread-manager.ts +27 -4
- package/src/adapters/thread/google-genai/activities.ts +33 -7
- 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 +7 -3
- package/src/adapters/thread/google-genai/proxy.ts +3 -2
- package/src/adapters/thread/google-genai/thread-manager.ts +27 -4
- package/src/adapters/thread/index.ts +39 -0
- package/src/adapters/thread/langchain/activities.ts +33 -7
- 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 +8 -3
- package/src/adapters/thread/langchain/proxy.ts +3 -2
- package/src/adapters/thread/langchain/thread-manager.ts +27 -4
- package/src/lib/lifecycle.ts +3 -1
- package/src/lib/model/types.ts +7 -10
- package/src/lib/session/session-edge-cases.integration.test.ts +131 -63
- package/src/lib/session/session.integration.test.ts +174 -5
- package/src/lib/session/session.ts +68 -28
- package/src/lib/session/types.ts +60 -9
- 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 +528 -0
- 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 +92 -14
- package/src/lib/thread/proxy.ts +2 -0
- package/src/lib/thread/types.ts +60 -6
- package/src/lib/tool-router/types.ts +16 -8
- package/src/lib/types.ts +12 -0
- package/src/workflow.ts +12 -1
- package/tsup.config.ts +1 -0
|
@@ -12,6 +12,7 @@ import type { JsonValue } from "../state/types";
|
|
|
12
12
|
import type {
|
|
13
13
|
InferSubagentResult,
|
|
14
14
|
SubagentConfig,
|
|
15
|
+
SubagentFnResult,
|
|
15
16
|
SubagentSandboxConfig,
|
|
16
17
|
SubagentWorkflowInput,
|
|
17
18
|
} from "./types";
|
|
@@ -25,6 +26,22 @@ import type {
|
|
|
25
26
|
import type { SandboxOps, SandboxSnapshot } from "../sandbox/types";
|
|
26
27
|
import { childSandboxReadySignal } from "./signals";
|
|
27
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Default `workflowRunTimeout` applied to every subagent child workflow
|
|
31
|
+
* unless overridden via `SubagentConfig.workflowOptions.workflowRunTimeout`.
|
|
32
|
+
*
|
|
33
|
+
* Chosen as a safety bound: Temporal retries failing workflow tasks forever
|
|
34
|
+
* by default, so a child that fails to initialize (e.g. missing workflow
|
|
35
|
+
* export) or is otherwise broken will never reach a terminal state on its
|
|
36
|
+
* own and the parent's `Subagent` tool call would hang indefinitely. A
|
|
37
|
+
* bounded run timeout guarantees the child is eventually terminated and the
|
|
38
|
+
* parent receives a structured `ChildWorkflowFailure` it can surface to the
|
|
39
|
+
* agent. One hour is generous enough for realistic agent sessions while
|
|
40
|
+
* still catching hangs; agents that legitimately need longer should set an
|
|
41
|
+
* explicit `workflowOptions.workflowRunTimeout`.
|
|
42
|
+
*/
|
|
43
|
+
export const DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT = "1h";
|
|
44
|
+
|
|
28
45
|
/** Normalized sandbox config after resolving the union. */
|
|
29
46
|
interface ResolvedSandboxConfig {
|
|
30
47
|
source: "none" | "inherit" | "own";
|
|
@@ -103,8 +120,18 @@ export function createSubagentHandler<
|
|
|
103
120
|
const persistentSandboxes = new Map<string, string>();
|
|
104
121
|
/** Tracks agents whose first lazy sandbox creation is in-flight (guards concurrent init) */
|
|
105
122
|
const persistentSandboxCreating = new Set<string>();
|
|
123
|
+
/**
|
|
124
|
+
* Latest failure from a lazy-creator call, keyed by agentName. Populated
|
|
125
|
+
* when a creator's `executeChild` throws, consumed by concurrent waiters so
|
|
126
|
+
* they fail deterministically instead of hanging on a condition predicate
|
|
127
|
+
* that will never be satisfied. Cleared once observed by all current
|
|
128
|
+
* waiters (on the next successful creator attempt).
|
|
129
|
+
*/
|
|
130
|
+
const persistentSandboxCreationError = new Map<string, unknown>();
|
|
106
131
|
/** Reverse lookup: childWorkflowId → agentName for in-flight lazy creators */
|
|
107
132
|
const lazyCreatorAgent = new Map<string, string>();
|
|
133
|
+
/** Reverse lookup: childWorkflowId → agentName for in-flight snapshot-base creators */
|
|
134
|
+
const snapshotBaseCreatorAgent = new Map<string, string>();
|
|
108
135
|
/** Maps childThreadId → latest snapshot for sandbox continuation via snapshots */
|
|
109
136
|
const threadSnapshots = new Map<
|
|
110
137
|
string,
|
|
@@ -117,14 +144,24 @@ export function createSubagentHandler<
|
|
|
117
144
|
const persistentBaseSnapshot = new Map<string, SandboxSnapshot>();
|
|
118
145
|
/** Tracks agents whose first snapshot-backed sandbox creation is in-flight */
|
|
119
146
|
const persistentBaseSnapshotCreating = new Set<string>();
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
147
|
+
/** Latest failure from a snapshot-base creator call, keyed by agentName. */
|
|
148
|
+
const persistentBaseSnapshotCreationError = new Map<string, unknown>();
|
|
149
|
+
|
|
150
|
+
setHandler(
|
|
151
|
+
childSandboxReadySignal,
|
|
152
|
+
({ childWorkflowId, sandboxId, baseSnapshot }) => {
|
|
153
|
+
const lazyAgent = lazyCreatorAgent.get(childWorkflowId);
|
|
154
|
+
if (lazyAgent && !persistentSandboxes.has(lazyAgent)) {
|
|
155
|
+
persistentSandboxes.set(lazyAgent, sandboxId);
|
|
156
|
+
lazyCreatorAgent.delete(childWorkflowId);
|
|
157
|
+
}
|
|
158
|
+
const snapAgent = snapshotBaseCreatorAgent.get(childWorkflowId);
|
|
159
|
+
if (snapAgent && baseSnapshot && !persistentBaseSnapshot.has(snapAgent)) {
|
|
160
|
+
persistentBaseSnapshot.set(snapAgent, baseSnapshot);
|
|
161
|
+
snapshotBaseCreatorAgent.delete(childWorkflowId);
|
|
162
|
+
}
|
|
126
163
|
}
|
|
127
|
-
|
|
164
|
+
);
|
|
128
165
|
|
|
129
166
|
const handler = async (
|
|
130
167
|
args: SubagentArgs,
|
|
@@ -208,8 +245,23 @@ export function createSubagentHandler<
|
|
|
208
245
|
baseSnap = persistentBaseSnapshot.get(config.agentName);
|
|
209
246
|
if (!baseSnap) {
|
|
210
247
|
if (persistentBaseSnapshotCreating.has(config.agentName)) {
|
|
211
|
-
await condition(
|
|
248
|
+
await condition(
|
|
249
|
+
() =>
|
|
250
|
+
persistentBaseSnapshot.has(config.agentName) ||
|
|
251
|
+
persistentBaseSnapshotCreationError.has(config.agentName) ||
|
|
252
|
+
!persistentBaseSnapshotCreating.has(config.agentName)
|
|
253
|
+
);
|
|
254
|
+
const creatorErr = persistentBaseSnapshotCreationError.get(
|
|
255
|
+
config.agentName
|
|
256
|
+
);
|
|
257
|
+
if (creatorErr !== undefined) {
|
|
258
|
+
throw creatorErr;
|
|
259
|
+
}
|
|
212
260
|
baseSnap = persistentBaseSnapshot.get(config.agentName);
|
|
261
|
+
if (!baseSnap) {
|
|
262
|
+
persistentBaseSnapshotCreating.add(config.agentName);
|
|
263
|
+
isSnapshotBaseCreator = true;
|
|
264
|
+
}
|
|
213
265
|
} else {
|
|
214
266
|
persistentBaseSnapshotCreating.add(config.agentName);
|
|
215
267
|
isSnapshotBaseCreator = true;
|
|
@@ -229,9 +281,27 @@ export function createSubagentHandler<
|
|
|
229
281
|
baseSandboxId = persistentSandboxes.get(config.agentName);
|
|
230
282
|
if (!baseSandboxId) {
|
|
231
283
|
if (persistentSandboxCreating.has(config.agentName)) {
|
|
232
|
-
// Another call is already creating — wait for it to finish
|
|
233
|
-
|
|
284
|
+
// Another call is already creating — wait for it to finish.
|
|
285
|
+
// Also break out if the creator failed, so we can either fail
|
|
286
|
+
// fast with the same error or (if no one has re-claimed the
|
|
287
|
+
// creator role yet) take over ourselves.
|
|
288
|
+
await condition(
|
|
289
|
+
() =>
|
|
290
|
+
persistentSandboxes.has(config.agentName) ||
|
|
291
|
+
persistentSandboxCreationError.has(config.agentName) ||
|
|
292
|
+
!persistentSandboxCreating.has(config.agentName)
|
|
293
|
+
);
|
|
294
|
+
const creatorErr = persistentSandboxCreationError.get(
|
|
295
|
+
config.agentName
|
|
296
|
+
);
|
|
297
|
+
if (creatorErr !== undefined) {
|
|
298
|
+
throw creatorErr;
|
|
299
|
+
}
|
|
234
300
|
baseSandboxId = persistentSandboxes.get(config.agentName);
|
|
301
|
+
if (!baseSandboxId) {
|
|
302
|
+
persistentSandboxCreating.add(config.agentName);
|
|
303
|
+
isLazyCreator = true;
|
|
304
|
+
}
|
|
235
305
|
} else {
|
|
236
306
|
// We're the first concurrent caller — claim the creator role
|
|
237
307
|
persistentSandboxCreating.add(config.agentName);
|
|
@@ -290,6 +360,12 @@ export function createSubagentHandler<
|
|
|
290
360
|
: config.context;
|
|
291
361
|
|
|
292
362
|
const childOpts = {
|
|
363
|
+
// Apply a bounded run timeout by default so a child workflow that
|
|
364
|
+
// fails to initialize or otherwise never reaches a terminal state
|
|
365
|
+
// cannot hang the parent's `Subagent` tool call forever. Callers can
|
|
366
|
+
// raise, lower, or disable it via `workflowOptions.workflowRunTimeout`.
|
|
367
|
+
workflowRunTimeout: DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT,
|
|
368
|
+
...(config.workflowOptions ?? {}),
|
|
293
369
|
workflowId: childWorkflowId,
|
|
294
370
|
args:
|
|
295
371
|
resolvedContext === undefined
|
|
@@ -301,6 +377,9 @@ export function createSubagentHandler<
|
|
|
301
377
|
if (isLazyCreator) {
|
|
302
378
|
lazyCreatorAgent.set(childWorkflowId, config.agentName);
|
|
303
379
|
}
|
|
380
|
+
if (isSnapshotBaseCreator) {
|
|
381
|
+
snapshotBaseCreatorAgent.set(childWorkflowId, config.agentName);
|
|
382
|
+
}
|
|
304
383
|
|
|
305
384
|
log.info("subagent spawned", {
|
|
306
385
|
subagent: config.agentName,
|
|
@@ -309,7 +388,38 @@ export function createSubagentHandler<
|
|
|
309
388
|
sandboxSource: sandboxCfg.source,
|
|
310
389
|
});
|
|
311
390
|
|
|
312
|
-
|
|
391
|
+
// Always clear in-flight creator bookkeeping, even if `executeChild`
|
|
392
|
+
// throws. Otherwise a failing subagent would strand other concurrent
|
|
393
|
+
// callers waiting on `condition(() => persistentSandboxes.has(...))` /
|
|
394
|
+
// `persistentBaseSnapshot.has(...)` forever, because those conditions are
|
|
395
|
+
// only ever satisfied on the success path below. When we were the
|
|
396
|
+
// creator, also publish the error so any already-waiting concurrent
|
|
397
|
+
// callers fail with the same error instead of silently retrying or
|
|
398
|
+
// hanging.
|
|
399
|
+
let childResult: SubagentFnResult<InferSubagentResult<T[number]> | null>;
|
|
400
|
+
try {
|
|
401
|
+
childResult = (await executeChild(
|
|
402
|
+
config.workflow,
|
|
403
|
+
childOpts
|
|
404
|
+
)) as SubagentFnResult<InferSubagentResult<T[number]> | null>;
|
|
405
|
+
} catch (err) {
|
|
406
|
+
log.warn("subagent failed", {
|
|
407
|
+
subagent: config.agentName,
|
|
408
|
+
childWorkflowId,
|
|
409
|
+
error: err instanceof Error ? err.message : String(err),
|
|
410
|
+
});
|
|
411
|
+
if (isLazyCreator) {
|
|
412
|
+
persistentSandboxCreating.delete(config.agentName);
|
|
413
|
+
persistentSandboxCreationError.set(config.agentName, err);
|
|
414
|
+
lazyCreatorAgent.delete(childWorkflowId);
|
|
415
|
+
}
|
|
416
|
+
if (isSnapshotBaseCreator) {
|
|
417
|
+
persistentBaseSnapshotCreating.delete(config.agentName);
|
|
418
|
+
persistentBaseSnapshotCreationError.set(config.agentName, err);
|
|
419
|
+
snapshotBaseCreatorAgent.delete(childWorkflowId);
|
|
420
|
+
}
|
|
421
|
+
throw err;
|
|
422
|
+
}
|
|
313
423
|
|
|
314
424
|
const effectiveShutdown =
|
|
315
425
|
sandboxShutdownOverride ?? sandboxCfg.shutdown ?? "destroy";
|
|
@@ -386,10 +496,13 @@ export function createSubagentHandler<
|
|
|
386
496
|
|
|
387
497
|
if (isLazyCreator) {
|
|
388
498
|
persistentSandboxCreating.delete(config.agentName);
|
|
499
|
+
persistentSandboxCreationError.delete(config.agentName);
|
|
389
500
|
lazyCreatorAgent.delete(childWorkflowId);
|
|
390
501
|
}
|
|
391
502
|
if (isSnapshotBaseCreator) {
|
|
392
503
|
persistentBaseSnapshotCreating.delete(config.agentName);
|
|
504
|
+
persistentBaseSnapshotCreationError.delete(config.agentName);
|
|
505
|
+
snapshotBaseCreatorAgent.delete(childWorkflowId);
|
|
393
506
|
}
|
|
394
507
|
|
|
395
508
|
if (!toolResponse) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type {
|
|
2
|
+
SubagentChildWorkflowOptions,
|
|
2
3
|
SubagentConfig,
|
|
3
4
|
SubagentContext,
|
|
4
5
|
SubagentDefinition,
|
|
@@ -13,7 +14,10 @@ export type {
|
|
|
13
14
|
} from "./types";
|
|
14
15
|
export { createSubagentTool, SUBAGENT_TOOL_NAME } from "./tool";
|
|
15
16
|
export type { SubagentArgs } from "./tool";
|
|
16
|
-
export {
|
|
17
|
+
export {
|
|
18
|
+
createSubagentHandler,
|
|
19
|
+
DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT,
|
|
20
|
+
} from "./handler";
|
|
17
21
|
export { defineSubagent } from "./define";
|
|
18
22
|
export { defineSubagentWorkflow } from "./workflow";
|
|
19
23
|
export { buildSubagentRegistration } from "./register";
|