@hashgraphonline/conversational-agent 0.1.217 → 0.1.219

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 (288) hide show
  1. package/cli/readme.md +181 -0
  2. package/dist/cjs/constants/entity-references.d.ts +18 -0
  3. package/dist/cjs/constants/form-priorities.d.ts +24 -0
  4. package/dist/cjs/constants/index.d.ts +4 -0
  5. package/dist/cjs/constants/messages.d.ts +19 -0
  6. package/dist/cjs/constants/test-constants.d.ts +42 -0
  7. package/dist/cjs/conversational-agent.d.ts +3 -8
  8. package/dist/{types/core/ToolRegistry.d.ts → cjs/core/tool-registry.d.ts} +11 -1
  9. package/dist/{types/execution/ExecutionPipeline.d.ts → cjs/execution/execution-pipeline.d.ts} +3 -3
  10. package/dist/cjs/forms/field-guidance-registry.d.ts +108 -0
  11. package/dist/cjs/forms/form-generator.d.ts +2 -7
  12. package/dist/cjs/forms/index.d.ts +3 -0
  13. package/dist/cjs/forms/types.d.ts +9 -1
  14. package/dist/cjs/index.cjs +1 -1
  15. package/dist/cjs/index.cjs.map +1 -1
  16. package/dist/cjs/index.d.ts +7 -12
  17. package/dist/cjs/langchain/external-tool-wrapper.d.ts +101 -0
  18. package/dist/{types/langchain/FormAwareAgentExecutor.d.ts → cjs/langchain/form-aware-agent-executor.d.ts} +19 -4
  19. package/dist/cjs/langchain/index.d.ts +3 -0
  20. package/dist/{types → cjs/langchain}/langchain-agent.d.ts +15 -7
  21. package/dist/cjs/mcp/adapters/index.d.ts +1 -0
  22. package/dist/cjs/mcp/adapters/langchain.d.ts +1 -1
  23. package/dist/{types/mcp/ContentProcessor.d.ts → cjs/mcp/content-processor.d.ts} +1 -1
  24. package/dist/cjs/mcp/index.d.ts +5 -0
  25. package/dist/{types/mcp/MCPClientManager.d.ts → cjs/mcp/mcp-client-manager.d.ts} +1 -1
  26. package/dist/cjs/memory/{ContentStorage.d.ts → content-storage.d.ts} +4 -4
  27. package/dist/cjs/memory/index.d.ts +5 -7
  28. package/dist/{types/memory/MemoryWindow.d.ts → cjs/memory/memory-window.d.ts} +1 -1
  29. package/dist/{types/memory/SmartMemoryManager.d.ts → cjs/memory/smart-memory-manager.d.ts} +1 -1
  30. package/dist/cjs/services/{ContentStoreManager.d.ts → content-store-manager.d.ts} +6 -6
  31. package/dist/cjs/services/context/resolution-context.d.ts +49 -0
  32. package/dist/cjs/services/entity-resolver.d.ts +58 -0
  33. package/dist/cjs/services/formatters/converters/index.d.ts +2 -0
  34. package/dist/cjs/services/formatters/converters/string-normalization-converter.d.ts +13 -0
  35. package/dist/cjs/services/formatters/converters/topic-id-to-hrl-converter.d.ts +17 -0
  36. package/dist/cjs/services/formatters/format-converter-registry.d.ts +66 -0
  37. package/dist/cjs/services/formatters/index.d.ts +3 -0
  38. package/dist/cjs/services/formatters/types.d.ts +29 -0
  39. package/dist/cjs/services/index.d.ts +3 -0
  40. package/dist/cjs/services/resolution/resolution-pipeline.d.ts +44 -0
  41. package/dist/cjs/tools/index.d.ts +1 -0
  42. package/dist/cjs/utils/index.d.ts +1 -0
  43. package/dist/esm/index.js +40 -13
  44. package/dist/esm/index.js.map +1 -1
  45. package/dist/esm/index10.js +669 -13
  46. package/dist/esm/index10.js.map +1 -1
  47. package/dist/esm/index11.js +310 -95
  48. package/dist/esm/index11.js.map +1 -1
  49. package/dist/esm/index12.js +130 -95
  50. package/dist/esm/index12.js.map +1 -1
  51. package/dist/esm/index13.js +262 -153
  52. package/dist/esm/index13.js.map +1 -1
  53. package/dist/esm/index14.js +100 -664
  54. package/dist/esm/index14.js.map +1 -1
  55. package/dist/esm/index15.js +135 -408
  56. package/dist/esm/index15.js.map +1 -1
  57. package/dist/esm/index16.js +240 -122
  58. package/dist/esm/index16.js.map +1 -1
  59. package/dist/esm/index17.js +147 -135
  60. package/dist/esm/index17.js.map +1 -1
  61. package/dist/esm/index18.js +376 -533
  62. package/dist/esm/index18.js.map +1 -1
  63. package/dist/esm/index19.js +87 -214
  64. package/dist/esm/index19.js.map +1 -1
  65. package/dist/esm/index2.js +21 -4
  66. package/dist/esm/index2.js.map +1 -1
  67. package/dist/esm/index20.js +158 -92
  68. package/dist/esm/index20.js.map +1 -1
  69. package/dist/esm/index21.js +717 -44
  70. package/dist/esm/index21.js.map +1 -1
  71. package/dist/esm/index22.js +58 -96
  72. package/dist/esm/index22.js.map +1 -1
  73. package/dist/esm/index23.js +324 -34
  74. package/dist/esm/index23.js.map +1 -1
  75. package/dist/esm/index24.js +125 -712
  76. package/dist/esm/index24.js.map +1 -1
  77. package/dist/esm/index25.js +113 -133
  78. package/dist/esm/index25.js.map +1 -1
  79. package/dist/esm/index26.js +18 -152
  80. package/dist/esm/index26.js.map +1 -1
  81. package/dist/esm/index27.js +14 -210
  82. package/dist/esm/index27.js.map +1 -1
  83. package/dist/esm/index28.js +70 -173
  84. package/dist/esm/index28.js.map +1 -1
  85. package/dist/esm/index29.js +882 -220
  86. package/dist/esm/index29.js.map +1 -1
  87. package/dist/esm/index30.js +218 -126
  88. package/dist/esm/index30.js.map +1 -1
  89. package/dist/esm/index31.js +1258 -44
  90. package/dist/esm/index31.js.map +1 -1
  91. package/dist/esm/index32.js +132 -24
  92. package/dist/esm/index32.js.map +1 -1
  93. package/dist/esm/index33.js +104 -82
  94. package/dist/esm/index33.js.map +1 -1
  95. package/dist/esm/index34.js +43 -239
  96. package/dist/esm/index34.js.map +1 -1
  97. package/dist/esm/index35.js +106 -0
  98. package/dist/esm/index35.js.map +1 -0
  99. package/dist/esm/index36.js +24 -0
  100. package/dist/esm/index36.js.map +1 -0
  101. package/dist/esm/index37.js +8 -0
  102. package/dist/esm/index37.js.map +1 -0
  103. package/dist/esm/index38.js +15 -0
  104. package/dist/esm/index38.js.map +1 -0
  105. package/dist/esm/index39.js +258 -0
  106. package/dist/esm/index39.js.map +1 -0
  107. package/dist/esm/index40.js +187 -0
  108. package/dist/esm/index40.js.map +1 -0
  109. package/dist/esm/index41.js +30 -0
  110. package/dist/esm/index41.js.map +1 -0
  111. package/dist/esm/index42.js +10 -0
  112. package/dist/esm/index42.js.map +1 -0
  113. package/dist/esm/index43.js +95 -0
  114. package/dist/esm/index43.js.map +1 -0
  115. package/dist/esm/index5.js +2 -2
  116. package/dist/esm/index5.js.map +1 -1
  117. package/dist/esm/index6.js +44 -67
  118. package/dist/esm/index6.js.map +1 -1
  119. package/dist/esm/index7.js +9 -0
  120. package/dist/esm/index7.js.map +1 -1
  121. package/dist/esm/index8.js +13 -1095
  122. package/dist/esm/index8.js.map +1 -1
  123. package/dist/esm/index9.js +17 -13
  124. package/dist/esm/index9.js.map +1 -1
  125. package/dist/types/constants/entity-references.d.ts +18 -0
  126. package/dist/types/constants/form-priorities.d.ts +24 -0
  127. package/dist/types/constants/index.d.ts +4 -0
  128. package/dist/types/constants/messages.d.ts +19 -0
  129. package/dist/types/constants/test-constants.d.ts +42 -0
  130. package/dist/types/conversational-agent.d.ts +3 -8
  131. package/dist/{cjs/core/ToolRegistry.d.ts → types/core/tool-registry.d.ts} +11 -1
  132. package/dist/{cjs/execution/ExecutionPipeline.d.ts → types/execution/execution-pipeline.d.ts} +3 -3
  133. package/dist/types/forms/field-guidance-registry.d.ts +108 -0
  134. package/dist/types/forms/form-generator.d.ts +2 -7
  135. package/dist/types/forms/index.d.ts +3 -0
  136. package/dist/types/forms/types.d.ts +9 -1
  137. package/dist/types/index.d.ts +7 -12
  138. package/dist/types/langchain/external-tool-wrapper.d.ts +101 -0
  139. package/dist/{cjs/langchain/FormAwareAgentExecutor.d.ts → types/langchain/form-aware-agent-executor.d.ts} +19 -4
  140. package/dist/types/langchain/index.d.ts +3 -0
  141. package/dist/{cjs → types/langchain}/langchain-agent.d.ts +15 -7
  142. package/dist/types/mcp/adapters/index.d.ts +1 -0
  143. package/dist/types/mcp/adapters/langchain.d.ts +1 -1
  144. package/dist/{cjs/mcp/ContentProcessor.d.ts → types/mcp/content-processor.d.ts} +1 -1
  145. package/dist/types/mcp/index.d.ts +5 -0
  146. package/dist/{cjs/mcp/MCPClientManager.d.ts → types/mcp/mcp-client-manager.d.ts} +1 -1
  147. package/dist/types/memory/{ContentStorage.d.ts → content-storage.d.ts} +4 -4
  148. package/dist/types/memory/index.d.ts +5 -7
  149. package/dist/{cjs/memory/MemoryWindow.d.ts → types/memory/memory-window.d.ts} +1 -1
  150. package/dist/{cjs/memory/SmartMemoryManager.d.ts → types/memory/smart-memory-manager.d.ts} +1 -1
  151. package/dist/types/services/{ContentStoreManager.d.ts → content-store-manager.d.ts} +6 -6
  152. package/dist/types/services/context/resolution-context.d.ts +49 -0
  153. package/dist/types/services/entity-resolver.d.ts +58 -0
  154. package/dist/types/services/formatters/converters/index.d.ts +2 -0
  155. package/dist/types/services/formatters/converters/string-normalization-converter.d.ts +13 -0
  156. package/dist/types/services/formatters/converters/topic-id-to-hrl-converter.d.ts +17 -0
  157. package/dist/types/services/formatters/format-converter-registry.d.ts +66 -0
  158. package/dist/types/services/formatters/index.d.ts +3 -0
  159. package/dist/types/services/formatters/types.d.ts +29 -0
  160. package/dist/types/services/index.d.ts +3 -0
  161. package/dist/types/services/resolution/resolution-pipeline.d.ts +44 -0
  162. package/dist/types/tools/index.d.ts +1 -0
  163. package/dist/types/utils/index.d.ts +1 -0
  164. package/package.json +30 -27
  165. package/src/agent-factory.ts +1 -1
  166. package/src/base-agent.ts +9 -0
  167. package/src/config/system-message.ts +2 -15
  168. package/src/constants/entity-references.ts +23 -0
  169. package/src/constants/form-priorities.ts +25 -0
  170. package/src/constants/index.ts +4 -0
  171. package/src/constants/messages.ts +20 -0
  172. package/src/constants/test-constants.ts +49 -0
  173. package/src/conversational-agent.ts +42 -69
  174. package/src/core/{ToolRegistry.ts → tool-registry.ts} +71 -1
  175. package/src/examples/external-tool-wrapper-example.ts +56 -0
  176. package/src/execution/{ExecutionPipeline.ts → execution-pipeline.ts} +3 -3
  177. package/src/forms/field-guidance-registry.ts +415 -0
  178. package/src/forms/field-type-registry.ts +49 -48
  179. package/src/forms/{FormEngine.ts → form-engine.ts} +66 -43
  180. package/src/forms/form-generator.ts +91 -17
  181. package/src/forms/index.ts +4 -1
  182. package/src/forms/types.ts +9 -1
  183. package/src/index.ts +7 -37
  184. package/src/langchain/external-tool-wrapper.ts +90 -0
  185. package/src/langchain/{FormAwareAgentExecutor.ts → form-aware-agent-executor.ts} +615 -231
  186. package/src/langchain/{FormValidatingToolWrapper.ts → form-validating-tool-wrapper.ts} +2 -1
  187. package/src/langchain/index.ts +3 -0
  188. package/src/{langchain-agent.ts → langchain/langchain-agent.ts} +389 -113
  189. package/src/mcp/adapters/index.ts +1 -0
  190. package/src/mcp/adapters/langchain.ts +27 -18
  191. package/src/mcp/{ContentProcessor.ts → content-processor.ts} +71 -47
  192. package/src/mcp/index.ts +5 -0
  193. package/src/mcp/{MCPClientManager.ts → mcp-client-manager.ts} +2 -2
  194. package/src/memory/{ContentStorage.ts → content-storage.ts} +263 -167
  195. package/src/memory/index.ts +5 -8
  196. package/src/memory/{MemoryWindow.ts → memory-window.ts} +47 -24
  197. package/src/memory/{SmartMemoryManager.ts → smart-memory-manager.ts} +49 -22
  198. package/src/plugins/hbar/HbarPlugin.ts +1 -1
  199. package/src/plugins/hcs-10/HCS10Plugin.ts +46 -28
  200. package/src/scripts/test-external-tool-wrapper.ts +6 -6
  201. package/src/scripts/test-inscribe-form-generation.ts +22 -21
  202. package/src/scripts/test-inscribe-wrapper-verification.ts +5 -4
  203. package/src/services/{ContentStoreManager.ts → content-store-manager.ts} +75 -33
  204. package/src/services/context/resolution-context.ts +80 -0
  205. package/src/services/entity-resolver.ts +425 -0
  206. package/src/services/formatters/converters/index.ts +2 -0
  207. package/src/services/formatters/converters/string-normalization-converter.ts +106 -0
  208. package/src/services/formatters/converters/topic-id-to-hrl-converter.ts +25 -0
  209. package/src/services/formatters/format-converter-registry.ts +229 -0
  210. package/src/services/formatters/index.ts +3 -0
  211. package/src/services/formatters/types.ts +31 -0
  212. package/src/services/index.ts +3 -0
  213. package/src/services/resolution/resolution-pipeline.ts +106 -0
  214. package/src/tools/index.ts +1 -0
  215. package/src/types/content-reference.ts +87 -60
  216. package/src/utils/index.ts +1 -0
  217. package/cli/dist/CLIApp.d.ts +0 -9
  218. package/cli/dist/CLIApp.js +0 -127
  219. package/cli/dist/LocalConversationalAgent.d.ts +0 -37
  220. package/cli/dist/LocalConversationalAgent.js +0 -58
  221. package/cli/dist/app.d.ts +0 -16
  222. package/cli/dist/app.js +0 -13
  223. package/cli/dist/cli.d.ts +0 -2
  224. package/cli/dist/cli.js +0 -51
  225. package/cli/dist/components/AppContainer.d.ts +0 -16
  226. package/cli/dist/components/AppContainer.js +0 -24
  227. package/cli/dist/components/AppScreens.d.ts +0 -2
  228. package/cli/dist/components/AppScreens.js +0 -259
  229. package/cli/dist/components/ChatScreen.d.ts +0 -15
  230. package/cli/dist/components/ChatScreen.js +0 -39
  231. package/cli/dist/components/DebugLoadingScreen.d.ts +0 -5
  232. package/cli/dist/components/DebugLoadingScreen.js +0 -31
  233. package/cli/dist/components/LoadingScreen.d.ts +0 -2
  234. package/cli/dist/components/LoadingScreen.js +0 -16
  235. package/cli/dist/components/LoadingScreenDebug.d.ts +0 -5
  236. package/cli/dist/components/LoadingScreenDebug.js +0 -27
  237. package/cli/dist/components/MCPConfigScreen.d.ts +0 -28
  238. package/cli/dist/components/MCPConfigScreen.js +0 -168
  239. package/cli/dist/components/ScreenRouter.d.ts +0 -12
  240. package/cli/dist/components/ScreenRouter.js +0 -22
  241. package/cli/dist/components/SetupScreen.d.ts +0 -15
  242. package/cli/dist/components/SetupScreen.js +0 -65
  243. package/cli/dist/components/SingleLoadingScreen.d.ts +0 -5
  244. package/cli/dist/components/SingleLoadingScreen.js +0 -27
  245. package/cli/dist/components/StatusBadge.d.ts +0 -7
  246. package/cli/dist/components/StatusBadge.js +0 -28
  247. package/cli/dist/components/TerminalWindow.d.ts +0 -8
  248. package/cli/dist/components/TerminalWindow.js +0 -24
  249. package/cli/dist/components/WelcomeScreen.d.ts +0 -11
  250. package/cli/dist/components/WelcomeScreen.js +0 -47
  251. package/cli/dist/context/AppContext.d.ts +0 -68
  252. package/cli/dist/context/AppContext.js +0 -363
  253. package/cli/dist/hooks/useInitializeAgent.d.ts +0 -19
  254. package/cli/dist/hooks/useInitializeAgent.js +0 -28
  255. package/cli/dist/hooks/useStableState.d.ts +0 -38
  256. package/cli/dist/hooks/useStableState.js +0 -68
  257. package/cli/dist/managers/AgentManager.d.ts +0 -57
  258. package/cli/dist/managers/AgentManager.js +0 -119
  259. package/cli/dist/managers/ConfigManager.d.ts +0 -53
  260. package/cli/dist/managers/ConfigManager.js +0 -173
  261. package/cli/dist/types.d.ts +0 -31
  262. package/cli/dist/types.js +0 -19
  263. package/dist/cjs/context/ReferenceContextManager.d.ts +0 -84
  264. package/dist/cjs/context/ReferenceResponseProcessor.d.ts +0 -76
  265. package/dist/cjs/services/EntityResolver.d.ts +0 -26
  266. package/dist/types/context/ReferenceContextManager.d.ts +0 -84
  267. package/dist/types/context/ReferenceResponseProcessor.d.ts +0 -76
  268. package/dist/types/services/EntityResolver.d.ts +0 -26
  269. package/src/context/ReferenceContextManager.ts +0 -350
  270. package/src/context/ReferenceResponseProcessor.ts +0 -295
  271. package/src/scripts/test-hedera-kit-wrapper.ts +0 -265
  272. package/src/services/EntityResolver.ts +0 -128
  273. /package/dist/cjs/forms/{FormEngine.d.ts → form-engine.d.ts} +0 -0
  274. /package/dist/cjs/langchain/{FormValidatingToolWrapper.d.ts → form-validating-tool-wrapper.d.ts} +0 -0
  275. /package/dist/cjs/memory/{ReferenceIdGenerator.d.ts → reference-id-generator.d.ts} +0 -0
  276. /package/dist/cjs/memory/{TokenCounter.d.ts → token-counter.d.ts} +0 -0
  277. /package/dist/cjs/tools/{EntityResolverTool.d.ts → entity-resolver-tool.d.ts} +0 -0
  278. /package/dist/cjs/utils/{ResponseFormatter.d.ts → response-formatter.d.ts} +0 -0
  279. /package/dist/types/forms/{FormEngine.d.ts → form-engine.d.ts} +0 -0
  280. /package/dist/types/langchain/{FormValidatingToolWrapper.d.ts → form-validating-tool-wrapper.d.ts} +0 -0
  281. /package/dist/types/memory/{ReferenceIdGenerator.d.ts → reference-id-generator.d.ts} +0 -0
  282. /package/dist/types/memory/{TokenCounter.d.ts → token-counter.d.ts} +0 -0
  283. /package/dist/types/tools/{EntityResolverTool.d.ts → entity-resolver-tool.d.ts} +0 -0
  284. /package/dist/types/utils/{ResponseFormatter.d.ts → response-formatter.d.ts} +0 -0
  285. /package/src/memory/{ReferenceIdGenerator.ts → reference-id-generator.ts} +0 -0
  286. /package/src/memory/{TokenCounter.ts → token-counter.ts} +0 -0
  287. /package/src/tools/{EntityResolverTool.ts → entity-resolver-tool.ts} +0 -0
  288. /package/src/utils/{ResponseFormatter.ts → response-formatter.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index15.js","sources":["../../src/memory/SmartMemoryManager.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport { Logger } from '@hashgraphonline/standards-sdk';\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/**\n * TODO: investigate using chroma / rag for long term memory\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 private logger: Logger;\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 this.logger = new Logger({ module: 'SmartMemoryManager' });\n\n this.tokenCounter = new TokenCounter(this.config.modelName);\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 * Get the content storage instance for file/content reference operations\n * @returns ContentStorage instance\n */\n get contentStorage(): ContentStorage {\n return this._contentStorage;\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 * 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 * 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 return;\n }\n\n if (\n !entityName ||\n typeof entityName !== 'string' ||\n entityName.trim().length === 0\n ) {\n return;\n }\n\n if (\n !entityType ||\n typeof entityType !== 'string' ||\n entityType.trim().length === 0\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 & { isEntityAssociation: boolean } =\n {\n entityId: sanitizedEntityId,\n entityName: sanitizedEntityName,\n entityType: sanitizedEntityType,\n createdAt: new Date(),\n isEntityAssociation: true,\n ...(transactionId !== undefined &&\n transactionId !== null &&\n 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 BaseMessage]);\n } catch (error) {\n this.logger.error('Failed to store entity association', {\n entityId,\n entityName,\n entityType,\n error: error instanceof Error ? error.message : String(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 return [];\n }\n\n const sanitizedQuery = query.trim();\n if (sanitizedQuery.length === 0) {\n return [];\n }\n\n if (sanitizedQuery.length > 200) {\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 isEntityIdQuery = /^0\\.0\\.\\d+$/.test(sanitizedQuery);\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 if (isEntityIdQuery) {\n if (parsed.entityId !== sanitizedQuery) {\n continue;\n }\n }\n\n associations.push(parsed as EntityAssociation);\n }\n }\n } catch {\n continue;\n }\n }\n\n if (fuzzyMatch && associations.length === 0 && !isEntityIdQuery) {\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 return results;\n } catch (error) {\n this.logger.error('Failed to resolve entity reference', {\n query,\n options,\n error: error instanceof Error ? error.message : String(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 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 this.logger.warn('Failed to parse entity association from message', {\n messageContent: typeof message.content === 'string' ? message.content.substring(0, 100) : 'non-string',\n error: parseError instanceof Error ? parseError.message : String(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 return results;\n } catch (error) {\n this.logger.error('Failed to get entity associations', {\n entityType,\n error: error instanceof Error ? error.message : String(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
+ {"version":3,"file":"index15.js","sources":["../../src/mcp/mcp-client-manager.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/content-storage';\nimport { MCPContentProcessor } from './content-processor';\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,138 +1,256 @@
1
- import { StructuredTool } from "@langchain/core/tools";
2
- import { z } from "zod";
3
- import { ChatOpenAI } from "@langchain/openai";
4
- import { Logger } from "@hashgraphonline/standards-sdk";
5
- const logger = new Logger({ module: "EntityResolverTool" });
6
- const ResolveEntitiesSchema = z.object({
7
- message: z.string().describe("The message containing entity references to resolve"),
8
- entities: z.array(z.object({
9
- entityId: z.string(),
10
- entityName: z.string(),
11
- entityType: z.string()
12
- })).describe("Available entities in memory")
13
- });
14
- const ExtractEntitiesSchema = z.object({
15
- response: z.string().describe("Agent response text to extract entities from"),
16
- userMessage: z.string().describe("Original user message for context")
17
- });
18
- class ResolveEntitiesTool extends StructuredTool {
19
- constructor(apiKey, modelName = "gpt-4o-mini") {
20
- super();
21
- this.name = "resolve_entities";
22
- this.description = 'Resolves entity references like "the topic", "it", "that" to actual entity IDs';
23
- this.schema = ResolveEntitiesSchema;
24
- this.llm = new ChatOpenAI({
25
- apiKey,
26
- modelName,
27
- temperature: 0
28
- });
1
+ class MCPContentProcessor {
2
+ constructor(contentStorage, logger) {
3
+ this.contentStorage = contentStorage;
4
+ this.logger = logger;
29
5
  }
30
- async _call(input) {
31
- const { message, entities } = input;
32
- if (!entities || entities.length === 0) {
33
- return message;
34
- }
35
- const byType = this.groupEntitiesByType(entities);
36
- const context = this.buildEntityContext(byType);
37
- const prompt = `Task: Replace entity references with IDs.
38
-
39
- ${context}
40
-
41
- Message: "${message}"
42
-
43
- Rules:
44
- - "the topic" or "that topic" → replace with most recent topic ID
45
- - "the token" or "that token" → replace with most recent token ID
46
- - "it" or "that" after action verb → replace with most recent entity ID
47
- - "airdrop X" without token ID → add most recent token ID as first parameter
48
- - Token operations without explicit token → use most recent token ID
49
-
50
- Examples:
51
- - "submit on the topic" → "submit on 0.0.6543472"
52
- - "airdrop the token" → "airdrop 0.0.123456"
53
- - "airdrop 10 to 0.0.5842697" → "airdrop 0.0.123456 10 to 0.0.5842697"
54
- - "mint 100" → "mint 0.0.123456 100"
55
-
56
- Return ONLY the resolved message:`;
6
+ analyzeResponse(response) {
7
+ const contents = [];
8
+ let totalSize = 0;
9
+ this.extractContentFromResponse(response, contents);
10
+ totalSize = contents.reduce((sum, content) => sum + content.sizeBytes, 0);
11
+ const largestContentSize = contents.reduce(
12
+ (max, content) => Math.max(max, content.sizeBytes),
13
+ 0
14
+ );
15
+ const shouldProcess = contents.some(
16
+ (content) => this.contentStorage.shouldUseReference(
17
+ typeof content.content === "string" ? content.content : JSON.stringify(content.content)
18
+ )
19
+ );
20
+ return {
21
+ shouldProcess,
22
+ contents,
23
+ totalSize,
24
+ largestContentSize
25
+ };
26
+ }
27
+ async processResponse(response, serverName, toolName) {
57
28
  try {
58
- const response = await this.llm.invoke(prompt);
59
- return response.content.trim();
29
+ const analysis = this.analyzeResponse(response);
30
+ if (!analysis.shouldProcess) {
31
+ return {
32
+ content: response,
33
+ wasProcessed: false
34
+ };
35
+ }
36
+ const processedResponse = await this.createReferencedResponse(
37
+ response,
38
+ analysis,
39
+ serverName,
40
+ toolName
41
+ );
42
+ return processedResponse;
60
43
  } catch (error) {
61
- logger.error("ResolveEntitiesTool failed:", error);
62
- return message;
44
+ this.logger.error("Error processing MCP response:", error);
45
+ return {
46
+ content: response,
47
+ wasProcessed: false,
48
+ errors: [
49
+ error instanceof Error ? error.message : "Unknown processing error"
50
+ ]
51
+ };
63
52
  }
64
53
  }
65
- groupEntitiesByType(entities) {
66
- return entities.reduce((acc, entity) => {
67
- if (!acc[entity.entityType]) {
68
- acc[entity.entityType] = [];
54
+ extractContentFromResponse(obj, contents) {
55
+ if (obj === null || obj === void 0) {
56
+ return;
57
+ }
58
+ if (Array.isArray(obj)) {
59
+ obj.forEach((item) => this.extractContentFromResponse(item, contents));
60
+ return;
61
+ }
62
+ if (typeof obj === "object") {
63
+ const record = obj;
64
+ if (record.type === "text" && typeof record.text === "string") {
65
+ contents.push({
66
+ content: record.text,
67
+ type: "text",
68
+ sizeBytes: Buffer.byteLength(record.text, "utf8"),
69
+ mimeType: this.detectMimeType(record.text)
70
+ });
71
+ return;
72
+ }
73
+ if (record.type === "image" && typeof record.data === "string") {
74
+ contents.push({
75
+ content: record.data,
76
+ type: "image",
77
+ sizeBytes: Math.ceil(record.data.length * 0.75),
78
+ mimeType: record.mimeType || "image/jpeg"
79
+ });
80
+ return;
81
+ }
82
+ if (record.type === "resource" && record.resource) {
83
+ const resourceStr = JSON.stringify(record.resource);
84
+ contents.push({
85
+ content: resourceStr,
86
+ type: "resource",
87
+ sizeBytes: Buffer.byteLength(resourceStr, "utf8"),
88
+ mimeType: "application/json"
89
+ });
90
+ return;
91
+ }
92
+ Object.values(record).forEach(
93
+ (value) => this.extractContentFromResponse(value, contents)
94
+ );
95
+ return;
96
+ }
97
+ if (typeof obj === "string") {
98
+ if (obj.length > 1e3) {
99
+ contents.push({
100
+ content: obj,
101
+ type: "text",
102
+ sizeBytes: Buffer.byteLength(obj, "utf8"),
103
+ mimeType: this.detectMimeType(obj)
104
+ });
69
105
  }
70
- acc[entity.entityType].push(entity);
71
- return acc;
72
- }, {});
106
+ }
73
107
  }
74
- buildEntityContext(groupedEntities) {
75
- let context = "Available entities:\n";
76
- for (const [type, list] of Object.entries(groupedEntities)) {
77
- const recent = list[0];
78
- context += `- Most recent ${type}: "${recent.entityName}" = ${recent.entityId}
79
- `;
80
- }
81
- return context;
108
+ async createReferencedResponse(originalResponse, analysis, serverName, toolName) {
109
+ const processedResponse = this.deepClone(originalResponse);
110
+ const errors = [];
111
+ let referenceCreated = false;
112
+ let totalReferenceSize = 0;
113
+ for (const contentInfo of analysis.contents) {
114
+ if (this.contentStorage.shouldUseReference(
115
+ typeof contentInfo.content === "string" ? contentInfo.content : JSON.stringify(contentInfo.content)
116
+ )) {
117
+ try {
118
+ const contentBuffer = Buffer.from(
119
+ typeof contentInfo.content === "string" ? contentInfo.content : JSON.stringify(contentInfo.content),
120
+ "utf8"
121
+ );
122
+ const contentType = this.mapMimeTypeToContentType(
123
+ contentInfo.mimeType
124
+ );
125
+ const metadata = {
126
+ contentType,
127
+ source: "mcp_tool",
128
+ mcpToolName: `${serverName}::${toolName}`,
129
+ tags: ["mcp_response", serverName, toolName]
130
+ };
131
+ if (contentInfo.mimeType !== void 0) {
132
+ metadata.mimeType = contentInfo.mimeType;
133
+ }
134
+ const reference = await this.contentStorage.storeContentIfLarge(
135
+ contentBuffer,
136
+ metadata
137
+ );
138
+ if (reference) {
139
+ this.replaceContentInResponse(
140
+ processedResponse,
141
+ contentInfo.content,
142
+ this.createLightweightReference(reference)
143
+ );
144
+ referenceCreated = true;
145
+ totalReferenceSize += contentBuffer.length;
146
+ }
147
+ } catch (error) {
148
+ errors.push(
149
+ `Failed to create reference: ${error instanceof Error ? error.message : "Unknown error"}`
150
+ );
151
+ }
152
+ }
153
+ }
154
+ const result = {
155
+ content: processedResponse,
156
+ wasProcessed: true,
157
+ referenceCreated,
158
+ originalSize: totalReferenceSize
159
+ };
160
+ if (errors.length > 0) {
161
+ result.errors = errors;
162
+ }
163
+ return result;
82
164
  }
83
- }
84
- class ExtractEntitiesTool extends StructuredTool {
85
- constructor(apiKey, modelName = "gpt-4o-mini") {
86
- super();
87
- this.name = "extract_entities";
88
- this.description = "Extracts newly created entities from agent responses";
89
- this.schema = ExtractEntitiesSchema;
90
- this.llm = new ChatOpenAI({
91
- apiKey,
92
- modelName,
93
- temperature: 0
94
- });
165
+ createLightweightReference(reference) {
166
+ return {
167
+ type: "content_reference",
168
+ referenceId: reference.referenceId,
169
+ preview: reference.preview,
170
+ size: reference.metadata.sizeBytes,
171
+ contentType: reference.metadata.contentType,
172
+ format: "ref://{id}",
173
+ _isReference: true
174
+ };
95
175
  }
96
- async _call(input) {
97
- const { response, userMessage } = input;
98
- const prompt = `Extract ONLY newly created entities from this response.
99
-
100
- User asked: "${userMessage.substring(0, 200)}"
101
- Response: ${response.substring(0, 3e3)}
102
-
103
- Look for:
104
- - Success messages with new entity IDs
105
- - Words like "created", "new", "successfully" followed by entity IDs
106
-
107
- Return JSON array of created entities:
108
- [{"id": "0.0.XXX", "name": "name", "type": "topic|token|account"}]
109
-
110
- If none created, return: []
111
-
112
- JSON:`;
113
- try {
114
- const llmResponse = await this.llm.invoke(prompt);
115
- const content = llmResponse.content;
116
- const match = content.match(/\[[\s\S]*?\]/);
117
- if (match) {
118
- return match[0];
176
+ replaceContentInResponse(obj, oldContent, newContent) {
177
+ if (obj === null || obj === void 0) {
178
+ return;
179
+ }
180
+ if (Array.isArray(obj)) {
181
+ for (let i = 0; i < obj.length; i++) {
182
+ if (obj[i] === oldContent) {
183
+ obj[i] = newContent;
184
+ } else {
185
+ this.replaceContentInResponse(obj[i], oldContent, newContent);
186
+ }
187
+ }
188
+ return;
189
+ }
190
+ if (typeof obj === "object") {
191
+ const record = obj;
192
+ if (record.type === "text" && record.text === oldContent) {
193
+ for (const key of Object.keys(record)) {
194
+ delete record[key];
195
+ }
196
+ if (typeof newContent === "object" && newContent !== null) {
197
+ const newContentRecord = newContent;
198
+ for (const key of Object.keys(newContentRecord)) {
199
+ record[key] = newContentRecord[key];
200
+ }
201
+ }
202
+ return;
203
+ }
204
+ for (const key in record) {
205
+ if (record[key] === oldContent) {
206
+ record[key] = newContent;
207
+ } else {
208
+ this.replaceContentInResponse(record[key], oldContent, newContent);
209
+ }
119
210
  }
120
- return "[]";
121
- } catch (error) {
122
- logger.error("ExtractEntitiesTool failed:", error);
123
- return "[]";
124
211
  }
125
212
  }
126
- }
127
- function createEntityTools(apiKey, modelName = "gpt-4o-mini") {
128
- return {
129
- resolveEntities: new ResolveEntitiesTool(apiKey, modelName),
130
- extractEntities: new ExtractEntitiesTool(apiKey, modelName)
131
- };
213
+ detectMimeType(content) {
214
+ if (content.trim().startsWith("{") || content.trim().startsWith("[")) {
215
+ return "application/json";
216
+ }
217
+ if (content.includes("<html>") || content.includes("<!DOCTYPE")) {
218
+ return "text/html";
219
+ }
220
+ if (content.includes("# ") || content.includes("## ")) {
221
+ return "text/markdown";
222
+ }
223
+ return "text/plain";
224
+ }
225
+ mapMimeTypeToContentType(mimeType) {
226
+ if (!mimeType) return "text";
227
+ if (mimeType.startsWith("text/plain")) return "text";
228
+ if (mimeType === "application/json") return "json";
229
+ if (mimeType === "text/html") return "html";
230
+ if (mimeType === "text/markdown") return "markdown";
231
+ if (mimeType.startsWith("text/")) return "text";
232
+ return "binary";
233
+ }
234
+ deepClone(obj) {
235
+ if (obj === null || typeof obj !== "object") {
236
+ return obj;
237
+ }
238
+ if (obj instanceof Date) {
239
+ return new Date(obj.getTime());
240
+ }
241
+ if (Array.isArray(obj)) {
242
+ return obj.map((item) => this.deepClone(item));
243
+ }
244
+ const cloned = {};
245
+ for (const key in obj) {
246
+ if (obj.hasOwnProperty(key)) {
247
+ cloned[key] = this.deepClone(obj[key]);
248
+ }
249
+ }
250
+ return cloned;
251
+ }
132
252
  }
133
253
  export {
134
- ExtractEntitiesTool,
135
- ResolveEntitiesTool,
136
- createEntityTools
254
+ MCPContentProcessor
137
255
  };
138
256
  //# sourceMappingURL=index16.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index16.js","sources":["../../src/tools/EntityResolverTool.ts"],"sourcesContent":["import { StructuredTool } from '@langchain/core/tools';\nimport { z } from 'zod';\nimport { ChatOpenAI } from '@langchain/openai';\nimport { Logger } from '@hashgraphonline/standards-sdk';\n\nconst logger = new Logger({ module: 'EntityResolverTool' });\n\nconst ResolveEntitiesSchema = z.object({\n message: z.string().describe('The message containing entity references to resolve'),\n entities: z.array(z.object({\n entityId: z.string(),\n entityName: z.string(),\n entityType: z.string(),\n })).describe('Available entities in memory'),\n});\n\nconst ExtractEntitiesSchema = z.object({\n response: z.string().describe('Agent response text to extract entities from'),\n userMessage: z.string().describe('Original user message for context'),\n});\n\nexport class ResolveEntitiesTool extends StructuredTool {\n name = 'resolve_entities';\n description = 'Resolves entity references like \"the topic\", \"it\", \"that\" to actual entity IDs';\n schema = ResolveEntitiesSchema;\n \n private llm: ChatOpenAI;\n \n constructor(apiKey: string, modelName = 'gpt-4o-mini') {\n super();\n this.llm = new ChatOpenAI({\n apiKey,\n modelName,\n temperature: 0,\n });\n }\n \n async _call(input: z.infer<typeof ResolveEntitiesSchema>): Promise<string> {\n const { message, entities } = input;\n \n if (!entities || entities.length === 0) {\n return message;\n }\n \n const byType = this.groupEntitiesByType(entities);\n const context = this.buildEntityContext(byType);\n \n const prompt = `Task: Replace entity references with IDs.\n\n${context}\n\nMessage: \"${message}\"\n\nRules:\n- \"the topic\" or \"that topic\" → replace with most recent topic ID\n- \"the token\" or \"that token\" → replace with most recent token ID\n- \"it\" or \"that\" after action verb → replace with most recent entity ID\n- \"airdrop X\" without token ID → add most recent token ID as first parameter\n- Token operations without explicit token → use most recent token ID\n\nExamples:\n- \"submit on the topic\" → \"submit on 0.0.6543472\"\n- \"airdrop the token\" → \"airdrop 0.0.123456\"\n- \"airdrop 10 to 0.0.5842697\" → \"airdrop 0.0.123456 10 to 0.0.5842697\"\n- \"mint 100\" → \"mint 0.0.123456 100\"\n\nReturn ONLY the resolved message:`;\n \n try {\n const response = await this.llm.invoke(prompt);\n return (response.content as string).trim();\n } catch (error) {\n logger.error('ResolveEntitiesTool failed:', error);\n return message;\n }\n }\n \n private groupEntitiesByType(entities: EntityGroup): GroupedEntities {\n return entities.reduce((acc, entity) => {\n if (!acc[entity.entityType]) {\n acc[entity.entityType] = [];\n }\n acc[entity.entityType].push(entity);\n return acc;\n }, {} as GroupedEntities);\n }\n \n private buildEntityContext(groupedEntities: GroupedEntities): string {\n let context = 'Available entities:\\n';\n for (const [type, list] of Object.entries(groupedEntities)) {\n const recent = list[0];\n context += `- Most recent ${type}: \"${recent.entityName}\" = ${recent.entityId}\\n`;\n }\n return context;\n }\n}\n\nexport class ExtractEntitiesTool extends StructuredTool {\n name = 'extract_entities';\n description = 'Extracts newly created entities from agent responses';\n schema = ExtractEntitiesSchema;\n \n private llm: ChatOpenAI;\n \n constructor(apiKey: string, modelName = 'gpt-4o-mini') {\n super();\n this.llm = new ChatOpenAI({\n apiKey,\n modelName,\n temperature: 0,\n });\n }\n \n async _call(input: z.infer<typeof ExtractEntitiesSchema>): Promise<string> {\n const { response, userMessage } = input;\n \n const prompt = `Extract ONLY newly created entities from this response.\n\nUser asked: \"${userMessage.substring(0, 200)}\"\nResponse: ${response.substring(0, 3000)}\n\nLook for:\n- Success messages with new entity IDs\n- Words like \"created\", \"new\", \"successfully\" followed by entity IDs\n\nReturn JSON array of created entities:\n[{\"id\": \"0.0.XXX\", \"name\": \"name\", \"type\": \"topic|token|account\"}]\n\nIf none created, return: []\n\nJSON:`;\n \n try {\n const llmResponse = await this.llm.invoke(prompt);\n const content = llmResponse.content as string;\n const match = content.match(/\\[[\\s\\S]*?\\]/);\n if (match) {\n return match[0];\n }\n return '[]';\n } catch (error) {\n logger.error('ExtractEntitiesTool failed:', error);\n return '[]';\n }\n }\n}\n\nexport function createEntityTools(apiKey: string, modelName = 'gpt-4o-mini'): {\n resolveEntities: ResolveEntitiesTool;\n extractEntities: ExtractEntitiesTool;\n} {\n return {\n resolveEntities: new ResolveEntitiesTool(apiKey, modelName),\n extractEntities: new ExtractEntitiesTool(apiKey, modelName),\n };\n}\n\ninterface EntityReference {\n entityId: string;\n entityName: string;\n entityType: string;\n}\n\ntype EntityGroup = EntityReference[];\n\ntype GroupedEntities = Record<string, EntityGroup>;\n\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index16.js","sources":["../../src/mcp/content-processor.ts"],"sourcesContent":["import type { ContentType, ContentSource } from '../types/content-reference';\nimport type { ContentStorage } from '../memory/content-storage';\nimport { Logger } from '@hashgraphonline/standards-sdk';\n\nexport interface MCPResponseContent {\n content: unknown;\n type: 'text' | 'image' | 'resource' | 'text[]' | 'image[]';\n sizeBytes: number;\n mimeType?: string;\n}\n\nexport interface ProcessedResponse {\n content: unknown;\n wasProcessed: boolean;\n referenceCreated?: boolean;\n referenceId?: string;\n originalSize?: number;\n errors?: string[];\n}\n\n/**\n * Content reference interface\n */\ninterface ContentReference {\n referenceId: string;\n preview?: string;\n metadata: {\n sizeBytes: number;\n contentType?: string;\n [key: string]: unknown;\n };\n}\n\nexport interface ContentAnalysis {\n shouldProcess: boolean;\n contents: MCPResponseContent[];\n totalSize: number;\n largestContentSize: number;\n}\n\nexport class MCPContentProcessor {\n private contentStorage: ContentStorage;\n private logger: Logger;\n\n constructor(contentStorage: ContentStorage, logger: Logger) {\n this.contentStorage = contentStorage;\n this.logger = logger;\n }\n\n analyzeResponse(response: unknown): ContentAnalysis {\n const contents: MCPResponseContent[] = [];\n let totalSize = 0;\n\n this.extractContentFromResponse(response, contents);\n\n totalSize = contents.reduce((sum, content) => sum + content.sizeBytes, 0);\n const largestContentSize = contents.reduce(\n (max, content) => Math.max(max, content.sizeBytes),\n 0\n );\n\n const shouldProcess = contents.some((content) =>\n this.contentStorage.shouldUseReference(\n typeof content.content === 'string'\n ? content.content\n : JSON.stringify(content.content)\n )\n );\n\n return {\n shouldProcess,\n contents,\n totalSize,\n largestContentSize,\n };\n }\n\n async processResponse(\n response: unknown,\n serverName: string,\n toolName: string\n ): Promise<ProcessedResponse> {\n try {\n const analysis = this.analyzeResponse(response);\n\n if (!analysis.shouldProcess) {\n return {\n content: response,\n wasProcessed: false,\n };\n }\n\n const processedResponse = await this.createReferencedResponse(\n response,\n analysis,\n serverName,\n toolName\n );\n\n return processedResponse;\n } catch (error) {\n this.logger.error('Error processing MCP response:', error);\n return {\n content: response,\n wasProcessed: false,\n errors: [\n error instanceof Error ? error.message : 'Unknown processing error',\n ],\n };\n }\n }\n\n private extractContentFromResponse(\n obj: unknown,\n contents: MCPResponseContent[]\n ): void {\n if (obj === null || obj === undefined) {\n return;\n }\n\n if (Array.isArray(obj)) {\n obj.forEach((item) => this.extractContentFromResponse(item, contents));\n return;\n }\n\n if (typeof obj === 'object') {\n const record = obj as Record<string, unknown>;\n\n if (record.type === 'text' && typeof record.text === 'string') {\n contents.push({\n content: record.text,\n type: 'text',\n sizeBytes: Buffer.byteLength(record.text, 'utf8'),\n mimeType: this.detectMimeType(record.text as string),\n });\n return;\n }\n\n if (record.type === 'image' && typeof record.data === 'string') {\n contents.push({\n content: record.data,\n type: 'image',\n sizeBytes: Math.ceil(record.data.length * 0.75),\n mimeType: (record.mimeType as string) || 'image/jpeg',\n });\n return;\n }\n\n if (record.type === 'resource' && record.resource) {\n const resourceStr = JSON.stringify(record.resource);\n contents.push({\n content: resourceStr,\n type: 'resource',\n sizeBytes: Buffer.byteLength(resourceStr, 'utf8'),\n mimeType: 'application/json',\n });\n return;\n }\n\n Object.values(record).forEach((value) =>\n this.extractContentFromResponse(value, contents)\n );\n return;\n }\n\n if (typeof obj === 'string') {\n if (obj.length > 1000) {\n contents.push({\n content: obj,\n type: 'text',\n sizeBytes: Buffer.byteLength(obj, 'utf8'),\n mimeType: this.detectMimeType(obj),\n });\n }\n }\n }\n\n private async createReferencedResponse(\n originalResponse: unknown,\n analysis: ContentAnalysis,\n serverName: string,\n toolName: string\n ): Promise<ProcessedResponse> {\n const processedResponse = this.deepClone(originalResponse);\n const errors: string[] = [];\n let referenceCreated = false;\n let totalReferenceSize = 0;\n\n for (const contentInfo of analysis.contents) {\n if (\n this.contentStorage.shouldUseReference(\n typeof contentInfo.content === 'string'\n ? contentInfo.content\n : JSON.stringify(contentInfo.content)\n )\n ) {\n try {\n const contentBuffer = Buffer.from(\n typeof contentInfo.content === 'string'\n ? contentInfo.content\n : JSON.stringify(contentInfo.content),\n 'utf8'\n );\n\n const contentType = this.mapMimeTypeToContentType(\n contentInfo.mimeType\n );\n\n const metadata: Parameters<\n typeof this.contentStorage.storeContentIfLarge\n >[1] = {\n contentType,\n source: 'mcp_tool' as ContentSource,\n mcpToolName: `${serverName}::${toolName}`,\n tags: ['mcp_response', serverName, toolName],\n };\n\n if (contentInfo.mimeType !== undefined) {\n metadata.mimeType = contentInfo.mimeType;\n }\n\n const reference = await this.contentStorage.storeContentIfLarge(\n contentBuffer,\n metadata\n );\n\n if (reference) {\n this.replaceContentInResponse(\n processedResponse,\n contentInfo.content,\n this.createLightweightReference(reference)\n );\n referenceCreated = true;\n totalReferenceSize += contentBuffer.length;\n }\n } catch (error) {\n errors.push(\n `Failed to create reference: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n }\n\n const result: ProcessedResponse = {\n content: processedResponse,\n wasProcessed: true,\n referenceCreated,\n originalSize: totalReferenceSize,\n };\n\n if (errors.length > 0) {\n result.errors = errors;\n }\n\n return result;\n }\n\n private createLightweightReference(\n reference: ContentReference\n ): Record<string, unknown> {\n return {\n type: 'content_reference',\n referenceId: reference.referenceId,\n preview: reference.preview,\n size: reference.metadata.sizeBytes,\n contentType: reference.metadata.contentType,\n format: 'ref://{id}',\n _isReference: true,\n };\n }\n\n private replaceContentInResponse(\n obj: unknown,\n oldContent: unknown,\n newContent: unknown\n ): void {\n if (obj === null || obj === undefined) {\n return;\n }\n\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n if (obj[i] === oldContent) {\n obj[i] = newContent;\n } else {\n this.replaceContentInResponse(obj[i], oldContent, newContent);\n }\n }\n return;\n }\n\n if (typeof obj === 'object') {\n const record = obj as Record<string, unknown>;\n if (record.type === 'text' && record.text === oldContent) {\n for (const key of Object.keys(record)) {\n delete record[key];\n }\n if (typeof newContent === 'object' && newContent !== null) {\n const newContentRecord = newContent as Record<string, unknown>;\n for (const key of Object.keys(newContentRecord)) {\n record[key] = newContentRecord[key];\n }\n }\n return;\n }\n for (const key in record) {\n if (record[key] === oldContent) {\n record[key] = newContent;\n } else {\n this.replaceContentInResponse(record[key], oldContent, newContent);\n }\n }\n }\n }\n\n private detectMimeType(content: string): string {\n if (content.trim().startsWith('{') || content.trim().startsWith('[')) {\n return 'application/json';\n }\n if (content.includes('<html>') || content.includes('<!DOCTYPE')) {\n return 'text/html';\n }\n if (content.includes('# ') || content.includes('## ')) {\n return 'text/markdown';\n }\n return 'text/plain';\n }\n\n private mapMimeTypeToContentType(mimeType?: string): ContentType {\n if (!mimeType) return 'text';\n\n if (mimeType.startsWith('text/plain')) return 'text';\n if (mimeType === 'application/json') return 'json';\n if (mimeType === 'text/html') return 'html';\n if (mimeType === 'text/markdown') return 'markdown';\n if (mimeType.startsWith('text/')) return 'text';\n\n return 'binary';\n }\n\n private deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => this.deepClone(item)) as T;\n }\n\n const cloned = {} as T;\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n cloned[key] = this.deepClone(obj[key]);\n }\n }\n\n return cloned;\n }\n}\n"],"names":[],"mappings":"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"}