zeitlich 0.2.15 → 0.2.17

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 (78) hide show
  1. package/README.md +125 -64
  2. package/dist/adapters/sandbox/daytona/index.cjs +52 -23
  3. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  4. package/dist/adapters/sandbox/daytona/index.d.cts +10 -2
  5. package/dist/adapters/sandbox/daytona/index.d.ts +10 -2
  6. package/dist/adapters/sandbox/daytona/index.js +52 -23
  7. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  8. package/dist/adapters/sandbox/inmemory/index.cjs +21 -16
  9. package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
  10. package/dist/adapters/sandbox/inmemory/index.d.cts +1 -1
  11. package/dist/adapters/sandbox/inmemory/index.d.ts +1 -1
  12. package/dist/adapters/sandbox/inmemory/index.js +21 -16
  13. package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
  14. package/dist/adapters/sandbox/virtual/index.cjs +83 -38
  15. package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
  16. package/dist/adapters/sandbox/virtual/index.d.cts +6 -6
  17. package/dist/adapters/sandbox/virtual/index.d.ts +6 -6
  18. package/dist/adapters/sandbox/virtual/index.js +80 -38
  19. package/dist/adapters/sandbox/virtual/index.js.map +1 -1
  20. package/dist/adapters/thread/google-genai/index.d.cts +2 -2
  21. package/dist/adapters/thread/google-genai/index.d.ts +2 -2
  22. package/dist/adapters/thread/langchain/index.cjs +2 -2
  23. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  24. package/dist/adapters/thread/langchain/index.d.cts +2 -2
  25. package/dist/adapters/thread/langchain/index.d.ts +2 -2
  26. package/dist/adapters/thread/langchain/index.js +2 -2
  27. package/dist/adapters/thread/langchain/index.js.map +1 -1
  28. package/dist/index.cjs +102 -10
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +6 -6
  31. package/dist/index.d.ts +6 -6
  32. package/dist/index.js +98 -11
  33. package/dist/index.js.map +1 -1
  34. package/dist/{types-CwwgQ_9H.d.ts → queries-BlC1I3DK.d.ts} +48 -3
  35. package/dist/{types-BVP87m_W.d.cts → queries-DlJ3jE48.d.cts} +48 -3
  36. package/dist/{types-CDubRtad.d.cts → types-BMRzfELQ.d.cts} +2 -0
  37. package/dist/{types-CDubRtad.d.ts → types-BMRzfELQ.d.ts} +2 -0
  38. package/dist/{types-Dje1TdH6.d.cts → types-Bh-BbfCp.d.cts} +31 -12
  39. package/dist/{types-BWvIYK28.d.ts → types-NkiAxU4t.d.ts} +31 -12
  40. package/dist/workflow.cjs +102 -10
  41. package/dist/workflow.cjs.map +1 -1
  42. package/dist/workflow.d.cts +114 -40
  43. package/dist/workflow.d.ts +114 -40
  44. package/dist/workflow.js +98 -11
  45. package/dist/workflow.js.map +1 -1
  46. package/package.json +1 -1
  47. package/src/adapters/sandbox/daytona/filesystem.ts +43 -19
  48. package/src/adapters/sandbox/daytona/index.ts +16 -3
  49. package/src/adapters/sandbox/daytona/types.ts +4 -0
  50. package/src/adapters/sandbox/inmemory/index.ts +22 -16
  51. package/src/adapters/sandbox/virtual/filesystem.ts +29 -31
  52. package/src/adapters/sandbox/virtual/index.ts +7 -3
  53. package/src/adapters/sandbox/virtual/provider.ts +5 -2
  54. package/src/adapters/sandbox/virtual/queries.ts +97 -0
  55. package/src/adapters/sandbox/virtual/types.ts +3 -0
  56. package/src/adapters/sandbox/virtual/with-virtual-sandbox.ts +4 -3
  57. package/src/adapters/thread/langchain/activities.ts +7 -5
  58. package/src/lib/sandbox/tree.integration.test.ts +153 -0
  59. package/src/lib/sandbox/types.ts +2 -0
  60. package/src/lib/session/session-edge-cases.integration.test.ts +962 -0
  61. package/src/lib/session/session.integration.test.ts +853 -0
  62. package/src/lib/session/session.ts +5 -4
  63. package/src/lib/skills/skills.integration.test.ts +308 -0
  64. package/src/lib/state/manager.integration.test.ts +342 -0
  65. package/src/lib/subagent/define.ts +34 -47
  66. package/src/lib/subagent/handler.ts +9 -6
  67. package/src/lib/subagent/index.ts +4 -1
  68. package/src/lib/subagent/subagent.integration.test.ts +573 -0
  69. package/src/lib/subagent/types.ts +40 -10
  70. package/src/lib/subagent/workflow.ts +114 -0
  71. package/src/lib/thread/id.test.ts +50 -0
  72. package/src/lib/tool-router/auto-append-sandbox.integration.test.ts +344 -0
  73. package/src/lib/tool-router/router-edge-cases.integration.test.ts +623 -0
  74. package/src/lib/tool-router/router.integration.test.ts +699 -0
  75. package/src/lib/types.test.ts +29 -0
  76. package/src/lib/workflow.test.ts +131 -0
  77. package/src/lib/workflow.ts +45 -0
  78. package/src/workflow.ts +12 -2
@@ -1,4 +1,4 @@
1
- import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox, d as SandboxCreateOptions } from './types-CDubRtad.js';
1
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox, d as SandboxCreateOptions } from './types-BMRzfELQ.js';
2
2
  import { R as RouterContext } from './types-BMXzv7TN.js';
3
3
 
4
4
  /**
@@ -11,10 +11,11 @@ import { R as RouterContext } from './types-BMXzv7TN.js';
11
11
  declare class VirtualSandboxFileSystem<TCtx = unknown, TMeta = FileEntryMetadata> implements SandboxFileSystem {
12
12
  private resolver;
13
13
  private ctx;
14
+ readonly workspaceBase: string;
14
15
  private entries;
15
16
  private directories;
16
17
  private mutations;
17
- constructor(tree: FileEntry<TMeta>[], resolver: FileResolver<TCtx, TMeta>, ctx: TCtx);
18
+ constructor(tree: FileEntry<TMeta>[], resolver: FileResolver<TCtx, TMeta>, ctx: TCtx, workspaceBase?: string);
18
19
  /** Return all mutations accumulated during this invocation. */
19
20
  getMutations(): TreeMutation<TMeta>[];
20
21
  /** Look up a file entry by virtual path. */
@@ -93,6 +94,8 @@ interface FileResolver<TCtx = unknown, TMeta = FileEntryMetadata> {
93
94
  */
94
95
  interface VirtualSandboxCreateOptions<TCtx> extends SandboxCreateOptions {
95
96
  resolverContext: TCtx;
97
+ /** Base path for resolving relative filesystem paths (default "/"). */
98
+ workspaceBase?: string;
96
99
  }
97
100
  /**
98
101
  * The portion of workflow `AgentState` that the virtual sandbox reads via
@@ -103,6 +106,7 @@ interface VirtualSandboxState<TCtx = unknown, TMeta = FileEntryMetadata> {
103
106
  sandboxId: string;
104
107
  fileTree: FileEntry<TMeta>[];
105
108
  resolverContext: TCtx;
109
+ workspaceBase?: string;
106
110
  }
107
111
  /**
108
112
  * A {@link Sandbox} whose filesystem is backed by a {@link VirtualSandboxFileSystem}.
@@ -118,4 +122,45 @@ interface VirtualSandboxContext<TCtx = unknown, TMeta = FileEntryMetadata> exten
118
122
  sandbox: VirtualSandbox<TCtx, TMeta>;
119
123
  }
120
124
 
121
- export { type FileEntryMetadata as F, type TreeMutation as T, type VirtualSandboxCreateOptions as V, type FileResolver as a, type VirtualSandboxContext as b, type FileEntry as c, type VirtualSandbox as d, type VirtualFileTree as e, VirtualSandboxFileSystem as f, type VirtualSandboxState as g };
125
+ /**
126
+ * Structural constraint: accepts any `AgentStateManager<T>` whose custom
127
+ * state includes `fileTree: FileEntry<TMeta>[]`.
128
+ */
129
+ interface FileTreeAccessor<TMeta> {
130
+ get(key: "fileTree"): FileEntry<TMeta>[];
131
+ }
132
+ /**
133
+ * Check whether any file in the tree has a `metadata.mimeType` that matches
134
+ * the given pattern.
135
+ *
136
+ * Patterns:
137
+ * - Exact: `"application/pdf"`
138
+ * - Wildcard type: `"image/*"`
139
+ *
140
+ * Useful for conditionally enabling tools:
141
+ *
142
+ * ```ts
143
+ * { enabled: hasFileWithMimeType(stateManager, "image/*") }
144
+ * { enabled: hasFileWithMimeType(stateManager, ["image/*", "application/pdf"]) }
145
+ * ```
146
+ */
147
+ declare function hasFileWithMimeType<TMeta>(stateManager: FileTreeAccessor<TMeta>, pattern: string | string[]): boolean;
148
+ /**
149
+ * Return all entries whose `metadata.mimeType` matches the given pattern.
150
+ */
151
+ declare function filesWithMimeType<TMeta>(stateManager: FileTreeAccessor<TMeta>, pattern: string): FileEntry<TMeta>[];
152
+ /**
153
+ * Check whether the tree contains a directory whose name matches the given
154
+ * pattern. Directories are inferred from file paths.
155
+ *
156
+ * Patterns:
157
+ * - Exact: `"src"`
158
+ * - Glob with `*` wildcard: `"test*"`, `"*.generated"`
159
+ *
160
+ * ```ts
161
+ * { enabled: hasDirectory(stateManager, "test*") }
162
+ * ```
163
+ */
164
+ declare function hasDirectory<TMeta>(stateManager: FileTreeAccessor<TMeta>, pattern: string): boolean;
165
+
166
+ export { type FileEntryMetadata as F, type TreeMutation as T, type VirtualSandboxCreateOptions as V, type FileResolver as a, type VirtualSandboxContext as b, type FileEntry as c, type VirtualSandbox as d, type FileTreeAccessor as e, type VirtualFileTree as f, VirtualSandboxFileSystem as g, type VirtualSandboxState as h, filesWithMimeType as i, hasDirectory as j, hasFileWithMimeType as k };
@@ -1,4 +1,4 @@
1
- import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox, d as SandboxCreateOptions } from './types-CDubRtad.cjs';
1
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox, d as SandboxCreateOptions } from './types-BMRzfELQ.cjs';
2
2
  import { R as RouterContext } from './types-BMXzv7TN.cjs';
3
3
 
4
4
  /**
@@ -11,10 +11,11 @@ import { R as RouterContext } from './types-BMXzv7TN.cjs';
11
11
  declare class VirtualSandboxFileSystem<TCtx = unknown, TMeta = FileEntryMetadata> implements SandboxFileSystem {
12
12
  private resolver;
13
13
  private ctx;
14
+ readonly workspaceBase: string;
14
15
  private entries;
15
16
  private directories;
16
17
  private mutations;
17
- constructor(tree: FileEntry<TMeta>[], resolver: FileResolver<TCtx, TMeta>, ctx: TCtx);
18
+ constructor(tree: FileEntry<TMeta>[], resolver: FileResolver<TCtx, TMeta>, ctx: TCtx, workspaceBase?: string);
18
19
  /** Return all mutations accumulated during this invocation. */
19
20
  getMutations(): TreeMutation<TMeta>[];
20
21
  /** Look up a file entry by virtual path. */
@@ -93,6 +94,8 @@ interface FileResolver<TCtx = unknown, TMeta = FileEntryMetadata> {
93
94
  */
94
95
  interface VirtualSandboxCreateOptions<TCtx> extends SandboxCreateOptions {
95
96
  resolverContext: TCtx;
97
+ /** Base path for resolving relative filesystem paths (default "/"). */
98
+ workspaceBase?: string;
96
99
  }
97
100
  /**
98
101
  * The portion of workflow `AgentState` that the virtual sandbox reads via
@@ -103,6 +106,7 @@ interface VirtualSandboxState<TCtx = unknown, TMeta = FileEntryMetadata> {
103
106
  sandboxId: string;
104
107
  fileTree: FileEntry<TMeta>[];
105
108
  resolverContext: TCtx;
109
+ workspaceBase?: string;
106
110
  }
107
111
  /**
108
112
  * A {@link Sandbox} whose filesystem is backed by a {@link VirtualSandboxFileSystem}.
@@ -118,4 +122,45 @@ interface VirtualSandboxContext<TCtx = unknown, TMeta = FileEntryMetadata> exten
118
122
  sandbox: VirtualSandbox<TCtx, TMeta>;
119
123
  }
120
124
 
121
- export { type FileEntryMetadata as F, type TreeMutation as T, type VirtualSandboxCreateOptions as V, type FileResolver as a, type VirtualSandboxContext as b, type FileEntry as c, type VirtualSandbox as d, type VirtualFileTree as e, VirtualSandboxFileSystem as f, type VirtualSandboxState as g };
125
+ /**
126
+ * Structural constraint: accepts any `AgentStateManager<T>` whose custom
127
+ * state includes `fileTree: FileEntry<TMeta>[]`.
128
+ */
129
+ interface FileTreeAccessor<TMeta> {
130
+ get(key: "fileTree"): FileEntry<TMeta>[];
131
+ }
132
+ /**
133
+ * Check whether any file in the tree has a `metadata.mimeType` that matches
134
+ * the given pattern.
135
+ *
136
+ * Patterns:
137
+ * - Exact: `"application/pdf"`
138
+ * - Wildcard type: `"image/*"`
139
+ *
140
+ * Useful for conditionally enabling tools:
141
+ *
142
+ * ```ts
143
+ * { enabled: hasFileWithMimeType(stateManager, "image/*") }
144
+ * { enabled: hasFileWithMimeType(stateManager, ["image/*", "application/pdf"]) }
145
+ * ```
146
+ */
147
+ declare function hasFileWithMimeType<TMeta>(stateManager: FileTreeAccessor<TMeta>, pattern: string | string[]): boolean;
148
+ /**
149
+ * Return all entries whose `metadata.mimeType` matches the given pattern.
150
+ */
151
+ declare function filesWithMimeType<TMeta>(stateManager: FileTreeAccessor<TMeta>, pattern: string): FileEntry<TMeta>[];
152
+ /**
153
+ * Check whether the tree contains a directory whose name matches the given
154
+ * pattern. Directories are inferred from file paths.
155
+ *
156
+ * Patterns:
157
+ * - Exact: `"src"`
158
+ * - Glob with `*` wildcard: `"test*"`, `"*.generated"`
159
+ *
160
+ * ```ts
161
+ * { enabled: hasDirectory(stateManager, "test*") }
162
+ * ```
163
+ */
164
+ declare function hasDirectory<TMeta>(stateManager: FileTreeAccessor<TMeta>, pattern: string): boolean;
165
+
166
+ export { type FileEntryMetadata as F, type TreeMutation as T, type VirtualSandboxCreateOptions as V, type FileResolver as a, type VirtualSandboxContext as b, type FileEntry as c, type VirtualSandbox as d, type FileTreeAccessor as e, type VirtualFileTree as f, VirtualSandboxFileSystem as g, type VirtualSandboxState as h, filesWithMimeType as i, hasDirectory as j, hasFileWithMimeType as k };
@@ -20,6 +20,8 @@ interface FileStat {
20
20
  * {@link SandboxNotSupportedError}.
21
21
  */
22
22
  interface SandboxFileSystem {
23
+ /** Base directory used when resolving relative paths. */
24
+ readonly workspaceBase: string;
23
25
  readFile(path: string): Promise<string>;
24
26
  readFileBuffer(path: string): Promise<Uint8Array>;
25
27
  writeFile(path: string, content: string | Uint8Array): Promise<void>;
@@ -20,6 +20,8 @@ interface FileStat {
20
20
  * {@link SandboxNotSupportedError}.
21
21
  */
22
22
  interface SandboxFileSystem {
23
+ /** Base directory used when resolving relative paths. */
24
+ readonly workspaceBase: string;
23
25
  readFile(path: string): Promise<string>;
24
26
  readFileBuffer(path: string): Promise<Uint8Array>;
25
27
  writeFile(path: string, content: string | Uint8Array): Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import { Duration } from '@temporalio/common';
2
2
  import { a as ToolMap, b as ToolRouterHooks, M as MessageContent, S as SessionExitReason, c as ToolHandlerResponse, P as PreToolUseHookResult, d as PostToolUseFailureHookResult, e as RawToolCall, f as TokenUsage, B as BaseAgentState, g as RunAgentConfig, h as AgentStatus, W as WorkflowTask, i as ToolDefinition, j as ToolResultConfig, k as ToolCallResultUnion, I as InferToolResults } from './types-BMXzv7TN.cjs';
3
3
  import { z } from 'zod';
4
- import { g as SandboxOps } from './types-CDubRtad.cjs';
4
+ import { g as SandboxOps } from './types-BMRzfELQ.cjs';
5
5
  import { QueryDefinition } from '@temporalio/workflow';
6
6
  import { UpdateDefinition } from '@temporalio/common/lib/interfaces';
7
7
 
@@ -73,7 +73,26 @@ interface Hooks<T extends ToolMap, TResult = unknown> extends ToolRouterHooks<T,
73
73
  type SubagentHandlerResponse<TResult = null> = ToolHandlerResponse<TResult> & {
74
74
  threadId: string;
75
75
  };
76
- type SubagentWorkflow<TResult extends z.ZodType = z.ZodType> = (input: SubagentInput) => Promise<SubagentHandlerResponse<z.infer<TResult> | null>>;
76
+ /**
77
+ * Raw workflow input fields passed from parent to child workflow.
78
+ * `defineSubagentWorkflow` maps this into `SubagentSessionInput`.
79
+ */
80
+ interface SubagentWorkflowInput {
81
+ /** Thread ID from parent for continuation */
82
+ previousThreadId?: string;
83
+ /** Sandbox ID inherited from parent */
84
+ sandboxId?: string;
85
+ }
86
+ type SubagentWorkflow<TResult extends z.ZodType = z.ZodType> = (prompt: string, workflowInput: SubagentWorkflowInput, context?: Record<string, unknown>) => Promise<SubagentHandlerResponse<z.infer<TResult> | null>>;
87
+ /**
88
+ * A subagent workflow with embedded metadata (name, description, resultSchema).
89
+ * Created by `defineSubagentWorkflow` — pass directly to `defineSubagent`.
90
+ */
91
+ type SubagentDefinition<TResult extends z.ZodType = z.ZodType, TContext extends Record<string, unknown> = Record<string, unknown>> = ((prompt: string, workflowInput: SubagentWorkflowInput, context?: TContext) => Promise<SubagentHandlerResponse<z.infer<TResult> | null>>) & {
92
+ readonly agentName: string;
93
+ readonly description: string;
94
+ readonly resultSchema?: TResult;
95
+ };
77
96
  /**
78
97
  * Configuration for a subagent that can be spawned by the parent workflow.
79
98
  *
@@ -133,16 +152,16 @@ interface SubagentHooks<TArgs = unknown, TResult = unknown> {
133
152
  }) => PostToolUseFailureHookResult | Promise<PostToolUseFailureHookResult>;
134
153
  }
135
154
  /**
136
- * Input passed to child workflows when spawned as subagents
155
+ * Session config fields passed from parent to child workflow.
137
156
  */
138
- interface SubagentInput {
139
- /** The prompt/task from the parent agent */
140
- prompt: string;
141
- /** Optional context parameters passed from the parent agent */
142
- context?: Record<string, unknown>;
143
- /** When set, the subagent should continue this thread instead of starting a new one */
144
- previousThreadId?: string;
145
- /** Sandbox ID inherited from the parent agent (when SubagentConfig.sandbox is 'inherit') */
157
+ interface SubagentSessionInput {
158
+ /** Agent name spread directly into `createSession` */
159
+ agentName: string;
160
+ /** Thread ID to continue from */
161
+ threadId?: string;
162
+ /** Whether to continue an existing thread */
163
+ continueThread?: boolean;
164
+ /** Sandbox ID inherited from the parent agent */
146
165
  sandboxId?: string;
147
166
  }
148
167
 
@@ -388,4 +407,4 @@ interface ZeitlichSession<M = unknown> {
388
407
  }>;
389
408
  }
390
409
 
391
- export type { AgentResponse as A, Hooks as H, JsonPrimitive as J, ModelInvoker as M, PostHumanMessageAppendHook as P, RunAgentActivity as R, SkillProvider as S, ThreadOps as T, ZeitlichSession as Z, ModelInvokerConfig as a, SkillMetadata as b, Skill as c, AgentState as d, AgentStateManager as e, JsonSerializable as f, JsonValue as g, PostHumanMessageAppendHookContext as h, PreHumanMessageAppendHook as i, PreHumanMessageAppendHookContext as j, SessionConfig as k, SessionEndHook as l, SessionEndHookContext as m, SessionStartHook as n, SessionStartHookContext as o, SubagentConfig as p, SubagentHandlerResponse as q, SubagentHooks as r, SubagentInput as s, SubagentWorkflow as t };
410
+ export type { AgentResponse as A, Hooks as H, JsonPrimitive as J, ModelInvoker as M, PostHumanMessageAppendHook as P, RunAgentActivity as R, SkillProvider as S, ThreadOps as T, ZeitlichSession as Z, ModelInvokerConfig as a, SkillMetadata as b, Skill as c, AgentState as d, AgentStateManager as e, JsonSerializable as f, JsonValue as g, PostHumanMessageAppendHookContext as h, PreHumanMessageAppendHook as i, PreHumanMessageAppendHookContext as j, SessionConfig as k, SessionEndHook as l, SessionEndHookContext as m, SessionStartHook as n, SessionStartHookContext as o, SubagentConfig as p, SubagentDefinition as q, SubagentHandlerResponse as r, SubagentHooks as s, SubagentSessionInput as t, SubagentWorkflow as u, SubagentWorkflowInput as v };
@@ -1,7 +1,7 @@
1
1
  import { Duration } from '@temporalio/common';
2
2
  import { a as ToolMap, b as ToolRouterHooks, M as MessageContent, S as SessionExitReason, c as ToolHandlerResponse, P as PreToolUseHookResult, d as PostToolUseFailureHookResult, e as RawToolCall, f as TokenUsage, B as BaseAgentState, g as RunAgentConfig, h as AgentStatus, W as WorkflowTask, i as ToolDefinition, j as ToolResultConfig, k as ToolCallResultUnion, I as InferToolResults } from './types-BMXzv7TN.js';
3
3
  import { z } from 'zod';
4
- import { g as SandboxOps } from './types-CDubRtad.js';
4
+ import { g as SandboxOps } from './types-BMRzfELQ.js';
5
5
  import { QueryDefinition } from '@temporalio/workflow';
6
6
  import { UpdateDefinition } from '@temporalio/common/lib/interfaces';
7
7
 
@@ -73,7 +73,26 @@ interface Hooks<T extends ToolMap, TResult = unknown> extends ToolRouterHooks<T,
73
73
  type SubagentHandlerResponse<TResult = null> = ToolHandlerResponse<TResult> & {
74
74
  threadId: string;
75
75
  };
76
- type SubagentWorkflow<TResult extends z.ZodType = z.ZodType> = (input: SubagentInput) => Promise<SubagentHandlerResponse<z.infer<TResult> | null>>;
76
+ /**
77
+ * Raw workflow input fields passed from parent to child workflow.
78
+ * `defineSubagentWorkflow` maps this into `SubagentSessionInput`.
79
+ */
80
+ interface SubagentWorkflowInput {
81
+ /** Thread ID from parent for continuation */
82
+ previousThreadId?: string;
83
+ /** Sandbox ID inherited from parent */
84
+ sandboxId?: string;
85
+ }
86
+ type SubagentWorkflow<TResult extends z.ZodType = z.ZodType> = (prompt: string, workflowInput: SubagentWorkflowInput, context?: Record<string, unknown>) => Promise<SubagentHandlerResponse<z.infer<TResult> | null>>;
87
+ /**
88
+ * A subagent workflow with embedded metadata (name, description, resultSchema).
89
+ * Created by `defineSubagentWorkflow` — pass directly to `defineSubagent`.
90
+ */
91
+ type SubagentDefinition<TResult extends z.ZodType = z.ZodType, TContext extends Record<string, unknown> = Record<string, unknown>> = ((prompt: string, workflowInput: SubagentWorkflowInput, context?: TContext) => Promise<SubagentHandlerResponse<z.infer<TResult> | null>>) & {
92
+ readonly agentName: string;
93
+ readonly description: string;
94
+ readonly resultSchema?: TResult;
95
+ };
77
96
  /**
78
97
  * Configuration for a subagent that can be spawned by the parent workflow.
79
98
  *
@@ -133,16 +152,16 @@ interface SubagentHooks<TArgs = unknown, TResult = unknown> {
133
152
  }) => PostToolUseFailureHookResult | Promise<PostToolUseFailureHookResult>;
134
153
  }
135
154
  /**
136
- * Input passed to child workflows when spawned as subagents
155
+ * Session config fields passed from parent to child workflow.
137
156
  */
138
- interface SubagentInput {
139
- /** The prompt/task from the parent agent */
140
- prompt: string;
141
- /** Optional context parameters passed from the parent agent */
142
- context?: Record<string, unknown>;
143
- /** When set, the subagent should continue this thread instead of starting a new one */
144
- previousThreadId?: string;
145
- /** Sandbox ID inherited from the parent agent (when SubagentConfig.sandbox is 'inherit') */
157
+ interface SubagentSessionInput {
158
+ /** Agent name spread directly into `createSession` */
159
+ agentName: string;
160
+ /** Thread ID to continue from */
161
+ threadId?: string;
162
+ /** Whether to continue an existing thread */
163
+ continueThread?: boolean;
164
+ /** Sandbox ID inherited from the parent agent */
146
165
  sandboxId?: string;
147
166
  }
148
167
 
@@ -388,4 +407,4 @@ interface ZeitlichSession<M = unknown> {
388
407
  }>;
389
408
  }
390
409
 
391
- export type { AgentResponse as A, Hooks as H, JsonPrimitive as J, ModelInvoker as M, PostHumanMessageAppendHook as P, RunAgentActivity as R, SkillProvider as S, ThreadOps as T, ZeitlichSession as Z, ModelInvokerConfig as a, SkillMetadata as b, Skill as c, AgentState as d, AgentStateManager as e, JsonSerializable as f, JsonValue as g, PostHumanMessageAppendHookContext as h, PreHumanMessageAppendHook as i, PreHumanMessageAppendHookContext as j, SessionConfig as k, SessionEndHook as l, SessionEndHookContext as m, SessionStartHook as n, SessionStartHookContext as o, SubagentConfig as p, SubagentHandlerResponse as q, SubagentHooks as r, SubagentInput as s, SubagentWorkflow as t };
410
+ export type { AgentResponse as A, Hooks as H, JsonPrimitive as J, ModelInvoker as M, PostHumanMessageAppendHook as P, RunAgentActivity as R, SkillProvider as S, ThreadOps as T, ZeitlichSession as Z, ModelInvokerConfig as a, SkillMetadata as b, Skill as c, AgentState as d, AgentStateManager as e, JsonSerializable as f, JsonValue as g, PostHumanMessageAppendHookContext as h, PreHumanMessageAppendHook as i, PreHumanMessageAppendHookContext as j, SessionConfig as k, SessionEndHook as l, SessionEndHookContext as m, SessionStartHook as n, SessionStartHookContext as o, SubagentConfig as p, SubagentDefinition as q, SubagentHandlerResponse as r, SubagentHooks as s, SubagentSessionInput as t, SubagentWorkflow as u, SubagentWorkflowInput as v };
package/dist/workflow.cjs CHANGED
@@ -336,15 +336,15 @@ function createSubagentHandler(subagents) {
336
336
  const childWorkflowId = `${args.subagent}-${getShortId()}`;
337
337
  const { sandboxId: parentSandboxId } = context;
338
338
  const inheritSandbox = config.sandbox !== "own" && !!parentSandboxId;
339
- const input = {
340
- prompt: args.prompt,
341
- ...config.context && { context: config.context },
342
- ...args.threadId && args.threadId !== null && config.allowThreadContinuation && { previousThreadId: args.threadId },
339
+ const workflowInput = {
340
+ ...args.threadId && args.threadId !== null && config.allowThreadContinuation && {
341
+ previousThreadId: args.threadId
342
+ },
343
343
  ...inheritSandbox && { sandboxId: parentSandboxId }
344
344
  };
345
345
  const childOpts = {
346
346
  workflowId: childWorkflowId,
347
- args: [input],
347
+ args: config.context === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, config.context],
348
348
  taskQueue: config.taskQueue ?? parentTaskQueue
349
349
  };
350
350
  const {
@@ -559,9 +559,7 @@ var createSession = async ({
559
559
  const result = await sandboxOps.createSandbox({ id: threadId });
560
560
  sandboxId = result.sandboxId;
561
561
  if (result.stateUpdate) {
562
- stateManager.mergeUpdate(
563
- result.stateUpdate
564
- );
562
+ stateManager.mergeUpdate(result.stateUpdate);
565
563
  }
566
564
  }
567
565
  if (hooks.onSessionStart) {
@@ -646,6 +644,7 @@ var createSession = async ({
646
644
  );
647
645
  if (!conditionMet) {
648
646
  stateManager.cancel();
647
+ exitReason = "cancelled";
649
648
  await workflow.condition(() => false, "2s");
650
649
  break;
651
650
  }
@@ -699,6 +698,20 @@ function proxySandboxOps(options) {
699
698
  );
700
699
  }
701
700
 
701
+ // src/lib/workflow.ts
702
+ function defineWorkflow(fn) {
703
+ return async (input, workflowInput = {}) => {
704
+ const sessionInput = {
705
+ ...workflowInput.previousThreadId && {
706
+ threadId: workflowInput.previousThreadId,
707
+ continueThread: true
708
+ },
709
+ ...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
710
+ };
711
+ return fn(input, sessionInput);
712
+ };
713
+ }
714
+
702
715
  // src/lib/types.ts
703
716
  function isTerminalStatus(status) {
704
717
  return status === "COMPLETED" || status === "FAILED" || status === "CANCELLED";
@@ -861,8 +874,40 @@ function createAgentStateManager({
861
874
  }
862
875
 
863
876
  // src/lib/subagent/define.ts
864
- function defineSubagent(config) {
865
- return config;
877
+ function defineSubagent(definition, overrides) {
878
+ return {
879
+ agentName: definition.agentName,
880
+ description: definition.description,
881
+ workflow: definition,
882
+ ...definition.resultSchema !== void 0 && {
883
+ resultSchema: definition.resultSchema
884
+ },
885
+ ...overrides
886
+ };
887
+ }
888
+
889
+ // src/lib/subagent/workflow.ts
890
+ function defineSubagentWorkflow(config, fn) {
891
+ const workflow = async (prompt, workflowInput, context) => {
892
+ const sessionInput = {
893
+ agentName: config.name,
894
+ ...workflowInput.previousThreadId && {
895
+ threadId: workflowInput.previousThreadId,
896
+ continueThread: true
897
+ },
898
+ ...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
899
+ };
900
+ return fn(prompt, sessionInput, context ?? {});
901
+ };
902
+ Object.defineProperty(workflow, "name", { value: config.name });
903
+ return Object.assign(workflow, {
904
+ agentName: config.name,
905
+ description: config.description,
906
+ ...config.resultSchema !== void 0 && {
907
+ resultSchema: config.resultSchema
908
+ }
909
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
910
+ });
866
911
  }
867
912
  var SandboxNotSupportedError = class extends common.ApplicationFailure {
868
913
  constructor(operation) {
@@ -949,6 +994,48 @@ function formatVirtualFileTree(entries, opts = {}) {
949
994
  return "/" + printNode(root, "", sort);
950
995
  }
951
996
 
997
+ // src/adapters/sandbox/virtual/queries.ts
998
+ function hasFileWithMimeType(stateManager, pattern) {
999
+ const tree = stateManager.get("fileTree");
1000
+ const matchers = (Array.isArray(pattern) ? pattern : [pattern]).map(buildMatcher);
1001
+ return tree.some((entry) => {
1002
+ const meta = entry.metadata;
1003
+ const mime = meta?.mimeType;
1004
+ return typeof mime === "string" && matchers.some((m) => m(mime));
1005
+ });
1006
+ }
1007
+ function filesWithMimeType(stateManager, pattern) {
1008
+ const tree = stateManager.get("fileTree");
1009
+ const match = buildMatcher(pattern);
1010
+ return tree.filter((entry) => {
1011
+ const meta = entry.metadata;
1012
+ const mime = meta?.mimeType;
1013
+ return typeof mime === "string" && match(mime);
1014
+ });
1015
+ }
1016
+ function hasDirectory(stateManager, pattern) {
1017
+ const tree = stateManager.get("fileTree");
1018
+ const match = buildGlobMatcher(pattern);
1019
+ return tree.some((entry) => {
1020
+ const segments = entry.path.split("/").filter(Boolean);
1021
+ return segments.slice(0, -1).some(match);
1022
+ });
1023
+ }
1024
+ function buildMatcher(pattern) {
1025
+ if (pattern.endsWith("/*")) {
1026
+ const prefix = pattern.slice(0, -1);
1027
+ return (v) => v.startsWith(prefix);
1028
+ }
1029
+ return (v) => v === pattern;
1030
+ }
1031
+ function buildGlobMatcher(pattern) {
1032
+ if (!pattern.includes("*")) return (v) => v === pattern;
1033
+ const re = new RegExp(
1034
+ "^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$"
1035
+ );
1036
+ return (v) => re.test(v);
1037
+ }
1038
+
952
1039
  // src/lib/skills/parse.ts
953
1040
  function parseSkillFile(raw) {
954
1041
  const trimmed = raw.replace(/^\uFEFF/, "");
@@ -1388,12 +1475,17 @@ exports.createTaskListHandler = createTaskListHandler;
1388
1475
  exports.createTaskUpdateHandler = createTaskUpdateHandler;
1389
1476
  exports.createToolRouter = createToolRouter;
1390
1477
  exports.defineSubagent = defineSubagent;
1478
+ exports.defineSubagentWorkflow = defineSubagentWorkflow;
1391
1479
  exports.defineTool = defineTool;
1480
+ exports.defineWorkflow = defineWorkflow;
1392
1481
  exports.editTool = editTool;
1482
+ exports.filesWithMimeType = filesWithMimeType;
1393
1483
  exports.formatVirtualFileTree = formatVirtualFileTree;
1394
1484
  exports.getShortId = getShortId;
1395
1485
  exports.globTool = globTool;
1396
1486
  exports.grepTool = grepTool;
1487
+ exports.hasDirectory = hasDirectory;
1488
+ exports.hasFileWithMimeType = hasFileWithMimeType;
1397
1489
  exports.hasNoOtherToolCalls = hasNoOtherToolCalls;
1398
1490
  exports.isTerminalStatus = isTerminalStatus;
1399
1491
  exports.parseSkillFile = parseSkillFile;