@hashgraphonline/conversational-agent 0.1.207 → 0.1.209

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 (70) hide show
  1. package/dist/cjs/conversational-agent.d.ts +67 -8
  2. package/dist/cjs/index.cjs +1 -1
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs/index.d.ts +1 -0
  5. package/dist/cjs/langchain/ContentAwareAgentExecutor.d.ts +4 -6
  6. package/dist/cjs/langchain-agent.d.ts +8 -0
  7. package/dist/cjs/memory/SmartMemoryManager.d.ts +58 -21
  8. package/dist/cjs/memory/index.d.ts +1 -1
  9. package/dist/esm/index.js +8 -0
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/index12.js +124 -46
  12. package/dist/esm/index12.js.map +1 -1
  13. package/dist/esm/index13.js +178 -13
  14. package/dist/esm/index13.js.map +1 -1
  15. package/dist/esm/index14.js +604 -100
  16. package/dist/esm/index14.js.map +1 -1
  17. package/dist/esm/index15.js +453 -59
  18. package/dist/esm/index15.js.map +1 -1
  19. package/dist/esm/index16.js +44 -172
  20. package/dist/esm/index16.js.map +1 -1
  21. package/dist/esm/index17.js +11 -156
  22. package/dist/esm/index17.js.map +1 -1
  23. package/dist/esm/index18.js +106 -191
  24. package/dist/esm/index18.js.map +1 -1
  25. package/dist/esm/index19.js +7 -90
  26. package/dist/esm/index19.js.map +1 -1
  27. package/dist/esm/index2.js +22 -13
  28. package/dist/esm/index2.js.map +1 -1
  29. package/dist/esm/index20.js +130 -616
  30. package/dist/esm/index20.js.map +1 -1
  31. package/dist/esm/index21.js +138 -215
  32. package/dist/esm/index21.js.map +1 -1
  33. package/dist/esm/index22.js +45 -159
  34. package/dist/esm/index22.js.map +1 -1
  35. package/dist/esm/index23.js +25 -121
  36. package/dist/esm/index23.js.map +1 -1
  37. package/dist/esm/index24.js +83 -56
  38. package/dist/esm/index24.js.map +1 -1
  39. package/dist/esm/index25.js +236 -32
  40. package/dist/esm/index25.js.map +1 -1
  41. package/dist/esm/index5.js +1 -1
  42. package/dist/esm/index6.js +295 -17
  43. package/dist/esm/index6.js.map +1 -1
  44. package/dist/esm/index8.js +82 -8
  45. package/dist/esm/index8.js.map +1 -1
  46. package/dist/types/conversational-agent.d.ts +67 -8
  47. package/dist/types/index.d.ts +1 -0
  48. package/dist/types/langchain/ContentAwareAgentExecutor.d.ts +4 -6
  49. package/dist/types/langchain-agent.d.ts +8 -0
  50. package/dist/types/memory/SmartMemoryManager.d.ts +58 -21
  51. package/dist/types/memory/index.d.ts +1 -1
  52. package/package.json +3 -3
  53. package/src/context/ReferenceContextManager.ts +9 -4
  54. package/src/context/ReferenceResponseProcessor.ts +3 -4
  55. package/src/conversational-agent.ts +379 -31
  56. package/src/index.ts +2 -0
  57. package/src/langchain/ContentAwareAgentExecutor.ts +4 -97
  58. package/src/langchain-agent.ts +94 -11
  59. package/src/mcp/ContentProcessor.ts +13 -3
  60. package/src/mcp/adapters/langchain.ts +1 -9
  61. package/src/memory/ContentStorage.ts +3 -51
  62. package/src/memory/MemoryWindow.ts +4 -16
  63. package/src/memory/ReferenceIdGenerator.ts +0 -4
  64. package/src/memory/SmartMemoryManager.ts +400 -33
  65. package/src/memory/TokenCounter.ts +12 -16
  66. package/src/memory/index.ts +1 -1
  67. package/src/plugins/hcs-10/HCS10Plugin.ts +44 -14
  68. package/src/services/ContentStoreManager.ts +0 -3
  69. package/src/types/content-reference.ts +8 -8
  70. package/src/types/index.ts +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index15.js","sources":["../../src/langchain/ContentAwareAgentExecutor.ts"],"sourcesContent":["import { AgentExecutor } from 'langchain/agents';\nimport type { AgentAction, AgentFinish, AgentStep } from '@langchain/core/agents';\nimport type { ChainValues } from '@langchain/core/utils/types';\nimport type { CallbackManagerForChainRun } from '@langchain/core/callbacks/manager';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type { ToolInterface } from '@langchain/core/tools';\nimport { ContentStoreService, shouldUseReference } from '@hashgraphonline/standards-sdk';\nimport { Logger } from '@hashgraphonline/standards-sdk';\n\n/**\n * Custom AgentExecutor that intercepts large tool outputs and converts them to content references\n * before they are sent to the LLM to avoid token limit issues.\n */\nexport class ContentAwareAgentExecutor extends AgentExecutor {\n private logger: Logger;\n private readonly MCP_REFERENCE_THRESHOLD = 10 * 1024; // 10KB for MCP tools\n\n constructor(config: any) {\n super(config);\n this.logger = new Logger({ module: 'ContentAwareAgentExecutor' });\n }\n\n /**\n * Override the method that processes tool outputs to intercept large content\n */\n override async _call(inputs: ChainValues): Promise<ChainValues> {\n try {\n // Store the original _takeNextStep method\n const originalTakeNextStep = this._takeNextStep.bind(this);\n\n // Override _takeNextStep to intercept tool outputs\n this._takeNextStep = async (\n nameToolMap: Record<string, ToolInterface>,\n inputs: ChainValues,\n intermediateSteps: AgentStep[],\n runManager?: CallbackManagerForChainRun,\n config?: RunnableConfig\n ): Promise<AgentFinish | AgentStep[]> => {\n // Call the original method\n const result = await originalTakeNextStep(nameToolMap, inputs, intermediateSteps, runManager, config);\n\n // If result is an array of intermediate steps, process tool outputs\n if (Array.isArray(result)) {\n const processedSteps = await Promise.all(\n result.map(async (step) => {\n const { action, observation } = step;\n \n // Check if observation is large and should be stored as reference\n if (typeof observation === 'string') {\n const observationBuffer = Buffer.from(observation, 'utf8');\n const shouldStore = observationBuffer.length > this.MCP_REFERENCE_THRESHOLD || \n shouldUseReference(observationBuffer);\n\n if (shouldStore) {\n this.logger.info(\n `[ContentAwareAgentExecutor] Large tool output detected: ${observationBuffer.length} bytes from ${action.tool}`\n );\n\n const contentStore = ContentStoreService.getInstance();\n if (contentStore) {\n try {\n const referenceId = await contentStore.storeContent(observationBuffer, {\n contentType: 'text',\n source: 'tool',\n toolName: action.tool,\n originalSize: observationBuffer.length\n });\n\n const referenceMessage = `content-ref:${referenceId}`;\n this.logger.info(\n `[ContentAwareAgentExecutor] Stored large output as reference: ${referenceMessage}`\n );\n\n // Return the step with the reference instead of the full content\n return { action, observation: referenceMessage };\n } catch (error) {\n this.logger.warn(\n '[ContentAwareAgentExecutor] Failed to store content as reference:',\n error\n );\n }\n } else {\n this.logger.warn('[ContentAwareAgentExecutor] ContentStoreService not available');\n }\n }\n }\n\n // Return unchanged if not large or storage failed\n return step;\n })\n );\n\n return processedSteps;\n }\n\n // Return as-is if not an array (AgentFinish)\n return result;\n };\n\n // Call the parent _call method with our overridden _takeNextStep\n const result = await super._call(inputs);\n\n // Restore the original method\n this._takeNextStep = originalTakeNextStep;\n\n return result;\n } catch (error) {\n this.logger.error('[ContentAwareAgentExecutor] Error in _call:', error);\n throw error;\n }\n }\n}"],"names":["inputs","result"],"mappings":";;AAaO,MAAM,kCAAkC,cAAc;AAAA;AAAA,EAI3D,YAAY,QAAa;AACvB,UAAM,MAAM;AAHd,SAAiB,0BAA0B,KAAK;AAI9C,SAAK,SAAS,IAAI,OAAO,EAAE,QAAQ,6BAA6B;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAe,MAAM,QAA2C;AAC9D,QAAI;AAEF,YAAM,uBAAuB,KAAK,cAAc,KAAK,IAAI;AAGzD,WAAK,gBAAgB,OACnB,aACAA,SACA,mBACA,YACA,WACuC;AAEvC,cAAMC,UAAS,MAAM,qBAAqB,aAAaD,SAAQ,mBAAmB,YAAY,MAAM;AAGpG,YAAI,MAAM,QAAQC,OAAM,GAAG;AACzB,gBAAM,iBAAiB,MAAM,QAAQ;AAAA,YACnCA,QAAO,IAAI,OAAO,SAAS;AACzB,oBAAM,EAAE,QAAQ,YAAA,IAAgB;AAGhC,kBAAI,OAAO,gBAAgB,UAAU;AACnC,sBAAM,oBAAoB,OAAO,KAAK,aAAa,MAAM;AACzD,sBAAM,cAAc,kBAAkB,SAAS,KAAK,2BACjC,mBAAmB,iBAAiB;AAEvD,oBAAI,aAAa;AACf,uBAAK,OAAO;AAAA,oBACV,2DAA2D,kBAAkB,MAAM,eAAe,OAAO,IAAI;AAAA,kBAAA;AAG/G,wBAAM,eAAe,oBAAoB,YAAA;AACzC,sBAAI,cAAc;AAChB,wBAAI;AACF,4BAAM,cAAc,MAAM,aAAa,aAAa,mBAAmB;AAAA,wBACrE,aAAa;AAAA,wBACb,QAAQ;AAAA,wBACR,UAAU,OAAO;AAAA,wBACjB,cAAc,kBAAkB;AAAA,sBAAA,CACjC;AAED,4BAAM,mBAAmB,eAAe,WAAW;AACnD,2BAAK,OAAO;AAAA,wBACV,iEAAiE,gBAAgB;AAAA,sBAAA;AAInF,6BAAO,EAAE,QAAQ,aAAa,iBAAA;AAAA,oBAChC,SAAS,OAAO;AACd,2BAAK,OAAO;AAAA,wBACV;AAAA,wBACA;AAAA,sBAAA;AAAA,oBAEJ;AAAA,kBACF,OAAO;AACL,yBAAK,OAAO,KAAK,+DAA+D;AAAA,kBAClF;AAAA,gBACF;AAAA,cACF;AAGA,qBAAO;AAAA,YACT,CAAC;AAAA,UAAA;AAGH,iBAAO;AAAA,QACT;AAGA,eAAOA;AAAAA,MACT;AAGA,YAAM,SAAS,MAAM,MAAM,MAAM,MAAM;AAGvC,WAAK,gBAAgB;AAErB,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,+CAA+C,KAAK;AACtE,YAAM;AAAA,IACR;AAAA,EACF;AACF;"}
1
+ {"version":3,"file":"index15.js","sources":["../../src/memory/SmartMemoryManager.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport { MemoryWindow } from './MemoryWindow';\nimport { ContentStorage } from './ContentStorage';\nimport { TokenCounter } from './TokenCounter';\n\n/**\n * Entity association for storing blockchain entity contexts\n */\nexport interface EntityAssociation {\n /** The blockchain entity ID (e.g., tokenId, accountId, topicId) */\n entityId: string;\n /** User-provided or derived friendly name */\n entityName: string;\n /** Type of entity (token, account, topic, schedule, etc.) */\n entityType: string;\n /** When the entity was created/associated */\n createdAt: Date;\n /** Transaction ID that created this entity */\n transactionId?: string;\n}\n\n/**\n * Options for resolving entity references\n */\nexport interface EntityResolutionOptions {\n /** Filter by specific entity type */\n entityType?: string;\n /** Maximum number of results to return */\n limit?: number;\n /** Whether to use fuzzy matching for natural language queries */\n fuzzyMatch?: boolean;\n}\n\n/**\n * Configuration for SmartMemoryManager\n */\nexport interface SmartMemoryConfig {\n /** Maximum tokens for active memory window */\n maxTokens?: number;\n /** Reserve tokens for response generation */\n reserveTokens?: number;\n /** Model name for token counting */\n modelName?: string;\n /** Maximum messages to store in content storage */\n storageLimit?: number;\n}\n\n/**\n * Search options for history search\n */\nexport interface SearchOptions {\n /** Whether to perform case-sensitive search */\n caseSensitive?: boolean;\n /** Maximum number of results to return */\n limit?: number;\n /** Whether to use regex pattern matching */\n useRegex?: boolean;\n}\n\n/**\n * Memory statistics for active memory window\n */\nexport interface MemoryStats {\n /** Total active messages in memory window */\n totalActiveMessages: number;\n /** Current token count including system prompt */\n currentTokenCount: number;\n /** Maximum token capacity */\n maxTokens: number;\n /** Remaining token capacity */\n remainingCapacity: number;\n /** System prompt token count */\n systemPromptTokens: number;\n /** Memory usage percentage */\n usagePercentage: number;\n}\n\nconst IS_ENTITY_ASSOCIATION_FLAG = '\"isEntityAssociation\":true';\n\n/**\n * Smart memory manager that combines active memory window with long-term storage\n * Provides context-aware memory management with automatic pruning and searchable history\n */\nexport class SmartMemoryManager {\n private memoryWindow: MemoryWindow;\n private contentStorage: ContentStorage;\n private tokenCounter: TokenCounter;\n private config: Required<SmartMemoryConfig>;\n\n private static readonly DEFAULT_CONFIG: Required<SmartMemoryConfig> = {\n maxTokens: 8000,\n reserveTokens: 1000,\n modelName: 'gpt-4o',\n storageLimit: 1000,\n };\n\n constructor(config: SmartMemoryConfig = {}) {\n this.config = { ...SmartMemoryManager.DEFAULT_CONFIG, ...config };\n\n this.tokenCounter = new TokenCounter(this.config.modelName as any);\n this.contentStorage = new ContentStorage(this.config.storageLimit);\n this.memoryWindow = new MemoryWindow(\n this.config.maxTokens,\n this.config.reserveTokens,\n this.tokenCounter\n );\n }\n\n /**\n * Add a message to the active memory window\n * Automatically handles pruning and storage of displaced messages\n * @param message - Message to add\n */\n addMessage(message: BaseMessage): void {\n const result = this.memoryWindow.addMessage(message);\n\n if (result.prunedMessages.length > 0) {\n this.contentStorage.storeMessages(result.prunedMessages);\n }\n }\n\n /**\n * Get all active messages from the memory window\n * @returns Array of active messages in chronological order\n */\n getMessages(): BaseMessage[] {\n return this.memoryWindow.getMessages();\n }\n\n /**\n * Clear active memory window\n * @param clearStorage - Whether to also clear the content storage (default: false)\n */\n clear(clearStorage: boolean = false): void {\n this.memoryWindow.clear();\n\n if (clearStorage) {\n this.contentStorage.clear();\n }\n }\n\n /**\n * Set the system prompt for the memory window\n * @param systemPrompt - System prompt text\n */\n setSystemPrompt(systemPrompt: string): void {\n this.memoryWindow.setSystemPrompt(systemPrompt);\n }\n\n /**\n * Get the current system prompt\n * @returns Current system prompt text\n */\n getSystemPrompt(): string {\n return this.memoryWindow.getSystemPrompt();\n }\n\n /**\n * Search through stored message history\n * @param query - Search term or pattern\n * @param options - Search configuration\n * @returns Array of matching messages from history\n */\n searchHistory(query: string, options: SearchOptions = {}): BaseMessage[] {\n return this.contentStorage.searchMessages(query, options);\n }\n\n /**\n * Get recent messages from storage history\n * @param count - Number of recent messages to retrieve\n * @returns Array of recent messages from storage\n */\n getRecentHistory(count: number): BaseMessage[] {\n return this.contentStorage.getRecentMessages(count);\n }\n\n /**\n * Check if a message can be added without exceeding limits\n * @param message - Message to test\n * @returns True if message can be added\n */\n canAddMessage(message: BaseMessage): boolean {\n return this.memoryWindow.canAddMessage(message);\n }\n\n /**\n * Get statistics about the active memory window\n * @returns Memory usage statistics\n */\n getMemoryStats(): MemoryStats {\n const windowStats = this.memoryWindow.getStats();\n\n return {\n totalActiveMessages: windowStats.totalMessages,\n currentTokenCount: windowStats.currentTokens,\n maxTokens: windowStats.maxTokens,\n remainingCapacity: windowStats.remainingCapacity,\n systemPromptTokens: windowStats.systemPromptTokens,\n usagePercentage: windowStats.usagePercentage,\n };\n }\n\n /**\n * Get statistics about the content storage\n * @returns Storage usage statistics\n */\n getStorageStats(): ReturnType<ContentStorage['getStorageStats']> {\n return this.contentStorage.getStorageStats();\n }\n\n /**\n * Get combined statistics for both active memory and storage\n * @returns Combined memory and storage statistics\n */\n getOverallStats(): {\n activeMemory: MemoryStats;\n storage: ReturnType<ContentStorage['getStorageStats']>;\n totalMessagesManaged: number;\n activeMemoryUtilization: number;\n storageUtilization: number;\n } {\n const memoryStats = this.getMemoryStats();\n const storageStats = this.getStorageStats();\n\n return {\n activeMemory: memoryStats,\n storage: storageStats,\n totalMessagesManaged:\n memoryStats.totalActiveMessages + storageStats.totalMessages,\n activeMemoryUtilization: memoryStats.usagePercentage,\n storageUtilization: storageStats.usagePercentage,\n };\n }\n\n /**\n * Update the configuration and apply changes\n * @param newConfig - New configuration options\n */\n updateConfig(newConfig: Partial<SmartMemoryConfig>): void {\n this.config = { ...this.config, ...newConfig };\n\n if (\n newConfig.maxTokens !== undefined ||\n newConfig.reserveTokens !== undefined\n ) {\n this.memoryWindow.updateLimits(\n this.config.maxTokens,\n this.config.reserveTokens\n );\n }\n\n if (newConfig.storageLimit !== undefined) {\n this.contentStorage.updateStorageLimit(this.config.storageLimit);\n }\n\n }\n\n /**\n * Get current configuration\n * @returns Current configuration settings\n */\n getConfig(): Required<SmartMemoryConfig> {\n return { ...this.config };\n }\n\n /**\n * Get messages from storage within a time range\n * @param startTime - Start of time range\n * @param endTime - End of time range\n * @returns Messages within the specified time range\n */\n getHistoryFromTimeRange(startTime: Date, endTime: Date): BaseMessage[] {\n return this.contentStorage.getMessagesFromTimeRange(startTime, endTime);\n }\n\n /**\n * Get messages from storage by message type\n * @param messageType - Type of messages to retrieve ('human', 'ai', 'system', etc.)\n * @param limit - Maximum number of messages to return\n * @returns Messages of the specified type\n */\n getHistoryByType(messageType: string, limit?: number): BaseMessage[] {\n return this.contentStorage.getMessagesByType(messageType, limit);\n }\n\n /**\n * Get recent messages from storage within the last N minutes\n * @param minutes - Number of minutes to look back\n * @returns Messages from the last N minutes\n */\n getRecentHistoryByTime(minutes: number): BaseMessage[] {\n return this.contentStorage.getRecentMessagesByTime(minutes);\n }\n\n /**\n * Export the current state for persistence or analysis\n * @returns Serializable representation of memory state\n */\n exportState(): {\n config: Required<SmartMemoryConfig>;\n activeMessages: Array<{ content: unknown; type: string }>;\n systemPrompt: string;\n memoryStats: MemoryStats;\n storageStats: ReturnType<ContentStorage['getStorageStats']>;\n storedMessages: ReturnType<ContentStorage['exportMessages']>;\n } {\n return {\n config: this.config,\n activeMessages: this.memoryWindow.getMessages().map((msg) => ({\n content: msg.content,\n type: msg._getType(),\n })),\n systemPrompt: this.memoryWindow.getSystemPrompt(),\n memoryStats: this.getMemoryStats(),\n storageStats: this.getStorageStats(),\n storedMessages: this.contentStorage.exportMessages(),\n };\n }\n\n /**\n * Get a summary of conversation context for external use\n * Useful for providing context to other systems or for logging\n * @param includeStoredContext - Whether to include recent stored messages\n * @returns Context summary object\n */\n getContextSummary(includeStoredContext: boolean = false): {\n activeMessageCount: number;\n systemPrompt: string;\n recentMessages: BaseMessage[];\n memoryUtilization: number;\n hasStoredHistory: boolean;\n recentStoredMessages?: BaseMessage[];\n storageStats?: ReturnType<ContentStorage['getStorageStats']>;\n } {\n const activeMessages = this.getMessages();\n const summary = {\n activeMessageCount: activeMessages.length,\n systemPrompt: this.getSystemPrompt(),\n recentMessages: activeMessages.slice(-5),\n memoryUtilization: this.getMemoryStats().usagePercentage,\n hasStoredHistory: this.getStorageStats().totalMessages > 0,\n };\n\n if (includeStoredContext) {\n return {\n ...summary,\n recentStoredMessages: this.getRecentHistory(10),\n storageStats: this.getStorageStats(),\n };\n }\n\n return summary;\n }\n\n /**\n * Perform maintenance operations\n * Optimizes storage and cleans up resources\n */\n performMaintenance(): void {\n }\n\n\n /**\n * Store an entity association for later resolution\n * @param entityId - The blockchain entity ID\n * @param entityName - User-provided or derived friendly name\n * @param entityType - Type of entity (token, account, topic, etc.)\n * @param transactionId - Optional transaction ID that created this entity\n */\n storeEntityAssociation(\n entityId: string,\n entityName: string,\n entityType: string,\n transactionId?: string\n ): void {\n try {\n if (\n !entityId ||\n typeof entityId !== 'string' ||\n entityId.trim().length === 0\n ) {\n console.warn(\n '[SmartMemoryManager] Invalid entityId provided:',\n entityId\n );\n return;\n }\n\n if (\n !entityName ||\n typeof entityName !== 'string' ||\n entityName.trim().length === 0\n ) {\n console.warn(\n '[SmartMemoryManager] Invalid entityName provided:',\n entityName\n );\n return;\n }\n\n if (\n !entityType ||\n typeof entityType !== 'string' ||\n entityType.trim().length === 0\n ) {\n console.warn(\n '[SmartMemoryManager] Invalid entityType provided:',\n entityType\n );\n return;\n }\n\n const sanitizedEntityId = entityId.trim();\n const sanitizedEntityName = entityName.trim().substring(0, 100);\n const sanitizedEntityType = entityType.trim().toLowerCase();\n\n const association: EntityAssociation = {\n entityId: sanitizedEntityId,\n entityName: sanitizedEntityName,\n entityType: sanitizedEntityType,\n createdAt: new Date(),\n ...(transactionId !== undefined && transactionId !== null && transactionId.trim() !== ''\n ? { transactionId: transactionId.trim() }\n : {})\n };\n\n const content = JSON.stringify(association);\n type LangChainLikeMessage = {\n _getType: () => string;\n content: unknown;\n id: string;\n name?: string;\n additional_kwargs?: Record<string, unknown>;\n };\n\n const entityMessage: LangChainLikeMessage = {\n _getType: () => 'system',\n content: content,\n id: `entity_${sanitizedEntityId}_${Date.now()}`,\n name: 'entity_association',\n additional_kwargs: {\n entityId: sanitizedEntityId,\n entityName: sanitizedEntityName,\n entityType: sanitizedEntityType,\n isEntityAssociation: true,\n }\n };\n \n this.contentStorage.storeMessages([entityMessage as any]);\n\n console.debug(\n `[SmartMemoryManager] Stored entity association: ${sanitizedEntityName} (${sanitizedEntityType}) -> ${sanitizedEntityId}`\n );\n } catch (_error) {\n console.error(\n '[SmartMemoryManager] Failed to store entity association:',\n _error\n );\n }\n }\n\n /**\n * Resolve entity references from natural language queries\n * @param query - Search query (entity name or natural language reference)\n * @param options - Resolution options for filtering and fuzzy matching\n * @returns Array of matching entity associations\n */\n resolveEntityReference(\n query: string,\n options: EntityResolutionOptions = {}\n ): EntityAssociation[] {\n try {\n if (!query || typeof query !== 'string') {\n console.warn(\n '[SmartMemoryManager] Invalid query provided for entity resolution:',\n query\n );\n return [];\n }\n\n const sanitizedQuery = query.trim();\n if (sanitizedQuery.length === 0) {\n return [];\n }\n\n if (sanitizedQuery.length > 200) {\n console.warn(\n '[SmartMemoryManager] Query too long, truncating:',\n sanitizedQuery.length\n );\n }\n\n const { entityType, limit = 10, fuzzyMatch = true } = options;\n\n const safeLimit = Math.max(1, Math.min(limit || 10, 100));\n\n const searchResults = this.contentStorage.searchMessages(\n sanitizedQuery.substring(0, 200),\n {\n caseSensitive: false,\n limit: safeLimit * 2,\n }\n );\n\n const associations: EntityAssociation[] = [];\n\n for (const message of searchResults) {\n try {\n const content = message.content as string;\n if (\n content.includes(IS_ENTITY_ASSOCIATION_FLAG) ||\n content.includes('entityId')\n ) {\n const parsed = JSON.parse(content);\n if (parsed.entityId && parsed.entityName && parsed.entityType) {\n if (entityType && parsed.entityType !== entityType) {\n continue;\n }\n\n associations.push(parsed as EntityAssociation);\n }\n }\n } catch {\n continue;\n }\n }\n\n if (fuzzyMatch && associations.length === 0) {\n const fuzzyQueries = [\n query.toLowerCase(),\n `token`,\n `account`,\n entityType || '',\n ].filter(Boolean);\n\n for (const fuzzyQuery of fuzzyQueries) {\n if (fuzzyQuery === query.toLowerCase()) continue;\n\n const fuzzyResults = this.contentStorage.searchMessages(fuzzyQuery, {\n caseSensitive: false,\n limit: limit,\n });\n\n for (const message of fuzzyResults) {\n try {\n const content = message.content as string;\n if (content.includes(IS_ENTITY_ASSOCIATION_FLAG)) {\n const parsed = JSON.parse(content);\n if (parsed.entityId && parsed.entityName && parsed.entityType) {\n if (entityType && parsed.entityType !== entityType) {\n continue;\n }\n associations.push(parsed as EntityAssociation);\n }\n }\n } catch {\n continue;\n }\n }\n }\n }\n\n const uniqueAssociations = associations\n .filter(\n (assoc, index, arr) =>\n arr.findIndex((a) => a.entityId === assoc.entityId) === index\n )\n .sort(\n (a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n\n const results = uniqueAssociations.slice(0, safeLimit);\n\n if (results.length > 1) {\n console.debug(\n `[SmartMemoryManager] Multiple entities found for \"${sanitizedQuery}\":`,\n results.map((r) => `${r.entityName} (${r.entityType})`).join(', ')\n );\n }\n\n return results;\n } catch (_error) {\n console.error(\n '[SmartMemoryManager] Failed to resolve entity reference:',\n _error\n );\n return [];\n }\n }\n\n /**\n * Get all entity associations, optionally filtered by type\n * @param entityType - Optional filter by entity type\n * @returns Array of entity associations\n */\n getEntityAssociations(entityType?: string): EntityAssociation[] {\n try {\n const sanitizedEntityType = entityType\n ? entityType.trim().toLowerCase()\n : undefined;\n\n if (\n entityType &&\n (!sanitizedEntityType || sanitizedEntityType.length === 0)\n ) {\n console.warn(\n '[SmartMemoryManager] Invalid entityType filter provided:',\n entityType\n );\n return [];\n }\n\n const SEARCH_ANY_ENTITY = 'entityId';\n const searchQuery = sanitizedEntityType || SEARCH_ANY_ENTITY;\n const searchResults = this.contentStorage.searchMessages(searchQuery, {\n caseSensitive: false,\n limit: 100,\n });\n\n const associations: EntityAssociation[] = [];\n\n for (const message of searchResults) {\n try {\n const content = message.content as string;\n if (content.includes(IS_ENTITY_ASSOCIATION_FLAG)) {\n const parsed = JSON.parse(content);\n\n if (parsed.entityId && parsed.entityName && parsed.entityType) {\n if (\n sanitizedEntityType &&\n parsed.entityType !== sanitizedEntityType\n ) {\n continue;\n }\n\n if (parsed.createdAt && typeof parsed.createdAt === 'string') {\n parsed.createdAt = new Date(parsed.createdAt);\n }\n\n associations.push(parsed as EntityAssociation);\n }\n }\n } catch (_parseError) {\n console.debug(\n '[SmartMemoryManager] Skipped malformed association data:',\n _parseError\n );\n continue;\n }\n }\n\n const results = associations\n .filter(\n (assoc, index, arr) =>\n arr.findIndex((a) => a.entityId === assoc.entityId) === index\n )\n .sort((a, b): number => {\n const getTime = (d: Date | string): number =>\n d instanceof Date ? d.getTime() : new Date(d).getTime();\n const aTime = getTime(a.createdAt);\n const bTime = getTime(b.createdAt);\n return bTime - aTime;\n });\n\n console.debug(\n `[SmartMemoryManager] Retrieved ${results.length} entity associations${\n sanitizedEntityType ? ` of type '${sanitizedEntityType}'` : ''\n }`\n );\n\n return results;\n } catch (_error) {\n console.error(\n '[SmartMemoryManager] Failed to get entity associations:',\n _error\n );\n return [];\n }\n }\n\n /**\n * Clean up resources and dispose of components\n */\n dispose(): void {\n this.memoryWindow.dispose();\n this.contentStorage.dispose();\n this.tokenCounter.dispose();\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,177 +1,49 @@
1
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
- import { MCPContentProcessor } from "./index21.js";
4
- class MCPClientManager {
5
- constructor(logger, contentStorage) {
6
- this.clients = /* @__PURE__ */ new Map();
7
- this.tools = /* @__PURE__ */ new Map();
8
- this.logger = logger;
9
- if (contentStorage) {
10
- this.contentProcessor = new MCPContentProcessor(contentStorage, logger);
11
- }
12
- }
13
- /**
14
- * Connect to an MCP server and discover its tools
15
- */
16
- async connectServer(config) {
17
- try {
18
- if (this.isServerConnected(config.name)) {
19
- return {
20
- serverName: config.name,
21
- connected: false,
22
- error: `Server ${config.name} is already connected`,
23
- tools: []
24
- };
25
- }
26
- if (config.transport && config.transport !== "stdio") {
27
- throw new Error(`Transport ${config.transport} not yet supported`);
28
- }
29
- const transport = new StdioClientTransport({
30
- command: config.command,
31
- args: config.args,
32
- ...config.env && { env: config.env }
33
- });
34
- const client = new Client({
35
- name: `conversational-agent-${config.name}`,
36
- version: "1.0.0"
37
- }, {
38
- capabilities: {}
39
- });
40
- await client.connect(transport);
41
- this.clients.set(config.name, client);
42
- const toolsResponse = await client.listTools();
43
- const toolsWithServer = toolsResponse.tools.map((tool) => ({
44
- ...tool,
45
- serverName: config.name
46
- }));
47
- this.tools.set(config.name, toolsWithServer);
48
- this.logger.info(`Connected to MCP server ${config.name} with ${toolsWithServer.length} tools`);
49
- return {
50
- serverName: config.name,
51
- connected: true,
52
- tools: toolsWithServer
53
- };
54
- } catch (error) {
55
- this.logger.error(`Failed to connect to MCP server ${config.name}:`, error);
56
- return {
57
- serverName: config.name,
58
- connected: false,
59
- error: error instanceof Error ? error.message : "Unknown error",
60
- tools: []
61
- };
62
- }
63
- }
64
- /**
65
- * Execute a tool on a specific MCP server
66
- */
67
- async executeTool(serverName, toolName, args) {
68
- const client = this.clients.get(serverName);
69
- if (!client) {
70
- throw new Error(`MCP server ${serverName} not connected`);
71
- }
72
- this.logger.debug(`Executing MCP tool ${toolName} on server ${serverName}`, args);
73
- try {
74
- const result = await client.callTool({
75
- name: toolName,
76
- arguments: args
77
- });
78
- if (this.contentProcessor) {
79
- const processed = await this.contentProcessor.processResponse(result, serverName, toolName);
80
- if (processed.wasProcessed) {
81
- this.logger.debug(
82
- `Processed MCP response from ${serverName}::${toolName}`,
83
- {
84
- referenceCreated: processed.referenceCreated,
85
- originalSize: processed.originalSize,
86
- errors: processed.errors
87
- }
88
- );
89
- if (processed.errors && processed.errors.length > 0) {
90
- this.logger.warn(`Content processing warnings for ${serverName}::${toolName}:`, processed.errors);
91
- }
92
- }
93
- return processed.content;
94
- }
95
- return result;
96
- } catch (error) {
97
- this.logger.error(`Error executing MCP tool ${toolName}:`, error);
98
- throw error;
99
- }
100
- }
101
- /**
102
- * Disconnect all MCP servers
103
- */
104
- async disconnectAll() {
105
- for (const [name, client] of this.clients) {
106
- try {
107
- await client.close();
108
- this.logger.info(`Disconnected from MCP server ${name}`);
109
- } catch (error) {
110
- this.logger.error(`Error disconnecting MCP server ${name}:`, error);
111
- }
112
- }
113
- this.clients.clear();
114
- this.tools.clear();
115
- }
116
- /**
117
- * Get all discovered tools from all connected servers
118
- */
119
- getAllTools() {
120
- const allTools = [];
121
- for (const tools of this.tools.values()) {
122
- allTools.push(...tools);
123
- }
124
- return allTools;
125
- }
126
- /**
127
- * Get tools from a specific server
128
- */
129
- getServerTools(serverName) {
130
- return this.tools.get(serverName) || [];
131
- }
132
- /**
133
- * Check if a server is connected
134
- */
135
- isServerConnected(serverName) {
136
- return this.clients.has(serverName);
137
- }
138
- /**
139
- * Get list of connected server names
140
- */
141
- getConnectedServers() {
142
- return Array.from(this.clients.keys());
143
- }
144
- /**
145
- * Enable content processing with content storage
146
- */
147
- enableContentProcessing(contentStorage) {
148
- this.contentProcessor = new MCPContentProcessor(contentStorage, this.logger);
149
- this.logger.info("Content processing enabled for MCP responses");
150
- }
151
- /**
152
- * Disable content processing
153
- */
154
- disableContentProcessing() {
155
- delete this.contentProcessor;
156
- this.logger.info("Content processing disabled for MCP responses");
157
- }
158
- /**
159
- * Check if content processing is enabled
160
- */
161
- isContentProcessingEnabled() {
162
- return this.contentProcessor !== void 0;
163
- }
164
- /**
165
- * Analyze a response without processing it (for testing/debugging)
166
- */
167
- analyzeResponseContent(response) {
168
- if (!this.contentProcessor) {
169
- throw new Error("Content processing is not enabled");
170
- }
171
- return this.contentProcessor.analyzeResponse(response);
1
+ import { z } from "zod";
2
+ import { AccountBuilder } from "./index24.js";
3
+ import { BaseHederaTransactionTool } from "hedera-agent-kit";
4
+ const HbarTransferInputSchema = z.object({
5
+ accountId: z.string().describe('Account ID for the transfer (e.g., "0.0.xxxx").'),
6
+ amount: z.union([z.number(), z.string()]).describe(
7
+ "HBAR amount in decimal format (e.g., 1 for 1 HBAR, 0.5 for 0.5 HBAR). Positive for credit, negative for debit. DO NOT multiply by 10^8 for tinybars - just use the HBAR amount directly."
8
+ )
9
+ });
10
+ const TransferHbarZodSchemaCore = z.object({
11
+ transfers: z.array(HbarTransferInputSchema).min(1).describe(
12
+ 'Array of ALL transfers for this transaction. For multi-party transfers (e.g., "A sends 5 to C and B sends 3 to C"), include all transfers here: [{accountId: "A", amount: -5}, {accountId: "B", amount: -3}, {accountId: "C", amount: 8}]. Amounts must sum to zero.'
13
+ ),
14
+ memo: z.string().optional().describe("Optional. Memo for the transaction.")
15
+ });
16
+ class TransferHbarTool extends BaseHederaTransactionTool {
17
+ constructor() {
18
+ super(...arguments);
19
+ this.name = "hedera-account-transfer-hbar-v2";
20
+ this.description = 'PRIMARY TOOL FOR HBAR TRANSFERS: Transfers HBAR between accounts. Supports multiple transfers in a single transaction - when multiple accounts need to send/receive HBAR (e.g., "A sends 5 HBAR to C and B sends 3 HBAR to C"), include ALL transfers in one transfers array. The sum of all transfers must equal zero. Use this for scheduled transactions and multi-signature scenarios.';
21
+ this.specificInputSchema = TransferHbarZodSchemaCore;
22
+ this.namespace = "account";
23
+ }
24
+ /**
25
+ * Creates and returns the service builder for account operations.
26
+ *
27
+ * @returns BaseServiceBuilder instance configured for account operations
28
+ */
29
+ getServiceBuilder() {
30
+ return new AccountBuilder(this.hederaKit);
31
+ }
32
+ /**
33
+ * Executes the HBAR transfer using the provided builder and arguments.
34
+ * Validates that all transfers sum to zero before execution.
35
+ *
36
+ * @param builder - The service builder instance for executing transactions
37
+ * @param specificArgs - The validated transfer parameters including transfers array and optional memo
38
+ * @returns Promise that resolves when the transfer is complete
39
+ */
40
+ async callBuilderMethod(builder, specificArgs) {
41
+ await builder.transferHbar(
42
+ specificArgs
43
+ );
172
44
  }
173
45
  }
174
46
  export {
175
- MCPClientManager
47
+ TransferHbarTool
176
48
  };
177
49
  //# sourceMappingURL=index16.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index16.js","sources":["../../src/mcp/MCPClientManager.ts"],"sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport type { MCPServerConfig, MCPToolInfo, MCPConnectionStatus } from './types';\nimport { Logger } from '@hashgraphonline/standards-sdk';\nimport type { ContentStorage } from '../memory/ContentStorage';\nimport { MCPContentProcessor, ProcessedResponse } from './ContentProcessor';\n\n/**\n * Manages connections to MCP servers and tool discovery\n */\nexport class MCPClientManager {\n private clients: Map<string, Client> = new Map();\n private tools: Map<string, MCPToolInfo[]> = new Map();\n private logger: Logger;\n private contentProcessor?: MCPContentProcessor;\n\n constructor(logger: Logger, contentStorage?: ContentStorage) {\n this.logger = logger;\n if (contentStorage) {\n this.contentProcessor = new MCPContentProcessor(contentStorage, logger);\n }\n }\n\n /**\n * Connect to an MCP server and discover its tools\n */\n async connectServer(config: MCPServerConfig): Promise<MCPConnectionStatus> {\n try {\n if (this.isServerConnected(config.name)) {\n return {\n serverName: config.name,\n connected: false,\n error: `Server ${config.name} is already connected`,\n tools: [],\n };\n }\n\n if (config.transport && config.transport !== 'stdio') {\n throw new Error(`Transport ${config.transport} not yet supported`);\n }\n\n const transport = new StdioClientTransport({\n command: config.command,\n args: config.args,\n ...(config.env && { env: config.env }),\n });\n\n const client = new Client({\n name: `conversational-agent-${config.name}`,\n version: '1.0.0',\n }, {\n capabilities: {},\n });\n\n await client.connect(transport);\n this.clients.set(config.name, client);\n\n const toolsResponse = await client.listTools();\n const toolsWithServer: MCPToolInfo[] = toolsResponse.tools.map(tool => ({\n ...tool,\n serverName: config.name,\n }));\n\n this.tools.set(config.name, toolsWithServer);\n this.logger.info(`Connected to MCP server ${config.name} with ${toolsWithServer.length} tools`);\n\n return {\n serverName: config.name,\n connected: true,\n tools: toolsWithServer,\n };\n } catch (error) {\n this.logger.error(`Failed to connect to MCP server ${config.name}:`, error);\n return {\n serverName: config.name,\n connected: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n tools: [],\n };\n }\n }\n\n /**\n * Execute a tool on a specific MCP server\n */\n async executeTool(serverName: string, toolName: string, args: Record<string, unknown>): Promise<unknown> {\n const client = this.clients.get(serverName);\n if (!client) {\n throw new Error(`MCP server ${serverName} not connected`);\n }\n\n this.logger.debug(`Executing MCP tool ${toolName} on server ${serverName}`, args);\n\n try {\n const result = await client.callTool({\n name: toolName,\n arguments: args,\n });\n\n if (this.contentProcessor) {\n const processed = await this.contentProcessor.processResponse(result, serverName, toolName);\n \n if (processed.wasProcessed) {\n this.logger.debug(\n `Processed MCP response from ${serverName}::${toolName}`,\n {\n referenceCreated: processed.referenceCreated,\n originalSize: processed.originalSize,\n errors: processed.errors\n }\n );\n\n if (processed.errors && processed.errors.length > 0) {\n this.logger.warn(`Content processing warnings for ${serverName}::${toolName}:`, processed.errors);\n }\n }\n\n return processed.content;\n }\n\n return result;\n } catch (error) {\n this.logger.error(`Error executing MCP tool ${toolName}:`, error);\n throw error;\n }\n }\n\n /**\n * Disconnect all MCP servers\n */\n async disconnectAll(): Promise<void> {\n for (const [name, client] of this.clients) {\n try {\n await client.close();\n this.logger.info(`Disconnected from MCP server ${name}`);\n } catch (error) {\n this.logger.error(`Error disconnecting MCP server ${name}:`, error);\n }\n }\n this.clients.clear();\n this.tools.clear();\n }\n\n /**\n * Get all discovered tools from all connected servers\n */\n getAllTools(): MCPToolInfo[] {\n const allTools: MCPToolInfo[] = [];\n for (const tools of this.tools.values()) {\n allTools.push(...tools);\n }\n return allTools;\n }\n\n /**\n * Get tools from a specific server\n */\n getServerTools(serverName: string): MCPToolInfo[] {\n return this.tools.get(serverName) || [];\n }\n\n /**\n * Check if a server is connected\n */\n isServerConnected(serverName: string): boolean {\n return this.clients.has(serverName);\n }\n\n /**\n * Get list of connected server names\n */\n getConnectedServers(): string[] {\n return Array.from(this.clients.keys());\n }\n\n /**\n * Enable content processing with content storage\n */\n enableContentProcessing(contentStorage: ContentStorage): void {\n this.contentProcessor = new MCPContentProcessor(contentStorage, this.logger);\n this.logger.info('Content processing enabled for MCP responses');\n }\n\n /**\n * Disable content processing\n */\n disableContentProcessing(): void {\n delete this.contentProcessor;\n this.logger.info('Content processing disabled for MCP responses');\n }\n\n /**\n * Check if content processing is enabled\n */\n isContentProcessingEnabled(): boolean {\n return this.contentProcessor !== undefined;\n }\n\n /**\n * Analyze a response without processing it (for testing/debugging)\n */\n analyzeResponseContent(response: unknown): unknown {\n if (!this.contentProcessor) {\n throw new Error('Content processing is not enabled');\n }\n return this.contentProcessor.analyzeResponse(response);\n }\n}"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index16.js","sources":["../../src/plugins/hbar-transfer/TransferHbarTool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { HbarTransferParams } from './types';\nimport { AccountBuilder } from './AccountBuilder';\nimport { BaseHederaTransactionTool, BaseServiceBuilder } from 'hedera-agent-kit';\n\nconst HbarTransferInputSchema = z.object({\n accountId: z\n .string()\n .describe('Account ID for the transfer (e.g., \"0.0.xxxx\").'),\n amount: z\n .union([z.number(), z.string()])\n .describe(\n 'HBAR amount in decimal format (e.g., 1 for 1 HBAR, 0.5 for 0.5 HBAR). Positive for credit, negative for debit. DO NOT multiply by 10^8 for tinybars - just use the HBAR amount directly.'\n ),\n});\n\nconst TransferHbarZodSchemaCore = z.object({\n transfers: z\n .array(HbarTransferInputSchema)\n .min(1)\n .describe(\n 'Array of ALL transfers for this transaction. For multi-party transfers (e.g., \"A sends 5 to C and B sends 3 to C\"), include all transfers here: [{accountId: \"A\", amount: -5}, {accountId: \"B\", amount: -3}, {accountId: \"C\", amount: 8}]. Amounts must sum to zero.'\n ),\n memo: z.string().optional().describe('Optional. Memo for the transaction.'),\n});\n\n/**\n * A Hedera transaction tool for transferring HBAR between accounts.\n * Supports single and multi-party transfers with automatic balance validation.\n * Extends BaseHederaTransactionTool to handle HBAR transfer transactions on the Hedera network.\n */\nexport class TransferHbarTool extends BaseHederaTransactionTool<\n typeof TransferHbarZodSchemaCore\n> {\n name = 'hedera-account-transfer-hbar-v2';\n description =\n 'PRIMARY TOOL FOR HBAR TRANSFERS: Transfers HBAR between accounts. Supports multiple transfers in a single transaction - when multiple accounts need to send/receive HBAR (e.g., \"A sends 5 HBAR to C and B sends 3 HBAR to C\"), include ALL transfers in one transfers array. The sum of all transfers must equal zero. Use this for scheduled transactions and multi-signature scenarios.';\n specificInputSchema = TransferHbarZodSchemaCore;\n namespace = 'account';\n\n\n /**\n * Creates and returns the service builder for account operations.\n * \n * @returns BaseServiceBuilder instance configured for account operations\n */\n protected getServiceBuilder(): BaseServiceBuilder {\n return new AccountBuilder(this.hederaKit) as BaseServiceBuilder;\n }\n\n /**\n * Executes the HBAR transfer using the provided builder and arguments.\n * Validates that all transfers sum to zero before execution.\n * \n * @param builder - The service builder instance for executing transactions\n * @param specificArgs - The validated transfer parameters including transfers array and optional memo\n * @returns Promise that resolves when the transfer is complete\n */\n protected async callBuilderMethod(\n builder: BaseServiceBuilder,\n specificArgs: z.infer<typeof TransferHbarZodSchemaCore>\n ): Promise<void> {\n await (builder as AccountBuilder).transferHbar(\n specificArgs as unknown as HbarTransferParams\n );\n }\n}"],"names":[],"mappings":";;;AAKA,MAAM,0BAA0B,EAAE,OAAO;AAAA,EACvC,WAAW,EACR,SACA,SAAS,iDAAiD;AAAA,EAC7D,QAAQ,EACL,MAAM,CAAC,EAAE,OAAA,GAAU,EAAE,QAAQ,CAAC,EAC9B;AAAA,IACC;AAAA,EAAA;AAEN,CAAC;AAED,MAAM,4BAA4B,EAAE,OAAO;AAAA,EACzC,WAAW,EACR,MAAM,uBAAuB,EAC7B,IAAI,CAAC,EACL;AAAA,IACC;AAAA,EAAA;AAAA,EAEJ,MAAM,EAAE,OAAA,EAAS,SAAA,EAAW,SAAS,qCAAqC;AAC5E,CAAC;AAOM,MAAM,yBAAyB,0BAEpC;AAAA,EAFK,cAAA;AAAA,UAAA,GAAA,SAAA;AAGL,SAAA,OAAO;AACP,SAAA,cACE;AACF,SAAA,sBAAsB;AACtB,SAAA,YAAY;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQF,oBAAwC;AAChD,WAAO,IAAI,eAAe,KAAK,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAgB,kBACd,SACA,cACe;AACf,UAAO,QAA2B;AAAA,MAChC;AAAA,IAAA;AAAA,EAEJ;AACF;"}
@@ -1,161 +1,16 @@
1
- import { DynamicStructuredTool } from "@langchain/core/tools";
2
- import { z } from "zod";
3
- import { shouldUseReference, ContentStoreService } from "@hashgraphonline/standards-sdk";
4
- function convertMCPToolToLangChain(tool, mcpManager, serverConfig) {
5
- const zodSchema = jsonSchemaToZod(tool.inputSchema);
6
- const sanitizedName = `${tool.serverName}_${tool.name}`.replace(
7
- /[^a-zA-Z0-9_]/g,
8
- "_"
9
- );
10
- let description = tool.description || `MCP tool ${tool.name} from ${tool.serverName}`;
11
- if (serverConfig?.toolDescriptions?.[tool.name]) {
12
- description = `${description}
1
+ const getSystemMessage = (accountId) => `You are a helpful assistant managing Hashgraph Online HCS-10 connections, messages, HCS-2 registries, and content inscription.
13
2
 
14
- ${serverConfig.toolDescriptions[tool.name]}`;
15
- }
16
- if (serverConfig?.additionalContext) {
17
- description = `${description}
3
+ You have access to tools for:
4
+ - HCS-10: registering agents, finding registered agents, initiating connections, listing active connections, sending messages over connections, and checking for new messages
5
+ - HCS-2: creating registries, registering entries, updating entries, deleting entries, migrating registries, and querying registry contents
6
+ - Inscription: inscribing content from URLs, files, or buffers, creating Hashinal NFTs, and retrieving inscriptions
18
7
 
19
- Context: ${serverConfig.additionalContext}`;
20
- }
21
- return new DynamicStructuredTool({
22
- name: sanitizedName,
23
- description,
24
- schema: zodSchema,
25
- func: async (input) => {
26
- try {
27
- const result = await mcpManager.executeTool(
28
- tool.serverName,
29
- tool.name,
30
- input
31
- );
32
- let responseText = "";
33
- if (typeof result === "string") {
34
- responseText = result;
35
- } else if (result && typeof result === "object" && "content" in result) {
36
- const content = result.content;
37
- if (Array.isArray(content)) {
38
- const textParts = content.filter(
39
- (item) => typeof item === "object" && item !== null && "type" in item && item.type === "text" && "text" in item
40
- ).map((item) => item.text);
41
- responseText = textParts.join("\n");
42
- } else {
43
- responseText = JSON.stringify(content);
44
- }
45
- } else {
46
- responseText = JSON.stringify(result);
47
- }
48
- const responseBuffer = Buffer.from(responseText, "utf8");
49
- console.log(`[MCP Adapter] Response size: ${responseBuffer.length} bytes, tool: ${tool.serverName}_${tool.name}`);
50
- const MCP_REFERENCE_THRESHOLD = 10 * 1024;
51
- const shouldStoreMCPContent = responseBuffer.length > MCP_REFERENCE_THRESHOLD;
52
- if (shouldStoreMCPContent || shouldUseReference(responseBuffer)) {
53
- console.log(`[MCP Adapter] Content exceeds threshold (${responseBuffer.length} > ${MCP_REFERENCE_THRESHOLD}), storing as reference`);
54
- const contentStore = ContentStoreService.getInstance();
55
- if (contentStore) {
56
- try {
57
- const referenceId = await contentStore.storeContent(responseBuffer, {
58
- contentType: "text",
59
- source: "mcp",
60
- mcpToolName: `${tool.serverName}_${tool.name}`,
61
- originalSize: responseBuffer.length
62
- });
63
- console.log(`[MCP Adapter] Stored content as reference: content-ref:${referenceId}`);
64
- return `content-ref:${referenceId}`;
65
- } catch (storeError) {
66
- console.warn("Failed to store large MCP content as reference:", storeError);
67
- }
68
- } else {
69
- console.warn("[MCP Adapter] ContentStoreService not available");
70
- }
71
- }
72
- return responseText;
73
- } catch (error) {
74
- const errorMessage = error instanceof Error ? error.message : "Unknown error";
75
- return `Error executing MCP tool ${tool.name}: ${errorMessage}`;
76
- }
77
- }
78
- });
79
- }
80
- function jsonSchemaToZod(schema) {
81
- if (!schema || typeof schema !== "object") {
82
- return z.object({});
83
- }
84
- const schemaObj = schema;
85
- if (schemaObj.type && schemaObj.type !== "object") {
86
- return convertType(schemaObj);
87
- }
88
- if (!schemaObj.properties || typeof schemaObj.properties !== "object") {
89
- return z.object({});
90
- }
91
- const shape = {};
92
- for (const [key, value] of Object.entries(schemaObj.properties)) {
93
- let zodType = convertType(value);
94
- const isRequired = Array.isArray(schemaObj.required) && schemaObj.required.includes(key);
95
- if (!isRequired) {
96
- zodType = zodType.optional();
97
- }
98
- shape[key] = zodType;
99
- }
100
- return z.object(shape);
101
- }
102
- function convertType(schema) {
103
- if (!schema || typeof schema !== "object" || !("type" in schema)) {
104
- return z.unknown();
105
- }
106
- const schemaObj = schema;
107
- let zodType;
108
- switch (schemaObj.type) {
109
- case "string":
110
- zodType = z.string();
111
- if (schemaObj.enum && Array.isArray(schemaObj.enum)) {
112
- zodType = z.enum(schemaObj.enum);
113
- }
114
- break;
115
- case "number":
116
- zodType = z.number();
117
- if ("minimum" in schemaObj && typeof schemaObj.minimum === "number") {
118
- zodType = zodType.min(schemaObj.minimum);
119
- }
120
- if ("maximum" in schemaObj && typeof schemaObj.maximum === "number") {
121
- zodType = zodType.max(schemaObj.maximum);
122
- }
123
- break;
124
- case "integer":
125
- zodType = z.number().int();
126
- if ("minimum" in schemaObj && typeof schemaObj.minimum === "number") {
127
- zodType = zodType.min(schemaObj.minimum);
128
- }
129
- if ("maximum" in schemaObj && typeof schemaObj.maximum === "number") {
130
- zodType = zodType.max(schemaObj.maximum);
131
- }
132
- break;
133
- case "boolean":
134
- zodType = z.boolean();
135
- break;
136
- case "array":
137
- if (schemaObj.items) {
138
- zodType = z.array(convertType(schemaObj.items));
139
- } else {
140
- zodType = z.array(z.unknown());
141
- }
142
- break;
143
- case "object":
144
- if ("properties" in schemaObj) {
145
- zodType = jsonSchemaToZod(schemaObj);
146
- } else {
147
- zodType = z.object({}).passthrough();
148
- }
149
- break;
150
- default:
151
- zodType = z.unknown();
152
- }
153
- if ("description" in schemaObj && typeof schemaObj.description === "string") {
154
- zodType = zodType.describe(schemaObj.description);
155
- }
156
- return zodType;
157
- }
8
+ *** IMPORTANT CONTEXT ***
9
+ You are currently operating as agent: ${accountId} on the Hashgraph Online network
10
+ When users ask about "my profile", "my account", "my connections", etc., use this account ID: ${accountId}
11
+
12
+ Remember the connection numbers when listing connections, as users might refer to them.`;
158
13
  export {
159
- convertMCPToolToLangChain
14
+ getSystemMessage
160
15
  };
161
16
  //# sourceMappingURL=index17.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index17.js","sources":["../../src/mcp/adapters/langchain.ts"],"sourcesContent":["import { DynamicStructuredTool } from '@langchain/core/tools';\nimport { z } from 'zod';\nimport type { MCPToolInfo, MCPServerConfig } from '../types';\nimport type { MCPClientManager } from '../MCPClientManager';\nimport { ContentStoreService, shouldUseReference } from '@hashgraphonline/standards-sdk';\nimport type { ContentSource } from '../../types/content-reference';\n\n/**\n * Convert an MCP tool to a LangChain DynamicStructuredTool\n */\nexport function convertMCPToolToLangChain(\n tool: MCPToolInfo,\n mcpManager: MCPClientManager,\n serverConfig?: MCPServerConfig\n): DynamicStructuredTool {\n const zodSchema = jsonSchemaToZod(tool.inputSchema);\n\n const sanitizedName = `${tool.serverName}_${tool.name}`.replace(\n /[^a-zA-Z0-9_]/g,\n '_'\n );\n\n let description = tool.description || `MCP tool ${tool.name} from ${tool.serverName}`;\n \n if (serverConfig?.toolDescriptions?.[tool.name]) {\n description = `${description}\\n\\n${serverConfig.toolDescriptions[tool.name]}`;\n }\n \n if (serverConfig?.additionalContext) {\n description = `${description}\\n\\nContext: ${serverConfig.additionalContext}`;\n }\n\n return new DynamicStructuredTool({\n name: sanitizedName,\n description,\n schema: zodSchema,\n func: async (input) => {\n try {\n const result = await mcpManager.executeTool(\n tool.serverName,\n tool.name,\n input\n );\n\n let responseText = '';\n \n if (typeof result === 'string') {\n responseText = result;\n } else if (\n result &&\n typeof result === 'object' &&\n 'content' in result\n ) {\n const content = (result as { content: unknown }).content;\n if (Array.isArray(content)) {\n const textParts = content\n .filter(\n (item): item is { type: string; text: string } =>\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n item.type === 'text' &&\n 'text' in item\n )\n .map((item) => item.text);\n responseText = textParts.join('\\n');\n } else {\n responseText = JSON.stringify(content);\n }\n } else {\n responseText = JSON.stringify(result);\n }\n\n // Check if content should be stored as reference\n const responseBuffer = Buffer.from(responseText, 'utf8');\n console.log(`[MCP Adapter] Response size: ${responseBuffer.length} bytes, tool: ${tool.serverName}_${tool.name}`);\n \n // Use a lower threshold for MCP tools (10KB) to avoid token limit issues\n const MCP_REFERENCE_THRESHOLD = 10 * 1024; // 10KB\n const shouldStoreMCPContent = responseBuffer.length > MCP_REFERENCE_THRESHOLD;\n \n if (shouldStoreMCPContent || shouldUseReference(responseBuffer)) {\n console.log(`[MCP Adapter] Content exceeds threshold (${responseBuffer.length} > ${MCP_REFERENCE_THRESHOLD}), storing as reference`);\n const contentStore = ContentStoreService.getInstance();\n if (contentStore) {\n try {\n const referenceId = await contentStore.storeContent(responseBuffer, {\n contentType: 'text' as ContentSource,\n source: 'mcp',\n mcpToolName: `${tool.serverName}_${tool.name}`,\n originalSize: responseBuffer.length\n });\n console.log(`[MCP Adapter] Stored content as reference: content-ref:${referenceId}`);\n return `content-ref:${referenceId}`;\n } catch (storeError) {\n // If storage fails, fall back to returning the content\n console.warn('Failed to store large MCP content as reference:', storeError);\n }\n } else {\n console.warn('[MCP Adapter] ContentStoreService not available');\n }\n }\n\n return responseText;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n return `Error executing MCP tool ${tool.name}: ${errorMessage}`;\n }\n },\n });\n}\n\n/**\n * Convert JSON Schema to Zod schema\n * This is a simplified converter that handles common cases\n */\nfunction jsonSchemaToZod(schema: unknown): z.ZodTypeAny {\n if (!schema || typeof schema !== 'object') {\n return z.object({});\n }\n\n const schemaObj = schema as Record<string, unknown>;\n\n if (schemaObj.type && schemaObj.type !== 'object') {\n return convertType(schemaObj);\n }\n\n if (!schemaObj.properties || typeof schemaObj.properties !== 'object') {\n return z.object({});\n }\n\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, value] of Object.entries(schemaObj.properties)) {\n let zodType = convertType(value);\n\n const isRequired =\n Array.isArray(schemaObj.required) && schemaObj.required.includes(key);\n if (!isRequired) {\n zodType = zodType.optional();\n }\n\n shape[key] = zodType;\n }\n\n return z.object(shape);\n}\n\n/**\n * Convert a single JSON Schema type to Zod\n */\nfunction convertType(schema: unknown): z.ZodTypeAny {\n if (!schema || typeof schema !== 'object' || !('type' in schema)) {\n return z.unknown();\n }\n\n const schemaObj = schema as {\n type: string;\n enum?: unknown[];\n items?: unknown;\n };\n let zodType: z.ZodTypeAny;\n\n switch (schemaObj.type) {\n case 'string':\n zodType = z.string();\n if (schemaObj.enum && Array.isArray(schemaObj.enum)) {\n zodType = z.enum(schemaObj.enum as [string, ...string[]]);\n }\n break;\n\n case 'number':\n zodType = z.number();\n if ('minimum' in schemaObj && typeof schemaObj.minimum === 'number') {\n zodType = (zodType as z.ZodNumber).min(schemaObj.minimum);\n }\n if ('maximum' in schemaObj && typeof schemaObj.maximum === 'number') {\n zodType = (zodType as z.ZodNumber).max(schemaObj.maximum);\n }\n break;\n\n case 'integer':\n zodType = z.number().int();\n if ('minimum' in schemaObj && typeof schemaObj.minimum === 'number') {\n zodType = (zodType as z.ZodNumber).min(schemaObj.minimum);\n }\n if ('maximum' in schemaObj && typeof schemaObj.maximum === 'number') {\n zodType = (zodType as z.ZodNumber).max(schemaObj.maximum);\n }\n break;\n\n case 'boolean':\n zodType = z.boolean();\n break;\n\n case 'array':\n if (schemaObj.items) {\n zodType = z.array(convertType(schemaObj.items));\n } else {\n zodType = z.array(z.unknown());\n }\n break;\n\n case 'object':\n if ('properties' in schemaObj) {\n zodType = jsonSchemaToZod(schemaObj);\n } else {\n zodType = z.object({}).passthrough();\n }\n break;\n\n default:\n zodType = z.unknown();\n }\n\n if ('description' in schemaObj && typeof schemaObj.description === 'string') {\n zodType = zodType.describe(schemaObj.description);\n }\n\n return zodType;\n}\n"],"names":[],"mappings":";;;AAUO,SAAS,0BACd,MACA,YACA,cACuB;AACvB,QAAM,YAAY,gBAAgB,KAAK,WAAW;AAElD,QAAM,gBAAgB,GAAG,KAAK,UAAU,IAAI,KAAK,IAAI,GAAG;AAAA,IACtD;AAAA,IACA;AAAA,EAAA;AAGF,MAAI,cAAc,KAAK,eAAe,YAAY,KAAK,IAAI,SAAS,KAAK,UAAU;AAEnF,MAAI,cAAc,mBAAmB,KAAK,IAAI,GAAG;AAC/C,kBAAc,GAAG,WAAW;AAAA;AAAA,EAAO,aAAa,iBAAiB,KAAK,IAAI,CAAC;AAAA,EAC7E;AAEA,MAAI,cAAc,mBAAmB;AACnC,kBAAc,GAAG,WAAW;AAAA;AAAA,WAAgB,aAAa,iBAAiB;AAAA,EAC5E;AAEA,SAAO,IAAI,sBAAsB;AAAA,IAC/B,MAAM;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,IACR,MAAM,OAAO,UAAU;AACrB,UAAI;AACF,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,QAAA;AAGF,YAAI,eAAe;AAEnB,YAAI,OAAO,WAAW,UAAU;AAC9B,yBAAe;AAAA,QACjB,WACE,UACA,OAAO,WAAW,YAClB,aAAa,QACb;AACA,gBAAM,UAAW,OAAgC;AACjD,cAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,kBAAM,YAAY,QACf;AAAA,cACC,CAAC,SACC,OAAO,SAAS,YAChB,SAAS,QACT,UAAU,QACV,KAAK,SAAS,UACd,UAAU;AAAA,YAAA,EAEb,IAAI,CAAC,SAAS,KAAK,IAAI;AAC1B,2BAAe,UAAU,KAAK,IAAI;AAAA,UACpC,OAAO;AACL,2BAAe,KAAK,UAAU,OAAO;AAAA,UACvC;AAAA,QACF,OAAO;AACL,yBAAe,KAAK,UAAU,MAAM;AAAA,QACtC;AAGA,cAAM,iBAAiB,OAAO,KAAK,cAAc,MAAM;AACvD,gBAAQ,IAAI,gCAAgC,eAAe,MAAM,iBAAiB,KAAK,UAAU,IAAI,KAAK,IAAI,EAAE;AAGhH,cAAM,0BAA0B,KAAK;AACrC,cAAM,wBAAwB,eAAe,SAAS;AAEtD,YAAI,yBAAyB,mBAAmB,cAAc,GAAG;AAC/D,kBAAQ,IAAI,4CAA4C,eAAe,MAAM,MAAM,uBAAuB,yBAAyB;AACnI,gBAAM,eAAe,oBAAoB,YAAA;AACzC,cAAI,cAAc;AAChB,gBAAI;AACF,oBAAM,cAAc,MAAM,aAAa,aAAa,gBAAgB;AAAA,gBAClE,aAAa;AAAA,gBACb,QAAQ;AAAA,gBACR,aAAa,GAAG,KAAK,UAAU,IAAI,KAAK,IAAI;AAAA,gBAC5C,cAAc,eAAe;AAAA,cAAA,CAC9B;AACD,sBAAQ,IAAI,0DAA0D,WAAW,EAAE;AACnF,qBAAO,eAAe,WAAW;AAAA,YACnC,SAAS,YAAY;AAEnB,sBAAQ,KAAK,mDAAmD,UAAU;AAAA,YAC5E;AAAA,UACF,OAAO;AACL,oBAAQ,KAAK,iDAAiD;AAAA,UAChE;AAAA,QACF;AAEA,eAAO;AAAA,MACT,SAAS,OAAO;AACd,cAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,eAAO,4BAA4B,KAAK,IAAI,KAAK,YAAY;AAAA,MAC/D;AAAA,IACF;AAAA,EAAA,CACD;AACH;AAMA,SAAS,gBAAgB,QAA+B;AACtD,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,WAAO,EAAE,OAAO,EAAE;AAAA,EACpB;AAEA,QAAM,YAAY;AAElB,MAAI,UAAU,QAAQ,UAAU,SAAS,UAAU;AACjD,WAAO,YAAY,SAAS;AAAA,EAC9B;AAEA,MAAI,CAAC,UAAU,cAAc,OAAO,UAAU,eAAe,UAAU;AACrE,WAAO,EAAE,OAAO,EAAE;AAAA,EACpB;AAEA,QAAM,QAAsC,CAAA;AAE5C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,UAAU,GAAG;AAC/D,QAAI,UAAU,YAAY,KAAK;AAE/B,UAAM,aACJ,MAAM,QAAQ,UAAU,QAAQ,KAAK,UAAU,SAAS,SAAS,GAAG;AACtE,QAAI,CAAC,YAAY;AACf,gBAAU,QAAQ,SAAA;AAAA,IACpB;AAEA,UAAM,GAAG,IAAI;AAAA,EACf;AAEA,SAAO,EAAE,OAAO,KAAK;AACvB;AAKA,SAAS,YAAY,QAA+B;AAClD,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,EAAE,UAAU,SAAS;AAChE,WAAO,EAAE,QAAA;AAAA,EACX;AAEA,QAAM,YAAY;AAKlB,MAAI;AAEJ,UAAQ,UAAU,MAAA;AAAA,IAChB,KAAK;AACH,gBAAU,EAAE,OAAA;AACZ,UAAI,UAAU,QAAQ,MAAM,QAAQ,UAAU,IAAI,GAAG;AACnD,kBAAU,EAAE,KAAK,UAAU,IAA6B;AAAA,MAC1D;AACA;AAAA,IAEF,KAAK;AACH,gBAAU,EAAE,OAAA;AACZ,UAAI,aAAa,aAAa,OAAO,UAAU,YAAY,UAAU;AACnE,kBAAW,QAAwB,IAAI,UAAU,OAAO;AAAA,MAC1D;AACA,UAAI,aAAa,aAAa,OAAO,UAAU,YAAY,UAAU;AACnE,kBAAW,QAAwB,IAAI,UAAU,OAAO;AAAA,MAC1D;AACA;AAAA,IAEF,KAAK;AACH,gBAAU,EAAE,OAAA,EAAS,IAAA;AACrB,UAAI,aAAa,aAAa,OAAO,UAAU,YAAY,UAAU;AACnE,kBAAW,QAAwB,IAAI,UAAU,OAAO;AAAA,MAC1D;AACA,UAAI,aAAa,aAAa,OAAO,UAAU,YAAY,UAAU;AACnE,kBAAW,QAAwB,IAAI,UAAU,OAAO;AAAA,MAC1D;AACA;AAAA,IAEF,KAAK;AACH,gBAAU,EAAE,QAAA;AACZ;AAAA,IAEF,KAAK;AACH,UAAI,UAAU,OAAO;AACnB,kBAAU,EAAE,MAAM,YAAY,UAAU,KAAK,CAAC;AAAA,MAChD,OAAO;AACL,kBAAU,EAAE,MAAM,EAAE,QAAA,CAAS;AAAA,MAC/B;AACA;AAAA,IAEF,KAAK;AACH,UAAI,gBAAgB,WAAW;AAC7B,kBAAU,gBAAgB,SAAS;AAAA,MACrC,OAAO;AACL,kBAAU,EAAE,OAAO,CAAA,CAAE,EAAE,YAAA;AAAA,MACzB;AACA;AAAA,IAEF;AACE,gBAAU,EAAE,QAAA;AAAA,EAAQ;AAGxB,MAAI,iBAAiB,aAAa,OAAO,UAAU,gBAAgB,UAAU;AAC3E,cAAU,QAAQ,SAAS,UAAU,WAAW;AAAA,EAClD;AAEA,SAAO;AACT;"}
1
+ {"version":3,"file":"index17.js","sources":["../../src/config/system-message.ts"],"sourcesContent":["export const getSystemMessage = (accountId: string): string => `You are a helpful assistant managing Hashgraph Online HCS-10 connections, messages, HCS-2 registries, and content inscription.\n\nYou have access to tools for:\n- HCS-10: registering agents, finding registered agents, initiating connections, listing active connections, sending messages over connections, and checking for new messages\n- HCS-2: creating registries, registering entries, updating entries, deleting entries, migrating registries, and querying registry contents\n- Inscription: inscribing content from URLs, files, or buffers, creating Hashinal NFTs, and retrieving inscriptions\n\n*** IMPORTANT CONTEXT ***\nYou are currently operating as agent: ${accountId} on the Hashgraph Online network\nWhen users ask about \"my profile\", \"my account\", \"my connections\", etc., use this account ID: ${accountId}\n\nRemember the connection numbers when listing connections, as users might refer to them.`"],"names":[],"mappings":"AAAO,MAAM,mBAAmB,CAAC,cAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wCAQvB,SAAS;AAAA,gGAC+C,SAAS;AAAA;AAAA;"}