@hashgraphonline/conversational-agent 0.1.209 → 0.1.211

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 (106) hide show
  1. package/bin/conversational-agent-cli.js +30 -0
  2. package/cli/readme.md +181 -0
  3. package/dist/cjs/base-agent.d.ts +3 -1
  4. package/dist/cjs/conversational-agent.d.ts +14 -22
  5. package/dist/cjs/index.cjs +1 -1
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs/index.d.ts +5 -3
  8. package/dist/cjs/langchain-agent.d.ts +6 -3
  9. package/dist/cjs/memory/SmartMemoryManager.d.ts +7 -1
  10. package/dist/cjs/memory/TokenCounter.d.ts +1 -1
  11. package/dist/cjs/plugins/hbar/AirdropToolWrapper.d.ts +43 -0
  12. package/dist/{types/plugins/hbar-transfer/HbarTransferPlugin.d.ts → cjs/plugins/hbar/HbarPlugin.d.ts} +2 -1
  13. package/dist/{types/plugins/hbar-transfer → cjs/plugins/hbar}/TransferHbarTool.d.ts +1 -1
  14. package/dist/cjs/plugins/hbar/index.d.ts +3 -0
  15. package/dist/cjs/plugins/index.d.ts +2 -1
  16. package/dist/cjs/services/EntityResolver.d.ts +26 -0
  17. package/dist/cjs/tools/EntityResolverTool.d.ts +104 -0
  18. package/dist/cjs/types/inscription.d.ts +37 -0
  19. package/dist/esm/index.js +8 -2
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/esm/index12.js +1 -4
  22. package/dist/esm/index12.js.map +1 -1
  23. package/dist/esm/index13.js +0 -1
  24. package/dist/esm/index13.js.map +1 -1
  25. package/dist/esm/index14.js +2 -7
  26. package/dist/esm/index14.js.map +1 -1
  27. package/dist/esm/index15.js +31 -69
  28. package/dist/esm/index15.js.map +1 -1
  29. package/dist/esm/index16.js +126 -39
  30. package/dist/esm/index16.js.map +1 -1
  31. package/dist/esm/index17.js +148 -13
  32. package/dist/esm/index17.js.map +1 -1
  33. package/dist/esm/index18.js +44 -146
  34. package/dist/esm/index18.js.map +1 -1
  35. package/dist/esm/index19.js +100 -6
  36. package/dist/esm/index19.js.map +1 -1
  37. package/dist/esm/index20.js +20 -174
  38. package/dist/esm/index20.js.map +1 -1
  39. package/dist/esm/index21.js +7 -151
  40. package/dist/esm/index21.js.map +1 -1
  41. package/dist/esm/index22.js +154 -45
  42. package/dist/esm/index22.js.map +1 -1
  43. package/dist/esm/index23.js +149 -24
  44. package/dist/esm/index23.js.map +1 -1
  45. package/dist/esm/index24.js +56 -83
  46. package/dist/esm/index24.js.map +1 -1
  47. package/dist/esm/index25.js +24 -236
  48. package/dist/esm/index25.js.map +1 -1
  49. package/dist/esm/index26.js +95 -0
  50. package/dist/esm/index26.js.map +1 -0
  51. package/dist/esm/index27.js +242 -0
  52. package/dist/esm/index27.js.map +1 -0
  53. package/dist/esm/index5.js +32 -19
  54. package/dist/esm/index5.js.map +1 -1
  55. package/dist/esm/index6.js +156 -195
  56. package/dist/esm/index6.js.map +1 -1
  57. package/dist/esm/index7.js +2 -2
  58. package/dist/esm/index7.js.map +1 -1
  59. package/dist/esm/index8.js +80 -48
  60. package/dist/esm/index8.js.map +1 -1
  61. package/dist/types/base-agent.d.ts +3 -1
  62. package/dist/types/conversational-agent.d.ts +14 -22
  63. package/dist/types/index.d.ts +5 -3
  64. package/dist/types/langchain-agent.d.ts +6 -3
  65. package/dist/types/memory/SmartMemoryManager.d.ts +7 -1
  66. package/dist/types/memory/TokenCounter.d.ts +1 -1
  67. package/dist/types/plugins/hbar/AirdropToolWrapper.d.ts +43 -0
  68. package/dist/{cjs/plugins/hbar-transfer/HbarTransferPlugin.d.ts → types/plugins/hbar/HbarPlugin.d.ts} +2 -1
  69. package/dist/{cjs/plugins/hbar-transfer → types/plugins/hbar}/TransferHbarTool.d.ts +1 -1
  70. package/dist/types/plugins/hbar/index.d.ts +3 -0
  71. package/dist/types/plugins/index.d.ts +2 -1
  72. package/dist/types/services/EntityResolver.d.ts +26 -0
  73. package/dist/types/tools/EntityResolverTool.d.ts +104 -0
  74. package/dist/types/types/inscription.d.ts +37 -0
  75. package/package.json +13 -4
  76. package/src/base-agent.ts +14 -9
  77. package/src/config/system-message.ts +11 -2
  78. package/src/context/ReferenceContextManager.ts +1 -1
  79. package/src/conversational-agent.ts +221 -254
  80. package/src/index.ts +17 -3
  81. package/src/langchain-agent.ts +130 -78
  82. package/src/mcp/ContentProcessor.ts +0 -2
  83. package/src/mcp/adapters/langchain.ts +0 -1
  84. package/src/memory/ContentStorage.ts +0 -5
  85. package/src/memory/MemoryWindow.ts +0 -1
  86. package/src/memory/ReferenceIdGenerator.ts +4 -4
  87. package/src/memory/SmartMemoryManager.ts +53 -92
  88. package/src/memory/TokenCounter.ts +4 -7
  89. package/src/plugins/hbar/AirdropToolWrapper.ts +157 -0
  90. package/src/plugins/hbar/HbarPlugin.ts +86 -0
  91. package/src/plugins/{hbar-transfer → hbar}/TransferHbarTool.ts +3 -3
  92. package/src/plugins/hbar/index.ts +3 -0
  93. package/src/plugins/index.ts +2 -1
  94. package/src/services/EntityResolver.ts +135 -0
  95. package/src/tools/EntityResolverTool.ts +170 -0
  96. package/src/types/inscription.ts +40 -0
  97. package/dist/cjs/plugins/hbar-transfer/index.d.ts +0 -1
  98. package/dist/types/plugins/hbar-transfer/index.d.ts +0 -1
  99. package/src/plugins/hbar-transfer/HbarTransferPlugin.ts +0 -66
  100. package/src/plugins/hbar-transfer/index.ts +0 -1
  101. /package/dist/cjs/plugins/{hbar-transfer → hbar}/AccountBuilder.d.ts +0 -0
  102. /package/dist/cjs/plugins/{hbar-transfer → hbar}/types.d.ts +0 -0
  103. /package/dist/types/plugins/{hbar-transfer → hbar}/AccountBuilder.d.ts +0 -0
  104. /package/dist/types/plugins/{hbar-transfer → hbar}/types.d.ts +0 -0
  105. /package/src/plugins/{hbar-transfer → hbar}/AccountBuilder.ts +0 -0
  106. /package/src/plugins/{hbar-transfer → hbar}/types.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index6.js","sources":["../../src/conversational-agent.ts"],"sourcesContent":["import {\n ServerSigner,\n getAllHederaCorePlugins,\n BasePlugin,\n} from 'hedera-agent-kit';\nimport {\n HederaMirrorNode,\n Logger,\n type NetworkType,\n} from '@hashgraphonline/standards-sdk';\nimport { createAgent } from './agent-factory';\nimport { LangChainProvider } from './providers';\nimport type { ChatResponse, ConversationContext } from './base-agent';\nimport { ChatOpenAI } from '@langchain/openai';\nimport { HumanMessage, AIMessage } from '@langchain/core/messages';\nimport type { AgentOperationalMode, MirrorNodeConfig } from 'hedera-agent-kit';\nimport { HCS10Plugin } from './plugins/hcs-10/HCS10Plugin';\nimport { HCS2Plugin } from './plugins/hcs-2/HCS2Plugin';\nimport { InscribePlugin } from './plugins/inscribe/InscribePlugin';\nimport { HbarTransferPlugin } from './plugins/hbar-transfer/HbarTransferPlugin';\nimport { OpenConvaiState } from '@hashgraphonline/standards-agent-kit';\nimport type { IStateManager } from '@hashgraphonline/standards-agent-kit';\nimport { PrivateKey } from '@hashgraph/sdk';\nimport { getSystemMessage } from './config/system-message';\nimport type { MCPServerConfig, MCPConnectionStatus } from './mcp/types';\nimport { ContentStoreManager } from './services/ContentStoreManager';\nimport { SmartMemoryManager, type SmartMemoryConfig } from './memory';\n\nexport type ToolDescriptor = {\n name: string;\n namespace?: string;\n};\n\nexport type ChatHistoryItem = {\n type: 'human' | 'ai';\n content: string;\n};\n\nexport type AgentInstance = ReturnType<typeof createAgent>;\n\nexport type MirrorNetwork = 'testnet' | 'mainnet' | 'previewnet';\n\nconst DEFAULT_MODEL_NAME = 'gpt-4o';\nconst DEFAULT_TEMPERATURE = 0.1;\nconst DEFAULT_NETWORK = 'testnet';\nconst DEFAULT_OPERATIONAL_MODE: AgentOperationalMode = 'autonomous';\n\nexport interface ConversationalAgentOptions {\n accountId: string;\n privateKey: string;\n network?: NetworkType;\n openAIApiKey: string;\n openAIModelName?: string;\n verbose?: boolean;\n operationalMode?: AgentOperationalMode;\n userAccountId?: string;\n customSystemMessagePreamble?: string;\n customSystemMessagePostamble?: string;\n additionalPlugins?: BasePlugin[];\n stateManager?: IStateManager;\n scheduleUserTransactionsInBytesMode?: boolean;\n mirrorNodeConfig?: MirrorNodeConfig;\n disableLogging?: boolean;\n enabledPlugins?: string[];\n toolFilter?: (tool: { name: string; namespace?: string }) => boolean;\n mcpServers?: MCPServerConfig[];\n \n /** Enable automatic entity memory functionality (default: true) */\n entityMemoryEnabled?: boolean;\n \n /** Configuration for entity memory system */\n entityMemoryConfig?: SmartMemoryConfig;\n}\n\n/**\n * The ConversationalAgent class is an optional wrapper around the HederaConversationalAgent class,\n * which includes the OpenConvAIPlugin and the OpenConvaiState by default.\n * If you want to use a different plugin or state manager, you can pass them in the options.\n * This class is not required and the plugin can be used directly with the HederaConversationalAgent class.\n *\n * @param options - The options for the ConversationalAgent.\n * @returns A new instance of the ConversationalAgent class.\n */\nexport class ConversationalAgent {\n protected agent?: AgentInstance;\n public hcs10Plugin: HCS10Plugin;\n public hcs2Plugin: HCS2Plugin;\n public inscribePlugin: InscribePlugin;\n public hbarTransferPlugin: HbarTransferPlugin;\n public stateManager: IStateManager;\n private options: ConversationalAgentOptions;\n protected logger: Logger;\n private contentStoreManager?: ContentStoreManager;\n private memoryManager?: SmartMemoryManager | undefined;\n private mcpConnectionStatus: Map<string, MCPConnectionStatus> = new Map();\n\n constructor(options: ConversationalAgentOptions) {\n this.options = options;\n this.stateManager = options.stateManager || new OpenConvaiState();\n this.hcs10Plugin = new HCS10Plugin();\n this.hcs2Plugin = new HCS2Plugin();\n this.inscribePlugin = new InscribePlugin();\n this.hbarTransferPlugin = new HbarTransferPlugin();\n this.logger = new Logger({\n module: 'ConversationalAgent',\n silent: options.disableLogging || false,\n });\n \n if (this.options.entityMemoryEnabled !== false) {\n this.memoryManager = new SmartMemoryManager(this.options.entityMemoryConfig);\n this.logger.info('Entity memory initialized');\n }\n }\n\n /**\n * Initialize the conversational agent with Hedera network connection and AI configuration\n * @throws {Error} If account ID or private key is missing\n * @throws {Error} If initialization fails\n */\n async initialize(): Promise<void> {\n const {\n accountId,\n privateKey,\n network = DEFAULT_NETWORK,\n openAIApiKey,\n openAIModelName = DEFAULT_MODEL_NAME,\n } = this.options;\n\n this.validateOptions(accountId, privateKey);\n\n try {\n const privateKeyInstance = await this.detectPrivateKeyType(\n accountId!,\n privateKey!,\n network\n );\n\n const serverSigner = new ServerSigner(\n accountId!,\n privateKeyInstance,\n network as MirrorNetwork\n );\n\n const allPlugins = this.preparePlugins();\n\n const llm = new ChatOpenAI({\n apiKey: openAIApiKey,\n modelName: openAIModelName,\n temperature: DEFAULT_TEMPERATURE,\n });\n\n const agentConfig = this.createAgentConfig(serverSigner, llm, allPlugins);\n this.agent = createAgent(agentConfig);\n\n this.configureHCS10Plugin(allPlugins);\n\n if (this.options.mcpServers && this.options.mcpServers.length > 0) {\n this.contentStoreManager = new ContentStoreManager();\n await this.contentStoreManager.initialize();\n this.logger.info('ContentStoreManager initialized for MCP content reference support');\n }\n\n await this.agent.boot();\n\n // Start MCP connections asynchronously after agent is booted\n if (this.options.mcpServers && this.options.mcpServers.length > 0) {\n this.connectMCP();\n }\n } catch (error) {\n this.logger.error('Failed to initialize ConversationalAgent:', error);\n throw error;\n }\n }\n\n /**\n * Get the HCS-10 plugin instance\n * @returns {HCS10Plugin} The HCS-10 plugin instance\n */\n getPlugin(): HCS10Plugin {\n return this.hcs10Plugin;\n }\n\n /**\n * Get the state manager instance\n * @returns {IStateManager} The state manager instance\n */\n getStateManager(): IStateManager {\n return this.stateManager;\n }\n\n /**\n * Get the underlying agent instance\n * @returns {ReturnType<typeof createAgent>} The agent instance\n * @throws {Error} If agent is not initialized\n */\n getAgent(): ReturnType<typeof createAgent> {\n if (!this.agent) {\n throw new Error('Agent not initialized. Call initialize() first.');\n }\n return this.agent;\n }\n\n /**\n * Get the conversational agent instance (alias for getAgent)\n * @returns {ReturnType<typeof createAgent>} The agent instance\n * @throws {Error} If agent is not initialized\n */\n getConversationalAgent(): ReturnType<typeof createAgent> {\n return this.getAgent();\n }\n\n /**\n * Process a message through the conversational agent\n * @param {string} message - The message to process\n * @param {Array<{type: 'human' | 'ai'; content: string}>} chatHistory - Previous chat history\n * @returns {Promise<ChatResponse>} The agent's response\n * @throws {Error} If agent is not initialized\n */\n async processMessage(\n message: string,\n chatHistory: ChatHistoryItem[] = []\n ): Promise<ChatResponse> {\n if (!this.agent) {\n throw new Error('Agent not initialized. Call initialize() first.');\n }\n\n try {\n const resolvedMessage = this.memoryManager \n ? await this.resolveEntitiesInMessage(message)\n : message;\n\n const messages = chatHistory.map((msg) => {\n if (msg.type === 'human') {\n return new HumanMessage(msg.content);\n } else {\n return new AIMessage(msg.content);\n }\n });\n\n const context: ConversationContext = {\n messages,\n };\n\n const response = await this.agent.chat(resolvedMessage, context);\n \n if (this.memoryManager) {\n await this.extractAndStoreEntities(response, message);\n }\n \n this.logger.info('Message processed successfully');\n \n return response;\n } catch (error) {\n this.logger.error('Error processing message:', error);\n throw error;\n }\n }\n\n /**\n * Validates initialization options and throws if required fields are missing.\n * \n * @param accountId - The Hedera account ID\n * @param privateKey - The private key for the account\n * @throws {Error} If required fields are missing\n */\n private validateOptions(accountId?: string, privateKey?: string): void {\n if (!accountId || !privateKey) {\n throw new Error('Account ID and private key are required');\n }\n }\n\n /**\n * Prepares the list of plugins to use based on configuration.\n * \n * @returns Array of plugins to initialize with the agent\n */\n private preparePlugins(): BasePlugin[] {\n const { additionalPlugins = [], enabledPlugins } = this.options;\n \n const standardPlugins = [\n this.hcs10Plugin,\n this.hcs2Plugin,\n this.inscribePlugin,\n this.hbarTransferPlugin,\n ];\n \n const corePlugins: BasePlugin[] = getAllHederaCorePlugins();\n \n if (enabledPlugins) {\n const enabledSet = new Set(enabledPlugins);\n const filteredPlugins = [...standardPlugins, ...corePlugins].filter(\n (plugin) => enabledSet.has(plugin.id)\n );\n return [...filteredPlugins, ...additionalPlugins];\n }\n \n return [...standardPlugins, ...corePlugins, ...additionalPlugins];\n }\n\n /**\n * Creates the agent configuration object.\n * \n * @param serverSigner - The server signer instance\n * @param llm - The language model instance\n * @param allPlugins - Array of plugins to use\n * @returns Configuration object for creating the agent\n */\n private createAgentConfig(\n serverSigner: ServerSigner,\n llm: ChatOpenAI,\n allPlugins: BasePlugin[]\n ): Parameters<typeof createAgent>[0] {\n const {\n operationalMode = DEFAULT_OPERATIONAL_MODE,\n userAccountId,\n scheduleUserTransactionsInBytesMode,\n customSystemMessagePreamble,\n customSystemMessagePostamble,\n verbose = false,\n mirrorNodeConfig,\n disableLogging,\n accountId = '',\n } = this.options;\n\n return {\n framework: 'langchain',\n signer: serverSigner,\n execution: {\n mode: operationalMode === 'autonomous' ? 'direct' : 'bytes',\n operationalMode: operationalMode,\n ...(userAccountId && { userAccountId }),\n ...(scheduleUserTransactionsInBytesMode !== undefined && {\n scheduleUserTransactionsInBytesMode: scheduleUserTransactionsInBytesMode,\n scheduleUserTransactions: scheduleUserTransactionsInBytesMode,\n }),\n },\n ai: {\n provider: new LangChainProvider(llm),\n temperature: DEFAULT_TEMPERATURE,\n },\n filtering: {\n toolPredicate: (tool: ToolDescriptor): boolean => {\n if (tool.name === 'hedera-account-transfer-hbar') return false;\n if (this.options.toolFilter && !this.options.toolFilter(tool)) {\n return false;\n }\n return true;\n },\n },\n messaging: {\n systemPreamble:\n customSystemMessagePreamble || getSystemMessage(accountId),\n ...(customSystemMessagePostamble && { systemPostamble: customSystemMessagePostamble }),\n conciseMode: true,\n },\n extensions: {\n plugins: allPlugins,\n ...(mirrorNodeConfig && {\n mirrorConfig: mirrorNodeConfig as Record<string, unknown>,\n }),\n },\n ...(this.options.mcpServers && {\n mcp: {\n servers: this.options.mcpServers,\n autoConnect: false,\n },\n }),\n debug: {\n verbose,\n silent: disableLogging ?? false,\n },\n };\n }\n\n /**\n * Configures the HCS-10 plugin with the state manager.\n * \n * @param allPlugins - Array of all plugins\n */\n private configureHCS10Plugin(allPlugins: BasePlugin[]): void {\n const hcs10 = allPlugins.find((p) => p.id === 'hcs-10');\n if (hcs10) {\n (hcs10 as BasePlugin & { appConfig?: Record<string, unknown> }).appConfig = {\n stateManager: this.stateManager,\n };\n }\n }\n\n /**\n * Create a ConversationalAgent with specific plugins enabled\n */\n private static withPlugins(\n options: ConversationalAgentOptions,\n plugins: string[]\n ): ConversationalAgent {\n return new ConversationalAgent({\n ...options,\n enabledPlugins: plugins,\n });\n }\n\n /**\n * Create a ConversationalAgent with only HTS (Hedera Token Service) tools enabled\n */\n static withHTS(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hts-token']);\n }\n\n /**\n * Create a ConversationalAgent with only HCS-2 tools enabled\n */\n static withHCS2(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hcs-2']);\n }\n\n /**\n * Create a ConversationalAgent with only HCS-10 tools enabled\n */\n static withHCS10(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hcs-10']);\n }\n\n /**\n * Create a ConversationalAgent with only inscription tools enabled\n */\n static withInscribe(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['inscribe']);\n }\n\n /**\n * Create a ConversationalAgent with only account management tools enabled\n */\n static withAccount(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['account']);\n }\n\n /**\n * Create a ConversationalAgent with only file service tools enabled\n */\n static withFileService(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['file-service']);\n }\n\n /**\n * Create a ConversationalAgent with only consensus service tools enabled\n */\n static withConsensusService(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['consensus-service']);\n }\n\n /**\n * Create a ConversationalAgent with only smart contract tools enabled\n */\n static withSmartContract(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['smart-contract']);\n }\n\n /**\n * Create a ConversationalAgent with all HCS standards plugins\n */\n static withAllStandards(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['hcs-10', 'hcs-2', 'inscribe']);\n }\n\n /**\n * Create a ConversationalAgent with minimal Hedera tools (no HCS standards)\n */\n static minimal(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, []);\n }\n\n /**\n * Create a ConversationalAgent with MCP servers configured\n */\n static withMCP(\n options: ConversationalAgentOptions,\n mcpServers: MCPServerConfig[]\n ): ConversationalAgent {\n return new ConversationalAgent({\n ...options,\n mcpServers,\n });\n }\n\n /**\n * Detect the private key type by querying the account info from mirror node\n * @param {string} accountId - The Hedera account ID\n * @param {string} privateKey - The private key string\n * @param {NetworkType} network - The Hedera network\n * @returns {Promise<PrivateKey>} The appropriate PrivateKey instance\n */\n private async detectPrivateKeyType(\n accountId: string,\n privateKey: string,\n network: NetworkType\n ): Promise<PrivateKey> {\n const mirrorNode = new HederaMirrorNode(network as 'testnet' | 'mainnet');\n const accountInfo = await mirrorNode.requestAccount(accountId);\n\n const keyType = accountInfo?.key?._type || '';\n\n if (keyType?.toLowerCase()?.includes('ecdsa')) {\n return PrivateKey.fromStringECDSA(privateKey);\n } else {\n return PrivateKey.fromStringED25519(privateKey);\n }\n }\n\n /**\n * Resolve entity references in the message content\n * @param content - Message content to resolve\n * @returns Resolved message content with entity IDs replaced\n */\n private async resolveEntitiesInMessage(content: string): Promise<string> {\n if (!this.memoryManager) {\n return content;\n }\n\n try {\n this.logger.info(`Starting entity resolution for message: \"${content.substring(0, 100)}...\"`);\n \n if (!content || typeof content !== 'string') {\n this.logger.warn('Invalid content provided for entity resolution');\n return content || '';\n }\n\n if (content.length > 5000) {\n this.logger.warn('Content too long for entity resolution, truncating');\n content = content.substring(0, 5000);\n }\n\n let resolvedContent = content;\n\n const patterns = [\n /\\b(my|the|our)\\s+(token|account|topic|schedule)\\b/gi,\n /'([^']+)'/g,\n /\"([^\"]+)\"/g,\n /\\b([A-Z][A-Za-z0-9_-]{2,})\\b/g\n ];\n\n for (const pattern of patterns) {\n try {\n let match;\n const matches: any[] = [];\n while ((match = pattern.exec(resolvedContent)) !== null) {\n matches.push(match);\n if (!pattern.global) break;\n }\n \n for (const match of matches) {\n try {\n const originalRef = match[0];\n const entityName = match[1] || match[0];\n \n if (entityName.length > 50) {\n this.logger.debug(`Skipping overly long entity name: ${entityName.substring(0, 20)}...`);\n continue;\n }\n \n const commonWords = ['the', 'my', 'our', 'this', 'that', 'it', 'is', 'are', 'was', 'will'];\n if (commonWords.includes(entityName.toLowerCase())) {\n continue;\n }\n \n let entityAssociations: any[] = [];\n \n if (match[1] && ['token', 'account', 'topic', 'schedule'].includes(match[1].toLowerCase())) {\n const entityType = match[1].toLowerCase();\n entityAssociations = this.memoryManager.resolveEntityReference(\n entityName, \n { entityType, limit: 1, fuzzyMatch: true }\n );\n } else {\n entityAssociations = this.memoryManager.resolveEntityReference(\n entityName,\n { limit: 1, fuzzyMatch: false }\n );\n }\n\n if (entityAssociations.length > 0) {\n const entity = entityAssociations[0];\n if (entity.entityId && entity.entityId.trim().length > 0) {\n if (entityAssociations.length > 1) {\n this.logger.info(`Multiple entities found for \"${originalRef}\", using most recent: ${entity.entityName}`);\n }\n \n resolvedContent = resolvedContent.replace(originalRef, entity.entityId);\n this.logger.info(`Resolved entity reference: \"${originalRef}\" -> ${entity.entityId}`);\n }\n }\n } catch (matchError) {\n this.logger.debug('Error processing entity match:', matchError);\n continue;\n }\n }\n } catch (patternError) {\n this.logger.debug('Error processing pattern:', patternError);\n continue;\n }\n }\n\n if (resolvedContent !== content) {\n this.logger.info(`Entity resolution completed. Original: \"${content}\" -> Resolved: \"${resolvedContent}\"`);\n } else {\n this.logger.info('No entity references resolved in message');\n }\n \n return resolvedContent;\n } catch (error) {\n this.logger.warn('Entity resolution failed, using original message:', error);\n return content;\n }\n }\n\n /**\n * Extract and store entity associations from transaction responses\n * @param response - Agent response containing potential entity information\n * @param originalMessage - Original user message for context\n */\n private async extractAndStoreEntities(response: any, originalMessage: string): Promise<void> {\n if (!this.memoryManager) {\n return;\n }\n\n try {\n this.logger.info('Starting entity extraction from response');\n \n const entityPatterns = {\n token: /(?:token|Token)\\s*(?:ID\\s*[:\"*\\s]*)?([0-9]+\\.[0-9]+\\.[0-9]+)/g,\n account: /(?:account|Account)\\s*(?:ID\\s*[:\"*\\s]*)?([0-9]+\\.[0-9]+\\.[0-9]+)/g,\n topic: /(?:topic|Topic)\\s*(?:ID\\s*[:\"*\\s]*)?([0-9]+\\.[0-9]+\\.[0-9]+)/g,\n schedule: /(?:schedule|Schedule)\\s*(?:ID\\s*[:\"*\\s]*)?([0-9]+\\.[0-9]+\\.[0-9]+)/g\n };\n\n const responseText = typeof response === 'string' ? response : JSON.stringify(response);\n this.logger.info(`Searching response text: ${responseText.substring(0, 200)}...`);\n \n for (const [entityType, pattern] of Object.entries(entityPatterns)) {\n let match;\n while ((match = pattern.exec(responseText)) !== null) {\n const entityId = match[1];\n \n let entityName = `${entityType}-${entityId}`;\n \n const namePatterns = [\n new RegExp(`(?:called|named)\\\\s+([\\\\w\\\\d_-]+)`, 'i'),\n new RegExp(`(?:token|account|topic|schedule)\\\\s+([\\\\w\\\\d_-]+)`, 'i'),\n new RegExp(`([\\\\w\\\\d_-]+)\\\\s+${entityType}`, 'i')\n ];\n \n for (const namePattern of namePatterns) {\n const nameMatch = originalMessage.match(namePattern);\n if (nameMatch && nameMatch[1]) {\n entityName = nameMatch[1].trim();\n break;\n }\n }\n \n this.logger.info(`Extracting entity: ${entityName} (${entityType}) -> ${entityId}`);\n \n this.memoryManager.storeEntityAssociation(\n entityId,\n entityName,\n entityType,\n this.extractTransactionId(response)\n );\n \n this.logger.info(`Stored entity association: ${entityName} (${entityId})`);\n }\n }\n \n this.logger.info('Entity extraction completed');\n } catch (error) {\n this.logger.warn('Entity extraction failed:', error);\n }\n }\n\n /**\n * Extract transaction ID from response if available\n * @param response - Transaction response\n * @returns Transaction ID or undefined\n */\n private extractTransactionId(response: any): string | undefined {\n try {\n if (typeof response === 'object' && response?.transactionId) {\n return response.transactionId;\n }\n if (typeof response === 'string') {\n const match = response.match(/transaction[\\s\\w]*ID[\\s:\"]*([0-9a-fA-F@\\.\\-]+)/i);\n return match ? match[1] : undefined;\n }\n return undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Connect to MCP servers asynchronously\n * @private\n */\n private connectMCP(): void {\n if (!this.agent || !this.options.mcpServers) {\n return;\n }\n\n // Initialize connection status for all servers\n this.options.mcpServers.forEach(server => {\n this.mcpConnectionStatus.set(server.name, {\n serverName: server.name,\n connected: false,\n tools: []\n });\n });\n\n // Call the agent's MCP connection method if available\n if (typeof (this.agent as any).connectMCPServers === 'function') {\n (this.agent as any).connectMCPServers().catch((error: any) => {\n this.logger.error('Failed to connect MCP servers:', error);\n });\n } else {\n // Fallback for agents that don't support async MCP connections\n this.startConnections();\n }\n }\n\n /**\n * Start MCP connections without blocking initialization\n * @private\n */\n private async startConnections(): Promise<void> {\n if (!this.agent || !this.options.mcpServers) {\n return;\n }\n\n try {\n this.logger.info('Starting MCP server connections asynchronously...');\n \n for (const server of this.options.mcpServers) {\n this.connectServer(server);\n }\n } catch (error) {\n this.logger.error('Error starting MCP connections:', error);\n }\n }\n\n /**\n * Connect to a single MCP server\n * @param {MCPServerConfig} server - Server configuration\n * @private\n */\n private async connectServer(server: MCPServerConfig): Promise<void> {\n try {\n this.logger.info(`Connecting to MCP server: ${server.name}`);\n \n // TODO: Implement actual MCP connection logic\n // For now, we'll simulate the connection process\n const status = this.mcpConnectionStatus.get(server.name);\n if (status) {\n // Simulate connection success after a delay\n setTimeout(() => {\n status.connected = true;\n this.logger.info(`MCP server ${server.name} connected successfully`);\n }, Math.random() * 2000 + 1000); // 1-3 second delay\n }\n \n } catch (error) {\n this.logger.error(`Failed to connect to MCP server ${server.name}:`, error);\n \n const status = this.mcpConnectionStatus.get(server.name);\n if (status) {\n status.connected = false;\n status.error = error instanceof Error ? error.message : 'Unknown error';\n }\n }\n }\n\n /**\n * Get MCP connection status for all servers\n * @returns {Map<string, MCPConnectionStatus>} Connection status map\n */\n getMCPConnectionStatus(): Map<string, MCPConnectionStatus> {\n return new Map(this.mcpConnectionStatus);\n }\n\n /**\n * Check if a specific MCP server is connected\n * @param {string} serverName - Name of the server to check\n * @returns {boolean} True if connected, false otherwise\n */\n isMCPServerConnected(serverName: string): boolean {\n const status = this.mcpConnectionStatus.get(serverName);\n return status?.connected ?? false;\n }\n\n /**\n * Clean up resources\n */\n async cleanup(): Promise<void> {\n try {\n this.logger.info('Cleaning up ConversationalAgent...');\n \n if (this.memoryManager) {\n try {\n this.memoryManager.dispose();\n this.logger.info('Memory manager cleaned up successfully');\n } catch (error) {\n this.logger.warn('Error cleaning up memory manager:', error);\n }\n this.memoryManager = undefined as any;\n }\n \n if (this.contentStoreManager) {\n await this.contentStoreManager.dispose();\n this.logger.info('ContentStoreManager cleaned up');\n }\n \n this.logger.info('ConversationalAgent cleanup completed');\n } catch (error) {\n this.logger.error('Error during cleanup:', error);\n }\n }\n}\n"],"names":["match"],"mappings":"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"}
1
+ {"version":3,"file":"index6.js","sources":["../../src/conversational-agent.ts"],"sourcesContent":["import {\n ServerSigner,\n getAllHederaCorePlugins,\n BasePlugin,\n} from 'hedera-agent-kit';\nimport {\n HederaMirrorNode,\n Logger,\n type NetworkType,\n} from '@hashgraphonline/standards-sdk';\nimport { createAgent } from './agent-factory';\nimport { LangChainProvider } from './providers';\nimport type { ChatResponse, ConversationContext } from './base-agent';\nimport { ChatOpenAI } from '@langchain/openai';\nimport { ChatAnthropic } from '@langchain/anthropic';\nimport { HumanMessage, AIMessage } from '@langchain/core/messages';\nimport type { AgentOperationalMode, MirrorNodeConfig } from 'hedera-agent-kit';\nimport { HCS10Plugin } from './plugins/hcs-10/HCS10Plugin';\nimport { HCS2Plugin } from './plugins/hcs-2/HCS2Plugin';\nimport { InscribePlugin } from './plugins/inscribe/InscribePlugin';\nimport { HbarPlugin } from './plugins/hbar/HbarPlugin';\nimport { OpenConvaiState } from '@hashgraphonline/standards-agent-kit';\nimport type { IStateManager } from '@hashgraphonline/standards-agent-kit';\nimport { PrivateKey } from '@hashgraph/sdk';\nimport { getSystemMessage } from './config/system-message';\nimport type { MCPServerConfig, MCPConnectionStatus } from './mcp/types';\nimport { ContentStoreManager } from './services/ContentStoreManager';\nimport { SmartMemoryManager, type SmartMemoryConfig } from './memory';\nimport {\n createEntityTools,\n ResolveEntitiesTool,\n ExtractEntitiesTool,\n} from './tools/EntityResolverTool';\n\nexport type ToolDescriptor = {\n name: string;\n namespace?: string;\n};\n\nexport type ChatHistoryItem = {\n type: 'human' | 'ai';\n content: string;\n};\n\nexport type AgentInstance = ReturnType<typeof createAgent>;\n\nexport type MirrorNetwork = 'testnet' | 'mainnet' | 'previewnet';\n\nconst DEFAULT_MODEL_NAME = 'gpt-4o';\nconst DEFAULT_TEMPERATURE = 0.1;\nconst DEFAULT_NETWORK = 'testnet';\nconst DEFAULT_OPERATIONAL_MODE: AgentOperationalMode = 'autonomous';\n\nexport interface ConversationalAgentOptions {\n accountId: string;\n privateKey: string;\n network?: NetworkType;\n openAIApiKey: string;\n openAIModelName?: string;\n llmProvider?: 'openai' | 'anthropic';\n verbose?: boolean;\n operationalMode?: AgentOperationalMode;\n userAccountId?: string;\n customSystemMessagePreamble?: string;\n customSystemMessagePostamble?: string;\n additionalPlugins?: BasePlugin[];\n stateManager?: IStateManager;\n scheduleUserTransactionsInBytesMode?: boolean;\n mirrorNodeConfig?: MirrorNodeConfig;\n disableLogging?: boolean;\n enabledPlugins?: string[];\n toolFilter?: (tool: { name: string; namespace?: string }) => boolean;\n mcpServers?: MCPServerConfig[];\n\n /** Enable automatic entity memory functionality (default: true) */\n entityMemoryEnabled?: boolean;\n\n /** Configuration for entity memory system */\n entityMemoryConfig?: SmartMemoryConfig;\n}\n\n/**\n * The ConversationalAgent class is an optional wrapper around the HederaConversationalAgent class,\n * which includes the OpenConvAIPlugin and the OpenConvaiState by default.\n * If you want to use a different plugin or state manager, you can pass them in the options.\n * This class is not required and the plugin can be used directly with the HederaConversationalAgent class.\n *\n * @param options - The options for the ConversationalAgent.\n * @returns A new instance of the ConversationalAgent class.\n */\nexport class ConversationalAgent {\n protected agent?: AgentInstance;\n public hcs10Plugin: HCS10Plugin;\n public hcs2Plugin: HCS2Plugin;\n public inscribePlugin: InscribePlugin;\n public hbarPlugin: HbarPlugin;\n public stateManager: IStateManager;\n private options: ConversationalAgentOptions;\n public logger: Logger;\n public contentStoreManager?: ContentStoreManager;\n public memoryManager?: SmartMemoryManager | undefined;\n private entityTools?: {\n resolveEntities: ResolveEntitiesTool;\n extractEntities: ExtractEntitiesTool;\n };\n\n constructor(options: ConversationalAgentOptions) {\n this.options = options;\n this.stateManager = options.stateManager || new OpenConvaiState();\n this.hcs10Plugin = new HCS10Plugin();\n this.hcs2Plugin = new HCS2Plugin();\n this.inscribePlugin = new InscribePlugin();\n this.hbarPlugin = new HbarPlugin();\n this.logger = new Logger({\n module: 'ConversationalAgent',\n silent: options.disableLogging || false,\n });\n\n if (this.options.entityMemoryEnabled !== false) {\n if (!options.openAIApiKey) {\n throw new Error(\n 'OpenAI API key is required when entity memory is enabled'\n );\n }\n\n this.memoryManager = new SmartMemoryManager(\n this.options.entityMemoryConfig\n );\n this.logger.info('Entity memory initialized');\n\n this.entityTools = createEntityTools(options.openAIApiKey, 'gpt-4o-mini');\n this.logger.info('LLM-based entity resolver tools initialized');\n }\n }\n\n /**\n * Initialize the conversational agent with Hedera Hashgraph connection and AI configuration\n * @throws {Error} If account ID or private key is missing\n * @throws {Error} If initialization fails\n */\n async initialize(): Promise<void> {\n const {\n accountId,\n privateKey,\n network = DEFAULT_NETWORK,\n openAIApiKey,\n openAIModelName = DEFAULT_MODEL_NAME,\n llmProvider = 'openai',\n } = this.options;\n\n this.validateOptions(accountId, privateKey);\n\n try {\n const privateKeyInstance = await this.detectPrivateKeyType(\n accountId!,\n privateKey!,\n network\n );\n\n const serverSigner = new ServerSigner(\n accountId!,\n privateKeyInstance,\n network as MirrorNetwork\n );\n\n let llm: ChatOpenAI | ChatAnthropic;\n if (llmProvider === 'anthropic') {\n llm = new ChatAnthropic({\n apiKey: openAIApiKey,\n modelName: openAIModelName || 'claude-3-5-sonnet-20241022',\n temperature: DEFAULT_TEMPERATURE,\n });\n } else {\n const modelName = openAIModelName || 'gpt-4o-mini';\n const isGPT5Model =\n modelName.toLowerCase().includes('gpt-5') ||\n modelName.toLowerCase().includes('gpt5');\n llm = new ChatOpenAI({\n apiKey: openAIApiKey,\n modelName: openAIModelName,\n ...(isGPT5Model\n ? { temperature: 1 }\n : { temperature: DEFAULT_TEMPERATURE }),\n });\n }\n\n const allPlugins = this.preparePlugins();\n const agentConfig = this.createAgentConfig(serverSigner, llm, allPlugins);\n\n this.agent = createAgent(agentConfig);\n\n this.configureHCS10Plugin(allPlugins);\n\n this.contentStoreManager = new ContentStoreManager();\n await this.contentStoreManager.initialize();\n this.logger.info(\n 'ContentStoreManager initialized for content reference support'\n );\n\n await this.agent.boot();\n\n if (this.agent) {\n const cfg = agentConfig;\n cfg.filtering = cfg.filtering || {};\n const originalPredicate = cfg.filtering.toolPredicate as\n | ((t: ToolDescriptor) => boolean)\n | undefined;\n const userPredicate = this.options.toolFilter;\n cfg.filtering.toolPredicate = (tool: ToolDescriptor): boolean => {\n if (tool && tool.name === 'hedera-account-transfer-hbar') {\n return false;\n }\n if (tool && tool.name === 'hedera-hts-airdrop-token') {\n return false;\n }\n if (originalPredicate && !originalPredicate(tool)) {\n return false;\n }\n if (userPredicate && !userPredicate(tool)) {\n return false;\n }\n return true;\n };\n }\n\n if (this.options.mcpServers && this.options.mcpServers.length > 0) {\n this.connectMCP();\n }\n } catch (error) {\n this.logger.error('Failed to initialize ConversationalAgent:', error);\n throw error;\n }\n }\n\n /**\n * Get the HCS-10 plugin instance\n * @returns {HCS10Plugin} The HCS-10 plugin instance\n */\n getPlugin(): HCS10Plugin {\n return this.hcs10Plugin;\n }\n\n /**\n * Get the state manager instance\n * @returns {IStateManager} The state manager instance\n */\n getStateManager(): IStateManager {\n return this.stateManager;\n }\n\n /**\n * Get the underlying agent instance\n * @returns {ReturnType<typeof createAgent>} The agent instance\n * @throws {Error} If agent is not initialized\n */\n getAgent(): ReturnType<typeof createAgent> {\n if (!this.agent) {\n throw new Error('Agent not initialized. Call initialize() first.');\n }\n return this.agent;\n }\n\n /**\n * Get the conversational agent instance (alias for getAgent)\n * @returns {ReturnType<typeof createAgent>} The agent instance\n * @throws {Error} If agent is not initialized\n */\n getConversationalAgent(): ReturnType<typeof createAgent> {\n return this.getAgent();\n }\n\n /**\n * Process a message through the conversational agent\n * @param {string} message - The message to process\n * @param {Array<{type: 'human' | 'ai'; content: string}>} chatHistory - Previous chat history\n * @returns {Promise<ChatResponse>} The agent's response\n * @throws {Error} If agent is not initialized\n */\n async processMessage(\n message: string,\n chatHistory: ChatHistoryItem[] = []\n ): Promise<ChatResponse> {\n if (!this.agent) {\n throw new Error('Agent not initialized. Call initialize() first.');\n }\n\n try {\n const resolvedMessage = this.memoryManager\n ? await this.resolveEntitiesInMessage(message)\n : message;\n\n const messages = chatHistory.map((msg) => {\n if (msg.type === 'human') {\n return new HumanMessage(msg.content);\n } else {\n return new AIMessage(msg.content);\n }\n });\n\n const context: ConversationContext = {\n messages,\n };\n\n const response = await this.agent.chat(resolvedMessage, context);\n\n if (this.memoryManager) {\n await this.extractAndStoreEntities(response, message);\n }\n\n this.logger.info('Message processed successfully');\n\n return response;\n } catch (error) {\n this.logger.error('Error processing message:', error);\n throw error;\n }\n }\n\n /**\n * Validates initialization options and throws if required fields are missing.\n *\n * @param accountId - The Hedera account ID\n * @param privateKey - The private key for the account\n * @throws {Error} If required fields are missing\n */\n private validateOptions(accountId?: string, privateKey?: string): void {\n if (!accountId || !privateKey) {\n throw new Error('Account ID and private key are required');\n }\n }\n\n /**\n * Prepares the list of plugins to use based on configuration.\n *\n * @returns Array of plugins to initialize with the agent\n */\n private preparePlugins(): BasePlugin[] {\n const { additionalPlugins = [], enabledPlugins } = this.options;\n\n const standardPlugins = [\n this.hcs10Plugin,\n this.hcs2Plugin,\n this.inscribePlugin,\n this.hbarPlugin,\n ];\n\n const corePlugins = getAllHederaCorePlugins();\n\n if (enabledPlugins) {\n const enabledSet = new Set(enabledPlugins);\n const filteredPlugins = [...standardPlugins, ...corePlugins].filter(\n (plugin) => enabledSet.has(plugin.id)\n );\n return [...filteredPlugins, ...additionalPlugins];\n }\n\n return [...standardPlugins, ...corePlugins, ...additionalPlugins];\n }\n\n /**\n * Creates the agent configuration object.\n *\n * @param serverSigner - The server signer instance\n * @param llm - The language model instance\n * @param allPlugins - Array of plugins to use\n * @returns Configuration object for creating the agent\n */\n private createAgentConfig(\n serverSigner: ServerSigner,\n llm: ChatOpenAI | ChatAnthropic,\n allPlugins: BasePlugin[]\n ): Parameters<typeof createAgent>[0] {\n const {\n operationalMode = DEFAULT_OPERATIONAL_MODE,\n userAccountId,\n scheduleUserTransactionsInBytesMode,\n customSystemMessagePreamble,\n customSystemMessagePostamble,\n verbose = false,\n mirrorNodeConfig,\n disableLogging,\n accountId = '',\n } = this.options;\n\n return {\n framework: 'langchain',\n signer: serverSigner,\n execution: {\n mode: operationalMode === 'autonomous' ? 'direct' : 'bytes',\n operationalMode: operationalMode,\n ...(userAccountId && { userAccountId }),\n ...(scheduleUserTransactionsInBytesMode !== undefined && {\n scheduleUserTransactionsInBytesMode:\n scheduleUserTransactionsInBytesMode,\n scheduleUserTransactions: scheduleUserTransactionsInBytesMode,\n }),\n },\n ai: {\n provider: new LangChainProvider(llm),\n temperature: DEFAULT_TEMPERATURE,\n },\n filtering: {\n toolPredicate: (tool: ToolDescriptor): boolean => {\n if (tool.name === 'hedera-account-transfer-hbar') return false;\n if (this.options.toolFilter && !this.options.toolFilter(tool)) {\n return false;\n }\n return true;\n },\n },\n messaging: {\n systemPreamble:\n customSystemMessagePreamble || getSystemMessage(accountId),\n ...(customSystemMessagePostamble && {\n systemPostamble: customSystemMessagePostamble,\n }),\n conciseMode: true,\n },\n extensions: {\n plugins: allPlugins,\n ...(mirrorNodeConfig && {\n mirrorConfig: mirrorNodeConfig as Record<string, unknown>,\n }),\n },\n ...(this.options.mcpServers && {\n mcp: {\n servers: this.options.mcpServers,\n autoConnect: false,\n },\n }),\n debug: {\n verbose,\n silent: disableLogging ?? false,\n },\n };\n }\n\n /**\n * Configures the HCS-10 plugin with the state manager.\n *\n * @param allPlugins - Array of all plugins\n */\n private configureHCS10Plugin(allPlugins: BasePlugin[]): void {\n const hcs10 = allPlugins.find((p) => p.id === 'hcs-10');\n if (hcs10) {\n (\n hcs10 as BasePlugin & { appConfig?: Record<string, unknown> }\n ).appConfig = {\n stateManager: this.stateManager,\n };\n }\n }\n\n /**\n * Create a ConversationalAgent with specific plugins enabled\n */\n private static withPlugins(\n options: ConversationalAgentOptions,\n plugins: string[]\n ): ConversationalAgent {\n return new ConversationalAgent({\n ...options,\n enabledPlugins: plugins,\n });\n }\n\n /**\n * Create a ConversationalAgent with only HTS (Hedera Token Service) tools enabled\n */\n static withHTS(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hts-token']);\n }\n\n /**\n * Create a ConversationalAgent with only HCS-2 tools enabled\n */\n static withHCS2(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hcs-2']);\n }\n\n /**\n * Create a ConversationalAgent with only HCS-10 tools enabled\n */\n static withHCS10(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hcs-10']);\n }\n\n /**\n * Create a ConversationalAgent with only inscription tools enabled\n */\n static withInscribe(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['inscribe']);\n }\n\n /**\n * Create a ConversationalAgent with only account management tools enabled\n */\n static withAccount(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['account']);\n }\n\n /**\n * Create a ConversationalAgent with only file service tools enabled\n */\n static withFileService(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['file-service']);\n }\n\n /**\n * Create a ConversationalAgent with only consensus service tools enabled\n */\n static withConsensusService(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['consensus-service']);\n }\n\n /**\n * Create a ConversationalAgent with only smart contract tools enabled\n */\n static withSmartContract(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['smart-contract']);\n }\n\n /**\n * Create a ConversationalAgent with all HCS standards plugins\n */\n static withAllStandards(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['hcs-10', 'hcs-2', 'inscribe']);\n }\n\n /**\n * Create a ConversationalAgent with minimal Hedera tools (no HCS standards)\n */\n static minimal(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, []);\n }\n\n /**\n * Create a ConversationalAgent with MCP servers configured\n */\n static withMCP(\n options: ConversationalAgentOptions,\n mcpServers: MCPServerConfig[]\n ): ConversationalAgent {\n return new ConversationalAgent({\n ...options,\n mcpServers,\n });\n }\n\n /**\n * Detect the private key type by querying the account info from mirror node\n * @param {string} accountId - The Hedera account ID\n * @param {string} privateKey - The private key string\n * @param {NetworkType} network - The Hedera Hashgraph\n * @returns {Promise<PrivateKey>} The appropriate PrivateKey instance\n */\n private async detectPrivateKeyType(\n accountId: string,\n privateKey: string,\n network: NetworkType\n ): Promise<PrivateKey> {\n const mirrorNode = new HederaMirrorNode(network as 'testnet' | 'mainnet');\n const accountInfo = await mirrorNode.requestAccount(accountId);\n\n const keyType = accountInfo?.key?._type || '';\n\n if (keyType?.toLowerCase()?.includes('ecdsa')) {\n return PrivateKey.fromStringECDSA(privateKey);\n } else {\n return PrivateKey.fromStringED25519(privateKey);\n }\n }\n\n /**\n * Resolve entity references using LLM-based resolver\n * @param content - Message content to resolve\n * @returns Resolved message content with entity IDs replaced\n */\n private async resolveEntitiesInMessage(content: string): Promise<string> {\n if (!this.memoryManager || !this.entityTools) {\n return content;\n }\n\n try {\n const entities = this.memoryManager.getEntityAssociations();\n\n if (entities.length === 0) {\n this.logger.info('No entities in memory, skipping resolution');\n return content;\n }\n\n this.logger.info(\n `Starting LLM-based entity resolution for: \"${content.substring(\n 0,\n 100\n )}...\"`\n );\n\n const resolvedContent = await this.entityTools.resolveEntities.call({\n message: content,\n entities: entities.map((e) => ({\n entityId: e.entityId,\n entityName: e.entityName,\n entityType: e.entityType,\n })),\n });\n\n if (resolvedContent !== content) {\n this.logger.info(\n `Entity resolution completed. Original: \"${content}\" -> Resolved: \"${resolvedContent}\"`\n );\n }\n\n return resolvedContent;\n } catch (error) {\n this.logger.error('Entity resolution failed:', error);\n throw error;\n }\n }\n\n /**\n * Extract and store entities from agent responses\n * @param response - Agent response containing potential entity information\n * @param originalMessage - Original user message for context\n */\n private async extractAndStoreEntities(\n response: unknown,\n originalMessage: string\n ): Promise<void> {\n if (!this.memoryManager || !this.entityTools) {\n return;\n }\n\n try {\n this.logger.info('Starting LLM-based entity extraction');\n\n const responseText = this.extractResponseText(response);\n\n const entitiesJson = await this.entityTools.extractEntities.call({\n response: responseText,\n userMessage: originalMessage,\n });\n\n try {\n const entities = JSON.parse(entitiesJson);\n\n for (const entity of entities) {\n this.logger.info(\n `Storing entity: ${entity.name} (${entity.type}) -> ${entity.id}`\n );\n\n const transactionId = this.extractTransactionId(response);\n this.memoryManager.storeEntityAssociation(\n entity.id,\n entity.name,\n entity.type,\n transactionId\n );\n }\n\n if (entities.length > 0) {\n this.logger.info(\n `Stored ${entities.length} entities via LLM extraction`\n );\n } else {\n this.logger.info('No entities found in response via LLM extraction');\n }\n } catch (parseError) {\n this.logger.error(\n 'Failed to parse extracted entities JSON:',\n parseError\n );\n throw parseError;\n }\n } catch (error) {\n this.logger.error('Entity extraction failed:', error);\n throw error;\n }\n }\n\n /**\n * Extract transaction ID from response if available\n * @param response - Transaction response\n * @returns Transaction ID or undefined\n */\n private extractTransactionId(response: unknown): string | undefined {\n try {\n if (\n typeof response === 'object' &&\n response &&\n 'transactionId' in response\n ) {\n return (response as { transactionId?: string }).transactionId;\n }\n if (typeof response === 'string') {\n const match = response.match(\n /transaction[\\s\\w]*ID[\\s:\"]*([0-9a-fA-F@\\.\\-]+)/i\n );\n return match ? match[1] : undefined;\n }\n return undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Connect to MCP servers asynchronously\n * @private\n */\n private connectMCP(): void {\n if (!this.agent || !this.options.mcpServers) {\n return;\n }\n\n this.agent\n .connectMCPServers()\n .catch((e) => {\n this.logger.error('Failed to connect MCP servers:', e);\n })\n .then(() => {\n this.logger.info('MCP servers connected successfully');\n });\n }\n\n /**\n * Get MCP connection status for all servers\n * @returns {Map<string, MCPConnectionStatus>} Connection status map\n */\n getMCPConnectionStatus(): Map<string, MCPConnectionStatus> {\n if (this.agent) {\n return this.agent.getMCPConnectionStatus();\n }\n return new Map();\n }\n\n /**\n * Check if a specific MCP server is connected\n * @param {string} serverName - Name of the server to check\n * @returns {boolean} True if connected, false otherwise\n */\n isMCPServerConnected(serverName: string): boolean {\n if (this.agent) {\n const statusMap = this.agent.getMCPConnectionStatus();\n const status = statusMap.get(serverName);\n return status?.connected ?? false;\n }\n return false;\n }\n\n /**\n * Clean up resources\n */\n async cleanup(): Promise<void> {\n try {\n this.logger.info('Cleaning up ConversationalAgent...');\n\n if (this.memoryManager) {\n try {\n this.memoryManager.dispose();\n this.logger.info('Memory manager cleaned up successfully');\n } catch (error) {\n this.logger.warn('Error cleaning up memory manager:', error);\n }\n this.memoryManager = undefined;\n }\n\n if (this.contentStoreManager) {\n await this.contentStoreManager.dispose();\n this.logger.info('ContentStoreManager cleaned up');\n }\n\n this.logger.info('ConversationalAgent cleanup completed');\n } catch (error) {\n this.logger.error('Error during cleanup:', error);\n }\n }\n\n private extractResponseText(response: unknown): string {\n if (typeof response === 'string') {\n return response;\n }\n\n if (response && typeof response === 'object' && 'output' in response) {\n return String(response.output);\n }\n\n return JSON.stringify(response);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -41,7 +41,7 @@ class BaseAgent {
41
41
  parts.push(this.config.messaging.systemPreamble);
42
42
  }
43
43
  parts.push(
44
- `You are a helpful Hedera assistant. Your primary operator account is ${operatorId}. You have tools to interact with the Hedera network. When using any tool, provide all necessary parameters as defined by that tool's schema and description.`
44
+ `You are a helpful Hedera assistant. Your primary operator account is ${operatorId}. You have tools to interact with the Hedera Hashgraph. When using any tool, provide all necessary parameters as defined by that tool's schema and description.`
45
45
  );
46
46
  if (userAccId) {
47
47
  parts.push(
@@ -63,7 +63,7 @@ OPERATIONAL MODE: 'returnBytes' with scheduled transactions for user actions. Wh
63
63
  } else {
64
64
  parts.push(
65
65
  `
66
- OPERATIONAL MODE: 'returnBytes'. Your goal is to provide transaction bytes directly. When a user asks for a transaction to be prepared (e.g., for them to sign, or for scheduling without the default scheduling flow), you MUST call the appropriate tool. If you want raw bytes for the user to sign for their own account ${userAccId || "if specified"}, ensure the tool constructs the transaction body accordingly and use metaOption 'returnBytes: true' if available, or ensure the builder is configured for the user.`
66
+ OPERATIONAL MODE: 'returnBytes'. Your goal is to provide transaction bytes when possible. When a user asks for a transaction to be prepared (e.g., for them to sign, or for scheduling without the default scheduling flow), you MUST call the appropriate tool. IMPORTANT: Only use metaOption 'returnBytes: true' for tools that explicitly support it (like HBAR transfers, token operations). Many tools (inscriptions, HCS-2, HCS-20, etc.) do NOT support returnBytes and will execute directly - this is expected behavior. For tools without returnBytes support, simply call them with their standard parameters. If you need raw bytes for the user to sign for their own account ${userAccId || "if specified"}, ensure the tool constructs the transaction body accordingly when returnBytes IS supported.`
67
67
  );
68
68
  }
69
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index7.js","sources":["../../src/base-agent.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport type { StructuredTool } from '@langchain/core/tools';\nimport type { TransactionReceipt } from '@hashgraph/sdk';\nimport {\n HederaAgentKit,\n ServerSigner,\n TokenUsageCallbackHandler,\n TokenUsage,\n BasePlugin,\n} from 'hedera-agent-kit';\nimport type { CostCalculation } from 'hedera-agent-kit';\nimport type { AIProvider, VercelAIProvider, BAMLProvider } from './providers';\nimport { Logger } from '@hashgraphonline/standards-sdk';\nimport type { MCPServerConfig } from './mcp/types';\n\nexport interface ToolFilterConfig {\n namespaceWhitelist?: string[];\n toolBlacklist?: string[];\n toolPredicate?: (tool: StructuredTool) => boolean;\n}\n\nexport type ExecutionMode = 'direct' | 'bytes';\nexport type OperationalMode = 'autonomous' | 'returnBytes';\n\nexport interface HederaAgentConfiguration {\n signer: ServerSigner;\n execution?: {\n mode?: ExecutionMode;\n operationalMode?: OperationalMode;\n userAccountId?: string;\n scheduleUserTransactions?: boolean;\n scheduleUserTransactionsInBytesMode?: boolean;\n };\n ai?: {\n provider?: AIProvider;\n llm?: unknown;\n apiKey?: string;\n modelName?: string;\n temperature?: number;\n };\n filtering?: ToolFilterConfig;\n messaging?: {\n systemPreamble?: string;\n systemPostamble?: string;\n conciseMode?: boolean;\n };\n extensions?: {\n plugins?: BasePlugin[];\n mirrorConfig?: Record<string, unknown>;\n modelCapability?: string;\n };\n mcp?: {\n servers?: MCPServerConfig[];\n autoConnect?: boolean;\n };\n debug?: {\n verbose?: boolean;\n silent?: boolean;\n };\n}\n\nexport interface ConversationContext {\n messages: BaseMessage[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface ChatResponse {\n output: string;\n message?: string;\n transactionBytes?: string;\n receipt?: TransactionReceipt | object;\n scheduleId?: string;\n transactionId?: string;\n notes?: string[];\n error?: string;\n intermediateSteps?: unknown;\n rawToolOutput?: unknown;\n tokenUsage?: TokenUsage;\n cost?: CostCalculation;\n metadata?: Record<string, unknown>;\n tool_calls?: Array<{\n id: string;\n name: string;\n args: Record<string, unknown>;\n output?: string;\n }>;\n [key: string]: unknown;\n}\n\nexport interface UsageStats extends TokenUsage {\n cost: CostCalculation;\n}\n\nexport abstract class BaseAgent {\n protected logger: Logger;\n protected agentKit: HederaAgentKit | undefined;\n protected tools: StructuredTool[] = [];\n protected initialized = false;\n protected tokenTracker: TokenUsageCallbackHandler | undefined;\n\n constructor(protected config: HederaAgentConfiguration) {\n this.logger = new Logger({\n module: 'BaseAgent',\n silent: config.debug?.silent || false,\n });\n }\n\n abstract boot(): Promise<void>;\n abstract chat(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse>;\n abstract shutdown(): Promise<void>;\n abstract switchMode(mode: OperationalMode): void;\n abstract getUsageStats(): UsageStats;\n abstract getUsageLog(): UsageStats[];\n abstract clearUsageStats(): void;\n\n getCore(): HederaAgentKit | undefined {\n return this.agentKit;\n }\n\n protected filterTools(\n tools: StructuredTool[]\n ): StructuredTool[] {\n let filtered = [...tools];\n const filter = this.config.filtering;\n if (!filter) return filtered;\n\n if (filter.namespaceWhitelist?.length) {\n filtered = filtered.filter((tool) => {\n const namespace = (tool as StructuredTool & { namespace?: string })\n .namespace;\n return !namespace || filter.namespaceWhitelist!.includes(namespace);\n });\n }\n\n if (filter.toolBlacklist?.length) {\n filtered = filtered.filter(\n (tool) => !filter.toolBlacklist!.includes(tool.name)\n );\n }\n\n if (filter.toolPredicate) {\n filtered = filtered.filter(filter.toolPredicate);\n }\n\n this.logger.debug(`Filtered tools: ${tools.length} → ${filtered.length}`);\n return filtered;\n }\n\n protected buildSystemPrompt(): string {\n const parts: string[] = [];\n const operatorId = this.config.signer.getAccountId().toString();\n const userAccId = this.config.execution?.userAccountId;\n\n if (this.config.messaging?.systemPreamble) {\n parts.push(this.config.messaging.systemPreamble);\n }\n\n parts.push(\n `You are a helpful Hedera assistant. Your primary operator account is ${operatorId}. ` +\n `You have tools to interact with the Hedera network. ` +\n `When using any tool, provide all necessary parameters as defined by that tool's schema and description.`\n );\n\n if (userAccId) {\n parts.push(\n `The user you are assisting has a personal Hedera account ID: ${userAccId}. ` +\n `IMPORTANT: When the user says things like \"I want to send HBAR\" or \"transfer my tokens\", you MUST use ${userAccId} as the sender/from account. ` +\n `For example, if user says \"I want to send 2 HBAR to 0.0.800\", you must set up a transfer where ${userAccId} sends the HBAR, not your operator account.`\n );\n }\n\n const operationalMode =\n this.config.execution?.operationalMode || 'returnBytes';\n if (operationalMode === 'autonomous') {\n parts.push(\n `\\nOPERATIONAL MODE: 'autonomous'. Your goal is to execute transactions directly using your tools. ` +\n `Your account ${operatorId} will be the payer for these transactions. ` +\n `Even if the user's account (${\n userAccId || 'a specified account'\n }) is the actor in the transaction body (e.g., sender of HBAR), ` +\n `you (the agent with operator ${operatorId}) are still executing and paying. For HBAR transfers, ensure the amounts in the 'transfers' array sum to zero (as per tool schema), balancing with your operator account if necessary.`\n );\n } else {\n if (\n this.config.execution?.scheduleUserTransactionsInBytesMode &&\n userAccId\n ) {\n parts.push(\n `\\nOPERATIONAL MODE: 'returnBytes' with scheduled transactions for user actions. ` +\n `When a user asks for a transaction to be prepared (e.g., creating a token, topic, transferring assets for them to sign, etc), ` +\n `you MUST default to creating a Scheduled Transaction using the appropriate tool with the metaOption 'schedule: true'. ` +\n `The user (with account ID ${userAccId}) will be the one to ultimately pay for and (if needed) sign the inner transaction. ` +\n `Your operator account (${operatorId}) will pay for creating the schedule entity itself. ` +\n `You MUST return the ScheduleId and details of the scheduled operation in a structured JSON format with these fields: success, op, schedule_id, description, payer_account_id_scheduled_tx, and scheduled_transaction_details.`\n );\n } else {\n parts.push(\n `\\nOPERATIONAL MODE: 'returnBytes'. Your goal is to provide transaction bytes directly. ` +\n `When a user asks for a transaction to be prepared (e.g., for them to sign, or for scheduling without the default scheduling flow), ` +\n `you MUST call the appropriate tool. If you want raw bytes for the user to sign for their own account ${\n userAccId || 'if specified'\n }, ensure the tool constructs the transaction body accordingly and use metaOption 'returnBytes: true' if available, or ensure the builder is configured for the user.`\n );\n }\n }\n\n if (this.config.messaging?.conciseMode !== false) {\n parts.push(\n '\\nAlways be concise. If the tool provides a JSON string as its primary output (especially in returnBytes mode), make your accompanying text brief. If the tool does not provide JSON output or an error occurs, your narrative becomes primary; if notes were generated by the tool in such cases, append them to your textual response.'\n );\n }\n\n if (this.config.messaging?.systemPostamble) {\n parts.push(this.config.messaging.systemPostamble);\n }\n\n return parts.join('\\n');\n }\n\n isReady(): boolean {\n return this.initialized;\n }\n}\n\nexport type { AIProvider, VercelAIProvider, BAMLProvider };\n"],"names":[],"mappings":";AA6FO,MAAe,UAAU;AAAA,EAO9B,YAAsB,QAAkC;AAAlC,SAAA,SAAA;AAJtB,SAAU,QAA0B,CAAA;AACpC,SAAU,cAAc;AAItB,SAAK,SAAS,IAAI,OAAO;AAAA,MACvB,QAAQ;AAAA,MACR,QAAQ,OAAO,OAAO,UAAU;AAAA,IAAA,CACjC;AAAA,EACH;AAAA,EAaA,UAAsC;AACpC,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,YACR,OACkB;AAClB,QAAI,WAAW,CAAC,GAAG,KAAK;AACxB,UAAM,SAAS,KAAK,OAAO;AAC3B,QAAI,CAAC,OAAQ,QAAO;AAEpB,QAAI,OAAO,oBAAoB,QAAQ;AACrC,iBAAW,SAAS,OAAO,CAAC,SAAS;AACnC,cAAM,YAAa,KAChB;AACH,eAAO,CAAC,aAAa,OAAO,mBAAoB,SAAS,SAAS;AAAA,MACpE,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,eAAe,QAAQ;AAChC,iBAAW,SAAS;AAAA,QAClB,CAAC,SAAS,CAAC,OAAO,cAAe,SAAS,KAAK,IAAI;AAAA,MAAA;AAAA,IAEvD;AAEA,QAAI,OAAO,eAAe;AACxB,iBAAW,SAAS,OAAO,OAAO,aAAa;AAAA,IACjD;AAEA,SAAK,OAAO,MAAM,mBAAmB,MAAM,MAAM,MAAM,SAAS,MAAM,EAAE;AACxE,WAAO;AAAA,EACT;AAAA,EAEU,oBAA4B;AACpC,UAAM,QAAkB,CAAA;AACxB,UAAM,aAAa,KAAK,OAAO,OAAO,aAAA,EAAe,SAAA;AACrD,UAAM,YAAY,KAAK,OAAO,WAAW;AAEzC,QAAI,KAAK,OAAO,WAAW,gBAAgB;AACzC,YAAM,KAAK,KAAK,OAAO,UAAU,cAAc;AAAA,IACjD;AAEA,UAAM;AAAA,MACJ,wEAAwE,UAAU;AAAA,IAAA;AAKpF,QAAI,WAAW;AACb,YAAM;AAAA,QACJ,gEAAgE,SAAS,2GACkC,SAAS,+HAChB,SAAS;AAAA,MAAA;AAAA,IAEjH;AAEA,UAAM,kBACJ,KAAK,OAAO,WAAW,mBAAmB;AAC5C,QAAI,oBAAoB,cAAc;AACpC,YAAM;AAAA,QACJ;AAAA,+GACkB,UAAU,0EAExB,aAAa,qBACf,+FACgC,UAAU;AAAA,MAAA;AAAA,IAEhD,OAAO;AACL,UACE,KAAK,OAAO,WAAW,uCACvB,WACA;AACA,cAAM;AAAA,UACJ;AAAA,8VAG+B,SAAS,8GACZ,UAAU;AAAA,QAAA;AAAA,MAG1C,OAAO;AACL,cAAM;AAAA,UACJ;AAAA,+TAGI,aAAa,cACf;AAAA,QAAA;AAAA,MAEN;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,WAAW,gBAAgB,OAAO;AAChD,YAAM;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,KAAK,OAAO,WAAW,iBAAiB;AAC1C,YAAM,KAAK,KAAK,OAAO,UAAU,eAAe;AAAA,IAClD;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AACF;"}
1
+ {"version":3,"file":"index7.js","sources":["../../src/base-agent.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport type { StructuredTool } from '@langchain/core/tools';\nimport type { TransactionReceipt } from '@hashgraph/sdk';\nimport {\n HederaAgentKit,\n ServerSigner,\n TokenUsageCallbackHandler,\n TokenUsage,\n BasePlugin,\n} from 'hedera-agent-kit';\nimport type { CostCalculation } from 'hedera-agent-kit';\nimport type { AIProvider, VercelAIProvider, BAMLProvider } from './providers';\nimport { Logger } from '@hashgraphonline/standards-sdk';\nimport type { MCPServerConfig, MCPConnectionStatus } from './mcp/types';\n\nexport interface ToolFilterConfig {\n namespaceWhitelist?: string[];\n toolBlacklist?: string[];\n toolPredicate?: (tool: StructuredTool) => boolean;\n}\n\nexport type ExecutionMode = 'direct' | 'bytes';\nexport type OperationalMode = 'autonomous' | 'returnBytes';\n\nexport interface HederaAgentConfiguration {\n signer: ServerSigner;\n execution?: {\n mode?: ExecutionMode;\n operationalMode?: OperationalMode;\n userAccountId?: string;\n scheduleUserTransactions?: boolean;\n scheduleUserTransactionsInBytesMode?: boolean;\n };\n ai?: {\n provider?: AIProvider;\n llm?: unknown;\n apiKey?: string;\n modelName?: string;\n temperature?: number;\n };\n filtering?: ToolFilterConfig;\n messaging?: {\n systemPreamble?: string;\n systemPostamble?: string;\n conciseMode?: boolean;\n };\n extensions?: {\n plugins?: BasePlugin[];\n mirrorConfig?: Record<string, unknown>;\n modelCapability?: string;\n };\n mcp?: {\n servers?: MCPServerConfig[];\n autoConnect?: boolean;\n };\n debug?: {\n verbose?: boolean;\n silent?: boolean;\n };\n}\n\nexport interface ConversationContext {\n messages: BaseMessage[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface ChatResponse {\n output: string;\n message?: string;\n transactionBytes?: string;\n receipt?: TransactionReceipt | object;\n scheduleId?: string;\n transactionId?: string;\n notes?: string[];\n error?: string;\n intermediateSteps?: unknown;\n rawToolOutput?: unknown;\n tokenUsage?: TokenUsage;\n cost?: CostCalculation;\n metadata?: Record<string, unknown>;\n tool_calls?: Array<{\n id: string;\n name: string;\n args: Record<string, unknown>;\n output?: string;\n }>;\n [key: string]: unknown;\n}\n\nexport interface UsageStats extends TokenUsage {\n cost: CostCalculation;\n}\n\nexport abstract class BaseAgent {\n protected logger: Logger;\n protected agentKit: HederaAgentKit | undefined;\n protected tools: StructuredTool[] = [];\n protected initialized = false;\n protected tokenTracker: TokenUsageCallbackHandler | undefined;\n\n constructor(protected config: HederaAgentConfiguration) {\n this.logger = new Logger({\n module: 'BaseAgent',\n silent: config.debug?.silent || false,\n });\n }\n\n abstract boot(): Promise<void>;\n abstract chat(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse>;\n abstract shutdown(): Promise<void>;\n abstract switchMode(mode: OperationalMode): void;\n abstract getUsageStats(): UsageStats;\n abstract getUsageLog(): UsageStats[];\n abstract clearUsageStats(): void;\n abstract connectMCPServers(): Promise<void>;\n abstract getMCPConnectionStatus(): Map<string, MCPConnectionStatus>;\n\n public getCore(): HederaAgentKit | undefined {\n return this.agentKit;\n }\n\n protected filterTools(tools: StructuredTool[]): StructuredTool[] {\n let filtered = [...tools];\n const filter = this.config.filtering;\n\n if (!filter) return filtered;\n\n if (filter.namespaceWhitelist?.length) {\n filtered = filtered.filter((tool) => {\n const namespace = (tool as StructuredTool & { namespace?: string })\n .namespace;\n return !namespace || filter.namespaceWhitelist!.includes(namespace);\n });\n }\n\n if (filter.toolBlacklist?.length) {\n filtered = filtered.filter(\n (tool) => !filter.toolBlacklist!.includes(tool.name)\n );\n }\n\n if (filter.toolPredicate) {\n filtered = filtered.filter(filter.toolPredicate);\n }\n\n this.logger.debug(`Filtered tools: ${tools.length} → ${filtered.length}`);\n return filtered;\n }\n\n protected buildSystemPrompt(): string {\n const parts: string[] = [];\n const operatorId = this.config.signer.getAccountId().toString();\n const userAccId = this.config.execution?.userAccountId;\n\n if (this.config.messaging?.systemPreamble) {\n parts.push(this.config.messaging.systemPreamble);\n }\n\n parts.push(\n `You are a helpful Hedera assistant. Your primary operator account is ${operatorId}. ` +\n `You have tools to interact with the Hedera Hashgraph. ` +\n `When using any tool, provide all necessary parameters as defined by that tool's schema and description.`\n );\n\n if (userAccId) {\n parts.push(\n `The user you are assisting has a personal Hedera account ID: ${userAccId}. ` +\n `IMPORTANT: When the user says things like \"I want to send HBAR\" or \"transfer my tokens\", you MUST use ${userAccId} as the sender/from account. ` +\n `For example, if user says \"I want to send 2 HBAR to 0.0.800\", you must set up a transfer where ${userAccId} sends the HBAR, not your operator account.`\n );\n }\n\n const operationalMode =\n this.config.execution?.operationalMode || 'returnBytes';\n if (operationalMode === 'autonomous') {\n parts.push(\n `\\nOPERATIONAL MODE: 'autonomous'. Your goal is to execute transactions directly using your tools. ` +\n `Your account ${operatorId} will be the payer for these transactions. ` +\n `Even if the user's account (${\n userAccId || 'a specified account'\n }) is the actor in the transaction body (e.g., sender of HBAR), ` +\n `you (the agent with operator ${operatorId}) are still executing and paying. For HBAR transfers, ensure the amounts in the 'transfers' array sum to zero (as per tool schema), balancing with your operator account if necessary.`\n );\n } else {\n if (\n this.config.execution?.scheduleUserTransactionsInBytesMode &&\n userAccId\n ) {\n parts.push(\n `\\nOPERATIONAL MODE: 'returnBytes' with scheduled transactions for user actions. ` +\n `When a user asks for a transaction to be prepared (e.g., creating a token, topic, transferring assets for them to sign, etc), ` +\n `you MUST default to creating a Scheduled Transaction using the appropriate tool with the metaOption 'schedule: true'. ` +\n `The user (with account ID ${userAccId}) will be the one to ultimately pay for and (if needed) sign the inner transaction. ` +\n `Your operator account (${operatorId}) will pay for creating the schedule entity itself. ` +\n `You MUST return the ScheduleId and details of the scheduled operation in a structured JSON format with these fields: success, op, schedule_id, description, payer_account_id_scheduled_tx, and scheduled_transaction_details.`\n );\n } else {\n parts.push(\n `\\nOPERATIONAL MODE: 'returnBytes'. Your goal is to provide transaction bytes when possible. ` +\n `When a user asks for a transaction to be prepared (e.g., for them to sign, or for scheduling without the default scheduling flow), ` +\n `you MUST call the appropriate tool. ` +\n `IMPORTANT: Only use metaOption 'returnBytes: true' for tools that explicitly support it (like HBAR transfers, token operations). ` +\n `Many tools (inscriptions, HCS-2, HCS-20, etc.) do NOT support returnBytes and will execute directly - this is expected behavior. ` +\n `For tools without returnBytes support, simply call them with their standard parameters. ` +\n `If you need raw bytes for the user to sign for their own account ${\n userAccId || 'if specified'\n }, ensure the tool constructs the transaction body accordingly when returnBytes IS supported.`\n );\n }\n }\n\n if (this.config.messaging?.conciseMode !== false) {\n parts.push(\n '\\nAlways be concise. If the tool provides a JSON string as its primary output (especially in returnBytes mode), make your accompanying text brief. If the tool does not provide JSON output or an error occurs, your narrative becomes primary; if notes were generated by the tool in such cases, append them to your textual response.'\n );\n }\n\n if (this.config.messaging?.systemPostamble) {\n parts.push(this.config.messaging.systemPostamble);\n }\n\n return parts.join('\\n');\n }\n\n isReady(): boolean {\n return this.initialized;\n }\n}\n\nexport type { AIProvider, VercelAIProvider, BAMLProvider };\n"],"names":[],"mappings":";AA6FO,MAAe,UAAU;AAAA,EAO9B,YAAsB,QAAkC;AAAlC,SAAA,SAAA;AAJtB,SAAU,QAA0B,CAAA;AACpC,SAAU,cAAc;AAItB,SAAK,SAAS,IAAI,OAAO;AAAA,MACvB,QAAQ;AAAA,MACR,QAAQ,OAAO,OAAO,UAAU;AAAA,IAAA,CACjC;AAAA,EACH;AAAA,EAeO,UAAsC;AAC3C,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,YAAY,OAA2C;AAC/D,QAAI,WAAW,CAAC,GAAG,KAAK;AACxB,UAAM,SAAS,KAAK,OAAO;AAE3B,QAAI,CAAC,OAAQ,QAAO;AAEpB,QAAI,OAAO,oBAAoB,QAAQ;AACrC,iBAAW,SAAS,OAAO,CAAC,SAAS;AACnC,cAAM,YAAa,KAChB;AACH,eAAO,CAAC,aAAa,OAAO,mBAAoB,SAAS,SAAS;AAAA,MACpE,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,eAAe,QAAQ;AAChC,iBAAW,SAAS;AAAA,QAClB,CAAC,SAAS,CAAC,OAAO,cAAe,SAAS,KAAK,IAAI;AAAA,MAAA;AAAA,IAEvD;AAEA,QAAI,OAAO,eAAe;AACxB,iBAAW,SAAS,OAAO,OAAO,aAAa;AAAA,IACjD;AAEA,SAAK,OAAO,MAAM,mBAAmB,MAAM,MAAM,MAAM,SAAS,MAAM,EAAE;AACxE,WAAO;AAAA,EACT;AAAA,EAEU,oBAA4B;AACpC,UAAM,QAAkB,CAAA;AACxB,UAAM,aAAa,KAAK,OAAO,OAAO,aAAA,EAAe,SAAA;AACrD,UAAM,YAAY,KAAK,OAAO,WAAW;AAEzC,QAAI,KAAK,OAAO,WAAW,gBAAgB;AACzC,YAAM,KAAK,KAAK,OAAO,UAAU,cAAc;AAAA,IACjD;AAEA,UAAM;AAAA,MACJ,wEAAwE,UAAU;AAAA,IAAA;AAKpF,QAAI,WAAW;AACb,YAAM;AAAA,QACJ,gEAAgE,SAAS,2GACkC,SAAS,+HAChB,SAAS;AAAA,MAAA;AAAA,IAEjH;AAEA,UAAM,kBACJ,KAAK,OAAO,WAAW,mBAAmB;AAC5C,QAAI,oBAAoB,cAAc;AACpC,YAAM;AAAA,QACJ;AAAA,+GACkB,UAAU,0EAExB,aAAa,qBACf,+FACgC,UAAU;AAAA,MAAA;AAAA,IAEhD,OAAO;AACL,UACE,KAAK,OAAO,WAAW,uCACvB,WACA;AACA,cAAM;AAAA,UACJ;AAAA,8VAG+B,SAAS,8GACZ,UAAU;AAAA,QAAA;AAAA,MAG1C,OAAO;AACL,cAAM;AAAA,UACJ;AAAA,8pBAOI,aAAa,cACf;AAAA,QAAA;AAAA,MAEN;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,WAAW,gBAAgB,OAAO;AAChD,YAAM;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,KAAK,OAAO,WAAW,iBAAiB;AAC1C,YAAM,KAAK,KAAK,OAAO,UAAU,eAAe;AAAA,IAClD;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AACF;"}
@@ -1,16 +1,17 @@
1
1
  import { createOpenAIToolsAgent } from "langchain/agents";
2
- import { ContentAwareAgentExecutor } from "./index19.js";
2
+ import { ContentAwareAgentExecutor } from "./index21.js";
3
3
  import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
4
4
  import { ChatOpenAI } from "@langchain/openai";
5
5
  import { TokenUsageCallbackHandler, calculateTokenCostSync, getAllHederaCorePlugins, HederaAgentKit } from "hedera-agent-kit";
6
6
  import { BaseAgent } from "./index7.js";
7
- import { MCPClientManager } from "./index20.js";
8
- import { convertMCPToolToLangChain } from "./index21.js";
7
+ import { MCPClientManager } from "./index22.js";
8
+ import { convertMCPToolToLangChain } from "./index23.js";
9
9
  import { SmartMemoryManager } from "./index15.js";
10
10
  class LangChainAgent extends BaseAgent {
11
11
  constructor() {
12
12
  super(...arguments);
13
13
  this.systemMessage = "";
14
+ this.mcpConnectionStatus = /* @__PURE__ */ new Map();
14
15
  }
15
16
  async boot() {
16
17
  if (this.initialized) {
@@ -28,7 +29,9 @@ class LangChainAgent extends BaseAgent {
28
29
  if (this.config.mcp.autoConnect !== false) {
29
30
  await this.initializeMCP();
30
31
  } else {
31
- this.logger.info("MCP servers configured but autoConnect=false, skipping synchronous connection");
32
+ this.logger.info(
33
+ "MCP servers configured but autoConnect=false, skipping synchronous connection"
34
+ );
32
35
  this.mcpManager = new MCPClientManager(this.logger);
33
36
  }
34
37
  }
@@ -59,7 +62,10 @@ class LangChainAgent extends BaseAgent {
59
62
  throw new Error("Agent not initialized. Call boot() first.");
60
63
  }
61
64
  try {
62
- this.logger.info("LangChainAgent.chat called with:", { message, contextLength: context?.messages?.length || 0 });
65
+ this.logger.info("LangChainAgent.chat called with:", {
66
+ message,
67
+ contextLength: context?.messages?.length || 0
68
+ });
63
69
  if (context?.messages && context.messages.length > 0) {
64
70
  this.smartMemory.clear();
65
71
  for (const msg of context.messages) {
@@ -88,12 +94,14 @@ class LangChainAgent extends BaseAgent {
88
94
  intermediateSteps: result.intermediateSteps
89
95
  };
90
96
  if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {
91
- const toolCalls = result.intermediateSteps.map((step, index) => ({
92
- id: `call_${index}`,
93
- name: step.action?.tool || "unknown",
94
- args: step.action?.toolInput || {},
95
- output: typeof step.observation === "string" ? step.observation : JSON.stringify(step.observation)
96
- }));
97
+ const toolCalls = result.intermediateSteps.map(
98
+ (step, index) => ({
99
+ id: `call_${index}`,
100
+ name: step.action?.tool || "unknown",
101
+ args: step.action?.toolInput || {},
102
+ output: typeof step.observation === "string" ? step.observation : JSON.stringify(step.observation)
103
+ })
104
+ );
97
105
  if (toolCalls.length > 0) {
98
106
  response.tool_calls = toolCalls;
99
107
  }
@@ -192,6 +200,9 @@ class LangChainAgent extends BaseAgent {
192
200
  this.logger.info("Usage statistics cleared");
193
201
  }
194
202
  }
203
+ getMCPConnectionStatus() {
204
+ return new Map(this.mcpConnectionStatus);
205
+ }
195
206
  async createAgentKit() {
196
207
  const corePlugins = getAllHederaCorePlugins();
197
208
  const extensionPlugins = this.config.extensions?.plugins || [];
@@ -221,11 +232,13 @@ class LangChainAgent extends BaseAgent {
221
232
  if (!apiKey) {
222
233
  throw new Error("OpenAI API key required");
223
234
  }
235
+ const modelName = this.config.ai?.modelName || "gpt-4o-mini";
236
+ const isGPT5Model = modelName.toLowerCase().includes("gpt-5") || modelName.toLowerCase().includes("gpt5");
224
237
  llm = new ChatOpenAI({
225
238
  apiKey,
226
- modelName: this.config.ai?.modelName || "gpt-4o-mini",
227
- temperature: this.config.ai?.temperature ?? 0.1,
228
- callbacks: this.tokenTracker ? [this.tokenTracker] : []
239
+ modelName,
240
+ callbacks: this.tokenTracker ? [this.tokenTracker] : [],
241
+ ...isGPT5Model ? { temperature: 1 } : {}
229
242
  });
230
243
  }
231
244
  const prompt = ChatPromptTemplate.fromMessages([
@@ -258,8 +271,8 @@ class LangChainAgent extends BaseAgent {
258
271
  cost = calculateTokenCostSync(tokenUsage);
259
272
  }
260
273
  }
261
- let userFriendlyMessage = "Sorry, I encountered an error processing your request.";
262
- let userFriendlyOutput = "Sorry, I encountered an error processing your request.";
274
+ let userFriendlyMessage = errorMessage;
275
+ let userFriendlyOutput = errorMessage;
263
276
  if (errorMessage.includes("429")) {
264
277
  if (errorMessage.includes("quota")) {
265
278
  userFriendlyMessage = "API quota exceeded. Please check your OpenAI billing and usage limits.";
@@ -277,6 +290,9 @@ class LangChainAgent extends BaseAgent {
277
290
  } else if (errorMessage.includes("network") || errorMessage.includes("fetch")) {
278
291
  userFriendlyMessage = "Network error. Please check your internet connection and try again.";
279
292
  userFriendlyOutput = "There was a network error. Please check your internet connection and try again.";
293
+ } else if (errorMessage.includes("400")) {
294
+ userFriendlyMessage = errorMessage;
295
+ userFriendlyOutput = errorMessage;
280
296
  }
281
297
  const errorResponse = {
282
298
  output: userFriendlyOutput,
@@ -322,53 +338,69 @@ class LangChainAgent extends BaseAgent {
322
338
  }
323
339
  }
324
340
  /**
325
- * Connect to MCP servers asynchronously after agent boot
341
+ * Connect to MCP servers asynchronously after agent boot with background timeout pattern
326
342
  */
327
343
  async connectMCPServers() {
328
344
  if (!this.config.mcp?.servers || this.config.mcp.servers.length === 0) {
329
345
  return;
330
346
  }
331
347
  if (!this.mcpManager) {
332
- this.logger.warn("MCP manager not initialized. Cannot connect to servers.");
333
- return;
334
- }
335
- this.logger.info("Starting async MCP server connections...");
336
- for (const serverConfig of this.config.mcp.servers) {
337
- this.connectServer(serverConfig).catch((error) => {
338
- this.logger.error(`Connection to MCP server ${serverConfig.name} failed:`, error);
339
- });
348
+ this.mcpManager = new MCPClientManager(this.logger);
340
349
  }
350
+ this.logger.info(
351
+ `Starting background MCP server connections for ${this.config.mcp.servers.length} servers...`
352
+ );
353
+ this.config.mcp.servers.forEach((serverConfig) => {
354
+ this.connectServerInBackground(serverConfig);
355
+ });
356
+ this.logger.info("MCP server connections initiated in background");
341
357
  }
342
358
  /**
343
- * Connect to a single MCP server
359
+ * Connect to a single MCP server in background with timeout
344
360
  */
345
- async connectServer(serverConfig) {
346
- try {
347
- this.logger.info(`Connecting to MCP server: ${serverConfig.name}`);
348
- const status = await this.mcpManager.connectServer(serverConfig);
349
- if (status.connected) {
350
- this.logger.info(
351
- `Connected to MCP server ${status.serverName} with ${status.tools.length} tools`
352
- );
353
- for (const mcpTool of status.tools) {
354
- const langchainTool = convertMCPToolToLangChain(
355
- mcpTool,
356
- this.mcpManager,
357
- serverConfig
361
+ connectServerInBackground(serverConfig) {
362
+ const serverName = serverConfig.name;
363
+ setTimeout(async () => {
364
+ try {
365
+ this.logger.info(`Background connecting to MCP server: ${serverName}`);
366
+ const status = await this.mcpManager.connectServer(serverConfig);
367
+ this.mcpConnectionStatus.set(serverName, status);
368
+ if (status.connected) {
369
+ this.logger.info(
370
+ `Successfully connected to MCP server ${status.serverName} with ${status.tools.length} tools`
371
+ );
372
+ for (const mcpTool of status.tools) {
373
+ const langchainTool = convertMCPToolToLangChain(
374
+ mcpTool,
375
+ this.mcpManager,
376
+ serverConfig
377
+ );
378
+ this.tools.push(langchainTool);
379
+ }
380
+ if (this.initialized && this.executor) {
381
+ this.logger.info(
382
+ `Recreating executor with ${this.tools.length} total tools`
383
+ );
384
+ await this.createExecutor();
385
+ }
386
+ } else {
387
+ this.logger.error(
388
+ `Failed to connect to MCP server ${status.serverName}: ${status.error}`
358
389
  );
359
- this.tools.push(langchainTool);
360
- }
361
- if (this.initialized && this.executor) {
362
- await this.createExecutor();
363
390
  }
364
- } else {
391
+ } catch (error) {
365
392
  this.logger.error(
366
- `Failed to connect to MCP server ${status.serverName}: ${status.error}`
393
+ `Background connection failed for MCP server ${serverName}:`,
394
+ error
367
395
  );
396
+ this.mcpConnectionStatus.set(serverName, {
397
+ connected: false,
398
+ serverName,
399
+ tools: [],
400
+ error: error instanceof Error ? error.message : "Connection failed"
401
+ });
368
402
  }
369
- } catch (error) {
370
- this.logger.error(`Error connecting to MCP server ${serverConfig.name}:`, error);
371
- }
403
+ }, 1e3);
372
404
  }
373
405
  /**
374
406
  * Check if a string is valid JSON
@@ -1 +1 @@
1
- {"version":3,"file":"index8.js","sources":["../../src/langchain-agent.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { StructuredTool } from '@langchain/core/tools';\nimport { createOpenAIToolsAgent } from 'langchain/agents';\nimport { ContentAwareAgentExecutor } from './langchain/ContentAwareAgentExecutor';\nimport {\n ChatPromptTemplate,\n MessagesPlaceholder,\n} from '@langchain/core/prompts';\nimport { ChatOpenAI } from '@langchain/openai';\nimport {\n calculateTokenCostSync,\n getAllHederaCorePlugins,\n HederaAgentKit,\n TokenUsageCallbackHandler,\n} from 'hedera-agent-kit';\nimport type { TokenUsage, CostCalculation } from 'hedera-agent-kit';\nimport {\n BaseAgent,\n type ConversationContext,\n type ChatResponse,\n type OperationalMode,\n type UsageStats,\n} from './base-agent';\nimport { MCPClientManager } from './mcp/MCPClientManager';\nimport { convertMCPToolToLangChain } from './mcp/adapters/langchain';\nimport { SmartMemoryManager } from './memory/SmartMemoryManager';\n\nexport class LangChainAgent extends BaseAgent {\n private executor: ContentAwareAgentExecutor | undefined;\n private systemMessage = '';\n private mcpManager?: MCPClientManager;\n private smartMemory: SmartMemoryManager | undefined;\n\n async boot(): Promise<void> {\n if (this.initialized) {\n this.logger.warn('Agent already initialized');\n return;\n }\n\n try {\n this.agentKit = await this.createAgentKit();\n await this.agentKit.initialize();\n\n const modelName =\n this.config.ai?.modelName ||\n process.env.OPENAI_MODEL_NAME ||\n 'gpt-4o-mini';\n this.tokenTracker = new TokenUsageCallbackHandler(modelName);\n\n const allTools = this.agentKit.getAggregatedLangChainTools();\n this.tools = this.filterTools(allTools);\n\n if (this.config.mcp?.servers && this.config.mcp.servers.length > 0) {\n if (this.config.mcp.autoConnect !== false) {\n await this.initializeMCP();\n } else {\n this.logger.info('MCP servers configured but autoConnect=false, skipping synchronous connection');\n // Initialize MCP manager for later async connections\n this.mcpManager = new MCPClientManager(this.logger);\n }\n }\n\n this.smartMemory = new SmartMemoryManager({\n modelName,\n maxTokens: 90000,\n reserveTokens: 10000,\n storageLimit: 1000\n });\n \n this.logger.info('SmartMemoryManager initialized:', {\n modelName,\n toolsCount: this.tools.length,\n maxTokens: 90000,\n reserveTokens: 10000\n });\n\n this.systemMessage = this.buildSystemPrompt();\n \n this.smartMemory.setSystemPrompt(this.systemMessage);\n\n await this.createExecutor();\n\n this.initialized = true;\n this.logger.info('LangChain Hedera agent initialized');\n } catch (error) {\n this.logger.error('Failed to initialize agent:', error);\n throw error;\n }\n }\n\n async chat(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse> {\n if (!this.initialized || !this.executor || !this.smartMemory) {\n throw new Error('Agent not initialized. Call boot() first.');\n }\n\n try {\n this.logger.info('LangChainAgent.chat called with:', { message, contextLength: context?.messages?.length || 0 });\n \n if (context?.messages && context.messages.length > 0) {\n this.smartMemory.clear();\n \n for (const msg of context.messages) {\n this.smartMemory.addMessage(msg);\n }\n }\n \n const { HumanMessage } = await import('@langchain/core/messages');\n this.smartMemory.addMessage(new HumanMessage(message));\n \n const memoryStats = this.smartMemory.getMemoryStats();\n this.logger.info('Memory stats before execution:', {\n totalMessages: memoryStats.totalActiveMessages,\n currentTokens: memoryStats.currentTokenCount,\n maxTokens: memoryStats.maxTokens,\n usagePercentage: memoryStats.usagePercentage,\n toolsCount: this.tools.length\n });\n \n const result = await this.executor.invoke({\n input: message,\n chat_history: this.smartMemory.getMessages(),\n });\n\n this.logger.info('LangChainAgent executor result:', result);\n\n let response: ChatResponse = {\n output: result.output || '',\n message: result.output || '',\n notes: [],\n intermediateSteps: result.intermediateSteps,\n };\n\n if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {\n const toolCalls = result.intermediateSteps.map((step: any, index: number) => ({\n id: `call_${index}`,\n name: step.action?.tool || 'unknown',\n args: step.action?.toolInput || {},\n output: typeof step.observation === 'string' ? step.observation : JSON.stringify(step.observation)\n }));\n \n if (toolCalls.length > 0) {\n response.tool_calls = toolCalls;\n }\n }\n\n const parsedSteps = result?.intermediateSteps?.[0]?.observation;\n if (\n parsedSteps &&\n typeof parsedSteps === 'string' &&\n this.isJSON(parsedSteps)\n ) {\n try {\n const parsed = JSON.parse(parsedSteps);\n response = { ...response, ...parsed };\n } catch (error) {\n this.logger.error('Error parsing intermediate steps:', error);\n }\n }\n\n if (!response.output || response.output.trim() === '') {\n response.output = 'Agent action complete.';\n }\n\n if (response.output) {\n const { AIMessage } = await import('@langchain/core/messages');\n this.smartMemory.addMessage(new AIMessage(response.output));\n }\n\n if (this.tokenTracker) {\n const tokenUsage = this.tokenTracker.getLatestTokenUsage();\n if (tokenUsage) {\n response.tokenUsage = tokenUsage;\n response.cost = calculateTokenCostSync(tokenUsage);\n }\n }\n\n const finalMemoryStats = this.smartMemory.getMemoryStats();\n response.metadata = {\n ...response.metadata,\n memoryStats: {\n activeMessages: finalMemoryStats.totalActiveMessages,\n tokenUsage: finalMemoryStats.currentTokenCount,\n maxTokens: finalMemoryStats.maxTokens,\n usagePercentage: finalMemoryStats.usagePercentage\n }\n };\n\n this.logger.info('LangChainAgent.chat returning response:', response);\n return response;\n } catch (error) {\n this.logger.error('LangChainAgent.chat error:', error);\n return this.handleError(error);\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.mcpManager) {\n await this.mcpManager.disconnectAll();\n }\n\n if (this.smartMemory) {\n this.smartMemory.dispose();\n this.smartMemory = undefined;\n }\n\n this.executor = undefined;\n this.agentKit = undefined;\n this.tools = [];\n this.initialized = false;\n this.logger.info('Agent cleaned up');\n }\n\n switchMode(mode: OperationalMode): void {\n if (this.config.execution) {\n this.config.execution.operationalMode = mode;\n } else {\n this.config.execution = { operationalMode: mode };\n }\n\n if (this.agentKit) {\n this.agentKit.operationalMode = mode;\n }\n\n this.systemMessage = this.buildSystemPrompt();\n this.logger.info(`Operational mode switched to: ${mode}`);\n }\n\n getUsageStats(): UsageStats {\n if (!this.tokenTracker) {\n return {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n cost: { totalCost: 0 } as CostCalculation,\n };\n }\n\n const usage = this.tokenTracker.getTotalTokenUsage();\n const cost = calculateTokenCostSync(usage);\n return { ...usage, cost };\n }\n\n getUsageLog(): UsageStats[] {\n if (!this.tokenTracker) {\n return [];\n }\n\n return this.tokenTracker.getTokenUsageHistory().map((usage) => ({\n ...usage,\n cost: calculateTokenCostSync(usage),\n }));\n }\n\n clearUsageStats(): void {\n if (this.tokenTracker) {\n this.tokenTracker.reset();\n this.logger.info('Usage statistics cleared');\n }\n }\n\n\n private async createAgentKit(): Promise<HederaAgentKit> {\n const corePlugins = getAllHederaCorePlugins();\n const extensionPlugins = this.config.extensions?.plugins || [];\n const plugins = [...corePlugins, ...extensionPlugins];\n\n const operationalMode =\n this.config.execution?.operationalMode || 'returnBytes';\n const modelName = this.config.ai?.modelName || 'gpt-4o';\n\n return new HederaAgentKit(\n this.config.signer,\n { plugins },\n operationalMode,\n this.config.execution?.userAccountId,\n this.config.execution?.scheduleUserTransactionsInBytesMode ?? false,\n undefined,\n modelName,\n this.config.extensions?.mirrorConfig,\n this.config.debug?.silent ?? false\n );\n }\n\n private async createExecutor(): Promise<void> {\n let llm: BaseChatModel;\n if (this.config.ai?.provider && this.config.ai.provider.getModel) {\n llm = this.config.ai.provider.getModel() as BaseChatModel;\n } else if (this.config.ai?.llm) {\n llm = this.config.ai.llm as BaseChatModel;\n } else {\n const apiKey = this.config.ai?.apiKey || process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new Error('OpenAI API key required');\n }\n\n llm = new ChatOpenAI({\n apiKey,\n modelName: this.config.ai?.modelName || 'gpt-4o-mini',\n temperature: this.config.ai?.temperature ?? 0.1,\n callbacks: this.tokenTracker ? [this.tokenTracker] : [],\n });\n }\n\n const prompt = ChatPromptTemplate.fromMessages([\n ['system', this.systemMessage],\n new MessagesPlaceholder('chat_history'),\n ['human', '{input}'],\n new MessagesPlaceholder('agent_scratchpad'),\n ]);\n\n const langchainTools = this.tools as unknown as StructuredTool[];\n\n const agent = await createOpenAIToolsAgent({\n llm,\n tools: langchainTools,\n prompt,\n });\n\n this.executor = new ContentAwareAgentExecutor({\n agent,\n tools: langchainTools,\n verbose: this.config.debug?.verbose ?? false,\n returnIntermediateSteps: true,\n });\n }\n\n private handleError(error: unknown): ChatResponse {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n this.logger.error('Chat error:', error);\n\n let tokenUsage: TokenUsage | undefined;\n let cost: CostCalculation | undefined;\n\n if (this.tokenTracker) {\n tokenUsage = this.tokenTracker.getLatestTokenUsage();\n if (tokenUsage) {\n cost = calculateTokenCostSync(tokenUsage);\n }\n }\n\n let userFriendlyMessage = 'Sorry, I encountered an error processing your request.';\n let userFriendlyOutput = 'Sorry, I encountered an error processing your request.';\n \n if (errorMessage.includes('429')) {\n if (errorMessage.includes('quota')) {\n userFriendlyMessage = 'API quota exceeded. Please check your OpenAI billing and usage limits.';\n userFriendlyOutput = 'I\\'m currently unable to respond because the API quota has been exceeded. Please check your OpenAI account billing and usage limits, then try again.';\n } else {\n userFriendlyMessage = 'Too many requests. Please wait a moment and try again.';\n userFriendlyOutput = 'I\\'m receiving too many requests right now. Please wait a moment and try again.';\n }\n } else if (errorMessage.includes('401') || errorMessage.includes('unauthorized')) {\n userFriendlyMessage = 'API authentication failed. Please check your API key configuration.';\n userFriendlyOutput = 'There\\'s an issue with the API authentication. Please check your OpenAI API key configuration in settings.';\n } else if (errorMessage.includes('timeout')) {\n userFriendlyMessage = 'Request timed out. Please try again.';\n userFriendlyOutput = 'The request took too long to process. Please try again.';\n } else if (errorMessage.includes('network') || errorMessage.includes('fetch')) {\n userFriendlyMessage = 'Network error. Please check your internet connection and try again.';\n userFriendlyOutput = 'There was a network error. Please check your internet connection and try again.';\n }\n\n const errorResponse: ChatResponse = {\n output: userFriendlyOutput,\n message: userFriendlyMessage,\n error: errorMessage,\n notes: [],\n };\n\n if (tokenUsage) {\n errorResponse.tokenUsage = tokenUsage;\n }\n\n if (cost) {\n errorResponse.cost = cost;\n }\n\n return errorResponse;\n }\n\n private async initializeMCP(): Promise<void> {\n this.mcpManager = new MCPClientManager(this.logger);\n\n for (const serverConfig of this.config.mcp!.servers!) {\n if (serverConfig.autoConnect === false) {\n this.logger.info(\n `Skipping MCP server ${serverConfig.name} (autoConnect=false)`\n );\n continue;\n }\n\n const status = await this.mcpManager.connectServer(serverConfig);\n\n if (status.connected) {\n this.logger.info(\n `Connected to MCP server ${status.serverName} with ${status.tools.length} tools`\n );\n\n for (const mcpTool of status.tools) {\n const langchainTool = convertMCPToolToLangChain(\n mcpTool,\n this.mcpManager,\n serverConfig\n );\n this.tools.push(langchainTool);\n }\n } else {\n this.logger.error(\n `Failed to connect to MCP server ${status.serverName}: ${status.error}`\n );\n }\n }\n }\n\n /**\n * Connect to MCP servers asynchronously after agent boot\n */\n async connectMCPServers(): Promise<void> {\n if (!this.config.mcp?.servers || this.config.mcp.servers.length === 0) {\n return;\n }\n\n if (!this.mcpManager) {\n this.logger.warn('MCP manager not initialized. Cannot connect to servers.');\n return;\n }\n\n this.logger.info('Starting async MCP server connections...');\n\n for (const serverConfig of this.config.mcp.servers) {\n // Connect servers asynchronously without blocking\n this.connectServer(serverConfig).catch(error => {\n this.logger.error(`Connection to MCP server ${serverConfig.name} failed:`, error);\n });\n }\n }\n\n /**\n * Connect to a single MCP server\n */\n private async connectServer(serverConfig: any): Promise<void> {\n try {\n this.logger.info(`Connecting to MCP server: ${serverConfig.name}`);\n \n const status = await this.mcpManager!.connectServer(serverConfig);\n \n if (status.connected) {\n this.logger.info(\n `Connected to MCP server ${status.serverName} with ${status.tools.length} tools`\n );\n \n // Add tools to the agent\n for (const mcpTool of status.tools) {\n const langchainTool = convertMCPToolToLangChain(\n mcpTool,\n this.mcpManager!,\n serverConfig\n );\n this.tools.push(langchainTool);\n }\n \n // Recreate executor with new tools if already initialized\n if (this.initialized && this.executor) {\n await this.createExecutor();\n }\n \n } else {\n this.logger.error(\n `Failed to connect to MCP server ${status.serverName}: ${status.error}`\n );\n }\n } catch (error) {\n this.logger.error(`Error connecting to MCP server ${serverConfig.name}:`, error);\n }\n }\n\n /**\n * Check if a string is valid JSON\n */\n private isJSON(str: string): boolean {\n if (typeof str !== 'string') return false;\n\n const trimmed = str.trim();\n if (!trimmed) return false;\n\n if (\n !(trimmed.startsWith('{') && trimmed.endsWith('}')) &&\n !(trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n return false;\n }\n\n try {\n JSON.parse(trimmed);\n return true;\n } catch {\n return false;\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index8.js","sources":["../../src/langchain-agent.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { StructuredTool } from '@langchain/core/tools';\nimport { createOpenAIToolsAgent } from 'langchain/agents';\nimport { ContentAwareAgentExecutor } from './langchain/ContentAwareAgentExecutor';\nimport {\n ChatPromptTemplate,\n MessagesPlaceholder,\n} from '@langchain/core/prompts';\nimport { ChatOpenAI } from '@langchain/openai';\nimport {\n calculateTokenCostSync,\n getAllHederaCorePlugins,\n HederaAgentKit,\n TokenUsageCallbackHandler,\n} from 'hedera-agent-kit';\nimport type { TokenUsage, CostCalculation } from 'hedera-agent-kit';\nimport {\n BaseAgent,\n type ConversationContext,\n type ChatResponse,\n type OperationalMode,\n type UsageStats,\n} from './base-agent';\nimport { MCPClientManager } from './mcp/MCPClientManager';\nimport { convertMCPToolToLangChain } from './mcp/adapters/langchain';\nimport { SmartMemoryManager } from './memory/SmartMemoryManager';\nimport type { MCPConnectionStatus } from './mcp/types';\n\nexport class LangChainAgent extends BaseAgent {\n private executor: ContentAwareAgentExecutor | undefined;\n private systemMessage = '';\n private mcpManager?: MCPClientManager;\n private smartMemory: SmartMemoryManager | undefined;\n private mcpConnectionStatus: Map<string, MCPConnectionStatus> = new Map();\n\n async boot(): Promise<void> {\n if (this.initialized) {\n this.logger.warn('Agent already initialized');\n return;\n }\n\n try {\n this.agentKit = await this.createAgentKit();\n await this.agentKit.initialize();\n\n const modelName =\n this.config.ai?.modelName ||\n process.env.OPENAI_MODEL_NAME ||\n 'gpt-4o-mini';\n this.tokenTracker = new TokenUsageCallbackHandler(modelName);\n\n const allTools = this.agentKit.getAggregatedLangChainTools();\n this.tools = this.filterTools(allTools);\n\n if (this.config.mcp?.servers && this.config.mcp.servers.length > 0) {\n if (this.config.mcp.autoConnect !== false) {\n await this.initializeMCP();\n } else {\n this.logger.info(\n 'MCP servers configured but autoConnect=false, skipping synchronous connection'\n );\n this.mcpManager = new MCPClientManager(this.logger);\n }\n }\n\n this.smartMemory = new SmartMemoryManager({\n modelName,\n maxTokens: 90000,\n reserveTokens: 10000,\n storageLimit: 1000,\n });\n\n this.logger.info('SmartMemoryManager initialized:', {\n modelName,\n toolsCount: this.tools.length,\n maxTokens: 90000,\n reserveTokens: 10000,\n });\n\n this.systemMessage = this.buildSystemPrompt();\n\n this.smartMemory.setSystemPrompt(this.systemMessage);\n\n await this.createExecutor();\n\n this.initialized = true;\n this.logger.info('LangChain Hedera agent initialized');\n } catch (error) {\n this.logger.error('Failed to initialize agent:', error);\n throw error;\n }\n }\n\n async chat(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse> {\n if (!this.initialized || !this.executor || !this.smartMemory) {\n throw new Error('Agent not initialized. Call boot() first.');\n }\n\n try {\n this.logger.info('LangChainAgent.chat called with:', {\n message,\n contextLength: context?.messages?.length || 0,\n });\n\n if (context?.messages && context.messages.length > 0) {\n this.smartMemory.clear();\n\n for (const msg of context.messages) {\n this.smartMemory.addMessage(msg);\n }\n }\n\n const { HumanMessage } = await import('@langchain/core/messages');\n this.smartMemory.addMessage(new HumanMessage(message));\n\n const memoryStats = this.smartMemory.getMemoryStats();\n this.logger.info('Memory stats before execution:', {\n totalMessages: memoryStats.totalActiveMessages,\n currentTokens: memoryStats.currentTokenCount,\n maxTokens: memoryStats.maxTokens,\n usagePercentage: memoryStats.usagePercentage,\n toolsCount: this.tools.length,\n });\n\n const result = await this.executor.invoke({\n input: message,\n chat_history: this.smartMemory.getMessages(),\n });\n\n this.logger.info('LangChainAgent executor result:', result);\n\n let response: ChatResponse = {\n output: result.output || '',\n message: result.output || '',\n notes: [],\n intermediateSteps: result.intermediateSteps,\n };\n\n if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {\n const toolCalls = result.intermediateSteps.map(\n (step: any, index: number) => ({\n id: `call_${index}`,\n name: step.action?.tool || 'unknown',\n args: step.action?.toolInput || {},\n output:\n typeof step.observation === 'string'\n ? step.observation\n : JSON.stringify(step.observation),\n })\n );\n\n if (toolCalls.length > 0) {\n response.tool_calls = toolCalls;\n }\n }\n\n const parsedSteps = result?.intermediateSteps?.[0]?.observation;\n if (\n parsedSteps &&\n typeof parsedSteps === 'string' &&\n this.isJSON(parsedSteps)\n ) {\n try {\n const parsed = JSON.parse(parsedSteps);\n response = { ...response, ...parsed };\n } catch (error) {\n this.logger.error('Error parsing intermediate steps:', error);\n }\n }\n\n if (!response.output || response.output.trim() === '') {\n response.output = 'Agent action complete.';\n }\n\n if (response.output) {\n const { AIMessage } = await import('@langchain/core/messages');\n this.smartMemory.addMessage(new AIMessage(response.output));\n }\n\n if (this.tokenTracker) {\n const tokenUsage = this.tokenTracker.getLatestTokenUsage();\n if (tokenUsage) {\n response.tokenUsage = tokenUsage;\n response.cost = calculateTokenCostSync(tokenUsage);\n }\n }\n\n const finalMemoryStats = this.smartMemory.getMemoryStats();\n response.metadata = {\n ...response.metadata,\n memoryStats: {\n activeMessages: finalMemoryStats.totalActiveMessages,\n tokenUsage: finalMemoryStats.currentTokenCount,\n maxTokens: finalMemoryStats.maxTokens,\n usagePercentage: finalMemoryStats.usagePercentage,\n },\n };\n\n this.logger.info('LangChainAgent.chat returning response:', response);\n return response;\n } catch (error) {\n this.logger.error('LangChainAgent.chat error:', error);\n return this.handleError(error);\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.mcpManager) {\n await this.mcpManager.disconnectAll();\n }\n\n if (this.smartMemory) {\n this.smartMemory.dispose();\n this.smartMemory = undefined;\n }\n\n this.executor = undefined;\n this.agentKit = undefined;\n this.tools = [];\n this.initialized = false;\n this.logger.info('Agent cleaned up');\n }\n\n switchMode(mode: OperationalMode): void {\n if (this.config.execution) {\n this.config.execution.operationalMode = mode;\n } else {\n this.config.execution = { operationalMode: mode };\n }\n\n if (this.agentKit) {\n this.agentKit.operationalMode = mode;\n }\n\n this.systemMessage = this.buildSystemPrompt();\n this.logger.info(`Operational mode switched to: ${mode}`);\n }\n\n getUsageStats(): UsageStats {\n if (!this.tokenTracker) {\n return {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n cost: { totalCost: 0 } as CostCalculation,\n };\n }\n\n const usage = this.tokenTracker.getTotalTokenUsage();\n const cost = calculateTokenCostSync(usage);\n return { ...usage, cost };\n }\n\n getUsageLog(): UsageStats[] {\n if (!this.tokenTracker) {\n return [];\n }\n\n return this.tokenTracker.getTokenUsageHistory().map((usage) => ({\n ...usage,\n cost: calculateTokenCostSync(usage),\n }));\n }\n\n clearUsageStats(): void {\n if (this.tokenTracker) {\n this.tokenTracker.reset();\n this.logger.info('Usage statistics cleared');\n }\n }\n\n getMCPConnectionStatus(): Map<string, MCPConnectionStatus> {\n return new Map(this.mcpConnectionStatus);\n }\n\n private async createAgentKit(): Promise<HederaAgentKit> {\n const corePlugins = getAllHederaCorePlugins();\n const extensionPlugins = this.config.extensions?.plugins || [];\n const plugins = [...corePlugins, ...extensionPlugins];\n\n const operationalMode =\n this.config.execution?.operationalMode || 'returnBytes';\n const modelName = this.config.ai?.modelName || 'gpt-4o';\n\n return new HederaAgentKit(\n this.config.signer,\n { plugins },\n operationalMode,\n this.config.execution?.userAccountId,\n this.config.execution?.scheduleUserTransactionsInBytesMode ?? false,\n undefined,\n modelName,\n this.config.extensions?.mirrorConfig,\n this.config.debug?.silent ?? false\n );\n }\n\n private async createExecutor(): Promise<void> {\n let llm: BaseChatModel;\n if (this.config.ai?.provider && this.config.ai.provider.getModel) {\n llm = this.config.ai.provider.getModel() as BaseChatModel;\n } else if (this.config.ai?.llm) {\n llm = this.config.ai.llm as BaseChatModel;\n } else {\n const apiKey = this.config.ai?.apiKey || process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new Error('OpenAI API key required');\n }\n\n const modelName = this.config.ai?.modelName || 'gpt-4o-mini';\n const isGPT5Model =\n modelName.toLowerCase().includes('gpt-5') ||\n modelName.toLowerCase().includes('gpt5');\n\n llm = new ChatOpenAI({\n apiKey,\n modelName,\n callbacks: this.tokenTracker ? [this.tokenTracker] : [],\n ...(isGPT5Model ? { temperature: 1 } : {}),\n });\n }\n\n const prompt = ChatPromptTemplate.fromMessages([\n ['system', this.systemMessage],\n new MessagesPlaceholder('chat_history'),\n ['human', '{input}'],\n new MessagesPlaceholder('agent_scratchpad'),\n ]);\n\n const langchainTools = this.tools as unknown as StructuredTool[];\n\n const agent = await createOpenAIToolsAgent({\n llm,\n tools: langchainTools,\n prompt,\n });\n\n this.executor = new ContentAwareAgentExecutor({\n agent,\n tools: langchainTools,\n verbose: this.config.debug?.verbose ?? false,\n returnIntermediateSteps: true,\n });\n }\n\n private handleError(error: unknown): ChatResponse {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n this.logger.error('Chat error:', error);\n\n let tokenUsage: TokenUsage | undefined;\n let cost: CostCalculation | undefined;\n\n if (this.tokenTracker) {\n tokenUsage = this.tokenTracker.getLatestTokenUsage();\n if (tokenUsage) {\n cost = calculateTokenCostSync(tokenUsage);\n }\n }\n\n let userFriendlyMessage = errorMessage;\n let userFriendlyOutput = errorMessage;\n\n if (errorMessage.includes('429')) {\n if (errorMessage.includes('quota')) {\n userFriendlyMessage =\n 'API quota exceeded. Please check your OpenAI billing and usage limits.';\n userFriendlyOutput =\n \"I'm currently unable to respond because the API quota has been exceeded. Please check your OpenAI account billing and usage limits, then try again.\";\n } else {\n userFriendlyMessage =\n 'Too many requests. Please wait a moment and try again.';\n userFriendlyOutput =\n \"I'm receiving too many requests right now. Please wait a moment and try again.\";\n }\n } else if (\n errorMessage.includes('401') ||\n errorMessage.includes('unauthorized')\n ) {\n userFriendlyMessage =\n 'API authentication failed. Please check your API key configuration.';\n userFriendlyOutput =\n \"There's an issue with the API authentication. Please check your OpenAI API key configuration in settings.\";\n } else if (errorMessage.includes('timeout')) {\n userFriendlyMessage = 'Request timed out. Please try again.';\n userFriendlyOutput =\n 'The request took too long to process. Please try again.';\n } else if (\n errorMessage.includes('network') ||\n errorMessage.includes('fetch')\n ) {\n userFriendlyMessage =\n 'Network error. Please check your internet connection and try again.';\n userFriendlyOutput =\n 'There was a network error. Please check your internet connection and try again.';\n } else if (errorMessage.includes('400')) {\n userFriendlyMessage = errorMessage;\n userFriendlyOutput = errorMessage;\n }\n\n const errorResponse: ChatResponse = {\n output: userFriendlyOutput,\n message: userFriendlyMessage,\n error: errorMessage,\n notes: [],\n };\n\n if (tokenUsage) {\n errorResponse.tokenUsage = tokenUsage;\n }\n\n if (cost) {\n errorResponse.cost = cost;\n }\n\n return errorResponse;\n }\n\n private async initializeMCP(): Promise<void> {\n this.mcpManager = new MCPClientManager(this.logger);\n\n for (const serverConfig of this.config.mcp!.servers!) {\n if (serverConfig.autoConnect === false) {\n this.logger.info(\n `Skipping MCP server ${serverConfig.name} (autoConnect=false)`\n );\n continue;\n }\n\n const status = await this.mcpManager.connectServer(serverConfig);\n\n if (status.connected) {\n this.logger.info(\n `Connected to MCP server ${status.serverName} with ${status.tools.length} tools`\n );\n\n for (const mcpTool of status.tools) {\n const langchainTool = convertMCPToolToLangChain(\n mcpTool,\n this.mcpManager,\n serverConfig\n );\n this.tools.push(langchainTool);\n }\n } else {\n this.logger.error(\n `Failed to connect to MCP server ${status.serverName}: ${status.error}`\n );\n }\n }\n }\n\n /**\n * Connect to MCP servers asynchronously after agent boot with background timeout pattern\n */\n async connectMCPServers(): Promise<void> {\n if (!this.config.mcp?.servers || this.config.mcp.servers.length === 0) {\n return;\n }\n\n if (!this.mcpManager) {\n this.mcpManager = new MCPClientManager(this.logger);\n }\n\n this.logger.info(\n `Starting background MCP server connections for ${this.config.mcp.servers.length} servers...`\n );\n\n this.config.mcp.servers.forEach((serverConfig) => {\n this.connectServerInBackground(serverConfig);\n });\n\n this.logger.info('MCP server connections initiated in background');\n }\n\n /**\n * Connect to a single MCP server in background with timeout\n */\n private connectServerInBackground(serverConfig: any): void {\n const serverName = serverConfig.name;\n\n setTimeout(async () => {\n try {\n this.logger.info(`Background connecting to MCP server: ${serverName}`);\n\n const status = await this.mcpManager!.connectServer(serverConfig);\n this.mcpConnectionStatus.set(serverName, status);\n\n if (status.connected) {\n this.logger.info(\n `Successfully connected to MCP server ${status.serverName} with ${status.tools.length} tools`\n );\n\n for (const mcpTool of status.tools) {\n const langchainTool = convertMCPToolToLangChain(\n mcpTool,\n this.mcpManager!,\n serverConfig\n );\n this.tools.push(langchainTool);\n }\n\n if (this.initialized && this.executor) {\n this.logger.info(\n `Recreating executor with ${this.tools.length} total tools`\n );\n await this.createExecutor();\n }\n } else {\n this.logger.error(\n `Failed to connect to MCP server ${status.serverName}: ${status.error}`\n );\n }\n } catch (error) {\n this.logger.error(\n `Background connection failed for MCP server ${serverName}:`,\n error\n );\n\n this.mcpConnectionStatus.set(serverName, {\n connected: false,\n serverName,\n tools: [],\n error: error instanceof Error ? error.message : 'Connection failed',\n });\n }\n }, 1000);\n }\n\n /**\n * Check if a string is valid JSON\n */\n private isJSON(str: string): boolean {\n if (typeof str !== 'string') return false;\n\n const trimmed = str.trim();\n if (!trimmed) return false;\n\n if (\n !(trimmed.startsWith('{') && trimmed.endsWith('}')) &&\n !(trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n return false;\n }\n\n try {\n JSON.parse(trimmed);\n return true;\n } catch {\n return false;\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { TransactionReceipt } from '@hashgraph/sdk';
4
4
  import { HederaAgentKit, ServerSigner, TokenUsageCallbackHandler, TokenUsage, BasePlugin, CostCalculation } from 'hedera-agent-kit';
5
5
  import { AIProvider, VercelAIProvider, BAMLProvider } from './providers';
6
6
  import { Logger } from '@hashgraphonline/standards-sdk';
7
- import { MCPServerConfig } from './mcp/types';
7
+ import { MCPServerConfig, MCPConnectionStatus } from './mcp/types';
8
8
 
9
9
  export interface ToolFilterConfig {
10
10
  namespaceWhitelist?: string[];
@@ -93,6 +93,8 @@ export declare abstract class BaseAgent {
93
93
  abstract getUsageStats(): UsageStats;
94
94
  abstract getUsageLog(): UsageStats[];
95
95
  abstract clearUsageStats(): void;
96
+ abstract connectMCPServers(): Promise<void>;
97
+ abstract getMCPConnectionStatus(): Map<string, MCPConnectionStatus>;
96
98
  getCore(): HederaAgentKit | undefined;
97
99
  protected filterTools(tools: StructuredTool[]): StructuredTool[];
98
100
  protected buildSystemPrompt(): string;