keyring-agent-core 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/AgentCore.d.ts +37 -1
- package/dist/agent/AgentCore.d.ts.map +1 -1
- package/dist/agent/AgentCore.js +287 -144
- package/dist/agent/AgentCore.js.map +1 -1
- package/dist/agent/QueryRewriter.d.ts +17 -0
- package/dist/agent/QueryRewriter.d.ts.map +1 -1
- package/dist/agent/QueryRewriter.js +48 -4
- package/dist/agent/QueryRewriter.js.map +1 -1
- package/dist/agent/Router.d.ts.map +1 -1
- package/dist/agent/Router.js +73 -35
- package/dist/agent/Router.js.map +1 -1
- package/dist/agent/Subagent.d.ts +17 -0
- package/dist/agent/Subagent.d.ts.map +1 -1
- package/dist/agent/Subagent.js +32 -0
- package/dist/agent/Subagent.js.map +1 -1
- package/dist/agent/chatGraph.d.ts +364 -0
- package/dist/agent/chatGraph.d.ts.map +1 -0
- package/dist/agent/chatGraph.js +184 -0
- package/dist/agent/chatGraph.js.map +1 -0
- package/dist/agent/subagents/AiAgent.d.ts +1 -1
- package/dist/agent/subagents/AiAgent.d.ts.map +1 -1
- package/dist/agent/subagents/AiAgent.js +24 -20
- package/dist/agent/subagents/AiAgent.js.map +1 -1
- package/dist/agent/subagents/NftAgent.d.ts +1 -1
- package/dist/agent/subagents/NftAgent.d.ts.map +1 -1
- package/dist/agent/subagents/NftAgent.js +36 -26
- package/dist/agent/subagents/NftAgent.js.map +1 -1
- package/dist/agent/subagents/PoolSubgraphAgent.d.ts +6 -0
- package/dist/agent/subagents/PoolSubgraphAgent.d.ts.map +1 -0
- package/dist/agent/subagents/PoolSubgraphAgent.js +117 -0
- package/dist/agent/subagents/PoolSubgraphAgent.js.map +1 -0
- package/dist/agent/subagents/TokenAgent.d.ts +1 -1
- package/dist/agent/subagents/TokenAgent.d.ts.map +1 -1
- package/dist/agent/subagents/TokenAgent.js +23 -22
- package/dist/agent/subagents/TokenAgent.js.map +1 -1
- package/dist/agent/subagents/WalletActionAgent.d.ts +6 -0
- package/dist/agent/subagents/WalletActionAgent.d.ts.map +1 -0
- package/dist/agent/subagents/WalletActionAgent.js +55 -0
- package/dist/agent/subagents/WalletActionAgent.js.map +1 -0
- package/dist/agent/subagents/WalletAgent.d.ts +1 -1
- package/dist/agent/subagents/WalletAgent.d.ts.map +1 -1
- package/dist/agent/subagents/WalletAgent.js +18 -17
- package/dist/agent/subagents/WalletAgent.js.map +1 -1
- package/dist/agent/subagents/index.d.ts +23 -3
- package/dist/agent/subagents/index.d.ts.map +1 -1
- package/dist/agent/subagents/index.js +42 -11
- package/dist/agent/subagents/index.js.map +1 -1
- package/dist/constants/abi.d.ts +31 -0
- package/dist/constants/abi.d.ts.map +1 -1
- package/dist/constants/abi.js +24 -1
- package/dist/constants/abi.js.map +1 -1
- package/dist/functions/web3.d.ts +0 -1
- package/dist/functions/web3.d.ts.map +1 -1
- package/dist/functions/web3.js +0 -45
- package/dist/functions/web3.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/llm/GeminiProvider.d.ts.map +1 -1
- package/dist/llm/GeminiProvider.js +115 -34
- package/dist/llm/GeminiProvider.js.map +1 -1
- package/dist/memory/UpstashKnowledgeBase.d.ts +1 -1
- package/dist/memory/UpstashKnowledgeBase.js +1 -1
- package/dist/services/MoralisService.d.ts +3 -25
- package/dist/services/MoralisService.d.ts.map +1 -1
- package/dist/services/MoralisService.js +7 -132
- package/dist/services/MoralisService.js.map +1 -1
- package/dist/services/PantographService.d.ts +61 -1
- package/dist/services/PantographService.d.ts.map +1 -1
- package/dist/services/PantographService.js +264 -12
- package/dist/services/PantographService.js.map +1 -1
- package/dist/services/PoolService.d.ts +1 -4
- package/dist/services/PoolService.d.ts.map +1 -1
- package/dist/services/PoolService.js +18 -40
- package/dist/services/PoolService.js.map +1 -1
- package/dist/services/UniswapSubgraphService.d.ts +144 -0
- package/dist/services/UniswapSubgraphService.d.ts.map +1 -0
- package/dist/services/UniswapSubgraphService.js +606 -0
- package/dist/services/UniswapSubgraphService.js.map +1 -0
- package/dist/services/rpc.d.ts +35 -0
- package/dist/services/rpc.d.ts.map +1 -0
- package/dist/services/rpc.js +110 -0
- package/dist/services/rpc.js.map +1 -0
- package/dist/services/swap/DebridgeAdapter.d.ts +17 -0
- package/dist/services/swap/DebridgeAdapter.d.ts.map +1 -1
- package/dist/services/swap/DebridgeAdapter.js +74 -6
- package/dist/services/swap/DebridgeAdapter.js.map +1 -1
- package/dist/services/swap/SwapServiceFactory.d.ts +1 -0
- package/dist/services/swap/SwapServiceFactory.d.ts.map +1 -1
- package/dist/services/swap/SwapServiceFactory.js +8 -3
- package/dist/services/swap/SwapServiceFactory.js.map +1 -1
- package/dist/tools/builtin/ai/GeminiSearchAiTool.d.ts +36 -0
- package/dist/tools/builtin/ai/GeminiSearchAiTool.d.ts.map +1 -0
- package/dist/tools/builtin/ai/GeminiSearchAiTool.js +91 -0
- package/dist/tools/builtin/ai/GeminiSearchAiTool.js.map +1 -0
- package/dist/tools/builtin/ai/index.d.ts +2 -4
- package/dist/tools/builtin/ai/index.d.ts.map +1 -1
- package/dist/tools/builtin/ai/index.js +3 -5
- package/dist/tools/builtin/ai/index.js.map +1 -1
- package/dist/tools/builtin/index.d.ts +2 -0
- package/dist/tools/builtin/index.d.ts.map +1 -1
- package/dist/tools/builtin/index.js +2 -0
- package/dist/tools/builtin/index.js.map +1 -1
- package/dist/tools/builtin/nft/BaseNftMessageTool.d.ts +35 -0
- package/dist/tools/builtin/nft/BaseNftMessageTool.d.ts.map +1 -0
- package/dist/tools/builtin/nft/BaseNftMessageTool.js +45 -0
- package/dist/tools/builtin/nft/BaseNftMessageTool.js.map +1 -0
- package/dist/tools/builtin/nft/NFTContractInfoTool.d.ts +7 -13
- package/dist/tools/builtin/nft/NFTContractInfoTool.d.ts.map +1 -1
- package/dist/tools/builtin/nft/NFTContractInfoTool.js +8 -43
- package/dist/tools/builtin/nft/NFTContractInfoTool.js.map +1 -1
- package/dist/tools/builtin/nft/NFTMetadataTool.d.ts +7 -113
- package/dist/tools/builtin/nft/NFTMetadataTool.d.ts.map +1 -1
- package/dist/tools/builtin/nft/NFTMetadataTool.js +9 -148
- package/dist/tools/builtin/nft/NFTMetadataTool.js.map +1 -1
- package/dist/tools/builtin/nft/SendNftTool.d.ts +14 -0
- package/dist/tools/builtin/nft/SendNftTool.d.ts.map +1 -0
- package/dist/tools/builtin/nft/SendNftTool.js +20 -0
- package/dist/tools/builtin/nft/SendNftTool.js.map +1 -0
- package/dist/tools/builtin/nft/WalletNFTsTool.d.ts +7 -74
- package/dist/tools/builtin/nft/WalletNFTsTool.d.ts.map +1 -1
- package/dist/tools/builtin/nft/WalletNFTsTool.js +9 -161
- package/dist/tools/builtin/nft/WalletNFTsTool.js.map +1 -1
- package/dist/tools/builtin/pool/EstimatePoolYieldTool.d.ts.map +1 -1
- package/dist/tools/builtin/pool/EstimatePoolYieldTool.js +4 -3
- package/dist/tools/builtin/pool/EstimatePoolYieldTool.js.map +1 -1
- package/dist/tools/builtin/pool/OpenAddLiquidityFormTool.d.ts +1 -0
- package/dist/tools/builtin/pool/OpenAddLiquidityFormTool.d.ts.map +1 -1
- package/dist/tools/builtin/pool/OpenAddLiquidityFormTool.js +8 -5
- package/dist/tools/builtin/pool/OpenAddLiquidityFormTool.js.map +1 -1
- package/dist/tools/builtin/pool/PoolByAddressTool.d.ts.map +1 -1
- package/dist/tools/builtin/pool/PoolByAddressTool.js +4 -3
- package/dist/tools/builtin/pool/PoolByAddressTool.js.map +1 -1
- package/dist/tools/builtin/pool/PoolDetailTool.d.ts.map +1 -1
- package/dist/tools/builtin/pool/PoolDetailTool.js +4 -3
- package/dist/tools/builtin/pool/PoolDetailTool.js.map +1 -1
- package/dist/tools/builtin/pool/PoolSearchTool.d.ts.map +1 -1
- package/dist/tools/builtin/pool/PoolSearchTool.js +4 -3
- package/dist/tools/builtin/pool/PoolSearchTool.js.map +1 -1
- package/dist/tools/builtin/pool/PreviewAddLiquidityTool.d.ts +1 -0
- package/dist/tools/builtin/pool/PreviewAddLiquidityTool.d.ts.map +1 -1
- package/dist/tools/builtin/pool/PreviewAddLiquidityTool.js +5 -3
- package/dist/tools/builtin/pool/PreviewAddLiquidityTool.js.map +1 -1
- package/dist/tools/builtin/pool/TopPoolsTool.d.ts.map +1 -1
- package/dist/tools/builtin/pool/TopPoolsTool.js +4 -3
- package/dist/tools/builtin/pool/TopPoolsTool.js.map +1 -1
- package/dist/tools/builtin/pool-subgraph/SubgraphCoinPoolPairsTool.d.ts +54 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphCoinPoolPairsTool.d.ts.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphCoinPoolPairsTool.js +98 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphCoinPoolPairsTool.js.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolByAddressTool.d.ts +63 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolByAddressTool.d.ts.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolByAddressTool.js +82 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolByAddressTool.js.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolByPositionIdTool.d.ts +79 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolByPositionIdTool.d.ts.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolByPositionIdTool.js +97 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolByPositionIdTool.js.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolSearchTool.d.ts +77 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolSearchTool.d.ts.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolSearchTool.js +190 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPoolSearchTool.js.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPositionDetailTool.d.ts +107 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPositionDetailTool.d.ts.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPositionDetailTool.js +92 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphPositionDetailTool.js.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphTrendingPoolsTool.d.ts +56 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphTrendingPoolsTool.d.ts.map +1 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphTrendingPoolsTool.js +94 -0
- package/dist/tools/builtin/pool-subgraph/SubgraphTrendingPoolsTool.js.map +1 -0
- package/dist/tools/builtin/pool-subgraph/index.d.ts +13 -0
- package/dist/tools/builtin/pool-subgraph/index.d.ts.map +1 -0
- package/dist/tools/builtin/pool-subgraph/index.js +18 -0
- package/dist/tools/builtin/pool-subgraph/index.js.map +1 -0
- package/dist/tools/builtin/token/TokenAnalyticsTool.d.ts.map +1 -1
- package/dist/tools/builtin/token/TokenAnalyticsTool.js +4 -3
- package/dist/tools/builtin/token/TokenAnalyticsTool.js.map +1 -1
- package/dist/tools/builtin/token/TokenHoldersTool.d.ts.map +1 -1
- package/dist/tools/builtin/token/TokenHoldersTool.js +4 -3
- package/dist/tools/builtin/token/TokenHoldersTool.js.map +1 -1
- package/dist/tools/builtin/token/TokenInfoTool.d.ts +6 -2
- package/dist/tools/builtin/token/TokenInfoTool.d.ts.map +1 -1
- package/dist/tools/builtin/token/TokenInfoTool.js +66 -8
- package/dist/tools/builtin/token/TokenInfoTool.js.map +1 -1
- package/dist/tools/builtin/token/TokenScoreTool.d.ts.map +1 -1
- package/dist/tools/builtin/token/TokenScoreTool.js +4 -3
- package/dist/tools/builtin/token/TokenScoreTool.js.map +1 -1
- package/dist/tools/builtin/token/TopGainersTool.d.ts +10 -19
- package/dist/tools/builtin/token/TopGainersTool.d.ts.map +1 -1
- package/dist/tools/builtin/token/TopGainersTool.js +44 -54
- package/dist/tools/builtin/token/TopGainersTool.js.map +1 -1
- package/dist/tools/builtin/token/TopLosersTool.d.ts.map +1 -1
- package/dist/tools/builtin/token/TopLosersTool.js +3 -2
- package/dist/tools/builtin/token/TopLosersTool.js.map +1 -1
- package/dist/tools/builtin/token/TrendingTokensTool.d.ts +1 -1
- package/dist/tools/builtin/token/TrendingTokensTool.d.ts.map +1 -1
- package/dist/tools/builtin/token/TrendingTokensTool.js +20 -12
- package/dist/tools/builtin/token/TrendingTokensTool.js.map +1 -1
- package/dist/tools/builtin/token/index.d.ts +0 -2
- package/dist/tools/builtin/token/index.d.ts.map +1 -1
- package/dist/tools/builtin/token/index.js +1 -3
- package/dist/tools/builtin/token/index.js.map +1 -1
- package/dist/tools/builtin/wallet/TransactionByHashTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/TransactionByHashTool.js +4 -3
- package/dist/tools/builtin/wallet/TransactionByHashTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletApprovalsTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletApprovalsTool.js +4 -3
- package/dist/tools/builtin/wallet/WalletApprovalsTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletDefiPositionsTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletDefiPositionsTool.js +4 -3
- package/dist/tools/builtin/wallet/WalletDefiPositionsTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletDefiProtocolPositionsTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletDefiProtocolPositionsTool.js +4 -3
- package/dist/tools/builtin/wallet/WalletDefiProtocolPositionsTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletDefiSummaryTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletDefiSummaryTool.js +4 -3
- package/dist/tools/builtin/wallet/WalletDefiSummaryTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletHistoryTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletHistoryTool.js +5 -4
- package/dist/tools/builtin/wallet/WalletHistoryTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletNetWorthTool.js +1 -1
- package/dist/tools/builtin/wallet/WalletNetWorthTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletNftTransfersTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletNftTransfersTool.js +5 -4
- package/dist/tools/builtin/wallet/WalletNftTransfersTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletPnlSummaryTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletPnlSummaryTool.js +4 -3
- package/dist/tools/builtin/wallet/WalletPnlSummaryTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletPnlTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletPnlTool.js +4 -3
- package/dist/tools/builtin/wallet/WalletPnlTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletTokenBalancesTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletTokenBalancesTool.js +4 -3
- package/dist/tools/builtin/wallet/WalletTokenBalancesTool.js.map +1 -1
- package/dist/tools/builtin/wallet/WalletTokenTransfersTool.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/WalletTokenTransfersTool.js +5 -4
- package/dist/tools/builtin/wallet/WalletTokenTransfersTool.js.map +1 -1
- package/dist/tools/builtin/wallet/index.d.ts +3 -0
- package/dist/tools/builtin/wallet/index.d.ts.map +1 -1
- package/dist/tools/builtin/wallet/index.js +5 -1
- package/dist/tools/builtin/wallet/index.js.map +1 -1
- package/dist/tools/builtin/wallet-action/ApproveTokenTool.d.ts +25 -0
- package/dist/tools/builtin/wallet-action/ApproveTokenTool.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/ApproveTokenTool.js +98 -0
- package/dist/tools/builtin/wallet-action/ApproveTokenTool.js.map +1 -0
- package/dist/tools/builtin/wallet-action/BaseWalletActionTool.d.ts +211 -0
- package/dist/tools/builtin/wallet-action/BaseWalletActionTool.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/BaseWalletActionTool.js +499 -0
- package/dist/tools/builtin/wallet-action/BaseWalletActionTool.js.map +1 -0
- package/dist/tools/builtin/wallet-action/BuyTokenTool.d.ts +240 -0
- package/dist/tools/builtin/wallet-action/BuyTokenTool.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/BuyTokenTool.js +1257 -0
- package/dist/tools/builtin/wallet-action/BuyTokenTool.js.map +1 -0
- package/dist/tools/builtin/wallet-action/SendNativeTool.d.ts +41 -0
- package/dist/tools/builtin/wallet-action/SendNativeTool.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/SendNativeTool.js +127 -0
- package/dist/tools/builtin/wallet-action/SendNativeTool.js.map +1 -0
- package/dist/tools/builtin/wallet-action/SendTokenTool.d.ts +63 -0
- package/dist/tools/builtin/wallet-action/SendTokenTool.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/SendTokenTool.js +294 -0
- package/dist/tools/builtin/wallet-action/SendTokenTool.js.map +1 -0
- package/dist/tools/builtin/wallet-action/SwapTokenTool.d.ts +247 -0
- package/dist/tools/builtin/wallet-action/SwapTokenTool.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/SwapTokenTool.js +1258 -0
- package/dist/tools/builtin/wallet-action/SwapTokenTool.js.map +1 -0
- package/dist/tools/builtin/wallet-action/UnwrapNativeTool.d.ts +20 -0
- package/dist/tools/builtin/wallet-action/UnwrapNativeTool.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/UnwrapNativeTool.js +36 -0
- package/dist/tools/builtin/wallet-action/UnwrapNativeTool.js.map +1 -0
- package/dist/tools/builtin/wallet-action/WrapNativeTool.d.ts +23 -0
- package/dist/tools/builtin/wallet-action/WrapNativeTool.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/WrapNativeTool.js +54 -0
- package/dist/tools/builtin/wallet-action/WrapNativeTool.js.map +1 -0
- package/dist/tools/builtin/wallet-action/amountSpec.d.ts +62 -0
- package/dist/tools/builtin/wallet-action/amountSpec.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/amountSpec.js +93 -0
- package/dist/tools/builtin/wallet-action/amountSpec.js.map +1 -0
- package/dist/tools/builtin/wallet-action/gasReserve.d.ts +42 -0
- package/dist/tools/builtin/wallet-action/gasReserve.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/gasReserve.js +103 -0
- package/dist/tools/builtin/wallet-action/gasReserve.js.map +1 -0
- package/dist/tools/builtin/wallet-action/index.d.ts +9 -0
- package/dist/tools/builtin/wallet-action/index.d.ts.map +1 -0
- package/dist/tools/builtin/wallet-action/index.js +20 -0
- package/dist/tools/builtin/wallet-action/index.js.map +1 -0
- package/dist/tools/chainResolver.d.ts +98 -0
- package/dist/tools/chainResolver.d.ts.map +1 -0
- package/dist/tools/chainResolver.js +302 -0
- package/dist/tools/chainResolver.js.map +1 -0
- package/dist/types/index.d.ts +218 -7
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +5 -2
- package/dist/tools/builtin/ai/MoralisCortexTool.d.ts +0 -33
- package/dist/tools/builtin/ai/MoralisCortexTool.d.ts.map +0 -1
- package/dist/tools/builtin/ai/MoralisCortexTool.js +0 -76
- package/dist/tools/builtin/ai/MoralisCortexTool.js.map +0 -1
- package/dist/tools/builtin/ai/SolanaCortexTool.d.ts +0 -22
- package/dist/tools/builtin/ai/SolanaCortexTool.d.ts.map +0 -1
- package/dist/tools/builtin/ai/SolanaCortexTool.js +0 -80
- package/dist/tools/builtin/ai/SolanaCortexTool.js.map +0 -1
package/dist/agent/AgentCore.js
CHANGED
|
@@ -13,6 +13,9 @@ const Router_1 = require("./Router");
|
|
|
13
13
|
const subagents_1 = require("./subagents");
|
|
14
14
|
const Synthesizer_1 = require("./Synthesizer");
|
|
15
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");
|
|
16
19
|
/** Generate a short stable id for one response turn (8 hex chars). */
|
|
17
20
|
function generateMessageId() {
|
|
18
21
|
const ts = Date.now().toString(16);
|
|
@@ -43,6 +46,8 @@ class AgentCore {
|
|
|
43
46
|
rewriter;
|
|
44
47
|
subagents;
|
|
45
48
|
synthesizer;
|
|
49
|
+
/** Compiled LangGraph that orchestrates one chat turn. */
|
|
50
|
+
chatGraph;
|
|
46
51
|
systemPrompt;
|
|
47
52
|
debug;
|
|
48
53
|
userContext = {};
|
|
@@ -73,6 +78,11 @@ class AgentCore {
|
|
|
73
78
|
*/
|
|
74
79
|
historyReady;
|
|
75
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);
|
|
76
86
|
this.llm = new GeminiProvider_1.GeminiProvider(config.llm);
|
|
77
87
|
this.registry = new ToolRegistry_1.ToolRegistry();
|
|
78
88
|
this.history = new ChatHistory_1.ChatHistory(config.maxHistoryMessages ?? 50);
|
|
@@ -142,10 +152,8 @@ class AgentCore {
|
|
|
142
152
|
if (config.moralis !== false) {
|
|
143
153
|
const moralisConfig = typeof config.moralis === 'object' ? config.moralis : undefined;
|
|
144
154
|
this.registry.register(new builtin_1.WalletTokenBalancesTool(moralisConfig));
|
|
155
|
+
// this.registry.register(new WalletNetWorthTool(moralisConfig)); deprecated
|
|
145
156
|
this.registry.register(new builtin_1.TokenInfoTool(moralisConfig));
|
|
146
|
-
this.registry.register(new builtin_1.WalletNFTsTool(moralisConfig));
|
|
147
|
-
this.registry.register(new builtin_1.NFTContractInfoTool(moralisConfig));
|
|
148
|
-
this.registry.register(new builtin_1.NFTMetadataTool(moralisConfig));
|
|
149
157
|
this.registry.register(new builtin_1.WalletHistoryTool(moralisConfig));
|
|
150
158
|
this.registry.register(new builtin_1.WalletTokenTransfersTool(moralisConfig));
|
|
151
159
|
this.registry.register(new builtin_1.WalletNftTransfersTool(moralisConfig));
|
|
@@ -153,20 +161,39 @@ class AgentCore {
|
|
|
153
161
|
this.registry.register(new builtin_1.WalletPnlSummaryTool(moralisConfig));
|
|
154
162
|
this.registry.register(new builtin_1.WalletPnlTool(moralisConfig));
|
|
155
163
|
this.registry.register(new builtin_1.TransactionByHashTool(moralisConfig));
|
|
156
|
-
this.registry.register(new builtin_1.SolanaCortexTool(moralisConfig));
|
|
157
164
|
this.registry.register(new builtin_1.WalletDefiSummaryTool(moralisConfig));
|
|
158
165
|
this.registry.register(new builtin_1.WalletDefiPositionsTool(moralisConfig));
|
|
159
166
|
this.registry.register(new builtin_1.WalletDefiProtocolPositionsTool(moralisConfig));
|
|
160
167
|
this.registry.register(new builtin_1.WalletApprovalsTool(moralisConfig));
|
|
161
168
|
this.registry.register(new builtin_1.TrendingTokensTool(moralisConfig));
|
|
162
|
-
|
|
163
|
-
// this.registry.register(new TopLosersTool(moralisConfig)); //Deprecated
|
|
169
|
+
this.registry.register(new builtin_1.TopGainersTool(moralisConfig));
|
|
164
170
|
this.registry.register(new builtin_1.TokenAnalyticsTool(moralisConfig));
|
|
165
171
|
this.registry.register(new builtin_1.TokenScoreTool(moralisConfig));
|
|
166
|
-
this.registry.register(new builtin_1.MoralisCortexTool(moralisConfig));
|
|
167
172
|
}
|
|
168
|
-
//
|
|
169
|
-
|
|
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) {
|
|
170
197
|
const uniswapConfig = typeof config.uniswap === 'object' ? config.uniswap : undefined;
|
|
171
198
|
this.registry.register(new builtin_1.TopPoolsTool(uniswapConfig));
|
|
172
199
|
this.registry.register(new builtin_1.PoolDetailTool(uniswapConfig));
|
|
@@ -174,12 +201,9 @@ class AgentCore {
|
|
|
174
201
|
this.registry.register(new builtin_1.PoolByAddressTool(uniswapConfig));
|
|
175
202
|
this.registry.register(new builtin_1.EstimatePoolYieldTool(uniswapConfig));
|
|
176
203
|
// Add-liquidity action tools (need on-chain RPC + gateway addresses).
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
isProduction: uniswapConfig.isProduction,
|
|
181
|
-
}
|
|
182
|
-
: undefined;
|
|
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;
|
|
183
207
|
this.registry.register(new builtin_1.OpenAddLiquidityFormTool({
|
|
184
208
|
baseUrl: uniswapConfig?.baseUrl,
|
|
185
209
|
pool: poolServiceConfig,
|
|
@@ -187,16 +211,51 @@ class AgentCore {
|
|
|
187
211
|
}));
|
|
188
212
|
this.registry.register(new builtin_1.PreviewAddLiquidityTool({ pool: poolServiceConfig }));
|
|
189
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 }));
|
|
190
244
|
// Wire router + subagents. Subagents share the same registry, so any custom
|
|
191
245
|
// tools registered later via `registerTool()` become available as long as
|
|
192
246
|
// their name matches one of the subagent's declared tool names.
|
|
193
247
|
this.router = new Router_1.Router(this.llm, { debug: this.debug });
|
|
194
248
|
this.rewriter = new QueryRewriter_1.QueryRewriter(this.llm, { debug: this.debug });
|
|
249
|
+
const subgraphConfigObj = typeof config.subgraph === 'object' ? config.subgraph : undefined;
|
|
195
250
|
const subagentList = (0, subagents_1.createDefaultSubagents)(this.llm, this.registry, {
|
|
196
251
|
maxToolCalls: config.maxIterations ?? 5,
|
|
197
252
|
debug: this.debug,
|
|
198
|
-
|
|
253
|
+
linkAddLiquidity: subgraphConfigObj?.linkAddLiquidity,
|
|
254
|
+
}, config.subagents);
|
|
199
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());
|
|
200
259
|
// Kick off the initial history load eagerly so consumers that read
|
|
201
260
|
// history synchronously right after `new AgentCore(...)` (e.g. a React
|
|
202
261
|
// component reading `getHistory()` during its first render) can await
|
|
@@ -429,138 +488,105 @@ class AgentCore {
|
|
|
429
488
|
*/
|
|
430
489
|
async chat(userMessage, options) {
|
|
431
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() : '';
|
|
432
497
|
// Ensure history is loaded from storage before processing the first message.
|
|
433
498
|
// This is a no-op if already loaded, and deduplicates concurrent calls so
|
|
434
499
|
// a racing useEffect loadHistory() and this call don't double-load.
|
|
435
500
|
await this.loadHistory();
|
|
436
501
|
// First-call auto-ingest for vector KB (if configured). Idempotent.
|
|
437
502
|
await this.maybeAutoIngest(this.autoIngestEnabled);
|
|
438
|
-
this.addUserMessage(userMessage);
|
|
439
|
-
if (this.history.needsSummary()) {
|
|
440
|
-
await this.compactHistory();
|
|
441
|
-
}
|
|
442
|
-
// Drop the trailing user message itself so Router/Subagent prompts don't
|
|
443
|
-
// duplicate it (we pass the query separately as "User query: …"). Keeping
|
|
444
|
-
// it would cause Gemini to focus on the last (standalone) user message
|
|
445
|
-
// and lose the prior context needed to resolve follow-ups.
|
|
446
|
-
const rawHistory = this.history.getConversation();
|
|
447
|
-
const conversationMessages = rawHistory.length > 0 && rawHistory[rawHistory.length - 1].role === 'user' ? rawHistory.slice(0, -1) : rawHistory;
|
|
448
503
|
const turnStart = Date.now();
|
|
449
504
|
if (this.debug) {
|
|
450
505
|
console.log(`\n${'─'.repeat(60)}`);
|
|
451
506
|
console.log(`[AgentCore] query: "${userMessage}"`);
|
|
452
507
|
}
|
|
453
|
-
//
|
|
454
|
-
//
|
|
455
|
-
//
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
console.log(`[AgentCore] previous turn handled by: ${lastSubagents.join(', ')}`);
|
|
459
|
-
}
|
|
460
|
-
// Stage 1 — Contextualize. Resolve coreferences / ellipsis / follow-ups
|
|
461
|
-
// BEFORE the Router so every downstream component (KB, Router, Subagent)
|
|
462
|
-
// operates on a fully-specified standalone question.
|
|
463
|
-
// See Alhena "Contextualizer" (2025) + "LLMs Get Lost in Multi-Turn" (ICLR 2025).
|
|
464
|
-
const rewrite = await this.rewriter.rewrite(userMessage, conversationMessages, lastSubagents);
|
|
465
|
-
if (this.debug) {
|
|
466
|
-
console.log('🚀 ~ AgentCore ~ chat ~ rewrite:', rewrite);
|
|
467
|
-
}
|
|
468
|
-
const effectiveQuery = rewrite.rewrittenQuery;
|
|
469
|
-
// Stage 2 — KB search.
|
|
470
|
-
// - For follow-ups ("yes" / "tiếp" / "thế còn..."), search with the
|
|
471
|
-
// rewritten query so we have enough signal to match anything.
|
|
472
|
-
// - For self-contained turns, search with the ORIGINAL message: it is
|
|
473
|
-
// what the user actually typed and is therefore the closest possible
|
|
474
|
-
// input to what the embedding model saw at upsert time. The rewriter
|
|
475
|
-
// is an LLM and may paraphrase even when told not to — which silently
|
|
476
|
-
// degrades retrieval (e.g. "CoinPool an toàn không?" gets reworded
|
|
477
|
-
// into something that no longer scores high against the indexed
|
|
478
|
-
// phrasing).
|
|
479
|
-
const kbQuery = rewrite.isFollowUp ? effectiveQuery : userMessage;
|
|
480
|
-
if (this.debug && kbQuery !== effectiveQuery) {
|
|
481
|
-
console.log(`[AgentCore] KB search using original message (not rewritten): "${kbQuery}"`);
|
|
482
|
-
}
|
|
483
|
-
const kbHits = await this.searchKB(kbQuery);
|
|
484
|
-
const kbContext = this.formatKBContext(kbHits);
|
|
485
|
-
// High-confidence KB match → answer via KB, then rollback the user message
|
|
486
|
-
// from the working window so this exchange never enters the LLM context.
|
|
487
|
-
// Both messages are written to fullMessages only (UI log).
|
|
488
|
-
const messageId = generateMessageId();
|
|
489
|
-
const kbAnswer = await this.tryAnswerFromKB(userMessage, kbHits, kbContext, messageId);
|
|
490
|
-
if (kbAnswer) {
|
|
491
|
-
return { ...kbAnswer, messageId, rewrite };
|
|
492
|
-
}
|
|
493
|
-
const cards = Array.from(this.subagents.values()).map((s) => s.getCard());
|
|
494
|
-
const decision = await this.router.route(effectiveQuery, conversationMessages, cards, this.userContext, lastSubagents);
|
|
495
|
-
// No subagent needed → answer directly via LLM
|
|
496
|
-
if (decision.assignments.length === 0) {
|
|
497
|
-
const direct = await this.answerDirectly(effectiveQuery, conversationMessages, kbContext, doSuggest, messageId);
|
|
498
|
-
if (this.debug)
|
|
499
|
-
console.log(`[AgentCore] turn done in ${Date.now() - turnStart}ms (direct LLM)\n`);
|
|
500
|
-
return { ...direct, messageId, routerDecision: decision, rewrite };
|
|
501
|
-
}
|
|
502
|
-
// Dispatch subagents in parallel
|
|
503
|
-
const subResults = await this.router.dispatch(decision, this.subagents, conversationMessages, this.userContext);
|
|
504
|
-
// Persist tool call/result messages BEFORE synthesising so the synthesiser
|
|
505
|
-
// (and all future turns) can see this turn's tool data via history.
|
|
506
|
-
this.persistToolMessages(subResults);
|
|
507
|
-
if (this.debug) {
|
|
508
|
-
const totalToolMsgs = subResults.reduce((n, r) => n + r.toolMessages.length, 0);
|
|
509
|
-
const totalToolCalls = subResults.reduce((n, r) => n + r.toolResults.length, 0);
|
|
510
|
-
const perSubagent = subResults
|
|
511
|
-
.map((r) => {
|
|
512
|
-
const tools = r.toolResults.map((t) => t.toolName);
|
|
513
|
-
const counts = tools.reduce((acc, name) => {
|
|
514
|
-
acc[name] = (acc[name] ?? 0) + 1;
|
|
515
|
-
return acc;
|
|
516
|
-
}, {});
|
|
517
|
-
const toolStr = Object.keys(counts).length === 0
|
|
518
|
-
? 'no tools'
|
|
519
|
-
: Object.entries(counts)
|
|
520
|
-
.map(([name, c]) => (c > 1 ? `${name}×${c}` : name))
|
|
521
|
-
.join(', ');
|
|
522
|
-
return `${r.subagentName} (${r.toolResults.length} tool call${r.toolResults.length === 1 ? '' : 's'}: ${toolStr})`;
|
|
523
|
-
})
|
|
524
|
-
.join(' | ');
|
|
525
|
-
console.log(`\n[AgentCore] turn summary — subagents: ${subResults.length}, total tool calls: ${totalToolCalls}\n ${perSubagent}`);
|
|
526
|
-
console.log(`[AgentCore] synthesising ${subResults.length} subagent result(s), stored ${totalToolMsgs} tool message(s) in history…`);
|
|
527
|
-
}
|
|
528
|
-
// Synthesiser runs WITHOUT tools — strip tool messages from the history
|
|
529
|
-
// slice to avoid sending orphan functionResponse parts to Gemini. Also
|
|
530
|
-
// drop the trailing user message (Synthesiser already receives userQuery
|
|
531
|
-
// as a separate argument; keeping it here would duplicate it).
|
|
532
|
-
const synthHistoryRaw = this.history.getConversation();
|
|
533
|
-
const synthHistoryTrimmed = synthHistoryRaw.length > 0 && synthHistoryRaw[synthHistoryRaw.length - 1].role === 'user'
|
|
534
|
-
? synthHistoryRaw.slice(0, -1)
|
|
535
|
-
: synthHistoryRaw;
|
|
536
|
-
const synthesiserHistory = (0, historyUtils_1.stripToolMessages)(synthHistoryTrimmed);
|
|
537
|
-
const trace = this.mergeTrace(subResults);
|
|
538
|
-
// Pass the ORIGINAL user message to the synthesiser so the final answer
|
|
539
|
-
// addresses what the user actually typed (the rewritten query was only
|
|
540
|
-
// for routing/tool-selection purposes, not user-facing phrasing).
|
|
541
|
-
// Note: kbContext is intentionally NOT forwarded here. When the router
|
|
542
|
-
// chose to dispatch subagents it judged the query needs live tool data —
|
|
543
|
-
// injecting (potentially loose-match) KB material into the synthesiser
|
|
544
|
-
// would let an unrelated reference override correct tool results. To
|
|
545
|
-
// make more KB hits answer from KB, lower `kbAnswerThreshold` instead.
|
|
546
|
-
const synthesised = await this.synthesizer.synthesise(userMessage, trace, synthesiserHistory, rewrite.language);
|
|
547
|
-
// Tag the assistant message with the subagents that handled it — used by
|
|
548
|
-
// QueryRewriter and Router on the NEXT turn to resolve "more" / "tiếp" / etc.
|
|
549
|
-
const handledBy = subResults.map((r) => r.subagentName);
|
|
550
|
-
const uiActions = this.collectUiActions(subResults, rewrite.language || null);
|
|
551
|
-
const response = await this.finaliseAnswer({ userMessage, answer: synthesised, subagents: handledBy, uiActions, messageId }, { generateSuggestions: doSuggest });
|
|
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 });
|
|
552
513
|
if (this.debug) {
|
|
553
514
|
console.log(`[AgentCore] turn done in ${Date.now() - turnStart}ms total`);
|
|
554
515
|
console.log(`${'─'.repeat(60)}\n`);
|
|
555
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() {
|
|
556
526
|
return {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
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),
|
|
564
590
|
};
|
|
565
591
|
}
|
|
566
592
|
/**
|
|
@@ -568,6 +594,59 @@ class AgentCore {
|
|
|
568
594
|
* 'action' attach a `ui` field to their ToolResult; the FE renders one
|
|
569
595
|
* component per entry in the order they were produced.
|
|
570
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
|
+
}
|
|
571
650
|
collectUiActions(subResults, language) {
|
|
572
651
|
const out = [];
|
|
573
652
|
for (const r of subResults) {
|
|
@@ -650,14 +729,26 @@ class AgentCore {
|
|
|
650
729
|
const intentCheckMessages = [
|
|
651
730
|
{
|
|
652
731
|
role: 'system',
|
|
653
|
-
content: 'You are a
|
|
654
|
-
'\n\
|
|
655
|
-
'\nAnswer "
|
|
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.',
|
|
656
745
|
timestamp: 0,
|
|
657
746
|
},
|
|
658
747
|
{
|
|
659
748
|
role: 'user',
|
|
660
|
-
content: `FAQ question: "${topQuestion}"\nUser message: "${userMessage}"\n\
|
|
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".',
|
|
661
752
|
timestamp: Date.now(),
|
|
662
753
|
},
|
|
663
754
|
];
|
|
@@ -705,16 +796,28 @@ class AgentCore {
|
|
|
705
796
|
await this.persistHistory();
|
|
706
797
|
return { answer, suggestedPrompts: [] };
|
|
707
798
|
}
|
|
708
|
-
async answerDirectly(userMessage, conversationMessages, kbContext, generateSuggestions = true, messageId) {
|
|
709
|
-
if (this.debug)
|
|
710
|
-
console.log(
|
|
711
|
-
|
|
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
|
|
712
815
|
? this.systemPrompt +
|
|
713
816
|
'\n\nYou may use the following reference material if relevant:\n\n' +
|
|
714
817
|
'---\nREFERENCE MATERIAL:\n' +
|
|
715
818
|
kbContext +
|
|
716
819
|
'\n---'
|
|
717
|
-
: this.systemPrompt;
|
|
820
|
+
: this.systemPrompt) + noSearchGuard;
|
|
718
821
|
// Direct LLM call has NO tools declared → strip tool messages to avoid
|
|
719
822
|
// orphan functionResponse parts (Gemini 400). Also append the current
|
|
720
823
|
// user message (caller dropped it from the history slice).
|
|
@@ -724,9 +827,47 @@ class AgentCore {
|
|
|
724
827
|
...cleanHistory,
|
|
725
828
|
{ role: 'user', content: userMessage, timestamp: Date.now() },
|
|
726
829
|
];
|
|
727
|
-
const directResponse = await this.llm.chat(directMessages, undefined, { googleSearch:
|
|
830
|
+
const directResponse = await this.llm.chat(directMessages, undefined, { googleSearch: useWebSearch });
|
|
728
831
|
return await this.finaliseAnswer({ userMessage, answer: directResponse.text, messageId }, { generateSuggestions });
|
|
729
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
|
+
}
|
|
730
871
|
/**
|
|
731
872
|
* Flatten the per-subagent ReAct steps into a single trace that the
|
|
732
873
|
* Synthesizer can consume. The `finalAnswer` here is a compact
|
|
@@ -751,7 +892,7 @@ class AgentCore {
|
|
|
751
892
|
return { steps, finalAnswer };
|
|
752
893
|
}
|
|
753
894
|
async finaliseAnswer(params, options) {
|
|
754
|
-
const { userMessage, answer, subagents, uiActions, messageId } = params ?? {};
|
|
895
|
+
const { userMessage, answer, subagents, uiActions, actionButtons, messageId } = params ?? {};
|
|
755
896
|
const { generateSuggestions = true } = options ?? {};
|
|
756
897
|
const suggestedPrompts = generateSuggestions
|
|
757
898
|
? await this.generateSuggestions(userMessage, answer, subagents ?? [])
|
|
@@ -763,11 +904,13 @@ class AgentCore {
|
|
|
763
904
|
msg.suggestedPrompts = suggestedPrompts;
|
|
764
905
|
if (uiActions && uiActions.length > 0)
|
|
765
906
|
msg.uiActions = uiActions;
|
|
907
|
+
if (actionButtons && actionButtons.length > 0)
|
|
908
|
+
msg.actionButtons = actionButtons;
|
|
766
909
|
if (messageId)
|
|
767
910
|
msg.messageId = messageId;
|
|
768
911
|
this.history.add(msg);
|
|
769
912
|
await this.persistHistory();
|
|
770
|
-
return { answer, suggestedPrompts };
|
|
913
|
+
return { answer, suggestedPrompts, ...(actionButtons && actionButtons.length > 0 ? { actionButtons } : {}) };
|
|
771
914
|
}
|
|
772
915
|
// ---- Suggested prompts ----
|
|
773
916
|
async generateSuggestions(userMessage, answer, subagents) {
|