@librechat/agents 3.1.77-dev.1 → 3.1.78-dev.0

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 (188) hide show
  1. package/dist/cjs/common/enum.cjs +54 -0
  2. package/dist/cjs/common/enum.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +148 -4
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +291 -0
  6. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -0
  7. package/dist/cjs/llm/openai/index.cjs +317 -1
  8. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  9. package/dist/cjs/main.cjs +90 -0
  10. package/dist/cjs/main.cjs.map +1 -1
  11. package/dist/cjs/messages/anthropicToolCache.cjs +102 -0
  12. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -0
  13. package/dist/cjs/messages/prune.cjs +27 -0
  14. package/dist/cjs/messages/prune.cjs.map +1 -1
  15. package/dist/cjs/messages/recency.cjs +99 -0
  16. package/dist/cjs/messages/recency.cjs.map +1 -0
  17. package/dist/cjs/run.cjs +30 -0
  18. package/dist/cjs/run.cjs.map +1 -1
  19. package/dist/cjs/summarization/node.cjs +100 -6
  20. package/dist/cjs/summarization/node.cjs.map +1 -1
  21. package/dist/cjs/tools/ToolNode.cjs +635 -23
  22. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  23. package/dist/cjs/tools/local/CompileCheckTool.cjs +227 -0
  24. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -0
  25. package/dist/cjs/tools/local/FileCheckpointer.cjs +90 -0
  26. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -0
  27. package/dist/cjs/tools/local/LocalCodingTools.cjs +1098 -0
  28. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -0
  29. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +1042 -0
  30. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -0
  31. package/dist/cjs/tools/local/LocalExecutionTools.cjs +122 -0
  32. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -0
  33. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +453 -0
  34. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -0
  35. package/dist/cjs/tools/local/attachments.cjs +183 -0
  36. package/dist/cjs/tools/local/attachments.cjs.map +1 -0
  37. package/dist/cjs/tools/local/bashAst.cjs +129 -0
  38. package/dist/cjs/tools/local/bashAst.cjs.map +1 -0
  39. package/dist/cjs/tools/local/editStrategies.cjs +188 -0
  40. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -0
  41. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +141 -0
  42. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -0
  43. package/dist/cjs/tools/local/syntaxCheck.cjs +182 -0
  44. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -0
  45. package/dist/cjs/tools/local/textEncoding.cjs +30 -0
  46. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -0
  47. package/dist/cjs/tools/local/workspaceFS.cjs +51 -0
  48. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -0
  49. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -0
  50. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  51. package/dist/esm/common/enum.mjs +53 -1
  52. package/dist/esm/common/enum.mjs.map +1 -1
  53. package/dist/esm/graphs/Graph.mjs +149 -5
  54. package/dist/esm/graphs/Graph.mjs.map +1 -1
  55. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +289 -0
  56. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -0
  57. package/dist/esm/llm/openai/index.mjs +318 -2
  58. package/dist/esm/llm/openai/index.mjs.map +1 -1
  59. package/dist/esm/main.mjs +17 -2
  60. package/dist/esm/main.mjs.map +1 -1
  61. package/dist/esm/messages/anthropicToolCache.mjs +99 -0
  62. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -0
  63. package/dist/esm/messages/prune.mjs +26 -1
  64. package/dist/esm/messages/prune.mjs.map +1 -1
  65. package/dist/esm/messages/recency.mjs +97 -0
  66. package/dist/esm/messages/recency.mjs.map +1 -0
  67. package/dist/esm/run.mjs +30 -0
  68. package/dist/esm/run.mjs.map +1 -1
  69. package/dist/esm/summarization/node.mjs +100 -6
  70. package/dist/esm/summarization/node.mjs.map +1 -1
  71. package/dist/esm/tools/ToolNode.mjs +635 -23
  72. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  73. package/dist/esm/tools/local/CompileCheckTool.mjs +223 -0
  74. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -0
  75. package/dist/esm/tools/local/FileCheckpointer.mjs +87 -0
  76. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -0
  77. package/dist/esm/tools/local/LocalCodingTools.mjs +1075 -0
  78. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -0
  79. package/dist/esm/tools/local/LocalExecutionEngine.mjs +1022 -0
  80. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -0
  81. package/dist/esm/tools/local/LocalExecutionTools.mjs +117 -0
  82. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -0
  83. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +448 -0
  84. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -0
  85. package/dist/esm/tools/local/attachments.mjs +180 -0
  86. package/dist/esm/tools/local/attachments.mjs.map +1 -0
  87. package/dist/esm/tools/local/bashAst.mjs +126 -0
  88. package/dist/esm/tools/local/bashAst.mjs.map +1 -0
  89. package/dist/esm/tools/local/editStrategies.mjs +185 -0
  90. package/dist/esm/tools/local/editStrategies.mjs.map +1 -0
  91. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +137 -0
  92. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -0
  93. package/dist/esm/tools/local/syntaxCheck.mjs +179 -0
  94. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -0
  95. package/dist/esm/tools/local/textEncoding.mjs +27 -0
  96. package/dist/esm/tools/local/textEncoding.mjs.map +1 -0
  97. package/dist/esm/tools/local/workspaceFS.mjs +49 -0
  98. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -0
  99. package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -0
  100. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  101. package/dist/types/common/enum.d.ts +39 -1
  102. package/dist/types/graphs/Graph.d.ts +34 -0
  103. package/dist/types/hooks/createWorkspacePolicyHook.d.ts +95 -0
  104. package/dist/types/hooks/index.d.ts +2 -0
  105. package/dist/types/index.d.ts +1 -0
  106. package/dist/types/llm/openai/index.d.ts +17 -0
  107. package/dist/types/messages/anthropicToolCache.d.ts +51 -0
  108. package/dist/types/messages/index.d.ts +2 -0
  109. package/dist/types/messages/prune.d.ts +11 -0
  110. package/dist/types/messages/recency.d.ts +64 -0
  111. package/dist/types/run.d.ts +21 -0
  112. package/dist/types/tools/ToolNode.d.ts +145 -2
  113. package/dist/types/tools/local/CompileCheckTool.d.ts +31 -0
  114. package/dist/types/tools/local/FileCheckpointer.d.ts +39 -0
  115. package/dist/types/tools/local/LocalCodingTools.d.ts +57 -0
  116. package/dist/types/tools/local/LocalExecutionEngine.d.ts +149 -0
  117. package/dist/types/tools/local/LocalExecutionTools.d.ts +9 -0
  118. package/dist/types/tools/local/LocalProgrammaticToolCalling.d.ts +21 -0
  119. package/dist/types/tools/local/attachments.d.ts +84 -0
  120. package/dist/types/tools/local/bashAst.d.ts +11 -0
  121. package/dist/types/tools/local/editStrategies.d.ts +28 -0
  122. package/dist/types/tools/local/index.d.ts +12 -0
  123. package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +38 -0
  124. package/dist/types/tools/local/syntaxCheck.d.ts +42 -0
  125. package/dist/types/tools/local/textEncoding.d.ts +21 -0
  126. package/dist/types/tools/local/workspaceFS.d.ts +49 -0
  127. package/dist/types/types/hitl.d.ts +56 -27
  128. package/dist/types/types/run.d.ts +8 -1
  129. package/dist/types/types/summarize.d.ts +30 -0
  130. package/dist/types/types/tools.d.ts +341 -6
  131. package/package.json +21 -2
  132. package/src/common/enum.ts +54 -0
  133. package/src/graphs/Graph.ts +164 -6
  134. package/src/hooks/__tests__/compactHooks.test.ts +38 -2
  135. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +393 -0
  136. package/src/hooks/createWorkspacePolicyHook.ts +355 -0
  137. package/src/hooks/index.ts +6 -0
  138. package/src/index.ts +1 -0
  139. package/src/llm/openai/deepseek.test.ts +479 -0
  140. package/src/llm/openai/index.ts +484 -1
  141. package/src/messages/__tests__/anthropicToolCache.test.ts +125 -0
  142. package/src/messages/__tests__/recency.test.ts +267 -0
  143. package/src/messages/anthropicToolCache.ts +116 -0
  144. package/src/messages/index.ts +2 -0
  145. package/src/messages/prune.ts +27 -1
  146. package/src/messages/recency.ts +155 -0
  147. package/src/run.ts +31 -0
  148. package/src/scripts/compare_pi_vs_ours.ts +840 -0
  149. package/src/scripts/local_engine.ts +166 -0
  150. package/src/scripts/local_engine_checkpointer.ts +205 -0
  151. package/src/scripts/local_engine_compile.ts +263 -0
  152. package/src/scripts/local_engine_hooks.ts +226 -0
  153. package/src/scripts/local_engine_image.ts +201 -0
  154. package/src/scripts/local_engine_ptc.ts +151 -0
  155. package/src/scripts/local_engine_workspace.ts +258 -0
  156. package/src/scripts/summarization-recency.ts +462 -0
  157. package/src/specs/prune.test.ts +39 -0
  158. package/src/summarization/__tests__/node.test.ts +499 -3
  159. package/src/summarization/node.ts +124 -7
  160. package/src/tools/ToolNode.ts +769 -20
  161. package/src/tools/__tests__/LocalExecutionTools.test.ts +2647 -0
  162. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +175 -0
  163. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +114 -0
  164. package/src/tools/__tests__/ToolNode.session.test.ts +84 -0
  165. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +467 -0
  166. package/src/tools/__tests__/directToolHooks.test.ts +411 -0
  167. package/src/tools/__tests__/localToolNames.test.ts +73 -0
  168. package/src/tools/__tests__/workspaceSeam.test.ts +134 -0
  169. package/src/tools/local/CompileCheckTool.ts +278 -0
  170. package/src/tools/local/FileCheckpointer.ts +93 -0
  171. package/src/tools/local/LocalCodingTools.ts +1342 -0
  172. package/src/tools/local/LocalExecutionEngine.ts +1329 -0
  173. package/src/tools/local/LocalExecutionTools.ts +167 -0
  174. package/src/tools/local/LocalProgrammaticToolCalling.ts +594 -0
  175. package/src/tools/local/__tests__/FileCheckpointer.test.ts +120 -0
  176. package/src/tools/local/__tests__/editStrategies.test.ts +134 -0
  177. package/src/tools/local/attachments.ts +251 -0
  178. package/src/tools/local/bashAst.ts +151 -0
  179. package/src/tools/local/editStrategies.ts +188 -0
  180. package/src/tools/local/index.ts +12 -0
  181. package/src/tools/local/resolveLocalExecutionTools.ts +208 -0
  182. package/src/tools/local/syntaxCheck.ts +243 -0
  183. package/src/tools/local/textEncoding.ts +37 -0
  184. package/src/tools/local/workspaceFS.ts +89 -0
  185. package/src/types/hitl.ts +56 -27
  186. package/src/types/run.ts +12 -1
  187. package/src/types/summarize.ts +31 -0
  188. package/src/types/tools.ts +359 -7
@@ -2,7 +2,7 @@ import { ToolCall } from '@langchain/core/messages/tool';
2
2
  import { END, Command, MessagesAnnotation } from '@langchain/langgraph';
3
3
  import type { RunnableConfig } from '@langchain/core/runnables';
4
4
  import type { BaseMessage } from '@langchain/core/messages';
5
- import type { ResolvedArgsByCallId } from '@/tools/toolOutputReferences';
5
+ import type { ToolOutputResolveView, ResolvedArgsByCallId } from '@/tools/toolOutputReferences';
6
6
  import type * as t from '@/types';
7
7
  import { RunnableCallable } from '@/utils';
8
8
  import { ToolOutputReferenceRegistry } from '@/tools/toolOutputReferences';
@@ -20,6 +20,36 @@ type RunToolBatchContext = {
20
20
  batchScopeId?: string;
21
21
  /** Batch-local sink for post-substitution args. */
22
22
  resolvedArgsByCallId?: ResolvedArgsByCallId;
23
+ /**
24
+ * Frozen pre-batch view of the tool-output registry. When supplied,
25
+ * `runTool` resolves `{{tool…turn…}}` placeholders against this
26
+ * snapshot instead of the live registry, so a slow `PreToolUse`
27
+ * hook on one direct call cannot cause a sibling's just-registered
28
+ * output to leak into this call's args mid-batch (Codex P1 #18 —
29
+ * `Promise.all`-induced ordering would otherwise be observable).
30
+ */
31
+ preBatchSnapshot?: ToolOutputResolveView;
32
+ /**
33
+ * Pre-incremented per-tool usage counter. Set by
34
+ * `runDirectToolWithLifecycleHooks` so PreToolUse hooks observe
35
+ * the same `turn` the tool will actually execute under (Codex P2
36
+ * #27 — without this, parallel direct calls of the same tool in
37
+ * one Promise.all batch all read `turn=N` for the hook but
38
+ * actually executed as `turn=N`, `N+1`, `N+2`). When supplied,
39
+ * `runTool` skips its own counter increment.
40
+ */
41
+ usageCount?: number;
42
+ /**
43
+ * Per-batch sink for `additionalContext` strings returned by
44
+ * direct-path PreToolUse / PostToolUse / PostToolUseFailure hooks.
45
+ * The caller in `run()` materializes the accumulated strings as a
46
+ * `HumanMessage` appended to outputs so the next model turn sees
47
+ * them — same shape as the event-driven path's `injected[]`.
48
+ * Codex P2 #39: pre-fix the direct path called `executeHooks` and
49
+ * discarded `additionalContexts`, silently breaking the hook API
50
+ * contract for hosts relying on it for policy / recovery guidance.
51
+ */
52
+ additionalContextsSink?: string[];
23
53
  };
24
54
  export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
25
55
  private toolMap;
@@ -31,6 +61,17 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
31
61
  private toolUsageCount;
32
62
  /** Maps toolCallId → turn captured in runTool, used by handleRunToolCompletions */
33
63
  private toolCallTurns;
64
+ /**
65
+ * `call.id → turn` map dedicated to the direct-path lifecycle so the
66
+ * turn assigned on first entry is REUSED on LangGraph resume.
67
+ * Distinct from `toolCallTurns` (which is cleared at the start of
68
+ * every `run()` to keep per-batch event-dispatch metadata fresh) —
69
+ * the direct path needs stability across re-entries triggered by
70
+ * `interrupt()` resumes (Codex P2 #30). Cleared with the rest of
71
+ * the per-Run state in `clearHeavyState`-equivalent flushes when
72
+ * the Run ends.
73
+ */
74
+ private directPathTurns;
34
75
  /** Tool registry for filtering (lazy computation of programmatic maps) */
35
76
  private toolRegistry?;
36
77
  /** Cached programmatic tools (computed once on first PTC call) */
@@ -43,6 +84,13 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
43
84
  private agentId?;
44
85
  /** Tool names that bypass event dispatch and execute directly (e.g., graph-managed handoff tools) */
45
86
  private directToolNames?;
87
+ /**
88
+ * File checkpointer extracted from the local coding tool bundle when
89
+ * `toolExecution.local.fileCheckpointing === true`. Exposed via
90
+ * {@link getFileCheckpointer}. Undefined when checkpointing is off
91
+ * or the local coding suite isn't bound to this node.
92
+ */
93
+ private fileCheckpointer?;
46
94
  /** Maximum characters allowed in a single tool result before truncation. */
47
95
  private maxToolResultChars;
48
96
  /** Hook registry for PreToolUse/PostToolUse lifecycle hooks */
@@ -65,6 +113,8 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
65
113
  * ToolNode building its own.
66
114
  */
67
115
  private toolOutputRegistry?;
116
+ /** Run-scoped selection for swapping remote code tools to local executors. */
117
+ private toolExecution?;
68
118
  /**
69
119
  * Monotonic counter used to mint a unique scope id for anonymous
70
120
  * batches (ones invoked without a `run_id` in
@@ -73,7 +123,7 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
73
123
  * other's in-flight state.
74
124
  */
75
125
  private anonBatchCounter;
76
- constructor({ tools, toolMap, name, tags, errorHandler, toolCallStepIds, handleToolErrors, loadRuntimeTools, toolRegistry, sessions, eventDrivenMode, agentId, directToolNames, maxContextTokens, maxToolResultChars, hookRegistry, humanInTheLoop, toolOutputReferences, toolOutputRegistry, }: t.ToolNodeConstructorParams);
126
+ constructor({ tools, toolMap, name, tags, errorHandler, toolCallStepIds, handleToolErrors, loadRuntimeTools, toolRegistry, sessions, eventDrivenMode, agentId, directToolNames, maxContextTokens, maxToolResultChars, hookRegistry, humanInTheLoop, toolOutputReferences, toolOutputRegistry, toolExecution, fileCheckpointer, }: t.ToolNodeConstructorParams);
77
127
  /**
78
128
  * Returns the run-scoped tool output registry, or `undefined` when
79
129
  * the feature is disabled.
@@ -83,6 +133,35 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
83
133
  * not mutate the registry directly.
84
134
  */
85
135
  _unsafeGetToolOutputRegistry(): ToolOutputReferenceRegistry | undefined;
136
+ /**
137
+ * Replaces known remote Code API tools with local-process tools when
138
+ * `RunConfig.toolExecution.engine === 'local'`. In event-driven mode those
139
+ * names are also marked direct so the SDK executes them locally instead of
140
+ * dispatching the batch to a host-side remote sandbox handler. When the
141
+ * local coding suite is enabled, this also injects file/search/edit tools.
142
+ */
143
+ private applyToolExecutionOverrides;
144
+ /**
145
+ * Returns the per-Run file checkpointer when
146
+ * `toolExecution.local.fileCheckpointing === true`. Hosts call
147
+ * `rewind()` on the returned object to restore captured pre-write
148
+ * file contents — the standard "undo a tool batch" pattern. Returns
149
+ * undefined when checkpointing is disabled or the local coding suite
150
+ * isn't bound. Manual review (finding E): without this getter, the
151
+ * config flag was a silent no-op outside of direct
152
+ * `createLocalCodingToolBundle()` use.
153
+ */
154
+ getFileCheckpointer(): t.LocalFileCheckpointer | undefined;
155
+ /**
156
+ * Flush the per-Run direct-path turn cache. Called by the Graph at
157
+ * end-of-Run via `clearHeavyState`. The map intentionally survives
158
+ * `run()` re-entry so an interrupt + resume reuses the original
159
+ * slot (Codex P2 #30), but it would otherwise grow linearly with
160
+ * tool calls and could collide across Runs if a provider reused
161
+ * call IDs (Codex P2 #33). Hosts can also call this directly if
162
+ * they reuse a ToolNode across batches outside of a Graph.
163
+ */
164
+ clearDirectPathTurns(): void;
86
165
  /**
87
166
  * Returns cached programmatic tools, computing once on first access.
88
167
  * Single iteration builds both toolMap and toolDefs simultaneously.
@@ -102,6 +181,70 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
102
181
  * substitutions. Omit when no registration should occur.
103
182
  */
104
183
  protected runTool(call: ToolCall, config: RunnableConfig, batchContext?: RunToolBatchContext): Promise<BaseMessage | Command>;
184
+ /**
185
+ * Runs a single in-process tool call with the same lifecycle hooks
186
+ * the event-dispatch path fires (`PreToolUse`, `PermissionDenied`,
187
+ * `PostToolUse`, `PostToolUseFailure`). Used for any tool whose
188
+ * implementation lives in the SDK process — i.e. every entry in
189
+ * `directToolNames` — so host-supplied policy hooks gate
190
+ * direct-invoked tools the same way they gate dispatched ones.
191
+ *
192
+ * Fast path: when the registry has none of the relevant events
193
+ * registered for this run, falls through to `runTool` with zero
194
+ * extra work. The hook list is also checked via
195
+ * `hasHookFor(event, runId)`, which performs the registry's own
196
+ * O(1) shortcut.
197
+ *
198
+ * Hook semantics intentionally mirror `dispatchToolEvents` for the
199
+ * single-call case:
200
+ * - `PreToolUse` returning `decision: 'deny'` synthesizes an error
201
+ * `ToolMessage` and fires `PermissionDenied` (observational).
202
+ * - `PreToolUse` returning `decision: 'ask'`:
203
+ * • When `humanInTheLoop.enabled === true`: raises a real
204
+ * `tool_approval` interrupt for this single tool call (the
205
+ * same payload shape the event path produces). On resume:
206
+ * `approve` runs the tool, `reject` blocks via
207
+ * `blockDirectCall`, `respond` returns the host-supplied
208
+ * `responseText` as a synthetic success ToolMessage,
209
+ * `edit` re-runs with edited args. LangGraph re-enters
210
+ * ToolNode.run from the start on resume; the hook fires
211
+ * again and the resume value distinguishes "first ask" from
212
+ * "second pass with decision".
213
+ * • When HITL is off: collapses to a fail-closed deny (matches
214
+ * the rest of the SDK's HITL-disabled default). One-time
215
+ * warning logged so hosts notice the gap.
216
+ * - `PreToolUse.updatedInput` is applied to the call before
217
+ * `runTool` runs; placeholder resolution inside `runTool` is
218
+ * idempotent on already-resolved args.
219
+ * - `PostToolUse.updatedOutput` replaces the returned
220
+ * `ToolMessage` content (preserving id/name/status).
221
+ * - `PostToolUseFailure` fires when `runTool` returns a
222
+ * `ToolMessage` whose `status === 'error'`. Observational only;
223
+ * the error message stays the source of truth.
224
+ *
225
+ * `PostToolBatch` aggregation across direct + dispatched outcomes is
226
+ * a separate concern: `dispatchToolEvents` accumulates batch entries
227
+ * locally and fires `PostToolBatch` at the end of its scope. Wiring
228
+ * direct-call entries into that aggregation crosses the two paths'
229
+ * scopes and is left to a follow-up.
230
+ */
231
+ private runDirectToolWithLifecycleHooks;
232
+ /**
233
+ * `ask` decisions on direct-path tools collapse to fail-closed deny
234
+ * only when `humanInTheLoop.enabled !== true` (i.e. there's no host
235
+ * UI configured to actually prompt the user). Logged once per process
236
+ * so the gap is visible. When HITL IS enabled, `ask` raises a real
237
+ * LangGraph `interrupt()` instead — see `runDirectToolWithLifecycleHooks`.
238
+ */
239
+ private askDirectWarningEmitted;
240
+ private resolveAskDecisionForDirectTool;
241
+ /**
242
+ * Synthesize a Blocked ToolMessage AND fire `PermissionDenied`
243
+ * (observational) for a direct-path tool call. Centralised so the
244
+ * deny path looks identical whether the block came from `'deny'` or
245
+ * from a fail-closed/`'reject'`/policy-violation path.
246
+ */
247
+ private blockDirectCall;
105
248
  /**
106
249
  * Registers the full, raw output under `refKey` (when provided) and
107
250
  * builds the per-message ref metadata stamped onto the resulting
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `compile_check` — a thin LLM-callable wrapper around the project's
3
+ * standard typecheck/lint command. Lets the agent answer "did my
4
+ * change break anything?" without us shipping a real LSP client.
5
+ *
6
+ * Auto-detection priority (first hit wins):
7
+ *
8
+ * 1. `local.compileCheck.command` — explicit override
9
+ * 2. `tsconfig.json` → `npx --no-install tsc --noEmit`
10
+ * 3. `package.json` with a typescript dep → same as 2
11
+ * 4. `pyproject.toml` or `setup.py` / `setup.cfg`
12
+ * with a dev dep on mypy → `python3 -m mypy .`
13
+ * else → `python3 -m py_compile <every .py>`
14
+ * (bounded by find-walk so node_modules
15
+ * and `.venv` don't blow up)
16
+ * 5. `Cargo.toml` → `cargo check --message-format=short`
17
+ * 6. `go.mod` → `go vet ./...`
18
+ * 7. otherwise → tells the agent there's
19
+ * no detected toolchain.
20
+ *
21
+ * Output is the spawn process's stdout/stderr passed through
22
+ * `truncateLocalOutput` so a 10MB tsc dump can't blow context. The
23
+ * exit code is reported.
24
+ */
25
+ import type { DynamicStructuredTool } from '@langchain/core/tools';
26
+ import type * as t from '@/types';
27
+ import { Constants } from '@/common';
28
+ /** Back-compat alias; canonical name lives on `Constants.COMPILE_CHECK`. */
29
+ export declare const CompileCheckToolName = Constants.COMPILE_CHECK;
30
+ export declare function createCompileCheckTool(config?: t.LocalExecutionConfig): DynamicStructuredTool;
31
+ export declare function createCompileCheckToolDefinition(): t.LCTool;
@@ -0,0 +1,39 @@
1
+ import type { WorkspaceFS } from './workspaceFS';
2
+ import type * as t from '@/types';
3
+ /**
4
+ * Per-Run snapshot store for write_file / edit_file. Captures the
5
+ * pre-write byte content of every path the local engine is about to
6
+ * mutate so a later `rewind()` can restore the working tree to its
7
+ * original state. Notes:
8
+ *
9
+ * - Idempotent per path: subsequent captures preserve the first
10
+ * snapshot (so rewind always restores the *original* content).
11
+ * - Captures missing files as `{ kind: 'absent' }`; rewind deletes
12
+ * those paths so created files are removed.
13
+ * - In-memory: snapshots live for the lifetime of this instance and
14
+ * are not persisted across processes. Tie the lifetime to a Run.
15
+ * - Bounded by `maxBytesPerFile` (default 32 MiB) to bound memory.
16
+ * A file larger than the cap is recorded but not snapshotted; the
17
+ * rewind of that path is best-effort and the caller is told via
18
+ * the result count not to trust it.
19
+ */
20
+ export declare class LocalFileCheckpointerImpl implements t.LocalFileCheckpointer {
21
+ private readonly maxBytesPerFile;
22
+ private readonly fs;
23
+ private snapshots;
24
+ private oversizePaths;
25
+ constructor(maxBytesPerFile?: number, fs?: WorkspaceFS);
26
+ captureBeforeWrite(absolutePath: string): Promise<void>;
27
+ rewind(): Promise<number>;
28
+ capturedPaths(): string[];
29
+ }
30
+ /**
31
+ * Convenience factory so callers don't have to reach for the impl
32
+ * class directly. Accepts an optional `WorkspaceFS` so a host using a
33
+ * non-default engine (remote sandbox, in-memory test FS, etc.) can
34
+ * route the checkpointer through the same I/O.
35
+ */
36
+ export declare function createLocalFileCheckpointer(options?: {
37
+ maxBytesPerFile?: number;
38
+ fs?: WorkspaceFS;
39
+ }): t.LocalFileCheckpointer;
@@ -0,0 +1,57 @@
1
+ import type { DynamicStructuredTool } from '@langchain/core/tools';
2
+ import type * as t from '@/types';
3
+ import { Constants } from '@/common';
4
+ /**
5
+ * Tool name aliases retained for back-compat with consumers that imported
6
+ * the per-file `Local*ToolName` constants. The canonical names live on
7
+ * `Constants.*` (see `src/common/enum.ts`); these aliases just point at
8
+ * them so a typo upstream gets caught at the type level.
9
+ */
10
+ export declare const LocalWriteFileToolName = Constants.WRITE_FILE;
11
+ export declare const LocalEditFileToolName = Constants.EDIT_FILE;
12
+ export declare const LocalGrepSearchToolName = Constants.GREP_SEARCH;
13
+ export declare const LocalGlobSearchToolName = Constants.GLOB_SEARCH;
14
+ export declare const LocalListDirectoryToolName = Constants.LIST_DIRECTORY;
15
+ export declare const LocalReadFileToolSchema: t.JsonSchemaType;
16
+ export declare const LocalWriteFileToolSchema: t.JsonSchemaType;
17
+ export declare const LocalEditFileToolSchema: t.JsonSchemaType;
18
+ export declare const LocalGrepSearchToolSchema: t.JsonSchemaType;
19
+ export declare const LocalGlobSearchToolSchema: t.JsonSchemaType;
20
+ export declare const LocalListDirectoryToolSchema: t.JsonSchemaType;
21
+ export declare function createLocalReadFileTool(config?: t.LocalExecutionConfig): DynamicStructuredTool;
22
+ export declare function createLocalWriteFileTool(config?: t.LocalExecutionConfig, checkpointer?: t.LocalFileCheckpointer): DynamicStructuredTool;
23
+ export declare function createLocalEditFileTool(config?: t.LocalExecutionConfig, checkpointer?: t.LocalFileCheckpointer): DynamicStructuredTool;
24
+ /**
25
+ * Test-only reset hook. Clears the ripgrep-availability cache so
26
+ * tests can swap in mocked spawn backends and reprobe deterministically.
27
+ *
28
+ * @internal Not part of the public SDK surface; the leading underscore
29
+ * and `@internal` tag together signal that consumers should not call
30
+ * this. Tests import it via the module path directly.
31
+ */
32
+ export declare function _resetRipgrepCacheForTests(): void;
33
+ export declare function createLocalGrepSearchTool(config?: t.LocalExecutionConfig): DynamicStructuredTool;
34
+ export declare function createLocalGlobSearchTool(config?: t.LocalExecutionConfig): DynamicStructuredTool;
35
+ export declare function createLocalListDirectoryTool(config?: t.LocalExecutionConfig): DynamicStructuredTool;
36
+ export type LocalCodingToolBundle = {
37
+ tools: DynamicStructuredTool[];
38
+ /**
39
+ * Present when `config.fileCheckpointing === true` or a `checkpointer`
40
+ * was passed in. Callers can call `rewind()` to restore captured
41
+ * pre-write contents.
42
+ */
43
+ checkpointer?: t.LocalFileCheckpointer;
44
+ };
45
+ export declare function createLocalCodingTools(config?: t.LocalExecutionConfig, options?: {
46
+ checkpointer?: t.LocalFileCheckpointer;
47
+ }): DynamicStructuredTool[];
48
+ /**
49
+ * Variant of `createLocalCodingTools` that returns the bundle alongside
50
+ * the file checkpointer so callers can later call
51
+ * `bundle.checkpointer?.rewind()`.
52
+ */
53
+ export declare function createLocalCodingToolBundle(config?: t.LocalExecutionConfig, options?: {
54
+ checkpointer?: t.LocalFileCheckpointer;
55
+ }): LocalCodingToolBundle;
56
+ export declare function createLocalCodingToolDefinitions(): t.LCTool[];
57
+ export declare function createLocalCodingToolRegistry(): t.LCToolRegistry;
@@ -0,0 +1,149 @@
1
+ import type { WorkspaceFS } from './workspaceFS';
2
+ import type * as t from '@/types';
3
+ type SpawnResult = {
4
+ stdout: string;
5
+ stderr: string;
6
+ exitCode: number | null;
7
+ timedOut: boolean;
8
+ /**
9
+ * True when the process was force-killed because total streamed bytes
10
+ * exceeded `maxSpawnedBytes`. Distinct from `timedOut`. Without this
11
+ * flag, callers (`bash_tool`, `execute_code`, etc.) would see a
12
+ * SIGKILL'd process with `exitCode: null` and treat it as success
13
+ * (Codex P1 — runaway commands like `yes` or noisy builds silently
14
+ * looked successful even though their output was truncated).
15
+ */
16
+ overflowKilled?: boolean;
17
+ /**
18
+ * Signal name (e.g. `'SIGKILL'`, `'SIGSEGV'`) when the process was
19
+ * terminated by a signal. Distinct from the overflow-kill path:
20
+ * this captures `kill -9 $$` from inside the script, native crashes,
21
+ * OS OOM killer, etc. Without this, signal-killed processes
22
+ * reported `exitCode: null` and looked like clean runs (Codex P2 —
23
+ * generalization of the overflow-kill fix). When present, the
24
+ * exitCode field is also synthesized to `128 + signum` per the
25
+ * POSIX convention so non-null-exit-code consumers see a failure.
26
+ */
27
+ signal?: string;
28
+ /** Path to the full untruncated stdout/stderr when output exceeded `maxOutputChars`. */
29
+ fullOutputPath?: string;
30
+ };
31
+ export type BashValidationResult = {
32
+ valid: boolean;
33
+ errors: string[];
34
+ warnings: string[];
35
+ };
36
+ export declare function resolveLocalExecutionConfig(config?: t.ToolExecutionConfig | t.LocalExecutionConfig): t.LocalExecutionConfig;
37
+ export declare function getLocalCwd(config?: t.LocalExecutionConfig): string;
38
+ /**
39
+ * Resolves the effective workspace boundary: a list of absolute roots
40
+ * that file operations are allowed to touch. The first entry is always
41
+ * the canonical root (`getLocalCwd`); subsequent entries come from
42
+ * `workspace.additionalRoots` when provided.
43
+ *
44
+ * Returns plain absolute paths — callers symlink-resolve when they
45
+ * need realpath equality (see `resolveWorkspacePathSafe`).
46
+ */
47
+ export declare function getWorkspaceRoots(config?: t.LocalExecutionConfig): string[];
48
+ /**
49
+ * Pluggable spawn resolver. Honours `local.exec.spawn` first, falls
50
+ * back to the legacy top-level `local.spawn`, then to Node's
51
+ * `child_process.spawn`. Centralised so engine swapping is one knob.
52
+ */
53
+ export declare function getSpawn(config?: t.LocalExecutionConfig): t.LocalSpawn;
54
+ /**
55
+ * Pluggable filesystem resolver. Honours `local.exec.fs`, falls back
56
+ * to the Node-host implementation. A future remote engine supplies
57
+ * its own implementation here and inherits every file-touching tool.
58
+ */
59
+ export declare function getWorkspaceFS(config?: t.LocalExecutionConfig): WorkspaceFS;
60
+ /**
61
+ * Resolves the workspace boundary for *write* operations. Honours
62
+ * `workspace.allowWriteOutside` (and the deprecated
63
+ * `allowOutsideWorkspace`) by returning `null`, which the path-safety
64
+ * helpers interpret as "skip the write clamp".
65
+ */
66
+ export declare function getWriteRoots(config?: t.LocalExecutionConfig): string[] | null;
67
+ /**
68
+ * Resolves the workspace boundary for *read* operations. Honours
69
+ * `workspace.allowReadOutside` (and the deprecated
70
+ * `allowOutsideWorkspace`) by returning `null`.
71
+ */
72
+ export declare function getReadRoots(config?: t.LocalExecutionConfig): string[] | null;
73
+ export declare function getLocalSessionId(config?: t.LocalExecutionConfig): string;
74
+ /**
75
+ * Test-only reset hook for the sandbox-off warning latch.
76
+ *
77
+ * @internal Not part of the public SDK surface.
78
+ */
79
+ export declare function _resetLocalEngineWarningsForTests(): void;
80
+ export declare function truncateLocalOutput(value: string, maxChars?: number): string;
81
+ export declare function validateBashCommand(command: string, config?: t.LocalExecutionConfig): Promise<BashValidationResult>;
82
+ /**
83
+ * Structural shape of the sandbox-runtime config we hand to
84
+ * `SandboxManager.initialize()`. Intentionally NOT typed as the peer
85
+ * `SandboxRuntimeConfig` from `@anthropic-ai/sandbox-runtime`: that
86
+ * package is an OPTIONAL peer dep, and exporting a function whose
87
+ * return type references it would make our generated `.d.ts` import
88
+ * a module the consumer may not have installed (Codex P1 #22 — type-
89
+ * checking would fail with `Cannot find module
90
+ * '@anthropic-ai/sandbox-runtime'` for any host that doesn't enable
91
+ * local sandboxing). The shape here is a structural subset; assignable
92
+ * to the real `SandboxRuntimeConfig` at the one runtime call site.
93
+ *
94
+ * @internal
95
+ */
96
+ export interface BuiltSandboxRuntimeConfig {
97
+ network: {
98
+ allowedDomains: string[];
99
+ deniedDomains: string[];
100
+ allowUnixSockets?: string[];
101
+ allowAllUnixSockets?: boolean;
102
+ allowLocalBinding?: boolean;
103
+ allowMachLookup?: string[];
104
+ };
105
+ filesystem: {
106
+ denyRead: string[];
107
+ allowRead?: string[];
108
+ allowWrite: string[];
109
+ denyWrite: string[];
110
+ allowGitConfig?: boolean;
111
+ };
112
+ }
113
+ export declare function buildSandboxRuntimeConfig(config: t.LocalExecutionConfig, cwd: string, getDefaultWritePaths: () => string[]): BuiltSandboxRuntimeConfig;
114
+ /**
115
+ * Internal options for {@link spawnLocalProcess} that we don't want
116
+ * exposed on the public `LocalExecutionConfig` type.
117
+ *
118
+ * @internal
119
+ */
120
+ export interface SpawnLocalProcessOptions {
121
+ /**
122
+ * When true, suppress the "sandbox is off" warning AND its latch
123
+ * for this spawn. Use for SDK-internal probes (`bash -n` syntax
124
+ * preflight, `rg --version`, etc.) that intentionally run with
125
+ * the sandbox forced off — the warning is noise for those, and
126
+ * letting the latch flip would hide the warning when a *real*
127
+ * unsandboxed execution happens later in the same process.
128
+ */
129
+ internal?: boolean;
130
+ }
131
+ export declare function spawnLocalProcess(command: string, args: string[], config?: t.LocalExecutionConfig, options?: SpawnLocalProcessOptions): Promise<SpawnResult>;
132
+ export declare function executeLocalBash(command: string, config?: t.LocalExecutionConfig): Promise<SpawnResult>;
133
+ export declare function executeLocalBashWithArgs(command: string, args: readonly string[], config?: t.LocalExecutionConfig): Promise<SpawnResult>;
134
+ export declare function executeLocalCode(input: {
135
+ lang: string;
136
+ code: string;
137
+ args?: string[];
138
+ }, config?: t.LocalExecutionConfig): Promise<SpawnResult>;
139
+ export declare function shellQuote(value: string): string;
140
+ export declare function resolveWorkspacePath(filePath: string, config?: t.LocalExecutionConfig, intent?: 'read' | 'write'): string;
141
+ /**
142
+ * Resolves a workspace path AND follows any symlinks before checking
143
+ * containment, so a symlink inside the workspace pointing outside is
144
+ * rejected even though the lexical path looks safe. Handles paths that
145
+ * don't yet exist (e.g. write_file targets) by realpath-resolving the
146
+ * nearest existing ancestor and re-attaching the unresolved suffix.
147
+ */
148
+ export declare function resolveWorkspacePathSafe(filePath: string, config?: t.LocalExecutionConfig, intent?: 'read' | 'write'): Promise<string>;
149
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { DynamicStructuredTool } from '@langchain/core/tools';
2
+ import type * as t from '@/types';
3
+ export declare const LocalCodeExecutionToolDescription: string;
4
+ export declare const LocalBashExecutionToolDescription: string;
5
+ export declare function createLocalCodeExecutionTool(config?: t.LocalExecutionConfig): DynamicStructuredTool;
6
+ export declare function createLocalBashExecutionTool(options?: {
7
+ config?: t.LocalExecutionConfig;
8
+ enableToolOutputReferences?: boolean;
9
+ }): DynamicStructuredTool;
@@ -0,0 +1,21 @@
1
+ import type { DynamicStructuredTool } from '@langchain/core/tools';
2
+ import type * as t from '@/types';
3
+ /**
4
+ * Run the host's `PreToolUse` hook chain for a single bridge call.
5
+ * Returns the (possibly rewritten) input and a `denyReason` if any
6
+ * matcher returned `decision: 'deny'` or `'ask'`. `'ask'` collapses
7
+ * to deny because the bridge can't raise a LangGraph interrupt from
8
+ * inside an HTTP handler — fail-closed matches the rest of the SDK
9
+ * when HITL is unavailable.
10
+ *
11
+ * @internal Exported for tests so the deny / allow / updatedInput /
12
+ * ask branches can be exercised without standing up the full HTTP
13
+ * bridge.
14
+ */
15
+ export declare function applyPreToolUseHooksForBridge(hookContext: t.ProgrammaticHookContext, toolName: string, toolUseId: string, toolInput: Record<string, unknown>): Promise<{
16
+ input: Record<string, unknown>;
17
+ denyReason?: string;
18
+ }>;
19
+ export declare function _createBashProgramForTests(code: string, toolDefs: t.LCTool[], bridgeUrl: string, bridgeToken: string): string;
20
+ export declare function createLocalProgrammaticToolCallingTool(localConfig?: t.LocalExecutionConfig): DynamicStructuredTool;
21
+ export declare function createLocalBashProgrammaticToolCallingTool(localConfig?: t.LocalExecutionConfig): DynamicStructuredTool;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Detects whether a file on disk is an LLM-renderable attachment
3
+ * (image / PDF) and produces the LangChain `MessageContentComplex[]`
4
+ * payload a `ToolMessage` needs to actually surface those bytes to
5
+ * the vision-capable model.
6
+ *
7
+ * Same approach as LibreChat's `api/server/utils/files.js`: sniff the
8
+ * magic bytes (NOT the extension) so a mislabelled `.png` that's
9
+ * really a binary blob doesn't get embedded as an image. Inlined for
10
+ * the five formats we actually care about (PNG / JPEG / GIF / WebP /
11
+ * PDF) instead of pulling the ESM-only `file-type` package — keeps
12
+ * the test setup CJS-clean.
13
+ *
14
+ * Provider compatibility:
15
+ * - Anthropic: tool_result content arrays accept `image` / `image_url`
16
+ * blocks; LangChain's anthropic adapter at
17
+ * `node_modules/@langchain/anthropic/dist/utils/message_inputs.js`
18
+ * converts them to native `image` source blocks.
19
+ * - OpenAI Chat Completions: image_url blocks in tool messages are
20
+ * accepted on vision-capable models.
21
+ * - OpenAI Responses API: tool messages are flattened to plain text;
22
+ * image_url blocks degrade to a JSON description (still useful as
23
+ * a textual hint to the model).
24
+ * - Google: image blocks in tool responses are accepted on Gemini
25
+ * vision models.
26
+ *
27
+ * Configuration:
28
+ * - `local.attachReadAttachments` (default `'images-only'`) controls
29
+ * which file kinds are returned as inline attachments. Other kinds
30
+ * fall through to the existing binary-stub path.
31
+ * - `local.maxAttachmentBytes` (default 5 MB) caps the pre-encoding
32
+ * size; oversize attachments degrade to a stub describing the
33
+ * refusal so the model isn't surprised.
34
+ */
35
+ import type { WorkspaceFS } from './workspaceFS';
36
+ export type AttachmentMode = 'images-only' | 'images-and-pdf' | 'off';
37
+ export type Attachment = {
38
+ kind: 'image';
39
+ mime: string;
40
+ bytes: number;
41
+ dataUrl: string;
42
+ } | {
43
+ kind: 'pdf';
44
+ mime: 'application/pdf';
45
+ bytes: number;
46
+ dataUrl: string;
47
+ } | {
48
+ kind: 'binary';
49
+ mime: string;
50
+ bytes: number;
51
+ } | {
52
+ kind: 'oversize';
53
+ mime: string;
54
+ bytes: number;
55
+ maxBytes: number;
56
+ } | {
57
+ kind: 'text-or-unknown';
58
+ bytes: number;
59
+ };
60
+ export declare function classifyAttachment(args: {
61
+ path: string;
62
+ bytes: number;
63
+ mode: AttachmentMode;
64
+ maxBytes: number;
65
+ /**
66
+ * WorkspaceFS to route I/O through — defaults to host fs/promises
67
+ * for backward compat. Manual review (finding F): without this
68
+ * routing, custom/remote FS implementations could either fail to
69
+ * embed valid attachments or accidentally read a host path with
70
+ * the same absolute name (since `read_file` itself does go through
71
+ * the configured WorkspaceFS).
72
+ */
73
+ fs?: WorkspaceFS;
74
+ }): Promise<Attachment>;
75
+ /** Build the LangChain content array for an image attachment. */
76
+ export declare function imageAttachmentContent(path: string, attachment: Extract<Attachment, {
77
+ kind: 'image';
78
+ }>): Array<{
79
+ type: 'text' | 'image_url';
80
+ text?: string;
81
+ image_url?: {
82
+ url: string;
83
+ };
84
+ }>;
@@ -0,0 +1,11 @@
1
+ import type * as t from '@/types';
2
+ export type BashAstFinding = {
3
+ code: string;
4
+ message: string;
5
+ severity: 'warn' | 'deny';
6
+ };
7
+ export declare function runBashAstChecks(command: string, mode?: t.LocalBashAstMode): BashAstFinding[];
8
+ export declare function bashAstFindingsToErrors(findings: BashAstFinding[]): {
9
+ errors: string[];
10
+ warnings: string[];
11
+ };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Single-occurrence string-replacement strategies for `edit_file`.
3
+ *
4
+ * The LLM frequently emits an `oldString` whose whitespace, indentation,
5
+ * or escape sequences are slightly off from the on-disk content. Rather
6
+ * than failing the call (which forces a re-read + retry round-trip),
7
+ * we walk a chain of progressively looser matchers, stopping at the
8
+ * first one that locates exactly one match. The matched on-disk slice
9
+ * is then literally replaced with `newString` — we never modify
10
+ * `newString`, only the search.
11
+ *
12
+ * Strategies are ordered from strict to lenient so we don't accidentally
13
+ * over-match a more specific pattern with a looser one. Inspired by
14
+ * opencode's nine-strategy chain (sst/opencode), trimmed to the four
15
+ * highest-yield strategies for a first cut. Add more (block-anchor +
16
+ * Levenshtein, escape-normalized, etc.) as needed.
17
+ */
18
+ export interface EditMatch {
19
+ /** Strategy name that produced the match, for telemetry/diagnostics. */
20
+ strategy: string;
21
+ /** Starting offset in the source. */
22
+ start: number;
23
+ /** Ending offset (exclusive). */
24
+ end: number;
25
+ }
26
+ export type EditStrategy = (source: string, oldString: string) => EditMatch | null;
27
+ export declare function locateEdit(source: string, oldString: string): EditMatch | null;
28
+ export declare function applyEdit(source: string, match: EditMatch, newString: string): string;
@@ -0,0 +1,12 @@
1
+ export * from './CompileCheckTool';
2
+ export * from './FileCheckpointer';
3
+ export * from './LocalCodingTools';
4
+ export * from './LocalExecutionEngine';
5
+ export * from './LocalExecutionTools';
6
+ export * from './LocalProgrammaticToolCalling';
7
+ export * from './resolveLocalExecutionTools';
8
+ export * from './attachments';
9
+ export * from './bashAst';
10
+ export * from './editStrategies';
11
+ export * from './syntaxCheck';
12
+ export * from './textEncoding';