@cicctencent/agent-core 0.1.1 → 0.1.3

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 (439) hide show
  1. package/dist/cjs/agent/engine.d.ts.map +1 -0
  2. package/dist/cjs/agent/engine.js +766 -0
  3. package/dist/cjs/agent/engine.js.map +1 -0
  4. package/dist/cjs/agent/history-manager.d.ts.map +1 -0
  5. package/dist/cjs/agent/history-manager.js +271 -0
  6. package/dist/cjs/agent/history-manager.js.map +1 -0
  7. package/dist/cjs/agent/llm-caller.d.ts.map +1 -0
  8. package/dist/cjs/agent/llm-caller.js +307 -0
  9. package/dist/cjs/agent/llm-caller.js.map +1 -0
  10. package/dist/cjs/agent/tool-executor.d.ts.map +1 -0
  11. package/dist/cjs/agent/tool-executor.js +568 -0
  12. package/dist/cjs/agent/tool-executor.js.map +1 -0
  13. package/dist/cjs/agent/types.d.ts.map +1 -0
  14. package/dist/cjs/agent/types.js +6 -0
  15. package/dist/cjs/agent/types.js.map +1 -0
  16. package/dist/cjs/agent/workflow.d.ts.map +1 -0
  17. package/dist/cjs/agent/workflow.js +262 -0
  18. package/dist/cjs/agent/workflow.js.map +1 -0
  19. package/dist/cjs/context/collector.d.ts.map +1 -0
  20. package/dist/cjs/context/collector.js +94 -0
  21. package/dist/cjs/context/collector.js.map +1 -0
  22. package/dist/cjs/context/manager.d.ts.map +1 -0
  23. package/dist/cjs/context/manager.js +36 -0
  24. package/dist/cjs/context/manager.js.map +1 -0
  25. package/dist/cjs/context/types.d.ts.map +1 -0
  26. package/dist/cjs/context/types.js +6 -0
  27. package/dist/cjs/context/types.js.map +1 -0
  28. package/dist/cjs/hooks/types.d.ts.map +1 -0
  29. package/dist/cjs/hooks/types.js +6 -0
  30. package/dist/cjs/hooks/types.js.map +1 -0
  31. package/dist/cjs/index.d.ts.map +1 -0
  32. package/dist/cjs/index.js +98 -0
  33. package/dist/cjs/index.js.map +1 -0
  34. package/dist/cjs/llm/anthropic-provider.d.ts.map +1 -0
  35. package/dist/cjs/llm/anthropic-provider.js +356 -0
  36. package/dist/cjs/llm/anthropic-provider.js.map +1 -0
  37. package/dist/cjs/llm/factory.d.ts.map +1 -0
  38. package/dist/cjs/llm/factory.js +34 -0
  39. package/dist/cjs/llm/factory.js.map +1 -0
  40. package/dist/cjs/llm/ollama-provider.d.ts.map +1 -0
  41. package/dist/cjs/llm/ollama-provider.js +34 -0
  42. package/dist/cjs/llm/ollama-provider.js.map +1 -0
  43. package/dist/cjs/llm/openai-provider.d.ts.map +1 -0
  44. package/dist/cjs/llm/openai-provider.js +186 -0
  45. package/dist/cjs/llm/openai-provider.js.map +1 -0
  46. package/dist/cjs/llm/provider.d.ts.map +1 -0
  47. package/dist/cjs/llm/provider.js +18 -0
  48. package/dist/cjs/llm/provider.js.map +1 -0
  49. package/dist/cjs/llm/types.d.ts.map +1 -0
  50. package/dist/cjs/llm/types.js +6 -0
  51. package/dist/cjs/llm/types.js.map +1 -0
  52. package/dist/cjs/mcp/base-client.d.ts.map +1 -0
  53. package/dist/cjs/mcp/base-client.js +112 -0
  54. package/dist/cjs/mcp/base-client.js.map +1 -0
  55. package/dist/cjs/mcp/client.d.ts.map +1 -0
  56. package/dist/cjs/mcp/client.js +76 -0
  57. package/dist/cjs/mcp/client.js.map +1 -0
  58. package/dist/cjs/mcp/factory.d.ts.map +1 -0
  59. package/dist/cjs/mcp/factory.js +43 -0
  60. package/dist/cjs/mcp/factory.js.map +1 -0
  61. package/dist/cjs/mcp/http-client.d.ts.map +1 -0
  62. package/dist/cjs/mcp/http-client.js +142 -0
  63. package/dist/cjs/mcp/http-client.js.map +1 -0
  64. package/dist/cjs/mcp/proxy-agent.d.ts.map +1 -0
  65. package/dist/cjs/mcp/proxy-agent.js +195 -0
  66. package/dist/cjs/mcp/proxy-agent.js.map +1 -0
  67. package/dist/cjs/mcp/stdio-client.d.ts.map +1 -0
  68. package/dist/cjs/mcp/stdio-client.js +95 -0
  69. package/dist/cjs/mcp/stdio-client.js.map +1 -0
  70. package/dist/cjs/mcp/types.d.ts.map +1 -0
  71. package/dist/cjs/mcp/types.js +6 -0
  72. package/dist/cjs/mcp/types.js.map +1 -0
  73. package/dist/cjs/memory/checkpoint.d.ts.map +1 -0
  74. package/dist/cjs/memory/checkpoint.js +160 -0
  75. package/dist/cjs/memory/checkpoint.js.map +1 -0
  76. package/dist/cjs/memory/extractor.d.ts.map +1 -0
  77. package/dist/cjs/memory/extractor.js +121 -0
  78. package/dist/cjs/memory/extractor.js.map +1 -0
  79. package/dist/cjs/memory/persona.d.ts.map +1 -0
  80. package/dist/cjs/memory/persona.js +79 -0
  81. package/dist/cjs/memory/persona.js.map +1 -0
  82. package/dist/cjs/memory/pipeline.d.ts.map +1 -0
  83. package/dist/cjs/memory/pipeline.js +148 -0
  84. package/dist/cjs/memory/pipeline.js.map +1 -0
  85. package/dist/cjs/memory/prompts.d.ts.map +1 -0
  86. package/dist/cjs/memory/prompts.js +70 -0
  87. package/dist/cjs/memory/prompts.js.map +1 -0
  88. package/dist/cjs/memory/recall.d.ts.map +1 -0
  89. package/dist/cjs/memory/recall.js +164 -0
  90. package/dist/cjs/memory/recall.js.map +1 -0
  91. package/dist/cjs/memory/scene.d.ts.map +1 -0
  92. package/dist/cjs/memory/scene.js +101 -0
  93. package/dist/cjs/memory/scene.js.map +1 -0
  94. package/dist/cjs/memory/types.d.ts.map +1 -0
  95. package/dist/cjs/memory/types.js +6 -0
  96. package/dist/cjs/memory/types.js.map +1 -0
  97. package/dist/cjs/middleware/types.d.ts.map +1 -0
  98. package/dist/cjs/middleware/types.js +6 -0
  99. package/dist/cjs/middleware/types.js.map +1 -0
  100. package/dist/cjs/package.json +3 -0
  101. package/dist/cjs/sandbox/types.d.ts.map +1 -0
  102. package/dist/cjs/sandbox/types.js +128 -0
  103. package/dist/cjs/sandbox/types.js.map +1 -0
  104. package/dist/cjs/security/guard.d.ts.map +1 -0
  105. package/dist/cjs/security/guard.js +229 -0
  106. package/dist/cjs/security/guard.js.map +1 -0
  107. package/dist/cjs/security/types.d.ts.map +1 -0
  108. package/dist/cjs/security/types.js +6 -0
  109. package/dist/cjs/security/types.js.map +1 -0
  110. package/dist/cjs/skill/manager.d.ts.map +1 -0
  111. package/dist/cjs/skill/manager.js +413 -0
  112. package/dist/cjs/skill/manager.js.map +1 -0
  113. package/dist/cjs/skill/router.d.ts.map +1 -0
  114. package/dist/cjs/skill/router.js +139 -0
  115. package/dist/cjs/skill/router.js.map +1 -0
  116. package/dist/cjs/skill/types.d.ts.map +1 -0
  117. package/dist/cjs/skill/types.js +6 -0
  118. package/dist/cjs/skill/types.js.map +1 -0
  119. package/dist/cjs/tool/delegate.d.ts.map +1 -0
  120. package/dist/cjs/tool/delegate.js +78 -0
  121. package/dist/cjs/tool/delegate.js.map +1 -0
  122. package/dist/cjs/tool/registry.d.ts.map +1 -0
  123. package/dist/cjs/tool/registry.js +57 -0
  124. package/dist/cjs/tool/registry.js.map +1 -0
  125. package/dist/cjs/tool/types.d.ts.map +1 -0
  126. package/dist/cjs/tool/types.js +6 -0
  127. package/dist/cjs/tool/types.js.map +1 -0
  128. package/dist/cjs/types.d.ts.map +1 -0
  129. package/dist/cjs/types.js +6 -0
  130. package/dist/cjs/types.js.map +1 -0
  131. package/dist/cjs/utils/token-counter.d.ts.map +1 -0
  132. package/dist/cjs/utils/token-counter.js +104 -0
  133. package/dist/cjs/utils/token-counter.js.map +1 -0
  134. package/dist/esm/agent/engine.d.ts +113 -0
  135. package/dist/esm/agent/engine.d.ts.map +1 -0
  136. package/dist/esm/agent/engine.js +762 -0
  137. package/dist/esm/agent/engine.js.map +1 -0
  138. package/dist/esm/agent/history-manager.d.ts +78 -0
  139. package/dist/esm/agent/history-manager.d.ts.map +1 -0
  140. package/dist/esm/agent/history-manager.js +267 -0
  141. package/dist/esm/agent/history-manager.js.map +1 -0
  142. package/dist/esm/agent/llm-caller.d.ts +58 -0
  143. package/dist/esm/agent/llm-caller.d.ts.map +1 -0
  144. package/dist/esm/agent/llm-caller.js +303 -0
  145. package/dist/esm/agent/llm-caller.js.map +1 -0
  146. package/dist/esm/agent/tool-executor.d.ts +95 -0
  147. package/dist/esm/agent/tool-executor.d.ts.map +1 -0
  148. package/dist/esm/agent/tool-executor.js +564 -0
  149. package/dist/esm/agent/tool-executor.js.map +1 -0
  150. package/dist/esm/agent/types.d.ts +128 -0
  151. package/dist/esm/agent/types.d.ts.map +1 -0
  152. package/dist/esm/agent/types.js +5 -0
  153. package/dist/esm/agent/types.js.map +1 -0
  154. package/dist/esm/agent/workflow.d.ts +74 -0
  155. package/dist/esm/agent/workflow.d.ts.map +1 -0
  156. package/dist/esm/agent/workflow.js +248 -0
  157. package/dist/esm/agent/workflow.js.map +1 -0
  158. package/dist/esm/context/collector.d.ts +12 -0
  159. package/dist/esm/context/collector.d.ts.map +1 -0
  160. package/dist/esm/context/collector.js +57 -0
  161. package/dist/esm/context/collector.js.map +1 -0
  162. package/dist/esm/context/manager.d.ts +16 -0
  163. package/dist/esm/context/manager.d.ts.map +1 -0
  164. package/dist/esm/context/manager.js +32 -0
  165. package/dist/esm/context/manager.js.map +1 -0
  166. package/dist/esm/context/types.d.ts +39 -0
  167. package/dist/esm/context/types.d.ts.map +1 -0
  168. package/dist/esm/context/types.js +5 -0
  169. package/dist/esm/context/types.js.map +1 -0
  170. package/dist/esm/hooks/types.d.ts +47 -0
  171. package/dist/esm/hooks/types.d.ts.map +1 -0
  172. package/dist/esm/hooks/types.js +5 -0
  173. package/dist/esm/hooks/types.js.map +1 -0
  174. package/{src/index.ts → dist/esm/index.d.ts} +15 -140
  175. package/dist/esm/index.d.ts.map +1 -0
  176. package/dist/esm/index.js +39 -0
  177. package/dist/esm/index.js.map +1 -0
  178. package/dist/esm/llm/anthropic-provider.d.ts +28 -0
  179. package/dist/esm/llm/anthropic-provider.d.ts.map +1 -0
  180. package/dist/esm/llm/anthropic-provider.js +352 -0
  181. package/dist/esm/llm/anthropic-provider.js.map +1 -0
  182. package/{src/llm/factory.ts → dist/esm/llm/factory.d.ts} +3 -18
  183. package/dist/esm/llm/factory.d.ts.map +1 -0
  184. package/dist/esm/llm/factory.js +30 -0
  185. package/dist/esm/llm/factory.js.map +1 -0
  186. package/dist/esm/llm/ollama-provider.d.ts +13 -0
  187. package/dist/esm/llm/ollama-provider.d.ts.map +1 -0
  188. package/dist/esm/llm/ollama-provider.js +30 -0
  189. package/dist/esm/llm/ollama-provider.js.map +1 -0
  190. package/dist/esm/llm/openai-provider.d.ts +18 -0
  191. package/dist/esm/llm/openai-provider.d.ts.map +1 -0
  192. package/dist/esm/llm/openai-provider.js +182 -0
  193. package/dist/esm/llm/openai-provider.js.map +1 -0
  194. package/{src/llm/provider.ts → dist/esm/llm/provider.d.ts} +1 -9
  195. package/dist/esm/llm/provider.d.ts.map +1 -0
  196. package/dist/esm/llm/provider.js +10 -0
  197. package/dist/esm/llm/provider.js.map +1 -0
  198. package/dist/esm/llm/types.d.ts +78 -0
  199. package/dist/esm/llm/types.d.ts.map +1 -0
  200. package/dist/esm/llm/types.js +5 -0
  201. package/dist/esm/llm/types.js.map +1 -0
  202. package/dist/esm/mcp/base-client.d.ts +50 -0
  203. package/dist/esm/mcp/base-client.d.ts.map +1 -0
  204. package/dist/esm/mcp/base-client.js +108 -0
  205. package/dist/esm/mcp/base-client.js.map +1 -0
  206. package/dist/esm/mcp/client.d.ts +27 -0
  207. package/dist/esm/mcp/client.d.ts.map +1 -0
  208. package/dist/esm/mcp/client.js +70 -0
  209. package/dist/esm/mcp/client.js.map +1 -0
  210. package/dist/esm/mcp/factory.d.ts +16 -0
  211. package/dist/esm/mcp/factory.d.ts.map +1 -0
  212. package/dist/esm/mcp/factory.js +39 -0
  213. package/dist/esm/mcp/factory.js.map +1 -0
  214. package/dist/esm/mcp/http-client.d.ts +24 -0
  215. package/dist/esm/mcp/http-client.d.ts.map +1 -0
  216. package/dist/esm/mcp/http-client.js +138 -0
  217. package/dist/esm/mcp/http-client.js.map +1 -0
  218. package/dist/esm/mcp/proxy-agent.d.ts +49 -0
  219. package/dist/esm/mcp/proxy-agent.d.ts.map +1 -0
  220. package/dist/esm/mcp/proxy-agent.js +187 -0
  221. package/dist/esm/mcp/proxy-agent.js.map +1 -0
  222. package/dist/esm/mcp/stdio-client.d.ts +16 -0
  223. package/dist/esm/mcp/stdio-client.d.ts.map +1 -0
  224. package/dist/esm/mcp/stdio-client.js +91 -0
  225. package/dist/esm/mcp/stdio-client.js.map +1 -0
  226. package/dist/esm/mcp/types.d.ts +60 -0
  227. package/dist/esm/mcp/types.d.ts.map +1 -0
  228. package/dist/esm/mcp/types.js +5 -0
  229. package/dist/esm/mcp/types.js.map +1 -0
  230. package/dist/esm/memory/checkpoint.d.ts +62 -0
  231. package/dist/esm/memory/checkpoint.d.ts.map +1 -0
  232. package/dist/esm/memory/checkpoint.js +121 -0
  233. package/dist/esm/memory/checkpoint.js.map +1 -0
  234. package/dist/esm/memory/extractor.d.ts +59 -0
  235. package/dist/esm/memory/extractor.d.ts.map +1 -0
  236. package/dist/esm/memory/extractor.js +117 -0
  237. package/dist/esm/memory/extractor.js.map +1 -0
  238. package/dist/esm/memory/persona.d.ts +38 -0
  239. package/dist/esm/memory/persona.d.ts.map +1 -0
  240. package/dist/esm/memory/persona.js +75 -0
  241. package/dist/esm/memory/persona.js.map +1 -0
  242. package/dist/esm/memory/pipeline.d.ts +50 -0
  243. package/dist/esm/memory/pipeline.d.ts.map +1 -0
  244. package/dist/esm/memory/pipeline.js +144 -0
  245. package/dist/esm/memory/pipeline.js.map +1 -0
  246. package/dist/esm/memory/prompts.d.ts +9 -0
  247. package/dist/esm/memory/prompts.d.ts.map +1 -0
  248. package/{src/memory/prompts.ts → dist/esm/memory/prompts.js} +6 -13
  249. package/dist/esm/memory/prompts.js.map +1 -0
  250. package/dist/esm/memory/recall.d.ts +66 -0
  251. package/dist/esm/memory/recall.d.ts.map +1 -0
  252. package/dist/esm/memory/recall.js +159 -0
  253. package/dist/esm/memory/recall.js.map +1 -0
  254. package/dist/esm/memory/scene.d.ts +49 -0
  255. package/dist/esm/memory/scene.d.ts.map +1 -0
  256. package/dist/esm/memory/scene.js +97 -0
  257. package/dist/esm/memory/scene.js.map +1 -0
  258. package/dist/esm/memory/types.d.ts +43 -0
  259. package/dist/esm/memory/types.d.ts.map +1 -0
  260. package/dist/esm/memory/types.js +5 -0
  261. package/dist/esm/memory/types.js.map +1 -0
  262. package/dist/esm/middleware/types.d.ts +52 -0
  263. package/dist/esm/middleware/types.d.ts.map +1 -0
  264. package/dist/esm/middleware/types.js +5 -0
  265. package/dist/esm/middleware/types.js.map +1 -0
  266. package/dist/esm/package.json +3 -0
  267. package/dist/esm/sandbox/types.d.ts +59 -0
  268. package/dist/esm/sandbox/types.d.ts.map +1 -0
  269. package/dist/esm/sandbox/types.js +125 -0
  270. package/dist/esm/sandbox/types.js.map +1 -0
  271. package/dist/esm/security/guard.d.ts +41 -0
  272. package/dist/esm/security/guard.d.ts.map +1 -0
  273. package/dist/esm/security/guard.js +225 -0
  274. package/dist/esm/security/guard.js.map +1 -0
  275. package/dist/esm/security/types.d.ts +36 -0
  276. package/dist/esm/security/types.d.ts.map +1 -0
  277. package/dist/esm/security/types.js +5 -0
  278. package/dist/esm/security/types.js.map +1 -0
  279. package/dist/esm/skill/manager.d.ts +95 -0
  280. package/dist/esm/skill/manager.d.ts.map +1 -0
  281. package/dist/esm/skill/manager.js +376 -0
  282. package/dist/esm/skill/manager.js.map +1 -0
  283. package/dist/esm/skill/router.d.ts +26 -0
  284. package/dist/esm/skill/router.d.ts.map +1 -0
  285. package/dist/esm/skill/router.js +135 -0
  286. package/dist/esm/skill/router.js.map +1 -0
  287. package/dist/esm/skill/types.d.ts +55 -0
  288. package/dist/esm/skill/types.d.ts.map +1 -0
  289. package/dist/esm/skill/types.js +5 -0
  290. package/dist/esm/skill/types.js.map +1 -0
  291. package/dist/esm/tool/delegate.d.ts +34 -0
  292. package/dist/esm/tool/delegate.d.ts.map +1 -0
  293. package/dist/esm/tool/delegate.js +75 -0
  294. package/dist/esm/tool/delegate.js.map +1 -0
  295. package/dist/esm/tool/registry.d.ts +24 -0
  296. package/dist/esm/tool/registry.d.ts.map +1 -0
  297. package/dist/esm/tool/registry.js +53 -0
  298. package/dist/esm/tool/registry.js.map +1 -0
  299. package/dist/esm/tool/types.d.ts +101 -0
  300. package/dist/esm/tool/types.d.ts.map +1 -0
  301. package/dist/esm/tool/types.js +5 -0
  302. package/dist/esm/tool/types.js.map +1 -0
  303. package/dist/esm/types.d.ts +150 -0
  304. package/dist/esm/types.d.ts.map +1 -0
  305. package/dist/esm/types.js +5 -0
  306. package/dist/esm/types.js.map +1 -0
  307. package/dist/esm/utils/token-counter.d.ts +22 -0
  308. package/dist/esm/utils/token-counter.d.ts.map +1 -0
  309. package/dist/esm/utils/token-counter.js +99 -0
  310. package/dist/esm/utils/token-counter.js.map +1 -0
  311. package/package.json +16 -10
  312. package/dist/agent/engine.d.ts.map +0 -1
  313. package/dist/agent/history-manager.d.ts.map +0 -1
  314. package/dist/agent/llm-caller.d.ts.map +0 -1
  315. package/dist/agent/tool-executor.d.ts.map +0 -1
  316. package/dist/agent/types.d.ts.map +0 -1
  317. package/dist/agent/workflow.d.ts.map +0 -1
  318. package/dist/context/collector.d.ts.map +0 -1
  319. package/dist/context/manager.d.ts.map +0 -1
  320. package/dist/context/types.d.ts.map +0 -1
  321. package/dist/hooks/types.d.ts.map +0 -1
  322. package/dist/index.d.ts.map +0 -1
  323. package/dist/llm/anthropic-provider.d.ts.map +0 -1
  324. package/dist/llm/factory.d.ts.map +0 -1
  325. package/dist/llm/ollama-provider.d.ts.map +0 -1
  326. package/dist/llm/openai-provider.d.ts.map +0 -1
  327. package/dist/llm/provider.d.ts.map +0 -1
  328. package/dist/llm/types.d.ts.map +0 -1
  329. package/dist/mcp/base-client.d.ts.map +0 -1
  330. package/dist/mcp/client.d.ts.map +0 -1
  331. package/dist/mcp/factory.d.ts.map +0 -1
  332. package/dist/mcp/http-client.d.ts.map +0 -1
  333. package/dist/mcp/proxy-agent.d.ts.map +0 -1
  334. package/dist/mcp/stdio-client.d.ts.map +0 -1
  335. package/dist/mcp/types.d.ts.map +0 -1
  336. package/dist/memory/checkpoint.d.ts.map +0 -1
  337. package/dist/memory/extractor.d.ts.map +0 -1
  338. package/dist/memory/persona.d.ts.map +0 -1
  339. package/dist/memory/pipeline.d.ts.map +0 -1
  340. package/dist/memory/prompts.d.ts.map +0 -1
  341. package/dist/memory/recall.d.ts.map +0 -1
  342. package/dist/memory/scene.d.ts.map +0 -1
  343. package/dist/memory/types.d.ts.map +0 -1
  344. package/dist/middleware/types.d.ts.map +0 -1
  345. package/dist/sandbox/types.d.ts.map +0 -1
  346. package/dist/security/guard.d.ts.map +0 -1
  347. package/dist/security/types.d.ts.map +0 -1
  348. package/dist/skill/manager.d.ts.map +0 -1
  349. package/dist/skill/router.d.ts.map +0 -1
  350. package/dist/skill/types.d.ts.map +0 -1
  351. package/dist/tool/delegate.d.ts.map +0 -1
  352. package/dist/tool/registry.d.ts.map +0 -1
  353. package/dist/tool/types.d.ts.map +0 -1
  354. package/dist/types.d.ts.map +0 -1
  355. package/dist/utils/token-counter.d.ts.map +0 -1
  356. package/src/agent/engine.ts +0 -875
  357. package/src/agent/history-manager.ts +0 -323
  358. package/src/agent/llm-caller.ts +0 -383
  359. package/src/agent/tool-executor.ts +0 -713
  360. package/src/agent/types.ts +0 -136
  361. package/src/agent/workflow.ts +0 -339
  362. package/src/context/collector.ts +0 -59
  363. package/src/context/manager.ts +0 -40
  364. package/src/context/types.ts +0 -51
  365. package/src/hooks/types.ts +0 -77
  366. package/src/llm/anthropic-provider.ts +0 -412
  367. package/src/llm/ollama-provider.ts +0 -39
  368. package/src/llm/openai-provider.ts +0 -200
  369. package/src/llm/types.ts +0 -91
  370. package/src/mcp/base-client.ts +0 -159
  371. package/src/mcp/client.ts +0 -81
  372. package/src/mcp/factory.ts +0 -45
  373. package/src/mcp/http-client.ts +0 -149
  374. package/src/mcp/proxy-agent.ts +0 -227
  375. package/src/mcp/stdio-client.ts +0 -104
  376. package/src/mcp/types.ts +0 -65
  377. package/src/memory/checkpoint.ts +0 -146
  378. package/src/memory/extractor.ts +0 -164
  379. package/src/memory/persona.ts +0 -106
  380. package/src/memory/pipeline.ts +0 -192
  381. package/src/memory/recall.ts +0 -217
  382. package/src/memory/scene.ts +0 -137
  383. package/src/memory/types.ts +0 -54
  384. package/src/middleware/types.ts +0 -62
  385. package/src/sandbox/types.ts +0 -185
  386. package/src/security/guard.ts +0 -249
  387. package/src/security/types.ts +0 -46
  388. package/src/skill/manager.ts +0 -420
  389. package/src/skill/router.ts +0 -158
  390. package/src/skill/types.ts +0 -67
  391. package/src/tool/delegate.ts +0 -105
  392. package/src/tool/registry.ts +0 -64
  393. package/src/tool/types.ts +0 -124
  394. package/src/types.ts +0 -188
  395. package/src/utils/token-counter.ts +0 -108
  396. /package/dist/{agent → cjs/agent}/engine.d.ts +0 -0
  397. /package/dist/{agent → cjs/agent}/history-manager.d.ts +0 -0
  398. /package/dist/{agent → cjs/agent}/llm-caller.d.ts +0 -0
  399. /package/dist/{agent → cjs/agent}/tool-executor.d.ts +0 -0
  400. /package/dist/{agent → cjs/agent}/types.d.ts +0 -0
  401. /package/dist/{agent → cjs/agent}/workflow.d.ts +0 -0
  402. /package/dist/{context → cjs/context}/collector.d.ts +0 -0
  403. /package/dist/{context → cjs/context}/manager.d.ts +0 -0
  404. /package/dist/{context → cjs/context}/types.d.ts +0 -0
  405. /package/dist/{hooks → cjs/hooks}/types.d.ts +0 -0
  406. /package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
  407. /package/dist/{llm → cjs/llm}/anthropic-provider.d.ts +0 -0
  408. /package/dist/{llm → cjs/llm}/factory.d.ts +0 -0
  409. /package/dist/{llm → cjs/llm}/ollama-provider.d.ts +0 -0
  410. /package/dist/{llm → cjs/llm}/openai-provider.d.ts +0 -0
  411. /package/dist/{llm → cjs/llm}/provider.d.ts +0 -0
  412. /package/dist/{llm → cjs/llm}/types.d.ts +0 -0
  413. /package/dist/{mcp → cjs/mcp}/base-client.d.ts +0 -0
  414. /package/dist/{mcp → cjs/mcp}/client.d.ts +0 -0
  415. /package/dist/{mcp → cjs/mcp}/factory.d.ts +0 -0
  416. /package/dist/{mcp → cjs/mcp}/http-client.d.ts +0 -0
  417. /package/dist/{mcp → cjs/mcp}/proxy-agent.d.ts +0 -0
  418. /package/dist/{mcp → cjs/mcp}/stdio-client.d.ts +0 -0
  419. /package/dist/{mcp → cjs/mcp}/types.d.ts +0 -0
  420. /package/dist/{memory → cjs/memory}/checkpoint.d.ts +0 -0
  421. /package/dist/{memory → cjs/memory}/extractor.d.ts +0 -0
  422. /package/dist/{memory → cjs/memory}/persona.d.ts +0 -0
  423. /package/dist/{memory → cjs/memory}/pipeline.d.ts +0 -0
  424. /package/dist/{memory → cjs/memory}/prompts.d.ts +0 -0
  425. /package/dist/{memory → cjs/memory}/recall.d.ts +0 -0
  426. /package/dist/{memory → cjs/memory}/scene.d.ts +0 -0
  427. /package/dist/{memory → cjs/memory}/types.d.ts +0 -0
  428. /package/dist/{middleware → cjs/middleware}/types.d.ts +0 -0
  429. /package/dist/{sandbox → cjs/sandbox}/types.d.ts +0 -0
  430. /package/dist/{security → cjs/security}/guard.d.ts +0 -0
  431. /package/dist/{security → cjs/security}/types.d.ts +0 -0
  432. /package/dist/{skill → cjs/skill}/manager.d.ts +0 -0
  433. /package/dist/{skill → cjs/skill}/router.d.ts +0 -0
  434. /package/dist/{skill → cjs/skill}/types.d.ts +0 -0
  435. /package/dist/{tool → cjs/tool}/delegate.d.ts +0 -0
  436. /package/dist/{tool → cjs/tool}/registry.d.ts +0 -0
  437. /package/dist/{tool → cjs/tool}/types.d.ts +0 -0
  438. /package/dist/{types.d.ts → cjs/types.d.ts} +0 -0
  439. /package/dist/{utils → cjs/utils}/token-counter.d.ts +0 -0
@@ -1,713 +0,0 @@
1
- // ============================================================
2
- // ToolExecutor — 工具执行管理器(并发分组 + 熔断 + 安全检查)
3
- // ============================================================
4
-
5
- import type { AgentEvent, Message, ToolCall, ToolCallRecord } from '../types.ts';
6
- import type { ToolRegistry } from '../tool/registry.ts';
7
- import type { ToolContext, ToolDefinition } from '../tool/types.ts';
8
- import type { SecurityGuard } from '../security/guard.ts';
9
- import type { HookEvent, HookContext, HookResult } from '../hooks/types.ts';
10
- import type { Middleware } from '../middleware/types.ts';
11
- import type { HistoryManager } from './history-manager.ts';
12
-
13
- /** 工具执行配置 */
14
- export interface ToolExecutorConfig {
15
- /** Tool Registry */
16
- toolRegistry: ToolRegistry;
17
- /** 安全守卫(可选) */
18
- securityGuard?: SecurityGuard;
19
- /** 单工具执行超时(毫秒) */
20
- toolTimeout: number;
21
- /** Hook 执行器 */
22
- runHooks: (event: HookEvent, ctx: HookContext) => Promise<HookResult[]>;
23
- /** 中间件工具阶段执行器 */
24
- runMiddlewareToolPhase: (phase: 'onToolBefore' | 'onToolAfter', ctx: HookContext) => Promise<HookResult[]>;
25
- /** 事件创建辅助 */
26
- createEvent: (sessionId: string, event: Record<string, unknown>) => AgentEvent;
27
- /** 历史管理器 */
28
- historyManager: HistoryManager;
29
- /** 中间件列表 */
30
- getMiddleware: () => Middleware[] | undefined;
31
- }
32
-
33
- /** 工具并发执行分组 */
34
- interface ToolCallGroup {
35
- concurrent: boolean;
36
- calls: ToolCall[];
37
- }
38
-
39
- /** 工具执行结果 */
40
- export interface ToolExecResult {
41
- result: string;
42
- isError: boolean;
43
- actualArgs: Record<string, unknown>;
44
- duration: number;
45
- call: ToolCall;
46
- }
47
-
48
- /** LoopState 接口(与 Engine 交互的最小契约) */
49
- export interface ToolLoopState {
50
- sessionId: string;
51
- messages: Message[];
52
- toolContext: ToolContext;
53
- internalAbort: AbortController;
54
- iteration: number;
55
- toolCallRecords: ToolCallRecord[];
56
- consecutiveToolFailures: Map<string, number>;
57
- }
58
-
59
- /**
60
- * 工具执行管理器
61
- *
62
- * 职责:
63
- * - 按并发属性分组执行 tool_calls
64
- * - 串行/并行执行 + 超时保护
65
- * - 熔断器(连续失败自动阻断)
66
- * - 安全检查(execute_command)
67
- * - Hook/Middleware 生命周期集成
68
- */
69
- export class AgentToolExecutor {
70
- private config: ToolExecutorConfig;
71
-
72
- /** 连续失败熔断阈值:同一工具连续失败超过此值后自动阻断(降低以加速失败重试终止) */
73
- private static readonly CIRCUIT_BREAKER_THRESHOLD = 2;
74
-
75
- constructor(config: ToolExecutorConfig) {
76
- this.config = config;
77
- }
78
-
79
- /** 执行一批 tool_calls(按并发属性分组) */
80
- async *executeToolCalls(state: ToolLoopState, toolCalls: ToolCall[]): AsyncGenerator<AgentEvent> {
81
- const groups = this.groupByConcurrency(toolCalls);
82
-
83
- for (const group of groups) {
84
- if (state.internalAbort.signal.aborted) break;
85
-
86
- if (group.concurrent && group.calls.length > 1) {
87
- yield* this.executeToolGroupParallel(state, group.calls);
88
- } else {
89
- for (const call of group.calls) {
90
- if (state.internalAbort.signal.aborted) break;
91
- yield* this.executeOneToolCall(state, call);
92
- }
93
- }
94
- }
95
- }
96
-
97
- // ---- 内部方法 ----
98
-
99
- /** 按并发属性将 tool_calls 分组 */
100
- private groupByConcurrency(toolCalls: ToolCall[]): ToolCallGroup[] {
101
- const groups: ToolCallGroup[] = [];
102
- let currentGroup: ToolCall[] = [];
103
- let currentConcurrent = false;
104
-
105
- for (const call of toolCalls) {
106
- const tool = this.config.toolRegistry.get(call.function.name);
107
- const isConcurrent = tool?.concurrent ?? false;
108
-
109
- if (currentGroup.length === 0) {
110
- currentConcurrent = isConcurrent;
111
- currentGroup.push(call);
112
- } else if (isConcurrent === currentConcurrent) {
113
- currentGroup.push(call);
114
- } else {
115
- groups.push({ concurrent: currentConcurrent, calls: currentGroup });
116
- currentGroup = [call];
117
- currentConcurrent = isConcurrent;
118
- }
119
- }
120
- if (currentGroup.length > 0) {
121
- groups.push({ concurrent: currentConcurrent, calls: currentGroup });
122
- }
123
- return groups;
124
- }
125
-
126
- /** 并行执行一组工具(按顺序推送事件和结果) */
127
- private async *executeToolGroupParallel(state: ToolLoopState, calls: ToolCall[]): AsyncGenerator<AgentEvent> {
128
- // 先解析所有参数并推送 tool_call 事件
129
- const parsedArgs = calls.map(call => {
130
- let args: Record<string, unknown>;
131
- try { args = JSON.parse(call.function.arguments); } catch { args = {}; }
132
- return { call, args };
133
- });
134
- for (const { call, args } of parsedArgs) {
135
- yield this.config.createEvent(state.sessionId, { type: 'tool_call', tool: call.function.name, args, callId: call.id });
136
- }
137
-
138
- // 熔断与可用性检查:过滤掉已被熔断或当前 Agent 未注册的工具
139
- const unavailable = parsedArgs.filter(({ call }) => !this.config.toolRegistry.has(call.function.name));
140
- for (const { call, args } of unavailable) {
141
- yield* this.emitUnavailableToolResult(state, call, args);
142
- }
143
-
144
- const available = parsedArgs.filter(({ call }) => this.config.toolRegistry.has(call.function.name));
145
- const executable = available.filter(({ call }) => !this.isCircuitBroken(state, call.function.name));
146
- const circuitBroken = available.filter(({ call }) => this.isCircuitBroken(state, call.function.name));
147
-
148
- // 被熔断的工具:直接推送阻断结果
149
- for (const { call, args } of circuitBroken) {
150
- const failCount = state.consecutiveToolFailures.get(call.function.name) || 0;
151
- const result = `CIRCUIT_BREAKER: ${call.function.name} has failed ${failCount} consecutive times. ` +
152
- `STOP calling this tool with the same approach. Fix your parameters or use a different tool.`;
153
- yield this.config.createEvent(state.sessionId, { type: 'tool_result', tool: call.function.name, result, isError: true, duration: 0, callId: call.id });
154
- const toolMessage: Message = { role: 'tool', tool_call_id: call.id, content: result };
155
- state.messages.push(toolMessage);
156
- this.config.historyManager.addHistory(state.sessionId, toolMessage);
157
- state.toolCallRecords.push({ callId: call.id, tool: call.function.name, args, result, isError: true, duration: 0, timestamp: Date.now() });
158
- }
159
-
160
- // 并行执行剩余未被熔断的工具
161
- const results = executable.length > 0
162
- ? await Promise.all(
163
- executable.map(({ call, args }) => this.runWithTimeout(state, call, args))
164
- )
165
- : [];
166
-
167
- // 按顺序推送结果并同步到历史
168
- for (const { result, isError, actualArgs, duration, call } of results) {
169
- const afterResults = await this.config.runHooks('after_tool', {
170
- sessionId: state.sessionId,
171
- iteration: state.iteration,
172
- tool: call.function.name,
173
- args: actualArgs,
174
- result,
175
- isError,
176
- duration,
177
- });
178
- const inject = afterResults.find(r => r.inject)?.inject;
179
- const finalResult = inject ? `${result}\n${inject}` : result;
180
-
181
- yield this.config.createEvent(state.sessionId, { type: 'tool_result', tool: call.function.name, result, isError, duration, callId: call.id });
182
-
183
- const sanitizedResult = this.config.securityGuard
184
- ? this.config.securityGuard.sanitizeCredentials(finalResult)
185
- : finalResult;
186
- const truncatedResult = this.config.historyManager.processToolOutput(sanitizedResult, call.id, call.function.name, state.sessionId);
187
- const toolMessage: Message = { role: 'tool', tool_call_id: call.id, content: truncatedResult };
188
- state.messages.push(toolMessage);
189
- this.config.historyManager.addHistory(state.sessionId, toolMessage);
190
- state.toolCallRecords.push({ callId: call.id, tool: call.function.name, args: actualArgs, result, isError, duration, timestamp: Date.now() });
191
- this.updateFailureCount(state, call.function.name, isError);
192
- }
193
- }
194
-
195
- /** 串行执行单个工具调用(含安全检查 + Hooks) */
196
- private async *executeOneToolCall(state: ToolLoopState, call: ToolCall): AsyncGenerator<AgentEvent> {
197
- let args: Record<string, unknown>;
198
- let jsonParseFailed = false;
199
- try { args = JSON.parse(call.function.arguments); } catch { args = {}; jsonParseFailed = true; }
200
-
201
- // run_script 截断抢救:从截断的 JSON 中提取 code 字段并尝试修复执行
202
- if (jsonParseFailed && call.function.name === 'run_script') {
203
- const rawArgs = call.function.arguments || '';
204
- const rescued = this.rescueRunScriptArgs(rawArgs);
205
- if (rescued) {
206
- args = rescued;
207
- jsonParseFailed = false;
208
- }
209
- }
210
-
211
- // write_file / append_file 截断抢救:提取 path 和部分内容并写入
212
- if (jsonParseFailed && (call.function.name === 'write_file' || call.function.name === 'append_file')) {
213
- const rawArgs = call.function.arguments || '';
214
- const rescued = this.rescueWriteFileArgs(rawArgs);
215
- if (rescued) {
216
- args = rescued;
217
- jsonParseFailed = false;
218
- }
219
- }
220
-
221
- // delegate_task 截断抢救:从截断的 JSON 中提取 agent + task(即使不完整也可用)
222
- if (jsonParseFailed && call.function.name === 'delegate_task') {
223
- const rawArgs = call.function.arguments || '';
224
- const rescued = this.rescueDelegateTaskArgs(rawArgs);
225
- if (rescued) {
226
- args = rescued;
227
- jsonParseFailed = false;
228
- }
229
- }
230
-
231
- yield this.config.createEvent(state.sessionId, { type: 'tool_call', tool: call.function.name, args, callId: call.id });
232
-
233
- if (!this.config.toolRegistry.has(call.function.name)) {
234
- yield* this.emitUnavailableToolResult(state, call, args);
235
- return;
236
- }
237
-
238
- // 空参数/截断参数早期检测
239
- const argKeys = Object.keys(args);
240
- const argsEffectivelyEmpty = argKeys.length === 0 || (argKeys.length === 1 && args[argKeys[0]] === '');
241
- const toolName = call.function.name;
242
- const isDocTool = ['create_presentation', 'create_document', 'create_pdf'].includes(toolName);
243
- const docPayloadKey = toolName === 'create_presentation' ? 'slides' : 'blocks';
244
- const docArgsIncomplete = isDocTool && !!args.title && !args.json_file && (!Array.isArray(args[docPayloadKey]) || (args[docPayloadKey] as unknown[]).length === 0);
245
- if (argsEffectivelyEmpty || docArgsIncomplete) {
246
- const toolDef = this.config.toolRegistry.get(call.function.name);
247
- const required = (toolDef?.definition?.function?.parameters as any)?.required as string[] | undefined;
248
- if ((required && required.length > 0) || docArgsIncomplete) {
249
- const rawArgs = (call.function.arguments || '').trim();
250
- const rawArgLength = (call as any)._rawArgLength ?? rawArgs.length;
251
- const isTruncated = (jsonParseFailed || docArgsIncomplete) && rawArgLength > 200;
252
- let result: string;
253
-
254
- if (isTruncated) {
255
- const isFileWrite = ['write_file', 'append_file'].includes(toolName);
256
- const isRunScript = toolName === 'run_script';
257
- const lines: string[] = [
258
- `TRUNCATED_PARAMS_ERROR: ${toolName} parameters were too long (${rawArgLength} chars, JSON truncated or incomplete).`,
259
- '',
260
- ];
261
-
262
- if (isDocTool) {
263
- const rootKey = toolName === 'create_presentation' ? 'slides' : 'blocks';
264
- const firstItemType = toolName === 'create_presentation' ? 'cover' : 'heading';
265
- const nextItemType = toolName === 'create_presentation' ? 'content' : 'paragraph';
266
- lines.push(
267
- `RECOMMENDED — use json_file + append_file strategy:`,
268
- ` 1. write_file({ path: "data.json", content: '{"${rootKey}": [' })`,
269
- ` 2. append_file({ path: "data.json", content: '{"type":"${firstItemType}","title":"..."},' })`,
270
- ` 3. append_file({ path: "data.json", content: '{"type":"${nextItemType}","title":"..."},' })`,
271
- ` ... repeat for each ${rootKey.slice(0, -1)} ...`,
272
- ` N. append_file({ path: "data.json", content: '], "theme": "professional"}' })`,
273
- ` N+1. ${toolName}({ title: "My Title", json_file: "data.json" })`,
274
- '',
275
- 'Each write_file/append_file content chunk should be under 3000 chars.',
276
- '',
277
- );
278
- } else if (isFileWrite) {
279
- lines.push(
280
- 'RECOMMENDED — split content across multiple calls:',
281
- ' 1. write_file({ path: "script.cjs", content: "<first ~2500 chars>" })',
282
- ' 2. append_file({ path: "script.cjs", content: "<next ~2500 chars>" })',
283
- ' 3. append_file({ path: "script.cjs", content: "<next ~2500 chars>" })',
284
- ' ... repeat until complete ...',
285
- '',
286
- 'Each chunk MUST be under 3000 characters. Count your characters!',
287
- '',
288
- );
289
- } else if (isRunScript) {
290
- lines.push(
291
- 'RECOMMENDED — use Two-Step approach for long scripts:',
292
- ' Step 1: write_file({ path: "generate.cjs", content: "<first ~2500 chars of script>" })',
293
- ' Step 2: append_file({ path: "generate.cjs", content: "<next ~2500 chars>" })',
294
- ' ... repeat append_file until script is complete ...',
295
- ' Final: run_script({ language: "nodejs", code: "require(require(\'path\').join(process.cwd(),\'generate.cjs\'));", timeout: 60000 })',
296
- '',
297
- 'Each write_file/append_file chunk MUST be under 3000 chars. The run_script `code` param MUST be under 3000 chars.',
298
- '',
299
- );
300
- } else if (toolName === 'execute_command') {
301
- lines.push(
302
- 'Your command is TOO LONG for a single tool call.',
303
- '',
304
- 'Do NOT use heredoc (cat >> file << EOF) to write scripts. Use the Two-Step approach:',
305
- ' Step 1: write_file({ path: "script.cjs", content: "<your FULL script>" })',
306
- ' Step 2: execute_command({ command: "node script.cjs", timeout: 60000 })',
307
- '',
308
- 'For appending: use append_file instead of cat >> heredoc.',
309
- '',
310
- );
311
- } else if (toolName === 'show_widget') {
312
- lines.push(
313
- 'Your HTML is TOO LONG for a single tool call.',
314
- '',
315
- 'Use the html_file approach for large widgets (ECharts dashboards, etc.):',
316
- ' Step 1: write_file({ path: "widget.html", content: "<your full HTML>" })',
317
- ' Step 2: show_widget({ html_file: "widget.html", title: "Dashboard" })',
318
- '',
319
- 'If HTML exceeds write_file limit, use append_file to build it incrementally.',
320
- '',
321
- );
322
- } else if (toolName === 'delegate_task') {
323
- lines.push(
324
- 'Your task description is TOO LONG for a single delegate_task call.',
325
- '',
326
- 'Strategy — write task details to a file, then reference it:',
327
- ' Step 1: write_file({ path: "task_brief.md", content: "<detailed task description + data>" })',
328
- ' Step 2: delegate_task({ agent: "<name>", task: "Read task_brief.md and execute: <short summary>" })',
329
- '',
330
- 'The sub-agent has read_file access and can load the full task from the file.',
331
- '',
332
- );
333
- } else {
334
- lines.push(
335
- 'Your content is TOO LONG for a single tool call.',
336
- '',
337
- 'Strategies:',
338
- ' 1. write_file + append_file: Split content into <3000 char chunks',
339
- ' 2. Write a more compact script (fewer items, less formatting)',
340
- '',
341
- );
342
- }
343
-
344
- lines.push('DO NOT retry the same approach — it will fail again.');
345
- result = lines.join('\n');
346
- } else {
347
- result = [
348
- `EMPTY_PARAMS_ERROR: ${call.function.name} was called with empty or invalid parameters.`,
349
- rawArgs ? ` Raw arguments: "${rawArgs.slice(0, 200)}"` : ' No arguments were received.',
350
- '',
351
- `Required parameters: ${required.join(', ')}`,
352
- '',
353
- 'You MUST include ALL parameters. If content is long, use the Two-Step approach:',
354
- ' Step 1: write_file({ path: "generate.cjs", content: "<your FULL script>" })',
355
- ' Step 2: run_script({ language: "nodejs", code: "require(require(\'path\').join(process.cwd(),\'generate.cjs\'));", timeout: 60000 })',
356
- ].join('\n');
357
- }
358
-
359
- yield this.config.createEvent(state.sessionId, { type: 'tool_result', tool: call.function.name, result, isError: true, duration: 0, callId: call.id });
360
- const toolMessage: Message = { role: 'tool', tool_call_id: call.id, content: result };
361
- state.messages.push(toolMessage);
362
- this.config.historyManager.addHistory(state.sessionId, toolMessage);
363
- state.toolCallRecords.push({ callId: call.id, tool: call.function.name, args, result, isError: true, duration: 0, timestamp: Date.now() });
364
- this.updateFailureCount(state, call.function.name, true);
365
- return;
366
- }
367
- }
368
-
369
- // 熔断检查
370
- if (this.isCircuitBroken(state, call.function.name)) {
371
- const failCount = state.consecutiveToolFailures.get(call.function.name) || 0;
372
- const result = `CIRCUIT_BREAKER: ${call.function.name} has failed ${failCount} consecutive times. ` +
373
- `STOP calling this tool with the same approach. ` +
374
- `If your content is too long for tool parameters, SPLIT it: use multiple execute_command calls with "cat >>" to append, ` +
375
- `or write a much shorter script. Review ALL error messages above for specific guidance.`;
376
- yield this.config.createEvent(state.sessionId, { type: 'tool_result', tool: call.function.name, result, isError: true, duration: 0, callId: call.id });
377
-
378
- const toolMessage: Message = { role: 'tool', tool_call_id: call.id, content: result };
379
- state.messages.push(toolMessage);
380
- this.config.historyManager.addHistory(state.sessionId, toolMessage);
381
- state.toolCallRecords.push({ callId: call.id, tool: call.function.name, args, result, isError: true, duration: 0, timestamp: Date.now() });
382
- return;
383
- }
384
-
385
- // 安全检查(execute_command)
386
- let actualArgs = args;
387
- if (call.function.name === 'execute_command' && this.config.securityGuard && args.command) {
388
- const check = this.config.securityGuard.sanitize(args.command as string);
389
- if (!check.safe) {
390
- const result = check.reason || 'BLOCKED: Command rejected by security policy';
391
- yield this.config.createEvent(state.sessionId, { type: 'tool_result', tool: call.function.name, result, isError: true, duration: 0, callId: call.id });
392
-
393
- const toolMessage: Message = { role: 'tool', tool_call_id: call.id, content: result };
394
- state.messages.push(toolMessage);
395
- this.config.historyManager.addHistory(state.sessionId, toolMessage);
396
- state.toolCallRecords.push({ callId: call.id, tool: call.function.name, args, result, isError: true, duration: 0, timestamp: Date.now() });
397
- return;
398
- }
399
- if (check.rewritten) actualArgs = { ...args, command: check.rewritten };
400
- }
401
-
402
- // Hook + Middleware: before_tool
403
- const hookCtx: HookContext = {
404
- sessionId: state.sessionId,
405
- iteration: state.iteration,
406
- tool: call.function.name,
407
- args: actualArgs,
408
- };
409
- const beforeResults = await this.config.runHooks('before_tool', hookCtx);
410
- const mwBeforeResults = await this.config.runMiddlewareToolPhase('onToolBefore', hookCtx);
411
- const allBefore = [...beforeResults, ...mwBeforeResults];
412
- const blocked = allBefore.find(r => r.block);
413
- if (blocked) {
414
- const result = blocked.reason || 'Blocked by hook';
415
- yield this.config.createEvent(state.sessionId, { type: 'tool_result', tool: call.function.name, result, isError: true, duration: 0, callId: call.id });
416
-
417
- const toolMessage: Message = { role: 'tool', tool_call_id: call.id, content: result };
418
- state.messages.push(toolMessage);
419
- this.config.historyManager.addHistory(state.sessionId, toolMessage);
420
- state.toolCallRecords.push({ callId: call.id, tool: call.function.name, args: actualArgs, result, isError: true, duration: 0, timestamp: Date.now() });
421
- return;
422
- }
423
- const modified = allBefore.find(r => r.modify);
424
- if (modified?.modify) actualArgs = { ...actualArgs, ...modified.modify };
425
-
426
- // 执行工具(带超时)
427
- const execResult = await this.runWithTimeout(state, call, actualArgs);
428
- const { result, isError, duration } = execResult;
429
-
430
- // Hook + Middleware: after_tool
431
- const afterHookCtx: HookContext = {
432
- sessionId: state.sessionId,
433
- iteration: state.iteration,
434
- traceId: state.toolContext.custom?.traceId as string | undefined,
435
- tool: call.function.name,
436
- args: actualArgs,
437
- result,
438
- isError,
439
- duration,
440
- };
441
- const afterResults = await this.config.runHooks('after_tool', afterHookCtx);
442
- const mwAfterResults = await this.config.runMiddlewareToolPhase('onToolAfter', afterHookCtx);
443
- const allAfter = [...afterResults, ...mwAfterResults];
444
- const inject = allAfter.find(r => r.inject)?.inject;
445
- const finalResult = inject ? `${result}\n${inject}` : result;
446
-
447
- yield this.config.createEvent(state.sessionId, { type: 'tool_result', tool: call.function.name, result, isError, duration, callId: call.id });
448
-
449
- const sanitizedResult = this.config.securityGuard
450
- ? this.config.securityGuard.sanitizeCredentials(finalResult)
451
- : finalResult;
452
- const truncatedResult = this.config.historyManager.processToolOutput(sanitizedResult, call.id, call.function.name, state.sessionId);
453
- const toolMessage: Message = { role: 'tool', tool_call_id: call.id, content: truncatedResult };
454
- state.messages.push(toolMessage);
455
- this.config.historyManager.addHistory(state.sessionId, toolMessage);
456
- state.toolCallRecords.push({ callId: call.id, tool: call.function.name, args: actualArgs, result, isError, duration, timestamp: Date.now() });
457
- this.updateFailureCount(state, call.function.name, isError);
458
- }
459
-
460
- /** 带超时的工具执行 */
461
- private async runWithTimeout(state: ToolLoopState, call: ToolCall, args: Record<string, unknown>): Promise<ToolExecResult> {
462
- const isDelegate = call.function.name === 'delegate_task';
463
- const timeout = isDelegate
464
- ? Math.max(this.config.toolTimeout * 30, 900000)
465
- : this.config.toolTimeout;
466
- const start = Date.now();
467
-
468
- // 为 delegate_task 创建子 AbortController:超时或父级 abort 时能中止子 Agent
469
- const childAbort = new AbortController();
470
- const parentSignal = state.toolContext.abortSignal;
471
- const onParentAbort = () => childAbort.abort();
472
- if (parentSignal?.aborted) {
473
- childAbort.abort();
474
- } else if (parentSignal) {
475
- parentSignal.addEventListener('abort', onParentAbort, { once: true });
476
- }
477
-
478
- // 超时定时器:触发时同时 abort 子 Agent(防止子 Agent 泄漏)
479
- let timeoutId: ReturnType<typeof setTimeout>;
480
- const timeoutPromise = new Promise<string>((_, reject) => {
481
- timeoutId = setTimeout(() => {
482
- childAbort.abort(); // 中止子 Agent 执行
483
- reject(new Error(`Tool execution timeout (${timeout}ms)`));
484
- }, timeout);
485
- });
486
-
487
- const ctxWithCallId: ToolContext = {
488
- ...state.toolContext,
489
- currentToolCallId: call.id,
490
- abortSignal: childAbort.signal,
491
- };
492
-
493
- try {
494
- const result = await Promise.race([
495
- this.config.toolRegistry.execute(call.function.name, args, ctxWithCallId),
496
- timeoutPromise,
497
- ]);
498
- clearTimeout(timeoutId);
499
- return { result, isError: false, actualArgs: args, duration: Date.now() - start, call };
500
- } catch (err: any) {
501
- clearTimeout(timeoutId);
502
- const errorMsg = `Error: ${err.message || err}`;
503
- if (isDelegate) {
504
- console.error(`[ToolExecutor] delegate_task failed after ${Date.now() - start}ms: ${err.message || err}`);
505
- }
506
- await this.config.runHooks('on_error', {
507
- sessionId: state.sessionId,
508
- iteration: state.iteration,
509
- tool: call.function.name,
510
- error: err.message || String(err),
511
- recoverable: true,
512
- });
513
- return { result: errorMsg, isError: true, actualArgs: args, duration: Date.now() - start, call };
514
- } finally {
515
- if (parentSignal) parentSignal.removeEventListener('abort', onParentAbort);
516
- }
517
- }
518
-
519
- private async *emitUnavailableToolResult(
520
- state: ToolLoopState,
521
- call: ToolCall,
522
- args: Record<string, unknown>,
523
- ): AsyncGenerator<AgentEvent> {
524
- const availableNames = this.config.toolRegistry.listNames();
525
- const mcpNames = availableNames.filter(name => name.startsWith('mcp_')).slice(0, 20);
526
- const otherNames = availableNames.filter(name => !name.startsWith('mcp_')).slice(0, 30);
527
- const result = [
528
- `UNAVAILABLE_TOOL: ${call.function.name} is not registered in the current Agent runtime.`,
529
- 'Do NOT call this tool again in this conversation.',
530
- 'This usually means the tool is not assigned to the current application/agent, the connector is not authorized, or an older conversation history referenced a stale tool name.',
531
- '',
532
- mcpNames.length > 0 ? `Available MCP tools: ${mcpNames.join(', ')}` : 'Available MCP tools: none',
533
- otherNames.length > 0 ? `Available non-MCP tools: ${otherNames.join(', ')}` : 'Available non-MCP tools: none',
534
- '',
535
- 'Use only one of the available tool names above, or explain to the user that the requested connector/tool is not available in the current application.',
536
- ].join('\n');
537
-
538
- yield this.config.createEvent(state.sessionId, { type: 'tool_result', tool: call.function.name, result, isError: true, duration: 0, callId: call.id });
539
- const toolMessage: Message = { role: 'tool', tool_call_id: call.id, content: result };
540
- state.messages.push(toolMessage);
541
- this.config.historyManager.addHistory(state.sessionId, toolMessage);
542
- state.toolCallRecords.push({ callId: call.id, tool: call.function.name, args, result, isError: true, duration: 0, timestamp: Date.now() });
543
- this.updateFailureCount(state, call.function.name, true);
544
- }
545
- /** 检查工具是否被熔断 */
546
- private isCircuitBroken(state: ToolLoopState, toolName: string): boolean {
547
- return (state.consecutiveToolFailures.get(toolName) || 0) >= AgentToolExecutor.CIRCUIT_BREAKER_THRESHOLD;
548
- }
549
-
550
- /** 更新工具连续失败计数 */
551
- private updateFailureCount(state: ToolLoopState, toolName: string, isError: boolean): void {
552
- if (isError) {
553
- state.consecutiveToolFailures.set(toolName, (state.consecutiveToolFailures.get(toolName) || 0) + 1);
554
- } else {
555
- state.consecutiveToolFailures.delete(toolName);
556
- }
557
- }
558
-
559
- /**
560
- * 从截断的 JSON 中抢救 run_script 的参数。
561
- * 当 LLM 生成过长的 code 导致 JSON 被截断时,尝试提取 language 和 code 字段并修复执行。
562
- * 返回 null 表示抢救失败。
563
- */
564
- private rescueRunScriptArgs(rawArgs: string): Record<string, unknown> | null {
565
- if (rawArgs.length < 50) return null;
566
-
567
- try {
568
- // 1. 提取 language(通常在开头,值很短不会截断)
569
- const langMatch = rawArgs.match(/"language"\s*:\s*"(nodejs|python|shell)"/);
570
- const language = langMatch ? langMatch[1] : 'nodejs';
571
-
572
- // 2. 提取 timeout(可选)
573
- const timeoutMatch = rawArgs.match(/"timeout"\s*:\s*(\d+)/);
574
- const timeout = timeoutMatch ? parseInt(timeoutMatch[1], 10) : undefined;
575
-
576
- // 3. 提取 code 字段:找到 "code":" 之后的所有内容
577
- const codeKeyIdx = rawArgs.indexOf('"code"');
578
- if (codeKeyIdx === -1) return null;
579
-
580
- // 找到 "code": 后面的值起始位置(第一个 " 是 key 结束,然后是 :,然后是 value 的开头 ")
581
- const afterKey = rawArgs.slice(codeKeyIdx);
582
- // 匹配 "code" : " 的模式,取 value 开始后的内容
583
- const valStartMatch = afterKey.match(/^"code"\s*:\s*"/);
584
- if (!valStartMatch) return null;
585
-
586
- const codeRawStart = codeKeyIdx + valStartMatch[0].length;
587
- let codeRaw = rawArgs.slice(codeRawStart);
588
-
589
- // 4. 处理 JSON 字符串转义,还原为实际代码
590
- // 按顺序处理:\\ -> \, \" -> ", \n -> newline, \t -> tab, \r -> CR
591
- // 先替换 \\ 为占位符,避免双重替换
592
- const BACKSLASH_PLACEHOLDER = '\x00BS\x00';
593
- codeRaw = codeRaw.replace(/\\\\/g, BACKSLASH_PLACEHOLDER);
594
- codeRaw = codeRaw.replace(/\\"/g, '"');
595
- codeRaw = codeRaw.replace(/\\n/g, '\n');
596
- codeRaw = codeRaw.replace(/\\t/g, '\t');
597
- codeRaw = codeRaw.replace(/\\r/g, '\r');
598
- codeRaw = codeRaw.replace(new RegExp(BACKSLASH_PLACEHOLDER, 'g'), '\\');
599
-
600
- // 5. 如果代码太短(<100字符),可能抢救意义不大
601
- if (codeRaw.trim().length < 20) return null;
602
-
603
- return { language, code: codeRaw, timeout };
604
- } catch {
605
- return null;
606
- }
607
- }
608
-
609
- /**
610
- * 从截断的 JSON 中抢救 delegate_task 的参数。
611
- * delegate_task 的 task 字段可能很长(包含数据、指令),导致 JSON 被截断。
612
- * 抢救策略:提取 agent(短字段,不会被截断)和 task(可能不完整但仍可执行)。
613
- * 返回 null 表示抢救失败。
614
- */
615
- private rescueDelegateTaskArgs(rawArgs: string): Record<string, unknown> | null {
616
- if (rawArgs.length < 50) return null;
617
-
618
- try {
619
- // 1. 提取 agent(通常在开头,值短不会截断)
620
- const agentMatch = rawArgs.match(/"agent"\s*:\s*"([^"]+)"/);
621
- if (!agentMatch) return null;
622
- const agent = agentMatch[1];
623
-
624
- // 2. 提取 role(可选,短字段)
625
- const roleMatch = rawArgs.match(/"role"\s*:\s*"([^"]+)"/);
626
- const role = roleMatch ? roleMatch[1] : undefined;
627
-
628
- // 3. 提取 structured(可选,布尔值)
629
- const structuredMatch = rawArgs.match(/"structured"\s*:\s*(true|false)/);
630
- const structured = structuredMatch ? structuredMatch[1] === 'true' : undefined;
631
-
632
- // 4. 提取 task 字段
633
- const taskKeyIdx = rawArgs.indexOf('"task"');
634
- if (taskKeyIdx === -1) return null;
635
-
636
- const afterKey = rawArgs.slice(taskKeyIdx);
637
- const valStartMatch = afterKey.match(/^"task"\s*:\s*"/);
638
- if (!valStartMatch) return null;
639
-
640
- const taskRawStart = taskKeyIdx + valStartMatch[0].length;
641
- let taskRaw = rawArgs.slice(taskRawStart);
642
-
643
- // 5. 处理 JSON 字符串转义
644
- const BACKSLASH_PLACEHOLDER = '\x00BS\x00';
645
- taskRaw = taskRaw.replace(/\\\\/g, BACKSLASH_PLACEHOLDER);
646
- taskRaw = taskRaw.replace(/\\"/g, '"');
647
- taskRaw = taskRaw.replace(/\\n/g, '\n');
648
- taskRaw = taskRaw.replace(/\\t/g, '\t');
649
- taskRaw = taskRaw.replace(/\\r/g, '\r');
650
- taskRaw = taskRaw.replace(new RegExp(BACKSLASH_PLACEHOLDER, 'g'), '\\');
651
-
652
- // 6. 去除末尾不完整的 JSON 残留
653
- taskRaw = taskRaw.replace(/["}\],\s]*$/, '');
654
-
655
- // 7. task 至少要有一定内容才有意义
656
- if (taskRaw.trim().length < 30) return null;
657
-
658
- const result: Record<string, unknown> = { agent, task: taskRaw };
659
- if (role) result.role = role;
660
- if (structured !== undefined) result.structured = structured;
661
- return result;
662
- } catch {
663
- return null;
664
- }
665
- }
666
-
667
- /**
668
- * 从截断的 JSON 中抢救 write_file / append_file 的参数。
669
- * 当 LLM 生成过长的 content 导致 JSON 被截断时,尝试提取 path 和部分内容并写入。
670
- * 返回 null 表示抢救失败。
671
- */
672
- private rescueWriteFileArgs(rawArgs: string): Record<string, unknown> | null {
673
- if (rawArgs.length < 50) return null;
674
-
675
- try {
676
- // 1. 提取 path 字段(通常在开头,值短不会截断)
677
- const pathMatch = rawArgs.match(/"path"\s*:\s*"([^"]+)"/);
678
- if (!pathMatch) return null;
679
- const filePath = pathMatch[1];
680
-
681
- // 2. 提取 content 字段:找到 "content": 之后的所有内容
682
- const contentKeyIdx = rawArgs.indexOf('"content"');
683
- if (contentKeyIdx === -1) return null;
684
-
685
- const afterKey = rawArgs.slice(contentKeyIdx);
686
- const valStartMatch = afterKey.match(/^"content"\s*:\s*"/);
687
- if (!valStartMatch) return null;
688
-
689
- const contentRawStart = contentKeyIdx + valStartMatch[0].length;
690
- let contentRaw = rawArgs.slice(contentRawStart);
691
-
692
- // 3. 处理 JSON 字符串转义
693
- const BACKSLASH_PLACEHOLDER = '\x00BS\x00';
694
- contentRaw = contentRaw.replace(/\\\\/g, BACKSLASH_PLACEHOLDER);
695
- contentRaw = contentRaw.replace(/\\"/g, '"');
696
- contentRaw = contentRaw.replace(/\\n/g, '\n');
697
- contentRaw = contentRaw.replace(/\\t/g, '\t');
698
- contentRaw = contentRaw.replace(/\\r/g, '\r');
699
- contentRaw = contentRaw.replace(new RegExp(BACKSLASH_PLACEHOLDER, 'g'), '\\');
700
-
701
- // 4. 去除末尾不完整的 JSON(截断的 } 或多余的引号)
702
- // 移除末尾可能的截断残留: 未闭合的 " 或 }
703
- contentRaw = contentRaw.replace(/["}]\s*$/, '');
704
-
705
- // 5. 如果内容太短(<100字符),抢救意义不大
706
- if (contentRaw.trim().length < 100) return null;
707
-
708
- return { path: filePath, content: contentRaw, _rescued: true };
709
- } catch {
710
- return null;
711
- }
712
- }
713
- }