@librechat/agents 3.2.31 → 3.2.33

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 (582) hide show
  1. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  2. package/dist/cjs/agents/AgentContext.cjs +844 -1046
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/common/constants.cjs +13 -13
  5. package/dist/cjs/common/constants.cjs.map +1 -1
  6. package/dist/cjs/common/enum.cjs +233 -240
  7. package/dist/cjs/common/enum.cjs.map +1 -1
  8. package/dist/cjs/common/index.cjs +2 -0
  9. package/dist/cjs/events.cjs +121 -169
  10. package/dist/cjs/events.cjs.map +1 -1
  11. package/dist/cjs/graphs/Graph.cjs +1389 -1807
  12. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  13. package/dist/cjs/graphs/MultiAgentGraph.cjs +713 -945
  14. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  15. package/dist/cjs/graphs/index.cjs +2 -0
  16. package/dist/cjs/hitl/askUserQuestion.cjs +60 -62
  17. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -1
  18. package/dist/cjs/hitl/index.cjs +1 -0
  19. package/dist/cjs/hooks/HookRegistry.cjs +176 -202
  20. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  21. package/dist/cjs/hooks/createToolPolicyHook.cjs +71 -101
  22. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -1
  23. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +170 -273
  24. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  25. package/dist/cjs/hooks/executeHooks.cjs +227 -282
  26. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  27. package/dist/cjs/hooks/index.cjs +6 -0
  28. package/dist/cjs/hooks/matchers.cjs +196 -230
  29. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  30. package/dist/cjs/hooks/types.cjs +24 -24
  31. package/dist/cjs/hooks/types.cjs.map +1 -1
  32. package/dist/cjs/instrumentation.cjs +110 -137
  33. package/dist/cjs/instrumentation.cjs.map +1 -1
  34. package/dist/cjs/langchain/google-common.cjs +0 -3
  35. package/dist/cjs/langchain/index.cjs +80 -43
  36. package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
  37. package/dist/cjs/langchain/messages/tool.cjs +0 -3
  38. package/dist/cjs/langchain/messages.cjs +35 -18
  39. package/dist/cjs/langchain/openai.cjs +0 -3
  40. package/dist/cjs/langchain/prompts.cjs +5 -8
  41. package/dist/cjs/langchain/runnables.cjs +11 -10
  42. package/dist/cjs/langchain/tools.cjs +14 -11
  43. package/dist/cjs/langchain/utils/env.cjs +5 -8
  44. package/dist/cjs/langfuse.cjs +60 -79
  45. package/dist/cjs/langfuse.cjs.map +1 -1
  46. package/dist/cjs/langfuseToolOutputTracing.cjs +267 -399
  47. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  48. package/dist/cjs/llm/anthropic/index.cjs +432 -562
  49. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  50. package/dist/cjs/llm/anthropic/types.cjs +23 -47
  51. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  52. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +441 -696
  53. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -252
  55. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  56. package/dist/cjs/llm/anthropic/utils/output_parsers.cjs +2 -0
  57. package/dist/cjs/llm/anthropic/utils/tools.cjs +12 -26
  58. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  59. package/dist/cjs/llm/bedrock/index.cjs +195 -240
  60. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  61. package/dist/cjs/llm/bedrock/toolCache.cjs +84 -106
  62. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  63. package/dist/cjs/llm/bedrock/utils/index.cjs +2 -0
  64. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +357 -620
  65. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  66. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +105 -149
  67. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  68. package/dist/cjs/llm/fake.cjs +86 -96
  69. package/dist/cjs/llm/fake.cjs.map +1 -1
  70. package/dist/cjs/llm/google/index.cjs +183 -237
  71. package/dist/cjs/llm/google/index.cjs.map +1 -1
  72. package/dist/cjs/llm/google/utils/common.cjs +398 -674
  73. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  74. package/dist/cjs/llm/google/utils/zod_to_genai_parameters.cjs +2 -0
  75. package/dist/cjs/llm/init.cjs +44 -53
  76. package/dist/cjs/llm/init.cjs.map +1 -1
  77. package/dist/cjs/llm/invoke.cjs +142 -182
  78. package/dist/cjs/llm/invoke.cjs.map +1 -1
  79. package/dist/cjs/llm/openai/index.cjs +991 -1276
  80. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  81. package/dist/cjs/llm/openai/utils/index.cjs +189 -316
  82. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  83. package/dist/cjs/llm/openrouter/index.cjs +102 -153
  84. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  85. package/dist/cjs/llm/openrouter/toolCache.cjs +35 -44
  86. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  87. package/dist/cjs/llm/providers.cjs +29 -37
  88. package/dist/cjs/llm/providers.cjs.map +1 -1
  89. package/dist/cjs/llm/request.cjs +20 -33
  90. package/dist/cjs/llm/request.cjs.map +1 -1
  91. package/dist/cjs/llm/vertexai/index.cjs +427 -453
  92. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  93. package/dist/cjs/main.cjs +547 -528
  94. package/dist/cjs/messages/anthropicToolCache.cjs +68 -119
  95. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
  96. package/dist/cjs/messages/cache.cjs +308 -401
  97. package/dist/cjs/messages/cache.cjs.map +1 -1
  98. package/dist/cjs/messages/content.cjs +36 -49
  99. package/dist/cjs/messages/content.cjs.map +1 -1
  100. package/dist/cjs/messages/contextPruning.cjs +112 -145
  101. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  102. package/dist/cjs/messages/contextPruningSettings.cjs +36 -46
  103. package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -1
  104. package/dist/cjs/messages/core.cjs +256 -397
  105. package/dist/cjs/messages/core.cjs.map +1 -1
  106. package/dist/cjs/messages/format.cjs +904 -1382
  107. package/dist/cjs/messages/format.cjs.map +1 -1
  108. package/dist/cjs/messages/ids.cjs +16 -20
  109. package/dist/cjs/messages/ids.cjs.map +1 -1
  110. package/dist/cjs/messages/index.cjs +12 -0
  111. package/dist/cjs/messages/langchain.cjs +18 -18
  112. package/dist/cjs/messages/langchain.cjs.map +1 -1
  113. package/dist/cjs/messages/prune.cjs +1054 -1517
  114. package/dist/cjs/messages/prune.cjs.map +1 -1
  115. package/dist/cjs/messages/recency.cjs +77 -95
  116. package/dist/cjs/messages/recency.cjs.map +1 -1
  117. package/dist/cjs/messages/reducer.cjs +63 -78
  118. package/dist/cjs/messages/reducer.cjs.map +1 -1
  119. package/dist/cjs/messages/tools.cjs +51 -79
  120. package/dist/cjs/messages/tools.cjs.map +1 -1
  121. package/dist/cjs/openai/index.cjs +171 -217
  122. package/dist/cjs/openai/index.cjs.map +1 -1
  123. package/dist/cjs/responses/index.cjs +302 -391
  124. package/dist/cjs/responses/index.cjs.map +1 -1
  125. package/dist/cjs/run.cjs +903 -1113
  126. package/dist/cjs/run.cjs.map +1 -1
  127. package/dist/cjs/session/AgentSession.cjs +805 -986
  128. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  129. package/dist/cjs/session/JsonlSessionStore.cjs +327 -410
  130. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  131. package/dist/cjs/session/handlers.cjs +192 -208
  132. package/dist/cjs/session/handlers.cjs.map +1 -1
  133. package/dist/cjs/session/ids.cjs +9 -10
  134. package/dist/cjs/session/ids.cjs.map +1 -1
  135. package/dist/cjs/session/index.cjs +4 -0
  136. package/dist/cjs/session/messageSerialization.cjs +94 -156
  137. package/dist/cjs/session/messageSerialization.cjs.map +1 -1
  138. package/dist/cjs/splitStream.cjs +147 -206
  139. package/dist/cjs/splitStream.cjs.map +1 -1
  140. package/dist/cjs/stream.cjs +856 -1344
  141. package/dist/cjs/stream.cjs.map +1 -1
  142. package/dist/cjs/summarization/index.cjs +57 -101
  143. package/dist/cjs/summarization/index.cjs.map +1 -1
  144. package/dist/cjs/summarization/node.cjs +643 -796
  145. package/dist/cjs/summarization/node.cjs.map +1 -1
  146. package/dist/cjs/tools/BashExecutor.cjs +110 -136
  147. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  148. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +165 -245
  149. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  150. package/dist/cjs/tools/Calculator.cjs +36 -57
  151. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  152. package/dist/cjs/tools/CodeExecutor.cjs +126 -168
  153. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  154. package/dist/cjs/tools/CodeSessionFileSummary.cjs +36 -46
  155. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -1
  156. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +459 -649
  157. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  158. package/dist/cjs/tools/ReadFile.cjs +17 -20
  159. package/dist/cjs/tools/ReadFile.cjs.map +1 -1
  160. package/dist/cjs/tools/SkillTool.cjs +26 -27
  161. package/dist/cjs/tools/SkillTool.cjs.map +1 -1
  162. package/dist/cjs/tools/SubagentTool.cjs +59 -61
  163. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  164. package/dist/cjs/tools/ToolNode.cjs +2109 -2686
  165. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  166. package/dist/cjs/tools/ToolSearch.cjs +663 -825
  167. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  168. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs +248 -340
  169. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -1
  170. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +170 -197
  171. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  172. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +425 -520
  173. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  174. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +91 -124
  175. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  176. package/dist/cjs/tools/cloudflare/index.cjs +4 -0
  177. package/dist/cjs/tools/eagerEventExecution.cjs +75 -99
  178. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -1
  179. package/dist/cjs/tools/handlers.cjs +200 -262
  180. package/dist/cjs/tools/handlers.cjs.map +1 -1
  181. package/dist/cjs/tools/local/CompileCheckTool.cjs +150 -212
  182. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  183. package/dist/cjs/tools/local/FileCheckpointer.cjs +77 -85
  184. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  185. package/dist/cjs/tools/local/LocalCodingTools.cjs +763 -1022
  186. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  187. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +666 -941
  188. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  189. package/dist/cjs/tools/local/LocalExecutionTools.cjs +49 -92
  190. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  191. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +286 -354
  192. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  193. package/dist/cjs/tools/local/attachments.cjs +108 -165
  194. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  195. package/dist/cjs/tools/local/bashAst.cjs +99 -113
  196. package/dist/cjs/tools/local/bashAst.cjs.map +1 -1
  197. package/dist/cjs/tools/local/editStrategies.cjs +126 -169
  198. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -1
  199. package/dist/cjs/tools/local/index.cjs +12 -0
  200. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +136 -218
  201. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  202. package/dist/cjs/tools/local/syntaxCheck.cjs +142 -161
  203. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -1
  204. package/dist/cjs/tools/local/textEncoding.cjs +25 -23
  205. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -1
  206. package/dist/cjs/tools/local/workspaceFS.cjs +38 -46
  207. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -1
  208. package/dist/cjs/tools/ptcTimeout.cjs +27 -47
  209. package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
  210. package/dist/cjs/tools/schema.cjs +24 -23
  211. package/dist/cjs/tools/schema.cjs.map +1 -1
  212. package/dist/cjs/tools/search/anthropic.cjs +24 -33
  213. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  214. package/dist/cjs/tools/search/content.cjs +95 -137
  215. package/dist/cjs/tools/search/content.cjs.map +1 -1
  216. package/dist/cjs/tools/search/firecrawl.cjs +141 -172
  217. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  218. package/dist/cjs/tools/search/format.cjs +128 -196
  219. package/dist/cjs/tools/search/format.cjs.map +1 -1
  220. package/dist/cjs/tools/search/highlights.cjs +165 -232
  221. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  222. package/dist/cjs/tools/search/index.cjs +2 -0
  223. package/dist/cjs/tools/search/rerankers.cjs +151 -174
  224. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  225. package/dist/cjs/tools/search/schema.cjs +40 -39
  226. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  227. package/dist/cjs/tools/search/search.cjs +428 -530
  228. package/dist/cjs/tools/search/search.cjs.map +1 -1
  229. package/dist/cjs/tools/search/serper-scraper.cjs +106 -127
  230. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  231. package/dist/cjs/tools/search/tavily-scraper.cjs +129 -181
  232. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -1
  233. package/dist/cjs/tools/search/tavily-search.cjs +295 -359
  234. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  235. package/dist/cjs/tools/search/tool.cjs +260 -299
  236. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  237. package/dist/cjs/tools/search/utils.cjs +74 -117
  238. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  239. package/dist/cjs/tools/skillCatalog.cjs +54 -72
  240. package/dist/cjs/tools/skillCatalog.cjs.map +1 -1
  241. package/dist/cjs/tools/streamedToolCallSeals.cjs +19 -36
  242. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -1
  243. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +612 -771
  244. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  245. package/dist/cjs/tools/subagent/index.cjs +1 -0
  246. package/dist/cjs/tools/toolOutputReferences.cjs +523 -630
  247. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  248. package/dist/cjs/utils/callbacks.cjs +11 -21
  249. package/dist/cjs/utils/callbacks.cjs.map +1 -1
  250. package/dist/cjs/utils/errors.cjs +70 -95
  251. package/dist/cjs/utils/errors.cjs.map +1 -1
  252. package/dist/cjs/utils/events.cjs +32 -42
  253. package/dist/cjs/utils/events.cjs.map +1 -1
  254. package/dist/cjs/utils/graph.cjs +8 -12
  255. package/dist/cjs/utils/graph.cjs.map +1 -1
  256. package/dist/cjs/utils/handlers.cjs +60 -82
  257. package/dist/cjs/utils/handlers.cjs.map +1 -1
  258. package/dist/cjs/utils/index.cjs +9 -0
  259. package/dist/cjs/utils/llm.cjs +19 -27
  260. package/dist/cjs/utils/llm.cjs.map +1 -1
  261. package/dist/cjs/utils/misc.cjs +30 -46
  262. package/dist/cjs/utils/misc.cjs.map +1 -1
  263. package/dist/cjs/utils/run.cjs +50 -66
  264. package/dist/cjs/utils/run.cjs.map +1 -1
  265. package/dist/cjs/utils/schema.cjs +11 -19
  266. package/dist/cjs/utils/schema.cjs.map +1 -1
  267. package/dist/cjs/utils/title.cjs +71 -106
  268. package/dist/cjs/utils/title.cjs.map +1 -1
  269. package/dist/cjs/utils/tokens.cjs +186 -283
  270. package/dist/cjs/utils/tokens.cjs.map +1 -1
  271. package/dist/cjs/utils/truncation.cjs +95 -114
  272. package/dist/cjs/utils/truncation.cjs.map +1 -1
  273. package/dist/esm/agents/AgentContext.mjs +844 -1044
  274. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  275. package/dist/esm/common/constants.mjs +13 -11
  276. package/dist/esm/common/constants.mjs.map +1 -1
  277. package/dist/esm/common/enum.mjs +221 -238
  278. package/dist/esm/common/enum.mjs.map +1 -1
  279. package/dist/esm/common/index.mjs +3 -0
  280. package/dist/esm/events.mjs +121 -167
  281. package/dist/esm/events.mjs.map +1 -1
  282. package/dist/esm/graphs/Graph.mjs +1388 -1804
  283. package/dist/esm/graphs/Graph.mjs.map +1 -1
  284. package/dist/esm/graphs/MultiAgentGraph.mjs +713 -943
  285. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  286. package/dist/esm/graphs/index.mjs +3 -0
  287. package/dist/esm/hitl/askUserQuestion.mjs +60 -60
  288. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -1
  289. package/dist/esm/hitl/index.mjs +2 -0
  290. package/dist/esm/hooks/HookRegistry.mjs +176 -200
  291. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  292. package/dist/esm/hooks/createToolPolicyHook.mjs +71 -99
  293. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -1
  294. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +170 -271
  295. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  296. package/dist/esm/hooks/executeHooks.mjs +227 -280
  297. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  298. package/dist/esm/hooks/index.mjs +7 -0
  299. package/dist/esm/hooks/matchers.mjs +196 -228
  300. package/dist/esm/hooks/matchers.mjs.map +1 -1
  301. package/dist/esm/hooks/types.mjs +24 -22
  302. package/dist/esm/hooks/types.mjs.map +1 -1
  303. package/dist/esm/instrumentation.mjs +109 -132
  304. package/dist/esm/instrumentation.mjs.map +1 -1
  305. package/dist/esm/langchain/google-common.mjs +1 -2
  306. package/dist/esm/langchain/index.mjs +5 -5
  307. package/dist/esm/langchain/language_models/chat_models.mjs +1 -2
  308. package/dist/esm/langchain/messages/tool.mjs +1 -2
  309. package/dist/esm/langchain/messages.mjs +2 -2
  310. package/dist/esm/langchain/openai.mjs +1 -2
  311. package/dist/esm/langchain/prompts.mjs +2 -2
  312. package/dist/esm/langchain/runnables.mjs +2 -2
  313. package/dist/esm/langchain/tools.mjs +2 -2
  314. package/dist/esm/langchain/utils/env.mjs +2 -2
  315. package/dist/esm/langfuse.mjs +60 -76
  316. package/dist/esm/langfuse.mjs.map +1 -1
  317. package/dist/esm/langfuseToolOutputTracing.mjs +267 -395
  318. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  319. package/dist/esm/llm/anthropic/index.mjs +432 -559
  320. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  321. package/dist/esm/llm/anthropic/types.mjs +23 -45
  322. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  323. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +439 -690
  324. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  325. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -249
  326. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  327. package/dist/esm/llm/anthropic/utils/output_parsers.mjs +3 -0
  328. package/dist/esm/llm/anthropic/utils/tools.mjs +12 -24
  329. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  330. package/dist/esm/llm/bedrock/index.mjs +195 -238
  331. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  332. package/dist/esm/llm/bedrock/toolCache.mjs +84 -104
  333. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  334. package/dist/esm/llm/bedrock/utils/index.mjs +3 -0
  335. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +357 -618
  336. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  337. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +105 -147
  338. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  339. package/dist/esm/llm/fake.mjs +86 -94
  340. package/dist/esm/llm/fake.mjs.map +1 -1
  341. package/dist/esm/llm/google/index.mjs +183 -235
  342. package/dist/esm/llm/google/index.mjs.map +1 -1
  343. package/dist/esm/llm/google/utils/common.mjs +397 -666
  344. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  345. package/dist/esm/llm/google/utils/zod_to_genai_parameters.mjs +3 -0
  346. package/dist/esm/llm/init.mjs +44 -51
  347. package/dist/esm/llm/init.mjs.map +1 -1
  348. package/dist/esm/llm/invoke.mjs +142 -180
  349. package/dist/esm/llm/invoke.mjs.map +1 -1
  350. package/dist/esm/llm/openai/index.mjs +991 -1271
  351. package/dist/esm/llm/openai/index.mjs.map +1 -1
  352. package/dist/esm/llm/openai/utils/index.mjs +188 -312
  353. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  354. package/dist/esm/llm/openrouter/index.mjs +102 -151
  355. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  356. package/dist/esm/llm/openrouter/toolCache.mjs +35 -42
  357. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  358. package/dist/esm/llm/providers.mjs +29 -34
  359. package/dist/esm/llm/providers.mjs.map +1 -1
  360. package/dist/esm/llm/request.mjs +20 -31
  361. package/dist/esm/llm/request.mjs.map +1 -1
  362. package/dist/esm/llm/vertexai/index.mjs +427 -449
  363. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  364. package/dist/esm/main.mjs +99 -87
  365. package/dist/esm/messages/anthropicToolCache.mjs +68 -117
  366. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
  367. package/dist/esm/messages/cache.mjs +308 -399
  368. package/dist/esm/messages/cache.mjs.map +1 -1
  369. package/dist/esm/messages/content.mjs +36 -47
  370. package/dist/esm/messages/content.mjs.map +1 -1
  371. package/dist/esm/messages/contextPruning.mjs +112 -143
  372. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  373. package/dist/esm/messages/contextPruningSettings.mjs +36 -44
  374. package/dist/esm/messages/contextPruningSettings.mjs.map +1 -1
  375. package/dist/esm/messages/core.mjs +254 -393
  376. package/dist/esm/messages/core.mjs.map +1 -1
  377. package/dist/esm/messages/format.mjs +902 -1378
  378. package/dist/esm/messages/format.mjs.map +1 -1
  379. package/dist/esm/messages/ids.mjs +16 -18
  380. package/dist/esm/messages/ids.mjs.map +1 -1
  381. package/dist/esm/messages/index.mjs +13 -0
  382. package/dist/esm/messages/langchain.mjs +18 -16
  383. package/dist/esm/messages/langchain.mjs.map +1 -1
  384. package/dist/esm/messages/prune.mjs +1053 -1514
  385. package/dist/esm/messages/prune.mjs.map +1 -1
  386. package/dist/esm/messages/recency.mjs +77 -93
  387. package/dist/esm/messages/recency.mjs.map +1 -1
  388. package/dist/esm/messages/reducer.mjs +63 -76
  389. package/dist/esm/messages/reducer.mjs.map +1 -1
  390. package/dist/esm/messages/tools.mjs +49 -75
  391. package/dist/esm/messages/tools.mjs.map +1 -1
  392. package/dist/esm/openai/index.mjs +170 -215
  393. package/dist/esm/openai/index.mjs.map +1 -1
  394. package/dist/esm/responses/index.mjs +301 -389
  395. package/dist/esm/responses/index.mjs.map +1 -1
  396. package/dist/esm/run.mjs +903 -1111
  397. package/dist/esm/run.mjs.map +1 -1
  398. package/dist/esm/session/AgentSession.mjs +806 -985
  399. package/dist/esm/session/AgentSession.mjs.map +1 -1
  400. package/dist/esm/session/JsonlSessionStore.mjs +326 -407
  401. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  402. package/dist/esm/session/handlers.mjs +192 -206
  403. package/dist/esm/session/handlers.mjs.map +1 -1
  404. package/dist/esm/session/ids.mjs +9 -8
  405. package/dist/esm/session/ids.mjs.map +1 -1
  406. package/dist/esm/session/index.mjs +5 -0
  407. package/dist/esm/session/messageSerialization.mjs +94 -154
  408. package/dist/esm/session/messageSerialization.mjs.map +1 -1
  409. package/dist/esm/splitStream.mjs +147 -204
  410. package/dist/esm/splitStream.mjs.map +1 -1
  411. package/dist/esm/stream.mjs +854 -1341
  412. package/dist/esm/stream.mjs.map +1 -1
  413. package/dist/esm/summarization/index.mjs +57 -99
  414. package/dist/esm/summarization/index.mjs.map +1 -1
  415. package/dist/esm/summarization/node.mjs +640 -790
  416. package/dist/esm/summarization/node.mjs.map +1 -1
  417. package/dist/esm/tools/BashExecutor.mjs +103 -129
  418. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  419. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +162 -239
  420. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  421. package/dist/esm/tools/Calculator.mjs +34 -36
  422. package/dist/esm/tools/Calculator.mjs.map +1 -1
  423. package/dist/esm/tools/CodeExecutor.mjs +123 -164
  424. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  425. package/dist/esm/tools/CodeSessionFileSummary.mjs +36 -44
  426. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -1
  427. package/dist/esm/tools/ProgrammaticToolCalling.mjs +454 -644
  428. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  429. package/dist/esm/tools/ReadFile.mjs +17 -18
  430. package/dist/esm/tools/ReadFile.mjs.map +1 -1
  431. package/dist/esm/tools/SkillTool.mjs +26 -25
  432. package/dist/esm/tools/SkillTool.mjs.map +1 -1
  433. package/dist/esm/tools/SubagentTool.mjs +59 -59
  434. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  435. package/dist/esm/tools/ToolNode.mjs +2107 -2684
  436. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  437. package/dist/esm/tools/ToolSearch.mjs +659 -804
  438. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  439. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs +248 -338
  440. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -1
  441. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +170 -195
  442. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  443. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +424 -517
  444. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  445. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +91 -122
  446. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  447. package/dist/esm/tools/cloudflare/index.mjs +5 -0
  448. package/dist/esm/tools/eagerEventExecution.mjs +75 -96
  449. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -1
  450. package/dist/esm/tools/handlers.mjs +200 -260
  451. package/dist/esm/tools/handlers.mjs.map +1 -1
  452. package/dist/esm/tools/local/CompileCheckTool.mjs +150 -210
  453. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  454. package/dist/esm/tools/local/FileCheckpointer.mjs +77 -83
  455. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  456. package/dist/esm/tools/local/LocalCodingTools.mjs +760 -1017
  457. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  458. package/dist/esm/tools/local/LocalExecutionEngine.mjs +663 -936
  459. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  460. package/dist/esm/tools/local/LocalExecutionTools.mjs +49 -90
  461. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  462. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +283 -349
  463. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  464. package/dist/esm/tools/local/attachments.mjs +108 -163
  465. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  466. package/dist/esm/tools/local/bashAst.mjs +99 -111
  467. package/dist/esm/tools/local/bashAst.mjs.map +1 -1
  468. package/dist/esm/tools/local/editStrategies.mjs +126 -167
  469. package/dist/esm/tools/local/editStrategies.mjs.map +1 -1
  470. package/dist/esm/tools/local/index.mjs +13 -0
  471. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +136 -216
  472. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  473. package/dist/esm/tools/local/syntaxCheck.mjs +138 -155
  474. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -1
  475. package/dist/esm/tools/local/textEncoding.mjs +25 -21
  476. package/dist/esm/tools/local/textEncoding.mjs.map +1 -1
  477. package/dist/esm/tools/local/workspaceFS.mjs +38 -44
  478. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -1
  479. package/dist/esm/tools/ptcTimeout.mjs +27 -42
  480. package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
  481. package/dist/esm/tools/schema.mjs +24 -21
  482. package/dist/esm/tools/schema.mjs.map +1 -1
  483. package/dist/esm/tools/search/anthropic.mjs +24 -31
  484. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  485. package/dist/esm/tools/search/content.mjs +93 -116
  486. package/dist/esm/tools/search/content.mjs.map +1 -1
  487. package/dist/esm/tools/search/firecrawl.mjs +139 -169
  488. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  489. package/dist/esm/tools/search/format.mjs +128 -194
  490. package/dist/esm/tools/search/format.mjs.map +1 -1
  491. package/dist/esm/tools/search/highlights.mjs +165 -230
  492. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  493. package/dist/esm/tools/search/index.mjs +3 -0
  494. package/dist/esm/tools/search/rerankers.mjs +149 -168
  495. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  496. package/dist/esm/tools/search/schema.mjs +39 -37
  497. package/dist/esm/tools/search/schema.mjs.map +1 -1
  498. package/dist/esm/tools/search/search.mjs +426 -528
  499. package/dist/esm/tools/search/search.mjs.map +1 -1
  500. package/dist/esm/tools/search/serper-scraper.mjs +104 -124
  501. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  502. package/dist/esm/tools/search/tavily-scraper.mjs +127 -178
  503. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -1
  504. package/dist/esm/tools/search/tavily-search.mjs +293 -357
  505. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  506. package/dist/esm/tools/search/tool.mjs +259 -297
  507. package/dist/esm/tools/search/tool.mjs.map +1 -1
  508. package/dist/esm/tools/search/utils.mjs +74 -115
  509. package/dist/esm/tools/search/utils.mjs.map +1 -1
  510. package/dist/esm/tools/skillCatalog.mjs +54 -70
  511. package/dist/esm/tools/skillCatalog.mjs.map +1 -1
  512. package/dist/esm/tools/streamedToolCallSeals.mjs +19 -31
  513. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -1
  514. package/dist/esm/tools/subagent/SubagentExecutor.mjs +612 -768
  515. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  516. package/dist/esm/tools/subagent/index.mjs +2 -0
  517. package/dist/esm/tools/toolOutputReferences.mjs +523 -624
  518. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  519. package/dist/esm/utils/callbacks.mjs +11 -19
  520. package/dist/esm/utils/callbacks.mjs.map +1 -1
  521. package/dist/esm/utils/errors.mjs +70 -93
  522. package/dist/esm/utils/errors.mjs.map +1 -1
  523. package/dist/esm/utils/events.mjs +32 -40
  524. package/dist/esm/utils/events.mjs.map +1 -1
  525. package/dist/esm/utils/graph.mjs +8 -10
  526. package/dist/esm/utils/graph.mjs.map +1 -1
  527. package/dist/esm/utils/handlers.mjs +60 -80
  528. package/dist/esm/utils/handlers.mjs.map +1 -1
  529. package/dist/esm/utils/index.mjs +10 -0
  530. package/dist/esm/utils/llm.mjs +19 -25
  531. package/dist/esm/utils/llm.mjs.map +1 -1
  532. package/dist/esm/utils/misc.mjs +30 -44
  533. package/dist/esm/utils/misc.mjs.map +1 -1
  534. package/dist/esm/utils/run.mjs +50 -64
  535. package/dist/esm/utils/run.mjs.map +1 -1
  536. package/dist/esm/utils/schema.mjs +11 -17
  537. package/dist/esm/utils/schema.mjs.map +1 -1
  538. package/dist/esm/utils/title.mjs +71 -104
  539. package/dist/esm/utils/title.mjs.map +1 -1
  540. package/dist/esm/utils/tokens.mjs +186 -281
  541. package/dist/esm/utils/tokens.mjs.map +1 -1
  542. package/dist/esm/utils/truncation.mjs +95 -112
  543. package/dist/esm/utils/truncation.mjs.map +1 -1
  544. package/dist/types/messages/format.d.ts +5 -0
  545. package/dist/types/tools/search/tool.d.ts +17 -0
  546. package/dist/types/tools/search/types.d.ts +4 -0
  547. package/package.json +11 -17
  548. package/src/llm/anthropic/llm.spec.ts +36 -0
  549. package/src/llm/anthropic/utils/message_inputs.ts +45 -3
  550. package/src/llm/anthropic/utils/message_outputs.ts +6 -2
  551. package/src/llm/anthropic/utils/streaming-tool-input.test.ts +186 -0
  552. package/src/messages/cache.test.ts +122 -0
  553. package/src/messages/cache.ts +25 -1
  554. package/src/messages/format.ts +9 -0
  555. package/src/messages/formatAgentMessages.skills.test.ts +100 -0
  556. package/src/tools/search/highlights.ts +9 -1
  557. package/src/tools/search/search.ts +41 -3
  558. package/src/tools/search/source-processing.test.ts +373 -0
  559. package/src/tools/search/tool.ts +22 -2
  560. package/src/tools/search/types.ts +4 -0
  561. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  562. package/dist/cjs/langchain/index.cjs.map +0 -1
  563. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  564. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  565. package/dist/cjs/langchain/messages.cjs.map +0 -1
  566. package/dist/cjs/langchain/openai.cjs.map +0 -1
  567. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  568. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  569. package/dist/cjs/langchain/tools.cjs.map +0 -1
  570. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  571. package/dist/cjs/main.cjs.map +0 -1
  572. package/dist/esm/langchain/google-common.mjs.map +0 -1
  573. package/dist/esm/langchain/index.mjs.map +0 -1
  574. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  575. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  576. package/dist/esm/langchain/messages.mjs.map +0 -1
  577. package/dist/esm/langchain/openai.mjs.map +0 -1
  578. package/dist/esm/langchain/prompts.mjs.map +0 -1
  579. package/dist/esm/langchain/runnables.mjs.map +0 -1
  580. package/dist/esm/langchain/tools.mjs.map +0 -1
  581. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  582. package/dist/esm/main.mjs.map +0 -1
@@ -1,182 +1,163 @@
1
- 'use strict';
2
-
3
- var path = require('path');
4
- var LocalExecutionEngine = require('./LocalExecutionEngine.cjs');
5
-
1
+ const require_LocalExecutionEngine = require("./LocalExecutionEngine.cjs");
2
+ let path = require("path");
3
+ //#region src/tools/local/syntaxCheck.ts
6
4
  /**
7
- * Per-file syntax check used by `edit_file` / `write_file` to surface
8
- * obvious errors immediately after the write — strictly cheaper than
9
- * full LSP integration and catches the bulk of "you broke the file"
10
- * regressions a vision-less agent loop would otherwise miss until
11
- * the next call.
12
- *
13
- * Each checker is a tiny shell-out (or in-process function) keyed on
14
- * file extension. Failures are returned as a single short message;
15
- * the wiring layer decides whether to append it to the tool result
16
- * advisorily (`auto`) or to throw and force the model to react
17
- * (`strict`).
18
- *
19
- * We deliberately do NOT cover TypeScript here because per-file `tsc`
20
- * is slow and per-file syntax (without type info) misses most TS
21
- * errors anyway. Use the project-level `compile_check` tool for that.
22
- */
23
- // Per-backend × per-env cache. Codex P2 #40 — keying by spawn
24
- // backend alone misses env-driven availability changes (e.g. PATH
25
- // loses node between Runs that share the same backend). Same fix
26
- // shape as the ripgrep cache (Codex P1 #34).
27
- let probeCacheByBackend = new WeakMap();
5
+ * Per-file syntax check used by `edit_file` / `write_file` to surface
6
+ * obvious errors immediately after the write — strictly cheaper than
7
+ * full LSP integration and catches the bulk of "you broke the file"
8
+ * regressions a vision-less agent loop would otherwise miss until
9
+ * the next call.
10
+ *
11
+ * Each checker is a tiny shell-out (or in-process function) keyed on
12
+ * file extension. Failures are returned as a single short message;
13
+ * the wiring layer decides whether to append it to the tool result
14
+ * advisorily (`auto`) or to throw and force the model to react
15
+ * (`strict`).
16
+ *
17
+ * We deliberately do NOT cover TypeScript here because per-file `tsc`
18
+ * is slow and per-file syntax (without type info) misses most TS
19
+ * errors anyway. Use the project-level `compile_check` tool for that.
20
+ */
21
+ let probeCacheByBackend = /* @__PURE__ */ new WeakMap();
28
22
  function envCacheKey(env) {
29
- if (env == null)
30
- return '';
31
- const sorted = {};
32
- for (const k of Object.keys(env).sort()) {
33
- sorted[k] = env[k];
34
- }
35
- return JSON.stringify(sorted);
23
+ if (env == null) return "";
24
+ const sorted = {};
25
+ for (const k of Object.keys(env).sort()) sorted[k] = env[k];
26
+ return JSON.stringify(sorted);
36
27
  }
37
28
  function cacheFor(config) {
38
- const backend = LocalExecutionEngine.getSpawn(config);
39
- let envMap = probeCacheByBackend.get(backend);
40
- if (envMap == null) {
41
- envMap = new Map();
42
- probeCacheByBackend.set(backend, envMap);
43
- }
44
- const envKey = envCacheKey(config.env);
45
- let entry = envMap.get(envKey);
46
- if (entry == null) {
47
- entry = {};
48
- envMap.set(envKey, entry);
49
- }
50
- return entry;
29
+ const backend = require_LocalExecutionEngine.getSpawn(config);
30
+ let envMap = probeCacheByBackend.get(backend);
31
+ if (envMap == null) {
32
+ envMap = /* @__PURE__ */ new Map();
33
+ probeCacheByBackend.set(backend, envMap);
34
+ }
35
+ const envKey = envCacheKey(config.env);
36
+ let entry = envMap.get(envKey);
37
+ if (entry == null) {
38
+ entry = {};
39
+ envMap.set(envKey, entry);
40
+ }
41
+ return entry;
51
42
  }
52
43
  async function probe(command, args, cached, config) {
53
- const entry = cacheFor(config);
54
- let probePromise = entry[cached];
55
- if (probePromise == null) {
56
- probePromise = LocalExecutionEngine.spawnLocalProcess(command, args, { ...config, timeoutMs: 5000, sandbox: { enabled: false } }, { internal: true })
57
- .then((result) => result != null && result.exitCode === 0)
58
- .catch(() => false);
59
- entry[cached] = probePromise;
60
- }
61
- return probePromise;
44
+ const entry = cacheFor(config);
45
+ let probePromise = entry[cached];
46
+ if (probePromise == null) {
47
+ probePromise = require_LocalExecutionEngine.spawnLocalProcess(command, args, {
48
+ ...config,
49
+ timeoutMs: 5e3,
50
+ sandbox: { enabled: false }
51
+ }, { internal: true }).then((result) => result != null && result.exitCode === 0).catch(() => false);
52
+ entry[cached] = probePromise;
53
+ }
54
+ return probePromise;
62
55
  }
63
56
  /**
64
- * Test-only reset hook. Clears the per-backend probe cache so tests
65
- * can swap in mocked spawn backends and reprobe deterministically.
66
- *
67
- * @internal Not part of the public SDK surface.
68
- */
57
+ * Test-only reset hook. Clears the per-backend probe cache so tests
58
+ * can swap in mocked spawn backends and reprobe deterministically.
59
+ *
60
+ * @internal Not part of the public SDK surface.
61
+ */
69
62
  function _resetSyntaxCheckProbeCacheForTests() {
70
- probeCacheByBackend = new WeakMap();
63
+ probeCacheByBackend = /* @__PURE__ */ new WeakMap();
71
64
  }
72
- const jsCheck = async (path, config) => {
73
- if (!(await probe('node', ['--version'], 'hasNode', config))) {
74
- return { ok: true };
75
- }
76
- const result = await LocalExecutionEngine.spawnLocalProcess('node', ['--check', path], { ...config, timeoutMs: 5000, sandbox: { enabled: false } }, { internal: true });
77
- if (result.exitCode === 0)
78
- return { ok: true };
79
- return {
80
- ok: false,
81
- checker: 'node --check',
82
- output: result.stderr.trim() || result.stdout.trim() || 'syntax error',
83
- };
65
+ const jsCheck = async (path$1, config) => {
66
+ if (!await probe("node", ["--version"], "hasNode", config)) return { ok: true };
67
+ const result = await require_LocalExecutionEngine.spawnLocalProcess("node", ["--check", path$1], {
68
+ ...config,
69
+ timeoutMs: 5e3,
70
+ sandbox: { enabled: false }
71
+ }, { internal: true });
72
+ if (result.exitCode === 0) return { ok: true };
73
+ return {
74
+ ok: false,
75
+ checker: "node --check",
76
+ output: result.stderr.trim() || result.stdout.trim() || "syntax error"
77
+ };
84
78
  };
85
- const pythonCheck = async (path, config) => {
86
- if (!(await probe('python3', ['--version'], 'hasPython', config))) {
87
- return { ok: true };
88
- }
89
- const program = 'import py_compile, sys\n' +
90
- 'try:\n' +
91
- ' py_compile.compile(sys.argv[1], doraise=True)\n' +
92
- 'except py_compile.PyCompileError as e:\n' +
93
- ' print(e.msg.strip(), file=sys.stderr)\n' +
94
- ' sys.exit(1)\n';
95
- const result = await LocalExecutionEngine.spawnLocalProcess('python3', ['-c', program, path], { ...config, timeoutMs: 5000, sandbox: { enabled: false } }, { internal: true });
96
- if (result.exitCode === 0)
97
- return { ok: true };
98
- return {
99
- ok: false,
100
- checker: 'py_compile',
101
- output: result.stderr.trim() || result.stdout.trim() || 'syntax error',
102
- };
79
+ const pythonCheck = async (path$2, config) => {
80
+ if (!await probe("python3", ["--version"], "hasPython", config)) return { ok: true };
81
+ const result = await require_LocalExecutionEngine.spawnLocalProcess("python3", [
82
+ "-c",
83
+ "import py_compile, sys\ntry:\n py_compile.compile(sys.argv[1], doraise=True)\nexcept py_compile.PyCompileError as e:\n print(e.msg.strip(), file=sys.stderr)\n sys.exit(1)\n",
84
+ path$2
85
+ ], {
86
+ ...config,
87
+ timeoutMs: 5e3,
88
+ sandbox: { enabled: false }
89
+ }, { internal: true });
90
+ if (result.exitCode === 0) return { ok: true };
91
+ return {
92
+ ok: false,
93
+ checker: "py_compile",
94
+ output: result.stderr.trim() || result.stdout.trim() || "syntax error"
95
+ };
103
96
  };
104
- const jsonCheck = async (path, config) => {
105
- // Route through the configured WorkspaceFS so a Run with a custom
106
- // `local.exec.fs` (in-memory or remote engine) validates the same
107
- // file the write_file/edit_file path actually wrote — pre-fix this
108
- // read went to the host fs and either silently passed (no host
109
- // file → catch returns undefined → ok: true) or read a different
110
- // file with the same absolute path. Codex P1 #24.
111
- const fs = LocalExecutionEngine.getWorkspaceFS(config);
112
- const raw = await fs.readFile(path, 'utf8').catch(() => undefined);
113
- if (raw == null)
114
- return { ok: true };
115
- try {
116
- JSON.parse(raw);
117
- return { ok: true };
118
- }
119
- catch (err) {
120
- return {
121
- ok: false,
122
- checker: 'JSON.parse',
123
- output: err.message,
124
- };
125
- }
97
+ const jsonCheck = async (path$3, config) => {
98
+ const raw = await require_LocalExecutionEngine.getWorkspaceFS(config).readFile(path$3, "utf8").catch(() => void 0);
99
+ if (raw == null) return { ok: true };
100
+ try {
101
+ JSON.parse(raw);
102
+ return { ok: true };
103
+ } catch (err) {
104
+ return {
105
+ ok: false,
106
+ checker: "JSON.parse",
107
+ output: err.message
108
+ };
109
+ }
126
110
  };
127
- const bashCheck = async (path, config) => {
128
- if (!(await probe('bash', ['--version'], 'hasBash', config))) {
129
- return { ok: true };
130
- }
131
- const result = await LocalExecutionEngine.spawnLocalProcess('bash', ['-n', path], { ...config, timeoutMs: 5000, sandbox: { enabled: false } }, { internal: true });
132
- if (result.exitCode === 0)
133
- return { ok: true };
134
- return {
135
- ok: false,
136
- checker: 'bash -n',
137
- output: result.stderr.trim() || result.stdout.trim() || 'syntax error',
138
- };
111
+ const bashCheck = async (path$4, config) => {
112
+ if (!await probe("bash", ["--version"], "hasBash", config)) return { ok: true };
113
+ const result = await require_LocalExecutionEngine.spawnLocalProcess("bash", ["-n", path$4], {
114
+ ...config,
115
+ timeoutMs: 5e3,
116
+ sandbox: { enabled: false }
117
+ }, { internal: true });
118
+ if (result.exitCode === 0) return { ok: true };
119
+ return {
120
+ ok: false,
121
+ checker: "bash -n",
122
+ output: result.stderr.trim() || result.stdout.trim() || "syntax error"
123
+ };
139
124
  };
140
125
  const CHECKERS_BY_EXT = {
141
- '.js': jsCheck,
142
- '.mjs': jsCheck,
143
- '.cjs': jsCheck,
144
- '.jsx': jsCheck,
145
- '.py': pythonCheck,
146
- '.pyw': pythonCheck,
147
- '.json': jsonCheck,
148
- '.sh': bashCheck,
149
- '.bash': bashCheck,
126
+ ".js": jsCheck,
127
+ ".mjs": jsCheck,
128
+ ".cjs": jsCheck,
129
+ ".jsx": jsCheck,
130
+ ".py": pythonCheck,
131
+ ".pyw": pythonCheck,
132
+ ".json": jsonCheck,
133
+ ".sh": bashCheck,
134
+ ".bash": bashCheck
150
135
  };
151
136
  /**
152
- * Run the post-edit syntax check for `absolutePath`. Returns
153
- * `null` when no checker matches the extension (most files), or a
154
- * `SyntaxCheckOutcome`.
155
- *
156
- * Truncates `output` to `maxOutputChars` (default 4096) so a
157
- * 10MB-of-errors transpiler dump can't blow the model context.
158
- */
137
+ * Run the post-edit syntax check for `absolutePath`. Returns
138
+ * `null` when no checker matches the extension (most files), or a
139
+ * `SyntaxCheckOutcome`.
140
+ *
141
+ * Truncates `output` to `maxOutputChars` (default 4096) so a
142
+ * 10MB-of-errors transpiler dump can't blow the model context.
143
+ */
159
144
  async function runPostEditSyntaxCheck(absolutePath, config) {
160
- const ext = path.extname(absolutePath).toLowerCase();
161
- const checker = CHECKERS_BY_EXT[ext];
162
- if (checker == null)
163
- return null;
164
- try {
165
- const result = await checker(absolutePath, config);
166
- if (!result.ok) {
167
- return {
168
- ok: false,
169
- checker: result.checker,
170
- output: result.output.slice(0, 4096),
171
- };
172
- }
173
- return result;
174
- }
175
- catch {
176
- return null;
177
- }
145
+ const checker = CHECKERS_BY_EXT[(0, path.extname)(absolutePath).toLowerCase()];
146
+ if (checker == null) return null;
147
+ try {
148
+ const result = await checker(absolutePath, config);
149
+ if (!result.ok) return {
150
+ ok: false,
151
+ checker: result.checker,
152
+ output: result.output.slice(0, 4096)
153
+ };
154
+ return result;
155
+ } catch {
156
+ return null;
157
+ }
178
158
  }
179
-
159
+ //#endregion
180
160
  exports._resetSyntaxCheckProbeCacheForTests = _resetSyntaxCheckProbeCacheForTests;
181
161
  exports.runPostEditSyntaxCheck = runPostEditSyntaxCheck;
182
- //# sourceMappingURL=syntaxCheck.cjs.map
162
+
163
+ //# sourceMappingURL=syntaxCheck.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"syntaxCheck.cjs","sources":["../../../../src/tools/local/syntaxCheck.ts"],"sourcesContent":["/**\n * Per-file syntax check used by `edit_file` / `write_file` to surface\n * obvious errors immediately after the write — strictly cheaper than\n * full LSP integration and catches the bulk of \"you broke the file\"\n * regressions a vision-less agent loop would otherwise miss until\n * the next call.\n *\n * Each checker is a tiny shell-out (or in-process function) keyed on\n * file extension. Failures are returned as a single short message;\n * the wiring layer decides whether to append it to the tool result\n * advisorily (`auto`) or to throw and force the model to react\n * (`strict`).\n *\n * We deliberately do NOT cover TypeScript here because per-file `tsc`\n * is slow and per-file syntax (without type info) misses most TS\n * errors anyway. Use the project-level `compile_check` tool for that.\n */\n\nimport { extname } from 'path';\nimport type * as t from '@/types';\nimport {\n getSpawn,\n getWorkspaceFS,\n spawnLocalProcess,\n} from './LocalExecutionEngine';\n\nexport type SyntaxCheckOutcome =\n | { ok: true }\n | { ok: false; checker: string; output: string };\n\nexport type SyntaxChecker = (\n path: string,\n config: t.LocalExecutionConfig\n) => Promise<SyntaxCheckOutcome>;\n\n/**\n * Per-backend availability cache for the post-edit syntax-check probe\n * tools (node, python3, bash). Keyed on the *effective spawn backend*\n * — see `getSpawn(config)` in LocalExecutionEngine — so a Run that\n * probes node over Node's child_process can't poison a subsequent Run\n * whose `local.exec.spawn` routes elsewhere (a remote sandbox might\n * have python but not node, etc.).\n *\n * Mirrors the same fix that landed for the ripgrep cache in\n * `LocalCodingTools.ts` after the first round of Codex review.\n * WeakMap keying lets disposed backends GC their entry; the test\n * reset hook re-creates the map.\n */\ntype ProbeKind = 'hasNode' | 'hasPython' | 'hasBash';\ntype ProbeCache = Partial<Record<ProbeKind, Promise<boolean>>>;\n\n// Per-backend × per-env cache. Codex P2 #40 — keying by spawn\n// backend alone misses env-driven availability changes (e.g. PATH\n// loses node between Runs that share the same backend). Same fix\n// shape as the ripgrep cache (Codex P1 #34).\nlet probeCacheByBackend = new WeakMap<\n t.LocalSpawn,\n Map<string, ProbeCache>\n>();\n\nfunction envCacheKey(env: NodeJS.ProcessEnv | undefined): string {\n if (env == null) return '';\n const sorted: Record<string, string | undefined> = {};\n for (const k of Object.keys(env).sort()) {\n sorted[k] = env[k];\n }\n return JSON.stringify(sorted);\n}\n\nfunction cacheFor(\n config: t.LocalExecutionConfig\n): ProbeCache {\n const backend = getSpawn(config);\n let envMap = probeCacheByBackend.get(backend);\n if (envMap == null) {\n envMap = new Map();\n probeCacheByBackend.set(backend, envMap);\n }\n const envKey = envCacheKey(config.env);\n let entry = envMap.get(envKey);\n if (entry == null) {\n entry = {};\n envMap.set(envKey, entry);\n }\n return entry;\n}\n\nasync function probe(\n command: string,\n args: string[],\n cached: ProbeKind,\n config: t.LocalExecutionConfig\n): Promise<boolean> {\n const entry = cacheFor(config);\n let probePromise = entry[cached];\n if (probePromise == null) {\n probePromise = spawnLocalProcess(\n command,\n args,\n { ...config, timeoutMs: 5000, sandbox: { enabled: false } },\n { internal: true }\n )\n .then((result) => result != null && result.exitCode === 0)\n .catch(() => false);\n entry[cached] = probePromise;\n }\n return probePromise;\n}\n\n/**\n * Test-only reset hook. Clears the per-backend probe cache so tests\n * can swap in mocked spawn backends and reprobe deterministically.\n *\n * @internal Not part of the public SDK surface.\n */\nexport function _resetSyntaxCheckProbeCacheForTests(): void {\n probeCacheByBackend = new WeakMap();\n}\n\nconst jsCheck: SyntaxChecker = async (path, config) => {\n if (!(await probe('node', ['--version'], 'hasNode', config))) {\n return { ok: true };\n }\n const result = await spawnLocalProcess(\n 'node',\n ['--check', path],\n { ...config, timeoutMs: 5000, sandbox: { enabled: false } },\n { internal: true }\n );\n if (result.exitCode === 0) return { ok: true };\n return {\n ok: false,\n checker: 'node --check',\n output: result.stderr.trim() || result.stdout.trim() || 'syntax error',\n };\n};\n\nconst pythonCheck: SyntaxChecker = async (path, config) => {\n if (!(await probe('python3', ['--version'], 'hasPython', config))) {\n return { ok: true };\n }\n const program =\n 'import py_compile, sys\\n' +\n 'try:\\n' +\n ' py_compile.compile(sys.argv[1], doraise=True)\\n' +\n 'except py_compile.PyCompileError as e:\\n' +\n ' print(e.msg.strip(), file=sys.stderr)\\n' +\n ' sys.exit(1)\\n';\n const result = await spawnLocalProcess(\n 'python3',\n ['-c', program, path],\n { ...config, timeoutMs: 5000, sandbox: { enabled: false } },\n { internal: true }\n );\n if (result.exitCode === 0) return { ok: true };\n return {\n ok: false,\n checker: 'py_compile',\n output: result.stderr.trim() || result.stdout.trim() || 'syntax error',\n };\n};\n\nconst jsonCheck: SyntaxChecker = async (path, config) => {\n // Route through the configured WorkspaceFS so a Run with a custom\n // `local.exec.fs` (in-memory or remote engine) validates the same\n // file the write_file/edit_file path actually wrote — pre-fix this\n // read went to the host fs and either silently passed (no host\n // file → catch returns undefined → ok: true) or read a different\n // file with the same absolute path. Codex P1 #24.\n const fs = getWorkspaceFS(config);\n const raw = await fs.readFile(path, 'utf8').catch(() => undefined);\n if (raw == null) return { ok: true };\n try {\n JSON.parse(raw);\n return { ok: true };\n } catch (err) {\n return {\n ok: false,\n checker: 'JSON.parse',\n output: (err as Error).message,\n };\n }\n};\n\nconst bashCheck: SyntaxChecker = async (path, config) => {\n if (!(await probe('bash', ['--version'], 'hasBash', config))) {\n return { ok: true };\n }\n const result = await spawnLocalProcess(\n 'bash',\n ['-n', path],\n { ...config, timeoutMs: 5000, sandbox: { enabled: false } },\n { internal: true }\n );\n if (result.exitCode === 0) return { ok: true };\n return {\n ok: false,\n checker: 'bash -n',\n output: result.stderr.trim() || result.stdout.trim() || 'syntax error',\n };\n};\n\nconst CHECKERS_BY_EXT: Record<string, SyntaxChecker> = {\n '.js': jsCheck,\n '.mjs': jsCheck,\n '.cjs': jsCheck,\n '.jsx': jsCheck,\n '.py': pythonCheck,\n '.pyw': pythonCheck,\n '.json': jsonCheck,\n '.sh': bashCheck,\n '.bash': bashCheck,\n};\n\n/**\n * Run the post-edit syntax check for `absolutePath`. Returns\n * `null` when no checker matches the extension (most files), or a\n * `SyntaxCheckOutcome`.\n *\n * Truncates `output` to `maxOutputChars` (default 4096) so a\n * 10MB-of-errors transpiler dump can't blow the model context.\n */\nexport async function runPostEditSyntaxCheck(\n absolutePath: string,\n config: t.LocalExecutionConfig\n): Promise<SyntaxCheckOutcome | null> {\n const ext = extname(absolutePath).toLowerCase();\n const checker = (CHECKERS_BY_EXT as Record<string, SyntaxChecker | undefined>)[ext];\n if (checker == null) return null;\n try {\n const result = await checker(absolutePath, config);\n if (!result.ok) {\n return {\n ok: false,\n checker: result.checker,\n output: result.output.slice(0, 4096),\n };\n }\n return result;\n } catch {\n return null;\n }\n}\n"],"names":["getSpawn","spawnLocalProcess","getWorkspaceFS","extname"],"mappings":"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"}
1
+ {"version":3,"file":"syntaxCheck.cjs","names":["getSpawn","spawnLocalProcess","path","getWorkspaceFS"],"sources":["../../../../src/tools/local/syntaxCheck.ts"],"sourcesContent":["/**\n * Per-file syntax check used by `edit_file` / `write_file` to surface\n * obvious errors immediately after the write — strictly cheaper than\n * full LSP integration and catches the bulk of \"you broke the file\"\n * regressions a vision-less agent loop would otherwise miss until\n * the next call.\n *\n * Each checker is a tiny shell-out (or in-process function) keyed on\n * file extension. Failures are returned as a single short message;\n * the wiring layer decides whether to append it to the tool result\n * advisorily (`auto`) or to throw and force the model to react\n * (`strict`).\n *\n * We deliberately do NOT cover TypeScript here because per-file `tsc`\n * is slow and per-file syntax (without type info) misses most TS\n * errors anyway. Use the project-level `compile_check` tool for that.\n */\n\nimport { extname } from 'path';\nimport type * as t from '@/types';\nimport {\n getSpawn,\n getWorkspaceFS,\n spawnLocalProcess,\n} from './LocalExecutionEngine';\n\nexport type SyntaxCheckOutcome =\n | { ok: true }\n | { ok: false; checker: string; output: string };\n\nexport type SyntaxChecker = (\n path: string,\n config: t.LocalExecutionConfig\n) => Promise<SyntaxCheckOutcome>;\n\n/**\n * Per-backend availability cache for the post-edit syntax-check probe\n * tools (node, python3, bash). Keyed on the *effective spawn backend*\n * — see `getSpawn(config)` in LocalExecutionEngine — so a Run that\n * probes node over Node's child_process can't poison a subsequent Run\n * whose `local.exec.spawn` routes elsewhere (a remote sandbox might\n * have python but not node, etc.).\n *\n * Mirrors the same fix that landed for the ripgrep cache in\n * `LocalCodingTools.ts` after the first round of Codex review.\n * WeakMap keying lets disposed backends GC their entry; the test\n * reset hook re-creates the map.\n */\ntype ProbeKind = 'hasNode' | 'hasPython' | 'hasBash';\ntype ProbeCache = Partial<Record<ProbeKind, Promise<boolean>>>;\n\n// Per-backend × per-env cache. Codex P2 #40 — keying by spawn\n// backend alone misses env-driven availability changes (e.g. PATH\n// loses node between Runs that share the same backend). Same fix\n// shape as the ripgrep cache (Codex P1 #34).\nlet probeCacheByBackend = new WeakMap<\n t.LocalSpawn,\n Map<string, ProbeCache>\n>();\n\nfunction envCacheKey(env: NodeJS.ProcessEnv | undefined): string {\n if (env == null) return '';\n const sorted: Record<string, string | undefined> = {};\n for (const k of Object.keys(env).sort()) {\n sorted[k] = env[k];\n }\n return JSON.stringify(sorted);\n}\n\nfunction cacheFor(\n config: t.LocalExecutionConfig\n): ProbeCache {\n const backend = getSpawn(config);\n let envMap = probeCacheByBackend.get(backend);\n if (envMap == null) {\n envMap = new Map();\n probeCacheByBackend.set(backend, envMap);\n }\n const envKey = envCacheKey(config.env);\n let entry = envMap.get(envKey);\n if (entry == null) {\n entry = {};\n envMap.set(envKey, entry);\n }\n return entry;\n}\n\nasync function probe(\n command: string,\n args: string[],\n cached: ProbeKind,\n config: t.LocalExecutionConfig\n): Promise<boolean> {\n const entry = cacheFor(config);\n let probePromise = entry[cached];\n if (probePromise == null) {\n probePromise = spawnLocalProcess(\n command,\n args,\n { ...config, timeoutMs: 5000, sandbox: { enabled: false } },\n { internal: true }\n )\n .then((result) => result != null && result.exitCode === 0)\n .catch(() => false);\n entry[cached] = probePromise;\n }\n return probePromise;\n}\n\n/**\n * Test-only reset hook. Clears the per-backend probe cache so tests\n * can swap in mocked spawn backends and reprobe deterministically.\n *\n * @internal Not part of the public SDK surface.\n */\nexport function _resetSyntaxCheckProbeCacheForTests(): void {\n probeCacheByBackend = new WeakMap();\n}\n\nconst jsCheck: SyntaxChecker = async (path, config) => {\n if (!(await probe('node', ['--version'], 'hasNode', config))) {\n return { ok: true };\n }\n const result = await spawnLocalProcess(\n 'node',\n ['--check', path],\n { ...config, timeoutMs: 5000, sandbox: { enabled: false } },\n { internal: true }\n );\n if (result.exitCode === 0) return { ok: true };\n return {\n ok: false,\n checker: 'node --check',\n output: result.stderr.trim() || result.stdout.trim() || 'syntax error',\n };\n};\n\nconst pythonCheck: SyntaxChecker = async (path, config) => {\n if (!(await probe('python3', ['--version'], 'hasPython', config))) {\n return { ok: true };\n }\n const program =\n 'import py_compile, sys\\n' +\n 'try:\\n' +\n ' py_compile.compile(sys.argv[1], doraise=True)\\n' +\n 'except py_compile.PyCompileError as e:\\n' +\n ' print(e.msg.strip(), file=sys.stderr)\\n' +\n ' sys.exit(1)\\n';\n const result = await spawnLocalProcess(\n 'python3',\n ['-c', program, path],\n { ...config, timeoutMs: 5000, sandbox: { enabled: false } },\n { internal: true }\n );\n if (result.exitCode === 0) return { ok: true };\n return {\n ok: false,\n checker: 'py_compile',\n output: result.stderr.trim() || result.stdout.trim() || 'syntax error',\n };\n};\n\nconst jsonCheck: SyntaxChecker = async (path, config) => {\n // Route through the configured WorkspaceFS so a Run with a custom\n // `local.exec.fs` (in-memory or remote engine) validates the same\n // file the write_file/edit_file path actually wrote — pre-fix this\n // read went to the host fs and either silently passed (no host\n // file → catch returns undefined → ok: true) or read a different\n // file with the same absolute path. Codex P1 #24.\n const fs = getWorkspaceFS(config);\n const raw = await fs.readFile(path, 'utf8').catch(() => undefined);\n if (raw == null) return { ok: true };\n try {\n JSON.parse(raw);\n return { ok: true };\n } catch (err) {\n return {\n ok: false,\n checker: 'JSON.parse',\n output: (err as Error).message,\n };\n }\n};\n\nconst bashCheck: SyntaxChecker = async (path, config) => {\n if (!(await probe('bash', ['--version'], 'hasBash', config))) {\n return { ok: true };\n }\n const result = await spawnLocalProcess(\n 'bash',\n ['-n', path],\n { ...config, timeoutMs: 5000, sandbox: { enabled: false } },\n { internal: true }\n );\n if (result.exitCode === 0) return { ok: true };\n return {\n ok: false,\n checker: 'bash -n',\n output: result.stderr.trim() || result.stdout.trim() || 'syntax error',\n };\n};\n\nconst CHECKERS_BY_EXT: Record<string, SyntaxChecker> = {\n '.js': jsCheck,\n '.mjs': jsCheck,\n '.cjs': jsCheck,\n '.jsx': jsCheck,\n '.py': pythonCheck,\n '.pyw': pythonCheck,\n '.json': jsonCheck,\n '.sh': bashCheck,\n '.bash': bashCheck,\n};\n\n/**\n * Run the post-edit syntax check for `absolutePath`. Returns\n * `null` when no checker matches the extension (most files), or a\n * `SyntaxCheckOutcome`.\n *\n * Truncates `output` to `maxOutputChars` (default 4096) so a\n * 10MB-of-errors transpiler dump can't blow the model context.\n */\nexport async function runPostEditSyntaxCheck(\n absolutePath: string,\n config: t.LocalExecutionConfig\n): Promise<SyntaxCheckOutcome | null> {\n const ext = extname(absolutePath).toLowerCase();\n const checker = (CHECKERS_BY_EXT as Record<string, SyntaxChecker | undefined>)[ext];\n if (checker == null) return null;\n try {\n const result = await checker(absolutePath, config);\n if (!result.ok) {\n return {\n ok: false,\n checker: result.checker,\n output: result.output.slice(0, 4096),\n };\n }\n return result;\n } catch {\n return null;\n }\n}\n"],"mappings":"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"}
@@ -1,30 +1,32 @@
1
- 'use strict';
2
-
1
+ //#region src/tools/local/textEncoding.ts
3
2
  /**
4
- * BOM and line-ending preservation helpers for the local engine's
5
- * file-mutating tools. We never *introduce* a BOM or change line
6
- * endings — only preserve what was already on disk so a Windows-
7
- * checked-in source file stays CRLF and a UTF-8-with-BOM JSON file
8
- * keeps its BOM after an edit.
9
- *
10
- * Inspired by opencode's `Bom` helper. Trimmed to the cases that
11
- * actually matter for editing source code (UTF-8 BOM only;
12
- * UTF-16/UTF-32 are out of scope).
13
- */
14
- const UTF8_BOM = '';
3
+ * BOM and line-ending preservation helpers for the local engine's
4
+ * file-mutating tools. We never *introduce* a BOM or change line
5
+ * endings — only preserve what was already on disk so a Windows-
6
+ * checked-in source file stays CRLF and a UTF-8-with-BOM JSON file
7
+ * keeps its BOM after an edit.
8
+ *
9
+ * Inspired by opencode's `Bom` helper. Trimmed to the cases that
10
+ * actually matter for editing source code (UTF-8 BOM only;
11
+ * UTF-16/UTF-32 are out of scope).
12
+ */
13
+ const UTF8_BOM = "";
15
14
  function decodeFile(raw) {
16
- const hasBom = raw.startsWith(UTF8_BOM);
17
- const stripped = hasBom ? raw.slice(1) : raw;
18
- const newline = stripped.includes('\r\n') ? '\r\n' : '\n';
19
- // Internally we always work in LF; encode() restores CRLF on write.
20
- const lf = newline === '\r\n' ? stripped.replace(/\r\n/g, '\n') : stripped;
21
- return { text: lf, hasBom, newline };
15
+ const hasBom = raw.startsWith(UTF8_BOM);
16
+ const stripped = hasBom ? raw.slice(1) : raw;
17
+ const newline = stripped.includes("\r\n") ? "\r\n" : "\n";
18
+ return {
19
+ text: newline === "\r\n" ? stripped.replace(/\r\n/g, "\n") : stripped,
20
+ hasBom,
21
+ newline
22
+ };
22
23
  }
23
24
  function encodeFile(text, encoding) {
24
- const out = encoding.newline === '\r\n' ? text.replace(/\n/g, '\r\n') : text;
25
- return encoding.hasBom ? `${UTF8_BOM}${out}` : out;
25
+ const out = encoding.newline === "\r\n" ? text.replace(/\n/g, "\r\n") : text;
26
+ return encoding.hasBom ? `${UTF8_BOM}${out}` : out;
26
27
  }
27
-
28
+ //#endregion
28
29
  exports.decodeFile = decodeFile;
29
30
  exports.encodeFile = encodeFile;
30
- //# sourceMappingURL=textEncoding.cjs.map
31
+
32
+ //# sourceMappingURL=textEncoding.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"textEncoding.cjs","sources":["../../../../src/tools/local/textEncoding.ts"],"sourcesContent":["/**\n * BOM and line-ending preservation helpers for the local engine's\n * file-mutating tools. We never *introduce* a BOM or change line\n * endings — only preserve what was already on disk so a Windows-\n * checked-in source file stays CRLF and a UTF-8-with-BOM JSON file\n * keeps its BOM after an edit.\n *\n * Inspired by opencode's `Bom` helper. Trimmed to the cases that\n * actually matter for editing source code (UTF-8 BOM only;\n * UTF-16/UTF-32 are out of scope).\n */\n\nconst UTF8_BOM = '';\n\nexport interface EncodedFile {\n /** File contents with BOM stripped. */\n text: string;\n /** Whether the on-disk file started with a UTF-8 BOM. */\n hasBom: boolean;\n /** Detected newline style. CRLF wins if any CRLF is present. */\n newline: '\\n' | '\\r\\n';\n}\n\nexport function decodeFile(raw: string): EncodedFile {\n const hasBom = raw.startsWith(UTF8_BOM);\n const stripped = hasBom ? raw.slice(1) : raw;\n const newline = stripped.includes('\\r\\n') ? '\\r\\n' : '\\n';\n // Internally we always work in LF; encode() restores CRLF on write.\n const lf = newline === '\\r\\n' ? stripped.replace(/\\r\\n/g, '\\n') : stripped;\n return { text: lf, hasBom, newline };\n}\n\nexport function encodeFile(text: string, encoding: EncodedFile): string {\n const out =\n encoding.newline === '\\r\\n' ? text.replace(/\\n/g, '\\r\\n') : text;\n return encoding.hasBom ? `${UTF8_BOM}${out}` : out;\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;AAUG;AAEH,MAAM,QAAQ,GAAG,GAAG;AAWd,SAAU,UAAU,CAAC,GAAW,EAAA;IACpC,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC;AACvC,IAAA,MAAM,QAAQ,GAAG,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG;AAC5C,IAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI;;IAEzD,MAAM,EAAE,GAAG,OAAO,KAAK,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,QAAQ;IAC1E,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;AACtC;AAEM,SAAU,UAAU,CAAC,IAAY,EAAE,QAAqB,EAAA;IAC5D,MAAM,GAAG,GACP,QAAQ,CAAC,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI;AAClE,IAAA,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAA,EAAG,QAAQ,CAAA,EAAG,GAAG,CAAA,CAAE,GAAG,GAAG;AACpD;;;;;"}
1
+ {"version":3,"file":"textEncoding.cjs","names":[],"sources":["../../../../src/tools/local/textEncoding.ts"],"sourcesContent":["/**\n * BOM and line-ending preservation helpers for the local engine's\n * file-mutating tools. We never *introduce* a BOM or change line\n * endings — only preserve what was already on disk so a Windows-\n * checked-in source file stays CRLF and a UTF-8-with-BOM JSON file\n * keeps its BOM after an edit.\n *\n * Inspired by opencode's `Bom` helper. Trimmed to the cases that\n * actually matter for editing source code (UTF-8 BOM only;\n * UTF-16/UTF-32 are out of scope).\n */\n\nconst UTF8_BOM = '';\n\nexport interface EncodedFile {\n /** File contents with BOM stripped. */\n text: string;\n /** Whether the on-disk file started with a UTF-8 BOM. */\n hasBom: boolean;\n /** Detected newline style. CRLF wins if any CRLF is present. */\n newline: '\\n' | '\\r\\n';\n}\n\nexport function decodeFile(raw: string): EncodedFile {\n const hasBom = raw.startsWith(UTF8_BOM);\n const stripped = hasBom ? raw.slice(1) : raw;\n const newline = stripped.includes('\\r\\n') ? '\\r\\n' : '\\n';\n // Internally we always work in LF; encode() restores CRLF on write.\n const lf = newline === '\\r\\n' ? stripped.replace(/\\r\\n/g, '\\n') : stripped;\n return { text: lf, hasBom, newline };\n}\n\nexport function encodeFile(text: string, encoding: EncodedFile): string {\n const out =\n encoding.newline === '\\r\\n' ? text.replace(/\\n/g, '\\r\\n') : text;\n return encoding.hasBom ? `${UTF8_BOM}${out}` : out;\n}\n"],"mappings":";;;;;;;;;;;;AAYA,MAAM,WAAW;AAWjB,SAAgB,WAAW,KAA0B;CACnD,MAAM,SAAS,IAAI,WAAW,QAAQ;CACtC,MAAM,WAAW,SAAS,IAAI,MAAM,CAAC,IAAI;CACzC,MAAM,UAAU,SAAS,SAAS,MAAM,IAAI,SAAS;CAGrD,OAAO;EAAE,MADE,YAAY,SAAS,SAAS,QAAQ,SAAS,IAAI,IAAI;EAC/C;EAAQ;CAAQ;AACrC;AAEA,SAAgB,WAAW,MAAc,UAA+B;CACtE,MAAM,MACJ,SAAS,YAAY,SAAS,KAAK,QAAQ,OAAO,MAAM,IAAI;CAC9D,OAAO,SAAS,SAAS,GAAG,WAAW,QAAQ;AACjD"}
@@ -1,51 +1,43 @@
1
- 'use strict';
2
-
3
- var promises = require('fs/promises');
4
-
1
+ let fs_promises = require("fs/promises");
2
+ //#region src/tools/local/workspaceFS.ts
5
3
  /**
6
- * Engine-agnostic filesystem seam for the local-coding tool suite.
7
- *
8
- * The current "local" engine maps every operation to Node's
9
- * `fs/promises` against the host machine. A future engine — e.g. a
10
- * stateful remote sandbox (e2b / Modal / Daytona / ssh-jail) —
11
- * supplies its own `WorkspaceFS` implementation and reuses every
12
- * tool factory unchanged. Same fuzzy-match `edit_file`, same
13
- * checkpointer, same syntax-check, same image attachments — only
14
- * the underlying I/O changes.
15
- *
16
- * Path semantics belong to the implementation. The local engine
17
- * interprets paths as host filesystem paths; a remote engine would
18
- * interpret them as remote-namespace paths. Tool factories don't
19
- * inspect the strings beyond passing them through.
20
- *
21
- * Keep this surface minimal. Add a method only when an existing
22
- * tool genuinely needs it; resist the temptation to mirror all of
23
- * `fs/promises`.
24
- */
4
+ * Engine-agnostic filesystem seam for the local-coding tool suite.
5
+ *
6
+ * The current "local" engine maps every operation to Node's
7
+ * `fs/promises` against the host machine. A future engine — e.g. a
8
+ * stateful remote sandbox (e2b / Modal / Daytona / ssh-jail) —
9
+ * supplies its own `WorkspaceFS` implementation and reuses every
10
+ * tool factory unchanged. Same fuzzy-match `edit_file`, same
11
+ * checkpointer, same syntax-check, same image attachments — only
12
+ * the underlying I/O changes.
13
+ *
14
+ * Path semantics belong to the implementation. The local engine
15
+ * interprets paths as host filesystem paths; a remote engine would
16
+ * interpret them as remote-namespace paths. Tool factories don't
17
+ * inspect the strings beyond passing them through.
18
+ *
19
+ * Keep this surface minimal. Add a method only when an existing
20
+ * tool genuinely needs it; resist the temptation to mirror all of
21
+ * `fs/promises`.
22
+ */
25
23
  /**
26
- * Default `WorkspaceFS` backed by Node's `fs/promises` module.
27
- * Returned by `getWorkspaceFS(config)` when the host hasn't supplied
28
- * an override on `local.exec.fs`.
29
- */
24
+ * Default `WorkspaceFS` backed by Node's `fs/promises` module.
25
+ * Returned by `getWorkspaceFS(config)` when the host hasn't supplied
26
+ * an override on `local.exec.fs`.
27
+ */
30
28
  const nodeWorkspaceFS = {
31
- // The runtime impl ignores the encoding-vs-buffer distinction; the
32
- // overload signatures above are what callers see.
33
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
- readFile: ((path, encoding) => encoding != null
35
- ? promises.readFile(path, encoding)
36
- : promises.readFile(path)),
37
- writeFile: (path, content, options) => promises.writeFile(path, content, options ?? 'utf8'),
38
- stat: (path) => promises.stat(path),
39
- readdir: ((path, options) => options?.withFileTypes === true
40
- ? promises.readdir(path, { withFileTypes: true })
41
- : promises.readdir(path)),
42
- mkdir: async (path, options) => {
43
- await promises.mkdir(path, options);
44
- },
45
- realpath: (path) => promises.realpath(path),
46
- unlink: (path) => promises.unlink(path),
47
- open: (path, flags) => promises.open(path, flags),
29
+ readFile: ((path, encoding) => encoding != null ? (0, fs_promises.readFile)(path, encoding) : (0, fs_promises.readFile)(path)),
30
+ writeFile: (path, content, options) => (0, fs_promises.writeFile)(path, content, options ?? "utf8"),
31
+ stat: (path) => (0, fs_promises.stat)(path),
32
+ readdir: ((path, options) => options?.withFileTypes === true ? (0, fs_promises.readdir)(path, { withFileTypes: true }) : (0, fs_promises.readdir)(path)),
33
+ mkdir: async (path, options) => {
34
+ await (0, fs_promises.mkdir)(path, options);
35
+ },
36
+ realpath: (path) => (0, fs_promises.realpath)(path),
37
+ unlink: (path) => (0, fs_promises.unlink)(path),
38
+ open: (path, flags) => (0, fs_promises.open)(path, flags)
48
39
  };
49
-
40
+ //#endregion
50
41
  exports.nodeWorkspaceFS = nodeWorkspaceFS;
51
- //# sourceMappingURL=workspaceFS.cjs.map
42
+
43
+ //# sourceMappingURL=workspaceFS.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspaceFS.cjs","sources":["../../../../src/tools/local/workspaceFS.ts"],"sourcesContent":["/**\n * Engine-agnostic filesystem seam for the local-coding tool suite.\n *\n * The current \"local\" engine maps every operation to Node's\n * `fs/promises` against the host machine. A future engine — e.g. a\n * stateful remote sandbox (e2b / Modal / Daytona / ssh-jail) —\n * supplies its own `WorkspaceFS` implementation and reuses every\n * tool factory unchanged. Same fuzzy-match `edit_file`, same\n * checkpointer, same syntax-check, same image attachments — only\n * the underlying I/O changes.\n *\n * Path semantics belong to the implementation. The local engine\n * interprets paths as host filesystem paths; a remote engine would\n * interpret them as remote-namespace paths. Tool factories don't\n * inspect the strings beyond passing them through.\n *\n * Keep this surface minimal. Add a method only when an existing\n * tool genuinely needs it; resist the temptation to mirror all of\n * `fs/promises`.\n */\n\nimport {\n mkdir as fsMkdir,\n open as fsOpen,\n readdir as fsReaddir,\n readFile as fsReadFile,\n realpath as fsRealpath,\n stat as fsStat,\n unlink as fsUnlink,\n writeFile as fsWriteFile,\n} from 'fs/promises';\nimport type { MakeDirectoryOptions, Stats, WriteFileOptions } from 'fs';\nimport type { FileHandle } from 'fs/promises';\n\nexport type ReaddirEntry = {\n name: string;\n isFile(): boolean;\n isDirectory(): boolean;\n isSymbolicLink(): boolean;\n};\n\nexport interface WorkspaceFS {\n readFile(path: string, encoding: 'utf8'): Promise<string>;\n readFile(path: string): Promise<Buffer>;\n writeFile(\n path: string,\n content: string | Buffer,\n options?: WriteFileOptions\n ): Promise<void>;\n stat(path: string): Promise<Stats>;\n readdir(\n path: string,\n options: { withFileTypes: true }\n ): Promise<ReaddirEntry[]>;\n readdir(path: string): Promise<string[]>;\n mkdir(path: string, options?: MakeDirectoryOptions): Promise<void>;\n realpath(path: string): Promise<string>;\n unlink(path: string): Promise<void>;\n /** Open a file for low-level read access (used by binary detection). */\n open(path: string, flags: 'r'): Promise<FileHandle>;\n}\n\n/**\n * Default `WorkspaceFS` backed by Node's `fs/promises` module.\n * Returned by `getWorkspaceFS(config)` when the host hasn't supplied\n * an override on `local.exec.fs`.\n */\nexport const nodeWorkspaceFS: WorkspaceFS = {\n // The runtime impl ignores the encoding-vs-buffer distinction; the\n // overload signatures above are what callers see.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readFile: ((path: string, encoding?: 'utf8') =>\n encoding != null\n ? fsReadFile(path, encoding)\n : fsReadFile(path)) as WorkspaceFS['readFile'],\n writeFile: (path, content, options) =>\n fsWriteFile(path, content, options ?? 'utf8'),\n stat: (path) => fsStat(path),\n readdir: ((path: string, options?: { withFileTypes: true }) =>\n options?.withFileTypes === true\n ? fsReaddir(path, { withFileTypes: true })\n : fsReaddir(path)) as WorkspaceFS['readdir'],\n mkdir: async (path, options) => {\n await fsMkdir(path, options);\n },\n realpath: (path) => fsRealpath(path),\n unlink: (path) => fsUnlink(path),\n open: (path, flags) => fsOpen(path, flags),\n};\n"],"names":["fsReadFile","fsWriteFile","fsStat","fsReaddir","fsMkdir","fsRealpath","fsUnlink","fsOpen"],"mappings":";;;;AAAA;;;;;;;;;;;;;;;;;;;AAmBG;AA2CH;;;;AAIG;AACI,MAAM,eAAe,GAAgB;;;;IAI1C,QAAQ,GAAG,CAAC,IAAY,EAAE,QAAiB,KACzC,QAAQ,IAAI;AACV,UAAEA,iBAAU,CAAC,IAAI,EAAE,QAAQ;AAC3B,UAAEA,iBAAU,CAAC,IAAI,CAAC,CAA4B;AAClD,IAAA,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,KAChCC,kBAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC;IAC/C,IAAI,EAAE,CAAC,IAAI,KAAKC,aAAM,CAAC,IAAI,CAAC;AAC5B,IAAA,OAAO,GAAG,CAAC,IAAY,EAAE,OAAiC,KACxD,OAAO,EAAE,aAAa,KAAK;UACvBC,gBAAS,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;AACzC,UAAEA,gBAAS,CAAC,IAAI,CAAC,CAA2B;AAChD,IAAA,KAAK,EAAE,OAAO,IAAI,EAAE,OAAO,KAAI;AAC7B,QAAA,MAAMC,cAAO,CAAC,IAAI,EAAE,OAAO,CAAC;IAC9B,CAAC;IACD,QAAQ,EAAE,CAAC,IAAI,KAAKC,iBAAU,CAAC,IAAI,CAAC;IACpC,MAAM,EAAE,CAAC,IAAI,KAAKC,eAAQ,CAAC,IAAI,CAAC;AAChC,IAAA,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,KAAKC,aAAM,CAAC,IAAI,EAAE,KAAK,CAAC;;;;;"}
1
+ {"version":3,"file":"workspaceFS.cjs","names":[],"sources":["../../../../src/tools/local/workspaceFS.ts"],"sourcesContent":["/**\n * Engine-agnostic filesystem seam for the local-coding tool suite.\n *\n * The current \"local\" engine maps every operation to Node's\n * `fs/promises` against the host machine. A future engine — e.g. a\n * stateful remote sandbox (e2b / Modal / Daytona / ssh-jail) —\n * supplies its own `WorkspaceFS` implementation and reuses every\n * tool factory unchanged. Same fuzzy-match `edit_file`, same\n * checkpointer, same syntax-check, same image attachments — only\n * the underlying I/O changes.\n *\n * Path semantics belong to the implementation. The local engine\n * interprets paths as host filesystem paths; a remote engine would\n * interpret them as remote-namespace paths. Tool factories don't\n * inspect the strings beyond passing them through.\n *\n * Keep this surface minimal. Add a method only when an existing\n * tool genuinely needs it; resist the temptation to mirror all of\n * `fs/promises`.\n */\n\nimport {\n mkdir as fsMkdir,\n open as fsOpen,\n readdir as fsReaddir,\n readFile as fsReadFile,\n realpath as fsRealpath,\n stat as fsStat,\n unlink as fsUnlink,\n writeFile as fsWriteFile,\n} from 'fs/promises';\nimport type { MakeDirectoryOptions, Stats, WriteFileOptions } from 'fs';\nimport type { FileHandle } from 'fs/promises';\n\nexport type ReaddirEntry = {\n name: string;\n isFile(): boolean;\n isDirectory(): boolean;\n isSymbolicLink(): boolean;\n};\n\nexport interface WorkspaceFS {\n readFile(path: string, encoding: 'utf8'): Promise<string>;\n readFile(path: string): Promise<Buffer>;\n writeFile(\n path: string,\n content: string | Buffer,\n options?: WriteFileOptions\n ): Promise<void>;\n stat(path: string): Promise<Stats>;\n readdir(\n path: string,\n options: { withFileTypes: true }\n ): Promise<ReaddirEntry[]>;\n readdir(path: string): Promise<string[]>;\n mkdir(path: string, options?: MakeDirectoryOptions): Promise<void>;\n realpath(path: string): Promise<string>;\n unlink(path: string): Promise<void>;\n /** Open a file for low-level read access (used by binary detection). */\n open(path: string, flags: 'r'): Promise<FileHandle>;\n}\n\n/**\n * Default `WorkspaceFS` backed by Node's `fs/promises` module.\n * Returned by `getWorkspaceFS(config)` when the host hasn't supplied\n * an override on `local.exec.fs`.\n */\nexport const nodeWorkspaceFS: WorkspaceFS = {\n // The runtime impl ignores the encoding-vs-buffer distinction; the\n // overload signatures above are what callers see.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readFile: ((path: string, encoding?: 'utf8') =>\n encoding != null\n ? fsReadFile(path, encoding)\n : fsReadFile(path)) as WorkspaceFS['readFile'],\n writeFile: (path, content, options) =>\n fsWriteFile(path, content, options ?? 'utf8'),\n stat: (path) => fsStat(path),\n readdir: ((path: string, options?: { withFileTypes: true }) =>\n options?.withFileTypes === true\n ? fsReaddir(path, { withFileTypes: true })\n : fsReaddir(path)) as WorkspaceFS['readdir'],\n mkdir: async (path, options) => {\n await fsMkdir(path, options);\n },\n realpath: (path) => fsRealpath(path),\n unlink: (path) => fsUnlink(path),\n open: (path, flags) => fsOpen(path, flags),\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEA,MAAa,kBAA+B;CAI1C,YAAY,MAAc,aACxB,YAAY,QAAA,GAAA,YAAA,SAAA,CACG,MAAM,QAAQ,KAAA,GAAA,YAAA,SAAA,CACd,IAAI;CACrB,YAAY,MAAM,SAAS,aAAA,GAAA,YAAA,UAAA,CACb,MAAM,SAAS,WAAW,MAAM;CAC9C,OAAO,UAAA,GAAA,YAAA,KAAA,CAAgB,IAAI;CAC3B,WAAW,MAAc,YACvB,SAAS,kBAAkB,QAAA,GAAA,YAAA,QAAA,CACb,MAAM,EAAE,eAAe,KAAK,CAAC,KAAA,GAAA,YAAA,QAAA,CAC7B,IAAI;CACpB,OAAO,OAAO,MAAM,YAAY;EAC9B,OAAA,GAAA,YAAA,MAAA,CAAc,MAAM,OAAO;CAC7B;CACA,WAAW,UAAA,GAAA,YAAA,SAAA,CAAoB,IAAI;CACnC,SAAS,UAAA,GAAA,YAAA,OAAA,CAAkB,IAAI;CAC/B,OAAO,MAAM,WAAA,GAAA,YAAA,KAAA,CAAiB,MAAM,KAAK;AAC3C"}