zeitlich 0.2.45 → 0.2.47

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 (109) hide show
  1. package/README.md +137 -11
  2. package/dist/{activities-Coafq5zr.d.cts → activities-CPwKoUlD.d.cts} +22 -2
  3. package/dist/{activities-CrN-ghLo.d.ts → activities-DlaBxNID.d.ts} +22 -2
  4. package/dist/adapters/thread/anthropic/index.cjs +276 -71
  5. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  6. package/dist/adapters/thread/anthropic/index.d.cts +62 -8
  7. package/dist/adapters/thread/anthropic/index.d.ts +62 -8
  8. package/dist/adapters/thread/anthropic/index.js +275 -72
  9. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  10. package/dist/adapters/thread/anthropic/workflow.cjs +38 -20
  11. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  12. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -4
  13. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -4
  14. package/dist/adapters/thread/anthropic/workflow.js +38 -20
  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 +6 -4
  19. package/dist/adapters/thread/google-genai/index.d.ts +6 -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 +38 -20
  23. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  24. package/dist/adapters/thread/google-genai/workflow.d.cts +7 -4
  25. package/dist/adapters/thread/google-genai/workflow.d.ts +7 -4
  26. package/dist/adapters/thread/google-genai/workflow.js +38 -20
  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 +19 -4
  31. package/dist/adapters/thread/langchain/index.d.ts +19 -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 +38 -20
  35. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  36. package/dist/adapters/thread/langchain/workflow.d.cts +5 -4
  37. package/dist/adapters/thread/langchain/workflow.d.ts +5 -4
  38. package/dist/adapters/thread/langchain/workflow.js +38 -20
  39. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  40. package/dist/cold-store-BDgJpwLI.d.ts +114 -0
  41. package/dist/cold-store-Z2wvK2cV.d.cts +114 -0
  42. package/dist/index.cjs +440 -67
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +150 -8
  45. package/dist/index.d.ts +150 -8
  46. package/dist/index.js +432 -68
  47. package/dist/index.js.map +1 -1
  48. package/dist/proxy-CDh3Rsa7.d.cts +40 -0
  49. package/dist/proxy-Du8ggERu.d.ts +40 -0
  50. package/dist/{thread-manager-wRVVBFgj.d.cts → thread-manager-BjoYYXgd.d.cts} +8 -2
  51. package/dist/{thread-manager-BsLO3Fgc.d.cts → thread-manager-D8zKNFZ9.d.cts} +8 -2
  52. package/dist/{thread-manager-Bi1XlbpJ.d.ts → thread-manager-DtHYws2F.d.ts} +8 -2
  53. package/dist/{thread-manager-BhkOyQ1I.d.ts → thread-manager-Dw96FKH1.d.ts} +8 -2
  54. package/dist/{types-C66-BVBr.d.cts → types-BMJrsHo0.d.cts} +17 -1
  55. package/dist/{types-BkX4HLzi.d.ts → types-CtdOquo3.d.ts} +17 -1
  56. package/dist/{types-CdALEF3z.d.cts → types-DNEl5uxQ.d.cts} +38 -0
  57. package/dist/{types-ChAy_jSP.d.ts → types-qQVZfhoT.d.ts} +38 -0
  58. package/dist/{workflow-DMmiaw6w.d.cts → workflow-BH9ImDGq.d.cts} +48 -2
  59. package/dist/{workflow-BwT5EybR.d.ts → workflow-Cdw3-RNB.d.ts} +48 -2
  60. package/dist/workflow.cjs +47 -4
  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 +47 -5
  65. package/dist/workflow.js.map +1 -1
  66. package/package.json +14 -3
  67. package/src/adapters/thread/anthropic/activities.ts +82 -39
  68. package/src/adapters/thread/anthropic/index.ts +8 -0
  69. package/src/adapters/thread/anthropic/model-invoker.test.ts +110 -0
  70. package/src/adapters/thread/anthropic/model-invoker.ts +26 -5
  71. package/src/adapters/thread/anthropic/prompt-cache.test.ts +134 -0
  72. package/src/adapters/thread/anthropic/prompt-cache.ts +163 -0
  73. package/src/adapters/thread/anthropic/proxy.ts +1 -0
  74. package/src/adapters/thread/anthropic/thread-manager.ts +9 -1
  75. package/src/adapters/thread/google-genai/activities.ts +64 -40
  76. package/src/adapters/thread/google-genai/proxy.ts +1 -0
  77. package/src/adapters/thread/google-genai/thread-manager.ts +9 -1
  78. package/src/adapters/thread/langchain/activities.ts +63 -36
  79. package/src/adapters/thread/langchain/proxy.ts +1 -0
  80. package/src/adapters/thread/langchain/thread-manager.ts +9 -1
  81. package/src/index.ts +21 -2
  82. package/src/lib/session/session-edge-cases.integration.test.ts +12 -0
  83. package/src/lib/session/session.integration.test.ts +138 -0
  84. package/src/lib/session/session.ts +29 -0
  85. package/src/lib/session/types.ts +22 -0
  86. package/src/lib/subagent/define.ts +1 -0
  87. package/src/lib/subagent/handler.ts +11 -2
  88. package/src/lib/subagent/subagent.integration.test.ts +139 -0
  89. package/src/lib/subagent/types.ts +16 -0
  90. package/src/lib/thread/cold-store.test.ts +221 -0
  91. package/src/lib/thread/cold-store.ts +269 -0
  92. package/src/lib/thread/index.ts +32 -0
  93. package/src/lib/thread/keys.ts +20 -0
  94. package/src/lib/thread/manager.ts +16 -27
  95. package/src/lib/thread/proxy.ts +79 -27
  96. package/src/lib/thread/snapshot.test.ts +443 -0
  97. package/src/lib/thread/snapshot.ts +163 -0
  98. package/src/lib/thread/test-utils.ts +228 -0
  99. package/src/lib/thread/tiered.test.ts +281 -0
  100. package/src/lib/thread/tiered.ts +135 -0
  101. package/src/lib/thread/types.ts +16 -0
  102. package/src/tools/edit/handler.test.ts +177 -0
  103. package/src/tools/edit/handler.ts +249 -47
  104. package/src/tools/edit/tool.ts +40 -0
  105. package/src/tools/task-create/handler.ts +1 -1
  106. package/src/tools/task-update/handler.ts +1 -1
  107. package/src/workflow.ts +2 -2
  108. package/dist/proxy-Bf7uI-Hw.d.cts +0 -24
  109. package/dist/proxy-COqA95FW.d.ts +0 -24
@@ -0,0 +1,40 @@
1
+ import { ActivityOptions, ActivityInterfaceFor } from '@temporalio/workflow';
2
+ import { T as ThreadOps } from './types-DNEl5uxQ.cjs';
3
+
4
+ /**
5
+ * Shared proxy helper for thread operations.
6
+ *
7
+ * Each adapter re-exports a thin wrapper that supplies its prefix and
8
+ * casts the return type to carry the adapter's native content type.
9
+ */
10
+
11
+ type OpName = keyof ThreadOps;
12
+ /**
13
+ * `perOp[op]` layers shallow-rightmost over `defaults` and the
14
+ * built-in cold-tier overlay (`hydrateThread` / `flushThread`).
15
+ * A bare {@link ActivityOptions} is also accepted (treated as `{ defaults }`).
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * proxyAnthropicThreadOps(undefined, {
20
+ * defaults: { startToCloseTimeout: "5s" },
21
+ * perOp: {
22
+ * flushThread: { startToCloseTimeout: "180s" }, // heartbeatTimeout still inherited
23
+ * },
24
+ * });
25
+ * ```
26
+ */
27
+ interface ThreadOpsProxyOptions {
28
+ defaults?: ActivityOptions;
29
+ perOp?: Partial<Record<OpName, ActivityOptions>>;
30
+ }
31
+ /**
32
+ * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.
33
+ *
34
+ * @param adapterPrefix - Adapter identifier (e.g. "anthropic", "googleGenAI", "langChain")
35
+ * @param scope - Workflow scope. Defaults to `workflowInfo().workflowType`.
36
+ * @param options - {@link ThreadOpsProxyOptions} or a bare {@link ActivityOptions}.
37
+ */
38
+ declare function createThreadOpsProxy(adapterPrefix: string, scope?: string, options?: ActivityOptions | ThreadOpsProxyOptions): ActivityInterfaceFor<ThreadOps>;
39
+
40
+ export { type ThreadOpsProxyOptions as T, createThreadOpsProxy as c };
@@ -0,0 +1,40 @@
1
+ import { ActivityOptions, ActivityInterfaceFor } from '@temporalio/workflow';
2
+ import { T as ThreadOps } from './types-qQVZfhoT.js';
3
+
4
+ /**
5
+ * Shared proxy helper for thread operations.
6
+ *
7
+ * Each adapter re-exports a thin wrapper that supplies its prefix and
8
+ * casts the return type to carry the adapter's native content type.
9
+ */
10
+
11
+ type OpName = keyof ThreadOps;
12
+ /**
13
+ * `perOp[op]` layers shallow-rightmost over `defaults` and the
14
+ * built-in cold-tier overlay (`hydrateThread` / `flushThread`).
15
+ * A bare {@link ActivityOptions} is also accepted (treated as `{ defaults }`).
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * proxyAnthropicThreadOps(undefined, {
20
+ * defaults: { startToCloseTimeout: "5s" },
21
+ * perOp: {
22
+ * flushThread: { startToCloseTimeout: "180s" }, // heartbeatTimeout still inherited
23
+ * },
24
+ * });
25
+ * ```
26
+ */
27
+ interface ThreadOpsProxyOptions {
28
+ defaults?: ActivityOptions;
29
+ perOp?: Partial<Record<OpName, ActivityOptions>>;
30
+ }
31
+ /**
32
+ * Creates a workflow-safe Temporal activity proxy for {@link ThreadOps}.
33
+ *
34
+ * @param adapterPrefix - Adapter identifier (e.g. "anthropic", "googleGenAI", "langChain")
35
+ * @param scope - Workflow scope. Defaults to `workflowInfo().workflowType`.
36
+ * @param options - {@link ThreadOpsProxyOptions} or a bare {@link ActivityOptions}.
37
+ */
38
+ declare function createThreadOpsProxy(adapterPrefix: string, scope?: string, options?: ActivityOptions | ThreadOpsProxyOptions): ActivityInterfaceFor<ThreadOps>;
39
+
40
+ export { type ThreadOpsProxyOptions as T, createThreadOpsProxy as c };
@@ -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-DNEl5uxQ.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-BMJrsHo0.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
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-DNEl5uxQ.cjs';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BMJrsHo0.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-qQVZfhoT.js';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-CtdOquo3.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-ChAy_jSP.js';
2
+ import { J as JsonValue } from './types-qQVZfhoT.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-CtdOquo3.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 {
@@ -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-DNEl5uxQ.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,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-qQVZfhoT.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
  /**
@@ -1283,6 +1283,22 @@ interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
1283
1283
  * directly to the existing thread in-place.
1284
1284
  */
1285
1285
  thread?: "new" | "fork" | "continue";
1286
+ /**
1287
+ * Where the subagent's thread comes from when the parent's tool call
1288
+ * omits `threadId`. Only meaningful in combination with
1289
+ * `thread: "fork"` or `"continue"`.
1290
+ *
1291
+ * - `"new"` (default) — start a fresh thread (the prior behavior).
1292
+ * - `"from-parent"` — use the parent's own `threadId` (from
1293
+ * `RouterContext`). With `thread: "fork"` the parent's conversation
1294
+ * is copied into a new thread; with `thread: "continue"` the
1295
+ * subagent appends to the parent's thread in-place.
1296
+ *
1297
+ * Has no effect when `thread` is `"new"` (or omitted). A `threadId`
1298
+ * supplied by the parent agent always wins — `newThreadSource` only
1299
+ * applies when none is provided.
1300
+ */
1301
+ newThreadSource?: "new" | "from-parent";
1286
1302
  /**
1287
1303
  * Sandbox strategy for this subagent.
1288
1304
  *
@@ -1529,6 +1545,28 @@ interface ThreadOps<TContent = string> {
1529
1545
  * store, continue later" works regardless of exit reason.
1530
1546
  */
1531
1547
  saveThreadState(threadId: string, state: PersistedThreadState, threadKey?: string): Promise<void>;
1548
+ /**
1549
+ * Restore the thread's contents from the durable cold tier (if any)
1550
+ * into Redis. Called once on session entry for `mode: "continue"`
1551
+ * and `mode: "fork"` so the rest of the loop reads the freshest data.
1552
+ *
1553
+ * Adapters configured without a cold-store implementation treat this
1554
+ * as a no-op. Implementations must be **idempotent** — Temporal
1555
+ * retries the activity on transient failures, and a thread that is
1556
+ * already hot must not be wiped.
1557
+ */
1558
+ hydrateThread(threadId: string, threadKey?: string): Promise<void>;
1559
+ /**
1560
+ * Archive the thread's contents to the durable cold tier and
1561
+ * (optionally) drop the hot-tier Redis keys. Called once in the
1562
+ * session's `finally` block on every exit path, after
1563
+ * `saveThreadState`.
1564
+ *
1565
+ * Adapters configured without a cold-store implementation treat this
1566
+ * as a no-op. Implementations must be **idempotent** — the cold
1567
+ * tier is last-writer-wins and a retried flush must converge.
1568
+ */
1569
+ flushThread(threadId: string, threadKey?: string): Promise<void>;
1532
1570
  }
1533
1571
  /**
1534
1572
  * Composes an adapter prefix + workflow scope for activity naming.
@@ -1283,6 +1283,22 @@ interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
1283
1283
  * directly to the existing thread in-place.
1284
1284
  */
1285
1285
  thread?: "new" | "fork" | "continue";
1286
+ /**
1287
+ * Where the subagent's thread comes from when the parent's tool call
1288
+ * omits `threadId`. Only meaningful in combination with
1289
+ * `thread: "fork"` or `"continue"`.
1290
+ *
1291
+ * - `"new"` (default) — start a fresh thread (the prior behavior).
1292
+ * - `"from-parent"` — use the parent's own `threadId` (from
1293
+ * `RouterContext`). With `thread: "fork"` the parent's conversation
1294
+ * is copied into a new thread; with `thread: "continue"` the
1295
+ * subagent appends to the parent's thread in-place.
1296
+ *
1297
+ * Has no effect when `thread` is `"new"` (or omitted). A `threadId`
1298
+ * supplied by the parent agent always wins — `newThreadSource` only
1299
+ * applies when none is provided.
1300
+ */
1301
+ newThreadSource?: "new" | "from-parent";
1286
1302
  /**
1287
1303
  * Sandbox strategy for this subagent.
1288
1304
  *
@@ -1529,6 +1545,28 @@ interface ThreadOps<TContent = string> {
1529
1545
  * store, continue later" works regardless of exit reason.
1530
1546
  */
1531
1547
  saveThreadState(threadId: string, state: PersistedThreadState, threadKey?: string): Promise<void>;
1548
+ /**
1549
+ * Restore the thread's contents from the durable cold tier (if any)
1550
+ * into Redis. Called once on session entry for `mode: "continue"`
1551
+ * and `mode: "fork"` so the rest of the loop reads the freshest data.
1552
+ *
1553
+ * Adapters configured without a cold-store implementation treat this
1554
+ * as a no-op. Implementations must be **idempotent** — Temporal
1555
+ * retries the activity on transient failures, and a thread that is
1556
+ * already hot must not be wiped.
1557
+ */
1558
+ hydrateThread(threadId: string, threadKey?: string): Promise<void>;
1559
+ /**
1560
+ * Archive the thread's contents to the durable cold tier and
1561
+ * (optionally) drop the hot-tier Redis keys. Called once in the
1562
+ * session's `finally` block on every exit path, after
1563
+ * `saveThreadState`.
1564
+ *
1565
+ * Adapters configured without a cold-store implementation treat this
1566
+ * as a no-op. Implementations must be **idempotent** — the cold
1567
+ * tier is last-writer-wins and a retried flush must converge.
1568
+ */
1569
+ flushThread(threadId: string, threadKey?: string): Promise<void>;
1532
1570
  }
1533
1571
  /**
1534
1572
  * Composes an adapter prefix + workflow scope for activity naming.
@@ -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-DNEl5uxQ.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.
@@ -304,6 +335,7 @@ declare function defineSubagent<TResult extends z.ZodType = z.ZodType, TContext
304
335
  enabled?: boolean | (() => boolean);
305
336
  taskQueue?: string;
306
337
  thread?: "new" | "fork" | "continue";
338
+ newThreadSource?: "new" | "from-parent";
307
339
  sandbox?: SubagentSandboxConfig;
308
340
  }): SubagentConfig<TResult>;
309
341
 
@@ -709,6 +741,20 @@ declare const editTool: {
709
741
  strict: true;
710
742
  };
711
743
  type FileEditArgs = z.infer<typeof editTool.schema>;
744
+ declare const multiEditTool: {
745
+ name: "FileMultiEdit";
746
+ description: string;
747
+ schema: z.ZodObject<{
748
+ file_path: z.ZodString;
749
+ edits: z.ZodArray<z.ZodObject<{
750
+ old_string: z.ZodString;
751
+ new_string: z.ZodString;
752
+ replace_all: z.ZodOptional<z.ZodBoolean>;
753
+ }, z.core.$strip>>;
754
+ }, z.core.$strip>;
755
+ strict: true;
756
+ };
757
+ type FileMultiEditArgs = z.infer<typeof multiEditTool.schema>;
712
758
 
713
759
  declare const taskCreateTool: {
714
760
  name: "TaskCreate";
@@ -856,4 +902,4 @@ declare const createAskUserQuestionHandler: () => ActivityToolHandler<AskUserQue
856
902
  }[];
857
903
  }>;
858
904
 
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 };
905
+ export { getThreadStateKey as $, type AskUserQuestionArgs as A, type BashArgs as B, createTaskCreateHandler as C, DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT as D, createTaskGetHandler as E, type FileEditArgs as F, type GlobArgs as G, createTaskListHandler as H, createTaskUpdateHandler as I, createToolRouter as J, defineSubagent as K, defineSubagentWorkflow as L, defineTool as M, defineWorkflow as N, type ObservabilityHooks as O, editTool as P, filesWithMimeType as Q, type ReadSkillArgs as R, type SessionEndedEvent as S, THREAD_TTL_SECONDS as T, formatVirtualFileTree as U, getShortId as V, type WorkflowConfig as W, getThreadDedupKey as X, getThreadListKey as Y, type ZeitlichObservabilitySinks as Z, getThreadMetaKey as _, type FileMultiEditArgs as a, globTool as a0, grepTool as a1, hasDirectory as a2, hasFileWithMimeType as a3, hasNoOtherToolCalls as a4, multiEditTool as a5, parseSkillFile as a6, proxyRunAgent as a7, proxyVirtualFsOps as a8, readFileTool as a9, taskCreateTool as aa, taskGetTool as ab, taskListTool as ac, taskUpdateTool as ad, writeFileTool as ae, type FileReadArgs as b, type FileWriteArgs as c, type FileTreeAccessor as d, type GrepArgs as e, type SessionStartedEvent as f, type SubagentArgs as g, type TaskCreateArgs as h, type TaskGetArgs as i, type TaskListArgs as j, type TaskUpdateArgs as k, type ToolExecutedEvent as l, type TurnCompletedEvent as m, type WorkflowInput as n, type WorkflowSessionInput as o, applyVirtualTreeMutations as p, askUserQuestionTool as q, bashTool as r, composeHooks as s, createAgentStateManager as t, createAskUserQuestionHandler as u, createBashToolDescription as v, createObservabilityHooks as w, createReadSkillHandler as x, createReadSkillTool as y, createSession 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-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-qQVZfhoT.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.
@@ -304,6 +335,7 @@ declare function defineSubagent<TResult extends z.ZodType = z.ZodType, TContext
304
335
  enabled?: boolean | (() => boolean);
305
336
  taskQueue?: string;
306
337
  thread?: "new" | "fork" | "continue";
338
+ newThreadSource?: "new" | "from-parent";
307
339
  sandbox?: SubagentSandboxConfig;
308
340
  }): SubagentConfig<TResult>;
309
341
 
@@ -709,6 +741,20 @@ declare const editTool: {
709
741
  strict: true;
710
742
  };
711
743
  type FileEditArgs = z.infer<typeof editTool.schema>;
744
+ declare const multiEditTool: {
745
+ name: "FileMultiEdit";
746
+ description: string;
747
+ schema: z.ZodObject<{
748
+ file_path: z.ZodString;
749
+ edits: z.ZodArray<z.ZodObject<{
750
+ old_string: z.ZodString;
751
+ new_string: z.ZodString;
752
+ replace_all: z.ZodOptional<z.ZodBoolean>;
753
+ }, z.core.$strip>>;
754
+ }, z.core.$strip>;
755
+ strict: true;
756
+ };
757
+ type FileMultiEditArgs = z.infer<typeof multiEditTool.schema>;
712
758
 
713
759
  declare const taskCreateTool: {
714
760
  name: "TaskCreate";
@@ -856,4 +902,4 @@ declare const createAskUserQuestionHandler: () => ActivityToolHandler<AskUserQue
856
902
  }[];
857
903
  }>;
858
904
 
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 };
905
+ export { getThreadStateKey as $, type AskUserQuestionArgs as A, type BashArgs as B, createTaskCreateHandler as C, DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT as D, createTaskGetHandler as E, type FileEditArgs as F, type GlobArgs as G, createTaskListHandler as H, createTaskUpdateHandler as I, createToolRouter as J, defineSubagent as K, defineSubagentWorkflow as L, defineTool as M, defineWorkflow as N, type ObservabilityHooks as O, editTool as P, filesWithMimeType as Q, type ReadSkillArgs as R, type SessionEndedEvent as S, THREAD_TTL_SECONDS as T, formatVirtualFileTree as U, getShortId as V, type WorkflowConfig as W, getThreadDedupKey as X, getThreadListKey as Y, type ZeitlichObservabilitySinks as Z, getThreadMetaKey as _, type FileMultiEditArgs as a, globTool as a0, grepTool as a1, hasDirectory as a2, hasFileWithMimeType as a3, hasNoOtherToolCalls as a4, multiEditTool as a5, parseSkillFile as a6, proxyRunAgent as a7, proxyVirtualFsOps as a8, readFileTool as a9, taskCreateTool as aa, taskGetTool as ab, taskListTool as ac, taskUpdateTool as ad, writeFileTool as ae, type FileReadArgs as b, type FileWriteArgs as c, type FileTreeAccessor as d, type GrepArgs as e, type SessionStartedEvent as f, type SubagentArgs as g, type TaskCreateArgs as h, type TaskGetArgs as i, type TaskListArgs as j, type TaskUpdateArgs as k, type ToolExecutedEvent as l, type TurnCompletedEvent as m, type WorkflowInput as n, type WorkflowSessionInput as o, applyVirtualTreeMutations as p, askUserQuestionTool as q, bashTool as r, composeHooks as s, createAgentStateManager as t, createAskUserQuestionHandler as u, createBashToolDescription as v, createObservabilityHooks as w, createReadSkillHandler as x, createReadSkillTool as y, createSession as z };
package/dist/workflow.cjs CHANGED
@@ -566,7 +566,8 @@ function createSubagentHandler(subagents) {
566
566
  }
567
567
  const threadMode = config.thread ?? "new";
568
568
  const allowsContinuation = threadMode !== "new";
569
- const continuationThreadId = args.threadId && allowsContinuation ? args.threadId : void 0;
569
+ const newThreadSource = config.newThreadSource ?? "new";
570
+ const continuationThreadId = !allowsContinuation ? void 0 : args.threadId ?? (newThreadSource === "from-parent" ? context.threadId : void 0);
570
571
  let thread;
571
572
  if (continuationThreadId) {
572
573
  thread = {
@@ -1034,7 +1035,9 @@ async function createSession(config) {
1034
1035
  appendAgentMessage,
1035
1036
  forkThread,
1036
1037
  loadThreadState,
1037
- saveThreadState
1038
+ saveThreadState,
1039
+ hydrateThread,
1040
+ flushThread
1038
1041
  } = threadOps;
1039
1042
  const plugins = [];
1040
1043
  let destroySubagentSandboxes;
@@ -1178,10 +1181,12 @@ async function createSession(config) {
1178
1181
  });
1179
1182
  };
1180
1183
  if (threadMode === "fork" && sourceThreadId) {
1184
+ await hydrateThread(sourceThreadId, threadKey);
1181
1185
  await forkThread(sourceThreadId, threadId, threadKey);
1182
1186
  const forkedSlice = await loadThreadState(threadId, threadKey);
1183
1187
  if (forkedSlice) rehydrateFromSlice(forkedSlice);
1184
1188
  } else if (threadMode === "continue") {
1189
+ await hydrateThread(threadId, threadKey);
1185
1190
  const continuedSlice = await loadThreadState(threadId, threadKey);
1186
1191
  if (continuedSlice) rehydrateFromSlice(continuedSlice);
1187
1192
  } else {
@@ -1363,6 +1368,15 @@ async function createSession(config) {
1363
1368
  error: persistError instanceof Error ? persistError.message : String(persistError)
1364
1369
  });
1365
1370
  }
1371
+ try {
1372
+ await flushThread(threadId, threadKey);
1373
+ } catch (flushError) {
1374
+ workflow.log.warn("failed to flush thread to cold tier", {
1375
+ agentName,
1376
+ threadId,
1377
+ error: flushError instanceof Error ? flushError.message : String(flushError)
1378
+ });
1379
+ }
1366
1380
  await callSessionEnd(exitReason, stateManager.getTurns());
1367
1381
  if (sandboxOwned && sandboxId && sandboxOps) {
1368
1382
  switch (resolvedShutdown) {
@@ -2105,6 +2119,13 @@ IMPORTANT:
2105
2119
  }),
2106
2120
  strict: true
2107
2121
  };
2122
+ var textEditSchema = z14.z.object({
2123
+ old_string: z14.z.string().describe("The exact text to replace"),
2124
+ new_string: z14.z.string().describe("The text to replace it with"),
2125
+ replace_all: z14.z.boolean().optional().describe(
2126
+ "If true, replace all occurrences of old_string for this edit (default: false)"
2127
+ )
2128
+ });
2108
2129
  var editTool = {
2109
2130
  name: "FileEdit",
2110
2131
  description: `Edit specific sections of a file by replacing text.
@@ -2133,6 +2154,27 @@ IMPORTANT:
2133
2154
  }),
2134
2155
  strict: true
2135
2156
  };
2157
+ var multiEditTool = {
2158
+ name: "FileMultiEdit",
2159
+ description: `Apply multiple exact text replacements to one file in order.
2160
+
2161
+ Usage:
2162
+ - Use this when a task needs several related edits in the same file
2163
+ - Each edit is applied to the file content produced by the prior edit
2164
+ - The operation is atomic: if any edit fails, the file is left unchanged
2165
+
2166
+ IMPORTANT:
2167
+ - You must read the file first (in this session) before editing it
2168
+ - Each old_string must match exactly (whitespace-sensitive)
2169
+ - Each old_string must be unique unless that edit uses replace_all: true
2170
+ - old_string and new_string must be different for every edit
2171
+ `,
2172
+ schema: z14.z.object({
2173
+ file_path: z14.z.string().describe("The absolute virtual path to the file to modify"),
2174
+ edits: z14.z.array(textEditSchema).min(1).describe("Exact replacements to apply sequentially to the file")
2175
+ }),
2176
+ strict: true
2177
+ };
2136
2178
  var taskCreateTool = {
2137
2179
  name: "TaskCreate",
2138
2180
  description: `Use this tool to create a structured task list. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
@@ -2203,7 +2245,7 @@ function createTaskCreateHandler(stateManager) {
2203
2245
  };
2204
2246
  stateManager.setTask(task);
2205
2247
  return {
2206
- toolResponse: JSON.stringify(task, null, 2),
2248
+ toolResponse: `Task ${task.id} created`,
2207
2249
  data: task
2208
2250
  };
2209
2251
  };
@@ -2302,7 +2344,7 @@ function createTaskUpdateHandler(stateManager) {
2302
2344
  }
2303
2345
  stateManager.setTask(task);
2304
2346
  return {
2305
- toolResponse: JSON.stringify(task, null, 2),
2347
+ toolResponse: `Task ${task.id} updated`,
2306
2348
  data: task
2307
2349
  };
2308
2350
  };
@@ -2411,6 +2453,7 @@ exports.hasDirectory = hasDirectory;
2411
2453
  exports.hasFileWithMimeType = hasFileWithMimeType;
2412
2454
  exports.hasNoOtherToolCalls = hasNoOtherToolCalls;
2413
2455
  exports.isTerminalStatus = isTerminalStatus;
2456
+ exports.multiEditTool = multiEditTool;
2414
2457
  exports.parseSkillFile = parseSkillFile;
2415
2458
  exports.proxyRunAgent = proxyRunAgent;
2416
2459
  exports.proxyVirtualFsOps = proxyVirtualFsOps;