zeitlich 0.2.36 → 0.2.37

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 (200) hide show
  1. package/README.md +146 -92
  2. package/dist/{activities-BVI2lTwr.d.ts → activities-Bb-nAjwQ.d.ts} +2 -2
  3. package/dist/{activities-hd4aNnZE.d.cts → activities-vkI4_3CC.d.cts} +2 -2
  4. package/dist/adapters/sandbox/bedrock/index.cjs +14 -11
  5. package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
  6. package/dist/adapters/sandbox/bedrock/index.d.cts +4 -3
  7. package/dist/adapters/sandbox/bedrock/index.d.ts +4 -3
  8. package/dist/adapters/sandbox/bedrock/index.js +14 -11
  9. package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
  10. package/dist/adapters/sandbox/bedrock/workflow.cjs +2 -0
  11. package/dist/adapters/sandbox/bedrock/workflow.cjs.map +1 -1
  12. package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
  13. package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
  14. package/dist/adapters/sandbox/bedrock/workflow.js +2 -0
  15. package/dist/adapters/sandbox/bedrock/workflow.js.map +1 -1
  16. package/dist/adapters/sandbox/daytona/index.cjs +8 -0
  17. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  18. package/dist/adapters/sandbox/daytona/index.d.cts +2 -1
  19. package/dist/adapters/sandbox/daytona/index.d.ts +2 -1
  20. package/dist/adapters/sandbox/daytona/index.js +8 -0
  21. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  22. package/dist/adapters/sandbox/daytona/workflow.cjs +2 -0
  23. package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -1
  24. package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
  25. package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
  26. package/dist/adapters/sandbox/daytona/workflow.js +2 -0
  27. package/dist/adapters/sandbox/daytona/workflow.js.map +1 -1
  28. package/dist/adapters/sandbox/e2b/index.cjs +59 -10
  29. package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
  30. package/dist/adapters/sandbox/e2b/index.d.cts +5 -3
  31. package/dist/adapters/sandbox/e2b/index.d.ts +5 -3
  32. package/dist/adapters/sandbox/e2b/index.js +59 -10
  33. package/dist/adapters/sandbox/e2b/index.js.map +1 -1
  34. package/dist/adapters/sandbox/e2b/workflow.cjs +2 -0
  35. package/dist/adapters/sandbox/e2b/workflow.cjs.map +1 -1
  36. package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
  37. package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
  38. package/dist/adapters/sandbox/e2b/workflow.js +2 -0
  39. package/dist/adapters/sandbox/e2b/workflow.js.map +1 -1
  40. package/dist/adapters/sandbox/inmemory/index.cjs +5 -0
  41. package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
  42. package/dist/adapters/sandbox/inmemory/index.d.cts +2 -1
  43. package/dist/adapters/sandbox/inmemory/index.d.ts +2 -1
  44. package/dist/adapters/sandbox/inmemory/index.js +5 -0
  45. package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
  46. package/dist/adapters/sandbox/inmemory/workflow.cjs +2 -0
  47. package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -1
  48. package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
  49. package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
  50. package/dist/adapters/sandbox/inmemory/workflow.js +2 -0
  51. package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -1
  52. package/dist/adapters/thread/anthropic/index.cjs +71 -36
  53. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  54. package/dist/adapters/thread/anthropic/index.d.cts +5 -5
  55. package/dist/adapters/thread/anthropic/index.d.ts +5 -5
  56. package/dist/adapters/thread/anthropic/index.js +71 -36
  57. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  58. package/dist/adapters/thread/anthropic/workflow.cjs +5 -1
  59. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  60. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
  61. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
  62. package/dist/adapters/thread/anthropic/workflow.js +5 -1
  63. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  64. package/dist/adapters/thread/google-genai/index.cjs +50 -25
  65. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  66. package/dist/adapters/thread/google-genai/index.d.cts +5 -5
  67. package/dist/adapters/thread/google-genai/index.d.ts +5 -5
  68. package/dist/adapters/thread/google-genai/index.js +50 -25
  69. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  70. package/dist/adapters/thread/google-genai/workflow.cjs +5 -1
  71. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  72. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -5
  73. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -5
  74. package/dist/adapters/thread/google-genai/workflow.js +5 -1
  75. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  76. package/dist/adapters/thread/langchain/index.cjs +34 -7
  77. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  78. package/dist/adapters/thread/langchain/index.d.cts +5 -5
  79. package/dist/adapters/thread/langchain/index.d.ts +5 -5
  80. package/dist/adapters/thread/langchain/index.js +34 -7
  81. package/dist/adapters/thread/langchain/index.js.map +1 -1
  82. package/dist/adapters/thread/langchain/workflow.cjs +5 -1
  83. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  84. package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
  85. package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
  86. package/dist/adapters/thread/langchain/workflow.js +5 -1
  87. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  88. package/dist/index.cjs +206 -120
  89. package/dist/index.cjs.map +1 -1
  90. package/dist/index.d.cts +17 -11
  91. package/dist/index.d.ts +17 -11
  92. package/dist/index.js +207 -121
  93. package/dist/index.js.map +1 -1
  94. package/dist/{proxy-BjdFGPTm.d.ts → proxy-0smGKvx8.d.ts} +1 -1
  95. package/dist/{proxy-7RnVaPdJ.d.cts → proxy-DEtowJyd.d.cts} +1 -1
  96. package/dist/{thread-manager-DjN5JYul.d.ts → thread-manager-3fszQih4.d.ts} +2 -2
  97. package/dist/{thread-manager-CbpiGq1L.d.ts → thread-manager-C-C4pI2z.d.ts} +2 -2
  98. package/dist/{thread-manager-BBzNgQWH.d.cts → thread-manager-CzYln2OC.d.cts} +2 -2
  99. package/dist/{thread-manager-DzXm9eeI.d.cts → thread-manager-D4vgzYrh.d.cts} +2 -2
  100. package/dist/{types-yiXmqedU.d.ts → types-B37hKoWA.d.ts} +1 -1
  101. package/dist/{types-DQ1l_gXL.d.cts → types-BO7Yju20.d.cts} +63 -14
  102. package/dist/{types-wiGLvxWf.d.ts → types-CNuWnvy9.d.ts} +1 -1
  103. package/dist/{types-CADc5V_P.d.ts → types-CPKDl-y_.d.ts} +63 -14
  104. package/dist/{types-Mc_4BCfT.d.cts → types-D08CXPh8.d.cts} +1 -1
  105. package/dist/{types-CBH54cwr.d.cts → types-DWEUmYAJ.d.cts} +1 -1
  106. package/dist/{types-DxCpFNv_.d.cts → types-tQL9njTu.d.cts} +25 -0
  107. package/dist/{types-DxCpFNv_.d.ts → types-tQL9njTu.d.ts} +25 -0
  108. package/dist/{workflow-P2pTSfKu.d.ts → workflow-CjXHbZZc.d.ts} +2 -2
  109. package/dist/{workflow-DhtWRovz.d.cts → workflow-Do_lzJpT.d.cts} +2 -2
  110. package/dist/workflow.cjs +182 -114
  111. package/dist/workflow.cjs.map +1 -1
  112. package/dist/workflow.d.cts +3 -3
  113. package/dist/workflow.d.ts +3 -3
  114. package/dist/workflow.js +183 -115
  115. package/dist/workflow.js.map +1 -1
  116. package/package.json +1 -1
  117. package/src/adapters/sandbox/bedrock/filesystem.ts +6 -12
  118. package/src/adapters/sandbox/bedrock/index.ts +10 -8
  119. package/src/adapters/sandbox/bedrock/proxy.ts +2 -0
  120. package/src/adapters/sandbox/daytona/index.ts +6 -0
  121. package/src/adapters/sandbox/daytona/proxy.ts +2 -0
  122. package/src/adapters/sandbox/e2b/filesystem.ts +5 -4
  123. package/src/adapters/sandbox/e2b/index.ts +63 -12
  124. package/src/adapters/sandbox/e2b/proxy.ts +2 -0
  125. package/src/adapters/sandbox/inmemory/index.ts +5 -0
  126. package/src/adapters/sandbox/inmemory/proxy.ts +2 -0
  127. package/src/adapters/thread/anthropic/activities.ts +49 -26
  128. package/src/adapters/thread/anthropic/model-invoker.ts +15 -6
  129. package/src/adapters/thread/anthropic/proxy.ts +6 -2
  130. package/src/adapters/thread/anthropic/thread-manager.test.ts +26 -7
  131. package/src/adapters/thread/anthropic/thread-manager.ts +60 -46
  132. package/src/adapters/thread/google-genai/activities.ts +7 -2
  133. package/src/adapters/thread/google-genai/model-invoker.ts +26 -8
  134. package/src/adapters/thread/google-genai/proxy.ts +6 -2
  135. package/src/adapters/thread/google-genai/thread-manager.test.ts +13 -3
  136. package/src/adapters/thread/google-genai/thread-manager.ts +54 -33
  137. package/src/adapters/thread/langchain/activities.ts +46 -24
  138. package/src/adapters/thread/langchain/hooks.test.ts +36 -49
  139. package/src/adapters/thread/langchain/hooks.ts +18 -5
  140. package/src/adapters/thread/langchain/model-invoker.ts +3 -3
  141. package/src/adapters/thread/langchain/proxy.ts +6 -2
  142. package/src/adapters/thread/langchain/thread-manager.test.ts +5 -1
  143. package/src/adapters/thread/langchain/thread-manager.ts +20 -9
  144. package/src/index.ts +4 -1
  145. package/src/lib/activity.ts +16 -6
  146. package/src/lib/hooks/types.ts +6 -6
  147. package/src/lib/lifecycle.ts +9 -1
  148. package/src/lib/model/proxy.ts +2 -2
  149. package/src/lib/observability/hooks.ts +4 -5
  150. package/src/lib/observability/index.ts +1 -4
  151. package/src/lib/sandbox/manager.ts +21 -4
  152. package/src/lib/sandbox/node-fs.ts +3 -6
  153. package/src/lib/sandbox/sandbox.test.ts +36 -3
  154. package/src/lib/sandbox/tree.integration.test.ts +10 -3
  155. package/src/lib/sandbox/types.ts +35 -1
  156. package/src/lib/session/session-edge-cases.integration.test.ts +51 -13
  157. package/src/lib/session/session.integration.test.ts +139 -0
  158. package/src/lib/session/session.ts +50 -19
  159. package/src/lib/session/types.ts +13 -5
  160. package/src/lib/skills/fs-provider.ts +12 -8
  161. package/src/lib/skills/handler.ts +1 -1
  162. package/src/lib/skills/parse.ts +3 -1
  163. package/src/lib/skills/register.ts +1 -3
  164. package/src/lib/skills/skills.integration.test.ts +25 -15
  165. package/src/lib/state/manager.integration.test.ts +12 -2
  166. package/src/lib/subagent/define.ts +1 -1
  167. package/src/lib/subagent/handler.ts +186 -71
  168. package/src/lib/subagent/index.ts +1 -5
  169. package/src/lib/subagent/register.ts +3 -2
  170. package/src/lib/subagent/signals.ts +1 -10
  171. package/src/lib/subagent/subagent.integration.test.ts +438 -156
  172. package/src/lib/subagent/tool.ts +4 -3
  173. package/src/lib/subagent/types.ts +50 -20
  174. package/src/lib/subagent/workflow.ts +9 -49
  175. package/src/lib/thread/id.test.ts +1 -1
  176. package/src/lib/thread/id.ts +1 -2
  177. package/src/lib/thread/proxy.ts +3 -4
  178. package/src/lib/thread/types.ts +11 -3
  179. package/src/lib/tool-router/index.ts +1 -5
  180. package/src/lib/tool-router/router-edge-cases.integration.test.ts +1 -1
  181. package/src/lib/tool-router/router.ts +3 -2
  182. package/src/lib/tool-router/types.ts +11 -3
  183. package/src/lib/tool-router/with-sandbox.ts +19 -5
  184. package/src/lib/virtual-fs/filesystem.ts +1 -1
  185. package/src/lib/virtual-fs/index.ts +5 -1
  186. package/src/lib/virtual-fs/mutations.ts +2 -4
  187. package/src/lib/virtual-fs/queries.ts +9 -5
  188. package/src/lib/virtual-fs/types.ts +4 -1
  189. package/src/lib/virtual-fs/virtual-fs.test.ts +9 -11
  190. package/src/lib/workflow.test.ts +7 -4
  191. package/src/lib/workflow.ts +1 -5
  192. package/src/tools/ask-user-question/tool.ts +1 -3
  193. package/src/tools/glob/handler.ts +1 -4
  194. package/src/tools/task-get/handler.ts +4 -5
  195. package/src/tools/task-list/handler.ts +1 -4
  196. package/src/tools/task-update/handler.ts +4 -5
  197. package/src/workflow.ts +20 -7
  198. package/tsup.config.ts +9 -6
  199. package/src/lib/.env +0 -1
  200. package/src/tools/bash/.env +0 -1
@@ -1,5 +1,5 @@
1
1
  import { proxyActivities, ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from './types-CADc5V_P.js';
2
+ import { T as ThreadOps } from './types-CPKDl-y_.js';
3
3
 
4
4
  /**
5
5
  * Shared proxy helper for thread operations.
@@ -1,5 +1,5 @@
1
1
  import { proxyActivities, ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from './types-DQ1l_gXL.cjs';
2
+ import { T as ThreadOps } from './types-BO7Yju20.cjs';
3
3
 
4
4
  /**
5
5
  * Shared proxy helper for thread operations.
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-CADc5V_P.js';
2
+ import { J as JsonValue } from './types-CPKDl-y_.js';
3
3
  import { MessageContent, StoredMessage, BaseMessage } from '@langchain/core/messages';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-yiXmqedU.js';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-B37hKoWA.js';
5
5
 
6
6
  /** SDK-native content type for LangChain human messages */
7
7
  type LangChainContent = string | MessageContent;
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
2
  import Anthropic from '@anthropic-ai/sdk';
3
- import { J as JsonValue } from './types-CADc5V_P.js';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-yiXmqedU.js';
3
+ import { J as JsonValue } from './types-CPKDl-y_.js';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-B37hKoWA.js';
5
5
 
6
6
  /** SDK-native content type for Anthropic human messages */
7
7
  type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-DQ1l_gXL.cjs';
2
+ import { J as JsonValue } from './types-BO7Yju20.cjs';
3
3
  import { MessageContent, StoredMessage, BaseMessage } from '@langchain/core/messages';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-Mc_4BCfT.cjs';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-D08CXPh8.cjs';
5
5
 
6
6
  /** SDK-native content type for LangChain human messages */
7
7
  type LangChainContent = string | MessageContent;
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
2
  import Anthropic from '@anthropic-ai/sdk';
3
- import { J as JsonValue } from './types-DQ1l_gXL.cjs';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-Mc_4BCfT.cjs';
3
+ import { J as JsonValue } from './types-BO7Yju20.cjs';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-D08CXPh8.cjs';
5
5
 
6
6
  /** SDK-native content type for Anthropic human messages */
7
7
  type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
@@ -1,5 +1,5 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-CADc5V_P.js';
2
+ import { J as JsonValue } from './types-CPKDl-y_.js';
3
3
 
4
4
  interface ThreadManagerConfig<T> {
5
5
  redis: Redis;
@@ -2,7 +2,7 @@ import { Duration } from '@temporalio/common';
2
2
  import { ActivityFunctionWithOptions, QueryDefinition, ActivityInterfaceFor } from '@temporalio/workflow';
3
3
  import { UpdateDefinition } from '@temporalio/common/lib/interfaces';
4
4
  import { z } from 'zod';
5
- import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, g as SandboxOps } from './types-DxCpFNv_.cjs';
5
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, f as SandboxSnapshot, g as SandboxOps } from './types-tQL9njTu.cjs';
6
6
 
7
7
  /**
8
8
  * A tool definition with a name, description, and Zod schema for arguments.
@@ -797,6 +797,7 @@ type ThreadInit = {
797
797
  mode: "fork";
798
798
  threadId: string;
799
799
  };
800
+
800
801
  /**
801
802
  * Sandbox initialization strategy.
802
803
  *
@@ -808,6 +809,8 @@ type ThreadInit = {
808
809
  * on exit.
809
810
  * - `"fork"` — fork from an existing (or paused) sandbox; a new sandbox is
810
811
  * created and owned by this session.
812
+ * - `"from-snapshot"` — restore a fresh sandbox from a previously captured
813
+ * {@link SandboxSnapshot}. The new sandbox is owned by this session.
811
814
  * - `"inherit"` — use a sandbox owned by someone else (e.g. a parent agent).
812
815
  * The session will **not** manage its lifecycle on exit.
813
816
  */
@@ -820,6 +823,9 @@ type SandboxInit = {
820
823
  } | {
821
824
  mode: "fork";
822
825
  sandboxId: string;
826
+ } | {
827
+ mode: "from-snapshot";
828
+ snapshot: SandboxSnapshot;
823
829
  } | {
824
830
  mode: "inherit";
825
831
  sandboxId: string;
@@ -830,8 +836,11 @@ type SandboxInit = {
830
836
  * - `"destroy"` — tear down the sandbox entirely.
831
837
  * - `"pause"` — pause the sandbox so it can be resumed later.
832
838
  * - `"keep"` — leave the sandbox running (no-op on exit).
839
+ * - `"snapshot"` — capture a snapshot then destroy the sandbox. The snapshot
840
+ * is surfaced on the session result so the caller can reuse it to spawn
841
+ * future sandboxes.
833
842
  */
834
- type SandboxShutdown = "destroy" | "pause" | "keep";
843
+ type SandboxShutdown = "destroy" | "pause" | "keep" | "snapshot";
835
844
  /**
836
845
  * Extended shutdown options available to subagent workflows.
837
846
  *
@@ -847,6 +856,14 @@ type SubagentSandboxShutdown = SandboxShutdown | "pause-until-parent-close" | "k
847
856
  type SubagentHandlerResponse<TResult = null, TToolResponse = JsonValue> = ToolHandlerResponse<TResult, TToolResponse> & {
848
857
  threadId: string;
849
858
  sandboxId?: string;
859
+ /** Snapshot captured on session exit when `sandboxShutdown === "snapshot"`. */
860
+ snapshot?: SandboxSnapshot;
861
+ /**
862
+ * Snapshot captured immediately after the sandbox was seeded (before the
863
+ * first agent turn) when `continuation === "snapshot"`. Only set on the
864
+ * first call that actually created the sandbox.
865
+ */
866
+ baseSnapshot?: SandboxSnapshot;
850
867
  };
851
868
  /**
852
869
  * Raw workflow input fields passed from parent to child workflow.
@@ -876,23 +893,31 @@ type SubagentContext = Record<string, unknown> | (() => Record<string, unknown>)
876
893
  * Sandbox configuration for a subagent.
877
894
  *
878
895
  * - `"none"` — no sandbox (default).
879
- * - `{ source: "inherit", continuation }` — reuse the parent's sandbox.
896
+ * - `{ source: "inherit", continuation, proxy }` — reuse the parent's sandbox.
880
897
  * `continuation: "continue"` shares the parent sandbox directly;
881
898
  * `continuation: "fork"` forks from the parent on every call.
882
- * - `{ source: "own", init?, continuation }` — the child gets its own sandbox.
883
- * `init: "per-call"` (default) creates fresh each call (thread continuation
884
- * uses the previous sandbox). `init: "once"` creates on the first call and
885
- * stores it for all subsequent calls.
899
+ * - `{ source: "own", init?, continuation, proxy }` — the child gets its own
900
+ * sandbox. `init: "per-call"` (default) creates fresh each call (thread
901
+ * continuation uses the previous sandbox). `init: "once"` creates on the
902
+ * first call and stores it for all subsequent calls.
903
+ *
904
+ * `proxy` is a factory that returns workflow-safe sandbox ops matching the
905
+ * subagent's own activities. Called once inside `createSubagentHandler` with
906
+ * `scope = agentName`, so the returned proxy resolves to the same activity
907
+ * prefix the child session uses. The parent uses it to destroy lingering
908
+ * sandboxes and delete stored snapshots at shutdown.
886
909
  */
887
910
  type SubagentSandboxConfig = "none" | {
888
911
  source: "inherit";
889
912
  continuation: "continue" | "fork";
890
913
  shutdown?: SubagentSandboxShutdown;
914
+ proxy: (scope: string) => SandboxOps;
891
915
  } | {
892
916
  source: "own";
893
917
  init?: "per-call" | "once";
894
- continuation: "continue" | "fork";
918
+ continuation: "continue" | "fork" | "snapshot";
895
919
  shutdown?: SubagentSandboxShutdown;
920
+ proxy: (scope: string) => SandboxOps;
896
921
  };
897
922
  /**
898
923
  * Configuration for a subagent that can be spawned by the parent workflow.
@@ -930,6 +955,21 @@ interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
930
955
  * Sandbox strategy for this subagent.
931
956
  *
932
957
  * @see {@link SubagentSandboxConfig}
958
+ *
959
+ * @example
960
+ * ```ts
961
+ * import { proxyDaytonaSandboxOps } from "zeitlich/adapters/sandbox/daytona/workflow";
962
+ *
963
+ * const researcher: SubagentConfig = {
964
+ * agentName: "researcher",
965
+ * workflow: researcherWorkflow,
966
+ * sandbox: {
967
+ * source: "own",
968
+ * continuation: "snapshot",
969
+ * proxy: proxyDaytonaSandboxOps,
970
+ * },
971
+ * };
972
+ * ```
933
973
  */
934
974
  sandbox?: SubagentSandboxConfig;
935
975
  }
@@ -963,18 +1003,16 @@ interface SubagentHooks<TArgs = unknown, TResult = unknown> {
963
1003
  }) => PostToolUseFailureHookResult | Promise<PostToolUseFailureHookResult>;
964
1004
  }
965
1005
  /**
966
- * Extended response from the subagent `fn` — includes optional cleanup callbacks
967
- * stripped before signaling the parent.
1006
+ * Response returned from a subagent workflow `fn`.
968
1007
  *
969
1008
  * When `TSandboxShutdown` is `"pause-until-parent-close"` or
970
- * `"keep-until-parent-close"`, both `destroySandbox` and `sandboxId` become
971
- * required so the parent can coordinate cleanup.
1009
+ * `"keep-until-parent-close"`, the parent needs the `sandboxId` to destroy
1010
+ * the sandbox at its own shutdown, so the field becomes required.
972
1011
  */
973
1012
  type SubagentFnResult<TResult = null, TSandboxShutdown extends SubagentSandboxShutdown = SubagentSandboxShutdown> = SubagentHandlerResponse<TResult> & (TSandboxShutdown extends "pause-until-parent-close" | "keep-until-parent-close" ? {
974
- destroySandbox: () => Promise<void>;
975
1013
  sandboxId: string;
976
1014
  } : {
977
- destroySandbox?: () => Promise<void>;
1015
+ sandboxId?: string;
978
1016
  });
979
1017
  /**
980
1018
  * Session config fields passed from parent to child workflow.
@@ -1221,6 +1259,17 @@ type SessionResult<M, TState extends JsonSerializable<TState>, HasSandbox extend
1221
1259
  finalMessage: M | null;
1222
1260
  exitReason: SessionExitReason;
1223
1261
  usage: ReturnType<AgentStateManager<TState>["getTotalUsage"]>;
1262
+ /**
1263
+ * Snapshot captured on exit when `sandboxShutdown === "snapshot"`.
1264
+ */
1265
+ snapshot?: SandboxSnapshot;
1266
+ /**
1267
+ * Snapshot captured immediately after sandbox seeding (before the agent
1268
+ * loop starts) when `sandbox.mode === "new"` and
1269
+ * `sandboxShutdown === "snapshot"`. Intended as a reusable "base" for new
1270
+ * threads that want to skip re-seeding.
1271
+ */
1272
+ baseSnapshot?: SandboxSnapshot;
1224
1273
  } & (HasSandbox extends true ? {
1225
1274
  sandboxId: string;
1226
1275
  } : {
@@ -1,4 +1,4 @@
1
- import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox, d as SandboxCreateOptions } from './types-DxCpFNv_.js';
1
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox, d as SandboxCreateOptions } from './types-tQL9njTu.js';
2
2
  import { BedrockAgentCoreClient, BedrockAgentCoreClientConfig } from '@aws-sdk/client-bedrock-agentcore';
3
3
 
4
4
  /**
@@ -2,7 +2,7 @@ import { Duration } from '@temporalio/common';
2
2
  import { ActivityFunctionWithOptions, QueryDefinition, ActivityInterfaceFor } from '@temporalio/workflow';
3
3
  import { UpdateDefinition } from '@temporalio/common/lib/interfaces';
4
4
  import { z } from 'zod';
5
- import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, g as SandboxOps } from './types-DxCpFNv_.js';
5
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, f as SandboxSnapshot, g as SandboxOps } from './types-tQL9njTu.js';
6
6
 
7
7
  /**
8
8
  * A tool definition with a name, description, and Zod schema for arguments.
@@ -797,6 +797,7 @@ type ThreadInit = {
797
797
  mode: "fork";
798
798
  threadId: string;
799
799
  };
800
+
800
801
  /**
801
802
  * Sandbox initialization strategy.
802
803
  *
@@ -808,6 +809,8 @@ type ThreadInit = {
808
809
  * on exit.
809
810
  * - `"fork"` — fork from an existing (or paused) sandbox; a new sandbox is
810
811
  * created and owned by this session.
812
+ * - `"from-snapshot"` — restore a fresh sandbox from a previously captured
813
+ * {@link SandboxSnapshot}. The new sandbox is owned by this session.
811
814
  * - `"inherit"` — use a sandbox owned by someone else (e.g. a parent agent).
812
815
  * The session will **not** manage its lifecycle on exit.
813
816
  */
@@ -820,6 +823,9 @@ type SandboxInit = {
820
823
  } | {
821
824
  mode: "fork";
822
825
  sandboxId: string;
826
+ } | {
827
+ mode: "from-snapshot";
828
+ snapshot: SandboxSnapshot;
823
829
  } | {
824
830
  mode: "inherit";
825
831
  sandboxId: string;
@@ -830,8 +836,11 @@ type SandboxInit = {
830
836
  * - `"destroy"` — tear down the sandbox entirely.
831
837
  * - `"pause"` — pause the sandbox so it can be resumed later.
832
838
  * - `"keep"` — leave the sandbox running (no-op on exit).
839
+ * - `"snapshot"` — capture a snapshot then destroy the sandbox. The snapshot
840
+ * is surfaced on the session result so the caller can reuse it to spawn
841
+ * future sandboxes.
833
842
  */
834
- type SandboxShutdown = "destroy" | "pause" | "keep";
843
+ type SandboxShutdown = "destroy" | "pause" | "keep" | "snapshot";
835
844
  /**
836
845
  * Extended shutdown options available to subagent workflows.
837
846
  *
@@ -847,6 +856,14 @@ type SubagentSandboxShutdown = SandboxShutdown | "pause-until-parent-close" | "k
847
856
  type SubagentHandlerResponse<TResult = null, TToolResponse = JsonValue> = ToolHandlerResponse<TResult, TToolResponse> & {
848
857
  threadId: string;
849
858
  sandboxId?: string;
859
+ /** Snapshot captured on session exit when `sandboxShutdown === "snapshot"`. */
860
+ snapshot?: SandboxSnapshot;
861
+ /**
862
+ * Snapshot captured immediately after the sandbox was seeded (before the
863
+ * first agent turn) when `continuation === "snapshot"`. Only set on the
864
+ * first call that actually created the sandbox.
865
+ */
866
+ baseSnapshot?: SandboxSnapshot;
850
867
  };
851
868
  /**
852
869
  * Raw workflow input fields passed from parent to child workflow.
@@ -876,23 +893,31 @@ type SubagentContext = Record<string, unknown> | (() => Record<string, unknown>)
876
893
  * Sandbox configuration for a subagent.
877
894
  *
878
895
  * - `"none"` — no sandbox (default).
879
- * - `{ source: "inherit", continuation }` — reuse the parent's sandbox.
896
+ * - `{ source: "inherit", continuation, proxy }` — reuse the parent's sandbox.
880
897
  * `continuation: "continue"` shares the parent sandbox directly;
881
898
  * `continuation: "fork"` forks from the parent on every call.
882
- * - `{ source: "own", init?, continuation }` — the child gets its own sandbox.
883
- * `init: "per-call"` (default) creates fresh each call (thread continuation
884
- * uses the previous sandbox). `init: "once"` creates on the first call and
885
- * stores it for all subsequent calls.
899
+ * - `{ source: "own", init?, continuation, proxy }` — the child gets its own
900
+ * sandbox. `init: "per-call"` (default) creates fresh each call (thread
901
+ * continuation uses the previous sandbox). `init: "once"` creates on the
902
+ * first call and stores it for all subsequent calls.
903
+ *
904
+ * `proxy` is a factory that returns workflow-safe sandbox ops matching the
905
+ * subagent's own activities. Called once inside `createSubagentHandler` with
906
+ * `scope = agentName`, so the returned proxy resolves to the same activity
907
+ * prefix the child session uses. The parent uses it to destroy lingering
908
+ * sandboxes and delete stored snapshots at shutdown.
886
909
  */
887
910
  type SubagentSandboxConfig = "none" | {
888
911
  source: "inherit";
889
912
  continuation: "continue" | "fork";
890
913
  shutdown?: SubagentSandboxShutdown;
914
+ proxy: (scope: string) => SandboxOps;
891
915
  } | {
892
916
  source: "own";
893
917
  init?: "per-call" | "once";
894
- continuation: "continue" | "fork";
918
+ continuation: "continue" | "fork" | "snapshot";
895
919
  shutdown?: SubagentSandboxShutdown;
920
+ proxy: (scope: string) => SandboxOps;
896
921
  };
897
922
  /**
898
923
  * Configuration for a subagent that can be spawned by the parent workflow.
@@ -930,6 +955,21 @@ interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
930
955
  * Sandbox strategy for this subagent.
931
956
  *
932
957
  * @see {@link SubagentSandboxConfig}
958
+ *
959
+ * @example
960
+ * ```ts
961
+ * import { proxyDaytonaSandboxOps } from "zeitlich/adapters/sandbox/daytona/workflow";
962
+ *
963
+ * const researcher: SubagentConfig = {
964
+ * agentName: "researcher",
965
+ * workflow: researcherWorkflow,
966
+ * sandbox: {
967
+ * source: "own",
968
+ * continuation: "snapshot",
969
+ * proxy: proxyDaytonaSandboxOps,
970
+ * },
971
+ * };
972
+ * ```
933
973
  */
934
974
  sandbox?: SubagentSandboxConfig;
935
975
  }
@@ -963,18 +1003,16 @@ interface SubagentHooks<TArgs = unknown, TResult = unknown> {
963
1003
  }) => PostToolUseFailureHookResult | Promise<PostToolUseFailureHookResult>;
964
1004
  }
965
1005
  /**
966
- * Extended response from the subagent `fn` — includes optional cleanup callbacks
967
- * stripped before signaling the parent.
1006
+ * Response returned from a subagent workflow `fn`.
968
1007
  *
969
1008
  * When `TSandboxShutdown` is `"pause-until-parent-close"` or
970
- * `"keep-until-parent-close"`, both `destroySandbox` and `sandboxId` become
971
- * required so the parent can coordinate cleanup.
1009
+ * `"keep-until-parent-close"`, the parent needs the `sandboxId` to destroy
1010
+ * the sandbox at its own shutdown, so the field becomes required.
972
1011
  */
973
1012
  type SubagentFnResult<TResult = null, TSandboxShutdown extends SubagentSandboxShutdown = SubagentSandboxShutdown> = SubagentHandlerResponse<TResult> & (TSandboxShutdown extends "pause-until-parent-close" | "keep-until-parent-close" ? {
974
- destroySandbox: () => Promise<void>;
975
1013
  sandboxId: string;
976
1014
  } : {
977
- destroySandbox?: () => Promise<void>;
1015
+ sandboxId?: string;
978
1016
  });
979
1017
  /**
980
1018
  * Session config fields passed from parent to child workflow.
@@ -1221,6 +1259,17 @@ type SessionResult<M, TState extends JsonSerializable<TState>, HasSandbox extend
1221
1259
  finalMessage: M | null;
1222
1260
  exitReason: SessionExitReason;
1223
1261
  usage: ReturnType<AgentStateManager<TState>["getTotalUsage"]>;
1262
+ /**
1263
+ * Snapshot captured on exit when `sandboxShutdown === "snapshot"`.
1264
+ */
1265
+ snapshot?: SandboxSnapshot;
1266
+ /**
1267
+ * Snapshot captured immediately after sandbox seeding (before the agent
1268
+ * loop starts) when `sandbox.mode === "new"` and
1269
+ * `sandboxShutdown === "snapshot"`. Intended as a reusable "base" for new
1270
+ * threads that want to skip re-seeding.
1271
+ */
1272
+ baseSnapshot?: SandboxSnapshot;
1224
1273
  } & (HasSandbox extends true ? {
1225
1274
  sandboxId: string;
1226
1275
  } : {
@@ -1,5 +1,5 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-DQ1l_gXL.cjs';
2
+ import { J as JsonValue } from './types-BO7Yju20.cjs';
3
3
 
4
4
  interface ThreadManagerConfig<T> {
5
5
  redis: Redis;
@@ -1,4 +1,4 @@
1
- import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox, d as SandboxCreateOptions } from './types-DxCpFNv_.cjs';
1
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox, d as SandboxCreateOptions } from './types-tQL9njTu.cjs';
2
2
  import { BedrockAgentCoreClient, BedrockAgentCoreClientConfig } from '@aws-sdk/client-bedrock-agentcore';
3
3
 
4
4
  /**
@@ -13,6 +13,15 @@ interface FileStat {
13
13
  size: number;
14
14
  mtime: Date;
15
15
  }
16
+ interface SandboxNetworkConfig {
17
+ allowOut?: string[];
18
+ denyOut?: string[];
19
+ allowPublicTraffic?: boolean;
20
+ }
21
+ interface SandboxLifecycleConfig {
22
+ onTimeout: "kill" | "pause";
23
+ autoResume?: boolean;
24
+ }
16
25
  /**
17
26
  * Provider-agnostic filesystem interface.
18
27
  *
@@ -83,6 +92,16 @@ interface SandboxCreateOptions {
83
92
  initialFiles?: Record<string, string | Uint8Array>;
84
93
  /** Environment variables available inside the sandbox */
85
94
  env?: Record<string, string>;
95
+ /** Key-value metadata surfaced via provider list/query APIs */
96
+ metadata?: Record<string, string>;
97
+ /** Sandbox idle timeout in milliseconds */
98
+ timeoutMs?: number;
99
+ /** Enable or disable outbound internet access */
100
+ allowInternetAccess?: boolean;
101
+ /** Outbound network allow/deny rules */
102
+ network?: SandboxNetworkConfig;
103
+ /** Sandbox timeout behaviour */
104
+ lifecycle?: SandboxLifecycleConfig;
86
105
  }
87
106
  interface SandboxCreateResult {
88
107
  sandbox: Sandbox;
@@ -98,6 +117,8 @@ interface SandboxProvider<TOptions extends SandboxCreateOptions = SandboxCreateO
98
117
  resume(sandboxId: string): Promise<void>;
99
118
  snapshot(sandboxId: string): Promise<SandboxSnapshot>;
100
119
  restore(snapshot: SandboxSnapshot): Promise<Sandbox>;
120
+ /** Delete a previously captured snapshot. No-op if already deleted. */
121
+ deleteSnapshot(snapshot: SandboxSnapshot): Promise<void>;
101
122
  fork(sandboxId: string): Promise<Sandbox>;
102
123
  }
103
124
  interface SandboxOps<TOptions extends SandboxCreateOptions = SandboxCreateOptions, TCtx = unknown> {
@@ -109,6 +130,10 @@ interface SandboxOps<TOptions extends SandboxCreateOptions = SandboxCreateOption
109
130
  /** Resume a paused sandbox. No-op if already running. */
110
131
  resumeSandbox(sandboxId: string): Promise<void>;
111
132
  snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;
133
+ /** Create a fresh sandbox from a previously captured snapshot. */
134
+ restoreSandbox(snapshot: SandboxSnapshot): Promise<string>;
135
+ /** Delete a previously captured snapshot. No-op if already deleted. */
136
+ deleteSandboxSnapshot(snapshot: SandboxSnapshot): Promise<void>;
112
137
  forkSandbox(sandboxId: string): Promise<string>;
113
138
  }
114
139
  /**
@@ -13,6 +13,15 @@ interface FileStat {
13
13
  size: number;
14
14
  mtime: Date;
15
15
  }
16
+ interface SandboxNetworkConfig {
17
+ allowOut?: string[];
18
+ denyOut?: string[];
19
+ allowPublicTraffic?: boolean;
20
+ }
21
+ interface SandboxLifecycleConfig {
22
+ onTimeout: "kill" | "pause";
23
+ autoResume?: boolean;
24
+ }
16
25
  /**
17
26
  * Provider-agnostic filesystem interface.
18
27
  *
@@ -83,6 +92,16 @@ interface SandboxCreateOptions {
83
92
  initialFiles?: Record<string, string | Uint8Array>;
84
93
  /** Environment variables available inside the sandbox */
85
94
  env?: Record<string, string>;
95
+ /** Key-value metadata surfaced via provider list/query APIs */
96
+ metadata?: Record<string, string>;
97
+ /** Sandbox idle timeout in milliseconds */
98
+ timeoutMs?: number;
99
+ /** Enable or disable outbound internet access */
100
+ allowInternetAccess?: boolean;
101
+ /** Outbound network allow/deny rules */
102
+ network?: SandboxNetworkConfig;
103
+ /** Sandbox timeout behaviour */
104
+ lifecycle?: SandboxLifecycleConfig;
86
105
  }
87
106
  interface SandboxCreateResult {
88
107
  sandbox: Sandbox;
@@ -98,6 +117,8 @@ interface SandboxProvider<TOptions extends SandboxCreateOptions = SandboxCreateO
98
117
  resume(sandboxId: string): Promise<void>;
99
118
  snapshot(sandboxId: string): Promise<SandboxSnapshot>;
100
119
  restore(snapshot: SandboxSnapshot): Promise<Sandbox>;
120
+ /** Delete a previously captured snapshot. No-op if already deleted. */
121
+ deleteSnapshot(snapshot: SandboxSnapshot): Promise<void>;
101
122
  fork(sandboxId: string): Promise<Sandbox>;
102
123
  }
103
124
  interface SandboxOps<TOptions extends SandboxCreateOptions = SandboxCreateOptions, TCtx = unknown> {
@@ -109,6 +130,10 @@ interface SandboxOps<TOptions extends SandboxCreateOptions = SandboxCreateOption
109
130
  /** Resume a paused sandbox. No-op if already running. */
110
131
  resumeSandbox(sandboxId: string): Promise<void>;
111
132
  snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;
133
+ /** Create a fresh sandbox from a previously captured snapshot. */
134
+ restoreSandbox(snapshot: SandboxSnapshot): Promise<string>;
135
+ /** Delete a previously captured snapshot. No-op if already deleted. */
136
+ deleteSandboxSnapshot(snapshot: SandboxSnapshot): Promise<void>;
112
137
  forkSandbox(sandboxId: string): Promise<string>;
113
138
  }
114
139
  /**
@@ -1,5 +1,5 @@
1
- import { ao as ToolMap, _ as SessionConfig, az as ZeitlichSession, Y as SandboxShutdown, ag as ThreadInit, X as SandboxInit, t as JsonSerializable, B as BaseAgentState, o as AgentStateManager, aB as ToolRouterOptions, ar as ToolRouter, R as RouterContext, J as JsonValue, at as ToolWithHandler, v as ParsedToolCallUnion, ap as ToolNames, a6 as SubagentDefinition, a9 as SubagentHooks, aa as SubagentSandboxConfig, a5 as SubagentConfig, ab as SubagentSandboxShutdown, ac as SubagentSessionInput, a7 as SubagentFnResult, a3 as SessionStartHook, $ as SessionEndHook, D as PostToolUseHook, y as PostToolUseFailureHook, a1 as SessionExitReason, ah as TokenUsage, e as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, av as VirtualFileTree, j as TreeMutation, r as FileEntry, aw as VirtualFsOps, g as SkillMetadata, h as Skill, b as ToolHandlerResponse, am as ToolHandler, ay as WorkflowTask, c as ActivityToolHandler } from './types-CADc5V_P.js';
2
- import { g as SandboxOps } from './types-DxCpFNv_.js';
1
+ import { ao as ToolMap, _ as SessionConfig, az as ZeitlichSession, Y as SandboxShutdown, ag as ThreadInit, X as SandboxInit, t as JsonSerializable, B as BaseAgentState, o as AgentStateManager, aB as ToolRouterOptions, ar as ToolRouter, R as RouterContext, J as JsonValue, at as ToolWithHandler, v as ParsedToolCallUnion, ap as ToolNames, a6 as SubagentDefinition, a9 as SubagentHooks, aa as SubagentSandboxConfig, a5 as SubagentConfig, ab as SubagentSandboxShutdown, ac as SubagentSessionInput, a7 as SubagentFnResult, a3 as SessionStartHook, $ as SessionEndHook, D as PostToolUseHook, y as PostToolUseFailureHook, a1 as SessionExitReason, ah as TokenUsage, e as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, av as VirtualFileTree, j as TreeMutation, r as FileEntry, aw as VirtualFsOps, g as SkillMetadata, h as Skill, b as ToolHandlerResponse, am as ToolHandler, ay as WorkflowTask, c as ActivityToolHandler } from './types-CPKDl-y_.js';
2
+ import { g as SandboxOps } from './types-tQL9njTu.js';
3
3
  import z$1, { z } from 'zod';
4
4
  import { Sinks, proxyActivities } from '@temporalio/workflow';
5
5
 
@@ -1,5 +1,5 @@
1
- import { ao as ToolMap, _ as SessionConfig, az as ZeitlichSession, Y as SandboxShutdown, ag as ThreadInit, X as SandboxInit, t as JsonSerializable, B as BaseAgentState, o as AgentStateManager, aB as ToolRouterOptions, ar as ToolRouter, R as RouterContext, J as JsonValue, at as ToolWithHandler, v as ParsedToolCallUnion, ap as ToolNames, a6 as SubagentDefinition, a9 as SubagentHooks, aa as SubagentSandboxConfig, a5 as SubagentConfig, ab as SubagentSandboxShutdown, ac as SubagentSessionInput, a7 as SubagentFnResult, a3 as SessionStartHook, $ as SessionEndHook, D as PostToolUseHook, y as PostToolUseFailureHook, a1 as SessionExitReason, ah as TokenUsage, e as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, av as VirtualFileTree, j as TreeMutation, r as FileEntry, aw as VirtualFsOps, g as SkillMetadata, h as Skill, b as ToolHandlerResponse, am as ToolHandler, ay as WorkflowTask, c as ActivityToolHandler } from './types-DQ1l_gXL.cjs';
2
- import { g as SandboxOps } from './types-DxCpFNv_.cjs';
1
+ import { ao as ToolMap, _ as SessionConfig, az as ZeitlichSession, Y as SandboxShutdown, ag as ThreadInit, X as SandboxInit, t as JsonSerializable, B as BaseAgentState, o as AgentStateManager, aB as ToolRouterOptions, ar as ToolRouter, R as RouterContext, J as JsonValue, at as ToolWithHandler, v as ParsedToolCallUnion, ap as ToolNames, a6 as SubagentDefinition, a9 as SubagentHooks, aa as SubagentSandboxConfig, a5 as SubagentConfig, ab as SubagentSandboxShutdown, ac as SubagentSessionInput, a7 as SubagentFnResult, a3 as SessionStartHook, $ as SessionEndHook, D as PostToolUseHook, y as PostToolUseFailureHook, a1 as SessionExitReason, ah as TokenUsage, e as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, av as VirtualFileTree, j as TreeMutation, r as FileEntry, aw as VirtualFsOps, g as SkillMetadata, h as Skill, b as ToolHandlerResponse, am as ToolHandler, ay as WorkflowTask, c as ActivityToolHandler } from './types-BO7Yju20.cjs';
2
+ import { g as SandboxOps } from './types-tQL9njTu.cjs';
3
3
  import z$1, { z } from 'zod';
4
4
  import { Sinks, proxyActivities } from '@temporalio/workflow';
5
5