zeitlich 0.2.21 → 0.2.22

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.
Files changed (117) hide show
  1. package/README.md +70 -55
  2. package/dist/adapters/sandbox/daytona/index.cjs +3 -0
  3. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  4. package/dist/adapters/sandbox/daytona/index.d.cts +2 -1
  5. package/dist/adapters/sandbox/daytona/index.d.ts +2 -1
  6. package/dist/adapters/sandbox/daytona/index.js +3 -0
  7. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  8. package/dist/adapters/sandbox/daytona/workflow.cjs +32 -0
  9. package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -0
  10. package/dist/adapters/sandbox/daytona/workflow.d.cts +27 -0
  11. package/dist/adapters/sandbox/daytona/workflow.d.ts +27 -0
  12. package/dist/adapters/sandbox/daytona/workflow.js +30 -0
  13. package/dist/adapters/sandbox/daytona/workflow.js.map +1 -0
  14. package/dist/adapters/sandbox/inmemory/index.cjs +4 -1
  15. package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
  16. package/dist/adapters/sandbox/inmemory/index.d.cts +3 -2
  17. package/dist/adapters/sandbox/inmemory/index.d.ts +3 -2
  18. package/dist/adapters/sandbox/inmemory/index.js +4 -1
  19. package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
  20. package/dist/adapters/sandbox/inmemory/workflow.cjs +32 -0
  21. package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -0
  22. package/dist/adapters/sandbox/inmemory/workflow.d.cts +25 -0
  23. package/dist/adapters/sandbox/inmemory/workflow.d.ts +25 -0
  24. package/dist/adapters/sandbox/inmemory/workflow.js +30 -0
  25. package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -0
  26. package/dist/adapters/sandbox/virtual/index.cjs +3 -0
  27. package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
  28. package/dist/adapters/sandbox/virtual/index.d.cts +6 -4
  29. package/dist/adapters/sandbox/virtual/index.d.ts +6 -4
  30. package/dist/adapters/sandbox/virtual/index.js +3 -0
  31. package/dist/adapters/sandbox/virtual/index.js.map +1 -1
  32. package/dist/adapters/sandbox/virtual/workflow.cjs +32 -0
  33. package/dist/adapters/sandbox/virtual/workflow.cjs.map +1 -0
  34. package/dist/adapters/sandbox/virtual/workflow.d.cts +27 -0
  35. package/dist/adapters/sandbox/virtual/workflow.d.ts +27 -0
  36. package/dist/adapters/sandbox/virtual/workflow.js +30 -0
  37. package/dist/adapters/sandbox/virtual/workflow.js.map +1 -0
  38. package/dist/adapters/thread/google-genai/index.cjs +9 -1
  39. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  40. package/dist/adapters/thread/google-genai/index.d.cts +30 -18
  41. package/dist/adapters/thread/google-genai/index.d.ts +30 -18
  42. package/dist/adapters/thread/google-genai/index.js +9 -1
  43. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  44. package/dist/adapters/thread/google-genai/workflow.cjs +33 -0
  45. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -0
  46. package/dist/adapters/thread/google-genai/workflow.d.cts +32 -0
  47. package/dist/adapters/thread/google-genai/workflow.d.ts +32 -0
  48. package/dist/adapters/thread/google-genai/workflow.js +31 -0
  49. package/dist/adapters/thread/google-genai/workflow.js.map +1 -0
  50. package/dist/adapters/thread/langchain/index.cjs +9 -1
  51. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  52. package/dist/adapters/thread/langchain/index.d.cts +26 -15
  53. package/dist/adapters/thread/langchain/index.d.ts +26 -15
  54. package/dist/adapters/thread/langchain/index.js +9 -1
  55. package/dist/adapters/thread/langchain/index.js.map +1 -1
  56. package/dist/adapters/thread/langchain/workflow.cjs +33 -0
  57. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -0
  58. package/dist/adapters/thread/langchain/workflow.d.cts +32 -0
  59. package/dist/adapters/thread/langchain/workflow.d.ts +32 -0
  60. package/dist/adapters/thread/langchain/workflow.js +31 -0
  61. package/dist/adapters/thread/langchain/workflow.js.map +1 -0
  62. package/dist/index.cjs +36 -34
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.d.cts +35 -14
  65. package/dist/index.d.ts +35 -14
  66. package/dist/index.js +38 -34
  67. package/dist/index.js.map +1 -1
  68. package/dist/queries-Bw6WEPMw.d.cts +44 -0
  69. package/dist/queries-C27raDaB.d.ts +44 -0
  70. package/dist/{queries-CHa2iv_I.d.cts → types-BJ8itUAl.d.cts} +2 -43
  71. package/dist/{types-BkAYmc96.d.ts → types-C5bkx6kQ.d.ts} +33 -5
  72. package/dist/{types-CES_30qx.d.cts → types-ClsHhtwL.d.cts} +33 -5
  73. package/dist/{queries-6Avfh74U.d.ts → types-ENYCKFBk.d.ts} +2 -43
  74. package/dist/{types-BMRzfELQ.d.cts → types-HBosetv3.d.cts} +15 -1
  75. package/dist/{types-BMRzfELQ.d.ts → types-HBosetv3.d.ts} +15 -1
  76. package/dist/workflow.cjs +4 -30
  77. package/dist/workflow.cjs.map +1 -1
  78. package/dist/workflow.d.cts +13 -41
  79. package/dist/workflow.d.ts +13 -41
  80. package/dist/workflow.js +6 -30
  81. package/dist/workflow.js.map +1 -1
  82. package/package.json +53 -1
  83. package/src/adapters/sandbox/daytona/index.ts +4 -0
  84. package/src/adapters/sandbox/daytona/proxy.ts +55 -0
  85. package/src/adapters/sandbox/e2b/filesystem.ts +147 -0
  86. package/src/adapters/sandbox/e2b/index.ts +159 -0
  87. package/src/adapters/sandbox/e2b/types.ts +23 -0
  88. package/src/adapters/sandbox/inmemory/index.ts +5 -1
  89. package/src/adapters/sandbox/inmemory/proxy.ts +53 -0
  90. package/src/adapters/sandbox/virtual/provider.ts +5 -1
  91. package/src/adapters/sandbox/virtual/proxy.ts +52 -0
  92. package/src/adapters/thread/google-genai/activities.ts +51 -17
  93. package/src/adapters/thread/google-genai/index.ts +1 -0
  94. package/src/adapters/thread/google-genai/proxy.ts +61 -0
  95. package/src/adapters/thread/langchain/activities.ts +47 -14
  96. package/src/adapters/thread/langchain/index.ts +1 -0
  97. package/src/adapters/thread/langchain/proxy.ts +61 -0
  98. package/src/lib/sandbox/manager.ts +40 -6
  99. package/src/lib/sandbox/sandbox.test.ts +12 -11
  100. package/src/lib/sandbox/types.ts +18 -0
  101. package/src/lib/session/index.ts +3 -5
  102. package/src/lib/session/session-edge-cases.integration.test.ts +45 -34
  103. package/src/lib/session/session.integration.test.ts +40 -48
  104. package/src/lib/session/session.ts +4 -66
  105. package/src/lib/session/types.ts +32 -1
  106. package/src/lib/subagent/define.ts +1 -1
  107. package/src/lib/subagent/handler.ts +9 -2
  108. package/src/lib/subagent/index.ts +1 -0
  109. package/src/lib/subagent/subagent.integration.test.ts +62 -0
  110. package/src/lib/subagent/types.ts +7 -2
  111. package/src/lib/tool-router/router-edge-cases.integration.test.ts +4 -1
  112. package/src/lib/tool-router/router.integration.test.ts +4 -1
  113. package/src/lib/workflow.test.ts +19 -10
  114. package/src/lib/workflow.ts +4 -1
  115. package/src/tools/bash/bash.test.ts +16 -7
  116. package/src/workflow.ts +6 -14
  117. package/tsup.config.ts +6 -0
@@ -323,6 +323,68 @@ describe("createSubagentHandler", () => {
323
323
  expect(workflowInput.sandboxId).toBe("parent-sb");
324
324
  });
325
325
 
326
+ it("resolves context function at invocation time", async () => {
327
+ const { executeChild } = await import("@temporalio/workflow");
328
+ const execMock = executeChild as ReturnType<typeof vi.fn>;
329
+ execMock.mockResolvedValueOnce({
330
+ toolResponse: "ok",
331
+ data: null,
332
+ threadId: "child-t",
333
+ });
334
+
335
+ let counter = 0;
336
+ const dynamicSubagent: SubagentConfig = {
337
+ agentName: "dynamic-ctx",
338
+ description: "Dynamic context",
339
+ workflow: "workflow",
340
+ context: () => {
341
+ counter++;
342
+ return { invocation: counter };
343
+ },
344
+ };
345
+
346
+ const handler = createSubagentHandler([dynamicSubagent]);
347
+
348
+ await handler(
349
+ { subagent: "dynamic-ctx", description: "test", prompt: "test" },
350
+ { threadId: "t", toolCallId: "tc", toolName: "Subagent" }
351
+ );
352
+
353
+ const lastCall = execMock.mock.calls[execMock.mock.calls.length - 1];
354
+ if (!lastCall) throw new Error("expected exec call");
355
+ const context = lastCall[1].args[2] as Record<string, unknown>;
356
+ expect(context).toEqual({ invocation: 1 });
357
+ });
358
+
359
+ it("passes static context unchanged", async () => {
360
+ const { executeChild } = await import("@temporalio/workflow");
361
+ const execMock = executeChild as ReturnType<typeof vi.fn>;
362
+ execMock.mockResolvedValueOnce({
363
+ toolResponse: "ok",
364
+ data: null,
365
+ threadId: "child-t",
366
+ });
367
+
368
+ const staticSubagent: SubagentConfig = {
369
+ agentName: "static-ctx",
370
+ description: "Static context",
371
+ workflow: "workflow",
372
+ context: { key: "value" },
373
+ };
374
+
375
+ const handler = createSubagentHandler([staticSubagent]);
376
+
377
+ await handler(
378
+ { subagent: "static-ctx", description: "test", prompt: "test" },
379
+ { threadId: "t", toolCallId: "tc", toolName: "Subagent" }
380
+ );
381
+
382
+ const lastCall = execMock.mock.calls[execMock.mock.calls.length - 1];
383
+ if (!lastCall) throw new Error("expected exec call");
384
+ const context = lastCall[1].args[2] as Record<string, unknown>;
385
+ expect(context).toEqual({ key: "value" });
386
+ });
387
+
326
388
  it("does not pass sandboxId when sandbox is own", async () => {
327
389
  const { executeChild } = await import("@temporalio/workflow");
328
390
  const execMock = executeChild as ReturnType<typeof vi.fn>;
@@ -43,6 +43,11 @@ export type SubagentDefinition<
43
43
  readonly resultSchema?: TResult;
44
44
  };
45
45
 
46
+ /** Context value or factory — resolved at invocation time when a function is provided */
47
+ export type SubagentContext =
48
+ | Record<string, unknown>
49
+ | (() => Record<string, unknown>);
50
+
46
51
  /** Infer the z.infer'd result type from a SubagentConfig, or null if no schema */
47
52
  export type InferSubagentResult<T extends SubagentConfig> =
48
53
  T extends SubagentConfig<infer S> ? z.infer<S> : null;
@@ -65,8 +70,8 @@ export interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
65
70
  taskQueue?: string;
66
71
  /** Optional Zod schema to validate the child workflow's result. If omitted, result is passed through as-is. */
67
72
  resultSchema?: TResult;
68
- /** Optional static context passed to the subagent on every invocation */
69
- context?: Record<string, unknown>;
73
+ /** Optional context passed to the subagent a static object or a function evaluated at invocation time */
74
+ context?: SubagentContext;
70
75
  /** Allow the parent agent to pass a threadId for this subagent to continue (default: false) */
71
76
  allowThreadContinuation?: boolean;
72
77
  /** Per-subagent lifecycle hooks */
@@ -22,7 +22,10 @@ vi.mock("@temporalio/workflow", () => {
22
22
  return err;
23
23
  }
24
24
  }
25
- return { ApplicationFailure: MockApplicationFailure };
25
+ return {
26
+ ApplicationFailure: MockApplicationFailure,
27
+ uuid4: () => "00000000-0000-0000-0000-000000000000",
28
+ };
26
29
  });
27
30
 
28
31
  import { createToolRouter, defineTool, hasNoOtherToolCalls } from "./router";
@@ -22,7 +22,10 @@ vi.mock("@temporalio/workflow", () => {
22
22
  return err;
23
23
  }
24
24
  }
25
- return { ApplicationFailure: MockApplicationFailure };
25
+ return {
26
+ ApplicationFailure: MockApplicationFailure,
27
+ uuid4: () => "00000000-0000-0000-0000-000000000000",
28
+ };
26
29
  });
27
30
 
28
31
  import { createToolRouter, defineTool } from "./router";
@@ -19,6 +19,7 @@ describe("defineWorkflow", () => {
19
19
  await workflow({}, { previousThreadId: "prev-42" });
20
20
 
21
21
  expect(capturedSession).toEqual({
22
+ agentName: "test-workflow",
22
23
  threadId: "prev-42",
23
24
  continueThread: true,
24
25
  });
@@ -34,7 +35,10 @@ describe("defineWorkflow", () => {
34
35
 
35
36
  await workflow({}, { sandboxId: "sb-123" });
36
37
 
37
- expect(capturedSession).toEqual({ sandboxId: "sb-123" });
38
+ expect(capturedSession).toEqual({
39
+ agentName: "test-workflow",
40
+ sandboxId: "sb-123",
41
+ });
38
42
  });
39
43
 
40
44
  it("maps both previousThreadId and sandboxId together", async () => {
@@ -48,6 +52,7 @@ describe("defineWorkflow", () => {
48
52
  await workflow({}, { previousThreadId: "prev-1", sandboxId: "sb-1" });
49
53
 
50
54
  expect(capturedSession).toEqual({
55
+ agentName: "test-workflow",
51
56
  threadId: "prev-1",
52
57
  continueThread: true,
53
58
  sandboxId: "sb-1",
@@ -64,18 +69,21 @@ describe("defineWorkflow", () => {
64
69
 
65
70
  await workflow({});
66
71
 
67
- expect(capturedSession).toEqual({});
72
+ expect(capturedSession).toEqual({ agentName: "test-workflow" });
68
73
  });
69
74
 
70
75
  it("passes full input as first argument", async () => {
71
76
  let capturedInput: unknown;
72
77
 
73
- const workflow = defineWorkflow<{
74
- prompt: string;
75
- metadata: { key: string };
76
- previousThreadId?: string;
77
- sandboxId?: string;
78
- }, { ok: boolean }>(cfg, async (input, _sessionInput) => {
78
+ const workflow = defineWorkflow<
79
+ {
80
+ prompt: string;
81
+ metadata: { key: string };
82
+ previousThreadId?: string;
83
+ sandboxId?: string;
84
+ },
85
+ { ok: boolean }
86
+ >(cfg, async (input, _sessionInput) => {
79
87
  capturedInput = input;
80
88
  return { ok: true };
81
89
  });
@@ -101,7 +109,7 @@ describe("defineWorkflow", () => {
101
109
  capturedInput = input;
102
110
  capturedSession = sessionInput;
103
111
  return { ok: true };
104
- },
112
+ }
105
113
  );
106
114
 
107
115
  const workflowInput: WorkflowInput = {
@@ -112,6 +120,7 @@ describe("defineWorkflow", () => {
112
120
 
113
121
  expect(capturedInput).toEqual({ prompt: "go" });
114
122
  expect(capturedSession).toEqual({
123
+ agentName: "test-workflow",
115
124
  threadId: "prev",
116
125
  continueThread: true,
117
126
  sandboxId: "sb",
@@ -135,7 +144,7 @@ describe("defineWorkflow", () => {
135
144
  it("sets the function name from config", () => {
136
145
  const workflow = defineWorkflow(
137
146
  { name: "my-main-workflow" },
138
- async () => ({}),
147
+ async () => ({})
139
148
  );
140
149
 
141
150
  expect(workflow.name).toBe("my-main-workflow");
@@ -3,6 +3,8 @@
3
3
  * into `createSession`.
4
4
  */
5
5
  export interface WorkflowSessionInput {
6
+ /** Agent name — spread directly into `createSession` */
7
+ agentName: string;
6
8
  /** Thread ID to continue (set from `input.previousThreadId`) */
7
9
  threadId?: string;
8
10
  /** Whether to continue an existing thread (true when `previousThreadId` is present) */
@@ -36,10 +38,11 @@ export interface WorkflowConfig {
36
38
  */
37
39
  export function defineWorkflow<TInput, TResult>(
38
40
  config: WorkflowConfig,
39
- fn: (input: TInput, sessionInput: WorkflowSessionInput) => Promise<TResult>,
41
+ fn: (input: TInput, sessionInput: WorkflowSessionInput) => Promise<TResult>
40
42
  ): (input: TInput, workflowInput?: WorkflowInput) => Promise<TResult> {
41
43
  const workflow = async (input: TInput, workflowInput: WorkflowInput = {}) => {
42
44
  const sessionInput: WorkflowSessionInput = {
45
+ agentName: config.name,
43
46
  ...(workflowInput.previousThreadId && {
44
47
  threadId: workflowInput.previousThreadId,
45
48
  continueThread: true,
@@ -4,11 +4,17 @@ import { withSandbox } from "../../lib/tool-router/with-sandbox";
4
4
  import { SandboxManager } from "../../lib/sandbox/manager";
5
5
  import { InMemorySandboxProvider } from "../../adapters/sandbox/inmemory/index";
6
6
  import type { RouterContext } from "../../lib/tool-router/types";
7
+ import type { Sandbox, SandboxCreateOptions } from "../../lib/sandbox";
7
8
 
8
9
  describe("bash handler with sandbox", () => {
9
- let manager: SandboxManager;
10
+ let manager: SandboxManager<SandboxCreateOptions, Sandbox, "inMemory">;
10
11
  let sandboxId: string;
11
- let handler: ReturnType<typeof withSandbox<Parameters<typeof bashHandler>[0], Awaited<ReturnType<typeof bashHandler>>["data"]>>;
12
+ let handler: ReturnType<
13
+ typeof withSandbox<
14
+ Parameters<typeof bashHandler>[0],
15
+ Awaited<ReturnType<typeof bashHandler>>["data"]
16
+ >
17
+ >;
12
18
 
13
19
  beforeEach(async () => {
14
20
  manager = new SandboxManager(new InMemorySandboxProvider());
@@ -83,11 +89,14 @@ describe("bash handler with sandbox", () => {
83
89
  });
84
90
 
85
91
  it("returns error when no sandboxId in context", async () => {
86
- const { toolResponse, data } = await handler({ command: "echo hi" }, {
87
- threadId: "test-thread",
88
- toolCallId: "test-call",
89
- toolName: "Bash",
90
- });
92
+ const { toolResponse, data } = await handler(
93
+ { command: "echo hi" },
94
+ {
95
+ threadId: "test-thread",
96
+ toolCallId: "test-call",
97
+ toolName: "Bash",
98
+ }
99
+ );
91
100
  expect(toolResponse).toContain("No sandbox configured");
92
101
  expect(data).toBeNull();
93
102
  });
package/src/workflow.ts CHANGED
@@ -7,24 +7,15 @@
7
7
  * @example
8
8
  * ```typescript
9
9
  * // In your workflow file
10
- * import {
11
- * createSession,
12
- * createAgentStateManager,
13
- * askUserQuestionTool,
14
- * bashTool,
15
- * defineTool,
16
- * type SubagentWorkflow,
17
- * } from 'zeitlich/workflow';
10
+ * import { createSession, defineWorkflow, defineTool, bashTool } from 'zeitlich/workflow';
11
+ * import { proxyLangChainThreadOps } from 'zeitlich/adapters/thread/langchain/workflow';
12
+ * import { proxyVirtualSandboxOps } from 'zeitlich/adapters/sandbox/virtual/workflow';
18
13
  * ```
19
14
  */
20
15
 
21
16
  // Session
22
- export {
23
- createSession,
24
- proxyDefaultThreadOps,
25
- proxySandboxOps,
26
- } from "./lib/session";
27
- export type { ZeitlichSession, ThreadOps, SessionConfig } from "./lib/session";
17
+ export { createSession } from "./lib/session";
18
+ export type { ZeitlichSession, ThreadOps, PrefixedThreadOps, ScopedPrefix, SessionConfig } from "./lib/session";
28
19
  export { defineWorkflow } from "./lib/workflow";
29
20
  export type { WorkflowConfig, WorkflowInput, WorkflowSessionInput } from "./lib/workflow";
30
21
 
@@ -147,6 +138,7 @@ export type {
147
138
  SandboxCreateResult,
148
139
  SandboxFileSystem,
149
140
  SandboxOps,
141
+ PrefixedSandboxOps,
150
142
  SandboxProvider,
151
143
  SandboxSnapshot,
152
144
  ExecOptions,
package/tsup.config.ts CHANGED
@@ -5,11 +5,17 @@ export default defineConfig({
5
5
  index: "src/index.ts",
6
6
  workflow: "src/workflow.ts",
7
7
  "adapters/thread/langchain/index": "src/adapters/thread/langchain/index.ts",
8
+ "adapters/thread/langchain/workflow": "src/adapters/thread/langchain/proxy.ts",
8
9
  "adapters/thread/google-genai/index":
9
10
  "src/adapters/thread/google-genai/index.ts",
11
+ "adapters/thread/google-genai/workflow":
12
+ "src/adapters/thread/google-genai/proxy.ts",
10
13
  "adapters/sandbox/inmemory/index": "src/adapters/sandbox/inmemory/index.ts",
14
+ "adapters/sandbox/inmemory/workflow": "src/adapters/sandbox/inmemory/proxy.ts",
11
15
  "adapters/sandbox/daytona/index": "src/adapters/sandbox/daytona/index.ts",
16
+ "adapters/sandbox/daytona/workflow": "src/adapters/sandbox/daytona/proxy.ts",
12
17
  "adapters/sandbox/virtual/index": "src/adapters/sandbox/virtual/index.ts",
18
+ "adapters/sandbox/virtual/workflow": "src/adapters/sandbox/virtual/proxy.ts",
13
19
  },
14
20
  format: ["esm", "cjs"],
15
21
  dts: true,