@robota-sdk/agent-core 3.0.0-beta.9 → 3.0.0-beta.92

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 (557) hide show
  1. package/CHANGELOG.md +1090 -0
  2. package/LICENSE +661 -21
  3. package/README.md +261 -50
  4. package/dist/browser/bounded-output-BdWv9SX3.js +2 -0
  5. package/dist/browser/bounded-output-BdWv9SX3.js.map +1 -0
  6. package/dist/browser/command-executor-DIXaSMrr.js +2 -0
  7. package/dist/browser/command-executor-DIXaSMrr.js.map +1 -0
  8. package/dist/browser/http-executor-B4YgCJg7.js +2 -0
  9. package/dist/browser/http-executor-B4YgCJg7.js.map +1 -0
  10. package/dist/browser/index.d.ts +6836 -3348
  11. package/dist/browser/index.d.ts.map +1 -0
  12. package/dist/browser/index.js +14 -5
  13. package/dist/browser/index.js.map +1 -0
  14. package/dist/browser/verdict-decoder-Dz_rjoIZ.js +2 -0
  15. package/dist/browser/verdict-decoder-Dz_rjoIZ.js.map +1 -0
  16. package/dist/node/bounded-output-BdWv9SX3.js +2 -0
  17. package/dist/node/bounded-output-BdWv9SX3.js.map +1 -0
  18. package/dist/node/command-executor-D_UBZHxh.js +2 -0
  19. package/dist/node/command-executor-D_UBZHxh.js.map +1 -0
  20. package/dist/node/command-executor-wBgBdWXr.cjs +1 -0
  21. package/dist/node/http-executor-ADn4locH.js +2 -0
  22. package/dist/node/http-executor-ADn4locH.js.map +1 -0
  23. package/dist/node/http-executor-CeAAZotH.cjs +1 -0
  24. package/dist/node/index-CrXqOyiE.d.ts +7395 -0
  25. package/dist/node/index-CrXqOyiE.d.ts.map +1 -0
  26. package/dist/node/index-_C864Ezv.d.cts +7395 -0
  27. package/dist/node/index-_C864Ezv.d.cts.map +1 -0
  28. package/dist/node/index.cjs +13 -5
  29. package/dist/node/index.d.cts +3 -4238
  30. package/dist/node/index.d.ts +3 -4238
  31. package/dist/node/index.js +14 -5
  32. package/dist/node/index.js.map +1 -0
  33. package/dist/node/node.cjs +1 -0
  34. package/dist/node/node.d.cts +247 -0
  35. package/dist/node/node.d.cts.map +1 -0
  36. package/dist/node/node.d.ts +247 -0
  37. package/dist/node/node.d.ts.map +1 -0
  38. package/dist/node/node.js +2 -0
  39. package/dist/node/node.js.map +1 -0
  40. package/dist/node/project-tool-schema-DrDjGKnH.cjs +1 -0
  41. package/dist/node/project-tool-schema-_UKfY7yO.js +2 -0
  42. package/dist/node/project-tool-schema-_UKfY7yO.js.map +1 -0
  43. package/dist/node/rolldown-runtime-DK3Fl9T5.js +1 -0
  44. package/dist/node/rolldown-runtime-DWNI8pZO.cjs +1 -0
  45. package/dist/node/testing/index.cjs +1 -0
  46. package/dist/node/testing/index.d.cts +96 -0
  47. package/dist/node/testing/index.d.cts.map +1 -0
  48. package/dist/node/testing/index.d.ts +96 -0
  49. package/dist/node/testing/index.d.ts.map +1 -0
  50. package/dist/node/testing/index.js +2 -0
  51. package/dist/node/testing/index.js.map +1 -0
  52. package/dist/node/types-Ge2XB-y-.d.cts +334 -0
  53. package/dist/node/types-Ge2XB-y-.d.cts.map +1 -0
  54. package/dist/node/types-Ge2XB-y-.d.ts +334 -0
  55. package/dist/node/types-Ge2XB-y-.d.ts.map +1 -0
  56. package/dist/node/verdict-decoder-DQqwwDE7.cjs +1 -0
  57. package/dist/node/verdict-decoder-Dz_rjoIZ.js +2 -0
  58. package/dist/node/verdict-decoder-Dz_rjoIZ.js.map +1 -0
  59. package/package.json +103 -33
  60. package/dist/abstracts/abstract-agent.d.ts +0 -56
  61. package/dist/abstracts/abstract-agent.d.ts.map +0 -1
  62. package/dist/abstracts/abstract-agent.js +0 -55
  63. package/dist/abstracts/abstract-agent.js.map +0 -1
  64. package/dist/abstracts/abstract-ai-provider.d.ts +0 -187
  65. package/dist/abstracts/abstract-ai-provider.d.ts.map +0 -1
  66. package/dist/abstracts/abstract-ai-provider.js +0 -252
  67. package/dist/abstracts/abstract-ai-provider.js.map +0 -1
  68. package/dist/abstracts/abstract-executor.d.ts +0 -110
  69. package/dist/abstracts/abstract-executor.d.ts.map +0 -1
  70. package/dist/abstracts/abstract-executor.js +0 -156
  71. package/dist/abstracts/abstract-executor.js.map +0 -1
  72. package/dist/abstracts/abstract-manager.d.ts +0 -42
  73. package/dist/abstracts/abstract-manager.d.ts.map +0 -1
  74. package/dist/abstracts/abstract-manager.js +0 -49
  75. package/dist/abstracts/abstract-manager.js.map +0 -1
  76. package/dist/abstracts/abstract-module.d.ts +0 -365
  77. package/dist/abstracts/abstract-module.d.ts.map +0 -1
  78. package/dist/abstracts/abstract-module.js +0 -474
  79. package/dist/abstracts/abstract-module.js.map +0 -1
  80. package/dist/abstracts/abstract-plugin.d.ts +0 -369
  81. package/dist/abstracts/abstract-plugin.d.ts.map +0 -1
  82. package/dist/abstracts/abstract-plugin.js +0 -258
  83. package/dist/abstracts/abstract-plugin.js.map +0 -1
  84. package/dist/abstracts/abstract-tool.d.ts +0 -175
  85. package/dist/abstracts/abstract-tool.d.ts.map +0 -1
  86. package/dist/abstracts/abstract-tool.js +0 -140
  87. package/dist/abstracts/abstract-tool.js.map +0 -1
  88. package/dist/abstracts/abstract-workflow-converter.d.ts +0 -136
  89. package/dist/abstracts/abstract-workflow-converter.d.ts.map +0 -1
  90. package/dist/abstracts/abstract-workflow-converter.js +0 -252
  91. package/dist/abstracts/abstract-workflow-converter.js.map +0 -1
  92. package/dist/abstracts/abstract-workflow-validator.d.ts +0 -203
  93. package/dist/abstracts/abstract-workflow-validator.d.ts.map +0 -1
  94. package/dist/abstracts/abstract-workflow-validator.js +0 -447
  95. package/dist/abstracts/abstract-workflow-validator.js.map +0 -1
  96. package/dist/abstracts/index.d.ts +0 -6
  97. package/dist/abstracts/index.d.ts.map +0 -1
  98. package/dist/abstracts/index.js +0 -9
  99. package/dist/abstracts/index.js.map +0 -1
  100. package/dist/agents/constants.d.ts +0 -23
  101. package/dist/agents/constants.d.ts.map +0 -1
  102. package/dist/agents/constants.js +0 -22
  103. package/dist/agents/constants.js.map +0 -1
  104. package/dist/agents/index.d.ts +0 -1
  105. package/dist/agents/index.d.ts.map +0 -1
  106. package/dist/agents/index.js +0 -4
  107. package/dist/agents/index.js.map +0 -1
  108. package/dist/agents/robota.test.d.ts +0 -2
  109. package/dist/agents/robota.test.d.ts.map +0 -1
  110. package/dist/agents/robota.test.js +0 -416
  111. package/dist/agents/robota.test.js.map +0 -1
  112. package/dist/browser/builtin-templates.json +0 -107
  113. package/dist/core/robota.d.ts +0 -694
  114. package/dist/core/robota.d.ts.map +0 -1
  115. package/dist/core/robota.js +0 -1277
  116. package/dist/core/robota.js.map +0 -1
  117. package/dist/executors/local-executor.d.ts +0 -96
  118. package/dist/executors/local-executor.d.ts.map +0 -1
  119. package/dist/executors/local-executor.js +0 -197
  120. package/dist/executors/local-executor.js.map +0 -1
  121. package/dist/executors/local-executor.test.d.ts +0 -2
  122. package/dist/executors/local-executor.test.d.ts.map +0 -1
  123. package/dist/executors/local-executor.test.js +0 -192
  124. package/dist/executors/local-executor.test.js.map +0 -1
  125. package/dist/index.d.ts +0 -274
  126. package/dist/index.d.ts.map +0 -1
  127. package/dist/index.js +0 -235
  128. package/dist/index.js.map +0 -1
  129. package/dist/interfaces/agent.d.ts +0 -198
  130. package/dist/interfaces/agent.d.ts.map +0 -1
  131. package/dist/interfaces/agent.js +0 -2
  132. package/dist/interfaces/agent.js.map +0 -1
  133. package/dist/interfaces/event-service.d.ts +0 -79
  134. package/dist/interfaces/event-service.d.ts.map +0 -1
  135. package/dist/interfaces/event-service.js +0 -2
  136. package/dist/interfaces/event-service.js.map +0 -1
  137. package/dist/interfaces/executor.d.ts +0 -128
  138. package/dist/interfaces/executor.d.ts.map +0 -1
  139. package/dist/interfaces/executor.js +0 -2
  140. package/dist/interfaces/executor.js.map +0 -1
  141. package/dist/interfaces/history-module.d.ts +0 -19
  142. package/dist/interfaces/history-module.d.ts.map +0 -1
  143. package/dist/interfaces/history-module.js +0 -2
  144. package/dist/interfaces/history-module.js.map +0 -1
  145. package/dist/interfaces/index.d.ts +0 -13
  146. package/dist/interfaces/index.d.ts.map +0 -1
  147. package/dist/interfaces/index.js +0 -4
  148. package/dist/interfaces/index.js.map +0 -1
  149. package/dist/interfaces/manager.d.ts +0 -142
  150. package/dist/interfaces/manager.d.ts.map +0 -1
  151. package/dist/interfaces/manager.js +0 -2
  152. package/dist/interfaces/manager.js.map +0 -1
  153. package/dist/interfaces/messages.d.ts +0 -75
  154. package/dist/interfaces/messages.d.ts.map +0 -1
  155. package/dist/interfaces/messages.js +0 -29
  156. package/dist/interfaces/messages.js.map +0 -1
  157. package/dist/interfaces/progress-reporting.d.ts +0 -86
  158. package/dist/interfaces/progress-reporting.d.ts.map +0 -1
  159. package/dist/interfaces/progress-reporting.js +0 -37
  160. package/dist/interfaces/progress-reporting.js.map +0 -1
  161. package/dist/interfaces/provider.d.ts +0 -217
  162. package/dist/interfaces/provider.d.ts.map +0 -1
  163. package/dist/interfaces/provider.js +0 -2
  164. package/dist/interfaces/provider.js.map +0 -1
  165. package/dist/interfaces/service.d.ts +0 -205
  166. package/dist/interfaces/service.d.ts.map +0 -1
  167. package/dist/interfaces/service.js +0 -6
  168. package/dist/interfaces/service.js.map +0 -1
  169. package/dist/interfaces/tool.d.ts +0 -248
  170. package/dist/interfaces/tool.d.ts.map +0 -1
  171. package/dist/interfaces/tool.js +0 -2
  172. package/dist/interfaces/tool.js.map +0 -1
  173. package/dist/interfaces/types.d.ts +0 -71
  174. package/dist/interfaces/types.d.ts.map +0 -1
  175. package/dist/interfaces/types.js +0 -33
  176. package/dist/interfaces/types.js.map +0 -1
  177. package/dist/interfaces/workflow-converter.d.ts +0 -193
  178. package/dist/interfaces/workflow-converter.d.ts.map +0 -1
  179. package/dist/interfaces/workflow-converter.js +0 -11
  180. package/dist/interfaces/workflow-converter.js.map +0 -1
  181. package/dist/interfaces/workflow-validator.d.ts +0 -209
  182. package/dist/interfaces/workflow-validator.d.ts.map +0 -1
  183. package/dist/interfaces/workflow-validator.js +0 -16
  184. package/dist/interfaces/workflow-validator.js.map +0 -1
  185. package/dist/managers/agent-factory.d.ts +0 -132
  186. package/dist/managers/agent-factory.d.ts.map +0 -1
  187. package/dist/managers/agent-factory.js +0 -284
  188. package/dist/managers/agent-factory.js.map +0 -1
  189. package/dist/managers/agent-factory.test.d.ts +0 -2
  190. package/dist/managers/agent-factory.test.d.ts.map +0 -1
  191. package/dist/managers/agent-factory.test.js +0 -249
  192. package/dist/managers/agent-factory.test.js.map +0 -1
  193. package/dist/managers/agent-templates.d.ts +0 -84
  194. package/dist/managers/agent-templates.d.ts.map +0 -1
  195. package/dist/managers/agent-templates.js +0 -159
  196. package/dist/managers/agent-templates.js.map +0 -1
  197. package/dist/managers/ai-provider-manager.d.ts +0 -80
  198. package/dist/managers/ai-provider-manager.d.ts.map +0 -1
  199. package/dist/managers/ai-provider-manager.js +0 -226
  200. package/dist/managers/ai-provider-manager.js.map +0 -1
  201. package/dist/managers/conversation-history-manager.d.ts +0 -455
  202. package/dist/managers/conversation-history-manager.d.ts.map +0 -1
  203. package/dist/managers/conversation-history-manager.js +0 -578
  204. package/dist/managers/conversation-history-manager.js.map +0 -1
  205. package/dist/managers/conversation-history-manager.test.d.ts +0 -2
  206. package/dist/managers/conversation-history-manager.test.d.ts.map +0 -1
  207. package/dist/managers/conversation-history-manager.test.js +0 -374
  208. package/dist/managers/conversation-history-manager.test.js.map +0 -1
  209. package/dist/managers/index.d.ts +0 -8
  210. package/dist/managers/index.d.ts.map +0 -1
  211. package/dist/managers/index.js +0 -8
  212. package/dist/managers/index.js.map +0 -1
  213. package/dist/managers/module-registry.d.ts +0 -161
  214. package/dist/managers/module-registry.d.ts.map +0 -1
  215. package/dist/managers/module-registry.js +0 -519
  216. package/dist/managers/module-registry.js.map +0 -1
  217. package/dist/managers/module-type-registry.d.ts +0 -113
  218. package/dist/managers/module-type-registry.d.ts.map +0 -1
  219. package/dist/managers/module-type-registry.js +0 -439
  220. package/dist/managers/module-type-registry.js.map +0 -1
  221. package/dist/managers/plugins.d.ts +0 -166
  222. package/dist/managers/plugins.d.ts.map +0 -1
  223. package/dist/managers/plugins.js +0 -339
  224. package/dist/managers/plugins.js.map +0 -1
  225. package/dist/managers/tool-manager.d.ts +0 -70
  226. package/dist/managers/tool-manager.d.ts.map +0 -1
  227. package/dist/managers/tool-manager.js +0 -138
  228. package/dist/managers/tool-manager.js.map +0 -1
  229. package/dist/managers/tool-manager.test.d.ts +0 -2
  230. package/dist/managers/tool-manager.test.d.ts.map +0 -1
  231. package/dist/managers/tool-manager.test.js +0 -186
  232. package/dist/managers/tool-manager.test.js.map +0 -1
  233. package/dist/node/builtin-templates.json +0 -107
  234. package/dist/plugins/conversation-history/conversation-history-plugin.d.ts +0 -67
  235. package/dist/plugins/conversation-history/conversation-history-plugin.d.ts.map +0 -1
  236. package/dist/plugins/conversation-history/conversation-history-plugin.js +0 -270
  237. package/dist/plugins/conversation-history/conversation-history-plugin.js.map +0 -1
  238. package/dist/plugins/conversation-history/index.d.ts +0 -3
  239. package/dist/plugins/conversation-history/index.d.ts.map +0 -1
  240. package/dist/plugins/conversation-history/index.js +0 -2
  241. package/dist/plugins/conversation-history/index.js.map +0 -1
  242. package/dist/plugins/conversation-history/storages/database-storage.d.ts +0 -19
  243. package/dist/plugins/conversation-history/storages/database-storage.d.ts.map +0 -1
  244. package/dist/plugins/conversation-history/storages/database-storage.js +0 -94
  245. package/dist/plugins/conversation-history/storages/database-storage.js.map +0 -1
  246. package/dist/plugins/conversation-history/storages/file-storage.d.ts +0 -15
  247. package/dist/plugins/conversation-history/storages/file-storage.d.ts.map +0 -1
  248. package/dist/plugins/conversation-history/storages/file-storage.js +0 -94
  249. package/dist/plugins/conversation-history/storages/file-storage.js.map +0 -1
  250. package/dist/plugins/conversation-history/storages/index.d.ts +0 -4
  251. package/dist/plugins/conversation-history/storages/index.d.ts.map +0 -1
  252. package/dist/plugins/conversation-history/storages/index.js +0 -4
  253. package/dist/plugins/conversation-history/storages/index.js.map +0 -1
  254. package/dist/plugins/conversation-history/storages/memory-storage.d.ts +0 -15
  255. package/dist/plugins/conversation-history/storages/memory-storage.d.ts.map +0 -1
  256. package/dist/plugins/conversation-history/storages/memory-storage.js +0 -33
  257. package/dist/plugins/conversation-history/storages/memory-storage.js.map +0 -1
  258. package/dist/plugins/conversation-history/types.d.ts +0 -61
  259. package/dist/plugins/conversation-history/types.d.ts.map +0 -1
  260. package/dist/plugins/conversation-history/types.js +0 -2
  261. package/dist/plugins/conversation-history/types.js.map +0 -1
  262. package/dist/plugins/error-handling/context-adapter.d.ts +0 -30
  263. package/dist/plugins/error-handling/context-adapter.d.ts.map +0 -1
  264. package/dist/plugins/error-handling/context-adapter.js +0 -41
  265. package/dist/plugins/error-handling/context-adapter.js.map +0 -1
  266. package/dist/plugins/error-handling/error-handling-plugin.d.ts +0 -49
  267. package/dist/plugins/error-handling/error-handling-plugin.d.ts.map +0 -1
  268. package/dist/plugins/error-handling/error-handling-plugin.js +0 -229
  269. package/dist/plugins/error-handling/error-handling-plugin.js.map +0 -1
  270. package/dist/plugins/error-handling/index.d.ts +0 -10
  271. package/dist/plugins/error-handling/index.d.ts.map +0 -1
  272. package/dist/plugins/error-handling/index.js +0 -10
  273. package/dist/plugins/error-handling/index.js.map +0 -1
  274. package/dist/plugins/error-handling/types.d.ts +0 -73
  275. package/dist/plugins/error-handling/types.d.ts.map +0 -1
  276. package/dist/plugins/error-handling/types.js +0 -14
  277. package/dist/plugins/error-handling/types.js.map +0 -1
  278. package/dist/plugins/event-emitter/metrics.d.ts +0 -17
  279. package/dist/plugins/event-emitter/metrics.d.ts.map +0 -1
  280. package/dist/plugins/event-emitter/metrics.js +0 -17
  281. package/dist/plugins/event-emitter/metrics.js.map +0 -1
  282. package/dist/plugins/event-emitter/types.d.ts +0 -112
  283. package/dist/plugins/event-emitter/types.d.ts.map +0 -1
  284. package/dist/plugins/event-emitter/types.js +0 -65
  285. package/dist/plugins/event-emitter/types.js.map +0 -1
  286. package/dist/plugins/event-emitter-plugin.d.ts +0 -222
  287. package/dist/plugins/event-emitter-plugin.d.ts.map +0 -1
  288. package/dist/plugins/event-emitter-plugin.js +0 -432
  289. package/dist/plugins/event-emitter-plugin.js.map +0 -1
  290. package/dist/plugins/event-emitter-plugin.test.d.ts +0 -2
  291. package/dist/plugins/event-emitter-plugin.test.d.ts.map +0 -1
  292. package/dist/plugins/event-emitter-plugin.test.js +0 -94
  293. package/dist/plugins/event-emitter-plugin.test.js.map +0 -1
  294. package/dist/plugins/execution/execution-analytics-plugin.d.ts +0 -129
  295. package/dist/plugins/execution/execution-analytics-plugin.d.ts.map +0 -1
  296. package/dist/plugins/execution/execution-analytics-plugin.js +0 -517
  297. package/dist/plugins/execution/execution-analytics-plugin.js.map +0 -1
  298. package/dist/plugins/execution/index.d.ts +0 -3
  299. package/dist/plugins/execution/index.d.ts.map +0 -1
  300. package/dist/plugins/execution/index.js +0 -2
  301. package/dist/plugins/execution/index.js.map +0 -1
  302. package/dist/plugins/execution/types.d.ts +0 -90
  303. package/dist/plugins/execution/types.d.ts.map +0 -1
  304. package/dist/plugins/execution/types.js +0 -2
  305. package/dist/plugins/execution/types.js.map +0 -1
  306. package/dist/plugins/index.d.ts +0 -10
  307. package/dist/plugins/index.d.ts.map +0 -1
  308. package/dist/plugins/index.js +0 -11
  309. package/dist/plugins/index.js.map +0 -1
  310. package/dist/plugins/limits/types.d.ts +0 -61
  311. package/dist/plugins/limits/types.d.ts.map +0 -1
  312. package/dist/plugins/limits/types.js +0 -2
  313. package/dist/plugins/limits/types.js.map +0 -1
  314. package/dist/plugins/limits-plugin.d.ts +0 -113
  315. package/dist/plugins/limits-plugin.d.ts.map +0 -1
  316. package/dist/plugins/limits-plugin.js +0 -380
  317. package/dist/plugins/limits-plugin.js.map +0 -1
  318. package/dist/plugins/logging/formatters.d.ts +0 -14
  319. package/dist/plugins/logging/formatters.d.ts.map +0 -1
  320. package/dist/plugins/logging/formatters.js +0 -24
  321. package/dist/plugins/logging/formatters.js.map +0 -1
  322. package/dist/plugins/logging/index.d.ts +0 -3
  323. package/dist/plugins/logging/index.d.ts.map +0 -1
  324. package/dist/plugins/logging/index.js +0 -2
  325. package/dist/plugins/logging/index.js.map +0 -1
  326. package/dist/plugins/logging/logging-plugin.d.ts +0 -91
  327. package/dist/plugins/logging/logging-plugin.d.ts.map +0 -1
  328. package/dist/plugins/logging/logging-plugin.js +0 -335
  329. package/dist/plugins/logging/logging-plugin.js.map +0 -1
  330. package/dist/plugins/logging/storages/console-storage.d.ts +0 -14
  331. package/dist/plugins/logging/storages/console-storage.d.ts.map +0 -1
  332. package/dist/plugins/logging/storages/console-storage.js +0 -38
  333. package/dist/plugins/logging/storages/console-storage.js.map +0 -1
  334. package/dist/plugins/logging/storages/file-storage.d.ts +0 -14
  335. package/dist/plugins/logging/storages/file-storage.d.ts.map +0 -1
  336. package/dist/plugins/logging/storages/file-storage.js +0 -41
  337. package/dist/plugins/logging/storages/file-storage.js.map +0 -1
  338. package/dist/plugins/logging/storages/index.d.ts +0 -5
  339. package/dist/plugins/logging/storages/index.d.ts.map +0 -1
  340. package/dist/plugins/logging/storages/index.js +0 -5
  341. package/dist/plugins/logging/storages/index.js.map +0 -1
  342. package/dist/plugins/logging/storages/remote-storage.d.ts +0 -20
  343. package/dist/plugins/logging/storages/remote-storage.d.ts.map +0 -1
  344. package/dist/plugins/logging/storages/remote-storage.js +0 -61
  345. package/dist/plugins/logging/storages/remote-storage.js.map +0 -1
  346. package/dist/plugins/logging/storages/silent-storage.d.ts +0 -10
  347. package/dist/plugins/logging/storages/silent-storage.d.ts.map +0 -1
  348. package/dist/plugins/logging/storages/silent-storage.js +0 -15
  349. package/dist/plugins/logging/storages/silent-storage.js.map +0 -1
  350. package/dist/plugins/logging/types.d.ts +0 -84
  351. package/dist/plugins/logging/types.d.ts.map +0 -1
  352. package/dist/plugins/logging/types.js +0 -2
  353. package/dist/plugins/logging/types.js.map +0 -1
  354. package/dist/plugins/performance/collectors/system-metrics-collector.d.ts +0 -12
  355. package/dist/plugins/performance/collectors/system-metrics-collector.d.ts.map +0 -1
  356. package/dist/plugins/performance/collectors/system-metrics-collector.js +0 -65
  357. package/dist/plugins/performance/collectors/system-metrics-collector.js.map +0 -1
  358. package/dist/plugins/performance/index.d.ts +0 -5
  359. package/dist/plugins/performance/index.d.ts.map +0 -1
  360. package/dist/plugins/performance/index.js +0 -4
  361. package/dist/plugins/performance/index.js.map +0 -1
  362. package/dist/plugins/performance/performance-plugin.d.ts +0 -49
  363. package/dist/plugins/performance/performance-plugin.d.ts.map +0 -1
  364. package/dist/plugins/performance/performance-plugin.js +0 -293
  365. package/dist/plugins/performance/performance-plugin.js.map +0 -1
  366. package/dist/plugins/performance/storages/index.d.ts +0 -2
  367. package/dist/plugins/performance/storages/index.d.ts.map +0 -1
  368. package/dist/plugins/performance/storages/index.js +0 -4
  369. package/dist/plugins/performance/storages/index.js.map +0 -1
  370. package/dist/plugins/performance/storages/memory-storage.d.ts +0 -19
  371. package/dist/plugins/performance/storages/memory-storage.d.ts.map +0 -1
  372. package/dist/plugins/performance/storages/memory-storage.js +0 -69
  373. package/dist/plugins/performance/storages/memory-storage.js.map +0 -1
  374. package/dist/plugins/performance/types.d.ts +0 -154
  375. package/dist/plugins/performance/types.d.ts.map +0 -1
  376. package/dist/plugins/performance/types.js +0 -2
  377. package/dist/plugins/performance/types.js.map +0 -1
  378. package/dist/plugins/usage/aggregate-usage-stats.d.ts +0 -12
  379. package/dist/plugins/usage/aggregate-usage-stats.d.ts.map +0 -1
  380. package/dist/plugins/usage/aggregate-usage-stats.js +0 -115
  381. package/dist/plugins/usage/aggregate-usage-stats.js.map +0 -1
  382. package/dist/plugins/usage/index.d.ts +0 -5
  383. package/dist/plugins/usage/index.d.ts.map +0 -1
  384. package/dist/plugins/usage/index.js +0 -4
  385. package/dist/plugins/usage/index.js.map +0 -1
  386. package/dist/plugins/usage/storages/file-storage.d.ts +0 -22
  387. package/dist/plugins/usage/storages/file-storage.d.ts.map +0 -1
  388. package/dist/plugins/usage/storages/file-storage.js +0 -111
  389. package/dist/plugins/usage/storages/file-storage.js.map +0 -1
  390. package/dist/plugins/usage/storages/index.d.ts +0 -5
  391. package/dist/plugins/usage/storages/index.d.ts.map +0 -1
  392. package/dist/plugins/usage/storages/index.js +0 -5
  393. package/dist/plugins/usage/storages/index.js.map +0 -1
  394. package/dist/plugins/usage/storages/memory-storage.d.ts +0 -22
  395. package/dist/plugins/usage/storages/memory-storage.d.ts.map +0 -1
  396. package/dist/plugins/usage/storages/memory-storage.js +0 -42
  397. package/dist/plugins/usage/storages/memory-storage.js.map +0 -1
  398. package/dist/plugins/usage/storages/remote-storage.d.ts +0 -26
  399. package/dist/plugins/usage/storages/remote-storage.d.ts.map +0 -1
  400. package/dist/plugins/usage/storages/remote-storage.js +0 -115
  401. package/dist/plugins/usage/storages/remote-storage.js.map +0 -1
  402. package/dist/plugins/usage/storages/silent-storage.d.ts +0 -19
  403. package/dist/plugins/usage/storages/silent-storage.d.ts.map +0 -1
  404. package/dist/plugins/usage/storages/silent-storage.js +0 -26
  405. package/dist/plugins/usage/storages/silent-storage.js.map +0 -1
  406. package/dist/plugins/usage/types.d.ts +0 -127
  407. package/dist/plugins/usage/types.d.ts.map +0 -1
  408. package/dist/plugins/usage/types.js +0 -2
  409. package/dist/plugins/usage/types.js.map +0 -1
  410. package/dist/plugins/usage/usage-plugin.d.ts +0 -67
  411. package/dist/plugins/usage/usage-plugin.d.ts.map +0 -1
  412. package/dist/plugins/usage/usage-plugin.js +0 -309
  413. package/dist/plugins/usage/usage-plugin.js.map +0 -1
  414. package/dist/plugins/webhook/http-client.d.ts +0 -30
  415. package/dist/plugins/webhook/http-client.d.ts.map +0 -1
  416. package/dist/plugins/webhook/http-client.js +0 -110
  417. package/dist/plugins/webhook/http-client.js.map +0 -1
  418. package/dist/plugins/webhook/index.d.ts +0 -9
  419. package/dist/plugins/webhook/index.d.ts.map +0 -1
  420. package/dist/plugins/webhook/index.js +0 -9
  421. package/dist/plugins/webhook/index.js.map +0 -1
  422. package/dist/plugins/webhook/transformer.d.ts +0 -63
  423. package/dist/plugins/webhook/transformer.d.ts.map +0 -1
  424. package/dist/plugins/webhook/transformer.js +0 -157
  425. package/dist/plugins/webhook/transformer.js.map +0 -1
  426. package/dist/plugins/webhook/types.d.ts +0 -183
  427. package/dist/plugins/webhook/types.d.ts.map +0 -1
  428. package/dist/plugins/webhook/types.js +0 -2
  429. package/dist/plugins/webhook/types.js.map +0 -1
  430. package/dist/plugins/webhook/webhook-plugin.d.ts +0 -92
  431. package/dist/plugins/webhook/webhook-plugin.d.ts.map +0 -1
  432. package/dist/plugins/webhook/webhook-plugin.js +0 -328
  433. package/dist/plugins/webhook/webhook-plugin.js.map +0 -1
  434. package/dist/schemas/agent-template-schema.d.ts +0 -137
  435. package/dist/schemas/agent-template-schema.d.ts.map +0 -1
  436. package/dist/schemas/agent-template-schema.js +0 -87
  437. package/dist/schemas/agent-template-schema.js.map +0 -1
  438. package/dist/services/conversation-service/index.d.ts +0 -88
  439. package/dist/services/conversation-service/index.d.ts.map +0 -1
  440. package/dist/services/conversation-service/index.js +0 -441
  441. package/dist/services/conversation-service/index.js.map +0 -1
  442. package/dist/services/conversation-service/types.d.ts +0 -32
  443. package/dist/services/conversation-service/types.d.ts.map +0 -1
  444. package/dist/services/conversation-service/types.js +0 -8
  445. package/dist/services/conversation-service/types.js.map +0 -1
  446. package/dist/services/event-service.d.ts +0 -61
  447. package/dist/services/event-service.d.ts.map +0 -1
  448. package/dist/services/event-service.js +0 -110
  449. package/dist/services/event-service.js.map +0 -1
  450. package/dist/services/event-service.test.d.ts +0 -2
  451. package/dist/services/event-service.test.d.ts.map +0 -1
  452. package/dist/services/event-service.test.js +0 -86
  453. package/dist/services/event-service.test.js.map +0 -1
  454. package/dist/services/execution-service.d.ts +0 -151
  455. package/dist/services/execution-service.d.ts.map +0 -1
  456. package/dist/services/execution-service.js +0 -1262
  457. package/dist/services/execution-service.js.map +0 -1
  458. package/dist/services/execution-service.test.d.ts +0 -2
  459. package/dist/services/execution-service.test.d.ts.map +0 -1
  460. package/dist/services/execution-service.test.js +0 -338
  461. package/dist/services/execution-service.test.js.map +0 -1
  462. package/dist/services/history-module.d.ts +0 -15
  463. package/dist/services/history-module.d.ts.map +0 -1
  464. package/dist/services/history-module.js +0 -42
  465. package/dist/services/history-module.js.map +0 -1
  466. package/dist/services/in-memory-history-store.d.ts +0 -12
  467. package/dist/services/in-memory-history-store.d.ts.map +0 -1
  468. package/dist/services/in-memory-history-store.js +0 -41
  469. package/dist/services/in-memory-history-store.js.map +0 -1
  470. package/dist/services/index.d.ts +0 -7
  471. package/dist/services/index.d.ts.map +0 -1
  472. package/dist/services/index.js +0 -13
  473. package/dist/services/index.js.map +0 -1
  474. package/dist/services/task-events.d.ts +0 -6
  475. package/dist/services/task-events.d.ts.map +0 -1
  476. package/dist/services/task-events.js +0 -6
  477. package/dist/services/task-events.js.map +0 -1
  478. package/dist/services/tool-execution-service.d.ts +0 -74
  479. package/dist/services/tool-execution-service.d.ts.map +0 -1
  480. package/dist/services/tool-execution-service.js +0 -189
  481. package/dist/services/tool-execution-service.js.map +0 -1
  482. package/dist/services/user-events.d.ts +0 -7
  483. package/dist/services/user-events.d.ts.map +0 -1
  484. package/dist/services/user-events.js +0 -6
  485. package/dist/services/user-events.js.map +0 -1
  486. package/dist/tools/implementations/function-tool/index.d.ts +0 -9
  487. package/dist/tools/implementations/function-tool/index.d.ts.map +0 -1
  488. package/dist/tools/implementations/function-tool/index.js +0 -13
  489. package/dist/tools/implementations/function-tool/index.js.map +0 -1
  490. package/dist/tools/implementations/function-tool/schema-converter.d.ts +0 -32
  491. package/dist/tools/implementations/function-tool/schema-converter.d.ts.map +0 -1
  492. package/dist/tools/implementations/function-tool/schema-converter.js +0 -164
  493. package/dist/tools/implementations/function-tool/schema-converter.js.map +0 -1
  494. package/dist/tools/implementations/function-tool/types.d.ts +0 -72
  495. package/dist/tools/implementations/function-tool/types.d.ts.map +0 -1
  496. package/dist/tools/implementations/function-tool/types.js +0 -14
  497. package/dist/tools/implementations/function-tool/types.js.map +0 -1
  498. package/dist/tools/implementations/function-tool.d.ts +0 -49
  499. package/dist/tools/implementations/function-tool.d.ts.map +0 -1
  500. package/dist/tools/implementations/function-tool.js +0 -223
  501. package/dist/tools/implementations/function-tool.js.map +0 -1
  502. package/dist/tools/implementations/index.d.ts +0 -4
  503. package/dist/tools/implementations/index.d.ts.map +0 -1
  504. package/dist/tools/implementations/index.js +0 -5
  505. package/dist/tools/implementations/index.js.map +0 -1
  506. package/dist/tools/implementations/mcp-tool.d.ts +0 -72
  507. package/dist/tools/implementations/mcp-tool.d.ts.map +0 -1
  508. package/dist/tools/implementations/mcp-tool.js +0 -246
  509. package/dist/tools/implementations/mcp-tool.js.map +0 -1
  510. package/dist/tools/implementations/openapi-tool.d.ts +0 -56
  511. package/dist/tools/implementations/openapi-tool.d.ts.map +0 -1
  512. package/dist/tools/implementations/openapi-tool.js +0 -324
  513. package/dist/tools/implementations/openapi-tool.js.map +0 -1
  514. package/dist/tools/implementations/relay-mcp-tool.d.ts +0 -38
  515. package/dist/tools/implementations/relay-mcp-tool.d.ts.map +0 -1
  516. package/dist/tools/implementations/relay-mcp-tool.js +0 -46
  517. package/dist/tools/implementations/relay-mcp-tool.js.map +0 -1
  518. package/dist/tools/index.d.ts +0 -3
  519. package/dist/tools/index.d.ts.map +0 -1
  520. package/dist/tools/index.js +0 -4
  521. package/dist/tools/index.js.map +0 -1
  522. package/dist/tools/registry/index.d.ts +0 -2
  523. package/dist/tools/registry/index.d.ts.map +0 -1
  524. package/dist/tools/registry/index.js +0 -3
  525. package/dist/tools/registry/index.js.map +0 -1
  526. package/dist/tools/registry/tool-registry.d.ts +0 -54
  527. package/dist/tools/registry/tool-registry.d.ts.map +0 -1
  528. package/dist/tools/registry/tool-registry.js +0 -146
  529. package/dist/tools/registry/tool-registry.js.map +0 -1
  530. package/dist/utils/errors.d.ts +0 -155
  531. package/dist/utils/errors.d.ts.map +0 -1
  532. package/dist/utils/errors.js +0 -203
  533. package/dist/utils/errors.js.map +0 -1
  534. package/dist/utils/execution-proxy.d.ts +0 -75
  535. package/dist/utils/execution-proxy.d.ts.map +0 -1
  536. package/dist/utils/execution-proxy.js +0 -230
  537. package/dist/utils/execution-proxy.js.map +0 -1
  538. package/dist/utils/index.d.ts +0 -11
  539. package/dist/utils/index.d.ts.map +0 -1
  540. package/dist/utils/index.js +0 -7
  541. package/dist/utils/index.js.map +0 -1
  542. package/dist/utils/logger.d.ts +0 -74
  543. package/dist/utils/logger.d.ts.map +0 -1
  544. package/dist/utils/logger.js +0 -143
  545. package/dist/utils/logger.js.map +0 -1
  546. package/dist/utils/message-converter.d.ts +0 -68
  547. package/dist/utils/message-converter.d.ts.map +0 -1
  548. package/dist/utils/message-converter.js +0 -87
  549. package/dist/utils/message-converter.js.map +0 -1
  550. package/dist/utils/periodic-task.d.ts +0 -14
  551. package/dist/utils/periodic-task.d.ts.map +0 -1
  552. package/dist/utils/periodic-task.js +0 -26
  553. package/dist/utils/periodic-task.js.map +0 -1
  554. package/dist/utils/validation.d.ts +0 -40
  555. package/dist/utils/validation.d.ts.map +0 -1
  556. package/dist/utils/validation.js +0 -162
  557. package/dist/utils/validation.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # @robota-sdk/agent-core
2
2
 
3
- The foundation layer of the Robota SDK. Provides the `Robota` agent class, abstract base classes for providers/tools/plugins, the permission system, hook system, event services, and error hierarchy.
3
+ The foundation of the Robota SDK. It provides the `ConversationAgent` class (a conversation loop with
4
+ tool calling), the provider, tool and plugin contracts with their abstract base classes, the
5
+ permission evaluator, the hook runner, event services, typed errors, model metadata, and structured
6
+ output. It has no `@robota-sdk/*` dependencies; every other agent runtime package builds on it.
4
7
 
5
8
  ## Installation
6
9
 
@@ -8,101 +11,309 @@ The foundation layer of the Robota SDK. Provides the `Robota` agent class, abstr
8
11
  npm install @robota-sdk/agent-core
9
12
  ```
10
13
 
14
+ Requires Node.js 22.12 or later. A provider package supplies the model connection, for example
15
+ `@robota-sdk/agent-provider-anthropic`.
16
+
11
17
  ## Quick Start
12
18
 
13
19
  ```typescript
14
- import { Robota } from '@robota-sdk/agent-core';
20
+ import { ConversationAgent } from '@robota-sdk/agent-core';
15
21
  import { AnthropicProvider } from '@robota-sdk/agent-provider-anthropic';
16
22
 
17
23
  const provider = new AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY });
18
24
 
19
- const agent = new Robota({
25
+ const agent = new ConversationAgent({
20
26
  name: 'MyAgent',
21
27
  aiProviders: [provider],
22
28
  defaultModel: {
23
29
  provider: 'anthropic',
24
30
  model: 'claude-sonnet-4-6',
25
- systemMessage: 'You are a helpful assistant.',
26
31
  },
32
+ systemMessage: 'You are a helpful assistant.',
27
33
  });
28
34
 
29
35
  const response = await agent.run('Hello, world!');
30
36
  console.log(response);
31
37
  ```
32
38
 
33
- ## Key Features
39
+ `defaultModel.provider` names one of the `aiProviders` by its `name` (`'anthropic'` here).
40
+
41
+ ## What it provides
34
42
 
35
- - **Robota class**: AI agent with conversation history, tool execution, and plugin support
36
- - **Multi-provider**: Register multiple providers, switch dynamically with `setModel()`
37
- - **Permission system**: Deterministic 3-step policy evaluation (`evaluatePermission`)
38
- - **Hook system**: Shell command-based lifecycle hooks (`runHooks`)
39
- - **Plugin system**: `AbstractPlugin` base class with lifecycle hooks (beforeRun, afterRun, onError, etc.)
40
- - **Event services**: Unified event emission with owner path tracking
41
- - **Error hierarchy**: Typed errors extending `RobotaError` (ProviderError, RateLimitError, etc.)
42
- - **Type safety**: Strict TypeScript, zero `any` in production code
43
+ - **`ConversationAgent`** — an agent with conversation history, automatic tool execution, plugins, streaming
44
+ (`runStream`) and structured output. By default history accumulates across runs; set
45
+ `retainHistory: false` to start every run from the system prompt.
46
+ - **Messages** — every message (`TUniversalMessage`) has a unique `id` and a `state`
47
+ (`'complete'` or `'interrupted'`). `ConversationStore` is the append-only history with a streaming
48
+ buffer.
49
+ - **Multiple providers** — register several providers and switch with `setModel()`. Providers extend
50
+ `AbstractAIProvider` and report capabilities (`getProviderCapabilities`), including whether they
51
+ offer hosted web search/fetch.
52
+ - **Tools** — `FunctionTool` and `ToolRegistry` live here, next to the `AbstractTool` base class and
53
+ the tool schema contract. Ready-made tools are in `@robota-sdk/agent-tools`.
54
+ - **Permissions** — `evaluatePermission` decides a tool call from the permission mode and
55
+ allow/deny/ask rules; it is the one evaluator every agent runtime caller uses.
56
+ - **Hooks** — `runHooks` runs the lifecycle hooks configured for an event. See the
57
+ [hook event catalog](./docs/HOOK-CATALOG.md).
58
+ - **Plugins** — `AbstractPlugin` with lifecycle hooks (`beforeRun`, `afterRun`, `onError`, …).
59
+ Ready-made plugins are in `@robota-sdk/agent-plugin`.
60
+ - **Events** — event services with owner-path tracking and `EventEmitterPlugin`.
61
+ - **Errors** — typed errors extending `AgentRuntimeError`, such as `ProviderError`, `RateLimitError`,
62
+ `ToolExecutionError` and `StructuredOutputError`.
63
+ - **Model metadata** — providers register their own models with `registerModelMetadata()`; core
64
+ owns the registry and the lookups (`getModelContextWindow()`, `getModelMaxOutput()`, …), not any
65
+ vendor's catalogue.
66
+ - **Cancellation** — an `AbortSignal` passed in run options reaches the provider call.
43
67
 
44
- ## Robota API
68
+ ## agent runtime API
45
69
 
46
70
  ```typescript
47
- const agent = new Robota(config);
71
+ import { ConversationAgent } from '@robota-sdk/agent-core';
72
+ import type { IAgentConfig } from '@robota-sdk/agent-core';
48
73
 
49
- // Send a message (executes tool calls automatically)
74
+ declare const config: IAgentConfig;
75
+ const agent = new ConversationAgent(config);
76
+
77
+ // Send a message (tool calls are executed automatically)
50
78
  const response = await agent.run('Hello');
51
79
 
52
80
  // Conversation history
53
81
  const history = agent.getHistory(); // TUniversalMessage[]
54
82
  agent.clearHistory();
55
83
 
56
- // Switch provider/model mid-conversation
84
+ // Switch provider/model mid-conversation (the provider must be registered in aiProviders)
57
85
  agent.setModel({ provider: 'openai', model: 'gpt-4o' });
86
+
87
+ // Release the agent's resources when you are done
88
+ await agent.destroy();
58
89
  ```
59
90
 
91
+ ### Structured output
92
+
93
+ `run(input, { output })` returns a schema-validated object instead of a string. A Zod schema gives a
94
+ typed result. The schema is sent to the provider's native structured-output support where one
95
+ exists, and the response is always validated by core with a bounded retry on violation
96
+ (`outputRetries`, default 2). When the retries are used up, `run` throws `StructuredOutputError`.
97
+
98
+ ```typescript
99
+ import { z } from 'zod';
100
+ import { ConversationAgent } from '@robota-sdk/agent-core';
101
+ import type { IAgentConfig } from '@robota-sdk/agent-core';
102
+
103
+ declare const config: IAgentConfig;
104
+ const agent = new ConversationAgent(config);
105
+
106
+ const reportSchema = z.object({
107
+ title: z.string(),
108
+ score: z.number(),
109
+ summary: z.string(),
110
+ });
111
+
112
+ // Typed result: { title: string; score: number; summary: string }
113
+ const report = await agent.run('Summarize the meeting as a report.', {
114
+ output: reportSchema,
115
+ });
116
+
117
+ // Streaming variant: text deltas stream as usual; the validated object is the
118
+ // generator's return value (the final { done: true, value } iterator result).
119
+ const stream = agent.runStream('Summarize again.', { output: reportSchema });
120
+ const iterator = stream[Symbol.asyncIterator]();
121
+ let next = await iterator.next();
122
+ while (!next.done) {
123
+ process.stdout.write(next.value);
124
+ next = await iterator.next();
125
+ }
126
+ const streamedReport = next.value;
127
+ console.log(report.title, streamedReport.title);
128
+ ```
129
+
130
+ A raw JSON-schema wrapper is also accepted:
131
+ `{ output: { jsonSchema: { type: 'object', properties: { answer: { type: 'string' } }, required: ['answer'] } } }`.
132
+
133
+ ### Model options per run
134
+
135
+ `run` and `runStream` accept run-scoped model options that win over `defaultModel.*`: `maxTokens`,
136
+ `temperature` and `toolChoice`. `toolChoice` controls tool calls: `'auto'` (the model decides),
137
+ `'none'` (no tool calls), `'required'` (must call some tool), or `{ tool: name }` (must call that
138
+ tool). Naming a tool that is not in the run's tool list throws immediately. A forcing directive
139
+ applies to the run's first model call only; later rounds revert to `'auto'` so the model can use the
140
+ tool results and finish.
141
+
142
+ ```typescript
143
+ import { ConversationAgent } from '@robota-sdk/agent-core';
144
+ import type { IAgentConfig } from '@robota-sdk/agent-core';
145
+
146
+ declare const config: IAgentConfig;
147
+ const agent = new ConversationAgent(config);
148
+
149
+ // Force the model to answer through a router tool (decision-agent pattern)
150
+ const decision = await agent.run('Route this request.', {
151
+ toolChoice: { tool: 'route-request' },
152
+ allowToolOnlyCompletion: true,
153
+ });
154
+
155
+ // Suppress tools for a plain-text turn, capped at 100 output tokens
156
+ const summary = await agent.run('Summarize the discussion.', {
157
+ toolChoice: 'none',
158
+ maxTokens: 100,
159
+ });
160
+ console.log(decision, summary);
161
+ ```
162
+
163
+ The same directive can be set for every run with `defaultModel.toolChoice`.
164
+
165
+ ### Model effort
166
+
167
+ `defaultModel.effort` and the per-call `IChatOptions.effort` accept `auto`, `none`, `minimal`,
168
+ `low`, `medium`, `high`, `xhigh` or `max`. `auto` is passed through to the provider adapter, which
169
+ applies the model's documented default. The adapter reports what it actually sent through
170
+ `onModelEffortOutcome`; core does not guess vendor field names or defaults.
171
+
172
+ ### Execution events and usage
173
+
174
+ `run()` accepts an `onExecutionEvent` callback in its options. The execution loop reports
175
+ provider-neutral events that a higher layer can persist as an append-only record of the run,
176
+ including `provider_request`, `provider_native_raw_payload`, `provider_stream_raw_delta`,
177
+ `provider_response_raw`, `provider_response_normalized`, `assistant_message_committed`,
178
+ `tool_batch_started`, `tool_execution_request`, `tool_execution_result`, `tool_message_committed`
179
+ and `history_mutation`. `@robota-sdk/agent-session` writes these events to its session log.
180
+
181
+ Capturing a vendor SDK's exact payloads stays in the provider package: a provider calls
182
+ `IChatOptions.onProviderNativeRawPayload`, and `ConversationAgent` forwards it as a
183
+ `provider_native_raw_payload` event without importing vendor SDK types.
184
+
185
+ Each provider call gets a `usageObservationId`. Streaming fragments of one call share it, and a
186
+ separately billed call gets a new one, so stored analytics can deduplicate usage by identity.
187
+
188
+ `sumMessagesUsage(messages)` sums the usage providers reported on assistant messages. The usage of
189
+ one run, tool rounds included, is the sum over the messages that run appended:
190
+
191
+ ```typescript
192
+ import { ConversationAgent, sumMessagesUsage } from '@robota-sdk/agent-core';
193
+ import type { IAgentConfig } from '@robota-sdk/agent-core';
194
+
195
+ declare const config: IAgentConfig;
196
+ const agent = new ConversationAgent(config);
197
+
198
+ const before = agent.getHistory().length;
199
+ await agent.run('Summarize the open issues.');
200
+ const usage = sumMessagesUsage(agent.getHistory().slice(before));
201
+ ```
202
+
203
+ `cacheReadTokens`, the part of `promptTokens` the provider served from its prompt cache, is present
204
+ only when a provider reports it (the OpenAI and OpenAI-compatible providers do).
205
+
60
206
  ## IAgentConfig
61
207
 
62
- | Field | Type | Description |
63
- | ---------------------------- | -------------------------- | ------------------------------ |
64
- | `name` | `string` | Agent name |
65
- | `aiProviders` | `IAIProvider[]` | One or more provider instances |
66
- | `defaultModel.provider` | `string` | Provider name |
67
- | `defaultModel.model` | `string` | Model identifier |
68
- | `defaultModel.systemMessage` | `string?` | System prompt |
69
- | `tools` | `IToolWithEventService[]?` | Tools the agent can call |
70
- | `plugins` | `IPluginContract[]?` | Plugins for lifecycle hooks |
208
+ The main fields:
71
209
 
72
- ## Architecture
210
+ | Field | Type | Description |
211
+ | ----------------------- | -------------------------- | ---------------------------------------------------------- |
212
+ | `name` | `string` | Agent name |
213
+ | `aiProviders` | `IAIProvider[]` | One or more provider instances |
214
+ | `defaultModel.provider` | `string` | Name of the provider to use |
215
+ | `defaultModel.model` | `string` | Model identifier |
216
+ | `systemMessage` | `string?` | System prompt |
217
+ | `tools` | `IToolWithEventService[]?` | Tools the agent can call |
218
+ | `plugins` | `IPluginContract[]?` | Plugins that receive lifecycle hooks |
219
+ | `retainHistory` | `boolean?` | Keep history across runs (default `true`) |
220
+ | `maxExecutionRounds` | `number?` | Cap on model-call rounds per run (`0` means no cap) |
221
+ | `isToolVisible` | `(name) => boolean` | Hide a registered tool from the model, checked every round |
222
+
223
+ `toolExecutionPolicy(calls)` is a trusted host callback evaluated for each model tool round.
224
+ It receives a copy of that round's calls and returns a policy keyed by call ID. `dependsOn`
225
+ requires successful predecessor results before dispatch; failed predecessors produce skipped
226
+ receipts. Resource claims use a host-chosen asset identity shared across plugins: readers may
227
+ share a resource, while a writer excludes readers and other writers. Omitted claims mean unknown
228
+ shared state and serialize conservatively; `resources: []` explicitly permits independent work.
229
+ `maxConcurrency` bounds active calls, and `continueOnError: false` skips queued calls after a
230
+ failure while retaining already started outcomes. `mode: 'sequential'` limits dispatch to one call.
231
+
232
+ Claims are copied and validated before dispatch. Unknown IDs, cycles, and invalid resource claims
233
+ refuse the batch with paired skipped results. The policy grants no permissions and does not retry
234
+ mutations. Coordination is within one batch; hosts sharing assets across sessions must provide
235
+ coordination at their effect boundary. Callers of the lower-level batch service opt into resource
236
+ scheduling by supplying `scheduling`; its existing unplanned strategies retain their behavior.
237
+
238
+ ## Entry points
239
+
240
+ | Import path | What it contains |
241
+ | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
242
+ | `@robota-sdk/agent-core` | The main API, listed under Main exports. It also has a browser build: nothing in its static import graph uses Node built-ins. |
243
+ | `@robota-sdk/agent-core/node` | Node-only pieces: the `CommandExecutor` and `HttpExecutor` hook executors, path containment (`canonicalizePath`, `isPathInside`), owner-only file writes, and the egress policy (`fetchWithEgressPolicy`). |
244
+ | `@robota-sdk/agent-core/testing` | Test fixtures: `createScriptedProvider`, `createRecordingProvider`, `createReplayProvider`. |
245
+
246
+ When you pass no executors, `runHooks` loads `CommandExecutor` and `HttpExecutor` on demand (this
247
+ needs Node). Import them from `@robota-sdk/agent-core/node` only to pass them explicitly.
248
+
249
+ ## Main exports
250
+
251
+ | Area | Exports |
252
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
253
+ | **Agent** | `ConversationAgent`, `ConversationStore`, `ConversationHistory`, `AbstractAgent`, `AgentFactory`, `AgentTemplates` |
254
+ | **Providers** | `AbstractAIProvider`, `IAIProvider`, `IChatOptions`, `IProviderCapabilities`, `getProviderCapabilities`, `assertProviderNativeWebToolsAvailable`, `IProviderDefinition`, `createProviderFromConfig` |
255
+ | **Media providers** | `IImageGenerationProvider`, `IVideoGenerationProvider`, `isImageGenerationProvider`, `isVideoGenerationProvider`, `createImageProviderFromDefinition`, `createVideoProviderFromDefinition`, `resolveMediaProviderConfig` |
256
+ | **Tools** | `FunctionTool`, `ToolRegistry`, `AbstractTool`, `IToolSchema`, `IToolResult`, `zodToJsonSchema` |
257
+ | **Execution** | `AbstractExecutor`, `LocalExecutor`, `IExecutor` |
258
+ | **Permissions** | `evaluatePermission`, `projectPermissionPolicy`, `RISK_CLASS_POLICY`, `UNCLASSIFIED_TOOL_FALLBACK`, `TRUST_TO_MODE`, `TPermissionMode`, `TTrustLevel`, `TPermissionDecision`, `TToolArgs`, `IPermissionLists` |
259
+ | **Hooks** | `runHooks`, `GuardrailExecutor`, `decodeHookVerdict`, `isEnforcing`, `THookEvent`, `THooksConfig`, `IHookGroup`, `THookDefinition`, `IHookInput`, `THookOutcome`, `IHookTypeExecutor` |
260
+ | **Plugins and events** | `AbstractPlugin`, `EventEmitterPlugin`, `IEventService`, `IOwnerPathSegment` |
261
+ | **Orchestration** | Contracts for multi-agent orchestration (`ISequentialOrchestrationSpec`, `IParallelOrchestrationSpec`, …, `ORCHESTRATION_EVENTS`); the runners are in `@robota-sdk/agent-framework` |
262
+ | **Models** | `registerModelMetadata`, `getModelContextWindow`, `getModelMaxOutput`, `getModelName`, `formatTokenCount`, `DEFAULT_CONTEXT_WINDOW`, `DEFAULT_MAX_OUTPUT`, `IModelDefinition` |
263
+ | **Context and usage** | `estimateContextTokensFromMessages`, `estimateSerializedContextTokens`, `readTokenUsageFromMessage`, `sumMessagesUsage`, `IContextWindowState`, `IContextTokenUsage` |
264
+ | **Messages** | `TUniversalMessage`, `IBaseMessage`, `TMessageState`, `createUserMessage`, `createAssistantMessage`, `isAssistantMessage`, … |
265
+ | **Errors** | `AgentRuntimeError`, `ProviderError`, `RateLimitError`, `AuthenticationError`, `ToolExecutionError`, `StructuredOutputError`, `classifyProviderFailure`, `toProviderError` |
266
+
267
+ ## Where it sits
73
268
 
74
269
  ```
75
- agent-core (this package — zero workspace dependencies)
270
+ agent-core ← this package (no workspace dependencies)
76
271
  ↑
77
- agent-sessions ← Session lifecycle
78
- agent-tools ← Tool implementations
79
- agent-providers ← AI provider implementations
80
- agent-plugins ← Plugin implementations (8 extracted packages)
272
+ agent-tools, agent-session, agent-plugin, agent-mcp, agent-provider-* (one package per vendor)
81
273
  ↑
82
- agent-sdk ← Assembly layer
274
+ agent-framework ← assembles sessions, commands, permissions and hooks
83
275
  ↑
84
- agent-cli ← Terminal UI
276
+ agent-cli ← the reference host
85
277
  ```
86
278
 
87
- ## What This Package Provides
279
+ - Built-in tools (Shell, Read, Edit, …): `@robota-sdk/agent-tools`
280
+ - Ready-made plugins (logging, usage, limits, …): `@robota-sdk/agent-plugin`
281
+ - MCP servers and tools: `@robota-sdk/agent-mcp`
282
+ - Sessions with permissions, hooks and compaction: `@robota-sdk/agent-session`
283
+
284
+ ## Repository examples
285
+
286
+ From `packages/agent-core` in a built checkout of the repository, these scripts exercise hooks
287
+ without a live model: `node examples/hook-block-demo.mjs`, `node examples/hook-json-response-demo.mjs`,
288
+ `node examples/hook-permission-mode-demo.mjs` and `node examples/hook-timeout-demo.mjs`.
289
+
290
+ The default outbound HTTP transport uses the installed Undici entry so Bun's built-in replacement
291
+ cannot discard its connection pinning. After `pnpm --filter @robota-sdk/agent-core build`, run the
292
+ same disposable HTTP fixture from the repository root in each runtime:
293
+
294
+ ```sh
295
+ node packages/agent-core/src/utils/fixtures/egress-runtime-smoke.mjs
296
+ bun packages/agent-core/src/utils/fixtures/egress-runtime-smoke.mjs
297
+ egress_fixture_dir=$(mktemp -d)
298
+ bun build --compile --minify packages/agent-core/src/utils/fixtures/egress-runtime-smoke.mjs --outfile "$egress_fixture_dir/egress-smoke"
299
+ "$egress_fixture_dir/egress-smoke"
300
+ rm -rf "$egress_fixture_dir"
301
+ ```
88
302
 
89
- | Category | Exports |
90
- | --------------- | ---------------------------------------------------------------------------------------------------------------------- |
91
- | **Core** | `Robota`, `AbstractAgent`, `AbstractAIProvider`, `AbstractPlugin`, `AbstractTool`, `AbstractExecutor`, `LocalExecutor` |
92
- | **Permissions** | `evaluatePermission`, `MODE_POLICY`, `TRUST_TO_MODE`, `TPermissionMode`, `TToolArgs` |
93
- | **Hooks** | `runHooks`, `THookEvent` (PreToolUse, PostToolUse, PreCompact, PostCompact, SessionStart, Stop) |
94
- | **Events** | `AbstractEventService`, `DefaultEventService`, `StructuredEventService`, `EventEmitterPlugin` |
95
- | **Types** | `TUniversalMessage`, `IAgentConfig`, `IAIProvider`, `IToolSchema`, `IContextWindowState` |
96
- | **Errors** | `RobotaError`, `ProviderError`, `RateLimitError`, `AuthenticationError`, `ToolExecutionError`, etc. |
303
+ The fixture explicitly permits its local server and connects an otherwise unresolvable hostname
304
+ to an injected address. It checks the built helper and Bun compilation, not a full CLI session,
305
+ provider isolation or physical worker egress. The socket and TLS test suites cover destination
306
+ refusal, redirects, cleanup and certificate identity separately. A trusted injected `fetch` owns
307
+ its own connection policy; it does not inherit the default transport's pinning guarantee.
97
308
 
98
- ## What Moved Out in v3
309
+ ## Documentation
99
310
 
100
- | What | Moved to |
101
- | --------------------------------------------- | ---------------------------- |
102
- | `FunctionTool`, `ToolRegistry`, `OpenAPITool` | `@robota-sdk/agent-tools` |
103
- | `MCPTool`, `RelayMcpTool` | `@robota-sdk/agent-tool-mcp` |
104
- | 8 plugins (logging, usage, performance, etc.) | `@robota-sdk/agent-plugin-*` |
311
+ - [docs/SPEC.md](./docs/SPEC.md) — package contract and design decisions
312
+ - [docs/HOOK-CATALOG.md](./docs/HOOK-CATALOG.md) — hook events, input fields and blocking semantics
313
+ - [Building agents](../../content/guide/building-agents.md) — a walkthrough of `ConversationAgent`, tools and
314
+ structured output
315
+ - [Permissions and hooks](../../content/guide/permissions-and-hooks.md)
105
316
 
106
317
  ## License
107
318
 
108
- MIT
319
+ This package is dual-licensed under the [GNU AGPL-3.0](../../LICENSE) or a [commercial license](../../COMMERCIAL.md). See [LICENSING.md](../../LICENSING.md).
@@ -0,0 +1,2 @@
1
+ var e=class extends Error{context;constructor(e,t){super(e),this.context=t,this.name=this.constructor.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{code=`CONFIGURATION_ERROR`;category=`user`;recoverable=!1;constructor(e,t){super(`Configuration Error: ${e}`,t)}},n=class extends e{field;code=`VALIDATION_ERROR`;category=`user`;recoverable=!1;constructor(e,t,n){super(`Validation Error: ${e}`,n),this.field=t}},r=class extends e{issues;attempts;code=`STRUCTURED_OUTPUT_ERROR`;category=`provider`;recoverable=!0;constructor(e,t,n,r){super(`Structured Output Error: ${e}`,r),this.issues=t,this.attempts=n}},i=class extends e{provider;originalError;code=`PROVIDER_ERROR`;category=`provider`;recoverable=!0;status;type;constructor(e,t,n,r,i){super(`Provider Error (${t}): ${e}`,r),this.provider=t,this.originalError=n,i?.status!==void 0&&(this.status=i.status),i?.type!==void 0&&(this.type=i.type)}},a=class extends e{provider;code=`AUTHENTICATION_ERROR`;category=`user`;recoverable=!1;constructor(e,t,n){super(`Authentication Error: ${e}`,n),this.provider=t}},o=class extends e{retryAfter;provider;code=`RATE_LIMIT_ERROR`;category=`provider`;recoverable=!0;constructor(e,t,n,r){super(`Rate Limit Error: ${e}`,r),this.retryAfter=t,this.provider=n}},s=class extends e{originalError;provider;code=`NETWORK_ERROR`;category=`system`;recoverable=!0;constructor(e,t,n,r){super(`Network Error: ${e}`,n),this.originalError=t,this.provider=r}},c=class extends e{toolName;originalError;code=`TOOL_EXECUTION_ERROR`;category=`system`;recoverable=!1;constructor(e,t,n,r){super(`Tool Execution Error (${t}): ${e}`,r),this.toolName=t,this.originalError=n}},l=class extends e{toolName;callCount;maxSameToolInputs;code=`SAME_TOOL_INPUT_LOOP`;category=`system`;recoverable=!0;constructor(e,t,n,r){super(`Tool "${e}" was called with identical input ${t} times, past the maxSameToolInputs limit of ${n} — stopping the turn to break the loop`,r),this.toolName=e,this.callCount=t,this.maxSameToolInputs=n}},u=class extends e{round;code=`EMPTY_COMPLETION`;category=`provider`;recoverable=!0;constructor(e,t){super(`Round ${e} ended with no tool call and no text response, and allowToolOnlyCompletion prevented the follow-up call that would otherwise recover it`,t),this.round=e}},d=class extends e{model;provider;availableModels;code=`MODEL_NOT_AVAILABLE`;category=`user`;recoverable=!1;constructor(e,t,n,r){let i=e===void 0?`No model available for provider "${t}"`:`Model "${e}" is not available for provider "${t}"`,a=r?.originalMessage;super(typeof a==`string`&&a.length>0?`${i}: ${a}`:i,r),this.model=e,this.provider=t,this.availableModels=n}},f=class extends e{code=`CIRCUIT_BREAKER_OPEN`;category=`system`;recoverable=!0;constructor(e=`Circuit breaker is open`,t){super(e,t)}},p=class extends e{pluginName;code=`PLUGIN_ERROR`;category=`system`;recoverable=!1;constructor(e,t,n){super(`Plugin Error (${t}): ${e}`,n),this.pluginName=t}},m=class extends e{code=`STORAGE_ERROR`;category=`system`;recoverable=!0;constructor(e,t){super(`Storage Error: ${e}`,t)}},h=class extends e{code=`CACHE_INTEGRITY_ERROR`;category=`system`;recoverable=!1;constructor(e,t){super(`Cache Integrity Error: ${e}`,t)}},g=class extends e{executable;code=`UNSUPPORTED_SHELL`;category=`user`;recoverable=!1;constructor(e){super(`Unsupported shell executable: ${e}`,{executable:e}),this.executable=e}};function _(e){return e===`darwin`?'Host OS: macOS (POSIX, BSD userland). Use BSD-flavored utilities: `sed -i ""` needs an empty backup arg, `date`/`grep`/`stat` flags differ from GNU. Prefer portable POSIX flags; avoid Linux/GNU-only options.':e===`linux`?"Host OS: Linux (POSIX, usually GNU coreutils, but distro/user setup varies). Prefer portable POSIX flags; do not assume a specific distro, and probe with `command -v` before relying on a non-standard tool.":`Host OS: ${e}; active shell family: POSIX sh/bash. Write portable POSIX syntax and avoid host-specific flags.`}function v(e,t){let n=x(e)===`bash`?`bash`:`sh`;return{command:e,kind:n,platform:t,commandArgs:e=>[`-c`,e],interactiveArgs:[],label:`${n} on ${t}`,syntaxHint:_(t)}}function y(e,t){return{command:e,kind:`powershell`,platform:t,commandArgs:e=>[`-NoProfile`,`-Command`,e],interactiveArgs:[`-NoProfile`],label:`PowerShell on ${t}`,syntaxHint:`Host OS: ${t}; active shell family: PowerShell. Write PowerShell syntax (not bash): e.g. \`Get-ChildItem\` not \`ls -la\`, \`\$env:VAR\` not \`\$VAR\`.`}}function b(e,t){return{command:e,kind:`cmd`,platform:t,commandArgs:e=>[`/d`,`/s`,`/c`,e],interactiveArgs:[],label:`cmd.exe on ${t}`,syntaxHint:`Host OS: ${t}; active shell family: Windows cmd.exe. Write cmd.exe syntax.`}}function x(e){return(e.split(/[\\/]/).at(-1)?.toLowerCase()??``).replace(/\.exe$/i,``)}function S(e,t){switch(x(e)){case`sh`:case`bash`:return v(e,t);case`powershell`:case`pwsh`:return y(e,t);case`cmd`:return b(e,t);default:throw new g(e)}}function C(e){let t=e?.trim();return t===void 0||t.length===0?void 0:t}function w(e={}){let t=e.env??process.env,n=e.platform??process.platform,r=C(e.executable);return r===void 0?n===`win32`?y(`powershell.exe`,n):v(C(t.SHELL)??`/bin/sh`,n):S(r,n)}const T=/^(?!0{32}$)[0-9a-f]{32}$/,E=/^(?!0{16}$)[0-9a-f]{16}$/;function D(e){return e.replaceAll(`-`,``).slice(0,16)}const O=D;function k(e){return E.test(e)}function A(e,t){if(!(!T.test(e)||!E.test(t)))return`00-${e}-${t}-01`}function j(e,t){if(e.allowedOrigins.length===0)return;let n=A(e.traceId,D(t));if(n!==void 0)return{traceparent:n,allowedOrigins:[...e.allowedOrigins]}}function M(e,t){return j(e,t)}function N(e,t,n){if(t?.subprocessClasses?.includes(e)!==!0)return;let r=A(t.traceId,n);return r===void 0?void 0:{TRACEPARENT:r}}function P(e,t,n={}){if(t===void 0||n.TRACEPARENT!==void 0)return{...e,...n};let{TRACESTATE:r,...i}=e;return{...i,...t,...n}}function F(e,t){if(e===void 0||t===void 0)return{};let n;try{n=new URL(e).origin}catch{return{}}return n===`null`||!t.allowedOrigins.includes(n)?{}:{traceparent:t.traceparent}}const I=e=>`\n…[output truncated: ${e} byte(s) dropped]`;function L(e){let t=e.retain??`head`,n=e.truncationMarker??I,r=Math.max(0,Math.floor(e.maxBytes)),i=new TextEncoder,a=[],o=0,s=0,c=e=>{let t=r-o;if(t<=0)return;let n=e.byteLength<=t?e:e.subarray(0,t);a.push(n),o+=n.byteLength},l=e=>{let t=e.byteLength<=r?e:e.subarray(e.byteLength-r);for(a.push(t),o+=t.byteLength;o>r&&a.length>0;){let e=a[0],t=o-r;e.byteLength<=t?(a.shift(),o-=e.byteLength):(a[0]=e.subarray(t),o-=t)}};return{append(e){let n=typeof e==`string`?i.encode(e):e;s+=n.byteLength,t===`head`?c(n):l(n)},get retainedBytes(){return o},get totalBytes(){return s},get droppedBytes(){return s-o},get truncated(){return s>o},toString(){let e=new Uint8Array(o),r=0;for(let t of a)e.set(t,r),r+=t.byteLength;a=a.length>1?[e]:a;let i=new TextDecoder().decode(e);if(s<=o)return i;let c=n(s-o);return t===`head`?`${i}${c}`:`${c.replace(/^\n/,``)}\n${i}`}}}export{o as C,c as D,r as E,n as O,i as S,m as T,t as _,O as a,s as b,M as c,g as d,w as f,f as g,h,j as i,N as l,a as m,A as n,D as o,e as p,k as r,P as s,L as t,F as u,u as v,l as w,p as x,d as y};
2
+ //# sourceMappingURL=bounded-output-BdWv9SX3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded-output-BdWv9SX3.js","names":[],"sources":["../../src/utils/errors.ts","../../src/utils/platform-shell.ts","../../src/utils/trace-context.ts","../../src/utils/bounded-output.ts"],"sourcesContent":["/**\n * Reusable type definitions for error utilities\n */\n\n/**\n * Error context data type\n * Used for storing contextual information in error instances\n */\nexport type TErrorContextData = Record<\n string,\n string | number | boolean | Date | Error | string[] | undefined\n>;\n\n/**\n * Error external input type\n * Used for handling external errors from unknown sources\n */\nexport type TErrorExternalInput =\n Error | string | Record<string, string | number | boolean> | null | undefined;\n\n/**\n * Base error class for all ConversationAgent errors\n */\nexport abstract class AgentRuntimeError extends Error {\n abstract readonly code: string;\n abstract readonly category: 'user' | 'system' | 'provider';\n abstract readonly recoverable: boolean;\n\n constructor(\n message: string,\n public readonly context?: TErrorContextData,\n ) {\n super(message);\n this.name = this.constructor.name;\n\n // Ensure proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Configuration related errors\n */\nexport class ConfigurationError extends AgentRuntimeError {\n readonly code = 'CONFIGURATION_ERROR';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(message: string, context?: TErrorContextData) {\n super(`Configuration Error: ${message}`, context);\n }\n}\n\n/**\n * Input validation errors\n */\nexport class ValidationError extends AgentRuntimeError {\n readonly code = 'VALIDATION_ERROR';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(\n message: string,\n public readonly field?: string,\n context?: TErrorContextData,\n ) {\n super(`Validation Error: ${message}`, context);\n }\n}\n\n/**\n * Structured output validation exhausted its retry budget (CORE-015).\n *\n * Thrown by `run(input, { output })` when the model's final response still fails\n * schema validation after the configured number of retries. `issues` holds the\n * validation messages from the last attempt; `attempts` is the total number of\n * provider turns spent (initial + retries).\n */\nexport class StructuredOutputError extends AgentRuntimeError {\n readonly code = 'STRUCTURED_OUTPUT_ERROR';\n readonly category = 'provider' as const;\n readonly recoverable = true;\n\n constructor(\n message: string,\n public readonly issues: string[],\n public readonly attempts: number,\n context?: TErrorContextData,\n ) {\n super(`Structured Output Error: ${message}`, context);\n }\n}\n\n/** What the vendor said about a failed call, as far as it said anything. */\nexport interface IProviderFailureDetails {\n /** The HTTP status of the failed response; absent for a failure with no response (e.g. an SSE error event). */\n status?: number;\n /** The vendor's own error type, e.g. Anthropic's `overloaded_error`. */\n type?: string;\n}\n\n/**\n * Provider related errors\n */\nexport class ProviderError extends AgentRuntimeError {\n readonly code = 'PROVIDER_ERROR';\n readonly category = 'provider' as const;\n readonly recoverable = true;\n readonly status?: number;\n readonly type?: string;\n\n constructor(\n message: string,\n public readonly provider: string,\n public readonly originalError?: Error,\n context?: TErrorContextData,\n details?: IProviderFailureDetails,\n ) {\n super(`Provider Error (${provider}): ${message}`, context);\n if (details?.status !== undefined) this.status = details.status;\n if (details?.type !== undefined) this.type = details.type;\n }\n}\n\n/**\n * Authentication errors\n */\nexport class AuthenticationError extends AgentRuntimeError {\n readonly code = 'AUTHENTICATION_ERROR';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(\n message: string,\n public readonly provider?: string,\n context?: TErrorContextData,\n ) {\n super(`Authentication Error: ${message}`, context);\n }\n}\n\n/**\n * Rate limit errors\n */\nexport class RateLimitError extends AgentRuntimeError {\n readonly code = 'RATE_LIMIT_ERROR';\n readonly category = 'provider' as const;\n readonly recoverable = true;\n\n constructor(\n message: string,\n public readonly retryAfter?: number,\n public readonly provider?: string,\n context?: TErrorContextData,\n ) {\n super(`Rate Limit Error: ${message}`, context);\n }\n}\n\n/**\n * Network/connectivity errors\n */\nexport class NetworkError extends AgentRuntimeError {\n readonly code = 'NETWORK_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = true;\n\n constructor(\n message: string,\n public readonly originalError?: Error,\n context?: TErrorContextData,\n /** `undefined` for a network failure with no provider context (e.g. a generic timeout). */\n public readonly provider?: string,\n ) {\n super(`Network Error: ${message}`, context);\n }\n}\n\n/**\n * Tool execution errors\n */\nexport class ToolExecutionError extends AgentRuntimeError {\n readonly code = 'TOOL_EXECUTION_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = false;\n\n constructor(\n message: string,\n public readonly toolName: string,\n public readonly originalError?: Error,\n context?: TErrorContextData,\n ) {\n super(`Tool Execution Error (${toolName}): ${message}`, context);\n }\n}\n\n/**\n * The same-tool-input loop guard tripped — CORE-035.\n *\n * A tool was invoked with byte-identical serialized inputs more times than `maxSameToolInputs`\n * allows, so the turn stopped rather than looping. This is the AGENT giving up, not the user\n * cancelling: the SPEC used to promise an `AbortError` here, which `isAbortFailure` resolves as\n * `success: true, interrupted: true` — reporting a run that produced no answer as a success.\n *\n * Named rather than a bare `Error` for the reason the SPEC was reaching for by naming a type at all:\n * a caller must be able to tell \"the agent looped\" from \"the network died\". `AgentRuntimeError` carries\n * `code`/`category`/`recoverable` out through CORE-027's failure path intact.\n *\n * `recoverable` is TRUE: the loop is a property of this turn's prompt and tool set, not of the\n * system, and a caller that varies either can reasonably try again.\n */\nexport class SameToolInputLoopError extends AgentRuntimeError {\n readonly code = 'SAME_TOOL_INPUT_LOOP';\n readonly category = 'system' as const;\n readonly recoverable = true;\n\n constructor(\n public readonly toolName: string,\n public readonly callCount: number,\n public readonly maxSameToolInputs: number,\n context?: TErrorContextData,\n ) {\n super(\n `Tool \"${toolName}\" was called with identical input ${callCount} times, past the ` +\n `maxSameToolInputs limit of ${maxSameToolInputs} — stopping the turn to break the loop`,\n context,\n );\n }\n}\n\n/**\n * A turn ended with neither a tool result nor a final text response while `allowToolOnlyCompletion`\n * was set.\n *\n * `allowToolOnlyCompletion` only WIDENS what counts as a valid finish (a tool call alone, with no\n * final text after it); it never narrows the ordinary case. Without the flag, a round that produces\n * neither is recovered by one more provider call asking for a summary (`forceSummaryCall`). Setting\n * the flag is what turns that rescue off — a decision agent wants exactly one provider call, never a\n * follow-up — so a round that produces neither has nothing left to recover it. That is a genuinely\n * unanswered turn, not the internal `[STRICT-POLICY]` result-shape violation an actually malformed\n * execution result trips; a caller must be able to catch this by type instead of parsing that message.\n *\n * `recoverable` is TRUE: like `SameToolInputLoopError`, this is a property of this turn's prompt and\n * model response, not of the system, and a caller that varies either can reasonably try again.\n */\nexport class EmptyCompletionError extends AgentRuntimeError {\n readonly code = 'EMPTY_COMPLETION';\n readonly category = 'provider' as const;\n readonly recoverable = true;\n\n constructor(\n public readonly round: number,\n context?: TErrorContextData,\n ) {\n super(\n `Round ${round} ended with no tool call and no text response, and allowToolOnlyCompletion ` +\n 'prevented the follow-up call that would otherwise recover it',\n context,\n );\n }\n}\n\n/**\n * Model not available errors\n */\nexport class ModelNotAvailableError extends AgentRuntimeError {\n readonly code = 'MODEL_NOT_AVAILABLE';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(\n /** `undefined` when the failure names no model — a provider adapter classifying a raw HTTP\n * response by status alone does not always know which model the vendor meant. */\n public readonly model: string | undefined,\n public readonly provider: string,\n public readonly availableModels?: string[],\n /**\n * `context.originalMessage`, when given, is the vendor's own text (already scrubbed of any\n * credential by the caller) — folded into `message` so a \"Details\" disclosure built from\n * `message` alone still shows the real cause instead of just this class's fixed sentence.\n */\n context?: TErrorContextData,\n ) {\n const base =\n model !== undefined\n ? `Model \"${model}\" is not available for provider \"${provider}\"`\n : `No model available for provider \"${provider}\"`;\n const detail = context?.['originalMessage'];\n super(typeof detail === 'string' && detail.length > 0 ? `${base}: ${detail}` : base, context);\n }\n}\n\n/**\n * Circuit breaker open error\n */\nexport class CircuitBreakerOpenError extends AgentRuntimeError {\n readonly code = 'CIRCUIT_BREAKER_OPEN';\n readonly category = 'system' as const;\n readonly recoverable = true;\n\n constructor(message: string = 'Circuit breaker is open', context?: TErrorContextData) {\n super(message, context);\n }\n}\n\n/**\n * Plugin errors\n */\nexport class PluginError extends AgentRuntimeError {\n readonly code = 'PLUGIN_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = false;\n\n constructor(\n message: string,\n public readonly pluginName: string,\n context?: TErrorContextData,\n ) {\n super(`Plugin Error (${pluginName}): ${message}`, context);\n }\n}\n\n/**\n * Storage related errors\n */\nexport class StorageError extends AgentRuntimeError {\n readonly code = 'STORAGE_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = true;\n\n constructor(message: string, context?: TErrorContextData) {\n super(`Storage Error: ${message}`, context);\n }\n}\n\n/**\n * Cache integrity validation errors\n */\nexport class CacheIntegrityError extends AgentRuntimeError {\n readonly code = 'CACHE_INTEGRITY_ERROR';\n readonly category = 'system' as const;\n readonly recoverable = false;\n\n constructor(message: string, context?: TErrorContextData) {\n super(`Cache Integrity Error: ${message}`, context);\n }\n}\n","/**\n * TERM-008: cross-platform shell resolution (SSOT).\n *\n * Single source of truth for \"which shell do we spawn, and how\", shared by every shell-running site.\n * Resolution is a pure function of one request so every branch is testable without the host shell.\n */\n\nimport { AgentRuntimeError } from './errors.js';\n\n/** Shell family — drives non-interactive arg shape, quoting, and LLM syntax guidance. */\nexport type TShellKind = 'bash' | 'sh' | 'powershell' | 'cmd';\n\n/** The active shell resolved for a platform, plus the metadata callers need to drive and describe it. */\nexport interface IPlatformShell {\n /** Executable to spawn (e.g. `/bin/sh`, `powershell.exe`, or `$SHELL`). */\n readonly command: string;\n /** Shell family. */\n readonly kind: TShellKind;\n /** Node platform this was resolved for (`process.platform`). */\n readonly platform: NodeJS.Platform;\n /** Args to run a single command string non-interactively. */\n commandArgs(command: string): string[];\n /** Args for an interactive shell session (drop-to-shell). */\n readonly interactiveArgs: string[];\n /** Human label for the active shell, for tool/UI descriptions (e.g. `PowerShell (Windows)`). */\n readonly label: string;\n /** One-line syntax guidance for an LLM authoring commands. */\n readonly syntaxHint: string;\n}\n\n/** Pure inputs for resolving one executable together with its command argument family. */\nexport interface IPlatformShellResolutionRequest {\n /** Request-local executable. A non-blank value has the highest precedence. */\n readonly executable?: string;\n /** Environment used for SHELL resolution. */\n readonly env?: NodeJS.ProcessEnv;\n /** Actual host platform retained in the resolved metadata. */\n readonly platform?: NodeJS.Platform;\n}\n\n/** An explicit executable whose basename has no supported command argument family. */\nexport class UnsupportedShellError extends AgentRuntimeError {\n readonly code = 'UNSUPPORTED_SHELL';\n readonly category = 'user' as const;\n readonly recoverable = false;\n\n constructor(public readonly executable: string) {\n super(`Unsupported shell executable: ${executable}`, { executable });\n }\n}\n\n/**\n * OS-family syntax guidance for the LLM. macOS and Linux are both POSIX but ship different userlands\n * (macOS = BSD coreutils, most Linux = GNU coreutils), so flags like `sed -i`, `date`, and `grep`\n * differ — naming the OS lets the model avoid Linux-only invocations on macOS and vice versa.\n */\nfunction posixSyntaxHint(platform: NodeJS.Platform): string {\n if (platform === 'darwin') {\n return 'Host OS: macOS (POSIX, BSD userland). Use BSD-flavored utilities: `sed -i \"\"` needs an empty backup arg, `date`/`grep`/`stat` flags differ from GNU. Prefer portable POSIX flags; avoid Linux/GNU-only options.';\n }\n if (platform === 'linux') {\n return 'Host OS: Linux (POSIX, usually GNU coreutils, but distro/user setup varies). Prefer portable POSIX flags; do not assume a specific distro, and probe with `command -v` before relying on a non-standard tool.';\n }\n return `Host OS: ${platform}; active shell family: POSIX sh/bash. Write portable POSIX syntax and avoid host-specific flags.`;\n}\n\nfunction posixShell(command: string, platform: NodeJS.Platform): IPlatformShell {\n const isBash = shellBasename(command) === 'bash';\n const kind: TShellKind = isBash ? 'bash' : 'sh';\n return {\n command,\n kind,\n platform,\n commandArgs: (cmd: string): string[] => ['-c', cmd],\n interactiveArgs: [],\n label: `${kind} on ${platform}`,\n syntaxHint: posixSyntaxHint(platform),\n };\n}\n\nfunction powerShell(command: string, platform: NodeJS.Platform): IPlatformShell {\n return {\n command,\n kind: 'powershell',\n platform,\n commandArgs: (cmd: string): string[] => ['-NoProfile', '-Command', cmd],\n interactiveArgs: ['-NoProfile'],\n label: `PowerShell on ${platform}`,\n syntaxHint:\n `Host OS: ${platform}; active shell family: PowerShell. Write PowerShell syntax (not bash): e.g. ` +\n '`Get-ChildItem` not `ls -la`, `$env:VAR` not `$VAR`.',\n };\n}\n\nfunction cmdShell(command: string, platform: NodeJS.Platform): IPlatformShell {\n return {\n command,\n kind: 'cmd',\n platform,\n commandArgs: (cmd: string): string[] => ['/d', '/s', '/c', cmd],\n interactiveArgs: [],\n label: `cmd.exe on ${platform}`,\n syntaxHint: `Host OS: ${platform}; active shell family: Windows cmd.exe. Write cmd.exe syntax.`,\n };\n}\n\nfunction shellBasename(command: string): string {\n const basename = command.split(/[\\\\/]/).at(-1)?.toLowerCase() ?? '';\n return basename.replace(/\\.exe$/i, '');\n}\n\nfunction explicitShell(command: string, platform: NodeJS.Platform): IPlatformShell {\n switch (shellBasename(command)) {\n case 'sh':\n case 'bash':\n return posixShell(command, platform);\n case 'powershell':\n case 'pwsh':\n return powerShell(command, platform);\n case 'cmd':\n return cmdShell(command, platform);\n default:\n throw new UnsupportedShellError(command);\n }\n}\n\nfunction nonBlank(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed === undefined || trimmed.length === 0 ? undefined : trimmed;\n}\n\n/**\n * Resolve the shell to spawn for the current (or a given) platform.\n *\n * - request `executable` wins when non-blank.\n * - **win32:** PowerShell.\n * - **posix:** `$SHELL` if set, else `/bin/sh`.\n */\nexport function resolvePlatformShell(\n request: IPlatformShellResolutionRequest = {},\n): IPlatformShell {\n const env = request.env ?? process.env;\n const platform = request.platform ?? process.platform;\n const requestedExecutable = nonBlank(request.executable);\n if (requestedExecutable !== undefined) return explicitShell(requestedExecutable, platform);\n\n if (platform === 'win32') return powerShell('powershell.exe', platform);\n\n return posixShell(nonBlank(env['SHELL']) ?? '/bin/sh', platform);\n}\n","/**\n * Pure helpers for trusted W3C trace context. Strings and the WHATWG `URL` only, so they are the\n * same in the browser build and in every adapter that attaches the header.\n */\nimport type {\n IOutboundTraceContext,\n IRunTraceContext,\n ISubprocessTraceEnv,\n TSubprocessTraceClass,\n} from '../interfaces/trace-context';\n\nconst TRACE_ID = /^(?!0{32}$)[0-9a-f]{32}$/;\nconst SPAN_ID = /^(?!0{16}$)[0-9a-f]{16}$/;\n\n/**\n * The span ID an operation is exported under, derived from the ID core mints before it runs (a\n * provider call's call ID, a tool body's body ID). One derivation for both the exporter and the\n * outgoing header, so the span a recipient sees as its parent is the span the trace contains.\n */\nexport function spanIdFromMintedId(mintedId: string): string {\n return mintedId.replaceAll('-', '').slice(0, 16);\n}\n\n/** The provider-call name for {@link spanIdFromMintedId}, kept so existing callers keep working. */\nexport const providerCallSpanId: (callId: string) => string = spanIdFromMintedId;\n\n/** Whether `spanId` is a well-formed minted span ID: 16 lowercase hex characters, not all zero. */\nexport function isMintedSpanId(spanId: string): boolean {\n return SPAN_ID.test(spanId);\n}\n\n/** A sampled version-00 `traceparent`, or undefined when either identifier is invalid. */\nexport function buildTraceparent(traceId: string, spanId: string): string | undefined {\n if (!TRACE_ID.test(traceId) || !SPAN_ID.test(spanId)) return undefined;\n return `00-${traceId}-${spanId}-01`;\n}\n\n/** The outbound context for one invoked call, or undefined when there is nothing valid to send. */\nexport function outboundTraceContextFor(\n traceContext: IRunTraceContext,\n callId: string,\n): IOutboundTraceContext | undefined {\n if (traceContext.allowedOrigins.length === 0) return undefined;\n const traceparent = buildTraceparent(traceContext.traceId, spanIdFromMintedId(callId));\n if (traceparent === undefined) return undefined;\n return { traceparent, allowedOrigins: [...traceContext.allowedOrigins] };\n}\n\n/**\n * The outbound context for one tool body, keyed by the body ID core minted for it — never the\n * vendor's tool call ID, which is neither unique nor hex.\n */\nexport function toolTraceContextFor(\n traceContext: IRunTraceContext,\n toolBodyId: string,\n): IOutboundTraceContext | undefined {\n return outboundTraceContextFor(traceContext, toolBodyId);\n}\n\n/**\n * The environment one child process of `subprocessClass` receives, naming `spanId` as its parent,\n * or undefined when the host did not enable that class. Independent of the origin allowlist.\n */\nexport function traceEnvFor(\n subprocessClass: TSubprocessTraceClass,\n traceContext: IRunTraceContext | undefined,\n spanId: string,\n): ISubprocessTraceEnv | undefined {\n if (traceContext?.subprocessClasses?.includes(subprocessClass) !== true) return undefined;\n const traceparent = buildTraceparent(traceContext.traceId, spanId);\n return traceparent === undefined ? undefined : { TRACEPARENT: traceparent };\n}\n\n/**\n * A fresh child environment: `base`, then ConversationAgent's trace, then `overrides`. When ConversationAgent's value\n * applies, the ambient `TRACESTATE` is dropped because it belongs to a different parent. When\n * `overrides` sets its own `TRACEPARENT`, ConversationAgent's value does not apply and `base` passes unchanged.\n * `base` itself is never modified.\n */\nexport function subprocessTraceEnvironment(\n base: Readonly<Record<string, string | undefined>>,\n traceEnv: ISubprocessTraceEnv | undefined,\n overrides: Readonly<Record<string, string>> = {},\n): Record<string, string | undefined> {\n if (traceEnv === undefined || overrides['TRACEPARENT'] !== undefined) return { ...base, ...overrides };\n const { TRACESTATE: _ambientState, ...rest } = base;\n return { ...rest, ...traceEnv, ...overrides };\n}\n\n/**\n * The headers to add to a request whose effective base URL is `baseUrl`: `traceparent` when its\n * origin exactly equals a listed origin, nothing otherwise. Scheme, host and port must all match;\n * a subdomain or a different port is a different origin.\n */\nexport function traceHeadersFor(\n baseUrl: string | undefined,\n traceContext: IOutboundTraceContext | undefined,\n): Readonly<Record<string, string>> {\n if (baseUrl === undefined || traceContext === undefined) return {};\n let origin: string;\n try {\n origin = new URL(baseUrl).origin;\n } catch {\n return {};\n }\n if (origin === 'null' || !traceContext.allowedOrigins.includes(origin)) return {};\n return { traceparent: traceContext.traceparent };\n}\n","/**\n * ARCH-056 (#2161): the bounded output-retention contract for child-process execution.\n *\n * Every path that reads a child's stdout/stderr must bound memory WHILE the output is being read —\n * not cap a summary afterwards while retaining the whole log. Before this existed, `shell-tool`\n * could buffer for ten minutes, the hook `CommandExecutor` repeated the pattern, and a subagent\n * runner had rediscovered a 4 KiB tail on its own. This module names the policy once:\n *\n * - **Budget.** `maxBytes` is the most that is ever RETAINED; bytes beyond it are dropped as they\n * arrive, so memory is bounded by the budget, not by the child's lifetime.\n * - **Retention.** `head` keeps the first `maxBytes` (a tool result: what the command said first);\n * `tail` keeps the last `maxBytes` (a diagnostic: how it ended).\n * - **Truncation is visible.** `truncated`, `droppedBytes` and a marker in `toString()` say that\n * output was dropped and how much — never a silently shorter string.\n * - **No spill.** This contract never writes to disk; a caller that needs the whole stream owns a\n * log file (background tasks do), and this buffer is what stays in memory beside it.\n * - **Termination is not here.** Exceeding the budget drops bytes; whether the child is killed is\n * the caller's policy (CORE-023 owns process-tree termination).\n *\n * Chunks are `Uint8Array` (a Node `Buffer` is one), and decoding happens once at `toString()`, so a\n * multi-byte character split across a chunk boundary is never decoded twice.\n */\n\nexport type TOutputRetention = 'head' | 'tail';\n\nexport interface IBoundedOutputOptions {\n /** Most bytes ever retained. */\n readonly maxBytes: number;\n /** Which end to keep once over budget. Default `head`. */\n readonly retain?: TOutputRetention;\n /** Marker appended (head) or prepended (tail) to `toString()` when bytes were dropped. */\n readonly truncationMarker?: (droppedBytes: number) => string;\n}\n\nexport interface IBoundedOutput {\n append(chunk: Uint8Array | string): void;\n /** Bytes currently retained (≤ `maxBytes`). */\n readonly retainedBytes: number;\n /** Bytes the child produced in total, retained or not. */\n readonly totalBytes: number;\n readonly droppedBytes: number;\n readonly truncated: boolean;\n /** The retained output, decoded as UTF-8, with the truncation marker when bytes were dropped. */\n toString(): string;\n}\n\nconst DEFAULT_MARKER = (dropped: number): string =>\n `\\n…[output truncated: ${dropped} byte(s) dropped]`;\n\nexport function createBoundedOutput(options: IBoundedOutputOptions): IBoundedOutput {\n const retain = options.retain ?? 'head';\n const marker = options.truncationMarker ?? DEFAULT_MARKER;\n const maxBytes = Math.max(0, Math.floor(options.maxBytes));\n const encoder = new TextEncoder();\n let chunks: Uint8Array[] = [];\n let retained = 0;\n let total = 0;\n\n const appendHead = (bytes: Uint8Array): void => {\n const room = maxBytes - retained;\n if (room <= 0) return;\n const kept = bytes.byteLength <= room ? bytes : bytes.subarray(0, room);\n chunks.push(kept);\n retained += kept.byteLength;\n };\n\n const appendTail = (bytes: Uint8Array): void => {\n const kept = bytes.byteLength <= maxBytes ? bytes : bytes.subarray(bytes.byteLength - maxBytes);\n chunks.push(kept);\n retained += kept.byteLength;\n // Drop whole leading chunks first, then trim the oldest survivor — O(chunks), no re-copying.\n while (retained > maxBytes && chunks.length > 0) {\n const oldest = chunks[0] as Uint8Array;\n const excess = retained - maxBytes;\n if (oldest.byteLength <= excess) {\n chunks.shift();\n retained -= oldest.byteLength;\n } else {\n chunks[0] = oldest.subarray(excess);\n retained -= excess;\n }\n }\n };\n\n return {\n append(chunk) {\n const bytes = typeof chunk === 'string' ? encoder.encode(chunk) : chunk;\n total += bytes.byteLength;\n if (retain === 'head') appendHead(bytes);\n else appendTail(bytes);\n },\n get retainedBytes() {\n return retained;\n },\n get totalBytes() {\n return total;\n },\n get droppedBytes() {\n return total - retained;\n },\n get truncated() {\n return total > retained;\n },\n toString() {\n const joined = new Uint8Array(retained);\n let offset = 0;\n for (const chunk of chunks) {\n joined.set(chunk, offset);\n offset += chunk.byteLength;\n }\n chunks = chunks.length > 1 ? [joined] : chunks;\n const text = new TextDecoder().decode(joined);\n if (total <= retained) return text;\n const note = marker(total - retained);\n return retain === 'head' ? `${text}${note}` : `${note.replace(/^\\n/, '')}\\n${text}`;\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{f as e,s as t,t as n}from"./bounded-output-BdWv9SX3.js";import{spawn as r}from"node:child_process";const i=1e6;function a(e,t){let r=n({maxBytes:i}),a=n({maxBytes:i,retain:`tail`});return e.stdout?.on(`data`,e=>r.append(e)),e.stderr?.on(`data`,e=>a.append(e)),e.stdin?.on(`error`,()=>{}),e.stdin?.write(t),e.stdin?.end(),{stdoutOutput:r,stderrOutput:a}}function o(e,t,n,r){if(e===0)return{outcome:`allow`,source:`command`,stdout:n};if(e===2)return{outcome:`deny`,source:`command`,reason:r.trim()||`Blocked by hook`};let i=r.trim()?`: ${r.trim()}`:``;return{outcome:`error`,source:`command`,kind:`nonzero-exit`,reason:e===null?`Hook terminated by signal ${t??`unknown`}${i}`:`Hook exited ${e}${i}`}}var s=class{shellExecutable;type=`command`;constructor(e){this.shellExecutable=e}execute(n,i,s){let c=n.timeout??600,l=c*1e3,u=JSON.stringify(i);return new Promise(d=>{let f=!1,p=e({executable:this.shellExecutable}),m=r(p.command,p.commandArgs(n.command),{cwd:i.cwd,env:t(process.env,s,i.env)}),{stdoutOutput:h,stderrOutput:g}=a(m,u),_=setTimeout(()=>{f||(f=!0,m.kill(`SIGTERM`),d({outcome:`error`,source:`command`,kind:`timeout`,reason:`Hook timed out after ${c}s`}))},l);m.on(`close`,(e,t)=>{f||(f=!0,clearTimeout(_),d(o(e,t,h.toString(),g.toString())))}),m.on(`error`,e=>{f||(f=!0,clearTimeout(_),d({outcome:`error`,source:`command`,kind:`spawn-failure`,reason:e.message}))})})}};export{s as CommandExecutor};
2
+ //# sourceMappingURL=command-executor-DIXaSMrr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-executor-DIXaSMrr.js","names":[],"sources":["../../src/hooks/executors/command-executor.ts"],"sourcesContent":["/**\n * Command hook executor — executes shell commands with JSON input on stdin.\n *\n * Exit-code mapping (SEC-015):\n * - `0` → `allow`, stdout carried for the runner's response-protocol decode\n * - `2` → `deny`, stderr carried as the reason\n * - any other code → `error` / `nonzero-exit`\n * - killed by a signal (exit code `null`) → `error` / `nonzero-exit`, signal named in the reason\n * - deadline elapsed → `error` / `timeout`\n * - the process never started → `error` / `spawn-failure`\n *\n * The last four used to be one number. A missing binary exits `127` and a timeout resolved `1`, and\n * the runner discarded both alike, so a gate that never ran was indistinguishable from one that\n * approved.\n */\n\nimport { spawn } from 'node:child_process';\n\nimport { createBoundedOutput, type IBoundedOutput } from '../../utils/bounded-output.js';\nimport { resolvePlatformShell } from '../../utils/platform-shell.js';\nimport { subprocessTraceEnvironment } from '../../utils/trace-context.js';\n\nimport type { ISubprocessTraceEnv } from '../../interfaces/trace-context.js';\nimport type {\n ICommandHookDefinition,\n IHookInput,\n THookOutcome,\n IHookTypeExecutor,\n} from '../types.js';\n\n/** Default timeout in seconds — matches Claude Code's 600s default */\nconst DEFAULT_TIMEOUT_SECONDS = 600;\n/** ARCH-056: most bytes retained per hook stream (stdout head, stderr tail). */\nconst MAX_HOOK_OUTPUT_BYTES = 1_000_000;\n\n/**\n * How a finished process maps onto an outcome — a pure function of what the process reported.\n *\n * Extracted from `execute` because it is the part that carries the contract: `execute` owns spawning\n * and settling exactly once, this owns what the result MEANS, and the two change for different\n * reasons.\n */\n/**\n * Attach the output collectors and feed the hook input to stdin.\n *\n * Separated from `execute` so the promise body reads as the three things that can settle it —\n * timeout, close, spawn error — rather than as stream plumbing interleaved with them. The\n * `settled` guard those three share is the invariant worth keeping visible in one place.\n */\nfunction wireChildIo(\n child: ReturnType<typeof spawn>,\n inputJson: string,\n): { stdoutOutput: IBoundedOutput; stderrOutput: IBoundedOutput } {\n // ARCH-056: bounded while reading; a hook that floods stdout cannot grow the parent's memory.\n const stdoutOutput = createBoundedOutput({ maxBytes: MAX_HOOK_OUTPUT_BYTES });\n const stderrOutput = createBoundedOutput({ maxBytes: MAX_HOOK_OUTPUT_BYTES, retain: 'tail' });\n child.stdout?.on('data', (chunk: Buffer) => stdoutOutput.append(chunk));\n child.stderr?.on('data', (chunk: Buffer) => stderrOutput.append(chunk));\n child.stdin?.on('error', () => {\n // EPIPE: child closed stdin before we finished writing — safe to ignore\n });\n child.stdin?.write(inputJson);\n child.stdin?.end();\n return { stdoutOutput, stderrOutput };\n}\n\nfunction outcomeOfExit(\n code: number | null,\n signal: NodeJS.Signals | null,\n stdout: string,\n stderr: string,\n): THookOutcome {\n if (code === 0) return { outcome: 'allow', source: 'command', stdout };\n if (code === 2) {\n return { outcome: 'deny', source: 'command', reason: stderr.trim() || 'Blocked by hook' };\n }\n const detail = stderr.trim() ? `: ${stderr.trim()}` : '';\n return {\n outcome: 'error',\n source: 'command',\n kind: 'nonzero-exit',\n // `code === null` means a signal ended it. That is not an exit code and must not be read as\n // one — the old `code ?? 1` made a SIGKILLed hook indistinguishable from one that exited 1.\n reason:\n code === null\n ? `Hook terminated by signal ${signal ?? 'unknown'}${detail}`\n : `Hook exited ${code}${detail}`,\n };\n}\n\nexport class CommandExecutor implements IHookTypeExecutor {\n readonly type = 'command' as const;\n\n constructor(private readonly shellExecutable?: string) {}\n\n /**\n * `traceEnv` is the prompt's trace for this child, handed separately so it never reaches the\n * stdin JSON. The child sees `process.env`, then ConversationAgent's value, then the hook's own `env`; a hook\n * that sets its own `TRACEPARENT` wins and gets the ambient environment unchanged.\n */\n execute(\n definition: ICommandHookDefinition,\n input: IHookInput,\n traceEnv?: ISubprocessTraceEnv,\n ): Promise<THookOutcome> {\n const timeoutSeconds = definition.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n const timeoutMs = timeoutSeconds * 1000;\n const inputJson = JSON.stringify(input);\n\n return new Promise<THookOutcome>((resolve) => {\n let settled = false;\n const shell = resolvePlatformShell({ executable: this.shellExecutable });\n const child = spawn(shell.command, shell.commandArgs(definition.command), {\n cwd: input.cwd,\n env: subprocessTraceEnvironment(process.env, traceEnv, input.env),\n });\n const { stdoutOutput, stderrOutput } = wireChildIo(child, inputJson);\n\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n child.kill('SIGTERM');\n resolve({\n outcome: 'error',\n source: 'command',\n kind: 'timeout',\n reason: `Hook timed out after ${timeoutSeconds}s`,\n });\n }\n }, timeoutMs);\n\n child.on('close', (code: number | null, signal: NodeJS.Signals | null) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(outcomeOfExit(code, signal, stdoutOutput.toString(), stderrOutput.toString()));\n });\n\n child.on('error', (err: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({\n outcome: 'error',\n source: 'command',\n kind: 'spawn-failure',\n reason: err.message,\n });\n });\n });\n }\n}\n"],"mappings":"0GA+BA,MAEM,EAAwB,IAgB9B,SAAS,EACP,EACA,EACgE,CAEhE,IAAM,EAAe,EAAoB,CAAE,SAAU,CAAsB,CAAC,EACtE,EAAe,EAAoB,CAAE,SAAU,EAAuB,OAAQ,MAAO,CAAC,EAQ5F,OAPA,EAAM,QAAQ,GAAG,OAAS,GAAkB,EAAa,OAAO,CAAK,CAAC,EACtE,EAAM,QAAQ,GAAG,OAAS,GAAkB,EAAa,OAAO,CAAK,CAAC,EACtE,EAAM,OAAO,GAAG,YAAe,CAE/B,CAAC,EACD,EAAM,OAAO,MAAM,CAAS,EAC5B,EAAM,OAAO,IAAI,EACV,CAAE,eAAc,cAAa,CACtC,CAEA,SAAS,EACP,EACA,EACA,EACA,EACc,CACd,GAAI,IAAS,EAAG,MAAO,CAAE,QAAS,QAAS,OAAQ,UAAW,QAAO,EACrE,GAAI,IAAS,EACX,MAAO,CAAE,QAAS,OAAQ,OAAQ,UAAW,OAAQ,EAAO,KAAK,GAAK,iBAAkB,EAE1F,IAAM,EAAS,EAAO,KAAK,EAAI,KAAK,EAAO,KAAK,IAAM,GACtD,MAAO,CACL,QAAS,QACT,OAAQ,UACR,KAAM,eAGN,OACE,IAAS,KACL,6BAA6B,GAAU,YAAY,IACnD,eAAe,IAAO,GAC9B,CACF,CAEA,IAAa,EAAb,KAA0D,CAG3B,gBAF7B,KAAgB,UAEhB,YAAY,EAA2C,CAA1B,KAAA,gBAAA,CAA2B,CAOxD,QACE,EACA,EACA,EACuB,CACvB,IAAM,EAAiB,EAAW,SAAW,IACvC,EAAY,EAAiB,IAC7B,EAAY,KAAK,UAAU,CAAK,EAEtC,OAAO,IAAI,QAAuB,GAAY,CAC5C,IAAI,EAAU,GACR,EAAQ,EAAqB,CAAE,WAAY,KAAK,eAAgB,CAAC,EACjE,EAAQ,EAAM,EAAM,QAAS,EAAM,YAAY,EAAW,OAAO,EAAG,CACxE,IAAK,EAAM,IACX,IAAK,EAA2B,QAAQ,IAAK,EAAU,EAAM,GAAG,CAClE,CAAC,EACK,CAAE,eAAc,gBAAiB,EAAY,EAAO,CAAS,EAE7D,EAAQ,eAAiB,CACxB,IACH,EAAU,GACV,EAAM,KAAK,SAAS,EACpB,EAAQ,CACN,QAAS,QACT,OAAQ,UACR,KAAM,UACN,OAAQ,wBAAwB,EAAe,EACjD,CAAC,EAEL,EAAG,CAAS,EAEZ,EAAM,GAAG,SAAU,EAAqB,IAAkC,CACpE,IACJ,EAAU,GACV,aAAa,CAAK,EAClB,EAAQ,EAAc,EAAM,EAAQ,EAAa,SAAS,EAAG,EAAa,SAAS,CAAC,CAAC,EACvF,CAAC,EAED,EAAM,GAAG,QAAU,GAAe,CAC5B,IACJ,EAAU,GACV,aAAa,CAAK,EAClB,EAAQ,CACN,QAAS,QACT,OAAQ,UACR,KAAM,gBACN,OAAQ,EAAI,OACd,CAAC,EACH,CAAC,CACH,CAAC,CACH,CACF"}
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./verdict-decoder-Dz_rjoIZ.js";function t(e){return e.replace(/\$([A-Za-z_][A-Za-z0-9_]*)/g,(e,t)=>{let n=process.env[t];return n===void 0?e:n})}var n=class{type=`http`;async execute(n,i){let a=(n.timeout??10)*1e3,o={"Content-Type":`application/json`};if(n.headers)for(let[e,r]of Object.entries(n.headers))o[e]=t(r);try{let t=await fetch(n.url,{method:`POST`,headers:o,body:JSON.stringify(i),signal:AbortSignal.timeout(a)});return t.ok?e(await t.text(),`http`,i.hook_event_name):{outcome:`error`,source:`http`,kind:`http-status`,reason:`HTTP ${t.status} ${t.statusText}`}}catch(e){return r(e)}}};function r(e){return{outcome:`error`,source:`http`,kind:e instanceof Error&&e.name===`TimeoutError`?`timeout`:`transport-failure`,reason:e instanceof Error?e.message:String(e)}}export{n as HttpExecutor};
2
+ //# sourceMappingURL=http-executor-B4YgCJg7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-executor-B4YgCJg7.js","names":[],"sources":["../../src/hooks/executors/http-executor.ts"],"sourcesContent":["/**\n * HTTP hook executor — POSTs hook input as JSON to a URL.\n *\n * Response format: `{ ok: boolean, reason?: string }`, decoded by `decodeHookVerdict` (SEC-015):\n * - `ok: true` → `allow`\n * - `ok: false` → `deny`, carrying `reason`\n * - anything else, including a non-boolean `ok` → `error` / `malformed-response`\n *\n * Transport conditions are outcomes in their own right rather than a shared failure code:\n * non-2xx → `http-status`, deadline elapsed → `timeout`, unreachable → `transport-failure`,\n * unparseable body → `malformed-response`.\n *\n * Supports env var interpolation in headers: $VAR_NAME\n */\n\nimport { decodeHookVerdict } from '../verdict-decoder.js';\n\nimport type { IHttpHookDefinition, IHookInput, THookOutcome, IHookTypeExecutor } from '../types.js';\n\n/** Default timeout in seconds */\nconst DEFAULT_TIMEOUT_SECONDS = 10;\n\n/** Interpolate $VAR_NAME references in a string with process.env values. */\nfunction interpolateEnvVars(value: string): string {\n return value.replace(/\\$([A-Za-z_][A-Za-z0-9_]*)/g, (_match, varName: string) => {\n const envValue = process.env[varName];\n return envValue !== undefined ? envValue : _match;\n });\n}\n\nexport class HttpExecutor implements IHookTypeExecutor {\n readonly type = 'http' as const;\n\n async execute(definition: IHttpHookDefinition, input: IHookInput): Promise<THookOutcome> {\n const timeoutSeconds = definition.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n const timeoutMs = timeoutSeconds * 1000;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (definition.headers) {\n for (const [key, value] of Object.entries(definition.headers)) {\n headers[key] = interpolateEnvVars(value);\n }\n }\n\n try {\n const response = await fetch(definition.url, {\n method: 'POST',\n headers,\n body: JSON.stringify(input),\n signal: AbortSignal.timeout(timeoutMs),\n });\n\n if (!response.ok) {\n return {\n outcome: 'error',\n source: 'http',\n kind: 'http-status',\n reason: `HTTP ${response.status} ${response.statusText}`,\n };\n }\n\n // Read the body as TEXT first. `response.json()` would collapse \"the endpoint sent HTML\" and\n // \"the endpoint sent a verdict\" into one throw, and the raw text is what the decoder quotes\n // back — so a misconfigured endpoint is identifiable from the reason alone.\n return decodeHookVerdict(await response.text(), 'http', input.hook_event_name);\n } catch (err: unknown) {\n return toTransportOutcome(err);\n }\n }\n}\n\n/**\n * Classify a `fetch` rejection.\n *\n * `AbortSignal.timeout` rejects with a `DOMException` named `TimeoutError`, which is a different\n * fact from a connection refused or dropped: one says the hook was too slow, the other says it was\n * never reached. Both are `error`, and an operator reading the reason needs to know which.\n */\nfunction toTransportOutcome(err: unknown): THookOutcome {\n return {\n outcome: 'error',\n source: 'http',\n kind: err instanceof Error && err.name === 'TimeoutError' ? 'timeout' : 'transport-failure',\n reason: err instanceof Error ? err.message : String(err),\n };\n}\n"],"mappings":"kDAuBA,SAAS,EAAmB,EAAuB,CACjD,OAAO,EAAM,QAAQ,+BAAgC,EAAQ,IAAoB,CAC/E,IAAM,EAAW,QAAQ,IAAI,GAC7B,OAAO,IAAa,IAAA,GAAuB,EAAX,CAClC,CAAC,CACH,CAEA,IAAa,EAAb,KAAuD,CACrD,KAAgB,OAEhB,MAAM,QAAQ,EAAiC,EAA0C,CAEvF,IAAM,GADiB,EAAW,SAAW,IACV,IAE7B,EAAkC,CACtC,eAAgB,kBAClB,EAEA,GAAI,EAAW,QACb,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAW,OAAO,EAC1D,EAAQ,GAAO,EAAmB,CAAK,EAI3C,GAAI,CACF,IAAM,EAAW,MAAM,MAAM,EAAW,IAAK,CAC3C,OAAQ,OACR,UACA,KAAM,KAAK,UAAU,CAAK,EAC1B,OAAQ,YAAY,QAAQ,CAAS,CACvC,CAAC,EAcD,OAZK,EAAS,GAYP,EAAkB,MAAM,EAAS,KAAK,EAAG,OAAQ,EAAM,eAAe,EAXpE,CACL,QAAS,QACT,OAAQ,OACR,KAAM,cACN,OAAQ,QAAQ,EAAS,OAAO,GAAG,EAAS,YAC9C,CAOJ,OAAS,EAAc,CACrB,OAAO,EAAmB,CAAG,CAC/B,CACF,CACF,EASA,SAAS,EAAmB,EAA4B,CACtD,MAAO,CACL,QAAS,QACT,OAAQ,OACR,KAAM,aAAe,OAAS,EAAI,OAAS,eAAiB,UAAY,oBACxE,OAAQ,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CACzD,CACF"}