@hashgraphonline/conversational-agent 0.1.214 → 0.1.217
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/dist/CLIApp.d.ts +9 -0
- package/cli/dist/CLIApp.js +127 -0
- package/cli/dist/LocalConversationalAgent.d.ts +37 -0
- package/cli/dist/LocalConversationalAgent.js +58 -0
- package/cli/dist/app.d.ts +16 -0
- package/cli/dist/app.js +13 -0
- package/cli/dist/cli.d.ts +2 -0
- package/cli/dist/cli.js +51 -0
- package/cli/dist/components/AppContainer.d.ts +16 -0
- package/cli/dist/components/AppContainer.js +24 -0
- package/cli/dist/components/AppScreens.d.ts +2 -0
- package/cli/dist/components/AppScreens.js +259 -0
- package/cli/dist/components/ChatScreen.d.ts +15 -0
- package/cli/dist/components/ChatScreen.js +39 -0
- package/cli/dist/components/DebugLoadingScreen.d.ts +5 -0
- package/cli/dist/components/DebugLoadingScreen.js +31 -0
- package/cli/dist/components/LoadingScreen.d.ts +2 -0
- package/cli/dist/components/LoadingScreen.js +16 -0
- package/cli/dist/components/LoadingScreenDebug.d.ts +5 -0
- package/cli/dist/components/LoadingScreenDebug.js +27 -0
- package/cli/dist/components/MCPConfigScreen.d.ts +28 -0
- package/cli/dist/components/MCPConfigScreen.js +168 -0
- package/cli/dist/components/ScreenRouter.d.ts +12 -0
- package/cli/dist/components/ScreenRouter.js +22 -0
- package/cli/dist/components/SetupScreen.d.ts +15 -0
- package/cli/dist/components/SetupScreen.js +65 -0
- package/cli/dist/components/SingleLoadingScreen.d.ts +5 -0
- package/cli/dist/components/SingleLoadingScreen.js +27 -0
- package/cli/dist/components/StatusBadge.d.ts +7 -0
- package/cli/dist/components/StatusBadge.js +28 -0
- package/cli/dist/components/TerminalWindow.d.ts +8 -0
- package/cli/dist/components/TerminalWindow.js +24 -0
- package/cli/dist/components/WelcomeScreen.d.ts +11 -0
- package/cli/dist/components/WelcomeScreen.js +47 -0
- package/cli/dist/context/AppContext.d.ts +68 -0
- package/cli/dist/context/AppContext.js +363 -0
- package/cli/dist/hooks/useInitializeAgent.d.ts +19 -0
- package/cli/dist/hooks/useInitializeAgent.js +28 -0
- package/cli/dist/hooks/useStableState.d.ts +38 -0
- package/cli/dist/hooks/useStableState.js +68 -0
- package/cli/dist/managers/AgentManager.d.ts +57 -0
- package/cli/dist/managers/AgentManager.js +119 -0
- package/cli/dist/managers/ConfigManager.d.ts +53 -0
- package/cli/dist/managers/ConfigManager.js +173 -0
- package/cli/dist/types.d.ts +31 -0
- package/cli/dist/types.js +19 -0
- package/dist/cjs/base-agent.d.ts +2 -0
- package/dist/cjs/conversational-agent.d.ts +8 -0
- package/dist/cjs/core/ToolRegistry.d.ts +130 -0
- package/dist/cjs/execution/ExecutionPipeline.d.ts +81 -0
- package/dist/cjs/forms/FormEngine.d.ts +121 -0
- package/dist/cjs/forms/field-type-registry.d.ts +51 -0
- package/dist/cjs/forms/form-generator.d.ts +123 -0
- package/dist/cjs/forms/index.d.ts +2 -0
- package/dist/cjs/forms/types.d.ts +108 -0
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/langchain/FormAwareAgentExecutor.d.ts +108 -0
- package/dist/cjs/langchain/FormValidatingToolWrapper.d.ts +81 -0
- package/dist/cjs/langchain-agent.d.ts +65 -0
- package/dist/cjs/memory/ContentStorage.d.ts +7 -0
- package/dist/cjs/memory/SmartMemoryManager.d.ts +1 -0
- package/dist/cjs/services/ContentStoreManager.d.ts +11 -1
- package/dist/cjs/utils/ResponseFormatter.d.ts +26 -0
- package/dist/esm/index.js +8 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index12.js +1 -1
- package/dist/esm/index12.js.map +1 -1
- package/dist/esm/index14.js +23 -5
- package/dist/esm/index14.js.map +1 -1
- package/dist/esm/index15.js +25 -4
- package/dist/esm/index15.js.map +1 -1
- package/dist/esm/index16.js +4 -2
- package/dist/esm/index16.js.map +1 -1
- package/dist/esm/index17.js +2 -7
- package/dist/esm/index17.js.map +1 -1
- package/dist/esm/index18.js +609 -36
- package/dist/esm/index18.js.map +1 -1
- package/dist/esm/index19.js +229 -84
- package/dist/esm/index19.js.map +1 -1
- package/dist/esm/index20.js +111 -17
- package/dist/esm/index20.js.map +1 -1
- package/dist/esm/index21.js +44 -7
- package/dist/esm/index21.js.map +1 -1
- package/dist/esm/index22.js +86 -157
- package/dist/esm/index22.js.map +1 -1
- package/dist/esm/index23.js +32 -150
- package/dist/esm/index23.js.map +1 -1
- package/dist/esm/index24.js +746 -80
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index25.js +154 -45
- package/dist/esm/index25.js.map +1 -1
- package/dist/esm/index26.js +149 -24
- package/dist/esm/index26.js.map +1 -1
- package/dist/esm/index27.js +196 -217
- package/dist/esm/index27.js.map +1 -1
- package/dist/esm/index28.js +187 -0
- package/dist/esm/index28.js.map +1 -0
- package/dist/esm/index29.js +308 -0
- package/dist/esm/index29.js.map +1 -0
- package/dist/esm/index30.js +159 -0
- package/dist/esm/index30.js.map +1 -0
- package/dist/esm/index31.js +68 -0
- package/dist/esm/index31.js.map +1 -0
- package/dist/esm/index32.js +30 -0
- package/dist/esm/index32.js.map +1 -0
- package/dist/esm/index33.js +95 -0
- package/dist/esm/index33.js.map +1 -0
- package/dist/esm/index34.js +245 -0
- package/dist/esm/index34.js.map +1 -0
- package/dist/esm/index5.js +2 -2
- package/dist/esm/index5.js.map +1 -1
- package/dist/esm/index6.js +68 -25
- package/dist/esm/index6.js.map +1 -1
- package/dist/esm/index7.js.map +1 -1
- package/dist/esm/index8.js +744 -70
- package/dist/esm/index8.js.map +1 -1
- package/dist/types/base-agent.d.ts +2 -0
- package/dist/types/conversational-agent.d.ts +8 -0
- package/dist/types/core/ToolRegistry.d.ts +130 -0
- package/dist/types/execution/ExecutionPipeline.d.ts +81 -0
- package/dist/types/forms/FormEngine.d.ts +121 -0
- package/dist/types/forms/field-type-registry.d.ts +51 -0
- package/dist/types/forms/form-generator.d.ts +123 -0
- package/dist/types/forms/index.d.ts +2 -0
- package/dist/types/forms/types.d.ts +108 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/langchain/FormAwareAgentExecutor.d.ts +108 -0
- package/dist/types/langchain/FormValidatingToolWrapper.d.ts +81 -0
- package/dist/types/langchain-agent.d.ts +65 -0
- package/dist/types/memory/ContentStorage.d.ts +7 -0
- package/dist/types/memory/SmartMemoryManager.d.ts +1 -0
- package/dist/types/services/ContentStoreManager.d.ts +11 -1
- package/dist/types/utils/ResponseFormatter.d.ts +26 -0
- package/package.json +35 -34
- package/src/base-agent.ts +2 -0
- package/src/config/system-message.ts +14 -0
- package/src/context/ReferenceContextManager.ts +1 -1
- package/src/conversational-agent.ts +95 -38
- package/src/core/ToolRegistry.ts +358 -0
- package/src/execution/ExecutionPipeline.ts +301 -0
- package/src/forms/FormEngine.ts +443 -0
- package/src/forms/field-type-registry.ts +203 -0
- package/src/forms/form-generator.ts +841 -0
- package/src/forms/index.ts +2 -0
- package/src/forms/types.ts +125 -0
- package/src/index.ts +9 -0
- package/src/langchain/FormAwareAgentExecutor.ts +971 -0
- package/src/langchain/FormValidatingToolWrapper.ts +355 -0
- package/src/langchain-agent.ts +1034 -87
- package/src/mcp/ContentProcessor.ts +20 -4
- package/src/mcp/MCPClientManager.ts +1 -1
- package/src/mcp/adapters/langchain.ts +1 -1
- package/src/memory/ContentStorage.ts +25 -5
- package/src/memory/SmartMemoryManager.ts +27 -4
- package/src/memory/TokenCounter.ts +1 -1
- package/src/plugins/hbar/HbarPlugin.ts +0 -1
- package/src/scripts/test-external-tool-wrapper.ts +103 -0
- package/src/scripts/test-hedera-kit-wrapper.ts +265 -0
- package/src/scripts/test-inscribe-form-generation.ts +494 -0
- package/src/scripts/test-inscribe-wrapper-verification.ts +220 -0
- package/src/services/ContentStoreManager.ts +23 -9
- package/src/services/EntityResolver.ts +2 -9
- package/src/tools/EntityResolverTool.ts +5 -8
- package/src/utils/ResponseFormatter.ts +146 -0
- package/cli/readme.md +0 -181
- package/dist/cjs/langchain/ContentAwareAgentExecutor.d.ts +0 -14
- package/dist/types/langchain/ContentAwareAgentExecutor.d.ts +0 -14
- package/src/langchain/ContentAwareAgentExecutor.ts +0 -19
package/dist/esm/index8.js.map
CHANGED
|
@@ -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';\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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"}
|
|
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 { FormAwareAgentExecutor } from './langchain/FormAwareAgentExecutor';\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, MCPServerConfig } from './mcp/types';\nimport { ResponseFormatter } from './utils/ResponseFormatter';\nimport type { FormSubmission } from './forms/types';\nimport type { ToolRegistrationOptions } from './core/ToolRegistry';\nimport { HumanMessage, AIMessage } from '@langchain/core/messages';\nimport { ToolRegistry } from './core/ToolRegistry';\nimport {\n ExecutionPipeline,\n SessionContext,\n} from './execution/ExecutionPipeline';\nimport { FormEngine } from './forms/FormEngine';\nimport type { ChainValues } from '@langchain/core/utils/types';\n\ninterface RenderConfigSchema {\n _renderConfig?: Record<string, unknown>;\n}\n\ninterface ToolExecutionData {\n type: string;\n formId?: string;\n parameters?: Record<string, unknown>;\n}\n\ninterface IntermediateStep {\n action?: {\n tool?: string;\n toolInput?: Record<string, unknown>;\n };\n observation?: unknown;\n}\ninterface RenderConfigSchema {\n _renderConfig?: Record<string, unknown>;\n}\n\ninterface ToolExecutionData {\n type: string;\n formId?: string;\n parameters?: Record<string, unknown>;\n}\n\ninterface IntermediateStep {\n action?: {\n tool?: string;\n toolInput?: Record<string, unknown>;\n };\n observation?: unknown;\n}\n\nexport class LangChainAgent extends BaseAgent {\n private executor: FormAwareAgentExecutor | undefined;\n private systemMessage = '';\n private mcpManager?: MCPClientManager;\n private smartMemory: SmartMemoryManager | undefined;\n private mcpConnectionStatus: Map<string, MCPConnectionStatus> = new Map();\n private toolRegistry!: ToolRegistry;\n private executionPipeline!: ExecutionPipeline;\n private formEngine!: FormEngine;\n\n /**\n * Get inscription tool by capability instead of hardcoded name\n */\n private getInscriptionTool(): StructuredTool | null {\n const criticalTools = this.toolRegistry.getToolsByCapability(\n 'priority',\n 'critical'\n );\n\n for (const entry of criticalTools) {\n const tool = entry.tool;\n const name = tool.name.toLowerCase();\n const desc = tool.description?.toLowerCase() || '';\n\n if (\n name.includes('inscribe') ||\n name.includes('hashinal') ||\n desc.includes('inscribe') ||\n desc.includes('hashinal')\n ) {\n return tool;\n }\n }\n\n const allTools = this.toolRegistry.getAllRegistryEntries();\n for (const entry of allTools) {\n const tool = entry.tool;\n const name = tool.name.toLowerCase();\n const desc = tool.description?.toLowerCase() || '';\n\n if (\n name.includes('inscribe') ||\n name.includes('hashinal') ||\n desc.includes('inscribe') ||\n desc.includes('hashinal')\n ) {\n return tool;\n }\n }\n\n return null;\n }\n\n /**\n * Get a tool by name from the registry with type safety\n */\n private getTool(name: string): StructuredTool | null {\n const entry = this.toolRegistry.getTool(name);\n return entry ? entry.tool : null;\n }\n\n /**\n * Execute a tool directly with parameters, optionally using ExecutionPipeline\n */\n private async executeToolDirect(\n toolName: string,\n parameters: Record<string, unknown>,\n useExecutionPipeline = false\n ): Promise<string> {\n if (useExecutionPipeline && this.executionPipeline && this.smartMemory) {\n const sessionContext: SessionContext = {\n sessionId: `session-${Date.now()}`,\n timestamp: Date.now(),\n };\n\n const result = await this.executionPipeline.execute(\n toolName,\n parameters,\n sessionContext\n );\n\n if (!result.success) {\n throw new Error(result.error || 'Pipeline execution failed');\n }\n\n return result.output;\n }\n\n const entry = this.toolRegistry.getTool(toolName);\n if (!entry) {\n throw new Error(`Tool not found: ${toolName}`);\n }\n\n const mergedArgs = { ...parameters, renderForm: false };\n\n if (entry.wrapper) {\n const maybeWrapper = entry.tool as unknown as {\n originalTool?: {\n call?: (a: Record<string, unknown>) => Promise<string>;\n };\n };\n if (maybeWrapper.originalTool?.call) {\n return await maybeWrapper.originalTool.call(mergedArgs);\n }\n }\n\n return await entry.tool.call(mergedArgs);\n }\n\n /**\n * Create a standard ChatResponse from tool output\n */\n private createToolResponse(toolOutput: string): ChatResponse {\n return {\n output: toolOutput,\n message: toolOutput,\n notes: [],\n };\n }\n\n /**\n * Handle TOOL_EXECUTION format messages\n */\n private async handleToolExecution(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse | null> {\n let isToolExecution = false;\n let toolExecutionData: ToolExecutionData | null = null;\n\n try {\n if (message.includes('TOOL_EXECUTION')) {\n const parsed = JSON.parse(message);\n if (parsed.type === 'TOOL_EXECUTION') {\n isToolExecution = true;\n toolExecutionData = parsed;\n }\n }\n } catch {}\n\n if (!isToolExecution || !toolExecutionData?.formId) {\n return null;\n }\n\n try {\n const params = (toolExecutionData.parameters || {}) as Record<\n string,\n unknown\n >;\n const toolName = (toolExecutionData as unknown as { toolName?: string })\n .toolName;\n\n if (toolName) {\n const toolOutput = await this.executeToolDirect(toolName, params);\n return this.createToolResponse(toolOutput);\n }\n } catch {}\n\n const formSubmission: FormSubmission = {\n formId: toolExecutionData.formId,\n toolName:\n (toolExecutionData as unknown as { toolName?: string }).toolName || '',\n parameters: toolExecutionData.parameters || {},\n timestamp: Date.now(),\n };\n\n if (\n this.executor &&\n 'processFormSubmission' in this.executor &&\n typeof this.executor.processFormSubmission === 'function'\n ) {\n return this.processFormSubmission(formSubmission, context);\n }\n\n return null;\n }\n\n /**\n * Handle direct tool execution commands\n */\n private async handleDirectToolExecution(\n message: string\n ): Promise<ChatResponse | null> {\n if (\n typeof message !== 'string' ||\n !message.includes('Please execute the following tool:')\n ) {\n return null;\n }\n\n try {\n const toolLineMatch = message.match(/Tool:\\s*(.+)/);\n const argsLineIndex = message.indexOf('Arguments:');\n\n if (toolLineMatch && argsLineIndex !== -1) {\n const toolName = toolLineMatch[1].trim();\n const argsText = message\n .slice(argsLineIndex + 'Arguments:'.length)\n .trim();\n\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(argsText);\n } catch {}\n\n const toolOutput = await this.executeToolDirect(toolName, args);\n return this.createToolResponse(toolOutput);\n }\n } catch {}\n\n return null;\n }\n\n /**\n * Handle JSON format tool calls and form submissions\n */\n private async handleJsonToolCalls(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse | null> {\n if (typeof message !== 'string') {\n return null;\n }\n\n try {\n const trimmed = message.trim();\n if (\n !(trimmed.startsWith('{') && trimmed.endsWith('}')) &&\n !(trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n return null;\n }\n\n const obj = JSON.parse(trimmed) as Record<string, unknown>;\n const formId = obj['formId'] as string | undefined;\n const toolName = (obj['toolName'] as string) || '';\n const parameters = (obj['parameters'] as Record<string, unknown>) || {};\n\n if (\n formId &&\n this.executor &&\n 'processFormSubmission' in this.executor &&\n typeof this.executor.processFormSubmission === 'function'\n ) {\n return this.processFormSubmission(\n { formId, toolName, parameters, timestamp: Date.now() },\n context\n );\n }\n\n if (toolName) {\n const toolOutput = await this.executeToolDirect(toolName, parameters);\n return this.createToolResponse(toolOutput);\n }\n } catch {}\n\n return null;\n }\n\n /**\n * Handle content-ref messages for inscription tools\n */\n private async handleContentRefMessages(\n message: string\n ): Promise<ChatResponse | null> {\n if (typeof message !== 'string' || !message.includes('content-ref:')) {\n return null;\n }\n\n try {\n const tool = this.getInscriptionTool();\n if (!tool) {\n return null;\n }\n\n const idMatch =\n message.match(/content-ref:([A-Za-z0-9_\\-]+)/i) ||\n message.match(/content-ref:([^\\s)]+)/i);\n const contentRef =\n idMatch && idMatch[1]\n ? `content-ref:${idMatch[1]}`\n : message.match(/content-ref:[^\\s)]+/i)?.[0] || undefined;\n\n const args = contentRef\n ? ({ contentRef, renderForm: true, withHashLinkBlocks: true } as Record<string, unknown>)\n : ({ renderForm: true, withHashLinkBlocks: true } as Record<string, unknown>);\n\n const toolOutput = await tool.call(args);\n let parsed: Record<string, unknown> | undefined;\n\n try {\n parsed =\n typeof toolOutput === 'string'\n ? (JSON.parse(toolOutput) as Record<string, unknown>)\n : (toolOutput as unknown as Record<string, unknown>);\n } catch {}\n\n if (parsed && parsed['requiresForm'] && parsed['formMessage']) {\n const pending = new Map<\n string,\n {\n toolName: string;\n originalInput: Record<string, unknown>;\n originalToolInput?: Record<string, unknown>;\n schema: unknown;\n }\n >();\n\n const originalInput = {\n input: message,\n chat_history: this.smartMemory!.getMessages(),\n } as Record<string, unknown>;\n\n const formMessage = parsed['formMessage'] as { id: string };\n pending.set(formMessage.id, {\n toolName: tool.name,\n originalInput,\n originalToolInput: args,\n schema: null,\n });\n\n const maybeRestore = this.executor as unknown as {\n restorePendingForms?: (p: Map<string, unknown>) => void;\n };\n\n if (typeof maybeRestore.restorePendingForms === 'function') {\n (\n maybeRestore.restorePendingForms as unknown as (\n p: Map<string, unknown>\n ) => void\n )(pending as unknown as Map<string, unknown>);\n }\n\n const outputMsg =\n (parsed['message'] as string) ||\n 'Please complete the form to continue.';\n\n return {\n output: outputMsg,\n message: outputMsg,\n notes: [],\n requiresForm: true,\n formMessage: formMessage as unknown as ChatResponse['formMessage'],\n } as ChatResponse;\n }\n } catch {}\n\n return null;\n }\n\n /**\n * Process executor result and format response\n */\n private async processExecutorResult(\n result: ChainValues\n ): Promise<ChatResponse> {\n let outputStr = '';\n if (typeof result.output === 'string') {\n outputStr = result.output;\n } else if (result.output) {\n try {\n outputStr = JSON.stringify(result.output);\n } catch {\n outputStr = String(result.output);\n }\n }\n\n let response: ChatResponse = {\n output: outputStr,\n message: outputStr,\n notes: [],\n intermediateSteps: result.intermediateSteps,\n };\n\n if (result.requiresForm && result.formMessage) {\n response.formMessage = result.formMessage;\n response.requiresForm = true;\n }\n\n if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {\n const toolCalls = result.intermediateSteps.map(\n (step: IntermediateStep, 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\n if (ResponseFormatter.isInscriptionResponse(parsed)) {\n const formattedMessage =\n ResponseFormatter.formatInscriptionResponse(parsed);\n response.output = formattedMessage;\n response.message = formattedMessage;\n\n if (parsed.inscription) {\n response.inscription = parsed.inscription;\n }\n if (parsed.metadata) {\n response.metadata = {\n ...response.metadata,\n ...parsed.metadata,\n };\n }\n } else {\n response = { ...response, ...parsed };\n }\n\n const blockMetadata = this.processHashLinkBlocks(parsed);\n if (blockMetadata.hashLinkBlock) {\n response.metadata = {\n ...response.metadata,\n ...blockMetadata,\n };\n }\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 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 }\n\n /**\n * Normalize context messages into LangChain message instances and load into memory\n */\n private loadContextMessages(context?: ConversationContext): void {\n if (!this.smartMemory) {\n return;\n }\n if (!context?.messages || context.messages.length === 0) {\n return;\n }\n this.smartMemory.clear();\n const rawMessages = context.messages as unknown[];\n for (const msg of rawMessages) {\n if (msg instanceof HumanMessage || msg instanceof AIMessage) {\n this.smartMemory.addMessage(msg);\n continue;\n }\n if (\n msg &&\n typeof msg === 'object' &&\n 'content' in (msg as Record<string, unknown>) &&\n 'type' in (msg as Record<string, unknown>)\n ) {\n const content = String((msg as { content: unknown }).content);\n const type = String((msg as { type: unknown }).type);\n if (type === 'human') {\n this.smartMemory.addMessage(new HumanMessage(content));\n } else {\n this.smartMemory.addMessage(new AIMessage(content));\n }\n }\n }\n }\n\n async boot(): Promise<void> {\n this.logger.info('🚨🚨🚨 LANGCHAIN AGENT BOOT METHOD CALLED 🚨🚨🚨');\n\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 this.toolRegistry = new ToolRegistry(this.logger);\n\n const allTools = this.agentKit.getAggregatedLangChainTools();\n this.logger.info('=== TOOL REGISTRATION START ===');\n this.logger.info(\n 'All tools from agentKit:',\n allTools.map((t) => t.name)\n );\n\n const filteredTools = this.filterTools(allTools);\n this.logger.info(\n 'Filtered tools for registration:',\n filteredTools.map((t) => t.name)\n );\n\n for (const tool of filteredTools) {\n this.logger.info(`🔧 Registering tool: ${tool.name}`);\n\n const options: ToolRegistrationOptions = {};\n\n const name = tool.name.toLowerCase();\n const desc = tool.description?.toLowerCase() || '';\n\n if (\n name.includes('inscribe') ||\n name.includes('hashinal') ||\n desc.includes('inscribe') ||\n desc.includes('hashinal')\n ) {\n options.forceWrapper = true;\n options.metadata = {\n category: 'core' as const,\n version: '1.0.0',\n dependencies: [],\n };\n\n this.logger.info(`🎯 CRITICAL TOOL DEBUG - ${tool.name} schema:`, {\n hasSchema: !!tool.schema,\n schemaType: tool.schema?.constructor?.name,\n hasRenderConfig: !!(tool.schema as RenderConfigSchema)\n ?._renderConfig,\n renderConfig: (tool.schema as RenderConfigSchema)?._renderConfig,\n });\n }\n\n this.toolRegistry.registerTool(tool, options);\n }\n\n this.tools = this.toolRegistry.getAllTools();\n\n this.logger.info(`🚀 TOOLS REGISTERED: ${this.tools.length} tools`);\n\n const stats = this.toolRegistry.getStatistics();\n this.logger.info('📊 Tool Registry Statistics:', {\n total: stats.totalTools,\n wrapped: stats.wrappedTools,\n unwrapped: stats.unwrappedTools,\n categories: stats.categoryCounts,\n priorities: stats.priorityCounts,\n });\n\n const inscriptionTool = this.getInscriptionTool();\n if (inscriptionTool) {\n const entry = this.toolRegistry.getTool(inscriptionTool.name);\n if (entry) {\n this.logger.info(\n `🔒 FINAL SECURITY CHECK - ${inscriptionTool.name} tool type: ${entry.tool.constructor.name}`\n );\n if (entry.tool.constructor.name !== 'FormValidatingToolWrapper') {\n this.logger.error(\n `🚨 SECURITY BREACH: ${inscriptionTool.name} tool is NOT wrapped!`\n );\n throw new Error(\n `Critical security failure: ${inscriptionTool.name} tool bypassed FormValidatingToolWrapper`\n );\n } else {\n this.logger.info(\n `✅ SECURITY VALIDATED: ${inscriptionTool.name} tool is properly wrapped`\n );\n }\n }\n }\n\n const toolNames = this.toolRegistry.getToolNames();\n const uniqueNames = new Set(toolNames);\n if (toolNames.length !== uniqueNames.size) {\n this.logger.error('DUPLICATE TOOL NAMES DETECTED in registry!');\n const duplicates = toolNames.filter(\n (name, index) => toolNames.indexOf(name) !== index\n );\n throw new Error(\n `Duplicate tool names detected: ${duplicates.join(', ')}`\n );\n }\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.formEngine = new FormEngine(this.logger);\n\n this.executionPipeline = new ExecutionPipeline(\n this.toolRegistry,\n this.formEngine,\n this.smartMemory,\n this.logger\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 with ToolRegistry');\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 const toolExecutionResult = await this.handleToolExecution(\n message,\n context\n );\n if (toolExecutionResult) {\n return toolExecutionResult;\n }\n\n const directToolResult = await this.handleDirectToolExecution(message);\n if (directToolResult) {\n return directToolResult;\n }\n\n const jsonToolResult = await this.handleJsonToolCalls(message, context);\n if (jsonToolResult) {\n return jsonToolResult;\n }\n\n const contentRefResult = await this.handleContentRefMessages(message);\n if (contentRefResult) {\n return contentRefResult;\n }\n\n this.logger.info('LangChainAgent.chat called with:', {\n message,\n contextLength: context?.messages?.length || 0,\n });\n\n this.loadContextMessages(context);\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 return this.processExecutorResult(result);\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 if (this.toolRegistry) {\n this.toolRegistry.clear();\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 /**\n * Processes form submission and continues with tool execution\n */\n async processFormSubmission(\n submission: FormSubmission,\n context?: ConversationContext\n ): Promise<ChatResponse> {\n this.logger.info('🔥 LangChainAgent.processFormSubmission START');\n \n if (!this.initialized || !this.executor || !this.smartMemory) {\n this.logger.error('🔥 LangChainAgent.processFormSubmission - Agent not initialized');\n throw new Error('Agent not initialized. Call boot() first.');\n }\n\n this.logger.info('🔥 LangChainAgent.processFormSubmission - After initialization check');\n\n try {\n this.logger.info('🔥 LangChainAgent.processFormSubmission - About to log submission info');\n \n this.logger.info('Processing form submission:', {\n formId: submission.formId,\n toolName: submission.toolName,\n parameterKeys: Object.keys(submission.parameters || {}),\n hasParameters: !!submission.parameters,\n parametersType: typeof submission.parameters,\n parametersIsNull: submission.parameters === null,\n parametersIsUndefined: submission.parameters === undefined,\n hasContext: !!submission.context,\n });\n\n this.logger.info('🔥 LangChainAgent.processFormSubmission - After submission info logged');\n\n if (!submission.parameters || typeof submission.parameters !== 'object') {\n this.logger.error('Invalid form submission parameters:', {\n parameters: submission.parameters,\n type: typeof submission.parameters,\n });\n const errorInfo = JSON.stringify(submission, null, 2);\n return this.handleError(\n new Error(`Invalid form submission parameters: ${errorInfo}`)\n );\n }\n\n this.logger.info('🔥 LangChainAgent.processFormSubmission - Parameters validated');\n\n this.loadContextMessages(context);\n\n this.logger.info('🔥 LangChainAgent.processFormSubmission - Context loaded');\n\n const safeSubmission = {\n ...submission,\n parameters: submission.parameters || {},\n };\n\n this.logger.info('🔥 LangChainAgent.processFormSubmission - Safe submission created');\n\n this.logger.info('About to call executor.processFormSubmission with:', {\n formId: safeSubmission.formId,\n toolName: safeSubmission.toolName,\n parameterKeys: Object.keys(safeSubmission.parameters),\n parameterCount: Object.keys(safeSubmission.parameters).length,\n });\n\n const result = await this.executor.processFormSubmission(safeSubmission);\n \n this.logger.info('🔍 DEBUG: Raw result from FormAwareAgentExecutor:', {\n hasResult: !!result,\n resultKeys: result ? Object.keys(result) : [],\n hasMetadata: !!result?.metadata,\n metadataKeys: result?.metadata ? Object.keys(result.metadata) : [],\n hasHashLinkBlock: !!(result?.metadata as any)?.hashLinkBlock,\n hashLinkBlockContent: (result?.metadata as any)?.hashLinkBlock\n });\n \n if (result?.metadata) {\n this.logger.info('🔍 DEBUG: Full metadata from executor:', JSON.stringify(result.metadata));\n }\n \n const preservedMetadata = result?.metadata ? { ...result.metadata } : {};\n\n this.logger.info('Executor processFormSubmission result:', {\n hasResult: !!result,\n hasOutput: !!result.output,\n hasError: !!result.error,\n hasMetadata: !!result.metadata,\n outputType: typeof result.output,\n });\n\n let outputMessage = 'Form processed successfully.';\n if (typeof result.output === 'string') {\n outputMessage = result.output;\n } else if (result.output) {\n try {\n outputMessage = JSON.stringify(result.output);\n } catch {\n outputMessage = String(result.output);\n }\n }\n\n let response: ChatResponse = {\n output: outputMessage,\n message: outputMessage,\n notes: [],\n intermediateSteps: result.intermediateSteps as IntermediateStep[],\n };\n\n if (result.metadata) {\n response.metadata = {\n ...response.metadata,\n ...result.metadata\n };\n this.logger.info('🔍 DEBUG: Metadata after merge from result:', {\n hasMetadata: !!response.metadata,\n metadataKeys: response.metadata ? Object.keys(response.metadata) : [],\n hasHashLinkBlock: !!(response.metadata as any)?.hashLinkBlock,\n hashLinkBlockContent: (response.metadata as any)?.hashLinkBlock\n });\n }\n\n if (result.requiresForm && result.formMessage) {\n response.formMessage = result.formMessage;\n response.requiresForm = true;\n }\n\n if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {\n const toolCalls = result.intermediateSteps.map(\n (step: IntermediateStep, index: number) => {\n const name = step?.action?.tool || 'unknown';\n const args = step?.action?.toolInput || {};\n const obs = step?.observation;\n let output = '';\n if (typeof obs === 'string') {\n output = obs;\n } else if (obs && typeof obs === 'object') {\n try {\n output = JSON.stringify(obs);\n } catch {\n output = String(obs);\n }\n } else if (obs !== undefined) {\n output = String(obs);\n }\n return { id: `call_${index}`, name, args, output };\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\n const blockMetadata = this.processHashLinkBlocks(parsed);\n if (blockMetadata.hashLinkBlock) {\n response.metadata = {\n ...response.metadata,\n ...blockMetadata,\n };\n }\n } catch (error) {\n this.logger.error('Error parsing intermediate steps:', error);\n }\n }\n\n if (response.output) {\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 this.logger.info('🔍 DEBUG: Metadata before memoryStats merge:', {\n hasMetadata: !!response.metadata,\n metadataKeys: response.metadata ? Object.keys(response.metadata) : [],\n hasHashLinkBlock: !!(response.metadata as any)?.hashLinkBlock\n });\n \n response.metadata = {\n ...preservedMetadata,\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('🔍 DEBUG: Final response metadata before return:', {\n hasMetadata: !!response.metadata,\n metadataKeys: response.metadata ? Object.keys(response.metadata) : [],\n hasHashLinkBlock: !!(response.metadata as any)?.hashLinkBlock,\n fullMetadata: response.metadata\n });\n \n if ((preservedMetadata as any)?.hashLinkBlock && !(response.metadata as any)?.hashLinkBlock) {\n this.logger.error('❌ CRITICAL: HashLink metadata was lost during processing!');\n this.logger.error('Original metadata had hashLinkBlock:', (preservedMetadata as any).hashLinkBlock);\n this.logger.error('Final metadata missing hashLinkBlock');\n }\n\n return response;\n } catch (error) {\n this.logger.error('Form submission processing error:', error);\n return this.handleError(error);\n }\n }\n\n /**\n * Check if the agent has pending forms that need to be completed\n */\n hasPendingForms(): boolean {\n return this.executor ? this.executor.hasPendingForms() : false;\n }\n\n /**\n * Get information about pending forms\n */\n getPendingFormsInfo(): Array<{ formId: string; toolName: string }> {\n return this.executor ? this.executor.getPendingFormsInfo() : [];\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 const existingPendingForms = this.executor?.getPendingForms() || new Map();\n\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 inscriptionTool = this.getInscriptionTool();\n if (inscriptionTool) {\n const entry = this.toolRegistry.getTool(inscriptionTool.name);\n if (entry) {\n this.logger.info(\n `🔒 FINAL SECURITY CHECK - ${inscriptionTool.name} tool type: ${entry.tool.constructor.name}`\n );\n if (entry.tool.constructor.name !== 'FormValidatingToolWrapper') {\n this.logger.error(\n `🚨 SECURITY BREACH: ${inscriptionTool.name} tool is NOT wrapped!`\n );\n throw new Error(\n `Critical security failure: ${inscriptionTool.name} tool bypassed FormValidatingToolWrapper`\n );\n } else {\n this.logger.info(\n `✅ SECURITY VALIDATED: ${inscriptionTool.name} tool is properly wrapped`\n );\n }\n }\n }\n\n const stats = this.toolRegistry.getStatistics();\n this.logger.info('🛡️ TOOL SECURITY REPORT:', {\n totalTools: stats.totalTools,\n wrappedTools: stats.wrappedTools,\n unwrappedTools: stats.unwrappedTools,\n categories: stats.categoryCounts,\n priorities: stats.priorityCounts,\n });\n\n this.logger.info(\n `📊 Tool Security Summary: ${stats.wrappedTools} wrapped, ${stats.unwrappedTools} unwrapped`\n );\n\n const agent = await createOpenAIToolsAgent({\n llm,\n tools: langchainTools,\n prompt,\n });\n\n this.executor = new FormAwareAgentExecutor({\n agent,\n tools: langchainTools,\n verbose: this.config.debug?.verbose ?? false,\n returnIntermediateSteps: true,\n });\n\n if (existingPendingForms.size > 0) {\n this.logger.info(\n `Restoring ${existingPendingForms.size} pending forms to new executor`\n );\n this.executor.restorePendingForms(existingPendingForms);\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\n this.toolRegistry.registerTool(langchainTool, {\n metadata: {\n category: 'mcp',\n version: '1.0.0',\n dependencies: [serverConfig.name],\n },\n });\n }\n\n this.tools = this.toolRegistry.getAllTools();\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: MCPServerConfig): 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\n this.toolRegistry.registerTool(langchainTool, {\n metadata: {\n category: 'mcp',\n version: '1.0.0',\n dependencies: [serverConfig.name],\n },\n });\n }\n\n this.tools = this.toolRegistry.getAllTools();\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 * Detects and processes HashLink blocks from tool responses\n * @param parsedResponse - The parsed JSON response from a tool\n * @returns Metadata object containing hashLinkBlock if detected\n */\n private processHashLinkBlocks(parsedResponse: unknown): {\n hashLinkBlock?: Record<string, unknown>;\n } {\n try {\n const responseRecord = parsedResponse as Record<string, unknown>;\n if (\n parsedResponse &&\n typeof parsedResponse === 'object' &&\n responseRecord.hashLinkBlock &&\n typeof responseRecord.hashLinkBlock === 'object'\n ) {\n const block = responseRecord.hashLinkBlock as Record<string, unknown>;\n\n if (\n block.blockId &&\n block.hashLink &&\n block.template &&\n block.attributes &&\n typeof block.blockId === 'string' &&\n typeof block.hashLink === 'string' &&\n typeof block.template === 'string' &&\n typeof block.attributes === 'object'\n ) {\n this.logger.info('HashLink block detected:', {\n blockId: block.blockId,\n hashLink: block.hashLink,\n template: block.template,\n attributeKeys: Object.keys(block.attributes),\n });\n\n return {\n hashLinkBlock: {\n blockId: block.blockId,\n hashLink: block.hashLink,\n template: block.template,\n attributes: block.attributes,\n },\n };\n } else {\n this.logger.warn('Invalid HashLink block structure detected:', block);\n }\n }\n } catch (error) {\n this.logger.error('Error processing HashLink blocks:', error);\n }\n\n return {};\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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"}
|
|
@@ -10,6 +10,7 @@ import { IStateManager } from '@hashgraphonline/standards-agent-kit';
|
|
|
10
10
|
import { MCPServerConfig, MCPConnectionStatus } from './mcp/types';
|
|
11
11
|
import { ContentStoreManager } from './services/ContentStoreManager';
|
|
12
12
|
import { SmartMemoryManager, SmartMemoryConfig } from './memory';
|
|
13
|
+
import { FormSubmission } from './forms/types';
|
|
13
14
|
|
|
14
15
|
export type ToolDescriptor = {
|
|
15
16
|
name: string;
|
|
@@ -107,6 +108,13 @@ export declare class ConversationalAgent {
|
|
|
107
108
|
* @throws {Error} If agent is not initialized
|
|
108
109
|
*/
|
|
109
110
|
processMessage(message: string, chatHistory?: ChatHistoryItem[]): Promise<ChatResponse>;
|
|
111
|
+
/**
|
|
112
|
+
* Process form submission through the conversational agent
|
|
113
|
+
* @param {FormSubmission} submission - The form submission data
|
|
114
|
+
* @returns {Promise<ChatResponse>} The agent's response after processing the form
|
|
115
|
+
* @throws {Error} If agent is not initialized or doesn't support form processing
|
|
116
|
+
*/
|
|
117
|
+
processFormSubmission(submission: FormSubmission): Promise<ChatResponse>;
|
|
110
118
|
/**
|
|
111
119
|
* Validates initialization options and throws if required fields are missing.
|
|
112
120
|
*
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { StructuredTool } from '@langchain/core/tools';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
4
|
+
import { FormValidatingToolWrapper } from '../langchain/FormValidatingToolWrapper';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Tool capabilities configuration for registry entries
|
|
8
|
+
*/
|
|
9
|
+
export interface ToolCapabilities {
|
|
10
|
+
supportsFormValidation: boolean;
|
|
11
|
+
requiresWrapper: boolean;
|
|
12
|
+
priority: 'low' | 'medium' | 'high' | 'critical';
|
|
13
|
+
category: 'core' | 'extension' | 'mcp';
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Tool metadata for comprehensive tool information
|
|
17
|
+
*/
|
|
18
|
+
export interface ToolMetadata {
|
|
19
|
+
name: string;
|
|
20
|
+
version: string;
|
|
21
|
+
category: ToolCapabilities['category'];
|
|
22
|
+
description: string;
|
|
23
|
+
capabilities: ToolCapabilities;
|
|
24
|
+
dependencies: string[];
|
|
25
|
+
schema: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Registry entry containing tool instance and metadata
|
|
29
|
+
*/
|
|
30
|
+
export interface ToolRegistryEntry {
|
|
31
|
+
tool: StructuredTool;
|
|
32
|
+
metadata: ToolMetadata;
|
|
33
|
+
wrapper?: FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape>> | undefined;
|
|
34
|
+
originalTool: StructuredTool;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Options for tool registration
|
|
38
|
+
*/
|
|
39
|
+
export interface ToolRegistrationOptions {
|
|
40
|
+
forceWrapper?: boolean;
|
|
41
|
+
skipWrapper?: boolean;
|
|
42
|
+
wrapperConfig?: {
|
|
43
|
+
requireAllFields?: boolean;
|
|
44
|
+
skipFields?: string[];
|
|
45
|
+
};
|
|
46
|
+
metadata?: Partial<ToolMetadata>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Query interface for finding tools
|
|
50
|
+
*/
|
|
51
|
+
export interface ToolQuery {
|
|
52
|
+
name?: string;
|
|
53
|
+
category?: ToolMetadata['category'];
|
|
54
|
+
capabilities?: Partial<ToolCapabilities>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Centralized tool registry for managing tool lifecycle
|
|
58
|
+
*/
|
|
59
|
+
export declare class ToolRegistry {
|
|
60
|
+
private tools;
|
|
61
|
+
private formGenerator;
|
|
62
|
+
private logger;
|
|
63
|
+
constructor(logger?: Logger);
|
|
64
|
+
/**
|
|
65
|
+
* Register a tool with the registry
|
|
66
|
+
*/
|
|
67
|
+
registerTool(tool: StructuredTool, options?: ToolRegistrationOptions): void;
|
|
68
|
+
/**
|
|
69
|
+
* Get a tool by name
|
|
70
|
+
*/
|
|
71
|
+
getTool(name: string): ToolRegistryEntry | null;
|
|
72
|
+
/**
|
|
73
|
+
* Get tools by capability
|
|
74
|
+
*/
|
|
75
|
+
getToolsByCapability(capability: keyof ToolCapabilities, value?: unknown): ToolRegistryEntry[];
|
|
76
|
+
/**
|
|
77
|
+
* Get tools by query
|
|
78
|
+
*/
|
|
79
|
+
getToolsByQuery(query: ToolQuery): ToolRegistryEntry[];
|
|
80
|
+
/**
|
|
81
|
+
* Get all registered tools
|
|
82
|
+
*/
|
|
83
|
+
getAllTools(): StructuredTool[];
|
|
84
|
+
/**
|
|
85
|
+
* Get all registry entries
|
|
86
|
+
*/
|
|
87
|
+
getAllRegistryEntries(): ToolRegistryEntry[];
|
|
88
|
+
/**
|
|
89
|
+
* Get all tool names
|
|
90
|
+
*/
|
|
91
|
+
getToolNames(): string[];
|
|
92
|
+
/**
|
|
93
|
+
* Check if a tool is registered
|
|
94
|
+
*/
|
|
95
|
+
hasTool(name: string): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Unregister a tool
|
|
98
|
+
*/
|
|
99
|
+
unregisterTool(name: string): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Clear all tools
|
|
102
|
+
*/
|
|
103
|
+
clear(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Analyze tool capabilities
|
|
106
|
+
*/
|
|
107
|
+
private analyzeToolCapabilities;
|
|
108
|
+
/**
|
|
109
|
+
* Check if tool has render configuration
|
|
110
|
+
*/
|
|
111
|
+
private hasRenderConfig;
|
|
112
|
+
/**
|
|
113
|
+
* Determine if tool should be wrapped
|
|
114
|
+
*/
|
|
115
|
+
private shouldWrapTool;
|
|
116
|
+
/**
|
|
117
|
+
* Check if schema is ZodObject-like
|
|
118
|
+
*/
|
|
119
|
+
private isZodObjectLike;
|
|
120
|
+
/**
|
|
121
|
+
* Get statistics about the registry
|
|
122
|
+
*/
|
|
123
|
+
getStatistics(): {
|
|
124
|
+
totalTools: number;
|
|
125
|
+
wrappedTools: number;
|
|
126
|
+
unwrappedTools: number;
|
|
127
|
+
categoryCounts: Record<ToolCapabilities['category'], number>;
|
|
128
|
+
priorityCounts: Record<ToolCapabilities['priority'], number>;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
2
|
+
import { SmartMemoryManager } from '../memory/SmartMemoryManager';
|
|
3
|
+
import { FormEngine, ToolExecutionResult } from '../forms/FormEngine';
|
|
4
|
+
import { ToolRegistry, ToolRegistryEntry } from '../core/ToolRegistry';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Session context for tool execution
|
|
8
|
+
*/
|
|
9
|
+
export interface SessionContext {
|
|
10
|
+
sessionId: string;
|
|
11
|
+
userId?: string;
|
|
12
|
+
timestamp: number;
|
|
13
|
+
conversationId?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Context passed through execution pipeline
|
|
17
|
+
*/
|
|
18
|
+
export interface ExecutionContext {
|
|
19
|
+
toolName: string;
|
|
20
|
+
input: unknown;
|
|
21
|
+
session: SessionContext;
|
|
22
|
+
memory: SmartMemoryManager;
|
|
23
|
+
traceId: string;
|
|
24
|
+
toolEntry: ToolRegistryEntry;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Result of tool execution with metadata
|
|
28
|
+
*/
|
|
29
|
+
export interface ExecutionResult extends ToolExecutionResult {
|
|
30
|
+
traceId: string;
|
|
31
|
+
executionTime: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* ExecutionPipeline handles tool execution coordination
|
|
35
|
+
*/
|
|
36
|
+
export declare class ExecutionPipeline {
|
|
37
|
+
private logger;
|
|
38
|
+
private toolRegistry;
|
|
39
|
+
private formEngine;
|
|
40
|
+
private memory;
|
|
41
|
+
constructor(toolRegistry: ToolRegistry, formEngine: FormEngine, memory: SmartMemoryManager, logger?: Logger);
|
|
42
|
+
/**
|
|
43
|
+
* Execute a tool through the pipeline
|
|
44
|
+
*/
|
|
45
|
+
execute(toolName: string, input: unknown, sessionContext?: SessionContext): Promise<ExecutionResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Execute tool with validation
|
|
48
|
+
*/
|
|
49
|
+
executeWithValidation(toolName: string, input: unknown, sessionContext?: SessionContext): Promise<ExecutionResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Process form submission
|
|
52
|
+
*/
|
|
53
|
+
processFormSubmission(toolName: string, formId: string, parameters: Record<string, unknown>, sessionContext?: SessionContext): Promise<ExecutionResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Check if form generation is required
|
|
56
|
+
*/
|
|
57
|
+
private checkFormGeneration;
|
|
58
|
+
/**
|
|
59
|
+
* Execute tool directly
|
|
60
|
+
*/
|
|
61
|
+
private executeToolDirect;
|
|
62
|
+
/**
|
|
63
|
+
* Execute wrapped tool
|
|
64
|
+
*/
|
|
65
|
+
private executeWrappedTool;
|
|
66
|
+
/**
|
|
67
|
+
* Handle execution error
|
|
68
|
+
*/
|
|
69
|
+
private handleExecutionError;
|
|
70
|
+
/**
|
|
71
|
+
* Build default session context
|
|
72
|
+
*/
|
|
73
|
+
private buildDefaultSession;
|
|
74
|
+
/**
|
|
75
|
+
* Get statistics about the pipeline
|
|
76
|
+
*/
|
|
77
|
+
getStatistics(): {
|
|
78
|
+
totalMiddleware: number;
|
|
79
|
+
registeredMiddleware: string[];
|
|
80
|
+
};
|
|
81
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { StructuredTool } from '@langchain/core/tools';
|
|
2
|
+
import { ZodError, z } from 'zod';
|
|
3
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
4
|
+
import { FormMessage, FormSubmission } from './types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Tool execution result with optional form requirement
|
|
8
|
+
*/
|
|
9
|
+
export interface ToolExecutionResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
output: string;
|
|
12
|
+
metadata?: Record<string, unknown>;
|
|
13
|
+
requiresForm?: boolean;
|
|
14
|
+
formMessage?: FormMessage;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Context for form generation operations
|
|
19
|
+
*/
|
|
20
|
+
export interface FormGenerationContext {
|
|
21
|
+
tool: StructuredTool;
|
|
22
|
+
input: unknown;
|
|
23
|
+
sessionId?: string;
|
|
24
|
+
userId?: string;
|
|
25
|
+
missingFields?: Set<string>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* FormEngine handles all form generation and validation logic
|
|
29
|
+
*/
|
|
30
|
+
export declare class FormEngine {
|
|
31
|
+
private formGenerator;
|
|
32
|
+
private logger;
|
|
33
|
+
constructor(logger?: Logger);
|
|
34
|
+
/**
|
|
35
|
+
* Generate a form for a tool with the given input
|
|
36
|
+
*/
|
|
37
|
+
generateForm(toolName: string, tool: StructuredTool, input: unknown, context?: Partial<FormGenerationContext>): Promise<FormMessage | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Process a form submission
|
|
40
|
+
*/
|
|
41
|
+
processSubmission(submission: FormSubmission, context?: {
|
|
42
|
+
originalInput?: Record<string, unknown>;
|
|
43
|
+
schema?: unknown;
|
|
44
|
+
}): Promise<Record<string, unknown>>;
|
|
45
|
+
/**
|
|
46
|
+
* Check if a tool requires form generation based on input
|
|
47
|
+
*/
|
|
48
|
+
shouldGenerateForm(tool: StructuredTool, input: unknown): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Generate form from error context
|
|
51
|
+
*/
|
|
52
|
+
generateFormFromError(error: ZodError, toolName: string, toolSchema: z.ZodSchema, originalPrompt: string): Promise<FormMessage>;
|
|
53
|
+
/**
|
|
54
|
+
* Generate form for FormValidatable tools
|
|
55
|
+
*/
|
|
56
|
+
private generateFormValidatableForm;
|
|
57
|
+
/**
|
|
58
|
+
* Generate form based on schema validation
|
|
59
|
+
*/
|
|
60
|
+
private generateSchemaBasedForm;
|
|
61
|
+
/**
|
|
62
|
+
* Generate form based on render config
|
|
63
|
+
*/
|
|
64
|
+
private generateRenderConfigForm;
|
|
65
|
+
/**
|
|
66
|
+
* Generate form from Zod validation error
|
|
67
|
+
*/
|
|
68
|
+
private generateErrorBasedForm;
|
|
69
|
+
/**
|
|
70
|
+
* Validate input against tool schema
|
|
71
|
+
*/
|
|
72
|
+
private validateInput;
|
|
73
|
+
/**
|
|
74
|
+
* Check if schema is ZodObject
|
|
75
|
+
*/
|
|
76
|
+
private isZodObject;
|
|
77
|
+
/**
|
|
78
|
+
* Check if tool has render configuration
|
|
79
|
+
*/
|
|
80
|
+
private hasRenderConfig;
|
|
81
|
+
/**
|
|
82
|
+
* Extract render configuration from tool
|
|
83
|
+
*/
|
|
84
|
+
private extractRenderConfig;
|
|
85
|
+
/**
|
|
86
|
+
* Resolve form schema for FormValidatable tools
|
|
87
|
+
*/
|
|
88
|
+
private resolveFormSchema;
|
|
89
|
+
/**
|
|
90
|
+
* Determine missing fields for form generation
|
|
91
|
+
*/
|
|
92
|
+
private determineMissingFields;
|
|
93
|
+
/**
|
|
94
|
+
* Generate form with resolved schema
|
|
95
|
+
*/
|
|
96
|
+
private generateFormWithSchema;
|
|
97
|
+
/**
|
|
98
|
+
* Validate form submission
|
|
99
|
+
*/
|
|
100
|
+
private validateSubmission;
|
|
101
|
+
/**
|
|
102
|
+
* Extract base tool input from context
|
|
103
|
+
*/
|
|
104
|
+
private extractBaseToolInput;
|
|
105
|
+
/**
|
|
106
|
+
* Extract submission data
|
|
107
|
+
*/
|
|
108
|
+
private extractSubmissionData;
|
|
109
|
+
/**
|
|
110
|
+
* Merge input data
|
|
111
|
+
*/
|
|
112
|
+
private mergeInputData;
|
|
113
|
+
/**
|
|
114
|
+
* Get registered strategies
|
|
115
|
+
*/
|
|
116
|
+
getRegisteredStrategies(): string[];
|
|
117
|
+
/**
|
|
118
|
+
* Get registered middleware
|
|
119
|
+
*/
|
|
120
|
+
getRegisteredMiddleware(): string[];
|
|
121
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FormFieldType } from './types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pattern-based field type detection rule
|
|
5
|
+
*/
|
|
6
|
+
export interface FieldTypePattern {
|
|
7
|
+
pattern: RegExp | string[];
|
|
8
|
+
type: FormFieldType;
|
|
9
|
+
priority?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Registry for managing field type detection patterns
|
|
13
|
+
*/
|
|
14
|
+
export declare class FieldTypeRegistry {
|
|
15
|
+
private static instance;
|
|
16
|
+
private patterns;
|
|
17
|
+
private constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Get singleton instance
|
|
20
|
+
*/
|
|
21
|
+
static getInstance(): FieldTypeRegistry;
|
|
22
|
+
/**
|
|
23
|
+
* Initialize default field type patterns
|
|
24
|
+
*/
|
|
25
|
+
private initializeDefaultPatterns;
|
|
26
|
+
/**
|
|
27
|
+
* Register a field type pattern
|
|
28
|
+
*/
|
|
29
|
+
register(key: string, pattern: FieldTypePattern): void;
|
|
30
|
+
/**
|
|
31
|
+
* Unregister a field type pattern
|
|
32
|
+
*/
|
|
33
|
+
unregister(key: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Detect field type based on field name
|
|
36
|
+
*/
|
|
37
|
+
detectType(fieldName: string): FormFieldType | null;
|
|
38
|
+
/**
|
|
39
|
+
* Get all registered patterns
|
|
40
|
+
*/
|
|
41
|
+
getPatterns(): Map<string, FieldTypePattern>;
|
|
42
|
+
/**
|
|
43
|
+
* Clear all patterns
|
|
44
|
+
*/
|
|
45
|
+
clear(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Reset to default patterns
|
|
48
|
+
*/
|
|
49
|
+
reset(): void;
|
|
50
|
+
}
|
|
51
|
+
export declare const fieldTypeRegistry: FieldTypeRegistry;
|