keyring-agent-core 0.2.1 → 0.2.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 (417) hide show
  1. package/dist/index.d.ts +6692 -27
  2. package/dist/index.js +877 -70
  3. package/package.json +6 -4
  4. package/dist/agent/AgentCore.d.ts +0 -256
  5. package/dist/agent/AgentCore.d.ts.map +0 -1
  6. package/dist/agent/AgentCore.js +0 -1093
  7. package/dist/agent/AgentCore.js.map +0 -1
  8. package/dist/agent/QueryRewriter.d.ts +0 -84
  9. package/dist/agent/QueryRewriter.d.ts.map +0 -1
  10. package/dist/agent/QueryRewriter.js +0 -306
  11. package/dist/agent/QueryRewriter.js.map +0 -1
  12. package/dist/agent/Router.d.ts +0 -33
  13. package/dist/agent/Router.d.ts.map +0 -1
  14. package/dist/agent/Router.js +0 -229
  15. package/dist/agent/Router.js.map +0 -1
  16. package/dist/agent/Subagent.d.ts +0 -80
  17. package/dist/agent/Subagent.d.ts.map +0 -1
  18. package/dist/agent/Subagent.js +0 -272
  19. package/dist/agent/Subagent.js.map +0 -1
  20. package/dist/agent/Synthesizer.d.ts +0 -11
  21. package/dist/agent/Synthesizer.d.ts.map +0 -1
  22. package/dist/agent/Synthesizer.js +0 -86
  23. package/dist/agent/Synthesizer.js.map +0 -1
  24. package/dist/agent/chatGraph.d.ts +0 -364
  25. package/dist/agent/chatGraph.d.ts.map +0 -1
  26. package/dist/agent/chatGraph.js +0 -184
  27. package/dist/agent/chatGraph.js.map +0 -1
  28. package/dist/agent/index.d.ts +0 -10
  29. package/dist/agent/index.d.ts.map +0 -1
  30. package/dist/agent/index.js +0 -24
  31. package/dist/agent/index.js.map +0 -1
  32. package/dist/agent/subagents/AiAgent.d.ts +0 -6
  33. package/dist/agent/subagents/AiAgent.d.ts.map +0 -1
  34. package/dist/agent/subagents/AiAgent.js +0 -52
  35. package/dist/agent/subagents/AiAgent.js.map +0 -1
  36. package/dist/agent/subagents/NftAgent.d.ts +0 -6
  37. package/dist/agent/subagents/NftAgent.d.ts.map +0 -1
  38. package/dist/agent/subagents/NftAgent.js +0 -79
  39. package/dist/agent/subagents/NftAgent.js.map +0 -1
  40. package/dist/agent/subagents/PoolAgent.d.ts +0 -6
  41. package/dist/agent/subagents/PoolAgent.d.ts.map +0 -1
  42. package/dist/agent/subagents/PoolAgent.js +0 -184
  43. package/dist/agent/subagents/PoolAgent.js.map +0 -1
  44. package/dist/agent/subagents/PoolSubgraphAgent.d.ts +0 -6
  45. package/dist/agent/subagents/PoolSubgraphAgent.d.ts.map +0 -1
  46. package/dist/agent/subagents/PoolSubgraphAgent.js +0 -117
  47. package/dist/agent/subagents/PoolSubgraphAgent.js.map +0 -1
  48. package/dist/agent/subagents/TokenAgent.d.ts +0 -6
  49. package/dist/agent/subagents/TokenAgent.d.ts.map +0 -1
  50. package/dist/agent/subagents/TokenAgent.js +0 -76
  51. package/dist/agent/subagents/TokenAgent.js.map +0 -1
  52. package/dist/agent/subagents/WalletActionAgent.d.ts +0 -6
  53. package/dist/agent/subagents/WalletActionAgent.d.ts.map +0 -1
  54. package/dist/agent/subagents/WalletActionAgent.js +0 -55
  55. package/dist/agent/subagents/WalletActionAgent.js.map +0 -1
  56. package/dist/agent/subagents/WalletAgent.d.ts +0 -6
  57. package/dist/agent/subagents/WalletAgent.d.ts.map +0 -1
  58. package/dist/agent/subagents/WalletAgent.js +0 -93
  59. package/dist/agent/subagents/WalletAgent.js.map +0 -1
  60. package/dist/agent/subagents/index.d.ts +0 -34
  61. package/dist/agent/subagents/index.d.ts.map +0 -1
  62. package/dist/agent/subagents/index.js +0 -69
  63. package/dist/agent/subagents/index.js.map +0 -1
  64. package/dist/constants/abi.d.ts +0 -551
  65. package/dist/constants/abi.d.ts.map +0 -1
  66. package/dist/constants/abi.js +0 -690
  67. package/dist/constants/abi.js.map +0 -1
  68. package/dist/functions/pool.d.ts +0 -25
  69. package/dist/functions/pool.d.ts.map +0 -1
  70. package/dist/functions/pool.js +0 -151
  71. package/dist/functions/pool.js.map +0 -1
  72. package/dist/functions/web3.d.ts +0 -31
  73. package/dist/functions/web3.d.ts.map +0 -1
  74. package/dist/functions/web3.js +0 -232
  75. package/dist/functions/web3.js.map +0 -1
  76. package/dist/index.d.ts.map +0 -1
  77. package/dist/index.js.map +0 -1
  78. package/dist/llm/GeminiProvider.d.ts +0 -16
  79. package/dist/llm/GeminiProvider.d.ts.map +0 -1
  80. package/dist/llm/GeminiProvider.js +0 -329
  81. package/dist/llm/GeminiProvider.js.map +0 -1
  82. package/dist/llm/index.d.ts +0 -2
  83. package/dist/llm/index.d.ts.map +0 -1
  84. package/dist/llm/index.js +0 -6
  85. package/dist/llm/index.js.map +0 -1
  86. package/dist/memory/ChatHistory.d.ts +0 -83
  87. package/dist/memory/ChatHistory.d.ts.map +0 -1
  88. package/dist/memory/ChatHistory.js +0 -143
  89. package/dist/memory/ChatHistory.js.map +0 -1
  90. package/dist/memory/KnowledgeBase.d.ts +0 -38
  91. package/dist/memory/KnowledgeBase.d.ts.map +0 -1
  92. package/dist/memory/KnowledgeBase.js +0 -139
  93. package/dist/memory/KnowledgeBase.js.map +0 -1
  94. package/dist/memory/Summarizer.d.ts +0 -12
  95. package/dist/memory/Summarizer.d.ts.map +0 -1
  96. package/dist/memory/Summarizer.js +0 -39
  97. package/dist/memory/Summarizer.js.map +0 -1
  98. package/dist/memory/UpstashKnowledgeBase.d.ts +0 -124
  99. package/dist/memory/UpstashKnowledgeBase.d.ts.map +0 -1
  100. package/dist/memory/UpstashKnowledgeBase.js +0 -152
  101. package/dist/memory/UpstashKnowledgeBase.js.map +0 -1
  102. package/dist/memory/historyUtils.d.ts +0 -58
  103. package/dist/memory/historyUtils.d.ts.map +0 -1
  104. package/dist/memory/historyUtils.js +0 -190
  105. package/dist/memory/historyUtils.js.map +0 -1
  106. package/dist/memory/index.d.ts +0 -7
  107. package/dist/memory/index.d.ts.map +0 -1
  108. package/dist/memory/index.js +0 -12
  109. package/dist/memory/index.js.map +0 -1
  110. package/dist/memory/ingestKnowledgeBase.d.ts +0 -17
  111. package/dist/memory/ingestKnowledgeBase.d.ts.map +0 -1
  112. package/dist/memory/ingestKnowledgeBase.js +0 -35
  113. package/dist/memory/ingestKnowledgeBase.js.map +0 -1
  114. package/dist/services/MoralisService.d.ts +0 -1328
  115. package/dist/services/MoralisService.d.ts.map +0 -1
  116. package/dist/services/MoralisService.js +0 -1239
  117. package/dist/services/MoralisService.js.map +0 -1
  118. package/dist/services/PantographService.d.ts +0 -98
  119. package/dist/services/PantographService.d.ts.map +0 -1
  120. package/dist/services/PantographService.js +0 -451
  121. package/dist/services/PantographService.js.map +0 -1
  122. package/dist/services/PoolService.d.ts +0 -238
  123. package/dist/services/PoolService.d.ts.map +0 -1
  124. package/dist/services/PoolService.js +0 -485
  125. package/dist/services/PoolService.js.map +0 -1
  126. package/dist/services/UniswapService.d.ts +0 -289
  127. package/dist/services/UniswapService.d.ts.map +0 -1
  128. package/dist/services/UniswapService.js +0 -585
  129. package/dist/services/UniswapService.js.map +0 -1
  130. package/dist/services/UniswapSubgraphService.d.ts +0 -144
  131. package/dist/services/UniswapSubgraphService.d.ts.map +0 -1
  132. package/dist/services/UniswapSubgraphService.js +0 -606
  133. package/dist/services/UniswapSubgraphService.js.map +0 -1
  134. package/dist/services/rpc.d.ts +0 -35
  135. package/dist/services/rpc.d.ts.map +0 -1
  136. package/dist/services/rpc.js +0 -110
  137. package/dist/services/rpc.js.map +0 -1
  138. package/dist/services/swap/BaseSwapService.d.ts +0 -17
  139. package/dist/services/swap/BaseSwapService.d.ts.map +0 -1
  140. package/dist/services/swap/BaseSwapService.js +0 -19
  141. package/dist/services/swap/BaseSwapService.js.map +0 -1
  142. package/dist/services/swap/DebridgeAdapter.d.ts +0 -37
  143. package/dist/services/swap/DebridgeAdapter.d.ts.map +0 -1
  144. package/dist/services/swap/DebridgeAdapter.js +0 -243
  145. package/dist/services/swap/DebridgeAdapter.js.map +0 -1
  146. package/dist/services/swap/RelayAdapter.d.ts +0 -19
  147. package/dist/services/swap/RelayAdapter.d.ts.map +0 -1
  148. package/dist/services/swap/RelayAdapter.js +0 -189
  149. package/dist/services/swap/RelayAdapter.js.map +0 -1
  150. package/dist/services/swap/SwapServiceFactory.d.ts +0 -25
  151. package/dist/services/swap/SwapServiceFactory.d.ts.map +0 -1
  152. package/dist/services/swap/SwapServiceFactory.js +0 -79
  153. package/dist/services/swap/SwapServiceFactory.js.map +0 -1
  154. package/dist/services/swap/addresses.d.ts +0 -3
  155. package/dist/services/swap/addresses.d.ts.map +0 -1
  156. package/dist/services/swap/addresses.js +0 -68
  157. package/dist/services/swap/addresses.js.map +0 -1
  158. package/dist/services/swap/affiliate.d.ts +0 -17
  159. package/dist/services/swap/affiliate.d.ts.map +0 -1
  160. package/dist/services/swap/affiliate.js +0 -126
  161. package/dist/services/swap/affiliate.js.map +0 -1
  162. package/dist/services/swap/config.d.ts +0 -9
  163. package/dist/services/swap/config.d.ts.map +0 -1
  164. package/dist/services/swap/config.js +0 -19
  165. package/dist/services/swap/config.js.map +0 -1
  166. package/dist/services/swap/index.d.ts +0 -10
  167. package/dist/services/swap/index.d.ts.map +0 -1
  168. package/dist/services/swap/index.js +0 -22
  169. package/dist/services/swap/index.js.map +0 -1
  170. package/dist/services/swap/types.d.ts +0 -89
  171. package/dist/services/swap/types.d.ts.map +0 -1
  172. package/dist/services/swap/types.js +0 -6
  173. package/dist/services/swap/types.js.map +0 -1
  174. package/dist/tools/BaseTool.d.ts +0 -15
  175. package/dist/tools/BaseTool.d.ts.map +0 -1
  176. package/dist/tools/BaseTool.js +0 -35
  177. package/dist/tools/BaseTool.js.map +0 -1
  178. package/dist/tools/ToolRegistry.d.ts +0 -27
  179. package/dist/tools/ToolRegistry.d.ts.map +0 -1
  180. package/dist/tools/ToolRegistry.js +0 -80
  181. package/dist/tools/ToolRegistry.js.map +0 -1
  182. package/dist/tools/builtin/ai/GeminiSearchAiTool.d.ts +0 -36
  183. package/dist/tools/builtin/ai/GeminiSearchAiTool.d.ts.map +0 -1
  184. package/dist/tools/builtin/ai/GeminiSearchAiTool.js +0 -91
  185. package/dist/tools/builtin/ai/GeminiSearchAiTool.js.map +0 -1
  186. package/dist/tools/builtin/ai/index.d.ts +0 -3
  187. package/dist/tools/builtin/ai/index.d.ts.map +0 -1
  188. package/dist/tools/builtin/ai/index.js +0 -6
  189. package/dist/tools/builtin/ai/index.js.map +0 -1
  190. package/dist/tools/builtin/index.d.ts +0 -8
  191. package/dist/tools/builtin/index.d.ts.map +0 -1
  192. package/dist/tools/builtin/index.js +0 -24
  193. package/dist/tools/builtin/index.js.map +0 -1
  194. package/dist/tools/builtin/nft/BaseNftMessageTool.d.ts +0 -35
  195. package/dist/tools/builtin/nft/BaseNftMessageTool.d.ts.map +0 -1
  196. package/dist/tools/builtin/nft/BaseNftMessageTool.js +0 -45
  197. package/dist/tools/builtin/nft/BaseNftMessageTool.js.map +0 -1
  198. package/dist/tools/builtin/nft/NFTContractInfoTool.d.ts +0 -15
  199. package/dist/tools/builtin/nft/NFTContractInfoTool.d.ts.map +0 -1
  200. package/dist/tools/builtin/nft/NFTContractInfoTool.js +0 -19
  201. package/dist/tools/builtin/nft/NFTContractInfoTool.js.map +0 -1
  202. package/dist/tools/builtin/nft/NFTMetadataTool.d.ts +0 -15
  203. package/dist/tools/builtin/nft/NFTMetadataTool.d.ts.map +0 -1
  204. package/dist/tools/builtin/nft/NFTMetadataTool.js +0 -20
  205. package/dist/tools/builtin/nft/NFTMetadataTool.js.map +0 -1
  206. package/dist/tools/builtin/nft/SendNftTool.d.ts +0 -14
  207. package/dist/tools/builtin/nft/SendNftTool.d.ts.map +0 -1
  208. package/dist/tools/builtin/nft/SendNftTool.js +0 -20
  209. package/dist/tools/builtin/nft/SendNftTool.js.map +0 -1
  210. package/dist/tools/builtin/nft/WalletNFTsTool.d.ts +0 -15
  211. package/dist/tools/builtin/nft/WalletNFTsTool.d.ts.map +0 -1
  212. package/dist/tools/builtin/nft/WalletNFTsTool.js +0 -20
  213. package/dist/tools/builtin/nft/WalletNFTsTool.js.map +0 -1
  214. package/dist/tools/builtin/nft/index.d.ts +0 -7
  215. package/dist/tools/builtin/nft/index.d.ts.map +0 -1
  216. package/dist/tools/builtin/nft/index.js +0 -10
  217. package/dist/tools/builtin/nft/index.js.map +0 -1
  218. package/dist/tools/builtin/pool/EstimatePoolYieldTool.d.ts +0 -124
  219. package/dist/tools/builtin/pool/EstimatePoolYieldTool.d.ts.map +0 -1
  220. package/dist/tools/builtin/pool/EstimatePoolYieldTool.js +0 -236
  221. package/dist/tools/builtin/pool/EstimatePoolYieldTool.js.map +0 -1
  222. package/dist/tools/builtin/pool/OpenAddLiquidityFormTool.d.ts +0 -128
  223. package/dist/tools/builtin/pool/OpenAddLiquidityFormTool.d.ts.map +0 -1
  224. package/dist/tools/builtin/pool/OpenAddLiquidityFormTool.js +0 -520
  225. package/dist/tools/builtin/pool/OpenAddLiquidityFormTool.js.map +0 -1
  226. package/dist/tools/builtin/pool/PoolByAddressTool.d.ts +0 -127
  227. package/dist/tools/builtin/pool/PoolByAddressTool.d.ts.map +0 -1
  228. package/dist/tools/builtin/pool/PoolByAddressTool.js +0 -238
  229. package/dist/tools/builtin/pool/PoolByAddressTool.js.map +0 -1
  230. package/dist/tools/builtin/pool/PoolDetailTool.d.ts +0 -127
  231. package/dist/tools/builtin/pool/PoolDetailTool.d.ts.map +0 -1
  232. package/dist/tools/builtin/pool/PoolDetailTool.js +0 -273
  233. package/dist/tools/builtin/pool/PoolDetailTool.js.map +0 -1
  234. package/dist/tools/builtin/pool/PoolSearchTool.d.ts +0 -50
  235. package/dist/tools/builtin/pool/PoolSearchTool.d.ts.map +0 -1
  236. package/dist/tools/builtin/pool/PoolSearchTool.js +0 -160
  237. package/dist/tools/builtin/pool/PoolSearchTool.js.map +0 -1
  238. package/dist/tools/builtin/pool/PreviewAddLiquidityTool.d.ts +0 -124
  239. package/dist/tools/builtin/pool/PreviewAddLiquidityTool.d.ts.map +0 -1
  240. package/dist/tools/builtin/pool/PreviewAddLiquidityTool.js +0 -382
  241. package/dist/tools/builtin/pool/PreviewAddLiquidityTool.js.map +0 -1
  242. package/dist/tools/builtin/pool/TopPoolsTool.d.ts +0 -68
  243. package/dist/tools/builtin/pool/TopPoolsTool.d.ts.map +0 -1
  244. package/dist/tools/builtin/pool/TopPoolsTool.js +0 -159
  245. package/dist/tools/builtin/pool/TopPoolsTool.js.map +0 -1
  246. package/dist/tools/builtin/pool/index.d.ts +0 -15
  247. package/dist/tools/builtin/pool/index.d.ts.map +0 -1
  248. package/dist/tools/builtin/pool/index.js +0 -18
  249. package/dist/tools/builtin/pool/index.js.map +0 -1
  250. package/dist/tools/builtin/pool-subgraph/SubgraphCoinPoolPairsTool.d.ts +0 -54
  251. package/dist/tools/builtin/pool-subgraph/SubgraphCoinPoolPairsTool.d.ts.map +0 -1
  252. package/dist/tools/builtin/pool-subgraph/SubgraphCoinPoolPairsTool.js +0 -98
  253. package/dist/tools/builtin/pool-subgraph/SubgraphCoinPoolPairsTool.js.map +0 -1
  254. package/dist/tools/builtin/pool-subgraph/SubgraphPoolByAddressTool.d.ts +0 -63
  255. package/dist/tools/builtin/pool-subgraph/SubgraphPoolByAddressTool.d.ts.map +0 -1
  256. package/dist/tools/builtin/pool-subgraph/SubgraphPoolByAddressTool.js +0 -82
  257. package/dist/tools/builtin/pool-subgraph/SubgraphPoolByAddressTool.js.map +0 -1
  258. package/dist/tools/builtin/pool-subgraph/SubgraphPoolByPositionIdTool.d.ts +0 -79
  259. package/dist/tools/builtin/pool-subgraph/SubgraphPoolByPositionIdTool.d.ts.map +0 -1
  260. package/dist/tools/builtin/pool-subgraph/SubgraphPoolByPositionIdTool.js +0 -97
  261. package/dist/tools/builtin/pool-subgraph/SubgraphPoolByPositionIdTool.js.map +0 -1
  262. package/dist/tools/builtin/pool-subgraph/SubgraphPoolSearchTool.d.ts +0 -77
  263. package/dist/tools/builtin/pool-subgraph/SubgraphPoolSearchTool.d.ts.map +0 -1
  264. package/dist/tools/builtin/pool-subgraph/SubgraphPoolSearchTool.js +0 -190
  265. package/dist/tools/builtin/pool-subgraph/SubgraphPoolSearchTool.js.map +0 -1
  266. package/dist/tools/builtin/pool-subgraph/SubgraphPositionDetailTool.d.ts +0 -107
  267. package/dist/tools/builtin/pool-subgraph/SubgraphPositionDetailTool.d.ts.map +0 -1
  268. package/dist/tools/builtin/pool-subgraph/SubgraphPositionDetailTool.js +0 -92
  269. package/dist/tools/builtin/pool-subgraph/SubgraphPositionDetailTool.js.map +0 -1
  270. package/dist/tools/builtin/pool-subgraph/SubgraphTrendingPoolsTool.d.ts +0 -56
  271. package/dist/tools/builtin/pool-subgraph/SubgraphTrendingPoolsTool.d.ts.map +0 -1
  272. package/dist/tools/builtin/pool-subgraph/SubgraphTrendingPoolsTool.js +0 -94
  273. package/dist/tools/builtin/pool-subgraph/SubgraphTrendingPoolsTool.js.map +0 -1
  274. package/dist/tools/builtin/pool-subgraph/index.d.ts +0 -13
  275. package/dist/tools/builtin/pool-subgraph/index.d.ts.map +0 -1
  276. package/dist/tools/builtin/pool-subgraph/index.js +0 -18
  277. package/dist/tools/builtin/pool-subgraph/index.js.map +0 -1
  278. package/dist/tools/builtin/token/TokenAnalyticsTool.d.ts +0 -71
  279. package/dist/tools/builtin/token/TokenAnalyticsTool.d.ts.map +0 -1
  280. package/dist/tools/builtin/token/TokenAnalyticsTool.js +0 -147
  281. package/dist/tools/builtin/token/TokenAnalyticsTool.js.map +0 -1
  282. package/dist/tools/builtin/token/TokenHoldersTool.d.ts +0 -81
  283. package/dist/tools/builtin/token/TokenHoldersTool.d.ts.map +0 -1
  284. package/dist/tools/builtin/token/TokenHoldersTool.js +0 -139
  285. package/dist/tools/builtin/token/TokenHoldersTool.js.map +0 -1
  286. package/dist/tools/builtin/token/TokenInfoTool.d.ts +0 -40
  287. package/dist/tools/builtin/token/TokenInfoTool.d.ts.map +0 -1
  288. package/dist/tools/builtin/token/TokenInfoTool.js +0 -221
  289. package/dist/tools/builtin/token/TokenInfoTool.js.map +0 -1
  290. package/dist/tools/builtin/token/TokenScoreTool.d.ts +0 -63
  291. package/dist/tools/builtin/token/TokenScoreTool.d.ts.map +0 -1
  292. package/dist/tools/builtin/token/TokenScoreTool.js +0 -148
  293. package/dist/tools/builtin/token/TokenScoreTool.js.map +0 -1
  294. package/dist/tools/builtin/token/TopGainersTool.d.ts +0 -37
  295. package/dist/tools/builtin/token/TopGainersTool.d.ts.map +0 -1
  296. package/dist/tools/builtin/token/TopGainersTool.js +0 -100
  297. package/dist/tools/builtin/token/TopGainersTool.js.map +0 -1
  298. package/dist/tools/builtin/token/TopLosersTool.d.ts +0 -66
  299. package/dist/tools/builtin/token/TopLosersTool.d.ts.map +0 -1
  300. package/dist/tools/builtin/token/TopLosersTool.js +0 -129
  301. package/dist/tools/builtin/token/TopLosersTool.js.map +0 -1
  302. package/dist/tools/builtin/token/TrendingTokensTool.d.ts +0 -39
  303. package/dist/tools/builtin/token/TrendingTokensTool.d.ts.map +0 -1
  304. package/dist/tools/builtin/token/TrendingTokensTool.js +0 -83
  305. package/dist/tools/builtin/token/TrendingTokensTool.js.map +0 -1
  306. package/dist/tools/builtin/token/index.d.ts +0 -13
  307. package/dist/tools/builtin/token/index.d.ts.map +0 -1
  308. package/dist/tools/builtin/token/index.js +0 -16
  309. package/dist/tools/builtin/token/index.js.map +0 -1
  310. package/dist/tools/builtin/wallet/TransactionByHashTool.d.ts +0 -70
  311. package/dist/tools/builtin/wallet/TransactionByHashTool.d.ts.map +0 -1
  312. package/dist/tools/builtin/wallet/TransactionByHashTool.js +0 -111
  313. package/dist/tools/builtin/wallet/TransactionByHashTool.js.map +0 -1
  314. package/dist/tools/builtin/wallet/WalletApprovalsTool.d.ts +0 -107
  315. package/dist/tools/builtin/wallet/WalletApprovalsTool.d.ts.map +0 -1
  316. package/dist/tools/builtin/wallet/WalletApprovalsTool.js +0 -164
  317. package/dist/tools/builtin/wallet/WalletApprovalsTool.js.map +0 -1
  318. package/dist/tools/builtin/wallet/WalletDefiPositionsTool.d.ts +0 -61
  319. package/dist/tools/builtin/wallet/WalletDefiPositionsTool.d.ts.map +0 -1
  320. package/dist/tools/builtin/wallet/WalletDefiPositionsTool.js +0 -100
  321. package/dist/tools/builtin/wallet/WalletDefiPositionsTool.js.map +0 -1
  322. package/dist/tools/builtin/wallet/WalletDefiProtocolPositionsTool.d.ts +0 -68
  323. package/dist/tools/builtin/wallet/WalletDefiProtocolPositionsTool.d.ts.map +0 -1
  324. package/dist/tools/builtin/wallet/WalletDefiProtocolPositionsTool.js +0 -115
  325. package/dist/tools/builtin/wallet/WalletDefiProtocolPositionsTool.js.map +0 -1
  326. package/dist/tools/builtin/wallet/WalletDefiSummaryTool.d.ts +0 -50
  327. package/dist/tools/builtin/wallet/WalletDefiSummaryTool.d.ts.map +0 -1
  328. package/dist/tools/builtin/wallet/WalletDefiSummaryTool.js +0 -80
  329. package/dist/tools/builtin/wallet/WalletDefiSummaryTool.js.map +0 -1
  330. package/dist/tools/builtin/wallet/WalletHistoryTool.d.ts +0 -31
  331. package/dist/tools/builtin/wallet/WalletHistoryTool.d.ts.map +0 -1
  332. package/dist/tools/builtin/wallet/WalletHistoryTool.js +0 -154
  333. package/dist/tools/builtin/wallet/WalletHistoryTool.js.map +0 -1
  334. package/dist/tools/builtin/wallet/WalletNetWorthTool.d.ts +0 -44
  335. package/dist/tools/builtin/wallet/WalletNetWorthTool.d.ts.map +0 -1
  336. package/dist/tools/builtin/wallet/WalletNetWorthTool.js +0 -122
  337. package/dist/tools/builtin/wallet/WalletNetWorthTool.js.map +0 -1
  338. package/dist/tools/builtin/wallet/WalletNftTransfersTool.d.ts +0 -86
  339. package/dist/tools/builtin/wallet/WalletNftTransfersTool.d.ts.map +0 -1
  340. package/dist/tools/builtin/wallet/WalletNftTransfersTool.js +0 -265
  341. package/dist/tools/builtin/wallet/WalletNftTransfersTool.js.map +0 -1
  342. package/dist/tools/builtin/wallet/WalletPnlSummaryTool.d.ts +0 -43
  343. package/dist/tools/builtin/wallet/WalletPnlSummaryTool.d.ts.map +0 -1
  344. package/dist/tools/builtin/wallet/WalletPnlSummaryTool.js +0 -89
  345. package/dist/tools/builtin/wallet/WalletPnlSummaryTool.js.map +0 -1
  346. package/dist/tools/builtin/wallet/WalletPnlTool.d.ts +0 -43
  347. package/dist/tools/builtin/wallet/WalletPnlTool.d.ts.map +0 -1
  348. package/dist/tools/builtin/wallet/WalletPnlTool.js +0 -175
  349. package/dist/tools/builtin/wallet/WalletPnlTool.js.map +0 -1
  350. package/dist/tools/builtin/wallet/WalletTokenBalancesTool.d.ts +0 -35
  351. package/dist/tools/builtin/wallet/WalletTokenBalancesTool.d.ts.map +0 -1
  352. package/dist/tools/builtin/wallet/WalletTokenBalancesTool.js +0 -68
  353. package/dist/tools/builtin/wallet/WalletTokenBalancesTool.js.map +0 -1
  354. package/dist/tools/builtin/wallet/WalletTokenTransfersTool.d.ts +0 -109
  355. package/dist/tools/builtin/wallet/WalletTokenTransfersTool.d.ts.map +0 -1
  356. package/dist/tools/builtin/wallet/WalletTokenTransfersTool.js +0 -354
  357. package/dist/tools/builtin/wallet/WalletTokenTransfersTool.js.map +0 -1
  358. package/dist/tools/builtin/wallet/index.d.ts +0 -28
  359. package/dist/tools/builtin/wallet/index.d.ts.map +0 -1
  360. package/dist/tools/builtin/wallet/index.js +0 -32
  361. package/dist/tools/builtin/wallet/index.js.map +0 -1
  362. package/dist/tools/builtin/wallet-action/ApproveTokenTool.d.ts +0 -25
  363. package/dist/tools/builtin/wallet-action/ApproveTokenTool.d.ts.map +0 -1
  364. package/dist/tools/builtin/wallet-action/ApproveTokenTool.js +0 -98
  365. package/dist/tools/builtin/wallet-action/ApproveTokenTool.js.map +0 -1
  366. package/dist/tools/builtin/wallet-action/BaseWalletActionTool.d.ts +0 -211
  367. package/dist/tools/builtin/wallet-action/BaseWalletActionTool.d.ts.map +0 -1
  368. package/dist/tools/builtin/wallet-action/BaseWalletActionTool.js +0 -499
  369. package/dist/tools/builtin/wallet-action/BaseWalletActionTool.js.map +0 -1
  370. package/dist/tools/builtin/wallet-action/BuyTokenTool.d.ts +0 -240
  371. package/dist/tools/builtin/wallet-action/BuyTokenTool.d.ts.map +0 -1
  372. package/dist/tools/builtin/wallet-action/BuyTokenTool.js +0 -1257
  373. package/dist/tools/builtin/wallet-action/BuyTokenTool.js.map +0 -1
  374. package/dist/tools/builtin/wallet-action/SendNativeTool.d.ts +0 -41
  375. package/dist/tools/builtin/wallet-action/SendNativeTool.d.ts.map +0 -1
  376. package/dist/tools/builtin/wallet-action/SendNativeTool.js +0 -127
  377. package/dist/tools/builtin/wallet-action/SendNativeTool.js.map +0 -1
  378. package/dist/tools/builtin/wallet-action/SendTokenTool.d.ts +0 -63
  379. package/dist/tools/builtin/wallet-action/SendTokenTool.d.ts.map +0 -1
  380. package/dist/tools/builtin/wallet-action/SendTokenTool.js +0 -294
  381. package/dist/tools/builtin/wallet-action/SendTokenTool.js.map +0 -1
  382. package/dist/tools/builtin/wallet-action/SwapTokenTool.d.ts +0 -247
  383. package/dist/tools/builtin/wallet-action/SwapTokenTool.d.ts.map +0 -1
  384. package/dist/tools/builtin/wallet-action/SwapTokenTool.js +0 -1258
  385. package/dist/tools/builtin/wallet-action/SwapTokenTool.js.map +0 -1
  386. package/dist/tools/builtin/wallet-action/UnwrapNativeTool.d.ts +0 -20
  387. package/dist/tools/builtin/wallet-action/UnwrapNativeTool.d.ts.map +0 -1
  388. package/dist/tools/builtin/wallet-action/UnwrapNativeTool.js +0 -36
  389. package/dist/tools/builtin/wallet-action/UnwrapNativeTool.js.map +0 -1
  390. package/dist/tools/builtin/wallet-action/WrapNativeTool.d.ts +0 -23
  391. package/dist/tools/builtin/wallet-action/WrapNativeTool.d.ts.map +0 -1
  392. package/dist/tools/builtin/wallet-action/WrapNativeTool.js +0 -54
  393. package/dist/tools/builtin/wallet-action/WrapNativeTool.js.map +0 -1
  394. package/dist/tools/builtin/wallet-action/amountSpec.d.ts +0 -62
  395. package/dist/tools/builtin/wallet-action/amountSpec.d.ts.map +0 -1
  396. package/dist/tools/builtin/wallet-action/amountSpec.js +0 -93
  397. package/dist/tools/builtin/wallet-action/amountSpec.js.map +0 -1
  398. package/dist/tools/builtin/wallet-action/gasReserve.d.ts +0 -42
  399. package/dist/tools/builtin/wallet-action/gasReserve.d.ts.map +0 -1
  400. package/dist/tools/builtin/wallet-action/gasReserve.js +0 -103
  401. package/dist/tools/builtin/wallet-action/gasReserve.js.map +0 -1
  402. package/dist/tools/builtin/wallet-action/index.d.ts +0 -9
  403. package/dist/tools/builtin/wallet-action/index.d.ts.map +0 -1
  404. package/dist/tools/builtin/wallet-action/index.js +0 -20
  405. package/dist/tools/builtin/wallet-action/index.js.map +0 -1
  406. package/dist/tools/chainResolver.d.ts +0 -98
  407. package/dist/tools/chainResolver.d.ts.map +0 -1
  408. package/dist/tools/chainResolver.js +0 -302
  409. package/dist/tools/chainResolver.js.map +0 -1
  410. package/dist/tools/index.d.ts +0 -4
  411. package/dist/tools/index.d.ts.map +0 -1
  412. package/dist/tools/index.js +0 -23
  413. package/dist/tools/index.js.map +0 -1
  414. package/dist/types/index.d.ts +0 -777
  415. package/dist/types/index.d.ts.map +0 -1
  416. package/dist/types/index.js +0 -6
  417. package/dist/types/index.js.map +0 -1
@@ -1,1093 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AgentCore = void 0;
4
- const GeminiProvider_1 = require("../llm/GeminiProvider");
5
- const ToolRegistry_1 = require("../tools/ToolRegistry");
6
- const builtin_1 = require("../tools/builtin");
7
- const ChatHistory_1 = require("../memory/ChatHistory");
8
- const Summarizer_1 = require("../memory/Summarizer");
9
- const KnowledgeBase_1 = require("../memory/KnowledgeBase");
10
- const UpstashKnowledgeBase_1 = require("../memory/UpstashKnowledgeBase");
11
- const historyUtils_1 = require("../memory/historyUtils");
12
- const Router_1 = require("./Router");
13
- const subagents_1 = require("./subagents");
14
- const Synthesizer_1 = require("./Synthesizer");
15
- const QueryRewriter_1 = require("./QueryRewriter");
16
- const chatGraph_1 = require("./chatGraph");
17
- const chainResolver_1 = require("../tools/chainResolver");
18
- const rpc_1 = require("../services/rpc");
19
- /** Generate a short stable id for one response turn (8 hex chars). */
20
- function generateMessageId() {
21
- const ts = Date.now().toString(16);
22
- const rand = Math.floor(Math.random() * 0xffff)
23
- .toString(16)
24
- .padStart(4, '0');
25
- return (ts + rand).slice(-8);
26
- }
27
- const DEFAULT_SYSTEM_PROMPT = 'You are a helpful AI assistant. Answer the user accurately and concisely. ' +
28
- 'Respond in the same language as the user.';
29
- /**
30
- * Top-level orchestrator. Two-layer architecture:
31
- *
32
- * User query
33
- * → Router (picks 0..N domain subagents)
34
- * → Subagent(s) (each runs its own ReAct loop over a narrow tool set, in parallel)
35
- * → Synthesizer (merges subagent answers into the final reply)
36
- *
37
- * Compared to a flat planner that sees every tool, this keeps per-call prompt
38
- * size bounded regardless of how many tools are registered.
39
- */
40
- class AgentCore {
41
- llm;
42
- registry;
43
- history;
44
- summarizer;
45
- router;
46
- rewriter;
47
- subagents;
48
- synthesizer;
49
- /** Compiled LangGraph that orchestrates one chat turn. */
50
- chatGraph;
51
- systemPrompt;
52
- debug;
53
- userContext = {};
54
- storage;
55
- storageKey;
56
- persistHistoryEnabled;
57
- /** Active KB used at search time. May be the legacy LLM matcher or a vector backend. */
58
- kb;
59
- /** Always-present in-memory KB that holds the original entries (used for autoIngest + as fallback). */
60
- kbEntries;
61
- vectorKB = null;
62
- vectorKBAutoIngested = false;
63
- vectorKBAutoIngestPromise = null;
64
- autoIngestEnabled = false;
65
- kbAnswerThreshold;
66
- suggestionsEnabled;
67
- historyLoaded = false;
68
- historyLoadingPromise = null;
69
- /**
70
- * Resolves once the initial persisted-history load attempt has finished
71
- * (success or failure). Only meaningful when `persistHistory: true` and a
72
- * `storage` provider is configured — in that case consumers rendering a
73
- * chat list on mount should `await agent.historyReady` before calling
74
- * {@link getHistory} / {@link getDisplayHistory}, otherwise the first read
75
- * happens before storage has been hydrated and returns an empty array.
76
- * With persistence disabled this still resolves (immediately), so it is
77
- * always safe to await.
78
- */
79
- historyReady;
80
- constructor(config) {
81
- // Install the core-wide RPC overrides before any RPC-using tool/service is
82
- // constructed. A single shared map drives every on-chain read (gas-reserve
83
- // estimation, swap allowance check, pool tools); chains not listed fall back
84
- // to the built-in public defaults.
85
- (0, rpc_1.setRpcOverrides)(config.rpcUrls);
86
- this.llm = new GeminiProvider_1.GeminiProvider(config.llm);
87
- this.registry = new ToolRegistry_1.ToolRegistry();
88
- this.history = new ChatHistory_1.ChatHistory(config.maxHistoryMessages ?? 50);
89
- this.summarizer = new Summarizer_1.Summarizer(this.llm);
90
- this.synthesizer = new Synthesizer_1.Synthesizer(this.llm);
91
- this.systemPrompt = config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;
92
- this.debug = config.debug ?? false;
93
- this.suggestionsEnabled = config.generateSuggestions ?? true;
94
- this.storage = config.storage ?? null;
95
- this.storageKey = config.storageKey ?? 'keyring-agent-history';
96
- this.persistHistoryEnabled = config.persistHistory ?? false;
97
- // Always build the in-memory KB so callers can add/replace entries at
98
- // runtime even when vector mode is enabled (we re-ingest from it).
99
- this.kbEntries = new KnowledgeBase_1.KnowledgeBase(config.knowledgeBase);
100
- this.kbEntries.setLLM(this.llm);
101
- // Resolve which backend handles search: vector (Upstash / custom) or legacy.
102
- const vec = config.vectorKB;
103
- if (vec?.enabled) {
104
- if (vec.provider) {
105
- this.kb = vec.provider;
106
- }
107
- else {
108
- this.vectorKB = new UpstashKnowledgeBase_1.UpstashKnowledgeBase({
109
- url: vec.url,
110
- token: vec.token,
111
- namespace: vec.namespace,
112
- minScore: vec.minScore,
113
- defaultTopK: vec.defaultTopK,
114
- debug: this.debug,
115
- });
116
- this.kb = this.vectorKB;
117
- this.autoIngestEnabled = vec.autoIngest === true;
118
- }
119
- if (this.debug) {
120
- console.log(`[AgentCore] vector KB enabled (${vec.provider ? 'custom provider' : 'Upstash'}` +
121
- (vec.namespace ? `, ns=${vec.namespace}` : '') +
122
- ')');
123
- }
124
- }
125
- else {
126
- this.kb = this.kbEntries;
127
- }
128
- // kbAnswerThreshold default differs by backend:
129
- // - LLM matcher: scores are 0.6–1.0, the "high-confidence" cut-off is 0.8.
130
- // - Upstash vector backend (DBSF fusion, hybrid index): scores are
131
- // distribution-fused and unbounded — strong matches sit above ~1.3,
132
- // decent ones around 0.6–1.0, noise near 0. We deliberately keep a
133
- // HIGH cut-off here (1.3) to avoid answer-from-KB false positives when
134
- // sparse keyword overlap pushes a non-matching entry above 1.0 even
135
- // though the dense semantic match is weak. Lower-scoring hits still
136
- // flow to the router/synthesiser as reference context — they are just
137
- // not allowed to bypass the router on their own.
138
- const explicitThreshold = config.kbAnswerThreshold;
139
- if (typeof explicitThreshold === 'number') {
140
- this.kbAnswerThreshold = explicitThreshold;
141
- }
142
- else if (vec?.enabled && !vec.provider) {
143
- this.kbAnswerThreshold = vec.minScore ?? 1.3;
144
- }
145
- else {
146
- this.kbAnswerThreshold = 0.8;
147
- }
148
- if (this.debug) {
149
- console.log(`[AgentCore] kbAnswerThreshold = ${this.kbAnswerThreshold}`);
150
- }
151
- // Register built-in Moralis tools
152
- if (config.moralis !== false) {
153
- const moralisConfig = typeof config.moralis === 'object' ? config.moralis : undefined;
154
- this.registry.register(new builtin_1.WalletTokenBalancesTool(moralisConfig));
155
- // this.registry.register(new WalletNetWorthTool(moralisConfig)); deprecated
156
- this.registry.register(new builtin_1.TokenInfoTool(moralisConfig));
157
- this.registry.register(new builtin_1.WalletHistoryTool(moralisConfig));
158
- this.registry.register(new builtin_1.WalletTokenTransfersTool(moralisConfig));
159
- this.registry.register(new builtin_1.WalletNftTransfersTool(moralisConfig));
160
- this.registry.register(new builtin_1.TokenHoldersTool(moralisConfig));
161
- this.registry.register(new builtin_1.WalletPnlSummaryTool(moralisConfig));
162
- this.registry.register(new builtin_1.WalletPnlTool(moralisConfig));
163
- this.registry.register(new builtin_1.TransactionByHashTool(moralisConfig));
164
- this.registry.register(new builtin_1.WalletDefiSummaryTool(moralisConfig));
165
- this.registry.register(new builtin_1.WalletDefiPositionsTool(moralisConfig));
166
- this.registry.register(new builtin_1.WalletDefiProtocolPositionsTool(moralisConfig));
167
- this.registry.register(new builtin_1.WalletApprovalsTool(moralisConfig));
168
- this.registry.register(new builtin_1.TrendingTokensTool(moralisConfig));
169
- this.registry.register(new builtin_1.TopGainersTool(moralisConfig));
170
- this.registry.register(new builtin_1.TokenAnalyticsTool(moralisConfig));
171
- this.registry.register(new builtin_1.TokenScoreTool(moralisConfig));
172
- }
173
- // NFT tools — point the user to the NFT website instead of returning
174
- // on-chain data. Independent of Moralis; the only config is the optional
175
- // link, which turns the "this website" phrase into a Markdown link when
176
- // present. The NFT notice tools (send-nft + the nft-agent view/detail
177
- // tools) all share the single `nftLink`.
178
- const nftUrl = config.nftLink;
179
- this.registry.register(new builtin_1.SendNftTool({ url: nftUrl }));
180
- this.registry.register(new builtin_1.WalletNFTsTool({ url: nftUrl }));
181
- this.registry.register(new builtin_1.NFTContractInfoTool({ url: nftUrl }));
182
- this.registry.register(new builtin_1.NFTMetadataTool({ url: nftUrl }));
183
- // Search-grounded Gemini fallback. Independent of Moralis — uses the same
184
- // LLM proxy as the rest of the agent. Subagents wire this in as their
185
- // `cortexFallbackTool` so they always have a tool to call.
186
- this.registry.register(new builtin_1.GeminiSearchAiTool(config.llm));
187
- // Pool subagent toggles — mirrors the mutually-exclusive logic in
188
- // createDefaultSubagents (subagents/index.ts). When `pool-subgraph` is
189
- // enabled it auto-disables `pool` unless the caller explicitly set it
190
- // back to true. We use the same rule here so we never register a tool set
191
- // whose subagent is off.
192
- const poolSubgraphSubagentOn = config.subagents?.['pool-subgraph'] === true;
193
- const poolSubagentOn = poolSubgraphSubagentOn ? config.subagents?.pool === true : config.subagents?.pool !== false;
194
- // Register built-in Uniswap (DEX pool) tools — only when the `pool`
195
- // subagent is enabled AND `uniswap` config is not turned off.
196
- if (poolSubagentOn && config.uniswap !== false) {
197
- const uniswapConfig = typeof config.uniswap === 'object' ? config.uniswap : undefined;
198
- this.registry.register(new builtin_1.TopPoolsTool(uniswapConfig));
199
- this.registry.register(new builtin_1.PoolDetailTool(uniswapConfig));
200
- this.registry.register(new builtin_1.PoolSearchTool(uniswapConfig));
201
- this.registry.register(new builtin_1.PoolByAddressTool(uniswapConfig));
202
- this.registry.register(new builtin_1.EstimatePoolYieldTool(uniswapConfig));
203
- // Add-liquidity action tools (need on-chain RPC + gateway addresses).
204
- // RPC endpoints come from the shared core-wide `rpcUrls` (installed via
205
- // setRpcOverrides above), so PoolService takes no per-chain RPC config here.
206
- const poolServiceConfig = uniswapConfig ? { isProduction: uniswapConfig.isProduction } : undefined;
207
- this.registry.register(new builtin_1.OpenAddLiquidityFormTool({
208
- baseUrl: uniswapConfig?.baseUrl,
209
- pool: poolServiceConfig,
210
- minProvideUsd: uniswapConfig?.minProvideUsd,
211
- }));
212
- this.registry.register(new builtin_1.PreviewAddLiquidityTool({ pool: poolServiceConfig }));
213
- }
214
- // Register built-in subgraph-backed pool tools — only when the
215
- // `pool-subgraph` subagent is enabled AND `subgraph` config is not off.
216
- if (poolSubgraphSubagentOn && config.subgraph !== false) {
217
- const subgraphConfig = typeof config.subgraph === 'object' ? config.subgraph : undefined;
218
- this.registry.register(new builtin_1.SubgraphPoolSearchTool(subgraphConfig));
219
- this.registry.register(new builtin_1.SubgraphTrendingPoolsTool(subgraphConfig));
220
- this.registry.register(new builtin_1.SubgraphPoolByAddressTool(subgraphConfig));
221
- this.registry.register(new builtin_1.SubgraphPoolByPositionIdTool(subgraphConfig));
222
- this.registry.register(new builtin_1.SubgraphPositionDetailTool(subgraphConfig));
223
- this.registry.register(new builtin_1.SubgraphCoinPoolPairsTool(subgraphConfig));
224
- }
225
- // Wallet-action tools — emit UI payloads only; the FE renders the form and
226
- // executes the tx itself. Tools that accept `token_symbol` use Moralis to
227
- // resolve the symbol → contract address (wallet balances first, then a
228
- // Pantograph search). When the moralis tool family is disabled, symbol
229
- // resolution is unavailable and the tools require an explicit
230
- // contract_address.
231
- const walletActionMoralisConfig = config.moralis === false ? undefined : typeof config.moralis === 'object' ? config.moralis : {};
232
- this.registry.register(new builtin_1.SendNativeTool(walletActionMoralisConfig));
233
- this.registry.register(new builtin_1.SendTokenTool(walletActionMoralisConfig));
234
- this.registry.register(new builtin_1.ApproveTokenTool(walletActionMoralisConfig));
235
- // Wrap/unwrap forward the Moralis config too: wrap_native sizes the amount
236
- // off the SPENDABLE native balance (held − gas reserve), which needs to read
237
- // the wallet balance first. Without a Moralis service the balance read bails
238
- // early, so the gas reserve is never estimated and spendable falls back to
239
- // the full balance (no gas withheld).
240
- this.registry.register(new builtin_1.WrapNativeTool(walletActionMoralisConfig));
241
- this.registry.register(new builtin_1.UnwrapNativeTool(walletActionMoralisConfig));
242
- this.registry.register(new builtin_1.BuyTokenTool(walletActionMoralisConfig, { debug: this.debug }));
243
- this.registry.register(new builtin_1.SwapTokenTool(walletActionMoralisConfig, { debug: this.debug }));
244
- // Wire router + subagents. Subagents share the same registry, so any custom
245
- // tools registered later via `registerTool()` become available as long as
246
- // their name matches one of the subagent's declared tool names.
247
- this.router = new Router_1.Router(this.llm, { debug: this.debug });
248
- this.rewriter = new QueryRewriter_1.QueryRewriter(this.llm, { debug: this.debug });
249
- const subgraphConfigObj = typeof config.subgraph === 'object' ? config.subgraph : undefined;
250
- const subagentList = (0, subagents_1.createDefaultSubagents)(this.llm, this.registry, {
251
- maxToolCalls: config.maxIterations ?? 5,
252
- debug: this.debug,
253
- linkAddLiquidity: subgraphConfigObj?.linkAddLiquidity,
254
- }, config.subagents);
255
- this.subagents = new Map(subagentList.map((s) => [s.name, s]));
256
- // Compile the LangGraph that drives one chat turn. Nodes reuse the helpers
257
- // below via a host object, so the graph is pure orchestration.
258
- this.chatGraph = (0, chatGraph_1.buildChatGraph)(this.createGraphHost());
259
- // Kick off the initial history load eagerly so consumers that read
260
- // history synchronously right after `new AgentCore(...)` (e.g. a React
261
- // component reading `getHistory()` during its first render) can await
262
- // `agent.historyReady` to ensure persisted storage has been hydrated.
263
- this.historyReady = this.loadHistory();
264
- }
265
- // ---- Tool management ----
266
- /** Register a tool so the agent can use it. */
267
- registerTool(tool) {
268
- this.registry.register(tool);
269
- }
270
- /** Register multiple tools at once. */
271
- registerTools(tools) {
272
- for (const tool of tools) {
273
- this.registry.register(tool);
274
- }
275
- }
276
- /** Unregister a tool by name. */
277
- unregisterTool(name) {
278
- return this.registry.unregister(name);
279
- }
280
- /** List registered tool names. */
281
- listTools() {
282
- return this.registry.listNames();
283
- }
284
- /**
285
- * Directly invoke a tool with structured args, bypassing the LLM/router.
286
- *
287
- * Use this from the FE for **deterministic actions** where the user has
288
- * already supplied structured input via a UI form (e.g. confirming an
289
- * AddLiquidityForm with a chosen strategy + amount). It is faster, cheaper,
290
- * and removes the risk of the LLM mis-parsing numeric values from form data.
291
- *
292
- * The result is returned with the same `AgentResponse` shape as `chat()` —
293
- * including `uiActions` collected from the tool's UI payload — so the FE
294
- * renders it uniformly. The interaction is also recorded in chat history so
295
- * subsequent conversational turns retain context.
296
- *
297
- * Use `chat()` (the LLM-driven path) for free-form natural-language input.
298
- */
299
- async invokeTool(name, args, options) {
300
- await this.loadHistory();
301
- const tool = this.registry.get(name);
302
- if (!tool) {
303
- const answer = `Unknown tool: "${name}".`;
304
- return { answer, messageId: generateMessageId() };
305
- }
306
- if (this.debug) {
307
- console.log(`[AgentCore] invokeTool ${name} ${JSON.stringify(args)}`);
308
- }
309
- // Record the user's intent in history so the next conversational turn
310
- // can reference what the user just confirmed.
311
- const userMsg = options?.userMessage ?? `[invoke ${name}]`;
312
- this.history.add({ role: 'user', content: userMsg, timestamp: Date.now() });
313
- const result = await this.registry.execute(name, args, this.userContext);
314
- // Build a synthetic assistant message so chat history stays well-formed
315
- // (one assistant reply per user turn). For UI/action tools this is
316
- // typically just the tool's own `summary` field.
317
- const data = result.data;
318
- const answer = result.success ? (data?.summary ?? `Done.`) : `Action failed: ${result.error ?? 'unknown error'}`;
319
- const messageId = generateMessageId();
320
- // invokeTool() is FE-driven (form confirmation, not free-form chat) — no
321
- // chat-message language detection runs here. Stamp 'en' as a safe default
322
- // so FE never sees `undefined`; FE may override with its own app locale.
323
- const uiActions = result.success && result.ui ? [this.stampLanguage(result.ui, null)] : [];
324
- const assistantMsg = {
325
- role: 'assistant',
326
- content: answer,
327
- timestamp: Date.now(),
328
- subagents: ['direct-invoke'],
329
- messageId,
330
- };
331
- if (uiActions.length > 0)
332
- assistantMsg.uiActions = uiActions;
333
- this.history.add(assistantMsg);
334
- await this.persistHistory();
335
- return {
336
- answer,
337
- messageId,
338
- ...(uiActions.length > 0 ? { uiActions } : {}),
339
- };
340
- }
341
- // ---- Subagent management ----
342
- /**
343
- * Register a custom subagent. Replaces any existing subagent with the same name.
344
- * Advanced: most consumers should rely on the default wallet/token/nft/ai agents.
345
- */
346
- registerSubagent(agent) {
347
- this.subagents.set(agent.name, agent);
348
- }
349
- /** Unregister a subagent by name. */
350
- unregisterSubagent(name) {
351
- return this.subagents.delete(name);
352
- }
353
- /** List registered subagent names. */
354
- listSubagents() {
355
- return Array.from(this.subagents.keys());
356
- }
357
- // ---- Knowledge Base ----
358
- /**
359
- * Replace all in-memory KB entries. When vector mode is enabled, the new
360
- * entries become the source of truth for the next `ingestKnowledgeBase()`
361
- * call but are NOT auto-pushed to the remote index — call that explicitly.
362
- */
363
- setKnowledgeBase(entries) {
364
- this.kbEntries.setEntries(entries);
365
- this.vectorKBAutoIngested = false;
366
- }
367
- addKnowledgeBase(entries) {
368
- this.kbEntries.addEntries(entries);
369
- this.vectorKBAutoIngested = false;
370
- }
371
- /**
372
- * Push the current in-memory KB entries to the configured vector backend.
373
- * Idempotent. No-op when vector mode is disabled or there are no entries.
374
- */
375
- async ingestKnowledgeBase() {
376
- if (!this.vectorKB)
377
- return { count: 0 };
378
- const entries = this.kbEntries.getEntries();
379
- if (entries.length === 0)
380
- return { count: 0 };
381
- const res = await this.vectorKB.upsert(entries);
382
- this.vectorKBAutoIngested = true;
383
- return res;
384
- }
385
- async maybeAutoIngest(autoIngest) {
386
- if (!autoIngest || !this.vectorKB || this.vectorKBAutoIngested)
387
- return;
388
- if (this.vectorKBAutoIngestPromise)
389
- return this.vectorKBAutoIngestPromise;
390
- this.vectorKBAutoIngestPromise = (async () => {
391
- try {
392
- const { count } = await this.ingestKnowledgeBase();
393
- if (this.debug && count > 0) {
394
- console.log(`[AgentCore] auto-ingested ${count} KB entr${count === 1 ? 'y' : 'ies'} to vector store`);
395
- }
396
- }
397
- catch (err) {
398
- if (this.debug)
399
- console.warn('[AgentCore] auto-ingest failed:', err);
400
- }
401
- finally {
402
- this.vectorKBAutoIngestPromise = null;
403
- }
404
- })();
405
- await this.vectorKBAutoIngestPromise;
406
- }
407
- // ---- User context (wallet / chain from UI) ----
408
- setUserContext(ctx) {
409
- this.userContext = { ...ctx };
410
- }
411
- getUserContext() {
412
- return { ...this.userContext };
413
- }
414
- // ---- Chat ----
415
- async loadHistory() {
416
- // If already loaded or loading, return the same promise so concurrent
417
- // callers (e.g. chat() racing with the consumer's useEffect) don't
418
- // trigger duplicate loads.
419
- if (this.historyLoaded)
420
- return;
421
- if (this.historyLoadingPromise)
422
- return this.historyLoadingPromise;
423
- this.historyLoadingPromise = this._doLoadHistory();
424
- await this.historyLoadingPromise;
425
- }
426
- async _doLoadHistory() {
427
- if (!this.storage) {
428
- if (this.debug)
429
- console.log(`[AgentCore] loadHistory: no storage configured`);
430
- this.historyLoaded = true;
431
- return;
432
- }
433
- if (!this.persistHistoryEnabled) {
434
- if (this.debug)
435
- console.log(`[AgentCore] loadHistory: persistHistory disabled — starting fresh session`);
436
- // Best-effort wipe any leftover data from a previous run that had
437
- // persistence enabled, so a consumer reading storage directly cannot
438
- // accidentally rehydrate the old session.
439
- try {
440
- await this.storage.removeItem(this.storageKey);
441
- }
442
- catch (err) {
443
- if (this.debug)
444
- console.warn('[AgentCore] failed to clear stale history:', err);
445
- }
446
- this.historyLoaded = true;
447
- return;
448
- }
449
- try {
450
- const raw = await this.storage.getItem(this.storageKey);
451
- if (this.debug) {
452
- console.log(`[AgentCore] loadHistory: storage key "${this.storageKey}" ${raw ? `has ${raw.length} chars` : 'is empty'}`);
453
- }
454
- if (raw) {
455
- const data = JSON.parse(raw);
456
- this.history.restore(data);
457
- if (this.debug) {
458
- console.log(`[AgentCore] Restored ${this.history.length} messages from storage`);
459
- }
460
- }
461
- }
462
- catch (err) {
463
- if (this.debug) {
464
- console.warn('[AgentCore] Failed to load history from storage:', err);
465
- }
466
- }
467
- finally {
468
- this.historyLoaded = true;
469
- }
470
- }
471
- async persistHistory() {
472
- if (!this.storage)
473
- return;
474
- if (!this.persistHistoryEnabled)
475
- return;
476
- try {
477
- const serialised = JSON.stringify(this.history.serialise());
478
- await this.storage.setItem(this.storageKey, serialised);
479
- }
480
- catch (err) {
481
- if (this.debug) {
482
- console.warn('[AgentCore] Failed to persist history to storage:', err);
483
- }
484
- }
485
- }
486
- /**
487
- * Process a user message and return an answer. Main entry point.
488
- */
489
- async chat(userMessage, options) {
490
- const doSuggest = options?.generateSuggestions ?? this.suggestionsEnabled;
491
- // FE-provided language hint — set when this turn originates from an
492
- // action-button click (the button's synthetic prompt is often English even
493
- // though the conversation is in another language). When present it wins
494
- // over auto-detection so the resulting form/reply stays in the user's
495
- // language. See SuggestedAction.language.
496
- const overrideLang = typeof options?.language === 'string' && options.language.trim() ? options.language.trim() : '';
497
- // Ensure history is loaded from storage before processing the first message.
498
- // This is a no-op if already loaded, and deduplicates concurrent calls so
499
- // a racing useEffect loadHistory() and this call don't double-load.
500
- await this.loadHistory();
501
- // First-call auto-ingest for vector KB (if configured). Idempotent.
502
- await this.maybeAutoIngest(this.autoIngestEnabled);
503
- const turnStart = Date.now();
504
- if (this.debug) {
505
- console.log(`\n${'─'.repeat(60)}`);
506
- console.log(`[AgentCore] query: "${userMessage}"`);
507
- }
508
- // Run the turn through the compiled LangGraph. All orchestration logic
509
- // (setup → rewrite → kb → route → direct | subagent fan-out → synthesize)
510
- // lives in chatGraph.ts; the nodes reuse the helpers on this class via the
511
- // host object, so behaviour is identical to the previous imperative flow.
512
- const finalState = await this.chatGraph.invoke({ userMessage, doSuggest, overrideLang });
513
- if (this.debug) {
514
- console.log(`[AgentCore] turn done in ${Date.now() - turnStart}ms total`);
515
- console.log(`${'─'.repeat(60)}\n`);
516
- }
517
- // A terminal node (kb / direct / synthesize) always sets `response`.
518
- return finalState.response ?? { answer: '', messageId: generateMessageId() };
519
- }
520
- /**
521
- * Build the host object the chat graph's nodes call into. Each method is a
522
- * thin closure over an existing (private) helper, so the graph stays pure
523
- * orchestration and AgentCore exposes no new public surface.
524
- */
525
- createGraphHost() {
526
- return {
527
- debug: this.debug,
528
- // setup
529
- addUserMessage: (message) => this.addUserMessage(message),
530
- needsSummary: () => this.history.needsSummary(),
531
- compactHistory: () => this.compactHistory(),
532
- conversationForTurn: () => {
533
- // Drop the trailing user message so Router/Subagent prompts don't
534
- // duplicate it (the query is passed separately as "User query: …").
535
- const raw = this.history.getConversation();
536
- return raw.length > 0 && raw[raw.length - 1].role === 'user' ? raw.slice(0, -1) : raw;
537
- },
538
- lastAssistantSubagents: (conversation) => (0, historyUtils_1.getLastAssistantSubagents)(conversation),
539
- generateMessageId: () => generateMessageId(),
540
- // rewrite
541
- rewrite: (userMessage, conversation, lastSubagents) => this.rewriter.rewrite(userMessage, conversation, lastSubagents),
542
- // knowledge base
543
- searchKB: (query) => this.searchKB(query),
544
- formatKBContext: (hits) => this.formatKBContext(hits),
545
- tryAnswerFromKB: (userMessage, hits, kbContext, messageId) => this.tryAnswerFromKB(userMessage, hits, kbContext, messageId),
546
- // router
547
- subagentCards: () => Array.from(this.subagents.values()).map((s) => s.getCard()),
548
- route: (query, conversation, cards, lastSubagents) => this.router.route(query, conversation, cards, this.userContext, lastSubagents),
549
- // unsupported chain
550
- connectedChain: () => this.userContext.chain,
551
- answerUnsupportedChain: (rawChain, language, messageId) => this.answerUnsupportedChain(rawChain, language, messageId),
552
- // direct answer
553
- answerDirectly: (query, conversation, kbContext, generateSuggestions, messageId, useWebSearch) => this.answerDirectly(query, conversation, kbContext, generateSuggestions, messageId, useWebSearch),
554
- // subagent — mirrors Router.dispatch's per-assignment handling, but for a
555
- // single assignment (the graph fans out one Send per assignment).
556
- runSubagent: async (assignment, conversation, turnLanguage) => {
557
- const agent = this.subagents.get(assignment.subagent);
558
- if (!agent) {
559
- if (this.debug)
560
- console.log(`[AgentCore] WARN: subagent "${assignment.subagent}" not registered`);
561
- return {
562
- subagentName: assignment.subagent,
563
- steps: [],
564
- finalAnswer: `Subagent "${assignment.subagent}" is not registered.`,
565
- toolResults: [],
566
- toolMessages: [],
567
- };
568
- }
569
- const t1 = Date.now();
570
- const result = await agent.run({ query: assignment.query, reasoning: assignment.reasoning, language: turnLanguage }, conversation, this.userContext);
571
- if (this.debug) {
572
- const toolNames = result.toolResults.map((r) => r.toolName).join(', ') || '—';
573
- console.log(`[AgentCore] ${assignment.subagent} done in ${Date.now() - t1}ms | tools: ${toolNames}`);
574
- }
575
- return result;
576
- },
577
- // synthesise
578
- persistToolMessages: (results) => this.persistToolMessages(results),
579
- synthesiserHistory: () => {
580
- const raw = this.history.getConversation();
581
- const trimmed = raw.length > 0 && raw[raw.length - 1].role === 'user' ? raw.slice(0, -1) : raw;
582
- return (0, historyUtils_1.stripToolMessages)(trimmed);
583
- },
584
- mergeTrace: (results) => this.mergeTrace(results),
585
- synthesise: (userMessage, trace, history, language) => this.synthesizer.synthesise(userMessage, trace, history, language),
586
- collectUiActions: (results, language) => this.collectUiActions(results, language),
587
- collectActionButtons: (results, language) => this.collectActionButtons(results, language),
588
- subResultsTriggerNoSuggestions: (results) => this.subResultsTriggerNoSuggestions(results),
589
- finaliseAnswer: (params, options) => this.finaliseAnswer(params, options),
590
- };
591
- }
592
- /**
593
- * Aggregate UI payloads from this turn's tool calls. Tools with kind='ui' or
594
- * 'action' attach a `ui` field to their ToolResult; the FE renders one
595
- * component per entry in the order they were produced.
596
- */
597
- /**
598
- * Return true when ANY tool successfully executed across the dispatched
599
- * subagents carries `noSuggestions: true` in its registry definition. Used to
600
- * skip the suggester for turns where the user is already pointed at a
601
- * concrete next action (a form / preview).
602
- */
603
- subResultsTriggerNoSuggestions(subResults) {
604
- for (const r of subResults) {
605
- for (const tr of r.toolResults) {
606
- if (!tr.success)
607
- continue;
608
- const def = this.registry.get(tr.toolName);
609
- if (def?.noSuggestions === true)
610
- return true;
611
- }
612
- }
613
- return false;
614
- }
615
- /**
616
- * Aggregate `actionButtons` emitted by tools across all subagent tool calls
617
- * this turn (e.g. a token-picker after the user said "send token" without
618
- * naming one). Preserves emission order; drops malformed entries.
619
- */
620
- collectActionButtons(subResults, language) {
621
- const out = [];
622
- // Dedup by label+prompt: the same tool result can be observed across more
623
- // than one subagent (or a tool emits an identical set twice), which would
624
- // otherwise render duplicate quick-pick chips (e.g. 25/50/75/100% twice).
625
- const seen = new Set();
626
- for (const r of subResults) {
627
- for (const tr of r.toolResults) {
628
- if (!tr.success || !Array.isArray(tr.actionButtons))
629
- continue;
630
- for (const btn of tr.actionButtons) {
631
- if (btn &&
632
- typeof btn === 'object' &&
633
- typeof btn.label === 'string' &&
634
- btn.label.trim() &&
635
- typeof btn.prompt === 'string' &&
636
- btn.prompt.trim()) {
637
- const key = `${btn.label}${btn.prompt}`;
638
- if (seen.has(key))
639
- continue;
640
- seen.add(key);
641
- // Stamp the turn language so the FE can echo it back on click,
642
- // keeping the follow-up turn in the user's language.
643
- out.push({ label: btn.label, prompt: btn.prompt, ...(language ? { language } : {}) });
644
- }
645
- }
646
- }
647
- }
648
- return out;
649
- }
650
- collectUiActions(subResults, language) {
651
- const out = [];
652
- for (const r of subResults) {
653
- for (const tr of r.toolResults) {
654
- if (tr.success && tr.ui && typeof tr.ui === 'object' && typeof tr.ui.component === 'string') {
655
- out.push(this.stampLanguage(tr.ui, language));
656
- }
657
- }
658
- }
659
- if (this.debug && out.length > 0) {
660
- const stamped = out.map((u) => `${u.component}=${u.language}`).join(', ');
661
- console.log(`[AgentCore] uiActions stamped (rewrite.language="${language ?? ''}"): ${stamped}`);
662
- }
663
- return out;
664
- }
665
- /**
666
- * Stamp the rewriter-detected user-message language onto a UIPayload so FE
667
- * renders the component in whichever language the user just typed in. Tools
668
- * never set this themselves — it is a transport-level concern owned by
669
- * AgentCore. No-op when the rewriter did not produce a language (FE may
670
- * fall back to its own locale in that rare case).
671
- */
672
- stampLanguage(ui, language) {
673
- if (!language || ui.language)
674
- return ui;
675
- return { ...ui, language };
676
- }
677
- // ---- Chat sub-steps ----
678
- addUserMessage(userMessage) {
679
- this.history.add({ role: 'user', content: userMessage, timestamp: Date.now() });
680
- }
681
- /** Single KB lookup — callers reuse the result for both context + short-circuit. */
682
- async searchKB(query) {
683
- const kbResults = await this.kb.search(query);
684
- if (this.debug) {
685
- if (kbResults.length === 0) {
686
- console.log(`[AgentCore] KB no hits for "${query}"`);
687
- }
688
- else {
689
- const summary = kbResults
690
- .slice(0, 3)
691
- .map((r) => `${r.score.toFixed(3)} ${this.snippet(r.entry.question, 60)}`)
692
- .join(' | ');
693
- console.log(`[AgentCore] KB hits (${kbResults.length}): ${summary}`);
694
- }
695
- }
696
- return kbResults;
697
- }
698
- snippet(text, max) {
699
- return text.length <= max ? text : text.slice(0, max - 1) + '…';
700
- }
701
- /** Format KB hits as a reference-block string for LLM consumption. */
702
- formatKBContext(hits) {
703
- if (hits.length === 0)
704
- return '';
705
- return hits.map((r, i) => `[Reference ${i + 1}]\nQ: ${r.entry.question}\nA: ${r.entry.answer}`).join('\n\n');
706
- }
707
- async tryAnswerFromKB(userMessage, kbResults, kbContext, messageId) {
708
- if (!kbContext || kbResults.length === 0) {
709
- if (this.debug)
710
- console.log('[AgentCore] KB skip: no hits → router pipeline');
711
- return null;
712
- }
713
- const top = kbResults[0].score;
714
- if (top < this.kbAnswerThreshold) {
715
- if (this.debug) {
716
- console.log(`[AgentCore] KB skip: top score ${top.toFixed(3)} < threshold ${this.kbAnswerThreshold} → router pipeline`);
717
- }
718
- return null;
719
- }
720
- if (this.debug) {
721
- console.log(`[AgentCore] KB answer: top score ${top.toFixed(3)} ≥ threshold ${this.kbAnswerThreshold} → verifying intent before KB answer`);
722
- }
723
- // Intent guard: verify the user message is actually asking about the FAQ
724
- // topic before bypassing the router. High embedding similarity alone is not
725
- // sufficient — a question like "what is the price of ETH?" can score high
726
- // against a KB entry about wallets simply due to shared vocabulary, but it
727
- // should be handled by a subagent, not the KB.
728
- const topQuestion = kbResults[0].entry.question;
729
- const intentCheckMessages = [
730
- {
731
- role: 'system',
732
- content: 'You are a STRICT intent classifier. Respond with ONLY "yes" or "no" — no other text.' +
733
- '\n\nDefault to "no". Only answer "yes" when you are confident.' +
734
- '\n\nAnswer "yes" ONLY IF the user message and the FAQ question are genuinely EQUIVALENT — i.e. ' +
735
- 'they ask the SAME thing and a single answer to the FAQ question would fully and directly answer the ' +
736
- 'user message. Merely sharing a topic, a keyword, or a domain is NOT enough.' +
737
- '\n\nAnswer "no" if ANY of these hold:' +
738
- '\n- The user is asking about a DIFFERENT aspect, sub-question, or angle of the same general topic ' +
739
- '(e.g. FAQ = "what is staking?" vs user = "how do I unstake?").' +
740
- '\n- The user message is broader, narrower, or only partially overlaps with the FAQ question.' +
741
- '\n- They merely share vocabulary or a domain but ask for different things.' +
742
- '\n- The user is asking for real-time data, live lookups, prices, balances, transactions, or anything ' +
743
- 'that requires fetching external data — even if the FAQ question looks similar.' +
744
- '\n- You are uncertain.',
745
- timestamp: 0,
746
- },
747
- {
748
- role: 'user',
749
- content: `FAQ question: "${topQuestion}"\nUser message: "${userMessage}"\n\n` +
750
- 'Are these two questions EQUIVALENT — asking the same thing such that one answer fully answers both? ' +
751
- 'Answer "yes" only if equivalent, otherwise "no".',
752
- timestamp: Date.now(),
753
- },
754
- ];
755
- const intentResponse = await this.llm.chat(intentCheckMessages);
756
- const intentVerdict = intentResponse.text.trim().toLowerCase();
757
- if (!intentVerdict.startsWith('yes')) {
758
- if (this.debug) {
759
- console.log(`[AgentCore] KB intent guard: verdict="${intentVerdict}" → skipping KB, routing to subagent pipeline`);
760
- }
761
- return null;
762
- }
763
- if (this.debug) {
764
- console.log(`[AgentCore] KB intent guard: verdict="yes" → answering from KB`);
765
- }
766
- // Strip tool messages (no tools declared here) and send only the system
767
- // prompt + KB material + the current user message. Omitting old history
768
- // prevents older turns in a different language from overriding language
769
- // detection — the LLM must reply in the language of THIS message only.
770
- const kbMessages = [
771
- {
772
- role: 'system',
773
- content: this.systemPrompt +
774
- "\n\nYou have reference material below. Use it ONLY if it directly addresses the user's question. " +
775
- 'Rephrase and adapt the content naturally — do NOT copy it verbatim. ' +
776
- 'Do NOT supplement with general knowledge or speculate beyond what the reference provides. ' +
777
- 'If the reference does not fully answer the question, say so honestly.' +
778
- '\n\n---\nREFERENCE MATERIAL:\n' +
779
- kbContext +
780
- '\n---',
781
- timestamp: 0,
782
- },
783
- {
784
- role: 'user',
785
- content: `${userMessage}\n\n(You MUST reply in the same language as the question above, regardless of the reference material language.)`,
786
- timestamp: Date.now(),
787
- },
788
- ];
789
- const kbResponse = await this.llm.chat(kbMessages);
790
- const answer = kbResponse.text;
791
- // KB turns are persisted to the working window so future turns can reference them.
792
- const kbMsg = { role: 'assistant', content: answer, timestamp: Date.now() };
793
- if (messageId)
794
- kbMsg.messageId = messageId;
795
- this.history.add(kbMsg);
796
- await this.persistHistory();
797
- return { answer, suggestedPrompts: [] };
798
- }
799
- async answerDirectly(userMessage, conversationMessages, kbContext, generateSuggestions = true, messageId, useWebSearch = false) {
800
- if (this.debug) {
801
- console.log(`[AgentCore] Router returned no assignments, answering directly via LLM… (webSearch=${useWebSearch})`);
802
- }
803
- // When the query does NOT need live web data (greetings, chit-chat,
804
- // references to the conversation, evergreen knowledge), we answer from the
805
- // model's own knowledge. Without search grounding the model is more prone
806
- // to fabricate, so we add an explicit guard: it must admit uncertainty
807
- // instead of inventing real-time facts (prices, news, current events).
808
- const noSearchGuard = useWebSearch
809
- ? ''
810
- : '\n\nYou are answering WITHOUT live web access. Rely only on knowledge you are ' +
811
- 'confident about. If the question needs real-time or recent information you do not ' +
812
- "have (current prices, today's news, latest events), say plainly that you do not have " +
813
- 'up-to-date data instead of guessing. Never fabricate numbers, dates, or facts.';
814
- const systemContent = (kbContext
815
- ? this.systemPrompt +
816
- '\n\nYou may use the following reference material if relevant:\n\n' +
817
- '---\nREFERENCE MATERIAL:\n' +
818
- kbContext +
819
- '\n---'
820
- : this.systemPrompt) + noSearchGuard;
821
- // Direct LLM call has NO tools declared → strip tool messages to avoid
822
- // orphan functionResponse parts (Gemini 400). Also append the current
823
- // user message (caller dropped it from the history slice).
824
- const cleanHistory = (0, historyUtils_1.stripToolMessages)(conversationMessages);
825
- const directMessages = [
826
- { role: 'system', content: systemContent, timestamp: 0 },
827
- ...cleanHistory,
828
- { role: 'user', content: userMessage, timestamp: Date.now() },
829
- ];
830
- const directResponse = await this.llm.chat(directMessages, undefined, { googleSearch: useWebSearch });
831
- return await this.finaliseAnswer({ userMessage, answer: directResponse.text, messageId }, { generateSuggestions });
832
- }
833
- /**
834
- * Deterministic short-circuit for the unsupported-connected-chain case: the
835
- * wallet is on a chain this core does not support and the user did not name a
836
- * supported one, so chain-scoped tools cannot serve the request. We produce a
837
- * short, localized "chain X is not supported" reply (no tools, no suggestions)
838
- * and persist it like any other assistant turn.
839
- */
840
- async answerUnsupportedChain(rawChain, language, messageId) {
841
- if (this.debug) {
842
- console.log(`[AgentCore] connected chain "${rawChain}" is not supported → short-circuit with notice`);
843
- }
844
- const lang = (language || '').trim();
845
- // Deliberately do NOT name the unsupported network or echo its chain id:
846
- // identifying an arbitrary chain id is unreliable (a wrong name is worse than
847
- // none). We only state that the current network is unsupported + list the
848
- // supported ones. The LLM call is purely for localization.
849
- const messages = [
850
- {
851
- role: 'system',
852
- content: 'Write ONE short, polite message telling the user that the blockchain network they want to use is ' +
853
- 'NOT supported by this assistant, and inviting them to use one of the supported networks. ' +
854
- `List the supported networks: ${chainResolver_1.SUPPORTED_CHAINS_LABEL}. ` +
855
- 'Do NOT mention or guess the name or chain id of the unsupported network. ' +
856
- (lang ? `Reply in BCP-47 language "${lang}".` : 'Reply in the same language the user has been using.') +
857
- ' Do NOT mention tools or internal implementation details.',
858
- timestamp: 0,
859
- },
860
- {
861
- role: 'user',
862
- content: 'Is my currently connected network supported?',
863
- timestamp: Date.now(),
864
- },
865
- ];
866
- const response = await this.llm.chat(messages);
867
- const answer = response.text?.trim() ||
868
- `Your currently connected network is not supported yet. Supported networks: ${chainResolver_1.SUPPORTED_CHAINS_LABEL}.`;
869
- return await this.finaliseAnswer({ userMessage: `[unsupported chain: ${rawChain}]`, answer, messageId }, { generateSuggestions: false });
870
- }
871
- /**
872
- * Flatten the per-subagent ReAct steps into a single trace that the
873
- * Synthesizer can consume. The `finalAnswer` here is a compact
874
- * concatenation of each subagent's own answer, labelled by name.
875
- */
876
- mergeTrace(results) {
877
- const steps = [];
878
- for (const r of results) {
879
- steps.push({
880
- phase: 'think',
881
- content: `[${r.subagentName}] begin`,
882
- timestamp: Date.now(),
883
- });
884
- steps.push(...r.steps);
885
- steps.push({
886
- phase: 'observe',
887
- content: `[${r.subagentName}] answer: ${r.finalAnswer}`,
888
- timestamp: Date.now(),
889
- });
890
- }
891
- const finalAnswer = results.map((r) => `[${r.subagentName}] ${r.finalAnswer}`).join('\n\n');
892
- return { steps, finalAnswer };
893
- }
894
- async finaliseAnswer(params, options) {
895
- const { userMessage, answer, subagents, uiActions, actionButtons, messageId } = params ?? {};
896
- const { generateSuggestions = true } = options ?? {};
897
- const suggestedPrompts = generateSuggestions
898
- ? await this.generateSuggestions(userMessage, answer, subagents ?? [])
899
- : [];
900
- const msg = { role: 'assistant', content: answer, timestamp: Date.now() };
901
- if (subagents && subagents.length > 0)
902
- msg.subagents = subagents;
903
- if (suggestedPrompts.length > 0)
904
- msg.suggestedPrompts = suggestedPrompts;
905
- if (uiActions && uiActions.length > 0)
906
- msg.uiActions = uiActions;
907
- if (actionButtons && actionButtons.length > 0)
908
- msg.actionButtons = actionButtons;
909
- if (messageId)
910
- msg.messageId = messageId;
911
- this.history.add(msg);
912
- await this.persistHistory();
913
- return { answer, suggestedPrompts, ...(actionButtons && actionButtons.length > 0 ? { actionButtons } : {}) };
914
- }
915
- // ---- Suggested prompts ----
916
- async generateSuggestions(userMessage, answer, subagents) {
917
- // The only domain we explicitly funnel is `pool`: once the user is looking
918
- // at a pool, the most valuable next step is almost always to add liquidity
919
- // or estimate yield on THAT pool, so we hard-code that bias. For every
920
- // other domain we let the model derive suggestions from the message + answer.
921
- const poolFunnel = subagents.includes('pool')
922
- ? '\nPOOL FUNNEL: This turn was handled by the pool subagent. If the answer references a SPECIFIC pool ' +
923
- '(token pair + fee tier, or a pool address), the FIRST suggestion MUST propose adding liquidity to ' +
924
- 'THAT exact pool (e.g. "Add liquidity to USDC/WETH 0.05%"). A second suggestion should propose ' +
925
- 'estimating yield for a deposit into the same pool. Skip this funnel only if no specific pool is ' +
926
- 'identifiable in the answer.\n'
927
- : '';
928
- const handledBy = subagents.length > 0 ? `\nHandled by subagent(s): ${subagents.join(', ')}` : '';
929
- try {
930
- const response = await this.llm.chat([
931
- {
932
- role: 'user',
933
- content: 'Analyze this conversation and propose follow-up prompts the user is likely to want NEXT.\n\n' +
934
- `User: ${userMessage}\nAssistant: ${answer}${handledBy}\n` +
935
- poolFunnel +
936
- '\nRULES:\n' +
937
- '- Derive suggestions from the user message + the assistant answer. Reference concrete entities that appear there (pool name, token symbol, chain, address, NFT, wallet).\n' +
938
- '- Prefer ACTION-ORIENTED suggestions over informational ones whenever the answer makes one possible. Example after showing a pool: "Add liquidity to USDC/WETH 0.05%", not "what is a liquidity pool?".\n' +
939
- '- Reference concrete entities from the answer (pool name, token symbol, chain, address) — never generic placeholders.\n' +
940
- '- If the topic is shallow, closed-ended, or fully resolved (greetings, simple yes/no, trivial facts), return an empty array: []\n' +
941
- '- Return a JSON array of 0 to 3 strings, no other text.\n' +
942
- '- Each suggestion must be concise (under 60 chars) and phrased as something the user would TYPE.\n' +
943
- '- Suggestions must be diverse — do not repeat the same intent in different words.\n' +
944
- '- Use the same language as the user.\n' +
945
- '- Good example (pool): ["Add liquidity to USDC/WETH 0.05%", "Estimate yield for $1000 here", "Compare with 0.3% fee tier"]\n' +
946
- '- Bad example: ["What is a pool?", "How do pools work?", "Tell me more"] (generic, no action, no specifics)',
947
- timestamp: 0,
948
- },
949
- ]);
950
- const match = response.text.match(/\[[\s\S]*\]/);
951
- if (!match)
952
- return [];
953
- const suggestions = JSON.parse(match[0]);
954
- return suggestions.filter((s) => typeof s === 'string' && s.length > 0).slice(0, 3);
955
- }
956
- catch {
957
- return [];
958
- }
959
- }
960
- // ---- History management ----
961
- getHistory() {
962
- return this.history.getAllFull();
963
- }
964
- /**
965
- * History filtered down to user-facing messages only — the user's prompts
966
- * and each turn's final assistant reply. Internal records (tool calls,
967
- * tool results, system summaries, and `_intermediate` bridging assistant
968
- * messages) are dropped, as is any assistant message with empty content
969
- * (a pure tool-call turn). Use this to seed a chat UI on mount.
970
- */
971
- getDisplayHistory() {
972
- return this.history.getAllFull().filter((m) => {
973
- if (m.role !== 'user' && m.role !== 'assistant')
974
- return false;
975
- if (m._intermediate)
976
- return false;
977
- if (m.role === 'assistant' && !m.content?.trim())
978
- return false;
979
- return true;
980
- });
981
- }
982
- /**
983
- * Suggested follow-up prompts attached to the most recent final assistant
984
- * turn, or `[]` if none. Used to re-seed suggestion chips after restoring
985
- * a persisted session — the chips travel with the assistant message in
986
- * storage, so this just locates the last one.
987
- */
988
- getLastSuggestions() {
989
- const display = this.getDisplayHistory();
990
- for (let i = display.length - 1; i >= 0; i--) {
991
- const m = display[i];
992
- if (m.role === 'assistant')
993
- return m.suggestedPrompts ?? [];
994
- }
995
- return [];
996
- }
997
- async clearHistory() {
998
- this.history.clear();
999
- this.historyLoaded = true; // cleared intentionally, no need to re-load
1000
- this.historyLoadingPromise = null;
1001
- await this.persistHistory();
1002
- }
1003
- restoreHistory(data) {
1004
- this.history.restore(data);
1005
- }
1006
- serialiseHistory() {
1007
- return this.history.serialise();
1008
- }
1009
- // ---- Internals ----
1010
- async compactHistory() {
1011
- if (this.debug) {
1012
- console.log('[AgentCore] Summarizing conversation history…');
1013
- }
1014
- const all = this.history.getAll();
1015
- // Keep the last 6 user turns (plus any tool messages belonging to those
1016
- // turns) so the working window always has meaningful recent context.
1017
- // We count backward by user turns rather than raw message count because
1018
- // tool exchanges inflate the raw count without adding user-visible turns.
1019
- const USER_TURNS_TO_KEEP = 6;
1020
- let userTurnsSeen = 0;
1021
- let keepStart = all.length;
1022
- for (let i = all.length - 1; i >= 0; i--) {
1023
- if (all[i].role === 'user') {
1024
- userTurnsSeen++;
1025
- if (userTurnsSeen >= USER_TURNS_TO_KEEP) {
1026
- keepStart = i;
1027
- break;
1028
- }
1029
- }
1030
- }
1031
- // Never split a tool-call group at the boundary.
1032
- const rawTail = all.slice(keepStart);
1033
- const keepTail = (0, historyUtils_1.trimPreservingToolPairs)(rawTail, rawTail.length);
1034
- const tailStart = all.length - keepTail.length;
1035
- const toSummarize = (0, historyUtils_1.stripToolMessages)(all.slice(0, tailStart));
1036
- const existingSummary = this.history.getSummary();
1037
- // Prepend the existing summary as a User turn so Summarizer includes it
1038
- // in the rolling summary (Summarizer filters to user/assistant only).
1039
- const messagesForSummary = [];
1040
- if (existingSummary) {
1041
- messagesForSummary.push({
1042
- role: 'user',
1043
- content: `[Previous context summary]: ${existingSummary}`,
1044
- timestamp: 0,
1045
- });
1046
- }
1047
- messagesForSummary.push(...toSummarize);
1048
- const summary = await this.summarizer.summarize(messagesForSummary);
1049
- this.history.compactWith(summary, keepTail);
1050
- }
1051
- /**
1052
- * Persist the interleaved assistant+toolCalls / role:'tool' messages from
1053
- * each subagent run into ChatHistory, followed by the subagent's finalAnswer
1054
- * as a plain assistant turn.
1055
- *
1056
- * The full sequence stored per subagent is:
1057
- * model(functionCall) → function(response) → ... → model(text: finalAnswer)
1058
- *
1059
- * This satisfies Gemini's strict turn-order rule: a function-response turn
1060
- * must always be followed by a model turn before the next user message.
1061
- * Without the trailing model(text), the history ends with function(response)
1062
- * and the next user message causes a 400 "function call turn must come
1063
- * immediately after a user turn" error.
1064
- */
1065
- persistToolMessages(results) {
1066
- for (const r of results) {
1067
- if (r.toolMessages.length > 0) {
1068
- this.history.addMany(r.toolMessages);
1069
- // Append the subagent's final text answer so the history always ends
1070
- // with model(text) after a tool exchange — never with function(response).
1071
- this.history.add({
1072
- role: 'assistant',
1073
- content: r.finalAnswer,
1074
- _intermediate: true,
1075
- timestamp: Date.now(),
1076
- });
1077
- if (this.debug) {
1078
- console.log(`[AgentCore] stored ${r.toolMessages.length} tool message(s) + finalAnswer from ${r.subagentName}`);
1079
- }
1080
- }
1081
- }
1082
- }
1083
- /** Expose the LLM provider for advanced usage. */
1084
- getLLMProvider() {
1085
- return this.llm;
1086
- }
1087
- /** Expose the tool registry for advanced usage. */
1088
- getToolRegistry() {
1089
- return this.registry;
1090
- }
1091
- }
1092
- exports.AgentCore = AgentCore;
1093
- //# sourceMappingURL=AgentCore.js.map