zeitlich 0.2.46 → 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 (83) hide show
  1. package/README.md +64 -6
  2. package/dist/{activities-CyeiqK_f.d.cts → activities-CPwKoUlD.d.cts} +3 -3
  3. package/dist/{activities-Bm4TLTid.d.ts → activities-DlaBxNID.d.ts} +3 -3
  4. package/dist/adapters/thread/anthropic/index.cjs +105 -6
  5. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  6. package/dist/adapters/thread/anthropic/index.d.cts +48 -9
  7. package/dist/adapters/thread/anthropic/index.d.ts +48 -9
  8. package/dist/adapters/thread/anthropic/index.js +104 -7
  9. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  10. package/dist/adapters/thread/anthropic/workflow.cjs +38 -22
  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 -22
  15. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  16. package/dist/adapters/thread/google-genai/index.d.cts +6 -5
  17. package/dist/adapters/thread/google-genai/index.d.ts +6 -5
  18. package/dist/adapters/thread/google-genai/workflow.cjs +38 -22
  19. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  20. package/dist/adapters/thread/google-genai/workflow.d.cts +7 -5
  21. package/dist/adapters/thread/google-genai/workflow.d.ts +7 -5
  22. package/dist/adapters/thread/google-genai/workflow.js +38 -22
  23. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  24. package/dist/adapters/thread/langchain/index.d.cts +6 -5
  25. package/dist/adapters/thread/langchain/index.d.ts +6 -5
  26. package/dist/adapters/thread/langchain/workflow.cjs +38 -22
  27. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  28. package/dist/adapters/thread/langchain/workflow.d.cts +5 -4
  29. package/dist/adapters/thread/langchain/workflow.d.ts +5 -4
  30. package/dist/adapters/thread/langchain/workflow.js +38 -22
  31. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  32. package/dist/{cold-store-CFHwemBJ.d.ts → cold-store-BDgJpwLI.d.ts} +8 -11
  33. package/dist/{cold-store-BC5L5Z8A.d.cts → cold-store-Z2wvK2cV.d.cts} +8 -11
  34. package/dist/index.cjs +264 -90
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +21 -9
  37. package/dist/index.d.ts +21 -9
  38. package/dist/index.js +265 -93
  39. package/dist/index.js.map +1 -1
  40. package/dist/proxy-CDh3Rsa7.d.cts +40 -0
  41. package/dist/proxy-Du8ggERu.d.ts +40 -0
  42. package/dist/{thread-manager-D33SUmZa.d.cts → thread-manager-BjoYYXgd.d.cts} +2 -2
  43. package/dist/{thread-manager-9tezUcLW.d.cts → thread-manager-D8zKNFZ9.d.cts} +2 -2
  44. package/dist/{thread-manager-B-zy3xrs.d.ts → thread-manager-DtHYws2F.d.ts} +2 -2
  45. package/dist/{thread-manager-DduoSkvJ.d.ts → thread-manager-Dw96FKH1.d.ts} +2 -2
  46. package/dist/{types-oxt8GN97.d.cts → types-BMJrsHo0.d.cts} +1 -1
  47. package/dist/{types-L5bvbF-n.d.ts → types-CtdOquo3.d.ts} +1 -1
  48. package/dist/{types-CnuN9T6t.d.cts → types-DNEl5uxQ.d.cts} +16 -0
  49. package/dist/{types-CwN6_tAL.d.ts → types-qQVZfhoT.d.ts} +16 -0
  50. package/dist/{workflow-DIaIV7L2.d.cts → workflow-BH9ImDGq.d.cts} +17 -2
  51. package/dist/{workflow-B1TOcHbt.d.ts → workflow-Cdw3-RNB.d.ts} +17 -2
  52. package/dist/workflow.cjs +33 -3
  53. package/dist/workflow.cjs.map +1 -1
  54. package/dist/workflow.d.cts +2 -2
  55. package/dist/workflow.d.ts +2 -2
  56. package/dist/workflow.js +33 -4
  57. package/dist/workflow.js.map +1 -1
  58. package/package.json +9 -3
  59. package/src/adapters/thread/anthropic/activities.ts +18 -11
  60. package/src/adapters/thread/anthropic/index.ts +8 -0
  61. package/src/adapters/thread/anthropic/model-invoker.test.ts +110 -0
  62. package/src/adapters/thread/anthropic/model-invoker.ts +26 -5
  63. package/src/adapters/thread/anthropic/prompt-cache.test.ts +134 -0
  64. package/src/adapters/thread/anthropic/prompt-cache.ts +163 -0
  65. package/src/adapters/thread/anthropic/proxy.ts +1 -0
  66. package/src/adapters/thread/google-genai/proxy.ts +1 -0
  67. package/src/adapters/thread/langchain/proxy.ts +1 -0
  68. package/src/index.ts +1 -1
  69. package/src/lib/subagent/define.ts +1 -0
  70. package/src/lib/subagent/handler.ts +11 -2
  71. package/src/lib/subagent/subagent.integration.test.ts +139 -0
  72. package/src/lib/subagent/types.ts +16 -0
  73. package/src/lib/thread/cold-store.test.ts +33 -5
  74. package/src/lib/thread/cold-store.ts +50 -31
  75. package/src/lib/thread/proxy.ts +79 -29
  76. package/src/tools/edit/handler.test.ts +177 -0
  77. package/src/tools/edit/handler.ts +249 -47
  78. package/src/tools/edit/tool.ts +40 -0
  79. package/src/tools/task-create/handler.ts +1 -1
  80. package/src/tools/task-update/handler.ts +1 -1
  81. package/src/workflow.ts +2 -2
  82. package/dist/proxy-BxFyd6cg.d.cts +0 -24
  83. package/dist/proxy-Cskmj4Yx.d.ts +0 -24
package/dist/index.d.cts CHANGED
@@ -1,19 +1,20 @@
1
- import { B as BashArgs, F as FileEditArgs, G as GlobArgs, a as FileReadArgs, b as FileWriteArgs } from './workflow-DIaIV7L2.cjs';
2
- export { A as AskUserQuestionArgs, D as DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, c as FileTreeAccessor, d as GrepArgs, O as ObservabilityHooks, R as ReadSkillArgs, S as SessionEndedEvent, e as SessionStartedEvent, f as SubagentArgs, T as THREAD_TTL_SECONDS, g as TaskCreateArgs, h as TaskGetArgs, i as TaskListArgs, j as TaskUpdateArgs, k as ToolExecutedEvent, l as TurnCompletedEvent, W as WorkflowConfig, m as WorkflowInput, n as WorkflowSessionInput, Z as ZeitlichObservabilitySinks, o as applyVirtualTreeMutations, p as askUserQuestionTool, q as bashTool, r as composeHooks, s as createAgentStateManager, t as createAskUserQuestionHandler, u as createBashToolDescription, v as createObservabilityHooks, w as createReadSkillHandler, x as createReadSkillTool, y as createSession, z as createTaskCreateHandler, C as createTaskGetHandler, E as createTaskListHandler, H as createTaskUpdateHandler, I as createToolRouter, J as defineSubagent, K as defineSubagentWorkflow, L as defineTool, M as defineWorkflow, N as editTool, P as filesWithMimeType, Q as formatVirtualFileTree, U as getShortId, V as getThreadDedupKey, X as getThreadListKey, Y as getThreadMetaKey, _ as getThreadStateKey, $ as globTool, a0 as grepTool, a1 as hasDirectory, a2 as hasFileWithMimeType, a3 as hasNoOtherToolCalls, a4 as parseSkillFile, a5 as proxyRunAgent, a6 as proxyVirtualFsOps, a7 as readFileTool, a8 as taskCreateTool, a9 as taskGetTool, aa as taskListTool, ab as taskUpdateTool, ac as writeFileTool } from './workflow-DIaIV7L2.cjs';
3
- import { R as RouterContext, e as ToolResultConfig, d as ActivityToolHandler, J as JsonValue, c as ToolHandlerResponse, B as BaseAgentState, f as RunAgentConfig, g as SkillProvider, h as SkillMetadata, i as Skill, F as FileEntryMetadata, j as FileResolver, V as VirtualFsContext, k as TreeMutation, l as PrefixedVirtualFsOps } from './types-CnuN9T6t.cjs';
4
- export { m as AgentConfig, n as AgentFile, A as AgentResponse, o as AgentState, p as AgentStateManager, q as AgentStatus, r as AppendToolResultFn, s as FileEntry, H as Hooks, I as InferToolResults, t as JsonPrimitive, u as JsonSerializable, a as ModelInvoker, M as ModelInvokerConfig, v as ParsedToolCall, w as ParsedToolCallUnion, P as PersistedThreadState, x as PostHumanMessageAppendHook, y as PostHumanMessageAppendHookContext, z as PostToolUseFailureHook, C as PostToolUseFailureHookContext, D as PostToolUseFailureHookResult, E as PostToolUseHook, G as PostToolUseHookContext, K as PreHumanMessageAppendHook, L as PreHumanMessageAppendHookContext, N as PreToolUseHook, O as PreToolUseHookContext, Q as PreToolUseHookResult, b as PrefixedThreadOps, U as ProcessToolCallsContext, W as ProcessToolCallsResult, X as RawToolCall, Y as RewindSignal, Z as RunAgentActivity, _ as SandboxInit, $ as SandboxShutdown, S as ScopedPrefix, a0 as SerializableToolDefinition, a1 as SessionConfig, a2 as SessionEndHook, a3 as SessionEndHookContext, a4 as SessionExitReason, a5 as SessionRequiredCaps, a6 as SessionResult, a7 as SessionStartHook, a8 as SessionStartHookContext, a9 as SubagentChildWorkflowOptions, aa as SubagentConfig, ab as SubagentContinuationCaps, ac as SubagentDefinition, ad as SubagentFnResult, ae as SubagentHandlerResponse, af as SubagentHooks, ag as SubagentSandboxConfig, ah as SubagentSandboxShutdown, ai as SubagentSessionInput, aj as SubagentWorkflow, ak as SubagentWorkflowInput, al as TaskStatus, am as ThreadInit, T as ThreadOps, an as TokenUsage, ao as ToolArgs, ap as ToolCallResult, aq as ToolCallResultUnion, ar as ToolDefinition, as as ToolHandler, at as ToolHooks, au as ToolMap, av as ToolNames, aw as ToolResult, ax as ToolRouter, ay as ToolRouterHooks, az as ToolWithHandler, aA as VirtualFileSystem, aB as VirtualFileTree, aC as VirtualFsOps, aD as VirtualFsState, aE as WorkflowTask, aF as ZeitlichSession, aG as isTerminalStatus } from './types-CnuN9T6t.cjs';
1
+ import { B as BashArgs, F as FileEditArgs, a as FileMultiEditArgs, G as GlobArgs, b as FileReadArgs, c as FileWriteArgs } from './workflow-BH9ImDGq.cjs';
2
+ export { A as AskUserQuestionArgs, D as DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, d as FileTreeAccessor, e as GrepArgs, O as ObservabilityHooks, R as ReadSkillArgs, S as SessionEndedEvent, f as SessionStartedEvent, g as SubagentArgs, T as THREAD_TTL_SECONDS, h as TaskCreateArgs, i as TaskGetArgs, j as TaskListArgs, k as TaskUpdateArgs, l as ToolExecutedEvent, m as TurnCompletedEvent, W as WorkflowConfig, n as WorkflowInput, o as WorkflowSessionInput, Z as ZeitlichObservabilitySinks, p as applyVirtualTreeMutations, q as askUserQuestionTool, r as bashTool, s as composeHooks, t as createAgentStateManager, u as createAskUserQuestionHandler, v as createBashToolDescription, w as createObservabilityHooks, x as createReadSkillHandler, y as createReadSkillTool, z as createSession, C as createTaskCreateHandler, E as createTaskGetHandler, H as createTaskListHandler, I as createTaskUpdateHandler, J as createToolRouter, K as defineSubagent, L as defineSubagentWorkflow, M as defineTool, N as defineWorkflow, P as editTool, Q as filesWithMimeType, U as formatVirtualFileTree, V as getShortId, X as getThreadDedupKey, Y as getThreadListKey, _ as getThreadMetaKey, $ as getThreadStateKey, a0 as globTool, a1 as grepTool, a2 as hasDirectory, a3 as hasFileWithMimeType, a4 as hasNoOtherToolCalls, a5 as multiEditTool, a6 as parseSkillFile, a7 as proxyRunAgent, a8 as proxyVirtualFsOps, a9 as readFileTool, aa as taskCreateTool, ab as taskGetTool, ac as taskListTool, ad as taskUpdateTool, ae as writeFileTool } from './workflow-BH9ImDGq.cjs';
3
+ import { R as RouterContext, e as ToolResultConfig, d as ActivityToolHandler, J as JsonValue, c as ToolHandlerResponse, B as BaseAgentState, f as RunAgentConfig, g as SkillProvider, h as SkillMetadata, i as Skill, F as FileEntryMetadata, j as FileResolver, V as VirtualFsContext, k as TreeMutation, l as PrefixedVirtualFsOps } from './types-DNEl5uxQ.cjs';
4
+ export { m as AgentConfig, n as AgentFile, A as AgentResponse, o as AgentState, p as AgentStateManager, q as AgentStatus, r as AppendToolResultFn, s as FileEntry, H as Hooks, I as InferToolResults, t as JsonPrimitive, u as JsonSerializable, a as ModelInvoker, M as ModelInvokerConfig, v as ParsedToolCall, w as ParsedToolCallUnion, P as PersistedThreadState, x as PostHumanMessageAppendHook, y as PostHumanMessageAppendHookContext, z as PostToolUseFailureHook, C as PostToolUseFailureHookContext, D as PostToolUseFailureHookResult, E as PostToolUseHook, G as PostToolUseHookContext, K as PreHumanMessageAppendHook, L as PreHumanMessageAppendHookContext, N as PreToolUseHook, O as PreToolUseHookContext, Q as PreToolUseHookResult, b as PrefixedThreadOps, U as ProcessToolCallsContext, W as ProcessToolCallsResult, X as RawToolCall, Y as RewindSignal, Z as RunAgentActivity, _ as SandboxInit, $ as SandboxShutdown, S as ScopedPrefix, a0 as SerializableToolDefinition, a1 as SessionConfig, a2 as SessionEndHook, a3 as SessionEndHookContext, a4 as SessionExitReason, a5 as SessionRequiredCaps, a6 as SessionResult, a7 as SessionStartHook, a8 as SessionStartHookContext, a9 as SubagentChildWorkflowOptions, aa as SubagentConfig, ab as SubagentContinuationCaps, ac as SubagentDefinition, ad as SubagentFnResult, ae as SubagentHandlerResponse, af as SubagentHooks, ag as SubagentSandboxConfig, ah as SubagentSandboxShutdown, ai as SubagentSessionInput, aj as SubagentWorkflow, ak as SubagentWorkflowInput, al as TaskStatus, am as ThreadInit, T as ThreadOps, an as TokenUsage, ao as ToolArgs, ap as ToolCallResult, aq as ToolCallResultUnion, ar as ToolDefinition, as as ToolHandler, at as ToolHooks, au as ToolMap, av as ToolNames, aw as ToolResult, ax as ToolRouter, ay as ToolRouterHooks, az as ToolWithHandler, aA as VirtualFileSystem, aB as VirtualFileTree, aC as VirtualFsOps, aD as VirtualFsState, aE as WorkflowTask, aF as ZeitlichSession, aG as isTerminalStatus } from './types-DNEl5uxQ.cjs';
5
5
  import { b as Sandbox, c as SandboxFileSystem, a as SandboxCreateOptions, h as SandboxCapability, d as SandboxProvider, g as SandboxSnapshot, P as PrefixedSandboxOps, F as FileStat, D as DirentEntry, E as ExecResult } from './types-CJ7tCdl6.cjs';
6
6
  export { i as ExecOptions, e as SandboxCapabilities, f as SandboxCreateResult, j as SandboxNotFoundError, k as SandboxNotSupportedError, S as SandboxOps } from './types-CJ7tCdl6.cjs';
7
7
  import { WorkflowClient } from '@temporalio/client';
8
- import { a as ThreadManagerConfig, B as BaseThreadManager } from './types-oxt8GN97.cjs';
9
- export { P as ProviderThreadManager } from './types-oxt8GN97.cjs';
10
- import { C as ColdThreadStore, T as ThreadSnapshot } from './cold-store-BC5L5Z8A.cjs';
11
- export { S as S3ColdStoreConfig, a as S3LikeClient, c as createS3ColdStore } from './cold-store-BC5L5Z8A.cjs';
8
+ import { a as ThreadManagerConfig, B as BaseThreadManager } from './types-BMJrsHo0.cjs';
9
+ export { P as ProviderThreadManager } from './types-BMJrsHo0.cjs';
10
+ import { C as ColdThreadStore, T as ThreadSnapshot } from './cold-store-Z2wvK2cV.cjs';
11
+ export { S as S3ColdStoreConfig, a as S3LikeClient, c as createS3ColdStore } from './cold-store-Z2wvK2cV.cjs';
12
12
  import Redis from 'ioredis';
13
13
  import 'zod';
14
14
  import '@temporalio/common';
15
15
  import '@temporalio/workflow';
16
16
  import '@temporalio/common/lib/interfaces';
17
+ import '@aws-sdk/client-s3';
17
18
 
18
19
  /**
19
20
  * Wraps a tool handler to automatically append its result directly to the
@@ -646,6 +647,16 @@ interface EditResult {
646
647
  path: string;
647
648
  success: boolean;
648
649
  replacements: number;
650
+ hunks?: EditHunk[];
651
+ }
652
+ interface EditHunk {
653
+ editIndex: number;
654
+ oldStartLine: number;
655
+ oldEndLine: number;
656
+ newStartLine: number;
657
+ newEndLine: number;
658
+ oldLines: string[];
659
+ newLines: string[];
649
660
  }
650
661
  /**
651
662
  * Edit tool handler — performs string replacements in sandbox files.
@@ -654,6 +665,7 @@ interface EditResult {
654
665
  * sandbox automatically.
655
666
  */
656
667
  declare const editHandler: ActivityToolHandler<FileEditArgs, EditResult, SandboxContext>;
668
+ declare const multiEditHandler: ActivityToolHandler<FileMultiEditArgs, EditResult, SandboxContext>;
657
669
 
658
670
  interface GlobResult {
659
671
  files: string[];
@@ -724,4 +736,4 @@ declare const toTree: (fs: SandboxFileSystem, opts?: {
724
736
  sort?: boolean;
725
737
  }) => Promise<string>;
726
738
 
727
- export { ActivityToolHandler, type AgentStateContext, type ApplySnapshotConfig, BaseAgentState, BaseThreadManager, BashArgs, type ClearHotTierConfig, ColdThreadStore, type EncodeSnapshotConfig, ExecResult, FileEditArgs, FileEntryMetadata, FileReadArgs, FileResolver, FileSystemSkillProvider, FileWriteArgs, type FlushOptions, GlobArgs, JsonValue, NodeFsSandboxFileSystem, type PreCreateHookResult, PrefixedSandboxOps, PrefixedVirtualFsOps, RouterContext, RunAgentConfig, Sandbox, SandboxCapability, type SandboxContext, SandboxCreateOptions, DirentEntry as SandboxDirentEntry, FileStat as SandboxFileStat, SandboxFileSystem, SandboxManager, type SandboxManagerHooks, SandboxProvider, SandboxSnapshot, Skill, SkillMetadata, SkillProvider, ThreadManagerConfig, ThreadSnapshot, type TieredThreadManager, type TieredThreadManagerConfig, ToolHandlerResponse, ToolResultConfig, TreeMutation, VirtualFsContext, type WithSandboxOptions, applySnapshot, bashHandler, clearHotTier, createRunAgentActivity, createThreadManager, createTieredThreadManager, createVirtualFsActivities, editHandler, encodeSnapshot, getActivityContext, globHandler, queryParentWorkflowState, readFileHandler, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler };
739
+ export { ActivityToolHandler, type AgentStateContext, type ApplySnapshotConfig, BaseAgentState, BaseThreadManager, BashArgs, type ClearHotTierConfig, ColdThreadStore, type EncodeSnapshotConfig, ExecResult, FileEditArgs, FileEntryMetadata, FileMultiEditArgs, FileReadArgs, FileResolver, FileSystemSkillProvider, FileWriteArgs, type FlushOptions, GlobArgs, JsonValue, NodeFsSandboxFileSystem, type PreCreateHookResult, PrefixedSandboxOps, PrefixedVirtualFsOps, RouterContext, RunAgentConfig, Sandbox, SandboxCapability, type SandboxContext, SandboxCreateOptions, DirentEntry as SandboxDirentEntry, FileStat as SandboxFileStat, SandboxFileSystem, SandboxManager, type SandboxManagerHooks, SandboxProvider, SandboxSnapshot, Skill, SkillMetadata, SkillProvider, ThreadManagerConfig, ThreadSnapshot, type TieredThreadManager, type TieredThreadManagerConfig, ToolHandlerResponse, ToolResultConfig, TreeMutation, VirtualFsContext, type WithSandboxOptions, applySnapshot, bashHandler, clearHotTier, createRunAgentActivity, createThreadManager, createTieredThreadManager, createVirtualFsActivities, editHandler, encodeSnapshot, getActivityContext, globHandler, multiEditHandler, queryParentWorkflowState, readFileHandler, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler };
package/dist/index.d.ts CHANGED
@@ -1,19 +1,20 @@
1
- import { B as BashArgs, F as FileEditArgs, G as GlobArgs, a as FileReadArgs, b as FileWriteArgs } from './workflow-B1TOcHbt.js';
2
- export { A as AskUserQuestionArgs, D as DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, c as FileTreeAccessor, d as GrepArgs, O as ObservabilityHooks, R as ReadSkillArgs, S as SessionEndedEvent, e as SessionStartedEvent, f as SubagentArgs, T as THREAD_TTL_SECONDS, g as TaskCreateArgs, h as TaskGetArgs, i as TaskListArgs, j as TaskUpdateArgs, k as ToolExecutedEvent, l as TurnCompletedEvent, W as WorkflowConfig, m as WorkflowInput, n as WorkflowSessionInput, Z as ZeitlichObservabilitySinks, o as applyVirtualTreeMutations, p as askUserQuestionTool, q as bashTool, r as composeHooks, s as createAgentStateManager, t as createAskUserQuestionHandler, u as createBashToolDescription, v as createObservabilityHooks, w as createReadSkillHandler, x as createReadSkillTool, y as createSession, z as createTaskCreateHandler, C as createTaskGetHandler, E as createTaskListHandler, H as createTaskUpdateHandler, I as createToolRouter, J as defineSubagent, K as defineSubagentWorkflow, L as defineTool, M as defineWorkflow, N as editTool, P as filesWithMimeType, Q as formatVirtualFileTree, U as getShortId, V as getThreadDedupKey, X as getThreadListKey, Y as getThreadMetaKey, _ as getThreadStateKey, $ as globTool, a0 as grepTool, a1 as hasDirectory, a2 as hasFileWithMimeType, a3 as hasNoOtherToolCalls, a4 as parseSkillFile, a5 as proxyRunAgent, a6 as proxyVirtualFsOps, a7 as readFileTool, a8 as taskCreateTool, a9 as taskGetTool, aa as taskListTool, ab as taskUpdateTool, ac as writeFileTool } from './workflow-B1TOcHbt.js';
3
- import { R as RouterContext, e as ToolResultConfig, d as ActivityToolHandler, J as JsonValue, c as ToolHandlerResponse, B as BaseAgentState, f as RunAgentConfig, g as SkillProvider, h as SkillMetadata, i as Skill, F as FileEntryMetadata, j as FileResolver, V as VirtualFsContext, k as TreeMutation, l as PrefixedVirtualFsOps } from './types-CwN6_tAL.js';
4
- export { m as AgentConfig, n as AgentFile, A as AgentResponse, o as AgentState, p as AgentStateManager, q as AgentStatus, r as AppendToolResultFn, s as FileEntry, H as Hooks, I as InferToolResults, t as JsonPrimitive, u as JsonSerializable, a as ModelInvoker, M as ModelInvokerConfig, v as ParsedToolCall, w as ParsedToolCallUnion, P as PersistedThreadState, x as PostHumanMessageAppendHook, y as PostHumanMessageAppendHookContext, z as PostToolUseFailureHook, C as PostToolUseFailureHookContext, D as PostToolUseFailureHookResult, E as PostToolUseHook, G as PostToolUseHookContext, K as PreHumanMessageAppendHook, L as PreHumanMessageAppendHookContext, N as PreToolUseHook, O as PreToolUseHookContext, Q as PreToolUseHookResult, b as PrefixedThreadOps, U as ProcessToolCallsContext, W as ProcessToolCallsResult, X as RawToolCall, Y as RewindSignal, Z as RunAgentActivity, _ as SandboxInit, $ as SandboxShutdown, S as ScopedPrefix, a0 as SerializableToolDefinition, a1 as SessionConfig, a2 as SessionEndHook, a3 as SessionEndHookContext, a4 as SessionExitReason, a5 as SessionRequiredCaps, a6 as SessionResult, a7 as SessionStartHook, a8 as SessionStartHookContext, a9 as SubagentChildWorkflowOptions, aa as SubagentConfig, ab as SubagentContinuationCaps, ac as SubagentDefinition, ad as SubagentFnResult, ae as SubagentHandlerResponse, af as SubagentHooks, ag as SubagentSandboxConfig, ah as SubagentSandboxShutdown, ai as SubagentSessionInput, aj as SubagentWorkflow, ak as SubagentWorkflowInput, al as TaskStatus, am as ThreadInit, T as ThreadOps, an as TokenUsage, ao as ToolArgs, ap as ToolCallResult, aq as ToolCallResultUnion, ar as ToolDefinition, as as ToolHandler, at as ToolHooks, au as ToolMap, av as ToolNames, aw as ToolResult, ax as ToolRouter, ay as ToolRouterHooks, az as ToolWithHandler, aA as VirtualFileSystem, aB as VirtualFileTree, aC as VirtualFsOps, aD as VirtualFsState, aE as WorkflowTask, aF as ZeitlichSession, aG as isTerminalStatus } from './types-CwN6_tAL.js';
1
+ import { B as BashArgs, F as FileEditArgs, a as FileMultiEditArgs, G as GlobArgs, b as FileReadArgs, c as FileWriteArgs } from './workflow-Cdw3-RNB.js';
2
+ export { A as AskUserQuestionArgs, D as DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, d as FileTreeAccessor, e as GrepArgs, O as ObservabilityHooks, R as ReadSkillArgs, S as SessionEndedEvent, f as SessionStartedEvent, g as SubagentArgs, T as THREAD_TTL_SECONDS, h as TaskCreateArgs, i as TaskGetArgs, j as TaskListArgs, k as TaskUpdateArgs, l as ToolExecutedEvent, m as TurnCompletedEvent, W as WorkflowConfig, n as WorkflowInput, o as WorkflowSessionInput, Z as ZeitlichObservabilitySinks, p as applyVirtualTreeMutations, q as askUserQuestionTool, r as bashTool, s as composeHooks, t as createAgentStateManager, u as createAskUserQuestionHandler, v as createBashToolDescription, w as createObservabilityHooks, x as createReadSkillHandler, y as createReadSkillTool, z as createSession, C as createTaskCreateHandler, E as createTaskGetHandler, H as createTaskListHandler, I as createTaskUpdateHandler, J as createToolRouter, K as defineSubagent, L as defineSubagentWorkflow, M as defineTool, N as defineWorkflow, P as editTool, Q as filesWithMimeType, U as formatVirtualFileTree, V as getShortId, X as getThreadDedupKey, Y as getThreadListKey, _ as getThreadMetaKey, $ as getThreadStateKey, a0 as globTool, a1 as grepTool, a2 as hasDirectory, a3 as hasFileWithMimeType, a4 as hasNoOtherToolCalls, a5 as multiEditTool, a6 as parseSkillFile, a7 as proxyRunAgent, a8 as proxyVirtualFsOps, a9 as readFileTool, aa as taskCreateTool, ab as taskGetTool, ac as taskListTool, ad as taskUpdateTool, ae as writeFileTool } from './workflow-Cdw3-RNB.js';
3
+ import { R as RouterContext, e as ToolResultConfig, d as ActivityToolHandler, J as JsonValue, c as ToolHandlerResponse, B as BaseAgentState, f as RunAgentConfig, g as SkillProvider, h as SkillMetadata, i as Skill, F as FileEntryMetadata, j as FileResolver, V as VirtualFsContext, k as TreeMutation, l as PrefixedVirtualFsOps } from './types-qQVZfhoT.js';
4
+ export { m as AgentConfig, n as AgentFile, A as AgentResponse, o as AgentState, p as AgentStateManager, q as AgentStatus, r as AppendToolResultFn, s as FileEntry, H as Hooks, I as InferToolResults, t as JsonPrimitive, u as JsonSerializable, a as ModelInvoker, M as ModelInvokerConfig, v as ParsedToolCall, w as ParsedToolCallUnion, P as PersistedThreadState, x as PostHumanMessageAppendHook, y as PostHumanMessageAppendHookContext, z as PostToolUseFailureHook, C as PostToolUseFailureHookContext, D as PostToolUseFailureHookResult, E as PostToolUseHook, G as PostToolUseHookContext, K as PreHumanMessageAppendHook, L as PreHumanMessageAppendHookContext, N as PreToolUseHook, O as PreToolUseHookContext, Q as PreToolUseHookResult, b as PrefixedThreadOps, U as ProcessToolCallsContext, W as ProcessToolCallsResult, X as RawToolCall, Y as RewindSignal, Z as RunAgentActivity, _ as SandboxInit, $ as SandboxShutdown, S as ScopedPrefix, a0 as SerializableToolDefinition, a1 as SessionConfig, a2 as SessionEndHook, a3 as SessionEndHookContext, a4 as SessionExitReason, a5 as SessionRequiredCaps, a6 as SessionResult, a7 as SessionStartHook, a8 as SessionStartHookContext, a9 as SubagentChildWorkflowOptions, aa as SubagentConfig, ab as SubagentContinuationCaps, ac as SubagentDefinition, ad as SubagentFnResult, ae as SubagentHandlerResponse, af as SubagentHooks, ag as SubagentSandboxConfig, ah as SubagentSandboxShutdown, ai as SubagentSessionInput, aj as SubagentWorkflow, ak as SubagentWorkflowInput, al as TaskStatus, am as ThreadInit, T as ThreadOps, an as TokenUsage, ao as ToolArgs, ap as ToolCallResult, aq as ToolCallResultUnion, ar as ToolDefinition, as as ToolHandler, at as ToolHooks, au as ToolMap, av as ToolNames, aw as ToolResult, ax as ToolRouter, ay as ToolRouterHooks, az as ToolWithHandler, aA as VirtualFileSystem, aB as VirtualFileTree, aC as VirtualFsOps, aD as VirtualFsState, aE as WorkflowTask, aF as ZeitlichSession, aG as isTerminalStatus } from './types-qQVZfhoT.js';
5
5
  import { b as Sandbox, c as SandboxFileSystem, a as SandboxCreateOptions, h as SandboxCapability, d as SandboxProvider, g as SandboxSnapshot, P as PrefixedSandboxOps, F as FileStat, D as DirentEntry, E as ExecResult } from './types-CJ7tCdl6.js';
6
6
  export { i as ExecOptions, e as SandboxCapabilities, f as SandboxCreateResult, j as SandboxNotFoundError, k as SandboxNotSupportedError, S as SandboxOps } from './types-CJ7tCdl6.js';
7
7
  import { WorkflowClient } from '@temporalio/client';
8
- import { a as ThreadManagerConfig, B as BaseThreadManager } from './types-L5bvbF-n.js';
9
- export { P as ProviderThreadManager } from './types-L5bvbF-n.js';
10
- import { C as ColdThreadStore, T as ThreadSnapshot } from './cold-store-CFHwemBJ.js';
11
- export { S as S3ColdStoreConfig, a as S3LikeClient, c as createS3ColdStore } from './cold-store-CFHwemBJ.js';
8
+ import { a as ThreadManagerConfig, B as BaseThreadManager } from './types-CtdOquo3.js';
9
+ export { P as ProviderThreadManager } from './types-CtdOquo3.js';
10
+ import { C as ColdThreadStore, T as ThreadSnapshot } from './cold-store-BDgJpwLI.js';
11
+ export { S as S3ColdStoreConfig, a as S3LikeClient, c as createS3ColdStore } from './cold-store-BDgJpwLI.js';
12
12
  import Redis from 'ioredis';
13
13
  import 'zod';
14
14
  import '@temporalio/common';
15
15
  import '@temporalio/workflow';
16
16
  import '@temporalio/common/lib/interfaces';
17
+ import '@aws-sdk/client-s3';
17
18
 
18
19
  /**
19
20
  * Wraps a tool handler to automatically append its result directly to the
@@ -646,6 +647,16 @@ interface EditResult {
646
647
  path: string;
647
648
  success: boolean;
648
649
  replacements: number;
650
+ hunks?: EditHunk[];
651
+ }
652
+ interface EditHunk {
653
+ editIndex: number;
654
+ oldStartLine: number;
655
+ oldEndLine: number;
656
+ newStartLine: number;
657
+ newEndLine: number;
658
+ oldLines: string[];
659
+ newLines: string[];
649
660
  }
650
661
  /**
651
662
  * Edit tool handler — performs string replacements in sandbox files.
@@ -654,6 +665,7 @@ interface EditResult {
654
665
  * sandbox automatically.
655
666
  */
656
667
  declare const editHandler: ActivityToolHandler<FileEditArgs, EditResult, SandboxContext>;
668
+ declare const multiEditHandler: ActivityToolHandler<FileMultiEditArgs, EditResult, SandboxContext>;
657
669
 
658
670
  interface GlobResult {
659
671
  files: string[];
@@ -724,4 +736,4 @@ declare const toTree: (fs: SandboxFileSystem, opts?: {
724
736
  sort?: boolean;
725
737
  }) => Promise<string>;
726
738
 
727
- export { ActivityToolHandler, type AgentStateContext, type ApplySnapshotConfig, BaseAgentState, BaseThreadManager, BashArgs, type ClearHotTierConfig, ColdThreadStore, type EncodeSnapshotConfig, ExecResult, FileEditArgs, FileEntryMetadata, FileReadArgs, FileResolver, FileSystemSkillProvider, FileWriteArgs, type FlushOptions, GlobArgs, JsonValue, NodeFsSandboxFileSystem, type PreCreateHookResult, PrefixedSandboxOps, PrefixedVirtualFsOps, RouterContext, RunAgentConfig, Sandbox, SandboxCapability, type SandboxContext, SandboxCreateOptions, DirentEntry as SandboxDirentEntry, FileStat as SandboxFileStat, SandboxFileSystem, SandboxManager, type SandboxManagerHooks, SandboxProvider, SandboxSnapshot, Skill, SkillMetadata, SkillProvider, ThreadManagerConfig, ThreadSnapshot, type TieredThreadManager, type TieredThreadManagerConfig, ToolHandlerResponse, ToolResultConfig, TreeMutation, VirtualFsContext, type WithSandboxOptions, applySnapshot, bashHandler, clearHotTier, createRunAgentActivity, createThreadManager, createTieredThreadManager, createVirtualFsActivities, editHandler, encodeSnapshot, getActivityContext, globHandler, queryParentWorkflowState, readFileHandler, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler };
739
+ export { ActivityToolHandler, type AgentStateContext, type ApplySnapshotConfig, BaseAgentState, BaseThreadManager, BashArgs, type ClearHotTierConfig, ColdThreadStore, type EncodeSnapshotConfig, ExecResult, FileEditArgs, FileEntryMetadata, FileMultiEditArgs, FileReadArgs, FileResolver, FileSystemSkillProvider, FileWriteArgs, type FlushOptions, GlobArgs, JsonValue, NodeFsSandboxFileSystem, type PreCreateHookResult, PrefixedSandboxOps, PrefixedVirtualFsOps, RouterContext, RunAgentConfig, Sandbox, SandboxCapability, type SandboxContext, SandboxCreateOptions, DirentEntry as SandboxDirentEntry, FileStat as SandboxFileStat, SandboxFileSystem, SandboxManager, type SandboxManagerHooks, SandboxProvider, SandboxSnapshot, Skill, SkillMetadata, SkillProvider, ThreadManagerConfig, ThreadSnapshot, type TieredThreadManager, type TieredThreadManagerConfig, ToolHandlerResponse, ToolResultConfig, TreeMutation, VirtualFsContext, type WithSandboxOptions, applySnapshot, bashHandler, clearHotTier, createRunAgentActivity, createThreadManager, createTieredThreadManager, createVirtualFsActivities, editHandler, encodeSnapshot, getActivityContext, globHandler, multiEditHandler, queryParentWorkflowState, readFileHandler, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler };
package/dist/index.js CHANGED
@@ -3,8 +3,10 @@ import z14, { z } from 'zod';
3
3
  import { randomUUID, randomFillSync } from 'crypto';
4
4
  import { ApplicationFailure as ApplicationFailure$1 } from '@temporalio/common';
5
5
  import { join, resolve, posix } from 'path';
6
- import { gzipSync, gunzipSync } from 'zlib';
7
- import { DeleteObjectCommand, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
6
+ import { gzip, gunzip } from 'zlib';
7
+ import { promisify } from 'util';
8
+ import { DeleteObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
9
+ import { Upload } from '@aws-sdk/lib-storage';
8
10
  import { Context } from '@temporalio/activity';
9
11
  import { promises } from 'fs';
10
12
 
@@ -566,7 +568,8 @@ function createSubagentHandler(subagents) {
566
568
  }
567
569
  const threadMode = config.thread ?? "new";
568
570
  const allowsContinuation = threadMode !== "new";
569
- const continuationThreadId = args.threadId && allowsContinuation ? args.threadId : void 0;
571
+ const newThreadSource = config.newThreadSource ?? "new";
572
+ const continuationThreadId = !allowsContinuation ? void 0 : args.threadId ?? (newThreadSource === "from-parent" ? context.threadId : void 0);
570
573
  let thread;
571
574
  if (continuationThreadId) {
572
575
  thread = {
@@ -2214,6 +2217,13 @@ IMPORTANT:
2214
2217
  }),
2215
2218
  strict: true
2216
2219
  };
2220
+ var textEditSchema = z.object({
2221
+ old_string: z.string().describe("The exact text to replace"),
2222
+ new_string: z.string().describe("The text to replace it with"),
2223
+ replace_all: z.boolean().optional().describe(
2224
+ "If true, replace all occurrences of old_string for this edit (default: false)"
2225
+ )
2226
+ });
2217
2227
  var editTool = {
2218
2228
  name: "FileEdit",
2219
2229
  description: `Edit specific sections of a file by replacing text.
@@ -2242,6 +2252,27 @@ IMPORTANT:
2242
2252
  }),
2243
2253
  strict: true
2244
2254
  };
2255
+ var multiEditTool = {
2256
+ name: "FileMultiEdit",
2257
+ description: `Apply multiple exact text replacements to one file in order.
2258
+
2259
+ Usage:
2260
+ - Use this when a task needs several related edits in the same file
2261
+ - Each edit is applied to the file content produced by the prior edit
2262
+ - The operation is atomic: if any edit fails, the file is left unchanged
2263
+
2264
+ IMPORTANT:
2265
+ - You must read the file first (in this session) before editing it
2266
+ - Each old_string must match exactly (whitespace-sensitive)
2267
+ - Each old_string must be unique unless that edit uses replace_all: true
2268
+ - old_string and new_string must be different for every edit
2269
+ `,
2270
+ schema: z.object({
2271
+ file_path: z.string().describe("The absolute virtual path to the file to modify"),
2272
+ edits: z.array(textEditSchema).min(1).describe("Exact replacements to apply sequentially to the file")
2273
+ }),
2274
+ strict: true
2275
+ };
2245
2276
  var taskCreateTool = {
2246
2277
  name: "TaskCreate",
2247
2278
  description: `Use this tool to create a structured task list. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
@@ -2312,7 +2343,7 @@ function createTaskCreateHandler(stateManager) {
2312
2343
  };
2313
2344
  stateManager.setTask(task);
2314
2345
  return {
2315
- toolResponse: JSON.stringify(task, null, 2),
2346
+ toolResponse: `Task ${task.id} created`,
2316
2347
  data: task
2317
2348
  };
2318
2349
  };
@@ -2411,7 +2442,7 @@ function createTaskUpdateHandler(stateManager) {
2411
2442
  }
2412
2443
  stateManager.setTask(task);
2413
2444
  return {
2414
- toolResponse: JSON.stringify(task, null, 2),
2445
+ toolResponse: `Task ${task.id} updated`,
2415
2446
  data: task
2416
2447
  };
2417
2448
  };
@@ -2743,6 +2774,44 @@ function createThreadManager(config) {
2743
2774
  }
2744
2775
  };
2745
2776
  }
2777
+ function getActivityContext() {
2778
+ try {
2779
+ const ctx = Context.current();
2780
+ return { heartbeat: () => ctx.heartbeat(), signal: ctx.cancellationSignal };
2781
+ } catch {
2782
+ return {};
2783
+ }
2784
+ }
2785
+ async function queryParentWorkflowState(client) {
2786
+ const { workflowExecution } = Context.current().info;
2787
+ if (!workflowExecution) {
2788
+ throw new Error("No workflow execution found");
2789
+ }
2790
+ const handle = client.getHandle(
2791
+ workflowExecution.workflowId,
2792
+ workflowExecution.runId
2793
+ );
2794
+ return handle.query("getAgentState");
2795
+ }
2796
+ function createRunAgentActivity(client, handler, scope) {
2797
+ const name = `run${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;
2798
+ return {
2799
+ [name]: async (config) => {
2800
+ const state = await queryParentWorkflowState(client);
2801
+ return handler({ ...config, state });
2802
+ }
2803
+ };
2804
+ }
2805
+ function withParentWorkflowState(client, handler) {
2806
+ return async (args, context) => {
2807
+ const state = await queryParentWorkflowState(client);
2808
+ return handler(args, { ...context, state });
2809
+ };
2810
+ }
2811
+
2812
+ // src/lib/thread/cold-store.ts
2813
+ var gzipAsync = promisify(gzip);
2814
+ var gunzipAsync = promisify(gunzip);
2746
2815
  function joinKey(parts) {
2747
2816
  return parts.map((p) => p.replace(/^\/+|\/+$/g, "")).filter((p) => p.length > 0).join("/");
2748
2817
  }
@@ -2754,9 +2823,17 @@ function buildKey(prefix, threadKey, threadId, gzip) {
2754
2823
  `${threadId}.${ext}`
2755
2824
  ]);
2756
2825
  }
2757
- async function streamToBuffer(body) {
2826
+ async function streamToBuffer(body, onChunk) {
2758
2827
  if (body == null) return Buffer.alloc(0);
2759
2828
  if (body instanceof Uint8Array) return Buffer.from(body);
2829
+ if (typeof body[Symbol.asyncIterator] === "function") {
2830
+ const chunks = [];
2831
+ for await (const chunk of body) {
2832
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
2833
+ onChunk?.();
2834
+ }
2835
+ return Buffer.concat(chunks);
2836
+ }
2760
2837
  if (typeof body.transformToByteArray === "function") {
2761
2838
  const bytes = await body.transformToByteArray();
2762
2839
  return Buffer.from(bytes);
@@ -2765,11 +2842,7 @@ async function streamToBuffer(body) {
2765
2842
  const ab = await body.arrayBuffer();
2766
2843
  return Buffer.from(ab);
2767
2844
  }
2768
- const chunks = [];
2769
- for await (const chunk of body) {
2770
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
2771
- }
2772
- return Buffer.concat(chunks);
2845
+ return Buffer.alloc(0);
2773
2846
  }
2774
2847
  function createS3ColdStore(config) {
2775
2848
  const { s3, bucket, prefix, gzip = true } = config;
@@ -2781,8 +2854,9 @@ function createS3ColdStore(config) {
2781
2854
  const resp = await s3.send(
2782
2855
  new GetObjectCommand({ Bucket: bucket, Key })
2783
2856
  );
2784
- const buf = await streamToBuffer(resp.Body);
2785
- const json = gzip ? gunzipSync(buf).toString("utf8") : buf.toString("utf8");
2857
+ const { heartbeat } = getActivityContext();
2858
+ const buf = await streamToBuffer(resp.Body, heartbeat);
2859
+ const json = gzip ? (await gunzipAsync(buf)).toString("utf8") : buf.toString("utf8");
2786
2860
  return JSON.parse(json);
2787
2861
  } catch (err) {
2788
2862
  if (isNotFound(err)) return null;
@@ -2792,15 +2866,14 @@ function createS3ColdStore(config) {
2792
2866
  async write(threadKey, threadId, snapshot) {
2793
2867
  const Key = buildKey(prefix, threadKey, threadId, gzip);
2794
2868
  const json = JSON.stringify(snapshot);
2795
- const body = gzip ? gzipSync(Buffer.from(json, "utf8")) : json;
2796
- await s3.send(
2797
- new PutObjectCommand({
2798
- Bucket: bucket,
2799
- Key,
2800
- Body: body,
2801
- ContentType: contentType
2802
- })
2803
- );
2869
+ const body = gzip ? await gzipAsync(Buffer.from(json, "utf8")) : json;
2870
+ const upload = new Upload({
2871
+ client: s3,
2872
+ params: { Bucket: bucket, Key, Body: body, ContentType: contentType }
2873
+ });
2874
+ const { heartbeat } = getActivityContext();
2875
+ if (heartbeat) upload.on("httpUploadProgress", heartbeat);
2876
+ await upload.done();
2804
2877
  },
2805
2878
  async delete(threadKey, threadId) {
2806
2879
  const Key = buildKey(prefix, threadKey, threadId, gzip);
@@ -2928,40 +3001,6 @@ function createTieredThreadManager(config) {
2928
3001
  }
2929
3002
  });
2930
3003
  }
2931
- function getActivityContext() {
2932
- try {
2933
- const ctx = Context.current();
2934
- return { heartbeat: () => ctx.heartbeat(), signal: ctx.cancellationSignal };
2935
- } catch {
2936
- return {};
2937
- }
2938
- }
2939
- async function queryParentWorkflowState(client) {
2940
- const { workflowExecution } = Context.current().info;
2941
- if (!workflowExecution) {
2942
- throw new Error("No workflow execution found");
2943
- }
2944
- const handle = client.getHandle(
2945
- workflowExecution.workflowId,
2946
- workflowExecution.runId
2947
- );
2948
- return handle.query("getAgentState");
2949
- }
2950
- function createRunAgentActivity(client, handler, scope) {
2951
- const name = `run${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;
2952
- return {
2953
- [name]: async (config) => {
2954
- const state = await queryParentWorkflowState(client);
2955
- return handler({ ...config, state });
2956
- }
2957
- };
2958
- }
2959
- function withParentWorkflowState(client, handler) {
2960
- return async (args, context) => {
2961
- const state = await queryParentWorkflowState(client);
2962
- return handler(args, { ...context, state });
2963
- };
2964
- }
2965
3004
 
2966
3005
  // src/lib/sandbox/manager.ts
2967
3006
  var CAP_METHOD_TO_CAPABILITY = [
@@ -3633,57 +3672,190 @@ ${result.stderr}`,
3633
3672
  };
3634
3673
 
3635
3674
  // src/tools/edit/handler.ts
3636
- function escapeRegExp(str) {
3637
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3675
+ function splitLines(text) {
3676
+ if (text.length === 0) return [];
3677
+ return text.replace(/\r\n/g, "\n").split("\n");
3678
+ }
3679
+ function lineNumberAt(content, index) {
3680
+ let line = 1;
3681
+ for (let i = 0; i < index; i++) {
3682
+ if (content.charCodeAt(i) === 10) line++;
3683
+ }
3684
+ return line;
3685
+ }
3686
+ function lineEnd(startLine, lines) {
3687
+ return lines.length === 0 ? startLine : startLine + lines.length - 1;
3688
+ }
3689
+ function indicesOf(content, needle) {
3690
+ const indices = [];
3691
+ let cursor = 0;
3692
+ while (cursor <= content.length) {
3693
+ const index = content.indexOf(needle, cursor);
3694
+ if (index === -1) break;
3695
+ indices.push(index);
3696
+ cursor = index + needle.length;
3697
+ }
3698
+ return indices;
3699
+ }
3700
+ function makeHunk(editIndex, beforeContent, replacementIndex, oldString, newString) {
3701
+ const oldStartLine = lineNumberAt(beforeContent, replacementIndex);
3702
+ const oldLines = splitLines(oldString);
3703
+ const newLines = splitLines(newString);
3704
+ return {
3705
+ editIndex,
3706
+ oldStartLine,
3707
+ oldEndLine: lineEnd(oldStartLine, oldLines),
3708
+ newStartLine: oldStartLine,
3709
+ newEndLine: lineEnd(oldStartLine, newLines),
3710
+ oldLines,
3711
+ newLines
3712
+ };
3713
+ }
3714
+ function applyOneEdit(content, edit, editIndex) {
3715
+ const { old_string, new_string, replace_all = false } = edit;
3716
+ if (old_string.length === 0) {
3717
+ return {
3718
+ ok: false,
3719
+ editIndex,
3720
+ message: `Error: old_string for edit ${editIndex} must not be empty.`
3721
+ };
3722
+ }
3723
+ if (old_string === new_string) {
3724
+ return {
3725
+ ok: false,
3726
+ editIndex,
3727
+ message: `Error: old_string and new_string must be different for edit ${editIndex}.`
3728
+ };
3729
+ }
3730
+ const matches = indicesOf(content, old_string);
3731
+ if (matches.length === 0) {
3732
+ return {
3733
+ ok: false,
3734
+ editIndex,
3735
+ message: `Error: Could not find old_string for edit ${editIndex}. Make sure it matches exactly (whitespace-sensitive).`
3736
+ };
3737
+ }
3738
+ if (!replace_all && matches.length > 1) {
3739
+ return {
3740
+ ok: false,
3741
+ editIndex,
3742
+ message: `Error: old_string for edit ${editIndex} appears ${matches.length} times. Provide more context to make it unique, or use replace_all: true for that edit.`
3743
+ };
3744
+ }
3745
+ if (replace_all) {
3746
+ const hunks = matches.map(
3747
+ (index2) => makeHunk(editIndex, content, index2, old_string, new_string)
3748
+ );
3749
+ return {
3750
+ ok: true,
3751
+ content: content.split(old_string).join(new_string),
3752
+ replacements: matches.length,
3753
+ hunks
3754
+ };
3755
+ }
3756
+ const index = matches[0];
3757
+ if (index === void 0) {
3758
+ return {
3759
+ ok: false,
3760
+ editIndex,
3761
+ message: `Error: Could not find old_string for edit ${editIndex}.`
3762
+ };
3763
+ }
3764
+ return {
3765
+ ok: true,
3766
+ content: content.slice(0, index) + new_string + content.slice(index + old_string.length),
3767
+ replacements: 1,
3768
+ hunks: [makeHunk(editIndex, content, index, old_string, new_string)]
3769
+ };
3770
+ }
3771
+ function applyEditPlan(content, edits) {
3772
+ if (edits.length === 0) {
3773
+ return {
3774
+ ok: false,
3775
+ message: "Error: edits must contain at least one edit."
3776
+ };
3777
+ }
3778
+ let current = content;
3779
+ let replacements = 0;
3780
+ const hunks = [];
3781
+ for (const [index, edit] of edits.entries()) {
3782
+ const result = applyOneEdit(current, edit, index);
3783
+ if (!result.ok) return result;
3784
+ current = result.content;
3785
+ replacements += result.replacements;
3786
+ hunks.push(...result.hunks);
3787
+ }
3788
+ return { ok: true, content: current, replacements, hunks };
3789
+ }
3790
+ function editFailureResult(filePath, message) {
3791
+ return {
3792
+ toolResponse: message,
3793
+ data: { path: filePath, success: false, replacements: 0 }
3794
+ };
3638
3795
  }
3639
3796
  var editHandler = async (args, { sandbox }) => {
3640
3797
  const { fs } = sandbox;
3641
3798
  const { file_path, old_string, new_string, replace_all = false } = args;
3642
- if (old_string === new_string) {
3799
+ try {
3800
+ const exists = await fs.exists(file_path);
3801
+ if (!exists) {
3802
+ return editFailureResult(
3803
+ file_path,
3804
+ `Error: File "${file_path}" does not exist.`
3805
+ );
3806
+ }
3807
+ const content = await fs.readFile(file_path);
3808
+ const result = applyEditPlan(content, [
3809
+ { old_string, new_string, replace_all }
3810
+ ]);
3811
+ if (!result.ok) {
3812
+ return editFailureResult(file_path, result.message);
3813
+ }
3814
+ await fs.writeFile(file_path, result.content);
3815
+ const summary = replace_all ? `Replaced ${result.replacements} occurrence(s)` : `Replaced 1 occurrence`;
3816
+ return {
3817
+ toolResponse: `${summary} in ${file_path}`,
3818
+ data: {
3819
+ path: file_path,
3820
+ success: true,
3821
+ replacements: result.replacements,
3822
+ hunks: result.hunks
3823
+ }
3824
+ };
3825
+ } catch (error) {
3826
+ const message = error instanceof Error ? error.message : "Unknown error";
3643
3827
  return {
3644
- toolResponse: `Error: old_string and new_string must be different.`,
3828
+ toolResponse: `Error editing file "${file_path}": ${message}`,
3645
3829
  data: { path: file_path, success: false, replacements: 0 }
3646
3830
  };
3647
3831
  }
3832
+ };
3833
+ var multiEditHandler = async (args, { sandbox }) => {
3834
+ const { fs } = sandbox;
3835
+ const { file_path, edits } = args;
3648
3836
  try {
3649
3837
  const exists = await fs.exists(file_path);
3650
3838
  if (!exists) {
3651
- return {
3652
- toolResponse: `Error: File "${file_path}" does not exist.`,
3653
- data: { path: file_path, success: false, replacements: 0 }
3654
- };
3839
+ return editFailureResult(
3840
+ file_path,
3841
+ `Error: File "${file_path}" does not exist.`
3842
+ );
3655
3843
  }
3656
3844
  const content = await fs.readFile(file_path);
3657
- if (!content.includes(old_string)) {
3658
- return {
3659
- toolResponse: `Error: Could not find the specified text in "${file_path}". Make sure old_string matches exactly (whitespace-sensitive).`,
3660
- data: { path: file_path, success: false, replacements: 0 }
3661
- };
3845
+ const result = applyEditPlan(content, edits);
3846
+ if (!result.ok) {
3847
+ const suffix = result.editIndex === void 0 ? "" : ` in ${file_path}`;
3848
+ return editFailureResult(file_path, `${result.message}${suffix}`);
3662
3849
  }
3663
- const escapedOldString = escapeRegExp(old_string);
3664
- const globalRegex = new RegExp(escapedOldString, "g");
3665
- const occurrences = (content.match(globalRegex) || []).length;
3666
- if (!replace_all && occurrences > 1) {
3667
- return {
3668
- toolResponse: `Error: old_string appears ${occurrences} times in "${file_path}". Either provide more context to make it unique, or use replace_all: true.`,
3669
- data: { path: file_path, success: false, replacements: 0 }
3670
- };
3671
- }
3672
- let newContent;
3673
- let replacements;
3674
- if (replace_all) {
3675
- newContent = content.split(old_string).join(new_string);
3676
- replacements = occurrences;
3677
- } else {
3678
- const index = content.indexOf(old_string);
3679
- newContent = content.slice(0, index) + new_string + content.slice(index + old_string.length);
3680
- replacements = 1;
3681
- }
3682
- await fs.writeFile(file_path, newContent);
3683
- const summary = replace_all ? `Replaced ${replacements} occurrence(s)` : `Replaced 1 occurrence`;
3850
+ await fs.writeFile(file_path, result.content);
3684
3851
  return {
3685
- toolResponse: `${summary} in ${file_path}`,
3686
- data: { path: file_path, success: true, replacements }
3852
+ toolResponse: `Applied ${edits.length} edit(s), ${result.replacements} replacement(s) in ${file_path}`,
3853
+ data: {
3854
+ path: file_path,
3855
+ success: true,
3856
+ replacements: result.replacements,
3857
+ hunks: result.hunks
3858
+ }
3687
3859
  };
3688
3860
  } catch (error) {
3689
3861
  const message = error instanceof Error ? error.message : "Unknown error";
@@ -3863,6 +4035,6 @@ var toTree = async (fs, opts = {}) => {
3863
4035
  return base + subtree;
3864
4036
  };
3865
4037
 
3866
- export { DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, FileSystemSkillProvider, NodeFsSandboxFileSystem, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, THREAD_TTL_SECONDS, VirtualFileSystem, applySnapshot, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, clearHotTier, composeHooks, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createObservabilityHooks, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createS3ColdStore, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createTieredThreadManager, createToolRouter, createVirtualFsActivities, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, encodeSnapshot, filesWithMimeType, formatVirtualFileTree, getActivityContext, getShortId, getThreadDedupKey, getThreadListKey, getThreadMetaKey, getThreadStateKey, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyRunAgent, proxyVirtualFsOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler, writeFileTool };
4038
+ export { DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT, FileSystemSkillProvider, NodeFsSandboxFileSystem, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, THREAD_TTL_SECONDS, VirtualFileSystem, applySnapshot, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, clearHotTier, composeHooks, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createObservabilityHooks, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createS3ColdStore, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createTieredThreadManager, createToolRouter, createVirtualFsActivities, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, encodeSnapshot, filesWithMimeType, formatVirtualFileTree, getActivityContext, getShortId, getThreadDedupKey, getThreadListKey, getThreadMetaKey, getThreadStateKey, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, multiEditHandler, multiEditTool, parseSkillFile, proxyRunAgent, proxyVirtualFsOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler, writeFileTool };
3867
4039
  //# sourceMappingURL=index.js.map
3868
4040
  //# sourceMappingURL=index.js.map