@librechat/agents 3.4.7 → 3.5.1

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 (924) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +0 -356
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/agents/projection.cjs +0 -9
  4. package/dist/cjs/agents/projection.cjs.map +1 -1
  5. package/dist/cjs/common/constants.cjs +0 -26
  6. package/dist/cjs/common/constants.cjs.map +1 -1
  7. package/dist/cjs/common/enum.cjs +0 -85
  8. package/dist/cjs/common/enum.cjs.map +1 -1
  9. package/dist/cjs/events.cjs +0 -14
  10. package/dist/cjs/events.cjs.map +1 -1
  11. package/dist/cjs/graphs/Graph.cjs +1 -909
  12. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  13. package/dist/cjs/graphs/MultiAgentGraph.cjs +7 -272
  14. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  15. package/dist/cjs/graphs/applyGraphRuntimeConfig.cjs.map +1 -1
  16. package/dist/cjs/graphs/createGraph.cjs.map +1 -1
  17. package/dist/cjs/hitl/askUserQuestion.cjs +0 -53
  18. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -1
  19. package/dist/cjs/hitl/askUserQuestions.cjs +0 -20
  20. package/dist/cjs/hitl/askUserQuestions.cjs.map +1 -1
  21. package/dist/cjs/hitl/askUserQuestionsInterrupt.cjs +0 -6
  22. package/dist/cjs/hitl/askUserQuestionsInterrupt.cjs.map +1 -1
  23. package/dist/cjs/hooks/HookRegistry.cjs +0 -127
  24. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  25. package/dist/cjs/hooks/createToolPolicyHook.cjs +0 -38
  26. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -1
  27. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +0 -77
  28. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  29. package/dist/cjs/hooks/executeHooks.cjs +0 -79
  30. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  31. package/dist/cjs/hooks/index.cjs +0 -16
  32. package/dist/cjs/hooks/index.cjs.map +1 -1
  33. package/dist/cjs/hooks/matchers.cjs +0 -104
  34. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  35. package/dist/cjs/hooks/types.cjs +0 -8
  36. package/dist/cjs/hooks/types.cjs.map +1 -1
  37. package/dist/cjs/instrumentation.cjs +0 -14
  38. package/dist/cjs/instrumentation.cjs.map +1 -1
  39. package/dist/cjs/langfuse.cjs +0 -75
  40. package/dist/cjs/langfuse.cjs.map +1 -1
  41. package/dist/cjs/langfuseConfig.cjs.map +1 -1
  42. package/dist/cjs/langfuseRuntimeContext.cjs +0 -13
  43. package/dist/cjs/langfuseRuntimeContext.cjs.map +1 -1
  44. package/dist/cjs/langfuseRuntimeScope.cjs +0 -4
  45. package/dist/cjs/langfuseRuntimeScope.cjs.map +1 -1
  46. package/dist/cjs/langfuseSpanRegistry.cjs +0 -28
  47. package/dist/cjs/langfuseSpanRegistry.cjs.map +1 -1
  48. package/dist/cjs/langfuseToolOutputTracing.cjs +0 -3
  49. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  50. package/dist/cjs/langfuseTraceShaping.cjs +0 -74
  51. package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
  52. package/dist/cjs/llm/anthropic/index.cjs +0 -3
  53. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  55. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +1 -111
  56. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  57. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +0 -1
  58. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  59. package/dist/cjs/llm/anthropic/utils/stream_events.cjs +0 -8
  60. package/dist/cjs/llm/anthropic/utils/stream_events.cjs.map +1 -1
  61. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  62. package/dist/cjs/llm/bedrock/cachePoints.cjs.map +1 -1
  63. package/dist/cjs/llm/bedrock/index.cjs +1 -95
  64. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  65. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  66. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +0 -78
  67. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  68. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +0 -24
  69. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  70. package/dist/cjs/llm/contextOverflowRecovery.cjs +0 -62
  71. package/dist/cjs/llm/contextOverflowRecovery.cjs.map +1 -1
  72. package/dist/cjs/llm/fake.cjs.map +1 -1
  73. package/dist/cjs/llm/google/index.cjs +2 -21
  74. package/dist/cjs/llm/google/index.cjs.map +1 -1
  75. package/dist/cjs/llm/google/utils/common.cjs +0 -35
  76. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  77. package/dist/cjs/llm/init.cjs +0 -9
  78. package/dist/cjs/llm/init.cjs.map +1 -1
  79. package/dist/cjs/llm/invoke.cjs +1 -270
  80. package/dist/cjs/llm/invoke.cjs.map +1 -1
  81. package/dist/cjs/llm/mistral/index.cjs.map +1 -1
  82. package/dist/cjs/llm/openai/index.cjs +0 -99
  83. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  84. package/dist/cjs/llm/openai/streamMetadata.cjs +0 -21
  85. package/dist/cjs/llm/openai/streamMetadata.cjs.map +1 -1
  86. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  87. package/dist/cjs/llm/openrouter/index.cjs +0 -1
  88. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  89. package/dist/cjs/llm/openrouter/toolCache.cjs +0 -6
  90. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  91. package/dist/cjs/llm/preempt.cjs +0 -75
  92. package/dist/cjs/llm/preempt.cjs.map +1 -1
  93. package/dist/cjs/llm/providers.cjs.map +1 -1
  94. package/dist/cjs/llm/request.cjs +0 -10
  95. package/dist/cjs/llm/request.cjs.map +1 -1
  96. package/dist/cjs/llm/stream/chunkAdapters.cjs +0 -62
  97. package/dist/cjs/llm/stream/chunkAdapters.cjs.map +1 -1
  98. package/dist/cjs/llm/stream/smoother.cjs +0 -58
  99. package/dist/cjs/llm/stream/smoother.cjs.map +1 -1
  100. package/dist/cjs/llm/streamLimits.cjs +4 -293
  101. package/dist/cjs/llm/streamLimits.cjs.map +1 -1
  102. package/dist/cjs/llm/truncation.cjs +0 -36
  103. package/dist/cjs/llm/truncation.cjs.map +1 -1
  104. package/dist/cjs/llm/vertexai/index.cjs +0 -330
  105. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  106. package/dist/cjs/messages/alternation.cjs +0 -43
  107. package/dist/cjs/messages/alternation.cjs.map +1 -1
  108. package/dist/cjs/messages/anthropicToolCache.cjs +0 -45
  109. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
  110. package/dist/cjs/messages/assistantPhase.cjs +0 -12
  111. package/dist/cjs/messages/assistantPhase.cjs.map +1 -1
  112. package/dist/cjs/messages/budget.cjs +0 -9
  113. package/dist/cjs/messages/budget.cjs.map +1 -1
  114. package/dist/cjs/messages/cache.cjs +0 -172
  115. package/dist/cjs/messages/cache.cjs.map +1 -1
  116. package/dist/cjs/messages/content.cjs +0 -9
  117. package/dist/cjs/messages/content.cjs.map +1 -1
  118. package/dist/cjs/messages/contextPruning.cjs +0 -15
  119. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  120. package/dist/cjs/messages/contextPruningSettings.cjs +0 -3
  121. package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -1
  122. package/dist/cjs/messages/core.cjs +0 -48
  123. package/dist/cjs/messages/core.cjs.map +1 -1
  124. package/dist/cjs/messages/format.cjs +1 -345
  125. package/dist/cjs/messages/format.cjs.map +1 -1
  126. package/dist/cjs/messages/handoffCue.cjs +0 -36
  127. package/dist/cjs/messages/handoffCue.cjs.map +1 -1
  128. package/dist/cjs/messages/ids.cjs.map +1 -1
  129. package/dist/cjs/messages/injected.cjs +0 -33
  130. package/dist/cjs/messages/injected.cjs.map +1 -1
  131. package/dist/cjs/messages/langchain.cjs +0 -14
  132. package/dist/cjs/messages/langchain.cjs.map +1 -1
  133. package/dist/cjs/messages/prune.cjs +1 -184
  134. package/dist/cjs/messages/prune.cjs.map +1 -1
  135. package/dist/cjs/messages/recency.cjs +0 -32
  136. package/dist/cjs/messages/recency.cjs.map +1 -1
  137. package/dist/cjs/messages/reducer.cjs +0 -30
  138. package/dist/cjs/messages/reducer.cjs.map +1 -1
  139. package/dist/cjs/messages/tools.cjs +0 -14
  140. package/dist/cjs/messages/tools.cjs.map +1 -1
  141. package/dist/cjs/openai/index.cjs.map +1 -1
  142. package/dist/cjs/prompts/activityLabel.cjs +9 -79
  143. package/dist/cjs/prompts/activityLabel.cjs.map +1 -1
  144. package/dist/cjs/responses/index.cjs.map +1 -1
  145. package/dist/cjs/run.cjs +2 -538
  146. package/dist/cjs/run.cjs.map +1 -1
  147. package/dist/cjs/session/AgentSession.cjs +1 -17
  148. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  149. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  150. package/dist/cjs/session/handlers.cjs +0 -7
  151. package/dist/cjs/session/handlers.cjs.map +1 -1
  152. package/dist/cjs/session/ids.cjs.map +1 -1
  153. package/dist/cjs/session/messageSerialization.cjs +0 -4
  154. package/dist/cjs/session/messageSerialization.cjs.map +1 -1
  155. package/dist/cjs/stream.cjs +1 -93
  156. package/dist/cjs/stream.cjs.map +1 -1
  157. package/dist/cjs/summarization/index.cjs +0 -27
  158. package/dist/cjs/summarization/index.cjs.map +1 -1
  159. package/dist/cjs/summarization/node.cjs +0 -273
  160. package/dist/cjs/summarization/node.cjs.map +1 -1
  161. package/dist/cjs/tools/BashExecutor.cjs +0 -35
  162. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  163. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +0 -24
  164. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  165. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  166. package/dist/cjs/tools/CodeExecutor.cjs +0 -13
  167. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  168. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -1
  169. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +0 -101
  170. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  171. package/dist/cjs/tools/ReadFile.cjs.map +1 -1
  172. package/dist/cjs/tools/SkillTool.cjs +0 -5
  173. package/dist/cjs/tools/SkillTool.cjs.map +1 -1
  174. package/dist/cjs/tools/SubagentTool.cjs +0 -10
  175. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  176. package/dist/cjs/tools/ToolNode.cjs +6 -1038
  177. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  178. package/dist/cjs/tools/ToolSearch.cjs +0 -179
  179. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  180. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -1
  181. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  182. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +0 -39
  183. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  184. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  185. package/dist/cjs/tools/eagerEventExecution.cjs +0 -6
  186. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -1
  187. package/dist/cjs/tools/handlers.cjs +1 -41
  188. package/dist/cjs/tools/handlers.cjs.map +1 -1
  189. package/dist/cjs/tools/intentArg.cjs +1 -132
  190. package/dist/cjs/tools/intentArg.cjs.map +1 -1
  191. package/dist/cjs/tools/local/CompileCheckTool.cjs +0 -25
  192. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  193. package/dist/cjs/tools/local/FileCheckpointer.cjs +0 -23
  194. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  195. package/dist/cjs/tools/local/LocalCodingTools.cjs +0 -80
  196. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  197. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +0 -126
  198. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  199. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  200. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +0 -12
  201. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  202. package/dist/cjs/tools/local/attachments.cjs +0 -44
  203. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  204. package/dist/cjs/tools/local/bashAst.cjs +0 -16
  205. package/dist/cjs/tools/local/bashAst.cjs.map +1 -1
  206. package/dist/cjs/tools/local/editStrategies.cjs +0 -14
  207. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -1
  208. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  209. package/dist/cjs/tools/local/syntaxCheck.cjs +0 -31
  210. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -1
  211. package/dist/cjs/tools/local/textEncoding.cjs +0 -11
  212. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -1
  213. package/dist/cjs/tools/local/workspaceFS.cjs +0 -33
  214. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -1
  215. package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
  216. package/dist/cjs/tools/schema.cjs +0 -8
  217. package/dist/cjs/tools/schema.cjs.map +1 -1
  218. package/dist/cjs/tools/search/anthropic.cjs +0 -9
  219. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  220. package/dist/cjs/tools/search/content.cjs.map +1 -1
  221. package/dist/cjs/tools/search/crw-scraper.cjs +0 -33
  222. package/dist/cjs/tools/search/crw-scraper.cjs.map +1 -1
  223. package/dist/cjs/tools/search/crw-search.cjs +0 -2
  224. package/dist/cjs/tools/search/crw-search.cjs.map +1 -1
  225. package/dist/cjs/tools/search/firecrawl.cjs +0 -25
  226. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  227. package/dist/cjs/tools/search/format.cjs +0 -30
  228. package/dist/cjs/tools/search/format.cjs.map +1 -1
  229. package/dist/cjs/tools/search/highlights.cjs +0 -16
  230. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  231. package/dist/cjs/tools/search/keenable-scraper.cjs +0 -8
  232. package/dist/cjs/tools/search/keenable-scraper.cjs.map +1 -1
  233. package/dist/cjs/tools/search/keenable-search.cjs +0 -7
  234. package/dist/cjs/tools/search/keenable-search.cjs.map +1 -1
  235. package/dist/cjs/tools/search/rerankers.cjs +0 -35
  236. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  237. package/dist/cjs/tools/search/schema.cjs +0 -1
  238. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  239. package/dist/cjs/tools/search/search.cjs +1 -14
  240. package/dist/cjs/tools/search/search.cjs.map +1 -1
  241. package/dist/cjs/tools/search/serper-scraper.cjs +0 -46
  242. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  243. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -1
  244. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  245. package/dist/cjs/tools/search/tool.cjs +0 -25
  246. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  247. package/dist/cjs/tools/search/utils.cjs +0 -8
  248. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  249. package/dist/cjs/tools/skillCatalog.cjs +0 -6
  250. package/dist/cjs/tools/skillCatalog.cjs.map +1 -1
  251. package/dist/cjs/tools/streamedToolCallSeals.cjs +0 -6
  252. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -1
  253. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs +0 -2
  254. package/dist/cjs/tools/subagent/SubagentExecutionRegistry.cjs.map +1 -1
  255. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +3 -213
  256. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  257. package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -1
  258. package/dist/cjs/tools/subagent/childGraphConfig.cjs +0 -4
  259. package/dist/cjs/tools/subagent/childGraphConfig.cjs.map +1 -1
  260. package/dist/cjs/tools/subagent/runtimeLimits.cjs.map +1 -1
  261. package/dist/cjs/tools/toolOutputReferences.cjs +1 -322
  262. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  263. package/dist/cjs/types/hitl.cjs +0 -5
  264. package/dist/cjs/types/hitl.cjs.map +1 -1
  265. package/dist/cjs/utils/callbacks.cjs.map +1 -1
  266. package/dist/cjs/utils/errors.cjs +14 -165
  267. package/dist/cjs/utils/errors.cjs.map +1 -1
  268. package/dist/cjs/utils/events.cjs +0 -10
  269. package/dist/cjs/utils/events.cjs.map +1 -1
  270. package/dist/cjs/utils/graph.cjs.map +1 -1
  271. package/dist/cjs/utils/handlers.cjs +0 -3
  272. package/dist/cjs/utils/handlers.cjs.map +1 -1
  273. package/dist/cjs/utils/llm.cjs +0 -1
  274. package/dist/cjs/utils/llm.cjs.map +1 -1
  275. package/dist/cjs/utils/misc.cjs +0 -16
  276. package/dist/cjs/utils/misc.cjs.map +1 -1
  277. package/dist/cjs/utils/proxy.cjs +0 -26
  278. package/dist/cjs/utils/proxy.cjs.map +1 -1
  279. package/dist/cjs/utils/run.cjs +0 -6
  280. package/dist/cjs/utils/run.cjs.map +1 -1
  281. package/dist/cjs/utils/schema.cjs +0 -5
  282. package/dist/cjs/utils/schema.cjs.map +1 -1
  283. package/dist/cjs/utils/title.cjs +0 -6
  284. package/dist/cjs/utils/title.cjs.map +1 -1
  285. package/dist/cjs/utils/tokens.cjs +0 -113
  286. package/dist/cjs/utils/tokens.cjs.map +1 -1
  287. package/dist/cjs/utils/toolContent.cjs +0 -41
  288. package/dist/cjs/utils/toolContent.cjs.map +1 -1
  289. package/dist/cjs/utils/truncation.cjs +0 -61
  290. package/dist/cjs/utils/truncation.cjs.map +1 -1
  291. package/dist/esm/agents/AgentContext.mjs +0 -356
  292. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  293. package/dist/esm/agents/projection.mjs +0 -9
  294. package/dist/esm/agents/projection.mjs.map +1 -1
  295. package/dist/esm/common/constants.mjs +0 -26
  296. package/dist/esm/common/constants.mjs.map +1 -1
  297. package/dist/esm/common/enum.mjs +0 -85
  298. package/dist/esm/common/enum.mjs.map +1 -1
  299. package/dist/esm/events.mjs +0 -14
  300. package/dist/esm/events.mjs.map +1 -1
  301. package/dist/esm/graphs/Graph.mjs +1 -909
  302. package/dist/esm/graphs/Graph.mjs.map +1 -1
  303. package/dist/esm/graphs/MultiAgentGraph.mjs +7 -272
  304. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  305. package/dist/esm/graphs/applyGraphRuntimeConfig.mjs.map +1 -1
  306. package/dist/esm/graphs/createGraph.mjs.map +1 -1
  307. package/dist/esm/hitl/askUserQuestion.mjs +0 -53
  308. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -1
  309. package/dist/esm/hitl/askUserQuestions.mjs +0 -20
  310. package/dist/esm/hitl/askUserQuestions.mjs.map +1 -1
  311. package/dist/esm/hitl/askUserQuestionsInterrupt.mjs +0 -6
  312. package/dist/esm/hitl/askUserQuestionsInterrupt.mjs.map +1 -1
  313. package/dist/esm/hooks/HookRegistry.mjs +0 -127
  314. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  315. package/dist/esm/hooks/createToolPolicyHook.mjs +0 -38
  316. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -1
  317. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +0 -77
  318. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  319. package/dist/esm/hooks/executeHooks.mjs +0 -79
  320. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  321. package/dist/esm/hooks/index.mjs +0 -16
  322. package/dist/esm/hooks/index.mjs.map +1 -1
  323. package/dist/esm/hooks/matchers.mjs +0 -104
  324. package/dist/esm/hooks/matchers.mjs.map +1 -1
  325. package/dist/esm/hooks/types.mjs +0 -8
  326. package/dist/esm/hooks/types.mjs.map +1 -1
  327. package/dist/esm/instrumentation.mjs +0 -14
  328. package/dist/esm/instrumentation.mjs.map +1 -1
  329. package/dist/esm/langfuse.mjs +0 -75
  330. package/dist/esm/langfuse.mjs.map +1 -1
  331. package/dist/esm/langfuseConfig.mjs.map +1 -1
  332. package/dist/esm/langfuseRuntimeContext.mjs +0 -13
  333. package/dist/esm/langfuseRuntimeContext.mjs.map +1 -1
  334. package/dist/esm/langfuseRuntimeScope.mjs +0 -4
  335. package/dist/esm/langfuseRuntimeScope.mjs.map +1 -1
  336. package/dist/esm/langfuseSpanRegistry.mjs +0 -28
  337. package/dist/esm/langfuseSpanRegistry.mjs.map +1 -1
  338. package/dist/esm/langfuseToolOutputTracing.mjs +0 -3
  339. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  340. package/dist/esm/langfuseTraceShaping.mjs +0 -74
  341. package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
  342. package/dist/esm/llm/anthropic/index.mjs +0 -3
  343. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  344. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  345. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +1 -111
  346. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  347. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +0 -1
  348. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  349. package/dist/esm/llm/anthropic/utils/stream_events.mjs +0 -8
  350. package/dist/esm/llm/anthropic/utils/stream_events.mjs.map +1 -1
  351. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  352. package/dist/esm/llm/bedrock/cachePoints.mjs.map +1 -1
  353. package/dist/esm/llm/bedrock/index.mjs +1 -95
  354. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  355. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  356. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +0 -78
  357. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  358. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +0 -24
  359. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  360. package/dist/esm/llm/contextOverflowRecovery.mjs +0 -62
  361. package/dist/esm/llm/contextOverflowRecovery.mjs.map +1 -1
  362. package/dist/esm/llm/fake.mjs.map +1 -1
  363. package/dist/esm/llm/google/index.mjs +2 -21
  364. package/dist/esm/llm/google/index.mjs.map +1 -1
  365. package/dist/esm/llm/google/utils/common.mjs +0 -35
  366. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  367. package/dist/esm/llm/init.mjs +0 -9
  368. package/dist/esm/llm/init.mjs.map +1 -1
  369. package/dist/esm/llm/invoke.mjs +1 -270
  370. package/dist/esm/llm/invoke.mjs.map +1 -1
  371. package/dist/esm/llm/mistral/index.mjs.map +1 -1
  372. package/dist/esm/llm/openai/index.mjs +0 -99
  373. package/dist/esm/llm/openai/index.mjs.map +1 -1
  374. package/dist/esm/llm/openai/streamMetadata.mjs +0 -21
  375. package/dist/esm/llm/openai/streamMetadata.mjs.map +1 -1
  376. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  377. package/dist/esm/llm/openrouter/index.mjs +0 -1
  378. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  379. package/dist/esm/llm/openrouter/toolCache.mjs +0 -6
  380. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  381. package/dist/esm/llm/preempt.mjs +0 -75
  382. package/dist/esm/llm/preempt.mjs.map +1 -1
  383. package/dist/esm/llm/providers.mjs.map +1 -1
  384. package/dist/esm/llm/request.mjs +0 -10
  385. package/dist/esm/llm/request.mjs.map +1 -1
  386. package/dist/esm/llm/stream/chunkAdapters.mjs +0 -62
  387. package/dist/esm/llm/stream/chunkAdapters.mjs.map +1 -1
  388. package/dist/esm/llm/stream/smoother.mjs +0 -58
  389. package/dist/esm/llm/stream/smoother.mjs.map +1 -1
  390. package/dist/esm/llm/streamLimits.mjs +4 -293
  391. package/dist/esm/llm/streamLimits.mjs.map +1 -1
  392. package/dist/esm/llm/truncation.mjs +0 -36
  393. package/dist/esm/llm/truncation.mjs.map +1 -1
  394. package/dist/esm/llm/vertexai/index.mjs +0 -330
  395. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  396. package/dist/esm/messages/alternation.mjs +0 -43
  397. package/dist/esm/messages/alternation.mjs.map +1 -1
  398. package/dist/esm/messages/anthropicToolCache.mjs +0 -45
  399. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
  400. package/dist/esm/messages/assistantPhase.mjs +0 -12
  401. package/dist/esm/messages/assistantPhase.mjs.map +1 -1
  402. package/dist/esm/messages/budget.mjs +0 -9
  403. package/dist/esm/messages/budget.mjs.map +1 -1
  404. package/dist/esm/messages/cache.mjs +0 -172
  405. package/dist/esm/messages/cache.mjs.map +1 -1
  406. package/dist/esm/messages/content.mjs +0 -9
  407. package/dist/esm/messages/content.mjs.map +1 -1
  408. package/dist/esm/messages/contextPruning.mjs +0 -15
  409. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  410. package/dist/esm/messages/contextPruningSettings.mjs +0 -3
  411. package/dist/esm/messages/contextPruningSettings.mjs.map +1 -1
  412. package/dist/esm/messages/core.mjs +0 -48
  413. package/dist/esm/messages/core.mjs.map +1 -1
  414. package/dist/esm/messages/format.mjs +1 -345
  415. package/dist/esm/messages/format.mjs.map +1 -1
  416. package/dist/esm/messages/handoffCue.mjs +0 -36
  417. package/dist/esm/messages/handoffCue.mjs.map +1 -1
  418. package/dist/esm/messages/ids.mjs.map +1 -1
  419. package/dist/esm/messages/injected.mjs +0 -33
  420. package/dist/esm/messages/injected.mjs.map +1 -1
  421. package/dist/esm/messages/langchain.mjs +0 -14
  422. package/dist/esm/messages/langchain.mjs.map +1 -1
  423. package/dist/esm/messages/prune.mjs +1 -184
  424. package/dist/esm/messages/prune.mjs.map +1 -1
  425. package/dist/esm/messages/recency.mjs +0 -32
  426. package/dist/esm/messages/recency.mjs.map +1 -1
  427. package/dist/esm/messages/reducer.mjs +0 -30
  428. package/dist/esm/messages/reducer.mjs.map +1 -1
  429. package/dist/esm/messages/tools.mjs +0 -14
  430. package/dist/esm/messages/tools.mjs.map +1 -1
  431. package/dist/esm/openai/index.mjs.map +1 -1
  432. package/dist/esm/prompts/activityLabel.mjs +9 -79
  433. package/dist/esm/prompts/activityLabel.mjs.map +1 -1
  434. package/dist/esm/responses/index.mjs.map +1 -1
  435. package/dist/esm/run.mjs +2 -538
  436. package/dist/esm/run.mjs.map +1 -1
  437. package/dist/esm/session/AgentSession.mjs +1 -17
  438. package/dist/esm/session/AgentSession.mjs.map +1 -1
  439. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  440. package/dist/esm/session/handlers.mjs +0 -7
  441. package/dist/esm/session/handlers.mjs.map +1 -1
  442. package/dist/esm/session/ids.mjs.map +1 -1
  443. package/dist/esm/session/messageSerialization.mjs +0 -4
  444. package/dist/esm/session/messageSerialization.mjs.map +1 -1
  445. package/dist/esm/stream.mjs +1 -93
  446. package/dist/esm/stream.mjs.map +1 -1
  447. package/dist/esm/summarization/index.mjs +0 -27
  448. package/dist/esm/summarization/index.mjs.map +1 -1
  449. package/dist/esm/summarization/node.mjs +0 -273
  450. package/dist/esm/summarization/node.mjs.map +1 -1
  451. package/dist/esm/tools/BashExecutor.mjs +0 -35
  452. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  453. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +0 -24
  454. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  455. package/dist/esm/tools/Calculator.mjs.map +1 -1
  456. package/dist/esm/tools/CodeExecutor.mjs +0 -13
  457. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  458. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -1
  459. package/dist/esm/tools/ProgrammaticToolCalling.mjs +0 -101
  460. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  461. package/dist/esm/tools/ReadFile.mjs.map +1 -1
  462. package/dist/esm/tools/SkillTool.mjs +0 -5
  463. package/dist/esm/tools/SkillTool.mjs.map +1 -1
  464. package/dist/esm/tools/SubagentTool.mjs +0 -10
  465. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  466. package/dist/esm/tools/ToolNode.mjs +6 -1038
  467. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  468. package/dist/esm/tools/ToolSearch.mjs +0 -179
  469. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  470. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -1
  471. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  472. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +0 -39
  473. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  474. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  475. package/dist/esm/tools/eagerEventExecution.mjs +0 -6
  476. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -1
  477. package/dist/esm/tools/handlers.mjs +1 -41
  478. package/dist/esm/tools/handlers.mjs.map +1 -1
  479. package/dist/esm/tools/intentArg.mjs +1 -132
  480. package/dist/esm/tools/intentArg.mjs.map +1 -1
  481. package/dist/esm/tools/local/CompileCheckTool.mjs +0 -25
  482. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  483. package/dist/esm/tools/local/FileCheckpointer.mjs +0 -23
  484. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  485. package/dist/esm/tools/local/LocalCodingTools.mjs +0 -80
  486. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  487. package/dist/esm/tools/local/LocalExecutionEngine.mjs +0 -126
  488. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  489. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  490. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +0 -12
  491. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  492. package/dist/esm/tools/local/attachments.mjs +0 -44
  493. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  494. package/dist/esm/tools/local/bashAst.mjs +0 -16
  495. package/dist/esm/tools/local/bashAst.mjs.map +1 -1
  496. package/dist/esm/tools/local/editStrategies.mjs +0 -14
  497. package/dist/esm/tools/local/editStrategies.mjs.map +1 -1
  498. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  499. package/dist/esm/tools/local/syntaxCheck.mjs +0 -31
  500. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -1
  501. package/dist/esm/tools/local/textEncoding.mjs +0 -11
  502. package/dist/esm/tools/local/textEncoding.mjs.map +1 -1
  503. package/dist/esm/tools/local/workspaceFS.mjs +0 -33
  504. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -1
  505. package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
  506. package/dist/esm/tools/schema.mjs +0 -8
  507. package/dist/esm/tools/schema.mjs.map +1 -1
  508. package/dist/esm/tools/search/anthropic.mjs +0 -9
  509. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  510. package/dist/esm/tools/search/content.mjs.map +1 -1
  511. package/dist/esm/tools/search/crw-scraper.mjs +0 -33
  512. package/dist/esm/tools/search/crw-scraper.mjs.map +1 -1
  513. package/dist/esm/tools/search/crw-search.mjs +0 -2
  514. package/dist/esm/tools/search/crw-search.mjs.map +1 -1
  515. package/dist/esm/tools/search/firecrawl.mjs +0 -25
  516. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  517. package/dist/esm/tools/search/format.mjs +0 -30
  518. package/dist/esm/tools/search/format.mjs.map +1 -1
  519. package/dist/esm/tools/search/highlights.mjs +0 -16
  520. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  521. package/dist/esm/tools/search/keenable-scraper.mjs +0 -8
  522. package/dist/esm/tools/search/keenable-scraper.mjs.map +1 -1
  523. package/dist/esm/tools/search/keenable-search.mjs +0 -7
  524. package/dist/esm/tools/search/keenable-search.mjs.map +1 -1
  525. package/dist/esm/tools/search/rerankers.mjs +0 -35
  526. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  527. package/dist/esm/tools/search/schema.mjs +0 -1
  528. package/dist/esm/tools/search/schema.mjs.map +1 -1
  529. package/dist/esm/tools/search/search.mjs +1 -14
  530. package/dist/esm/tools/search/search.mjs.map +1 -1
  531. package/dist/esm/tools/search/serper-scraper.mjs +0 -46
  532. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  533. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -1
  534. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  535. package/dist/esm/tools/search/tool.mjs +0 -25
  536. package/dist/esm/tools/search/tool.mjs.map +1 -1
  537. package/dist/esm/tools/search/utils.mjs +0 -8
  538. package/dist/esm/tools/search/utils.mjs.map +1 -1
  539. package/dist/esm/tools/skillCatalog.mjs +0 -6
  540. package/dist/esm/tools/skillCatalog.mjs.map +1 -1
  541. package/dist/esm/tools/streamedToolCallSeals.mjs +0 -6
  542. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -1
  543. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs +0 -2
  544. package/dist/esm/tools/subagent/SubagentExecutionRegistry.mjs.map +1 -1
  545. package/dist/esm/tools/subagent/SubagentExecutor.mjs +3 -213
  546. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  547. package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -1
  548. package/dist/esm/tools/subagent/childGraphConfig.mjs +0 -4
  549. package/dist/esm/tools/subagent/childGraphConfig.mjs.map +1 -1
  550. package/dist/esm/tools/subagent/runtimeLimits.mjs.map +1 -1
  551. package/dist/esm/tools/toolOutputReferences.mjs +1 -322
  552. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  553. package/dist/esm/types/hitl.mjs +0 -5
  554. package/dist/esm/types/hitl.mjs.map +1 -1
  555. package/dist/esm/utils/callbacks.mjs.map +1 -1
  556. package/dist/esm/utils/errors.mjs +14 -165
  557. package/dist/esm/utils/errors.mjs.map +1 -1
  558. package/dist/esm/utils/events.mjs +0 -10
  559. package/dist/esm/utils/events.mjs.map +1 -1
  560. package/dist/esm/utils/graph.mjs.map +1 -1
  561. package/dist/esm/utils/handlers.mjs +0 -3
  562. package/dist/esm/utils/handlers.mjs.map +1 -1
  563. package/dist/esm/utils/llm.mjs +0 -1
  564. package/dist/esm/utils/llm.mjs.map +1 -1
  565. package/dist/esm/utils/misc.mjs +0 -16
  566. package/dist/esm/utils/misc.mjs.map +1 -1
  567. package/dist/esm/utils/proxy.mjs +0 -26
  568. package/dist/esm/utils/proxy.mjs.map +1 -1
  569. package/dist/esm/utils/run.mjs +0 -6
  570. package/dist/esm/utils/run.mjs.map +1 -1
  571. package/dist/esm/utils/schema.mjs +0 -5
  572. package/dist/esm/utils/schema.mjs.map +1 -1
  573. package/dist/esm/utils/title.mjs +0 -6
  574. package/dist/esm/utils/title.mjs.map +1 -1
  575. package/dist/esm/utils/tokens.mjs +0 -113
  576. package/dist/esm/utils/tokens.mjs.map +1 -1
  577. package/dist/esm/utils/toolContent.mjs +0 -41
  578. package/dist/esm/utils/toolContent.mjs.map +1 -1
  579. package/dist/esm/utils/truncation.mjs +0 -61
  580. package/dist/esm/utils/truncation.mjs.map +1 -1
  581. package/package.json +35 -32
  582. package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +0 -52
  583. package/dist/types/test/mockTools.d.ts +0 -28
  584. package/dist/types/utils/__tests__/fixtures/contextOverflowSignatures.d.ts +0 -40
  585. package/src/__tests__/stream.eagerArgsDivergence.test.ts +0 -911
  586. package/src/__tests__/stream.eagerEventExecution.test.ts +0 -5046
  587. package/src/__tests__/stream.streamLimits.test.ts +0 -1982
  588. package/src/agents/__tests__/AgentContext.anthropic.live.test.ts +0 -448
  589. package/src/agents/__tests__/AgentContext.bedrock.live.test.ts +0 -655
  590. package/src/agents/__tests__/AgentContext.openrouter.live.test.ts +0 -128
  591. package/src/agents/__tests__/AgentContext.overflow.test.ts +0 -205
  592. package/src/agents/__tests__/AgentContext.test.ts +0 -2425
  593. package/src/agents/__tests__/projection.test.ts +0 -73
  594. package/src/agents/__tests__/promptCacheLiveHelpers.ts +0 -175
  595. package/src/aggregator.test.ts +0 -1214
  596. package/src/graphs/__tests__/Graph.breakerLifecycle.test.ts +0 -273
  597. package/src/graphs/__tests__/Graph.closeRunStep.test.ts +0 -385
  598. package/src/graphs/__tests__/Graph.contextOverflow.test.ts +0 -1766
  599. package/src/graphs/__tests__/Graph.preemptSignal.test.ts +0 -126
  600. package/src/graphs/__tests__/Graph.reasoning.test.ts +0 -1717
  601. package/src/graphs/__tests__/Graph.subagentResumeState.test.ts +0 -80
  602. package/src/graphs/__tests__/MultiAgentGraph.test.ts +0 -177
  603. package/src/graphs/__tests__/composition.smoke.test.ts +0 -509
  604. package/src/graphs/__tests__/createGraph.test.ts +0 -206
  605. package/src/hooks/__tests__/HookRegistry.test.ts +0 -334
  606. package/src/hooks/__tests__/compactHooks.test.ts +0 -250
  607. package/src/hooks/__tests__/createToolPolicyHook.test.ts +0 -268
  608. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +0 -405
  609. package/src/hooks/__tests__/executeHooks.test.ts +0 -1294
  610. package/src/hooks/__tests__/integration.test.ts +0 -337
  611. package/src/hooks/__tests__/matchers.test.ts +0 -238
  612. package/src/hooks/__tests__/preemptBoundary.test.ts +0 -152
  613. package/src/hooks/__tests__/toolHooks.test.ts +0 -669
  614. package/src/llm/__tests__/contextOverflowRecovery.test.ts +0 -401
  615. package/src/llm/__tests__/fallbackOverflow.test.ts +0 -287
  616. package/src/llm/anthropic/Jacob_Lee_Resume_2023.pdf +0 -0
  617. package/src/llm/anthropic/inherited-content-utils.spec.ts +0 -249
  618. package/src/llm/anthropic/inherited-stream-events.spec.ts +0 -1259
  619. package/src/llm/anthropic/inherited-strict.spec.ts +0 -302
  620. package/src/llm/anthropic/llm.spec.ts +0 -3394
  621. package/src/llm/anthropic/utils/cross-provider-reasoning.test.ts +0 -383
  622. package/src/llm/anthropic/utils/cross-provider-server-tools.test.ts +0 -110
  623. package/src/llm/anthropic/utils/server-tool-inputs.test.ts +0 -508
  624. package/src/llm/anthropic/utils/streaming-tool-input.test.ts +0 -361
  625. package/src/llm/anthropic/utils/stripPrefillCache.test.ts +0 -111
  626. package/src/llm/anthropic/utils/tool-id-normalization.test.ts +0 -287
  627. package/src/llm/bedrock/inherited-cache.spec.ts +0 -144
  628. package/src/llm/bedrock/inherited.spec.ts +0 -724
  629. package/src/llm/bedrock/llm.spec.ts +0 -1533
  630. package/src/llm/bedrock/streamSealDispatch.test.ts +0 -331
  631. package/src/llm/bedrock/toolCache.test.ts +0 -194
  632. package/src/llm/bedrock/utils/cross-provider-reasoning.test.ts +0 -131
  633. package/src/llm/bedrock/utils/cross-provider-server-tools.test.ts +0 -122
  634. package/src/llm/bedrock/utils/message_inputs.test.ts +0 -650
  635. package/src/llm/bedrock/utils/message_outputs.test.ts +0 -85
  636. package/src/llm/bedrock/utils/toolResultCachePoint.test.ts +0 -118
  637. package/src/llm/custom-chat-models.smoke.test.ts +0 -1966
  638. package/src/llm/google/data/gettysburg10.wav +0 -0
  639. package/src/llm/google/data/hotdog.jpg +0 -0
  640. package/src/llm/google/inherited-stream-events.spec.ts +0 -350
  641. package/src/llm/google/llm.spec.ts +0 -1388
  642. package/src/llm/google/streamSmoothing.test.ts +0 -121
  643. package/src/llm/google/utils/common.test.ts +0 -196
  644. package/src/llm/invoke.alternation.test.ts +0 -87
  645. package/src/llm/invoke.handoffCue.test.ts +0 -112
  646. package/src/llm/invoke.streamLimits.test.ts +0 -142
  647. package/src/llm/invoke.test.ts +0 -1198
  648. package/src/llm/mistral/streamSmoothing.test.ts +0 -97
  649. package/src/llm/openai/cacheWriteTokens.test.ts +0 -112
  650. package/src/llm/openai/contentBlocks.test.ts +0 -381
  651. package/src/llm/openai/deepseek.test.ts +0 -747
  652. package/src/llm/openai/inherited-deepseek.spec.ts +0 -347
  653. package/src/llm/openai/inherited-xai.spec.ts +0 -416
  654. package/src/llm/openai/llm.spec.ts +0 -1774
  655. package/src/llm/openai/managedRequests.test.ts +0 -182
  656. package/src/llm/openai/sequentialToolCallSeals.test.ts +0 -199
  657. package/src/llm/openai/streamMetadata.spec.ts +0 -86
  658. package/src/llm/openai/streamMetadataDedup.spec.ts +0 -166
  659. package/src/llm/openai/utils/isReasoningModel.test.ts +0 -90
  660. package/src/llm/openai/utils/messages.test.ts +0 -488
  661. package/src/llm/openrouter/reasoning.test.ts +0 -561
  662. package/src/llm/openrouter/toolCache.test.ts +0 -134
  663. package/src/llm/preempt.test.ts +0 -323
  664. package/src/llm/stream/chunkAdapters.test.ts +0 -202
  665. package/src/llm/stream/reassembly.test.ts +0 -241
  666. package/src/llm/stream/smoother.bench.test.ts +0 -155
  667. package/src/llm/stream/smoother.test.ts +0 -519
  668. package/src/llm/streamLimits.test.ts +0 -450
  669. package/src/llm/truncation.test.ts +0 -242
  670. package/src/llm/vertexai/fixThoughtSignatures.test.ts +0 -154
  671. package/src/llm/vertexai/inherited-stream-events.spec.ts +0 -271
  672. package/src/llm/vertexai/llm.spec.ts +0 -159
  673. package/src/llm/vertexai/repairUsageMetadata.test.ts +0 -54
  674. package/src/llm/vertexai/sealStreamedToolCalls.test.ts +0 -88
  675. package/src/llm/vertexai/streamSealDispatch.test.ts +0 -148
  676. package/src/llm/vertexai/streamSmoothing.test.ts +0 -109
  677. package/src/messages/__tests__/anthropicToolCache.test.ts +0 -339
  678. package/src/messages/__tests__/observationMasking.test.ts +0 -312
  679. package/src/messages/__tests__/recency.test.ts +0 -267
  680. package/src/messages/__tests__/tools.test.ts +0 -473
  681. package/src/messages/alternation.test.ts +0 -212
  682. package/src/messages/assistantPhase.test.ts +0 -75
  683. package/src/messages/cache.tail.test.ts +0 -533
  684. package/src/messages/cache.test.ts +0 -2166
  685. package/src/messages/content.test.ts +0 -362
  686. package/src/messages/contextPruning.test.ts +0 -184
  687. package/src/messages/ensureThinkingBlock.test.ts +0 -1427
  688. package/src/messages/foldToollessToolBlocks.test.ts +0 -596
  689. package/src/messages/formatAgentMessages.reducer.test.ts +0 -162
  690. package/src/messages/formatAgentMessages.skills.test.ts +0 -513
  691. package/src/messages/formatAgentMessages.steer.test.ts +0 -598
  692. package/src/messages/formatAgentMessages.test.ts +0 -8111
  693. package/src/messages/formatAgentMessages.tools.test.ts +0 -522
  694. package/src/messages/formatMessage.test.ts +0 -693
  695. package/src/messages/handoffCue.test.ts +0 -96
  696. package/src/messages/injected.test.ts +0 -107
  697. package/src/messages/labelContentByAgent.test.ts +0 -962
  698. package/src/messages/reducer.spec.ts +0 -32
  699. package/src/messages/shiftIndexTokenCountMap.test.ts +0 -81
  700. package/src/messages/tailCacheConversion.test.ts +0 -161
  701. package/src/openai/__tests__/openai.test.ts +0 -337
  702. package/src/responses/__tests__/responses.test.ts +0 -652
  703. package/src/scripts/abort.ts +0 -157
  704. package/src/scripts/activity-labels/captured.json +0 -56
  705. package/src/scripts/activity-labels/checks.cjs +0 -205
  706. package/src/scripts/activity-labels/corpus.cjs +0 -473
  707. package/src/scripts/activity-labels/report.cjs +0 -203
  708. package/src/scripts/activity-labels/rescore.cjs +0 -102
  709. package/src/scripts/activity-labels/run.ts +0 -705
  710. package/src/scripts/activity-labels/variants.ts +0 -71
  711. package/src/scripts/ant_web_search.ts +0 -159
  712. package/src/scripts/ant_web_search_edge_case.ts +0 -163
  713. package/src/scripts/ant_web_search_error_edge_case.ts +0 -149
  714. package/src/scripts/args.ts +0 -48
  715. package/src/scripts/bedrock-cache-debug.ts +0 -250
  716. package/src/scripts/bedrock-content-aggregation-test.ts +0 -266
  717. package/src/scripts/bedrock-merge-test.ts +0 -107
  718. package/src/scripts/bedrock-parallel-tools-test.ts +0 -204
  719. package/src/scripts/bench-prompt-cache.ts +0 -479
  720. package/src/scripts/caching.ts +0 -132
  721. package/src/scripts/cli.ts +0 -172
  722. package/src/scripts/cli2.ts +0 -133
  723. package/src/scripts/cli3.ts +0 -184
  724. package/src/scripts/cli4.ts +0 -191
  725. package/src/scripts/cli5.ts +0 -191
  726. package/src/scripts/code_exec.ts +0 -214
  727. package/src/scripts/code_exec_files.ts +0 -237
  728. package/src/scripts/code_exec_multi_session.ts +0 -237
  729. package/src/scripts/code_exec_ptc.ts +0 -335
  730. package/src/scripts/code_exec_session.ts +0 -283
  731. package/src/scripts/code_exec_simple.ts +0 -148
  732. package/src/scripts/compare_pi_vs_ours.ts +0 -1259
  733. package/src/scripts/content.ts +0 -139
  734. package/src/scripts/context-overflow-probe.ts +0 -997
  735. package/src/scripts/empty_input.ts +0 -137
  736. package/src/scripts/handoff-test.ts +0 -134
  737. package/src/scripts/local_engine.ts +0 -166
  738. package/src/scripts/local_engine_checkpointer.ts +0 -205
  739. package/src/scripts/local_engine_compile.ts +0 -263
  740. package/src/scripts/local_engine_hooks.ts +0 -226
  741. package/src/scripts/local_engine_image.ts +0 -201
  742. package/src/scripts/local_engine_ptc.ts +0 -151
  743. package/src/scripts/local_engine_workspace.ts +0 -258
  744. package/src/scripts/memory.ts +0 -107
  745. package/src/scripts/multi-agent-chain.ts +0 -332
  746. package/src/scripts/multi-agent-conditional.ts +0 -222
  747. package/src/scripts/multi-agent-document-review-chain.ts +0 -198
  748. package/src/scripts/multi-agent-hybrid-flow.ts +0 -311
  749. package/src/scripts/multi-agent-parallel-start.ts +0 -265
  750. package/src/scripts/multi-agent-parallel.ts +0 -395
  751. package/src/scripts/multi-agent-sequence.ts +0 -217
  752. package/src/scripts/multi-agent-subagent.ts +0 -246
  753. package/src/scripts/multi-agent-supervisor.ts +0 -366
  754. package/src/scripts/multi-agent-test.ts +0 -187
  755. package/src/scripts/openrouter_prompt_cache_live.ts +0 -310
  756. package/src/scripts/parallel-asymmetric-tools-test.ts +0 -275
  757. package/src/scripts/parallel-full-metadata-test.ts +0 -241
  758. package/src/scripts/parallel-tools-test.ts +0 -341
  759. package/src/scripts/preempt-probe.ts +0 -330
  760. package/src/scripts/preempt-scenarios.ts +0 -388
  761. package/src/scripts/programmatic_exec.ts +0 -387
  762. package/src/scripts/programmatic_exec_agent.ts +0 -232
  763. package/src/scripts/search.ts +0 -147
  764. package/src/scripts/sequential-full-metadata-test.ts +0 -198
  765. package/src/scripts/session_live.ts +0 -548
  766. package/src/scripts/simple.ts +0 -226
  767. package/src/scripts/single-agent-metadata-test.ts +0 -196
  768. package/src/scripts/stream.ts +0 -141
  769. package/src/scripts/subagent-configurable-inheritance.ts +0 -252
  770. package/src/scripts/subagent-event-driven-debug.ts +0 -190
  771. package/src/scripts/subagent-tools-debug.ts +0 -160
  772. package/src/scripts/subagent-usage-sink.ts +0 -176
  773. package/src/scripts/summarization-recency.ts +0 -462
  774. package/src/scripts/test-custom-prompt-key.ts +0 -145
  775. package/src/scripts/test-handoff-input.ts +0 -170
  776. package/src/scripts/test-handoff-preamble.ts +0 -278
  777. package/src/scripts/test-handoff-steering.ts +0 -430
  778. package/src/scripts/test-multi-agent-list-handoff.ts +0 -418
  779. package/src/scripts/test-parallel-agent-labeling.ts +0 -327
  780. package/src/scripts/test-parallel-handoffs.ts +0 -292
  781. package/src/scripts/test-thinking-handoff-bedrock.ts +0 -154
  782. package/src/scripts/test-thinking-handoff.ts +0 -156
  783. package/src/scripts/test-thinking-to-thinking-handoff-bedrock.ts +0 -166
  784. package/src/scripts/test-tool-before-handoff-role-order.ts +0 -276
  785. package/src/scripts/test-tools-before-handoff.ts +0 -222
  786. package/src/scripts/test_code_api.ts +0 -354
  787. package/src/scripts/thinking-bedrock.ts +0 -160
  788. package/src/scripts/thinking-vertexai.ts +0 -168
  789. package/src/scripts/thinking.ts +0 -172
  790. package/src/scripts/tool_search.ts +0 -153
  791. package/src/scripts/tools.ts +0 -163
  792. package/src/session/__tests__/JsonlSessionStore.test.ts +0 -1463
  793. package/src/session/__tests__/handlers.test.ts +0 -161
  794. package/src/specs/activity-label-observability.live.test.ts +0 -262
  795. package/src/specs/activity-label-observability.test.ts +0 -167
  796. package/src/specs/activity-label-prompt.test.ts +0 -359
  797. package/src/specs/activity-label-trace-seed.test.ts +0 -47
  798. package/src/specs/activity-phase-label.test.ts +0 -306
  799. package/src/specs/agent-handoffs.live.test.ts +0 -140
  800. package/src/specs/agent-handoffs.test.ts +0 -2465
  801. package/src/specs/anthropic.simple.test.ts +0 -453
  802. package/src/specs/ask-user-question-batch.test.ts +0 -289
  803. package/src/specs/ask-user-questions.live.test.ts +0 -185
  804. package/src/specs/ask-user-questions.test.ts +0 -293
  805. package/src/specs/azure.simple.test.ts +0 -502
  806. package/src/specs/bedrock-toolless.live.test.ts +0 -123
  807. package/src/specs/bedrock-truncation.live.test.ts +0 -191
  808. package/src/specs/cache.simple.test.ts +0 -416
  809. package/src/specs/context-accuracy.live.test.ts +0 -409
  810. package/src/specs/context-overflow-recovery.live.test.ts +0 -213
  811. package/src/specs/context-usage-event.test.ts +0 -117
  812. package/src/specs/context-usage.live.test.ts +0 -297
  813. package/src/specs/custom-event-await.test.ts +0 -304
  814. package/src/specs/deepseek.simple.test.ts +0 -290
  815. package/src/specs/deterministic-trace-id.test.ts +0 -43
  816. package/src/specs/discovered-tools.test.ts +0 -217
  817. package/src/specs/durability-checkpoint.integration.test.ts +0 -243
  818. package/src/specs/graph-subagent.live.test.ts +0 -242
  819. package/src/specs/graph-subagent.test.ts +0 -322
  820. package/src/specs/handoffCue.test.ts +0 -165
  821. package/src/specs/langfuse-callbacks.test.ts +0 -1578
  822. package/src/specs/langfuse-config.test.ts +0 -247
  823. package/src/specs/langfuse-instrumentation.test.ts +0 -393
  824. package/src/specs/langfuse-metadata.test.ts +0 -245
  825. package/src/specs/langfuse-routing.integration.test.ts +0 -844
  826. package/src/specs/langfuse-runtime-context.test.ts +0 -92
  827. package/src/specs/langfuse-span-registry.test.ts +0 -87
  828. package/src/specs/langfuse-tool-output-tracing.test.ts +0 -1858
  829. package/src/specs/langfuse-trace-shaping.test.ts +0 -591
  830. package/src/specs/moonshot.simple.test.ts +0 -367
  831. package/src/specs/multi-agent-summarization.test.ts +0 -396
  832. package/src/specs/openai.simple.test.ts +0 -315
  833. package/src/specs/openrouter.simple.test.ts +0 -275
  834. package/src/specs/preemptSeal.test.ts +0 -678
  835. package/src/specs/prune.test.ts +0 -3741
  836. package/src/specs/reasoning.test.ts +0 -201
  837. package/src/specs/run-step-timestamps.test.ts +0 -414
  838. package/src/specs/spec.utils.ts +0 -15
  839. package/src/specs/subagent.test.ts +0 -864
  840. package/src/specs/summarization-unit.test.ts +0 -973
  841. package/src/specs/summarization.test.ts +0 -3823
  842. package/src/specs/summarize-prune.test.ts +0 -376
  843. package/src/specs/thinking-handoff.test.ts +0 -621
  844. package/src/specs/thinking-prune.test.ts +0 -827
  845. package/src/specs/token-accounting-e2e.test.ts +0 -1034
  846. package/src/specs/token-accounting-pipeline.test.ts +0 -1008
  847. package/src/specs/token-distribution-edge-case.test.ts +0 -315
  848. package/src/specs/token-memoization.test.ts +0 -40
  849. package/src/specs/tokens.test.ts +0 -1000
  850. package/src/specs/tool-error-resume.test.ts +0 -194
  851. package/src/specs/tool-error.test.ts +0 -198
  852. package/src/specs/vllm-reasoning-toolcalls.test.ts +0 -340
  853. package/src/stream.dispatch.test.ts +0 -63
  854. package/src/stream.test.ts +0 -144
  855. package/src/summarization/__tests__/aggregator.test.ts +0 -236
  856. package/src/summarization/__tests__/node.test.ts +0 -1996
  857. package/src/summarization/__tests__/trigger.test.ts +0 -149
  858. package/src/summarization/chunkHandler.test.ts +0 -196
  859. package/src/test/mockTools.ts +0 -386
  860. package/src/tools/Calculator.test.ts +0 -278
  861. package/src/tools/__tests__/BashExecutor.test.ts +0 -108
  862. package/src/tools/__tests__/CloudflareSandboxExecution.test.ts +0 -939
  863. package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +0 -858
  864. package/src/tools/__tests__/CodeExecutor.stateful.test.ts +0 -124
  865. package/src/tools/__tests__/LocalExecutionRoots.test.ts +0 -8
  866. package/src/tools/__tests__/LocalExecutionTools.test.ts +0 -2733
  867. package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.ts +0 -318
  868. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +0 -1557
  869. package/src/tools/__tests__/ReadFile.test.ts +0 -44
  870. package/src/tools/__tests__/SkillTool.test.ts +0 -442
  871. package/src/tools/__tests__/SubagentExecutor.test.ts +0 -3728
  872. package/src/tools/__tests__/SubagentReplay.test.ts +0 -329
  873. package/src/tools/__tests__/SubagentTool.test.ts +0 -149
  874. package/src/tools/__tests__/ToolNode.breakerSignal.test.ts +0 -595
  875. package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +0 -1191
  876. package/src/tools/__tests__/ToolNode.invalidToolCalls.test.ts +0 -757
  877. package/src/tools/__tests__/ToolNode.langfuse.test.ts +0 -57
  878. package/src/tools/__tests__/ToolNode.onResultCompletion.test.ts +0 -736
  879. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +0 -1710
  880. package/src/tools/__tests__/ToolNode.runtimeState.test.ts +0 -120
  881. package/src/tools/__tests__/ToolNode.session.test.ts +0 -1352
  882. package/src/tools/__tests__/ToolNode.streamLimits.test.ts +0 -69
  883. package/src/tools/__tests__/ToolSearch.integration.test.ts +0 -161
  884. package/src/tools/__tests__/ToolSearch.test.ts +0 -1227
  885. package/src/tools/__tests__/annotateMessagesForLLM.test.ts +0 -561
  886. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +0 -980
  887. package/src/tools/__tests__/directToolHooks.test.ts +0 -700
  888. package/src/tools/__tests__/eagerEventExecution.session.test.ts +0 -92
  889. package/src/tools/__tests__/handlers.test.ts +0 -997
  890. package/src/tools/__tests__/hitl.test.ts +0 -4663
  891. package/src/tools/__tests__/intentArg.test.ts +0 -357
  892. package/src/tools/__tests__/intentCoverage.test.ts +0 -139
  893. package/src/tools/__tests__/localToolNames.test.ts +0 -75
  894. package/src/tools/__tests__/skillCatalog.test.ts +0 -161
  895. package/src/tools/__tests__/subagentHooks.test.ts +0 -1651
  896. package/src/tools/__tests__/toolOutputReferences.test.ts +0 -515
  897. package/src/tools/__tests__/workspaceSeam.test.ts +0 -147
  898. package/src/tools/local/__tests__/FileCheckpointer.test.ts +0 -162
  899. package/src/tools/local/__tests__/editStrategies.test.ts +0 -134
  900. package/src/tools/search/content.test.ts +0 -173
  901. package/src/tools/search/crw.test.ts +0 -836
  902. package/src/tools/search/format.test.ts +0 -242
  903. package/src/tools/search/http-agent.test.ts +0 -133
  904. package/src/tools/search/jina-reranker.test.ts +0 -306
  905. package/src/tools/search/keenable-scraper.test.ts +0 -153
  906. package/src/tools/search/keenable.test.ts +0 -183
  907. package/src/tools/search/outcome.test.ts +0 -90
  908. package/src/tools/search/output.md +0 -2775
  909. package/src/tools/search/rag-api-reranker.test.ts +0 -891
  910. package/src/tools/search/source-processing.test.ts +0 -516
  911. package/src/tools/search/tavily.test.ts +0 -965
  912. package/src/tools/search/test.html +0 -884
  913. package/src/tools/search/test.md +0 -643
  914. package/src/tools/subagent/__tests__/SubagentExecutionRegistry.test.ts +0 -637
  915. package/src/tools/subagent/__tests__/SubagentExecutor.lazy.test.ts +0 -3054
  916. package/src/tools/subagent/__tests__/childGraphConfig.test.ts +0 -521
  917. package/src/utils/__tests__/apportion.test.ts +0 -32
  918. package/src/utils/__tests__/errors.test.ts +0 -270
  919. package/src/utils/__tests__/fixtures/contextOverflowSignatures.ts +0 -336
  920. package/src/utils/__tests__/redactSecrets.test.ts +0 -56
  921. package/src/utils/__tests__/truncation.test.ts +0 -66
  922. package/src/utils/llm.test.ts +0 -18
  923. package/src/utils/proxy.test.ts +0 -176
  924. package/src/utils/toolContent.test.ts +0 -1432
@@ -1 +1 @@
1
- {"version":3,"file":"HookRegistry.mjs","names":[],"sources":["../../../src/hooks/HookRegistry.ts"],"sourcesContent":["// src/hooks/HookRegistry.ts\nimport type {\n HookEvent,\n HookMatcher,\n ToolApprovalReplayKey,\n ToolApprovalReplaySnapshot,\n AggregatedHookResult,\n} from './types';\n\nfunction serializeApprovalKey(key: ToolApprovalReplayKey): string {\n return JSON.stringify([key.executionScope, key.agentId, key.toolUseId]);\n}\n\nfunction deserializeApprovalKey(value: string): ToolApprovalReplayKey | null {\n const parsed: unknown = JSON.parse(value);\n if (\n !Array.isArray(parsed) ||\n parsed.length !== 3 ||\n parsed.some((part) => typeof part !== 'string')\n ) {\n return null;\n }\n return {\n executionScope: parsed[0],\n agentId: parsed[1],\n toolUseId: parsed[2],\n };\n}\n\n/**\n * Internal matcher storage type.\n *\n * Matchers registered via the public `register<E>` API are strictly typed\n * to a single `E`, but the storage needs one uniform slot type per event.\n * We store them as `HookMatcher<HookEvent>` and cast once at the variance\n * boundary — see `ensureList` and `snapshot` below. The invariant (every\n * matcher in `bucket[event]` was registered with that exact event) is\n * enforced by the public API; breaking it requires bypassing the types.\n */\ntype MatcherBucket = Partial<Record<HookEvent, HookMatcher<HookEvent>[]>>;\n\n/**\n * Events whose hooks can change a tool call's input or output. Presence of\n * any of these disables eager tool execution and early completion emission;\n * observation-only events (`PostToolBatch`, `Stop`, telemetry hooks) do not.\n */\nconst RESULT_ALTERING_HOOK_EVENTS = [\n 'PreToolUse',\n 'PostToolUse',\n 'PostToolUseFailure',\n] as const satisfies readonly HookEvent[];\n\n/**\n * Snapshot of a halt request raised by a hook returning\n * `preventContinuation: true`. The SDK's run loop polls for this between\n * stream events and exits cleanly when set, skipping the `Stop` hook\n * (the run is being halted, not naturally completing). One per registry\n * instance — the first hook to halt wins; subsequent halts are ignored\n * so the original reason isn't clobbered.\n */\nexport interface HookHaltSignal {\n reason: string;\n /** Event of the hook that triggered the halt (for diagnostics). */\n source: HookEvent;\n}\n\n/**\n * Run-scoped storage for hook matchers with an additional layer for\n * session-scoped matchers that should be cleaned up between sessions.\n *\n * Hosts construct one registry per `Run` (mirroring how `HandlerRegistry` is\n * scoped) and register global matchers + per-session matchers against it.\n * Registration is strictly additive — nothing in this class mutates a\n * matcher's callbacks or flags after insertion.\n *\n * ## Why `Map<sessionId, MatcherBucket>` and not `Record`\n *\n * LibreChat runs thousands of parallel sessions in one Node process, and\n * hook registration happens inside hot paths (tool loading, agent spawning).\n * A `Record<sessionId, ...>` has to be spread on every insertion, which is\n * O(n) per call and O(n²) total for a batch of parallel registrations. A\n * Map mutates in place, keeping insertions O(1). This mirrors the reasoning\n * Claude Code documents at `utils/hooks/sessionHooks.ts:62`.\n */\nexport class HookRegistry {\n private readonly global: MatcherBucket = {};\n private readonly sessions: Map<string, MatcherBucket> = new Map();\n /**\n * Per-session halt signals. Scoped by `sessionId` (= the run id the\n * hook fired under) so a host that shares one registry across\n * concurrent runs cannot leak `preventContinuation` from one run\n * into another. Without scoping, a halt raised by run A's hook\n * would trip run B's stream-loop poll on the next iteration —\n * silently terminating an unrelated run.\n *\n * Map storage mirrors the reasoning above for session matchers:\n * O(1) insertion in hot paths, no spread-on-write.\n */\n private readonly haltSignals: Map<string, HookHaltSignal> = new Map();\n /** One-shot hook contributions retained until approval is consumed. */\n private readonly pendingToolApprovals = new Map<\n string,\n Map<string, AggregatedHookResult>\n >();\n\n /**\n * Register a matcher for the lifetime of this registry (= one Run).\n * Returns an unregister function that removes the matcher by reference.\n */\n register<E extends HookEvent>(event: E, matcher: HookMatcher<E>): () => void {\n const list = ensureList(this.global, event);\n list.push(widen(matcher));\n return () => {\n removeFromList(list, matcher);\n };\n }\n\n /**\n * Register a matcher for a specific session. Cleared automatically when\n * `clearSession(sessionId)` is called, or can be removed directly via the\n * returned unregister function.\n */\n registerSession<E extends HookEvent>(\n sessionId: string,\n event: E,\n matcher: HookMatcher<E>\n ): () => void {\n const bucket = this.ensureSessionBucket(sessionId);\n const list = ensureList(bucket, event);\n list.push(widen(matcher));\n return () => {\n removeFromList(list, matcher);\n };\n }\n\n /**\n * Returns all matchers registered for `event`, concatenating global first\n * and then session-specific (when `sessionId` is supplied). The caller\n * receives a fresh array, so iterating it is safe even if a matcher is\n * removed mid-iteration (e.g. via `once: true`).\n */\n getMatchers<E extends HookEvent>(\n event: E,\n sessionId?: string\n ): HookMatcher<E>[] {\n const globalList = readList(this.global, event);\n if (sessionId === undefined) {\n return snapshot<E>(globalList);\n }\n const bucket = this.sessions.get(sessionId);\n if (bucket === undefined) {\n return snapshot<E>(globalList);\n }\n const sessionList = readList(bucket, event);\n if (globalList.length === 0) {\n return snapshot<E>(sessionList);\n }\n if (sessionList.length === 0) {\n return snapshot<E>(globalList);\n }\n return snapshot<E>([...globalList, ...sessionList]);\n }\n\n /**\n * Removes `matcher` by reference from global storage first, falling back\n * to the session bucket when `sessionId` is supplied. Used by\n * `executeHooks` to drop `once: true` matchers after they fire.\n */\n removeMatcher<E extends HookEvent>(\n event: E,\n matcher: HookMatcher<E>,\n sessionId?: string\n ): boolean {\n if (removeFromList(readList(this.global, event), matcher)) {\n return true;\n }\n if (sessionId === undefined) {\n return false;\n }\n const bucket = this.sessions.get(sessionId);\n if (bucket === undefined) {\n return false;\n }\n return removeFromList(readList(bucket, event), matcher);\n }\n\n /**\n * Drops every session-scoped matcher for `sessionId`. Call this in the\n * `finally` block around a Run so a `once: true` hook that never fired\n * cannot leak into the next session on the same registry.\n */\n clearSession(sessionId: string): void {\n this.sessions.delete(sessionId);\n this.pendingToolApprovals.delete(sessionId);\n }\n\n /** Copies session-scoped policy into a rebuilt or branched Run. */\n copySession(sourceSessionId: string, targetSessionId: string): void {\n if (sourceSessionId === targetSessionId) {\n return;\n }\n const source = this.sessions.get(sourceSessionId);\n if (source != null) {\n const target = this.ensureSessionBucket(targetSessionId);\n for (const event of Object.keys(source) as HookEvent[]) {\n const targetList = ensureList(target, event);\n for (const matcher of readList(source, event)) {\n if (!targetList.includes(matcher)) {\n targetList.push(matcher);\n }\n }\n }\n }\n const pending = this.pendingToolApprovals.get(sourceSessionId);\n if (pending == null) {\n return;\n }\n let targetPending = this.pendingToolApprovals.get(targetSessionId);\n if (targetPending == null) {\n targetPending = new Map();\n this.pendingToolApprovals.set(targetSessionId, targetPending);\n }\n for (const [toolUseId, result] of pending) {\n if (!targetPending.has(toolUseId)) {\n targetPending.set(toolUseId, result);\n }\n }\n }\n\n getPendingToolApproval(\n sessionId: string,\n key: ToolApprovalReplayKey\n ): AggregatedHookResult | undefined {\n return this.pendingToolApprovals\n .get(sessionId)\n ?.get(serializeApprovalKey(key));\n }\n\n setPendingToolApproval(\n sessionId: string,\n key: ToolApprovalReplayKey,\n result: AggregatedHookResult\n ): void {\n let pending = this.pendingToolApprovals.get(sessionId);\n if (pending == null) {\n pending = new Map();\n this.pendingToolApprovals.set(sessionId, pending);\n }\n pending.set(serializeApprovalKey(key), result);\n }\n\n clearPendingToolApproval(\n sessionId: string,\n key: ToolApprovalReplayKey\n ): void {\n const pending = this.pendingToolApprovals.get(sessionId);\n if (pending == null) {\n return;\n }\n pending.delete(serializeApprovalKey(key));\n if (pending.size === 0) {\n this.pendingToolApprovals.delete(sessionId);\n }\n }\n\n snapshotPendingToolApprovals(\n sessionId: string,\n executionScope: string\n ): ToolApprovalReplaySnapshot[] {\n const pending = this.pendingToolApprovals.get(sessionId);\n if (pending == null) {\n return [];\n }\n const snapshots: ToolApprovalReplaySnapshot[] = [];\n for (const [serializedKey, result] of pending) {\n const key = deserializeApprovalKey(serializedKey);\n if (key == null || key.executionScope !== executionScope) {\n continue;\n }\n snapshots.push({ key, result });\n }\n return snapshots;\n }\n\n restorePendingToolApprovals(\n sessionId: string,\n targetExecutionScope: string,\n snapshots: ReadonlyArray<ToolApprovalReplaySnapshot>\n ): void {\n const restored = new Map<string, AggregatedHookResult>();\n for (const [serializedKey, result] of this.pendingToolApprovals.get(\n sessionId\n ) ?? []) {\n const key = deserializeApprovalKey(serializedKey);\n if (key?.executionScope !== targetExecutionScope) {\n restored.set(serializedKey, result);\n }\n }\n for (const snapshot of snapshots) {\n restored.set(\n serializeApprovalKey({\n ...snapshot.key,\n executionScope: targetExecutionScope,\n }),\n snapshot.result\n );\n }\n if (restored.size === 0) {\n this.pendingToolApprovals.delete(sessionId);\n return;\n }\n this.pendingToolApprovals.set(sessionId, restored);\n }\n\n /**\n * Raise a halt signal scoped to `sessionId` (= the run id the hook\n * fired under). The SDK's run loop polls for this between stream\n * events with the run's own id. First-write-wins per session: a\n * halt already raised by an earlier hook in the same run is\n * preserved so the original `reason` / `source` aren't overwritten.\n *\n * Per-session scoping is critical when hosts share one registry\n * across concurrent runs (e.g. a global policy registered once and\n * reused). Without it, a `preventContinuation` from run A would\n * trip run B's stream-loop poll on the next iteration and silently\n * terminate an unrelated run.\n *\n * Called by the SDK after `executeHooks` returns an aggregate with\n * `preventContinuation: true`. Hosts can also call it directly from\n * inside a hook callback if they want to halt without going through\n * the aggregated return value, but `preventContinuation` is the\n * canonical path.\n */\n haltRun(sessionId: string, reason: string, source: HookEvent): void {\n if (this.haltSignals.has(sessionId)) {\n return;\n }\n this.haltSignals.set(sessionId, { reason, source });\n }\n\n /**\n * Returns the halt signal raised by hooks running under `sessionId`,\n * or `undefined` if no hook in that run has halted. Polled by\n * `Run.processStream` between stream events using the run's own id.\n */\n getHaltSignal(sessionId: string): HookHaltSignal | undefined {\n return this.haltSignals.get(sessionId);\n }\n\n /**\n * Clears the halt signal for `sessionId`. Called by\n * `Run.processStream` in its `finally` block so a subsequent\n * invocation of the same Run (e.g. resume) starts with a fresh\n * halt state. No-op when no signal exists for that session.\n */\n clearHaltSignal(sessionId: string): void {\n this.haltSignals.delete(sessionId);\n }\n\n /**\n * True when any registered hook can alter a tool result before or after\n * execution (`PreToolUse`, `PostToolUse`, `PostToolUseFailure`). Eager\n * tool execution and early completion emission gate on this instead of\n * registry presence, so observation-only registries (e.g. a\n * `PostToolBatch` steering drain) keep those fast paths. With\n * `sessionId`, checks global + that session; without it, conservatively\n * scans every session bucket.\n */\n hasResultAlteringHooks(sessionId?: string): boolean {\n if (hasResultAlteringInBucket(this.global)) {\n return true;\n }\n if (sessionId !== undefined) {\n const bucket = this.sessions.get(sessionId);\n return bucket !== undefined && hasResultAlteringInBucket(bucket);\n }\n for (const bucket of this.sessions.values()) {\n if (hasResultAlteringInBucket(bucket)) {\n return true;\n }\n }\n return false;\n }\n\n /** True if at least one matcher exists for `event` (global + session). */\n hasHookFor(event: HookEvent, sessionId?: string): boolean {\n if (readList(this.global, event).length > 0) {\n return true;\n }\n if (sessionId === undefined) {\n return false;\n }\n const bucket = this.sessions.get(sessionId);\n if (bucket === undefined) {\n return false;\n }\n return readList(bucket, event).length > 0;\n }\n\n /**\n * True when at least one matcher for `event` would actually DISPATCH on a\n * query-less call — a wildcard pattern with a non-empty `hooks` array.\n *\n * `hasHookFor` answers \"is one registered\", which is not the same question:\n * a matcher carrying a pattern is inert for events that supply no\n * `matchQuery`, so a caller using registration as a proxy for \"something\n * will run\" can act on a hook that never fires. Mirrors the two skips in\n * `executeHooks` (pattern mismatch, empty `hooks`).\n *\n * Non-allocating on purpose — `StandardGraph.canClaimPreemptSeal` reads it\n * once per streamed chunk, where `getMatchers`' defensive `slice()` would\n * allocate on every delta.\n */\n hasDispatchableHookFor(event: HookEvent, sessionId?: string): boolean {\n if (hasDispatchableInList(readList(this.global, event))) {\n return true;\n }\n if (sessionId === undefined) {\n return false;\n }\n const bucket = this.sessions.get(sessionId);\n if (bucket === undefined) {\n return false;\n }\n return hasDispatchableInList(readList(bucket, event));\n }\n\n private ensureSessionBucket(sessionId: string): MatcherBucket {\n const existing = this.sessions.get(sessionId);\n if (existing !== undefined) {\n return existing;\n }\n const fresh: MatcherBucket = {};\n this.sessions.set(sessionId, fresh);\n return fresh;\n }\n}\n\nfunction ensureList(\n bucket: MatcherBucket,\n event: HookEvent\n): HookMatcher<HookEvent>[] {\n const existing = bucket[event];\n if (existing !== undefined) {\n return existing;\n }\n const fresh: HookMatcher<HookEvent>[] = [];\n bucket[event] = fresh;\n return fresh;\n}\n\nfunction readList(\n bucket: MatcherBucket,\n event: HookEvent\n): HookMatcher<HookEvent>[] {\n return bucket[event] ?? [];\n}\n\nfunction hasDispatchableInList(list: HookMatcher<HookEvent>[]): boolean {\n for (const matcher of list) {\n if (\n (matcher.pattern === undefined || matcher.pattern === '') &&\n matcher.hooks.length > 0\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction hasResultAlteringInBucket(bucket: MatcherBucket): boolean {\n for (const event of RESULT_ALTERING_HOOK_EVENTS) {\n if (readList(bucket, event).length > 0) {\n return true;\n }\n }\n return false;\n}\n\nfunction removeFromList<E extends HookEvent>(\n list: HookMatcher<HookEvent>[],\n matcher: HookMatcher<E>\n): boolean {\n const idx = list.indexOf(widen(matcher));\n if (idx < 0) {\n return false;\n }\n list.splice(idx, 1);\n return true;\n}\n\n/**\n * Widen a per-event matcher to the storage's uniform slot type. Unsound at\n * the type level (function parameters are contravariant) but safe by\n * construction: `HookRegistry.register<E>` only ever puts matchers into the\n * bucket slot for their own event, and reads go through `snapshot<E>`\n * which is only called with the same `E`.\n */\nfunction widen<E extends HookEvent>(\n matcher: HookMatcher<E>\n): HookMatcher<HookEvent> {\n return matcher as unknown as HookMatcher<HookEvent>;\n}\n\n/**\n * Narrow a storage list back to a per-event matcher list on the way out.\n * Sound counterpart to `widen`: the list only contains matchers that were\n * registered against `E`, because the public API enforces it on insert.\n */\nfunction snapshot<E extends HookEvent>(\n list: readonly HookMatcher<HookEvent>[]\n): HookMatcher<E>[] {\n return list.slice() as unknown as HookMatcher<E>[];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HookRegistry.mjs","names":[],"sources":["../../../src/hooks/HookRegistry.ts"],"mappings":"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"}
@@ -1,17 +1,8 @@
1
1
  //#region src/hooks/createToolPolicyHook.ts
2
- /**
3
- * Compile a glob string with `*` wildcards into a single anchored
4
- * `RegExp`. Other regex metacharacters are escaped, so `read_file.md`
5
- * matches the literal dot. Patterns are short (tool names), so we do
6
- * not cache here — the registry's `matchesQuery` already caches its own
7
- * regex compilations and our patterns are evaluated once per ToolNode
8
- * batch, not once per stream chunk.
9
- */
10
2
  function globToRegex(pattern) {
11
3
  const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
12
4
  return new RegExp("^" + escaped.replace(/\*/g, ".*") + "$");
13
5
  }
14
- /** Pre-compile a list of glob patterns into a single match function. */
15
6
  function compileMatchers(patterns) {
16
7
  if (patterns == null || patterns.length === 0) return () => false;
17
8
  const regexes = patterns.map(globToRegex);
@@ -24,35 +15,6 @@ function formatReason(template, toolName) {
24
15
  if (template == null) return;
25
16
  return template.replace(/\{tool\}/g, toolName);
26
17
  }
27
- /**
28
- * Build a `PreToolUse` hook callback that applies a declarative tool
29
- * permission policy. Register it with a `HookRegistry` and the SDK's
30
- * `humanInTheLoop` machinery handles the rest:
31
- *
32
- * ```ts
33
- * const policyHook = createToolPolicyHook({
34
- * mode: 'default',
35
- * allow: ['read_*', 'grep', 'glob'],
36
- * deny: ['delete_*'],
37
- * ask: ['execute_*', 'mcp:*'],
38
- * });
39
- * registry.register('PreToolUse', { hooks: [policyHook] });
40
- * ```
41
- *
42
- * Explicit rules take precedence over fallback modes:
43
- *
44
- * 1. `deny` rule match → `'deny'` (always wins, even in `bypass`).
45
- * 2. `ask` rule match → `'ask'`.
46
- * 3. `allow` rule match → `'allow'`.
47
- * 4. `mode === 'bypass'` → `'allow'`.
48
- * 5. `mode === 'dontAsk'` → `'deny'`.
49
- * 6. fallthrough → `'ask'`.
50
- *
51
- * The returned callback is a single `HookCallback`, not a `HookMatcher` —
52
- * register it under the matcher with the pattern you want (omit the
53
- * pattern to fire on every tool call, which is the typical case since
54
- * the policy itself does the filtering).
55
- */
56
18
  function createToolPolicyHook(config) {
57
19
  const denyMatcher = compileMatchers(config.deny);
58
20
  const allowMatcher = compileMatchers(config.allow);
@@ -1 +1 @@
1
- {"version":3,"file":"createToolPolicyHook.mjs","names":[],"sources":["../../../src/hooks/createToolPolicyHook.ts"],"sourcesContent":["/**\n * Declarative `PreToolUse` hook factory. Lets hosts express common\n * permission policies (allow / deny / ask lists + a global mode) without\n * hand-rolling matching, precedence, and decision logic per-host.\n *\n * Uses the Claude Code Agent SDK permission vocabulary (`allowed_tools` /\n * `disallowed_tools` / `permissionMode`) while treating modes as fallbacks\n * for calls that match no explicit rule. See the README's HITL section for\n * the cross-walk and `docs/hooks-design-report.md` for the broader hook\n * system context.\n */\n\nimport type { HookCallback, PreToolUseHookOutput, ToolDecision } from './types';\n\n/**\n * Permission mode controlling how tool calls that match no rule are\n * resolved. Mirrors Claude Code's `permissionMode`.\n *\n * - `default` — unmatched tools fall through to `'ask'` (interrupt).\n * - `dontAsk` — unmatched tools are denied; the human is never\n * prompted. Useful for headless / API agents where a\n * silent denial is preferable to a hung interrupt.\n * - `bypass` — unmatched tools are approved. Explicit `deny` and `ask`\n * rules still apply.\n */\nexport type ToolPolicyMode = 'default' | 'dontAsk' | 'bypass';\n\nexport interface ToolPolicyConfig {\n /**\n * Global mode applied to tools that don't match any rule.\n * Defaults to `'default'` (ask the human).\n */\n mode?: ToolPolicyMode;\n /**\n * Tool name patterns that are auto-approved without a prompt.\n * Patterns support glob `*` wildcards: `read_file`, `mcp:github:*`,\n * `*search*`. Match is anchored (`^pattern$`).\n */\n allow?: readonly string[];\n /**\n * Tool name patterns that are blocked outright. Wins over `allow`\n * and `ask`, and overrides `mode: 'bypass'` — a deny rule always\n * holds, matching Claude Code's \"deny rules are checked first\" guarantee.\n */\n deny?: readonly string[];\n /**\n * Tool name patterns that always trigger human approval. Wins over\n * `allow` and every mode, but not `deny`.\n */\n ask?: readonly string[];\n /**\n * Optional reason attached to the resulting `ask` / `deny` hook\n * decision so the host UI can render why approval is required.\n * The literal token `{tool}` is replaced with the tool name.\n */\n reason?: string;\n}\n\n/**\n * Compile a glob string with `*` wildcards into a single anchored\n * `RegExp`. Other regex metacharacters are escaped, so `read_file.md`\n * matches the literal dot. Patterns are short (tool names), so we do\n * not cache here — the registry's `matchesQuery` already caches its own\n * regex compilations and our patterns are evaluated once per ToolNode\n * batch, not once per stream chunk.\n */\nfunction globToRegex(pattern: string): RegExp {\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp('^' + escaped.replace(/\\*/g, '.*') + '$');\n}\n\n/** Pre-compile a list of glob patterns into a single match function. */\nfunction compileMatchers(\n patterns: readonly string[] | undefined\n): (toolName: string) => boolean {\n if (patterns == null || patterns.length === 0) {\n return () => false;\n }\n const regexes = patterns.map(globToRegex);\n return (toolName: string): boolean => {\n for (const regex of regexes) {\n if (regex.test(toolName)) {\n return true;\n }\n }\n return false;\n };\n}\n\nfunction formatReason(\n template: string | undefined,\n toolName: string\n): string | undefined {\n if (template == null) {\n return undefined;\n }\n return template.replace(/\\{tool\\}/g, toolName);\n}\n\n/**\n * Build a `PreToolUse` hook callback that applies a declarative tool\n * permission policy. Register it with a `HookRegistry` and the SDK's\n * `humanInTheLoop` machinery handles the rest:\n *\n * ```ts\n * const policyHook = createToolPolicyHook({\n * mode: 'default',\n * allow: ['read_*', 'grep', 'glob'],\n * deny: ['delete_*'],\n * ask: ['execute_*', 'mcp:*'],\n * });\n * registry.register('PreToolUse', { hooks: [policyHook] });\n * ```\n *\n * Explicit rules take precedence over fallback modes:\n *\n * 1. `deny` rule match → `'deny'` (always wins, even in `bypass`).\n * 2. `ask` rule match → `'ask'`.\n * 3. `allow` rule match → `'allow'`.\n * 4. `mode === 'bypass'` → `'allow'`.\n * 5. `mode === 'dontAsk'` → `'deny'`.\n * 6. fallthrough → `'ask'`.\n *\n * The returned callback is a single `HookCallback`, not a `HookMatcher` —\n * register it under the matcher with the pattern you want (omit the\n * pattern to fire on every tool call, which is the typical case since\n * the policy itself does the filtering).\n */\nexport function createToolPolicyHook(\n config: ToolPolicyConfig\n): HookCallback<'PreToolUse'> {\n const denyMatcher = compileMatchers(config.deny);\n const allowMatcher = compileMatchers(config.allow);\n const askMatcher = compileMatchers(config.ask);\n const mode: ToolPolicyMode = config.mode ?? 'default';\n const reasonTemplate = config.reason;\n\n return async (input): Promise<PreToolUseHookOutput> => {\n const toolName = input.toolName;\n const decision = decide(\n toolName,\n mode,\n denyMatcher,\n allowMatcher,\n askMatcher\n );\n if (decision === 'allow') {\n return { decision };\n }\n const reason = formatReason(reasonTemplate, toolName);\n if (reason != null) {\n return { decision, reason };\n }\n return { decision };\n };\n}\n\nfunction decide(\n toolName: string,\n mode: ToolPolicyMode,\n denyMatch: (n: string) => boolean,\n allowMatch: (n: string) => boolean,\n askMatch: (n: string) => boolean\n): ToolDecision {\n if (denyMatch(toolName)) {\n return 'deny';\n }\n if (askMatch(toolName)) {\n return 'ask';\n }\n if (allowMatch(toolName)) {\n return 'allow';\n }\n if (mode === 'bypass') {\n return 'allow';\n }\n if (mode === 'dontAsk') {\n return 'deny';\n }\n return 'ask';\n}\n"],"mappings":";;;;;;;;;AAkEA,SAAS,YAAY,SAAyB;CAC5C,MAAM,UAAU,QAAQ,QAAQ,sBAAsB,MAAM;CAC5D,OAAO,IAAI,OAAO,MAAM,QAAQ,QAAQ,OAAO,IAAI,IAAI,GAAG;AAC5D;;AAGA,SAAS,gBACP,UAC+B;CAC/B,IAAI,YAAY,QAAQ,SAAS,WAAW,GAC1C,aAAa;CAEf,MAAM,UAAU,SAAS,IAAI,WAAW;CACxC,QAAQ,aAA8B;EACpC,KAAK,MAAM,SAAS,SAClB,IAAI,MAAM,KAAK,QAAQ,GACrB,OAAO;EAGX,OAAO;CACT;AACF;AAEA,SAAS,aACP,UACA,UACoB;CACpB,IAAI,YAAY,MACd;CAEF,OAAO,SAAS,QAAQ,aAAa,QAAQ;AAC/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,qBACd,QAC4B;CAC5B,MAAM,cAAc,gBAAgB,OAAO,IAAI;CAC/C,MAAM,eAAe,gBAAgB,OAAO,KAAK;CACjD,MAAM,aAAa,gBAAgB,OAAO,GAAG;CAC7C,MAAM,OAAuB,OAAO,QAAQ;CAC5C,MAAM,iBAAiB,OAAO;CAE9B,OAAO,OAAO,UAAyC;EACrD,MAAM,WAAW,MAAM;EACvB,MAAM,WAAW,OACf,UACA,MACA,aACA,cACA,UACF;EACA,IAAI,aAAa,SACf,OAAO,EAAE,SAAS;EAEpB,MAAM,SAAS,aAAa,gBAAgB,QAAQ;EACpD,IAAI,UAAU,MACZ,OAAO;GAAE;GAAU;EAAO;EAE5B,OAAO,EAAE,SAAS;CACpB;AACF;AAEA,SAAS,OACP,UACA,MACA,WACA,YACA,UACc;CACd,IAAI,UAAU,QAAQ,GACpB,OAAO;CAET,IAAI,SAAS,QAAQ,GACnB,OAAO;CAET,IAAI,WAAW,QAAQ,GACrB,OAAO;CAET,IAAI,SAAS,UACX,OAAO;CAET,IAAI,SAAS,WACX,OAAO;CAET,OAAO;AACT"}
1
+ {"version":3,"file":"createToolPolicyHook.mjs","names":[],"sources":["../../../src/hooks/createToolPolicyHook.ts"],"mappings":";AAkEA,SAAS,YAAY,SAAyB;CAC5C,MAAM,UAAU,QAAQ,QAAQ,sBAAsB,MAAM;CAC5D,OAAO,IAAI,OAAO,MAAM,QAAQ,QAAQ,OAAO,IAAI,IAAI,GAAG;AAC5D;AAGA,SAAS,gBACP,UAC+B;CAC/B,IAAI,YAAY,QAAQ,SAAS,WAAW,GAC1C,aAAa;CAEf,MAAM,UAAU,SAAS,IAAI,WAAW;CACxC,QAAQ,aAA8B;EACpC,KAAK,MAAM,SAAS,SAClB,IAAI,MAAM,KAAK,QAAQ,GACrB,OAAO;EAGX,OAAO;CACT;AACF;AAEA,SAAS,aACP,UACA,UACoB;CACpB,IAAI,YAAY,MACd;CAEF,OAAO,SAAS,QAAQ,aAAa,QAAQ;AAC/C;AA+BA,SAAgB,qBACd,QAC4B;CAC5B,MAAM,cAAc,gBAAgB,OAAO,IAAI;CAC/C,MAAM,eAAe,gBAAgB,OAAO,KAAK;CACjD,MAAM,aAAa,gBAAgB,OAAO,GAAG;CAC7C,MAAM,OAAuB,OAAO,QAAQ;CAC5C,MAAM,iBAAiB,OAAO;CAE9B,OAAO,OAAO,UAAyC;EACrD,MAAM,WAAW,MAAM;EACvB,MAAM,WAAW,OACf,UACA,MACA,aACA,cACA,UACF;EACA,IAAI,aAAa,SACf,OAAO,EAAE,SAAS;EAEpB,MAAM,SAAS,aAAa,gBAAgB,QAAQ;EACpD,IAAI,UAAU,MACZ,OAAO;GAAE;GAAU;EAAO;EAE5B,OAAO,EAAE,SAAS;CACpB;AACF;AAEA,SAAS,OACP,UACA,MACA,WACA,YACA,UACc;CACd,IAAI,UAAU,QAAQ,GACpB,OAAO;CAET,IAAI,SAAS,QAAQ,GACnB,OAAO;CAET,IAAI,WAAW,QAAQ,GACrB,OAAO;CAET,IAAI,SAAS,UACX,OAAO;CAET,IAAI,SAAS,WACX,OAAO;CAET,OAAO;AACT"}
@@ -4,54 +4,6 @@ import { homedir } from "os";
4
4
  import { realpath } from "fs/promises";
5
5
  import { isAbsolute, relative, resolve } from "path";
6
6
  //#region src/hooks/createWorkspacePolicyHook.ts
7
- /**
8
- * Workspace boundary policy as a `PreToolUse` hook.
9
- *
10
- * Local-engine file tools enforce a hard workspace boundary at the
11
- * tool implementation layer (`resolveWorkspacePathSafe`). This hook
12
- * adds a complementary, host-controlled layer on top that uses the
13
- * standard PreToolUse / HITL machinery to *negotiate* access to
14
- * paths outside the workspace — instead of just throwing.
15
- *
16
- * The host opts in by registering this hook on a `HookRegistry`; the
17
- * hook inspects each tool call's input, extracts the file paths it
18
- * mentions via per-tool extractors, and returns:
19
- *
20
- * - `allow` — every path is inside `workspace.root`
21
- * (or `additionalRoots`)
22
- * - `deny` — at least one path is outside, and the
23
- * configured outside-policy is `'deny'`
24
- * - `ask` — at least one path is outside, and the
25
- * outside-policy is `'ask'` (default).
26
- * When `humanInTheLoop.enabled` is true,
27
- * the existing PreToolUse `'ask'` flow
28
- * raises a tool_approval interrupt the
29
- * host UI can render. When HITL is off,
30
- * `'ask'` collapses to `deny` (matches
31
- * the rest of the SDK's default).
32
- *
33
- * Default per-tool path extractors cover the local-engine coding
34
- * suite (`read_file`, `write_file`, `edit_file`, `grep_search`,
35
- * `glob_search`, `list_directory`, `compile_check`). The host can
36
- * override or extend via `pathExtractors`. Bash/code paths are not
37
- * extracted by default — bash command parsing is its own concern, and
38
- * the existing `bashAst` validator + sandbox-runtime fs allowlist are
39
- * the right gates for those.
40
- *
41
- * Important: this hook does NOT replace `resolveWorkspacePathSafe`.
42
- * Even if the hook returns `allow`, the file tool still enforces its
43
- * own clamp unless `workspace.allowReadOutside` /
44
- * `workspace.allowWriteOutside` (or the legacy
45
- * `allowOutsideWorkspace`) is set. The recommended composition for
46
- * "ask the user" semantics is:
47
- *
48
- * workspace: {
49
- * root,
50
- * allowReadOutside: true,
51
- * allowWriteOutside: true,
52
- * },
53
- * // …with the hook installed and humanInTheLoop.enabled = true.
54
- */
55
7
  const READ_TOOLS = new Set([
56
8
  "read_file",
57
9
  "grep_search",
@@ -93,20 +45,6 @@ function isInsideAnyRoot(absolutePath, roots) {
93
45
  }
94
46
  return false;
95
47
  }
96
- /**
97
- * Symlink-aware variant: realpaths the candidate AND the roots before
98
- * comparing. Without this, a symlink inside the workspace pointing
99
- * outside (e.g. `workspace/link → /etc/passwd`) compares as
100
- * "in-workspace" lexically, but actually grants the agent reach
101
- * outside the boundary. Critical when this hook is the primary gate
102
- * (i.e. the host opted into `workspace.allowReadOutside: true` /
103
- * `allowWriteOutside: true` so the file tools' own clamp is off).
104
- *
105
- * Handles paths that don't yet exist (e.g. `write_file` to a brand
106
- * new path) by walking up to the nearest existing ancestor and
107
- * realpathing that, then re-attaching the unresolved suffix. Mirrors
108
- * `resolveWorkspacePathSafe`'s approach in LocalExecutionEngine.
109
- */
110
48
  async function realpathOrSelf(absolutePath) {
111
49
  try {
112
50
  return await realpath(absolutePath);
@@ -136,20 +74,6 @@ function formatReason(template, toolName, outsidePaths) {
136
74
  if (template == null) return fallback;
137
75
  return template.replace(/\{tool\}/g, toolName).replace(/\{paths\}/g, outsidePaths.join(", "));
138
76
  }
139
- /**
140
- * Build a `PreToolUse` callback that enforces the workspace policy.
141
- * Register it on a `HookRegistry`:
142
- *
143
- * ```ts
144
- * registry.register('PreToolUse', {
145
- * hooks: [createWorkspacePolicyHook({ root, outsideWrite: 'ask' })],
146
- * });
147
- * ```
148
- *
149
- * The hook is composable with `createToolPolicyHook` — register both;
150
- * `executeHooks` precedence (`deny > ask > allow`) sorts out which
151
- * decision wins per call.
152
- */
153
77
  function createWorkspacePolicyHook(config) {
154
78
  const root = resolve(config.root);
155
79
  const allRoots = [root, ...(config.additionalRoots ?? []).map((p) => isAbsolute(p) ? resolve(p) : resolve(root, p))];
@@ -164,7 +88,6 @@ function createWorkspacePolicyHook(config) {
164
88
  ...DEFAULT_EXTRACTORS,
165
89
  ...config.pathExtractors ?? {}
166
90
  };
167
- /** Unknown tools are treated as writes (the stricter policy). */
168
91
  const resolvePolicy = (toolName) => {
169
92
  if (WRITE_TOOLS.has(toolName)) return writePolicy;
170
93
  if (READ_TOOLS.has(toolName)) return readPolicy;
@@ -1 +1 @@
1
- {"version":3,"file":"createWorkspacePolicyHook.mjs","names":[],"sources":["../../../src/hooks/createWorkspacePolicyHook.ts"],"sourcesContent":["/**\n * Workspace boundary policy as a `PreToolUse` hook.\n *\n * Local-engine file tools enforce a hard workspace boundary at the\n * tool implementation layer (`resolveWorkspacePathSafe`). This hook\n * adds a complementary, host-controlled layer on top that uses the\n * standard PreToolUse / HITL machinery to *negotiate* access to\n * paths outside the workspace — instead of just throwing.\n *\n * The host opts in by registering this hook on a `HookRegistry`; the\n * hook inspects each tool call's input, extracts the file paths it\n * mentions via per-tool extractors, and returns:\n *\n * - `allow` — every path is inside `workspace.root`\n * (or `additionalRoots`)\n * - `deny` — at least one path is outside, and the\n * configured outside-policy is `'deny'`\n * - `ask` — at least one path is outside, and the\n * outside-policy is `'ask'` (default).\n * When `humanInTheLoop.enabled` is true,\n * the existing PreToolUse `'ask'` flow\n * raises a tool_approval interrupt the\n * host UI can render. When HITL is off,\n * `'ask'` collapses to `deny` (matches\n * the rest of the SDK's default).\n *\n * Default per-tool path extractors cover the local-engine coding\n * suite (`read_file`, `write_file`, `edit_file`, `grep_search`,\n * `glob_search`, `list_directory`, `compile_check`). The host can\n * override or extend via `pathExtractors`. Bash/code paths are not\n * extracted by default — bash command parsing is its own concern, and\n * the existing `bashAst` validator + sandbox-runtime fs allowlist are\n * the right gates for those.\n *\n * Important: this hook does NOT replace `resolveWorkspacePathSafe`.\n * Even if the hook returns `allow`, the file tool still enforces its\n * own clamp unless `workspace.allowReadOutside` /\n * `workspace.allowWriteOutside` (or the legacy\n * `allowOutsideWorkspace`) is set. The recommended composition for\n * \"ask the user\" semantics is:\n *\n * workspace: {\n * root,\n * allowReadOutside: true,\n * allowWriteOutside: true,\n * },\n * // …with the hook installed and humanInTheLoop.enabled = true.\n */\n\nimport { homedir } from 'os';\nimport { realpath } from 'fs/promises';\nimport { isAbsolute, relative, resolve } from 'path';\nimport type {\n HookCallback,\n PreToolUseHookInput,\n PreToolUseHookOutput,\n ToolDecision,\n} from './types';\nimport { Constants } from '@/common';\n\n/**\n * What to do when a tool call references a path outside the workspace.\n *\n * - `'ask'` : default. Raise a PreToolUse `ask` (host UI prompts\n * via the HITL interrupt path).\n * - `'allow'` : let the call through (use the existing tool clamp\n * to actually enforce — the hook is purely advisory).\n * - `'deny'` : block the call with an error ToolMessage.\n */\nexport type OutsideAccessPolicy = 'ask' | 'allow' | 'deny';\n\nexport interface WorkspacePolicyConfig {\n /** Canonical workspace root. Required. */\n root: string;\n /** Sibling roots that count as inside-workspace. */\n additionalRoots?: readonly string[];\n /** Policy applied to read-only file tools. Defaults to `'ask'`. */\n outsideRead?: OutsideAccessPolicy;\n /** Policy applied to write-shaped file tools. Defaults to `'ask'`. */\n outsideWrite?: OutsideAccessPolicy;\n /**\n * Optional reason template surfaced in the `ask`/`deny` decision.\n * Supports `{tool}` and `{paths}` substitution.\n */\n reason?: string;\n /**\n * Per-tool path extractors. Defaults cover the local-engine coding\n * suite. Returning an empty array opts that tool out of policy.\n */\n pathExtractors?: Record<string, PathExtractor>;\n}\n\nexport type PathExtractor = (\n toolInput: Record<string, unknown>\n) => readonly string[];\n\nconst READ_TOOLS = new Set<string>([\n Constants.READ_FILE,\n Constants.GREP_SEARCH,\n Constants.GLOB_SEARCH,\n Constants.LIST_DIRECTORY,\n Constants.COMPILE_CHECK,\n]);\n\nconst WRITE_TOOLS = new Set<string>([\n Constants.WRITE_FILE,\n Constants.EDIT_FILE,\n]);\n\n/**\n * Best-effort extractor for `compile_check` — pulls absolute and `~/`\n * path tokens out of the `command` string so the workspace boundary\n * sees them. Without this, a model could ship `command: 'cat\n * /etc/passwd'` and the policy hook would short-circuit to `allow`\n * (Codex P1 #26 — the prior `() => []` made the hook a no-op for\n * compile_check). Conservative by design:\n *\n * - Matches `/foo`, `~/foo`, `$HOME/foo`, `${HOME}/foo` followed by\n * non-shell-special chars. Stops at whitespace, quotes, redirect\n * operators, pipes, semicolons.\n * - Strips a leading `--flag=` so `--out=/etc/foo` extracts as\n * `/etc/foo` (the path the agent's actually trying to write).\n * - Misses relative paths (intended — those resolve under cwd\n * anyway), and shell-substituted paths whose final form isn't\n * visible at extract time. Hosts that need bulletproof gating\n * should pair this with a `bash_tool`-level policy.\n */\n// `[\"']?` slots before AND after the captured path cover quoted\n// forms like `cat \"/etc/passwd\"` and `--out='/tmp/x'`. Codex P1 #31\n// — the previous regex only matched unquoted tokens, so a model\n// could trivially bypass the workspace policy by quoting any\n// destination path. The path content character class still excludes\n// quotes/whitespace/shell-specials so we don't over-extract; that's\n// the defensive trade we want for fallback-grep style matching.\n//\n// The `\\.\\.(?:\\/[^…]*)?` alternation covers parent-traversal forms\n// (`..`, `../secrets.txt`, `../foo/bar`). Without it, a model could\n// exfiltrate parent-directory files via `cat ../secrets` and the\n// hook would short-circuit to `allow` because the extractor saw no\n// \"absolute\" token. The boundary check at the call site resolves\n// non-absolute extracted tokens against `root`, so `../secrets`\n// becomes `<parent-of-workspace>/secrets` which the boundary then\n// correctly flags as outside. Codex P2 #35.\nconst PATH_TOKEN =\n /(?:^|[\\s=])(?:--[^\\s=]+=)?[\"']?(\\/[^\\s'\"|;&<>()`]+|~\\/[^\\s'\"|;&<>()`]+|\\$\\{?HOME\\}?\\/[^\\s'\"|;&<>()`]+|\\.\\.(?:\\/[^\\s'\"|;&<>()`]*)?)[\"']?/g;\n// Back-compat alias kept for any downstream import.\nconst ABSOLUTE_PATH_TOKEN = PATH_TOKEN;\nfunction expandHomeRelative(token: string): string {\n // Expand ~/foo and $HOME/foo and ${HOME}/foo to absolute. The\n // workspace boundary check resolves non-absolute paths against the\n // workspace root, which would silently treat `~/secret` as\n // `<workspace>/~/secret` — exactly the bypass the codex flagged.\n const home = homedir();\n if (token.startsWith('~/')) return `${home}/${token.slice(2)}`;\n if (token.startsWith('${HOME}/')) return `${home}/${token.slice(8)}`;\n if (token.startsWith('$HOME/')) return `${home}/${token.slice(6)}`;\n return token;\n}\nfunction extractCompileCheckPaths(input: Record<string, unknown>): string[] {\n const command = typeof input.command === 'string' ? input.command : '';\n if (command === '') return [];\n const out: string[] = [];\n for (const match of command.matchAll(ABSOLUTE_PATH_TOKEN)) {\n out.push(expandHomeRelative(match[1]));\n }\n return out;\n}\n\n// All built-in coding tools take their file/dir target in `path`.\nconst extractPath: PathExtractor = (i) =>\n typeof i.path === 'string' && i.path !== '' ? [i.path] : [];\n\nconst DEFAULT_EXTRACTORS: Record<string, PathExtractor> = {\n [Constants.READ_FILE]: extractPath,\n [Constants.WRITE_FILE]: extractPath,\n [Constants.EDIT_FILE]: extractPath,\n [Constants.GREP_SEARCH]: (i) =>\n typeof i.path === 'string' && i.path !== '' ? [i.path] : [],\n [Constants.GLOB_SEARCH]: (i) =>\n typeof i.path === 'string' && i.path !== '' ? [i.path] : [],\n [Constants.LIST_DIRECTORY]: (i) =>\n typeof i.path === 'string' && i.path !== '' ? [i.path] : [],\n [Constants.COMPILE_CHECK]: extractCompileCheckPaths,\n};\n\nfunction isInsideAnyRoot(absolutePath: string, roots: string[]): boolean {\n for (const root of roots) {\n if (absolutePath === root) return true;\n const rel = relative(root, absolutePath);\n if (!rel.startsWith('..') && !isAbsolute(rel)) return true;\n }\n return false;\n}\n\n/**\n * Symlink-aware variant: realpaths the candidate AND the roots before\n * comparing. Without this, a symlink inside the workspace pointing\n * outside (e.g. `workspace/link → /etc/passwd`) compares as\n * \"in-workspace\" lexically, but actually grants the agent reach\n * outside the boundary. Critical when this hook is the primary gate\n * (i.e. the host opted into `workspace.allowReadOutside: true` /\n * `allowWriteOutside: true` so the file tools' own clamp is off).\n *\n * Handles paths that don't yet exist (e.g. `write_file` to a brand\n * new path) by walking up to the nearest existing ancestor and\n * realpathing that, then re-attaching the unresolved suffix. Mirrors\n * `resolveWorkspacePathSafe`'s approach in LocalExecutionEngine.\n */\nasync function realpathOrSelf(absolutePath: string): Promise<string> {\n try {\n return await realpath(absolutePath);\n } catch {\n return absolutePath;\n }\n}\n\nasync function realpathOfPathOrAncestor(absolutePath: string): Promise<string> {\n let current = absolutePath;\n let suffix = '';\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while (true) {\n try {\n const real = await realpath(current);\n return suffix === '' ? real : resolve(real, suffix);\n } catch {\n const parent = resolve(current, '..');\n if (parent === current) {\n return absolutePath;\n }\n const base = current.slice(parent.length + 1);\n suffix = suffix === '' ? base : `${base}/${suffix}`;\n current = parent;\n }\n }\n}\n\nasync function isInsideAnyRootRealpath(\n absolutePath: string,\n realRoots: readonly string[]\n): Promise<boolean> {\n const real = await realpathOfPathOrAncestor(absolutePath);\n return isInsideAnyRoot(real, [...realRoots]);\n}\n\nfunction formatReason(\n template: string | undefined,\n toolName: string,\n outsidePaths: readonly string[]\n): string {\n const fallback = `Tool \"${toolName}\" wants to touch ${outsidePaths.length} path(s) outside the workspace: ${outsidePaths.join(', ')}`;\n if (template == null) return fallback;\n return template\n .replace(/\\{tool\\}/g, toolName)\n .replace(/\\{paths\\}/g, outsidePaths.join(', '));\n}\n\n/**\n * Build a `PreToolUse` callback that enforces the workspace policy.\n * Register it on a `HookRegistry`:\n *\n * ```ts\n * registry.register('PreToolUse', {\n * hooks: [createWorkspacePolicyHook({ root, outsideWrite: 'ask' })],\n * });\n * ```\n *\n * The hook is composable with `createToolPolicyHook` — register both;\n * `executeHooks` precedence (`deny > ask > allow`) sorts out which\n * decision wins per call.\n */\nexport function createWorkspacePolicyHook(\n config: WorkspacePolicyConfig\n): HookCallback<'PreToolUse'> {\n const root = resolve(config.root);\n // Relative `additionalRoots` entries are anchored to `root` so a\n // monorepo config like `additionalRoots: ['../shared']` resolves\n // to a sibling of `root`, not of process.cwd. Matches\n // `getWorkspaceRoots` in LocalExecutionEngine.\n const additionalRoots = (config.additionalRoots ?? []).map((p) =>\n isAbsolute(p) ? resolve(p) : resolve(root, p)\n );\n const allRoots = [root, ...additionalRoots];\n\n // Pre-realpath the roots once at construction — these are stable\n // per Run. The candidate paths get realpath'd lazily inside the\n // hook callback. Cached so the per-call cost is just one realpath.\n let realRootsPromise: Promise<string[]> | undefined;\n const getRealRoots = (): Promise<string[]> => {\n if (realRootsPromise == null) {\n realRootsPromise = Promise.all(allRoots.map(realpathOrSelf));\n }\n return realRootsPromise;\n };\n\n const readPolicy: OutsideAccessPolicy = config.outsideRead ?? 'ask';\n const writePolicy: OutsideAccessPolicy = config.outsideWrite ?? 'ask';\n\n const extractors: Record<string, PathExtractor | undefined> = {\n ...DEFAULT_EXTRACTORS,\n ...(config.pathExtractors ?? {}),\n };\n\n /** Unknown tools are treated as writes (the stricter policy). */\n const resolvePolicy = (toolName: string): OutsideAccessPolicy => {\n if (WRITE_TOOLS.has(toolName)) {\n return writePolicy;\n }\n if (READ_TOOLS.has(toolName)) {\n return readPolicy;\n }\n return writePolicy;\n };\n\n return async (input: PreToolUseHookInput): Promise<PreToolUseHookOutput> => {\n const extractor = extractors[input.toolName];\n if (extractor == null) return { decision: 'allow' };\n\n const paths = extractor(input.toolInput);\n if (paths.length === 0) return { decision: 'allow' };\n\n // Two-stage check:\n // 1. Lexical fast path — anything that's lexically inside the\n // workspace AND doesn't get redirected by realpath stays\n // allow-able without paying the realpath cost on every call.\n // 2. For paths that look outside lexically OR look inside but\n // may have been routed through a symlink, realpath both the\n // candidate and the roots and compare. This catches the\n // `workspace/link → /etc/passwd` escape that lexical-only\n // checks miss.\n const outside: string[] = [];\n const realRoots = await getRealRoots();\n for (const p of paths) {\n const abs = isAbsolute(p) ? resolve(p) : resolve(root, p);\n // Realpath is the source of truth — it catches both the\n // symlink-escape case (lexically-inside path that resolves\n // outside) and the alternate-mount case (lexically-outside\n // path that resolves back inside the workspace). The lexical\n // check alone gives the wrong answer for either, so we don't\n // bother computing it.\n const realInside = await isInsideAnyRootRealpath(abs, realRoots);\n if (!realInside) {\n outside.push(p);\n }\n }\n if (outside.length === 0) return { decision: 'allow' };\n\n const policy = resolvePolicy(input.toolName);\n if (policy === 'allow') return { decision: 'allow' };\n\n const decision: ToolDecision = policy === 'deny' ? 'deny' : 'ask';\n return {\n decision,\n reason: formatReason(config.reason, input.toolName, outside),\n ...(decision === 'ask'\n ? { allowedDecisions: ['approve', 'reject'] as const }\n : {}),\n };\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createWorkspacePolicyHook.mjs","names":[],"sources":["../../../src/hooks/createWorkspacePolicyHook.ts"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { matchesQuery } from "./matchers.mjs";
2
2
  //#region src/hooks/executeHooks.ts
3
- /** Default per-hook timeout when a matcher doesn't set its own. */
4
3
  const DEFAULT_HOOK_TIMEOUT_MS = 3e4;
5
4
  function freshResult() {
6
5
  return {
@@ -191,12 +190,6 @@ function fold(outcomes) {
191
190
  }
192
191
  const output = outcome.output;
193
192
  if (output === null) continue;
194
- /**
195
- * Skip fire-and-forget outputs entirely: the agent has already
196
- * moved on, so an async hook cannot influence the run. Background
197
- * work inside the hook body still runs (we don't cancel it), it
198
- * just doesn't fold into the aggregate result.
199
- */
200
193
  if (output.async === true) continue;
201
194
  const targets = isOnceMatcher ? [aggregated, onceContribution] : [aggregated];
202
195
  if (isOnceMatcher) hasOnceContribution = true;
@@ -215,60 +208,6 @@ function fold(outcomes) {
215
208
  ...hasOnceContribution ? { onceReplayContribution: onceContribution } : {}
216
209
  };
217
210
  }
218
- /**
219
- * Fires every matcher registered against `input.hook_event_name`, folding
220
- * their results per `deny > ask > allow` precedence and accumulating
221
- * context/errors.
222
- *
223
- * ## Parallelism and determinism
224
- *
225
- * All matching hooks fire simultaneously and are awaited via `Promise.all`,
226
- * which preserves input-array order in its returned results. The fold
227
- * therefore iterates outcomes in **registration order** — outer loop over
228
- * matchers as they sit in the registry (global first, then session), inner
229
- * loop over each matcher's `hooks` array. Last-writer-wins fields
230
- * (`updatedInput`, `updatedOutput`) are deterministic in that order, even
231
- * though hooks may complete in arbitrary wall-clock order.
232
- *
233
- * Consumers that need a single authoritative rewrite should still scope
234
- * `updatedInput`/`updatedOutput` to one hook per matcher to avoid subtle
235
- * precedence bugs when matchers are added in a different order than
236
- * expected.
237
- *
238
- * ## Timeouts and cancellation
239
- *
240
- * Each matcher receives **one shared `AbortSignal`** derived from the
241
- * caller's parent signal combined with `matcher.timeout` (falling back to
242
- * `opts.timeoutMs`, default {@link DEFAULT_HOOK_TIMEOUT_MS}). Sharing the
243
- * signal across hooks in a matcher collapses N timer allocations into
244
- * one, which matters on the PreToolUse hot path where a matcher with
245
- * several hooks fires on every tool call. Each hook call is raced
246
- * against the shared signal, so even a hook that ignores the signal is
247
- * force-unblocked when the timeout fires. Timeout/abort errors are
248
- * swallowed into the aggregated result's `errors` array (non-fatal by
249
- * default).
250
- *
251
- * ## Internal matchers
252
- *
253
- * A matcher with `internal: true` is excluded from both the `errors` array
254
- * and the logger output. Use it for infrastructure hooks whose failures
255
- * should not pollute user-visible diagnostics.
256
- *
257
- * ## Once semantics — atomic at-most-once
258
- *
259
- * A matcher with `once: true` is removed from the registry **before any
260
- * hook runs**, inside the synchronous prefix of `executeHooks` (between
261
- * `getMatchers` and the first `await`). Because Node's event loop serialises
262
- * sync work, two concurrent `executeHooks` calls can never both observe
263
- * and dispatch the same `once` matcher — whichever call runs its sync
264
- * prefix first consumes it, and the loser sees an empty bucket.
265
- *
266
- * Trade-off: if every hook in a `once` matcher throws, the matcher is
267
- * still gone. "Once" here means "at most one dispatch, ever", not "at
268
- * most one successful execution with retry on failure". Hosts that need
269
- * retry semantics should register a normal matcher and self-unregister
270
- * via the `unregister` callback returned from `registry.register`.
271
- */
272
211
  async function executeHooks(opts) {
273
212
  const { registry, input, sessionId, matchQuery, onceReplayKey, onceReplaySessionId, signal, timeoutMs = DEFAULT_HOOK_TIMEOUT_MS, logger } = opts;
274
213
  const event = input.hook_event_name;
@@ -291,24 +230,6 @@ async function executeHooks(opts) {
291
230
  const aggregated = combineAggregatedResults(pendingApproval, liveResult);
292
231
  if (event === "PreToolUse" && aggregated.decision === "ask" && onceReplayContribution != null && replaySessionId != null && onceReplayKey != null) registry.setPendingToolApproval(replaySessionId, onceReplayKey, createPendingApprovalReplay(aggregated, pendingApproval, onceReplayContribution));
293
232
  else if (event === "PreToolUse" && aggregated.decision !== "ask" && pendingApproval != null && replaySessionId != null && onceReplayKey != null) registry.clearPendingToolApproval(replaySessionId, onceReplayKey);
294
- /**
295
- * Centralized `preventContinuation` propagation: when any hook (across
296
- * any callsite — RunStart, PreToolUse, PostToolBatch, SubagentStop,
297
- * etc.) returns `preventContinuation: true`, raise a halt signal on
298
- * the registry scoped to the run's `sessionId`. `Run.processStream`
299
- * polls the signal between stream events using its own id and exits
300
- * cleanly, skipping the `Stop` hook (since the run is being halted,
301
- * not naturally completing).
302
- *
303
- * First-write-wins per session inside the registry — a halt already
304
- * raised by an earlier hook in the same run is preserved so the
305
- * original `reason` / `source` are not clobbered. Hooks fired
306
- * without a `sessionId` cannot raise a halt (there's no run for the
307
- * loop to poll under), which is fine: every in-tree callsite passes
308
- * `sessionId: runId`. Pre-stream callsites in `Run.processStream`
309
- * still read `preventContinuation` directly off the result for an
310
- * early return because they have not yet entered the stream loop.
311
- */
312
233
  if (aggregated.preventContinuation === true && sessionId !== void 0) registry.haltRun(sessionId, aggregated.stopReason ?? "preventContinuation", event);
313
234
  return aggregated;
314
235
  }
@@ -1 +1 @@
1
- {"version":3,"file":"executeHooks.mjs","names":[],"sources":["../../../src/hooks/executeHooks.ts"],"sourcesContent":["// src/hooks/executeHooks.ts\nimport type { Logger } from 'winston';\nimport type {\n HookInput,\n HookEvent,\n HookOutput,\n HookMatcher,\n ToolDecision,\n StopDecision,\n HookCallback,\n ToolApprovalReplayKey,\n AggregatedHookResult,\n} from './types';\nimport type { HookRegistry } from './HookRegistry';\nimport { matchesQuery } from './matchers';\n\n/** Default per-hook timeout when a matcher doesn't set its own. */\nexport const DEFAULT_HOOK_TIMEOUT_MS = 30_000;\n\n/**\n * Options for a single `executeHooks` call. The `input` drives everything —\n * the event name is read from `input.hook_event_name`, matchers are looked\n * up against that event, and each hook receives `input` directly.\n */\nexport interface ExecuteHooksOptions {\n registry: HookRegistry;\n input: HookInput;\n /** Scope lookup to this session (in addition to global matchers). */\n sessionId?: string;\n /** Query string matched against each matcher's pattern (tool name, etc.). */\n matchQuery?: string;\n /** Stable tool-call key for replaying consumed one-shot contributions. */\n onceReplayKey?: ToolApprovalReplayKey;\n /** Storage scope for replay state when it must outlive or branch from the hook session. */\n onceReplaySessionId?: string;\n /** Parent AbortSignal — combined with per-hook timeout into the hook signal. */\n signal?: AbortSignal;\n /** Default per-hook timeout; overridden by `matcher.timeout` when present. */\n timeoutMs?: number;\n /** Optional winston logger for non-internal hook errors. */\n logger?: Logger;\n}\n\ntype WideMatcher = HookMatcher<HookEvent>;\ntype WideCallback = HookCallback<HookEvent>;\n\ninterface HookOutcome {\n matcher: WideMatcher;\n output: HookOutput | null;\n error: string | null;\n timedOut: boolean;\n}\n\ninterface AbortRace {\n promise: Promise<never>;\n cleanup: () => void;\n}\n\nfunction freshResult(): AggregatedHookResult {\n return {\n additionalContexts: [],\n injectedMessages: [],\n errors: [],\n };\n}\n\nfunction combineSignals(\n parent: AbortSignal | undefined,\n timeoutMs: number\n): AbortSignal {\n const timeoutSignal = AbortSignal.timeout(timeoutMs);\n if (parent === undefined) {\n return timeoutSignal;\n }\n return AbortSignal.any([parent, timeoutSignal]);\n}\n\nfunction isTimeout(err: unknown): boolean {\n if (err instanceof Error) {\n return err.name === 'TimeoutError' || err.name === 'AbortError';\n }\n return false;\n}\n\nfunction describeError(err: unknown): string {\n if (err instanceof Error) {\n return err.message !== '' ? err.message : err.name;\n }\n return String(err);\n}\n\nfunction makeAbortPromise(signal: AbortSignal): {\n promise: Promise<never>;\n cleanup: () => void;\n} {\n let onAbort: (() => void) | undefined;\n const promise = new Promise<never>((_resolve, reject) => {\n if (signal.aborted) {\n reject(\n signal.reason instanceof Error ? signal.reason : new Error('aborted')\n );\n return;\n }\n onAbort = (): void => {\n reject(\n signal.reason instanceof Error ? signal.reason : new Error('aborted')\n );\n };\n signal.addEventListener('abort', onAbort, { once: true });\n });\n const cleanup = (): void => {\n if (onAbort !== undefined) {\n signal.removeEventListener('abort', onAbort);\n onAbort = undefined;\n }\n };\n return { promise, cleanup };\n}\n\nasync function runHook(\n hook: WideCallback,\n input: HookInput,\n signal: AbortSignal,\n abortPromise: Promise<never>,\n matcher: WideMatcher\n): Promise<HookOutcome> {\n const hookPromise = Promise.resolve().then(() => hook(input, signal));\n try {\n const output = await Promise.race([hookPromise, abortPromise]);\n return { matcher, output, error: null, timedOut: false };\n } catch (err) {\n return {\n matcher,\n output: null,\n error: describeError(err),\n timedOut: isTimeout(err),\n };\n }\n}\n\nasync function runMatcherHooks(\n matcher: WideMatcher,\n input: HookInput,\n signal: AbortSignal\n): Promise<HookOutcome[]> {\n const abortRace: AbortRace = makeAbortPromise(signal);\n const tasks = matcher.hooks.map((hook) =>\n runHook(hook, input, signal, abortRace.promise, matcher)\n );\n try {\n return await Promise.all(tasks);\n } finally {\n abortRace.cleanup();\n }\n}\n\nfunction reportErrors(\n outcomes: readonly HookOutcome[],\n event: HookEvent,\n logger: Logger | undefined\n): void {\n for (const outcome of outcomes) {\n if (outcome.error === null) {\n continue;\n }\n if (outcome.matcher.internal === true) {\n continue;\n }\n const label = outcome.timedOut ? 'timed out' : 'threw an error';\n const message = `Hook for ${event} ${label}: ${outcome.error}`;\n if (logger !== undefined) {\n logger.warn(message);\n continue;\n }\n // eslint-disable-next-line no-console\n console.warn(message);\n }\n}\n\nfunction applyToolDecision(\n agg: AggregatedHookResult,\n decision: ToolDecision,\n reason: string | undefined\n): void {\n if (decision === 'deny') {\n if (agg.decision === 'deny') {\n return;\n }\n agg.decision = 'deny';\n agg.reason = reason;\n return;\n }\n if (decision === 'ask') {\n if (agg.decision === 'deny' || agg.decision === 'ask') {\n return;\n }\n agg.decision = 'ask';\n agg.reason = reason;\n return;\n }\n if (agg.decision === undefined) {\n agg.decision = 'allow';\n agg.reason = reason;\n }\n}\n\nfunction applyStopDecision(\n agg: AggregatedHookResult,\n decision: StopDecision,\n reason: string | undefined\n): void {\n if (decision === 'block') {\n if (agg.stopDecision === 'block') {\n return;\n }\n agg.stopDecision = 'block';\n agg.reason = reason;\n return;\n }\n if (agg.stopDecision === undefined) {\n agg.stopDecision = 'continue';\n if (agg.reason === undefined) {\n agg.reason = reason;\n }\n }\n}\n\nfunction applyDecision(agg: AggregatedHookResult, output: HookOutput): void {\n if (!('decision' in output) || output.decision === undefined) {\n return;\n }\n const decision = output.decision;\n const reason =\n 'reason' in output && typeof output.reason === 'string'\n ? output.reason\n : undefined;\n if (decision === 'deny' || decision === 'ask' || decision === 'allow') {\n applyToolDecision(agg, decision, reason);\n return;\n }\n applyStopDecision(agg, decision, reason);\n}\n\nfunction applyContext(agg: AggregatedHookResult, output: HookOutput): void {\n if (\n typeof output.additionalContext === 'string' &&\n output.additionalContext.length > 0\n ) {\n agg.additionalContexts.push(output.additionalContext);\n }\n}\n\nfunction applyInjectedMessages(\n agg: AggregatedHookResult,\n output: HookOutput\n): void {\n if (\n output.injectedMessages === undefined ||\n output.injectedMessages.length === 0\n ) {\n return;\n }\n agg.injectedMessages.push(...output.injectedMessages);\n}\n\nfunction applyStopFlag(agg: AggregatedHookResult, output: HookOutput): void {\n if (output.preventContinuation !== true) {\n return;\n }\n agg.preventContinuation = true;\n if (typeof output.stopReason === 'string' && agg.stopReason === undefined) {\n agg.stopReason = output.stopReason;\n }\n}\n\nfunction applyUpdatedInput(\n agg: AggregatedHookResult,\n output: HookOutput\n): void {\n if (!('updatedInput' in output) || output.updatedInput === undefined) {\n return;\n }\n agg.updatedInput = output.updatedInput;\n}\n\nfunction applyUpdatedOutput(\n agg: AggregatedHookResult,\n output: HookOutput\n): void {\n if (!('updatedOutput' in output) || output.updatedOutput === undefined) {\n return;\n }\n agg.updatedOutput = output.updatedOutput;\n}\n\nfunction applyAllowedDecisions(\n agg: AggregatedHookResult,\n output: HookOutput\n): void {\n if (\n !('allowedDecisions' in output) ||\n output.allowedDecisions === undefined\n ) {\n return;\n }\n agg.allowedDecisions = output.allowedDecisions;\n}\n\nfunction applyAggregatedResult(\n target: AggregatedHookResult,\n source: AggregatedHookResult\n): void {\n target.additionalContexts.push(...source.additionalContexts);\n target.injectedMessages.push(...source.injectedMessages);\n target.errors.push(...source.errors);\n if (source.decision != null) {\n applyToolDecision(target, source.decision, source.reason);\n }\n if (source.stopDecision != null) {\n applyStopDecision(target, source.stopDecision, source.reason);\n }\n if (source.updatedInput != null) {\n target.updatedInput = source.updatedInput;\n }\n if (source.updatedOutput !== undefined) {\n target.updatedOutput = source.updatedOutput;\n }\n if (source.allowedDecisions != null) {\n target.allowedDecisions = source.allowedDecisions;\n }\n if (source.preventContinuation === true) {\n target.preventContinuation = true;\n target.stopReason ??= source.stopReason;\n }\n}\n\nfunction combineAggregatedResults(\n first: AggregatedHookResult | undefined,\n second: AggregatedHookResult\n): AggregatedHookResult {\n if (first == null) {\n return second;\n }\n const combined = freshResult();\n applyAggregatedResult(combined, first);\n applyAggregatedResult(combined, second);\n return combined;\n}\n\nfunction createPendingApprovalReplay(\n approvalResult: AggregatedHookResult,\n pendingApproval: AggregatedHookResult | undefined,\n onceContribution: AggregatedHookResult\n): AggregatedHookResult {\n const replay = freshResult();\n if (pendingApproval != null) {\n applyAggregatedResult(replay, pendingApproval);\n }\n applyAggregatedResult(replay, onceContribution);\n replay.decision = 'ask';\n replay.reason = approvalResult.reason;\n if (approvalResult.allowedDecisions == null) {\n delete replay.allowedDecisions;\n } else {\n replay.allowedDecisions = approvalResult.allowedDecisions;\n }\n return replay;\n}\n\nfunction fold(outcomes: readonly HookOutcome[]): {\n aggregated: AggregatedHookResult;\n onceReplayContribution?: AggregatedHookResult;\n} {\n const aggregated = freshResult();\n const onceContribution = freshResult();\n let hasOnceContribution = false;\n for (const outcome of outcomes) {\n const isOnceMatcher = outcome.matcher.once === true;\n if (outcome.error !== null) {\n if (outcome.matcher.internal !== true) {\n aggregated.errors.push(outcome.error);\n }\n continue;\n }\n const output = outcome.output;\n if (output === null) {\n continue;\n }\n /**\n * Skip fire-and-forget outputs entirely: the agent has already\n * moved on, so an async hook cannot influence the run. Background\n * work inside the hook body still runs (we don't cancel it), it\n * just doesn't fold into the aggregate result.\n */\n if (output.async === true) {\n continue;\n }\n const targets = isOnceMatcher\n ? [aggregated, onceContribution]\n : [aggregated];\n if (isOnceMatcher) {\n hasOnceContribution = true;\n }\n for (const target of targets) {\n applyContext(target, output);\n applyInjectedMessages(target, output);\n applyStopFlag(target, output);\n applyDecision(target, output);\n applyUpdatedInput(target, output);\n applyUpdatedOutput(target, output);\n applyAllowedDecisions(target, output);\n }\n }\n return {\n aggregated,\n ...(hasOnceContribution\n ? { onceReplayContribution: onceContribution }\n : {}),\n };\n}\n\n/**\n * Fires every matcher registered against `input.hook_event_name`, folding\n * their results per `deny > ask > allow` precedence and accumulating\n * context/errors.\n *\n * ## Parallelism and determinism\n *\n * All matching hooks fire simultaneously and are awaited via `Promise.all`,\n * which preserves input-array order in its returned results. The fold\n * therefore iterates outcomes in **registration order** — outer loop over\n * matchers as they sit in the registry (global first, then session), inner\n * loop over each matcher's `hooks` array. Last-writer-wins fields\n * (`updatedInput`, `updatedOutput`) are deterministic in that order, even\n * though hooks may complete in arbitrary wall-clock order.\n *\n * Consumers that need a single authoritative rewrite should still scope\n * `updatedInput`/`updatedOutput` to one hook per matcher to avoid subtle\n * precedence bugs when matchers are added in a different order than\n * expected.\n *\n * ## Timeouts and cancellation\n *\n * Each matcher receives **one shared `AbortSignal`** derived from the\n * caller's parent signal combined with `matcher.timeout` (falling back to\n * `opts.timeoutMs`, default {@link DEFAULT_HOOK_TIMEOUT_MS}). Sharing the\n * signal across hooks in a matcher collapses N timer allocations into\n * one, which matters on the PreToolUse hot path where a matcher with\n * several hooks fires on every tool call. Each hook call is raced\n * against the shared signal, so even a hook that ignores the signal is\n * force-unblocked when the timeout fires. Timeout/abort errors are\n * swallowed into the aggregated result's `errors` array (non-fatal by\n * default).\n *\n * ## Internal matchers\n *\n * A matcher with `internal: true` is excluded from both the `errors` array\n * and the logger output. Use it for infrastructure hooks whose failures\n * should not pollute user-visible diagnostics.\n *\n * ## Once semantics — atomic at-most-once\n *\n * A matcher with `once: true` is removed from the registry **before any\n * hook runs**, inside the synchronous prefix of `executeHooks` (between\n * `getMatchers` and the first `await`). Because Node's event loop serialises\n * sync work, two concurrent `executeHooks` calls can never both observe\n * and dispatch the same `once` matcher — whichever call runs its sync\n * prefix first consumes it, and the loser sees an empty bucket.\n *\n * Trade-off: if every hook in a `once` matcher throws, the matcher is\n * still gone. \"Once\" here means \"at most one dispatch, ever\", not \"at\n * most one successful execution with retry on failure\". Hosts that need\n * retry semantics should register a normal matcher and self-unregister\n * via the `unregister` callback returned from `registry.register`.\n */\nexport async function executeHooks(\n opts: ExecuteHooksOptions\n): Promise<AggregatedHookResult> {\n const {\n registry,\n input,\n sessionId,\n matchQuery,\n onceReplayKey,\n onceReplaySessionId,\n signal,\n timeoutMs = DEFAULT_HOOK_TIMEOUT_MS,\n logger,\n } = opts;\n const event = input.hook_event_name;\n const replaySessionId = onceReplaySessionId ?? sessionId;\n const pendingApproval =\n event === 'PreToolUse' && replaySessionId != null && onceReplayKey != null\n ? registry.getPendingToolApproval(replaySessionId, onceReplayKey)\n : undefined;\n const matchers = registry.getMatchers(event, sessionId);\n if (matchers.length === 0) {\n return pendingApproval ?? freshResult();\n }\n\n // --- SYNC CRITICAL SECTION: once-matcher removal must complete before any await ---\n const tasks: Promise<HookOutcome[]>[] = [];\n for (const matcher of matchers) {\n if (!matchesQuery(matcher.pattern, matchQuery)) {\n continue;\n }\n if (matcher.once === true) {\n registry.removeMatcher(event, matcher, sessionId);\n }\n if (matcher.hooks.length === 0) {\n continue;\n }\n const perHookTimeout = matcher.timeout ?? timeoutMs;\n const matcherSignal = combineSignals(signal, perHookTimeout);\n tasks.push(runMatcherHooks(matcher, input, matcherSignal));\n }\n // --- END SYNC CRITICAL SECTION ---\n if (tasks.length === 0) {\n return pendingApproval ?? freshResult();\n }\n\n const outcomes = (await Promise.all(tasks)).flat();\n reportErrors(outcomes, event, logger);\n const { aggregated: liveResult, onceReplayContribution } = fold(outcomes);\n const aggregated = combineAggregatedResults(pendingApproval, liveResult);\n if (\n event === 'PreToolUse' &&\n aggregated.decision === 'ask' &&\n onceReplayContribution != null &&\n replaySessionId != null &&\n onceReplayKey != null\n ) {\n registry.setPendingToolApproval(\n replaySessionId,\n onceReplayKey,\n createPendingApprovalReplay(\n aggregated,\n pendingApproval,\n onceReplayContribution\n )\n );\n } else if (\n event === 'PreToolUse' &&\n aggregated.decision !== 'ask' &&\n pendingApproval != null &&\n replaySessionId != null &&\n onceReplayKey != null\n ) {\n registry.clearPendingToolApproval(replaySessionId, onceReplayKey);\n }\n /**\n * Centralized `preventContinuation` propagation: when any hook (across\n * any callsite — RunStart, PreToolUse, PostToolBatch, SubagentStop,\n * etc.) returns `preventContinuation: true`, raise a halt signal on\n * the registry scoped to the run's `sessionId`. `Run.processStream`\n * polls the signal between stream events using its own id and exits\n * cleanly, skipping the `Stop` hook (since the run is being halted,\n * not naturally completing).\n *\n * First-write-wins per session inside the registry — a halt already\n * raised by an earlier hook in the same run is preserved so the\n * original `reason` / `source` are not clobbered. Hooks fired\n * without a `sessionId` cannot raise a halt (there's no run for the\n * loop to poll under), which is fine: every in-tree callsite passes\n * `sessionId: runId`. Pre-stream callsites in `Run.processStream`\n * still read `preventContinuation` directly off the result for an\n * early return because they have not yet entered the stream loop.\n */\n if (aggregated.preventContinuation === true && sessionId !== undefined) {\n registry.haltRun(\n sessionId,\n aggregated.stopReason ?? 'preventContinuation',\n event\n );\n }\n return aggregated;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"executeHooks.mjs","names":[],"sources":["../../../src/hooks/executeHooks.ts"],"mappings":"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"}
@@ -5,23 +5,7 @@ import "./createToolPolicyHook.mjs";
5
5
  import "./createWorkspacePolicyHook.mjs";
6
6
  import "./types.mjs";
7
7
  //#region src/hooks/index.ts
8
- /**
9
- * Feature probe for hosts: hook outputs support `injectedMessages`
10
- * (per-message graph-state injection at the `PostToolBatch` boundary).
11
- * Hosts must gate drain-style hooks on this so a queued message can never
12
- * be consumed by an SDK version that would silently drop it.
13
- */
14
8
  const HOOK_INJECTED_MESSAGES_CAPABLE = true;
15
- /**
16
- * Feature probe for hosts: this SDK dispatches `PreemptBoundary`, so a
17
- * cooperative mid-generation seal can drain into the run.
18
- *
19
- * Deliberately separate from {@link HOOK_INJECTED_MESSAGES_CAPABLE} — an SDK
20
- * version can support `injectedMessages` at the tool boundary and know
21
- * nothing about preemption. A host that probed the wrong flag would arm an
22
- * interrupt control whose seal request is silently ignored, which reads to
23
- * the user as a dead button rather than as an unsupported feature.
24
- */
25
9
  const HOOK_PREEMPT_BOUNDARY_CAPABLE = true;
26
10
  //#endregion
27
11
  export { HOOK_INJECTED_MESSAGES_CAPABLE, HOOK_PREEMPT_BOUNDARY_CAPABLE };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/hooks/index.ts"],"sourcesContent":["// src/hooks/index.ts\n//\n// Hook lifecycle system for `@librechat/agents`. Re-exported from\n// `src/index.ts` and consumed by `Run.processStream` (RunStart,\n// UserPromptSubmit, Stop, StopFailure), `ToolNode.dispatchToolEvents`\n// (PreToolUse, PostToolUse, PostToolUseFailure, PermissionDenied),\n// `createSummarizeNode` (PreCompact, PostCompact),\n// `SubagentExecutor.execute` (SubagentStart, SubagentStop), and\n// `StandardGraph.createCallModel` (PreemptBoundary).\nexport { HookRegistry } from './HookRegistry';\nexport type { HookHaltSignal } from './HookRegistry';\nexport { executeHooks, DEFAULT_HOOK_TIMEOUT_MS } from './executeHooks';\n/**\n * Feature probe for hosts: hook outputs support `injectedMessages`\n * (per-message graph-state injection at the `PostToolBatch` boundary).\n * Hosts must gate drain-style hooks on this so a queued message can never\n * be consumed by an SDK version that would silently drop it.\n */\nexport const HOOK_INJECTED_MESSAGES_CAPABLE = true;\n/**\n * Feature probe for hosts: this SDK dispatches `PreemptBoundary`, so a\n * cooperative mid-generation seal can drain into the run.\n *\n * Deliberately separate from {@link HOOK_INJECTED_MESSAGES_CAPABLE} — an SDK\n * version can support `injectedMessages` at the tool boundary and know\n * nothing about preemption. A host that probed the wrong flag would arm an\n * interrupt control whose seal request is silently ignored, which reads to\n * the user as a dead button rather than as an unsupported feature.\n */\nexport const HOOK_PREEMPT_BOUNDARY_CAPABLE = true;\nexport {\n matchesQuery,\n hasNestedQuantifier,\n MAX_PATTERN_LENGTH,\n MAX_CACHE_SIZE,\n} from './matchers';\nexport { createToolPolicyHook } from './createToolPolicyHook';\nexport type { ToolPolicyMode, ToolPolicyConfig } from './createToolPolicyHook';\nexport { createWorkspacePolicyHook } from './createWorkspacePolicyHook';\nexport type {\n OutsideAccessPolicy,\n WorkspacePolicyConfig,\n PathExtractor,\n} from './createWorkspacePolicyHook';\nexport { HOOK_EVENTS, TOOL_APPROVAL_EXECUTION_SCOPE_CONFIG_KEY } from './types';\nexport type {\n HookEvent,\n HookInput,\n HookOutput,\n HookCallback,\n HookMatcher,\n HooksByEvent,\n HookInputByEvent,\n HookOutputByEvent,\n BaseHookInput,\n BaseHookOutput,\n ToolDecision,\n StopDecision,\n ToolApprovalReplayKey,\n ToolApprovalReplaySnapshot,\n AggregatedHookResult,\n RunStartHookInput,\n UserPromptSubmitHookInput,\n PreToolUseHookInput,\n PostToolUseHookInput,\n PostToolUseFailureHookInput,\n PostToolBatchHookInput,\n PostToolBatchEntry,\n PreemptBoundaryHookInput,\n PermissionDeniedHookInput,\n SubagentStartHookInput,\n SubagentStopHookInput,\n StopHookInput,\n StopFailureHookInput,\n PreCompactHookInput,\n PostCompactHookInput,\n RunStartHookOutput,\n UserPromptSubmitHookOutput,\n PreToolUseHookOutput,\n PostToolUseHookOutput,\n PostToolUseFailureHookOutput,\n PostToolBatchHookOutput,\n PreemptBoundaryHookOutput,\n PermissionDeniedHookOutput,\n SubagentStartHookOutput,\n SubagentStopHookOutput,\n StopHookOutput,\n StopFailureHookOutput,\n PreCompactHookOutput,\n PostCompactHookOutput,\n} from './types';\nexport type { ExecuteHooksOptions } from './executeHooks';\n"],"mappings":";;;;;;;;;;;;;AAkBA,MAAa,iCAAiC;;;;;;;;;;;AAW9C,MAAa,gCAAgC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/hooks/index.ts"],"mappings":";;;;;;;AAkBA,MAAa,iCAAiC;AAW9C,MAAa,gCAAgC"}