zeitlich 0.2.45 → 0.2.46

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 (89) hide show
  1. package/README.md +78 -10
  2. package/dist/{activities-CrN-ghLo.d.ts → activities-Bm4TLTid.d.ts} +22 -2
  3. package/dist/{activities-Coafq5zr.d.cts → activities-CyeiqK_f.d.cts} +22 -2
  4. package/dist/adapters/thread/anthropic/index.cjs +171 -65
  5. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  6. package/dist/adapters/thread/anthropic/index.d.cts +19 -4
  7. package/dist/adapters/thread/anthropic/index.d.ts +19 -4
  8. package/dist/adapters/thread/anthropic/index.js +171 -65
  9. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  10. package/dist/adapters/thread/anthropic/workflow.cjs +3 -1
  11. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  12. package/dist/adapters/thread/anthropic/workflow.d.cts +4 -4
  13. package/dist/adapters/thread/anthropic/workflow.d.ts +4 -4
  14. package/dist/adapters/thread/anthropic/workflow.js +3 -1
  15. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  16. package/dist/adapters/thread/google-genai/index.cjs +171 -69
  17. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  18. package/dist/adapters/thread/google-genai/index.d.cts +5 -4
  19. package/dist/adapters/thread/google-genai/index.d.ts +5 -4
  20. package/dist/adapters/thread/google-genai/index.js +171 -69
  21. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  22. package/dist/adapters/thread/google-genai/workflow.cjs +3 -1
  23. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  24. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -4
  25. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -4
  26. package/dist/adapters/thread/google-genai/workflow.js +3 -1
  27. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  28. package/dist/adapters/thread/langchain/index.cjs +170 -66
  29. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  30. package/dist/adapters/thread/langchain/index.d.cts +18 -4
  31. package/dist/adapters/thread/langchain/index.d.ts +18 -4
  32. package/dist/adapters/thread/langchain/index.js +170 -66
  33. package/dist/adapters/thread/langchain/index.js.map +1 -1
  34. package/dist/adapters/thread/langchain/workflow.cjs +3 -1
  35. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  36. package/dist/adapters/thread/langchain/workflow.d.cts +4 -4
  37. package/dist/adapters/thread/langchain/workflow.d.ts +4 -4
  38. package/dist/adapters/thread/langchain/workflow.js +3 -1
  39. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  40. package/dist/cold-store-BC5L5Z8A.d.cts +117 -0
  41. package/dist/cold-store-CFHwemBJ.d.ts +117 -0
  42. package/dist/index.cjs +226 -27
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +138 -8
  45. package/dist/index.d.ts +138 -8
  46. package/dist/index.js +220 -28
  47. package/dist/index.js.map +1 -1
  48. package/dist/{proxy-Bf7uI-Hw.d.cts → proxy-BxFyd6cg.d.cts} +1 -1
  49. package/dist/{proxy-COqA95FW.d.ts → proxy-Cskmj4Yx.d.ts} +1 -1
  50. package/dist/{thread-manager-BsLO3Fgc.d.cts → thread-manager-9tezUcLW.d.cts} +8 -2
  51. package/dist/{thread-manager-Bi1XlbpJ.d.ts → thread-manager-B-zy3xrs.d.ts} +8 -2
  52. package/dist/{thread-manager-wRVVBFgj.d.cts → thread-manager-D33SUmZa.d.cts} +8 -2
  53. package/dist/{thread-manager-BhkOyQ1I.d.ts → thread-manager-DduoSkvJ.d.ts} +8 -2
  54. package/dist/{types-CdALEF3z.d.cts → types-CnuN9T6t.d.cts} +22 -0
  55. package/dist/{types-ChAy_jSP.d.ts → types-CwN6_tAL.d.ts} +22 -0
  56. package/dist/{types-BkX4HLzi.d.ts → types-L5bvbF-n.d.ts} +17 -1
  57. package/dist/{types-C66-BVBr.d.cts → types-oxt8GN97.d.cts} +17 -1
  58. package/dist/{workflow-BwT5EybR.d.ts → workflow-B1TOcHbt.d.ts} +33 -2
  59. package/dist/{workflow-DMmiaw6w.d.cts → workflow-DIaIV7L2.d.cts} +33 -2
  60. package/dist/workflow.cjs +14 -1
  61. package/dist/workflow.cjs.map +1 -1
  62. package/dist/workflow.d.cts +2 -2
  63. package/dist/workflow.d.ts +2 -2
  64. package/dist/workflow.js +14 -1
  65. package/dist/workflow.js.map +1 -1
  66. package/package.json +6 -1
  67. package/src/adapters/thread/anthropic/activities.ts +72 -36
  68. package/src/adapters/thread/anthropic/thread-manager.ts +9 -1
  69. package/src/adapters/thread/google-genai/activities.ts +64 -40
  70. package/src/adapters/thread/google-genai/thread-manager.ts +9 -1
  71. package/src/adapters/thread/langchain/activities.ts +63 -36
  72. package/src/adapters/thread/langchain/thread-manager.ts +9 -1
  73. package/src/index.ts +20 -1
  74. package/src/lib/session/session-edge-cases.integration.test.ts +12 -0
  75. package/src/lib/session/session.integration.test.ts +138 -0
  76. package/src/lib/session/session.ts +29 -0
  77. package/src/lib/session/types.ts +22 -0
  78. package/src/lib/thread/cold-store.test.ts +193 -0
  79. package/src/lib/thread/cold-store.ts +250 -0
  80. package/src/lib/thread/index.ts +32 -0
  81. package/src/lib/thread/keys.ts +20 -0
  82. package/src/lib/thread/manager.ts +16 -27
  83. package/src/lib/thread/proxy.ts +2 -0
  84. package/src/lib/thread/snapshot.test.ts +443 -0
  85. package/src/lib/thread/snapshot.ts +163 -0
  86. package/src/lib/thread/test-utils.ts +228 -0
  87. package/src/lib/thread/tiered.test.ts +281 -0
  88. package/src/lib/thread/tiered.ts +135 -0
  89. package/src/lib/thread/types.ts +16 -0
@@ -1,5 +1,5 @@
1
1
  import { proxyActivities, ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from './types-CdALEF3z.cjs';
2
+ import { T as ThreadOps } from './types-CnuN9T6t.cjs';
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-ChAy_jSP.js';
2
+ import { T as ThreadOps } from './types-CwN6_tAL.js';
3
3
 
4
4
  /**
5
5
  * Shared proxy helper for thread operations.
@@ -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-CdALEF3z.cjs';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-C66-BVBr.cjs';
3
+ import { J as JsonValue } from './types-CnuN9T6t.cjs';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-oxt8GN97.cjs';
5
5
 
6
6
  /** SDK-native content type for Anthropic human messages */
7
7
  type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
@@ -21,6 +21,12 @@ interface AnthropicThreadManagerConfig {
21
21
  /** Thread key, defaults to 'messages' */
22
22
  key?: string;
23
23
  hooks?: AnthropicThreadManagerHooks;
24
+ /**
25
+ * Override the default thread TTL (90 days). When pairing the
26
+ * adapter with a durable cold tier, a shorter TTL (hours) is
27
+ * typically more appropriate.
28
+ */
29
+ ttlSeconds?: number;
24
30
  }
25
31
  /** Prepared payload ready to send to the Anthropic API */
26
32
  interface AnthropicInvocationPayload {
@@ -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-ChAy_jSP.js';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BkX4HLzi.js';
3
+ import { J as JsonValue } from './types-CwN6_tAL.js';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-L5bvbF-n.js';
5
5
 
6
6
  /** SDK-native content type for Anthropic human messages */
7
7
  type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
@@ -21,6 +21,12 @@ interface AnthropicThreadManagerConfig {
21
21
  /** Thread key, defaults to 'messages' */
22
22
  key?: string;
23
23
  hooks?: AnthropicThreadManagerHooks;
24
+ /**
25
+ * Override the default thread TTL (90 days). When pairing the
26
+ * adapter with a durable cold tier, a shorter TTL (hours) is
27
+ * typically more appropriate.
28
+ */
29
+ ttlSeconds?: number;
24
30
  }
25
31
  /** Prepared payload ready to send to the Anthropic API */
26
32
  interface AnthropicInvocationPayload {
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-CdALEF3z.cjs';
2
+ import { J as JsonValue } from './types-CnuN9T6t.cjs';
3
3
  import { MessageContent, StoredMessage, BaseMessage } from '@langchain/core/messages';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-C66-BVBr.cjs';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-oxt8GN97.cjs';
5
5
 
6
6
  /** SDK-native content type for LangChain human messages */
7
7
  type LangChainContent = string | MessageContent;
@@ -14,6 +14,12 @@ interface LangChainThreadManagerConfig {
14
14
  /** Thread key, defaults to 'messages' */
15
15
  key?: string;
16
16
  hooks?: LangChainThreadManagerHooks;
17
+ /**
18
+ * Override the default thread TTL (90 days). When pairing the
19
+ * adapter with a durable cold tier, a shorter TTL (hours) is
20
+ * typically more appropriate.
21
+ */
22
+ ttlSeconds?: number;
17
23
  }
18
24
  /** Prepared payload ready to send to a LangChain chat model */
19
25
  interface LangChainInvocationPayload {
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-ChAy_jSP.js';
2
+ import { J as JsonValue } from './types-CwN6_tAL.js';
3
3
  import { MessageContent, StoredMessage, BaseMessage } from '@langchain/core/messages';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BkX4HLzi.js';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-L5bvbF-n.js';
5
5
 
6
6
  /** SDK-native content type for LangChain human messages */
7
7
  type LangChainContent = string | MessageContent;
@@ -14,6 +14,12 @@ interface LangChainThreadManagerConfig {
14
14
  /** Thread key, defaults to 'messages' */
15
15
  key?: string;
16
16
  hooks?: LangChainThreadManagerHooks;
17
+ /**
18
+ * Override the default thread TTL (90 days). When pairing the
19
+ * adapter with a durable cold tier, a shorter TTL (hours) is
20
+ * typically more appropriate.
21
+ */
22
+ ttlSeconds?: number;
17
23
  }
18
24
  /** Prepared payload ready to send to a LangChain chat model */
19
25
  interface LangChainInvocationPayload {
@@ -1529,6 +1529,28 @@ interface ThreadOps<TContent = string> {
1529
1529
  * store, continue later" works regardless of exit reason.
1530
1530
  */
1531
1531
  saveThreadState(threadId: string, state: PersistedThreadState, threadKey?: string): Promise<void>;
1532
+ /**
1533
+ * Restore the thread's contents from the durable cold tier (if any)
1534
+ * into Redis. Called once on session entry for `mode: "continue"`
1535
+ * and `mode: "fork"` so the rest of the loop reads the freshest data.
1536
+ *
1537
+ * Adapters configured without a cold-store implementation treat this
1538
+ * as a no-op. Implementations must be **idempotent** — Temporal
1539
+ * retries the activity on transient failures, and a thread that is
1540
+ * already hot must not be wiped.
1541
+ */
1542
+ hydrateThread(threadId: string, threadKey?: string): Promise<void>;
1543
+ /**
1544
+ * Archive the thread's contents to the durable cold tier and
1545
+ * (optionally) drop the hot-tier Redis keys. Called once in the
1546
+ * session's `finally` block on every exit path, after
1547
+ * `saveThreadState`.
1548
+ *
1549
+ * Adapters configured without a cold-store implementation treat this
1550
+ * as a no-op. Implementations must be **idempotent** — the cold
1551
+ * tier is last-writer-wins and a retried flush must converge.
1552
+ */
1553
+ flushThread(threadId: string, threadKey?: string): Promise<void>;
1532
1554
  }
1533
1555
  /**
1534
1556
  * Composes an adapter prefix + workflow scope for activity naming.
@@ -1529,6 +1529,28 @@ interface ThreadOps<TContent = string> {
1529
1529
  * store, continue later" works regardless of exit reason.
1530
1530
  */
1531
1531
  saveThreadState(threadId: string, state: PersistedThreadState, threadKey?: string): Promise<void>;
1532
+ /**
1533
+ * Restore the thread's contents from the durable cold tier (if any)
1534
+ * into Redis. Called once on session entry for `mode: "continue"`
1535
+ * and `mode: "fork"` so the rest of the loop reads the freshest data.
1536
+ *
1537
+ * Adapters configured without a cold-store implementation treat this
1538
+ * as a no-op. Implementations must be **idempotent** — Temporal
1539
+ * retries the activity on transient failures, and a thread that is
1540
+ * already hot must not be wiped.
1541
+ */
1542
+ hydrateThread(threadId: string, threadKey?: string): Promise<void>;
1543
+ /**
1544
+ * Archive the thread's contents to the durable cold tier and
1545
+ * (optionally) drop the hot-tier Redis keys. Called once in the
1546
+ * session's `finally` block on every exit path, after
1547
+ * `saveThreadState`.
1548
+ *
1549
+ * Adapters configured without a cold-store implementation treat this
1550
+ * as a no-op. Implementations must be **idempotent** — the cold
1551
+ * tier is last-writer-wins and a retried flush must converge.
1552
+ */
1553
+ flushThread(threadId: string, threadKey?: string): Promise<void>;
1532
1554
  }
1533
1555
  /**
1534
1556
  * Composes an adapter prefix + workflow scope for activity naming.
@@ -1,5 +1,5 @@
1
1
  import Redis from 'ioredis';
2
- import { P as PersistedThreadState, J as JsonValue } from './types-ChAy_jSP.js';
2
+ import { P as PersistedThreadState, J as JsonValue } from './types-CwN6_tAL.js';
3
3
 
4
4
  interface ThreadManagerConfig<T> {
5
5
  redis: Redis;
@@ -15,6 +15,17 @@ interface ThreadManagerConfig<T> {
15
15
  * When provided, `append` uses an atomic Lua script to skip duplicate writes.
16
16
  */
17
17
  idOf?: (message: T) => string;
18
+ /**
19
+ * TTL (in seconds) applied to every Redis key the manager writes
20
+ * (the list, the meta marker, the state slice, and dedup markers).
21
+ *
22
+ * Defaults to {@link THREAD_TTL_SECONDS} (90 days) for back-compat.
23
+ * When the consumer pairs the thread manager with a durable cold
24
+ * tier (see `createTieredThreadManager`), a much shorter TTL — e.g.
25
+ * a few hours — is usually more appropriate since the cold tier is
26
+ * the source of truth and Redis is just a hot cache.
27
+ */
28
+ ttlSeconds?: number;
18
29
  }
19
30
  /** Generic thread manager for any message type */
20
31
  interface BaseThreadManager<T> {
@@ -26,6 +37,11 @@ interface BaseThreadManager<T> {
26
37
  * Append messages to the thread.
27
38
  * When `idOf` is configured, appends are idempotent — retries with the
28
39
  * same message ids are atomically skipped via a Redis Lua script.
40
+ *
41
+ * Caveat with tiered storage: multi-message batches write one composite
42
+ * dedup key (`"m1:m2"`); snapshots only persist per-message keys, so a
43
+ * batch retried after `flush` → `hydrate` will not be deduped. Adapter
44
+ * helpers all single-append and are unaffected.
29
45
  */
30
46
  append(messages: T[]): Promise<void>;
31
47
  /**
@@ -1,5 +1,5 @@
1
1
  import Redis from 'ioredis';
2
- import { P as PersistedThreadState, J as JsonValue } from './types-CdALEF3z.cjs';
2
+ import { P as PersistedThreadState, J as JsonValue } from './types-CnuN9T6t.cjs';
3
3
 
4
4
  interface ThreadManagerConfig<T> {
5
5
  redis: Redis;
@@ -15,6 +15,17 @@ interface ThreadManagerConfig<T> {
15
15
  * When provided, `append` uses an atomic Lua script to skip duplicate writes.
16
16
  */
17
17
  idOf?: (message: T) => string;
18
+ /**
19
+ * TTL (in seconds) applied to every Redis key the manager writes
20
+ * (the list, the meta marker, the state slice, and dedup markers).
21
+ *
22
+ * Defaults to {@link THREAD_TTL_SECONDS} (90 days) for back-compat.
23
+ * When the consumer pairs the thread manager with a durable cold
24
+ * tier (see `createTieredThreadManager`), a much shorter TTL — e.g.
25
+ * a few hours — is usually more appropriate since the cold tier is
26
+ * the source of truth and Redis is just a hot cache.
27
+ */
28
+ ttlSeconds?: number;
18
29
  }
19
30
  /** Generic thread manager for any message type */
20
31
  interface BaseThreadManager<T> {
@@ -26,6 +37,11 @@ interface BaseThreadManager<T> {
26
37
  * Append messages to the thread.
27
38
  * When `idOf` is configured, appends are idempotent — retries with the
28
39
  * same message ids are atomically skipped via a Redis Lua script.
40
+ *
41
+ * Caveat with tiered storage: multi-message batches write one composite
42
+ * dedup key (`"m1:m2"`); snapshots only persist per-message keys, so a
43
+ * batch retried after `flush` → `hydrate` will not be deduped. Adapter
44
+ * helpers all single-append and are unaffected.
29
45
  */
30
46
  append(messages: T[]): Promise<void>;
31
47
  /**
@@ -1,4 +1,4 @@
1
- import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, an as TokenUsage, f as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, c as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, d as ActivityToolHandler } from './types-ChAy_jSP.js';
1
+ import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, an as TokenUsage, f as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, c as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, d as ActivityToolHandler } from './types-CwN6_tAL.js';
2
2
  import z$1, { z } from 'zod';
3
3
  import './types-CJ7tCdl6.js';
4
4
  import { Duration } from '@temporalio/common';
@@ -159,6 +159,37 @@ declare function getThreadListKey(threadKey: string, threadId: string): string;
159
159
  * @param threadId - Thread id as provided to the thread manager.
160
160
  */
161
161
  declare function getThreadMetaKey(threadKey: string, threadId: string): string;
162
+ /**
163
+ * Build the Redis key that stores a thread's persisted state slice
164
+ * (tasks + custom state) written by zeitlich's session loop on every
165
+ * exit path.
166
+ *
167
+ * Consumers can read this key with `redis.get(getThreadStateKey(key, id))`
168
+ * and `JSON.parse` the result into a {@link PersistedThreadState}.
169
+ *
170
+ * @param threadKey - Thread key (defaults to `"messages"` inside the
171
+ * thread manager, but downstream adapters may pass
172
+ * their own value).
173
+ * @param threadId - Thread id as provided to the thread manager.
174
+ */
175
+ declare function getThreadStateKey(threadKey: string, threadId: string): string;
176
+ /**
177
+ * Build the Redis key that guards an idempotent append against a
178
+ * duplicate write of the message (or message batch) identified by
179
+ * `dedupId`. Zeitlich's thread manager writes one of these per
180
+ * single-message append (and one per batch for multi-message appends),
181
+ * keyed by the message id returned by the configured `idOf`.
182
+ *
183
+ * Note: the key layout intentionally does **not** include the
184
+ * `threadKey` prefix — the dedup namespace is shared across thread
185
+ * keys for a given `threadId`, mirroring the original internal
186
+ * implementation.
187
+ *
188
+ * @param threadId - Thread id as provided to the thread manager.
189
+ * @param dedupId - Joined message ids (single message id for the
190
+ * common single-append case).
191
+ */
192
+ declare function getThreadDedupKey(threadId: string, dedupId: string): string;
162
193
 
163
194
  /**
164
195
  * Creates an agent state manager for tracking workflow state.
@@ -856,4 +887,4 @@ declare const createAskUserQuestionHandler: () => ActivityToolHandler<AskUserQue
856
887
  }[];
857
888
  }>;
858
889
 
859
- export { hasDirectory as $, type AskUserQuestionArgs as A, type BashArgs as B, createTaskGetHandler as C, DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT as D, createTaskListHandler as E, type FileEditArgs as F, type GlobArgs as G, createTaskUpdateHandler as H, createToolRouter as I, defineSubagent as J, defineSubagentWorkflow as K, defineTool as L, defineWorkflow as M, editTool as N, type ObservabilityHooks as O, filesWithMimeType as P, formatVirtualFileTree as Q, type ReadSkillArgs as R, type SessionEndedEvent as S, THREAD_TTL_SECONDS as T, getShortId as U, getThreadListKey as V, type WorkflowConfig as W, getThreadMetaKey as X, globTool as Y, type ZeitlichObservabilitySinks as Z, grepTool as _, type FileReadArgs as a, hasFileWithMimeType as a0, hasNoOtherToolCalls as a1, parseSkillFile as a2, proxyRunAgent as a3, proxyVirtualFsOps as a4, readFileTool as a5, taskCreateTool as a6, taskGetTool as a7, taskListTool as a8, taskUpdateTool as a9, writeFileTool as aa, type FileWriteArgs as b, type FileTreeAccessor as c, type GrepArgs as d, type SessionStartedEvent as e, type SubagentArgs as f, type TaskCreateArgs as g, type TaskGetArgs as h, type TaskListArgs as i, type TaskUpdateArgs as j, type ToolExecutedEvent as k, type TurnCompletedEvent as l, type WorkflowInput as m, type WorkflowSessionInput as n, applyVirtualTreeMutations as o, askUserQuestionTool as p, bashTool as q, composeHooks as r, createAgentStateManager as s, createAskUserQuestionHandler as t, createBashToolDescription as u, createObservabilityHooks as v, createReadSkillHandler as w, createReadSkillTool as x, createSession as y, createTaskCreateHandler as z };
890
+ export { globTool as $, type AskUserQuestionArgs as A, type BashArgs as B, createTaskGetHandler as C, DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT as D, createTaskListHandler as E, type FileEditArgs as F, type GlobArgs as G, createTaskUpdateHandler as H, createToolRouter as I, defineSubagent as J, defineSubagentWorkflow as K, defineTool as L, defineWorkflow as M, editTool as N, type ObservabilityHooks as O, filesWithMimeType as P, formatVirtualFileTree as Q, type ReadSkillArgs as R, type SessionEndedEvent as S, THREAD_TTL_SECONDS as T, getShortId as U, getThreadDedupKey as V, type WorkflowConfig as W, getThreadListKey as X, getThreadMetaKey as Y, type ZeitlichObservabilitySinks as Z, getThreadStateKey as _, type FileReadArgs as a, grepTool as a0, hasDirectory as a1, hasFileWithMimeType as a2, hasNoOtherToolCalls as a3, parseSkillFile as a4, proxyRunAgent as a5, proxyVirtualFsOps as a6, readFileTool as a7, taskCreateTool as a8, taskGetTool as a9, taskListTool as aa, taskUpdateTool as ab, writeFileTool as ac, type FileWriteArgs as b, type FileTreeAccessor as c, type GrepArgs as d, type SessionStartedEvent as e, type SubagentArgs as f, type TaskCreateArgs as g, type TaskGetArgs as h, type TaskListArgs as i, type TaskUpdateArgs as j, type ToolExecutedEvent as k, type TurnCompletedEvent as l, type WorkflowInput as m, type WorkflowSessionInput as n, applyVirtualTreeMutations as o, askUserQuestionTool as p, bashTool as q, composeHooks as r, createAgentStateManager as s, createAskUserQuestionHandler as t, createBashToolDescription as u, createObservabilityHooks as v, createReadSkillHandler as w, createReadSkillTool as x, createSession as y, createTaskCreateHandler as z };
@@ -1,4 +1,4 @@
1
- import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, an as TokenUsage, f as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, c as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, d as ActivityToolHandler } from './types-CdALEF3z.cjs';
1
+ import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, an as TokenUsage, f as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, c as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, d as ActivityToolHandler } from './types-CnuN9T6t.cjs';
2
2
  import z$1, { z } from 'zod';
3
3
  import './types-CJ7tCdl6.cjs';
4
4
  import { Duration } from '@temporalio/common';
@@ -159,6 +159,37 @@ declare function getThreadListKey(threadKey: string, threadId: string): string;
159
159
  * @param threadId - Thread id as provided to the thread manager.
160
160
  */
161
161
  declare function getThreadMetaKey(threadKey: string, threadId: string): string;
162
+ /**
163
+ * Build the Redis key that stores a thread's persisted state slice
164
+ * (tasks + custom state) written by zeitlich's session loop on every
165
+ * exit path.
166
+ *
167
+ * Consumers can read this key with `redis.get(getThreadStateKey(key, id))`
168
+ * and `JSON.parse` the result into a {@link PersistedThreadState}.
169
+ *
170
+ * @param threadKey - Thread key (defaults to `"messages"` inside the
171
+ * thread manager, but downstream adapters may pass
172
+ * their own value).
173
+ * @param threadId - Thread id as provided to the thread manager.
174
+ */
175
+ declare function getThreadStateKey(threadKey: string, threadId: string): string;
176
+ /**
177
+ * Build the Redis key that guards an idempotent append against a
178
+ * duplicate write of the message (or message batch) identified by
179
+ * `dedupId`. Zeitlich's thread manager writes one of these per
180
+ * single-message append (and one per batch for multi-message appends),
181
+ * keyed by the message id returned by the configured `idOf`.
182
+ *
183
+ * Note: the key layout intentionally does **not** include the
184
+ * `threadKey` prefix — the dedup namespace is shared across thread
185
+ * keys for a given `threadId`, mirroring the original internal
186
+ * implementation.
187
+ *
188
+ * @param threadId - Thread id as provided to the thread manager.
189
+ * @param dedupId - Joined message ids (single message id for the
190
+ * common single-append case).
191
+ */
192
+ declare function getThreadDedupKey(threadId: string, dedupId: string): string;
162
193
 
163
194
  /**
164
195
  * Creates an agent state manager for tracking workflow state.
@@ -856,4 +887,4 @@ declare const createAskUserQuestionHandler: () => ActivityToolHandler<AskUserQue
856
887
  }[];
857
888
  }>;
858
889
 
859
- export { hasDirectory as $, type AskUserQuestionArgs as A, type BashArgs as B, createTaskGetHandler as C, DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT as D, createTaskListHandler as E, type FileEditArgs as F, type GlobArgs as G, createTaskUpdateHandler as H, createToolRouter as I, defineSubagent as J, defineSubagentWorkflow as K, defineTool as L, defineWorkflow as M, editTool as N, type ObservabilityHooks as O, filesWithMimeType as P, formatVirtualFileTree as Q, type ReadSkillArgs as R, type SessionEndedEvent as S, THREAD_TTL_SECONDS as T, getShortId as U, getThreadListKey as V, type WorkflowConfig as W, getThreadMetaKey as X, globTool as Y, type ZeitlichObservabilitySinks as Z, grepTool as _, type FileReadArgs as a, hasFileWithMimeType as a0, hasNoOtherToolCalls as a1, parseSkillFile as a2, proxyRunAgent as a3, proxyVirtualFsOps as a4, readFileTool as a5, taskCreateTool as a6, taskGetTool as a7, taskListTool as a8, taskUpdateTool as a9, writeFileTool as aa, type FileWriteArgs as b, type FileTreeAccessor as c, type GrepArgs as d, type SessionStartedEvent as e, type SubagentArgs as f, type TaskCreateArgs as g, type TaskGetArgs as h, type TaskListArgs as i, type TaskUpdateArgs as j, type ToolExecutedEvent as k, type TurnCompletedEvent as l, type WorkflowInput as m, type WorkflowSessionInput as n, applyVirtualTreeMutations as o, askUserQuestionTool as p, bashTool as q, composeHooks as r, createAgentStateManager as s, createAskUserQuestionHandler as t, createBashToolDescription as u, createObservabilityHooks as v, createReadSkillHandler as w, createReadSkillTool as x, createSession as y, createTaskCreateHandler as z };
890
+ export { globTool as $, type AskUserQuestionArgs as A, type BashArgs as B, createTaskGetHandler as C, DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT as D, createTaskListHandler as E, type FileEditArgs as F, type GlobArgs as G, createTaskUpdateHandler as H, createToolRouter as I, defineSubagent as J, defineSubagentWorkflow as K, defineTool as L, defineWorkflow as M, editTool as N, type ObservabilityHooks as O, filesWithMimeType as P, formatVirtualFileTree as Q, type ReadSkillArgs as R, type SessionEndedEvent as S, THREAD_TTL_SECONDS as T, getShortId as U, getThreadDedupKey as V, type WorkflowConfig as W, getThreadListKey as X, getThreadMetaKey as Y, type ZeitlichObservabilitySinks as Z, getThreadStateKey as _, type FileReadArgs as a, grepTool as a0, hasDirectory as a1, hasFileWithMimeType as a2, hasNoOtherToolCalls as a3, parseSkillFile as a4, proxyRunAgent as a5, proxyVirtualFsOps as a6, readFileTool as a7, taskCreateTool as a8, taskGetTool as a9, taskListTool as aa, taskUpdateTool as ab, writeFileTool as ac, type FileWriteArgs as b, type FileTreeAccessor as c, type GrepArgs as d, type SessionStartedEvent as e, type SubagentArgs as f, type TaskCreateArgs as g, type TaskGetArgs as h, type TaskListArgs as i, type TaskUpdateArgs as j, type ToolExecutedEvent as k, type TurnCompletedEvent as l, type WorkflowInput as m, type WorkflowSessionInput as n, applyVirtualTreeMutations as o, askUserQuestionTool as p, bashTool as q, composeHooks as r, createAgentStateManager as s, createAskUserQuestionHandler as t, createBashToolDescription as u, createObservabilityHooks as v, createReadSkillHandler as w, createReadSkillTool as x, createSession as y, createTaskCreateHandler as z };
package/dist/workflow.cjs CHANGED
@@ -1034,7 +1034,9 @@ async function createSession(config) {
1034
1034
  appendAgentMessage,
1035
1035
  forkThread,
1036
1036
  loadThreadState,
1037
- saveThreadState
1037
+ saveThreadState,
1038
+ hydrateThread,
1039
+ flushThread
1038
1040
  } = threadOps;
1039
1041
  const plugins = [];
1040
1042
  let destroySubagentSandboxes;
@@ -1178,10 +1180,12 @@ async function createSession(config) {
1178
1180
  });
1179
1181
  };
1180
1182
  if (threadMode === "fork" && sourceThreadId) {
1183
+ await hydrateThread(sourceThreadId, threadKey);
1181
1184
  await forkThread(sourceThreadId, threadId, threadKey);
1182
1185
  const forkedSlice = await loadThreadState(threadId, threadKey);
1183
1186
  if (forkedSlice) rehydrateFromSlice(forkedSlice);
1184
1187
  } else if (threadMode === "continue") {
1188
+ await hydrateThread(threadId, threadKey);
1185
1189
  const continuedSlice = await loadThreadState(threadId, threadKey);
1186
1190
  if (continuedSlice) rehydrateFromSlice(continuedSlice);
1187
1191
  } else {
@@ -1363,6 +1367,15 @@ async function createSession(config) {
1363
1367
  error: persistError instanceof Error ? persistError.message : String(persistError)
1364
1368
  });
1365
1369
  }
1370
+ try {
1371
+ await flushThread(threadId, threadKey);
1372
+ } catch (flushError) {
1373
+ workflow.log.warn("failed to flush thread to cold tier", {
1374
+ agentName,
1375
+ threadId,
1376
+ error: flushError instanceof Error ? flushError.message : String(flushError)
1377
+ });
1378
+ }
1366
1379
  await callSessionEnd(exitReason, stateManager.getTurns());
1367
1380
  if (sandboxOwned && sandboxId && sandboxOps) {
1368
1381
  switch (resolvedShutdown) {