@hashgraphonline/conversational-agent 0.1.208 → 0.1.210

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 (117) hide show
  1. package/bin/conversational-agent-cli.js +30 -0
  2. package/cli/readme.md +181 -0
  3. package/dist/cjs/base-agent.d.ts +3 -1
  4. package/dist/cjs/conversational-agent.d.ts +64 -13
  5. package/dist/cjs/index.cjs +1 -1
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs/index.d.ts +6 -3
  8. package/dist/cjs/langchain-agent.d.ts +11 -0
  9. package/dist/cjs/memory/SmartMemoryManager.d.ts +65 -22
  10. package/dist/cjs/memory/TokenCounter.d.ts +1 -1
  11. package/dist/cjs/memory/index.d.ts +1 -1
  12. package/dist/cjs/plugins/hbar/AirdropToolWrapper.d.ts +43 -0
  13. package/dist/{types/plugins/hbar-transfer/HbarTransferPlugin.d.ts → cjs/plugins/hbar/HbarPlugin.d.ts} +2 -1
  14. package/dist/{types/plugins/hbar-transfer → cjs/plugins/hbar}/TransferHbarTool.d.ts +1 -1
  15. package/dist/cjs/plugins/hbar/index.d.ts +3 -0
  16. package/dist/cjs/plugins/index.d.ts +2 -1
  17. package/dist/cjs/services/EntityResolver.d.ts +26 -0
  18. package/dist/cjs/tools/EntityResolverTool.d.ts +104 -0
  19. package/dist/cjs/types/inscription.d.ts +37 -0
  20. package/dist/esm/index.js +16 -2
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/index12.js +121 -46
  23. package/dist/esm/index12.js.map +1 -1
  24. package/dist/esm/index13.js +177 -13
  25. package/dist/esm/index13.js.map +1 -1
  26. package/dist/esm/index14.js +599 -100
  27. package/dist/esm/index14.js.map +1 -1
  28. package/dist/esm/index15.js +426 -9
  29. package/dist/esm/index15.js.map +1 -1
  30. package/dist/esm/index16.js +119 -160
  31. package/dist/esm/index16.js.map +1 -1
  32. package/dist/esm/index17.js +140 -150
  33. package/dist/esm/index17.js.map +1 -1
  34. package/dist/esm/index18.js +44 -231
  35. package/dist/esm/index18.js.map +1 -1
  36. package/dist/esm/index19.js +86 -643
  37. package/dist/esm/index19.js.map +1 -1
  38. package/dist/esm/index2.js +22 -13
  39. package/dist/esm/index2.js.map +1 -1
  40. package/dist/esm/index20.js +20 -230
  41. package/dist/esm/index20.js.map +1 -1
  42. package/dist/esm/index21.js +9 -179
  43. package/dist/esm/index21.js.map +1 -1
  44. package/dist/esm/index22.js +140 -89
  45. package/dist/esm/index22.js.map +1 -1
  46. package/dist/esm/index23.js +141 -81
  47. package/dist/esm/index23.js.map +1 -1
  48. package/dist/esm/index24.js +4 -4
  49. package/dist/esm/index24.js.map +1 -1
  50. package/dist/esm/index25.js +0 -8
  51. package/dist/esm/index25.js.map +1 -1
  52. package/dist/esm/index26.js +95 -0
  53. package/dist/esm/index26.js.map +1 -0
  54. package/dist/esm/index27.js +242 -0
  55. package/dist/esm/index27.js.map +1 -0
  56. package/dist/esm/index5.js +32 -19
  57. package/dist/esm/index5.js.map +1 -1
  58. package/dist/esm/index6.js +276 -37
  59. package/dist/esm/index6.js.map +1 -1
  60. package/dist/esm/index7.js +2 -2
  61. package/dist/esm/index7.js.map +1 -1
  62. package/dist/esm/index8.js +124 -18
  63. package/dist/esm/index8.js.map +1 -1
  64. package/dist/types/base-agent.d.ts +3 -1
  65. package/dist/types/conversational-agent.d.ts +64 -13
  66. package/dist/types/index.d.ts +6 -3
  67. package/dist/types/langchain-agent.d.ts +11 -0
  68. package/dist/types/memory/SmartMemoryManager.d.ts +65 -22
  69. package/dist/types/memory/TokenCounter.d.ts +1 -1
  70. package/dist/types/memory/index.d.ts +1 -1
  71. package/dist/types/plugins/hbar/AirdropToolWrapper.d.ts +43 -0
  72. package/dist/{cjs/plugins/hbar-transfer/HbarTransferPlugin.d.ts → types/plugins/hbar/HbarPlugin.d.ts} +2 -1
  73. package/dist/{cjs/plugins/hbar-transfer → types/plugins/hbar}/TransferHbarTool.d.ts +1 -1
  74. package/dist/types/plugins/hbar/index.d.ts +3 -0
  75. package/dist/types/plugins/index.d.ts +2 -1
  76. package/dist/types/services/EntityResolver.d.ts +26 -0
  77. package/dist/types/tools/EntityResolverTool.d.ts +104 -0
  78. package/dist/types/types/inscription.d.ts +37 -0
  79. package/package.json +13 -4
  80. package/src/base-agent.ts +14 -9
  81. package/src/config/system-message.ts +11 -2
  82. package/src/context/ReferenceContextManager.ts +10 -5
  83. package/src/context/ReferenceResponseProcessor.ts +3 -4
  84. package/src/conversational-agent.ts +372 -57
  85. package/src/index.ts +19 -3
  86. package/src/langchain/ContentAwareAgentExecutor.ts +0 -1
  87. package/src/langchain-agent.ts +168 -33
  88. package/src/mcp/ContentProcessor.ts +11 -3
  89. package/src/mcp/adapters/langchain.ts +1 -10
  90. package/src/memory/ContentStorage.ts +2 -55
  91. package/src/memory/MemoryWindow.ts +4 -17
  92. package/src/memory/ReferenceIdGenerator.ts +4 -8
  93. package/src/memory/SmartMemoryManager.ts +375 -47
  94. package/src/memory/TokenCounter.ts +15 -22
  95. package/src/memory/index.ts +1 -1
  96. package/src/plugins/hbar/AirdropToolWrapper.ts +157 -0
  97. package/src/plugins/hbar/HbarPlugin.ts +86 -0
  98. package/src/plugins/{hbar-transfer → hbar}/TransferHbarTool.ts +3 -3
  99. package/src/plugins/hbar/index.ts +3 -0
  100. package/src/plugins/hcs-10/HCS10Plugin.ts +44 -14
  101. package/src/plugins/index.ts +2 -1
  102. package/src/services/ContentStoreManager.ts +0 -3
  103. package/src/services/EntityResolver.ts +135 -0
  104. package/src/tools/EntityResolverTool.ts +170 -0
  105. package/src/types/content-reference.ts +8 -8
  106. package/src/types/index.ts +0 -1
  107. package/src/types/inscription.ts +40 -0
  108. package/dist/cjs/plugins/hbar-transfer/index.d.ts +0 -1
  109. package/dist/types/plugins/hbar-transfer/index.d.ts +0 -1
  110. package/src/plugins/hbar-transfer/HbarTransferPlugin.ts +0 -66
  111. package/src/plugins/hbar-transfer/index.ts +0 -1
  112. /package/dist/cjs/plugins/{hbar-transfer → hbar}/AccountBuilder.d.ts +0 -0
  113. /package/dist/cjs/plugins/{hbar-transfer → hbar}/types.d.ts +0 -0
  114. /package/dist/types/plugins/{hbar-transfer → hbar}/AccountBuilder.d.ts +0 -0
  115. /package/dist/types/plugins/{hbar-transfer → hbar}/types.d.ts +0 -0
  116. /package/src/plugins/{hbar-transfer → hbar}/AccountBuilder.ts +0 -0
  117. /package/src/plugins/{hbar-transfer → hbar}/types.ts +0 -0
@@ -12,18 +12,39 @@ import { createAgent } from './agent-factory';
12
12
  import { LangChainProvider } from './providers';
13
13
  import type { ChatResponse, ConversationContext } from './base-agent';
14
14
  import { ChatOpenAI } from '@langchain/openai';
15
+ import { ChatAnthropic } from '@langchain/anthropic';
15
16
  import { HumanMessage, AIMessage } from '@langchain/core/messages';
16
17
  import type { AgentOperationalMode, MirrorNodeConfig } from 'hedera-agent-kit';
17
18
  import { HCS10Plugin } from './plugins/hcs-10/HCS10Plugin';
18
19
  import { HCS2Plugin } from './plugins/hcs-2/HCS2Plugin';
19
20
  import { InscribePlugin } from './plugins/inscribe/InscribePlugin';
20
- import { HbarTransferPlugin } from './plugins/hbar-transfer/HbarTransferPlugin';
21
+ import { HbarPlugin } from './plugins/hbar/HbarPlugin';
21
22
  import { OpenConvaiState } from '@hashgraphonline/standards-agent-kit';
22
23
  import type { IStateManager } from '@hashgraphonline/standards-agent-kit';
23
24
  import { PrivateKey } from '@hashgraph/sdk';
24
25
  import { getSystemMessage } from './config/system-message';
25
- import type { MCPServerConfig } from './mcp/types';
26
+ import type { MCPServerConfig, MCPConnectionStatus } from './mcp/types';
26
27
  import { ContentStoreManager } from './services/ContentStoreManager';
28
+ import { SmartMemoryManager, type SmartMemoryConfig } from './memory';
29
+ import {
30
+ createEntityTools,
31
+ ResolveEntitiesTool,
32
+ ExtractEntitiesTool,
33
+ } from './tools/EntityResolverTool';
34
+
35
+ export type ToolDescriptor = {
36
+ name: string;
37
+ namespace?: string;
38
+ };
39
+
40
+ export type ChatHistoryItem = {
41
+ type: 'human' | 'ai';
42
+ content: string;
43
+ };
44
+
45
+ export type AgentInstance = ReturnType<typeof createAgent>;
46
+
47
+ export type MirrorNetwork = 'testnet' | 'mainnet' | 'previewnet';
27
48
 
28
49
  const DEFAULT_MODEL_NAME = 'gpt-4o';
29
50
  const DEFAULT_TEMPERATURE = 0.1;
@@ -36,6 +57,7 @@ export interface ConversationalAgentOptions {
36
57
  network?: NetworkType;
37
58
  openAIApiKey: string;
38
59
  openAIModelName?: string;
60
+ llmProvider?: 'openai' | 'anthropic';
39
61
  verbose?: boolean;
40
62
  operationalMode?: AgentOperationalMode;
41
63
  userAccountId?: string;
@@ -49,6 +71,12 @@ export interface ConversationalAgentOptions {
49
71
  enabledPlugins?: string[];
50
72
  toolFilter?: (tool: { name: string; namespace?: string }) => boolean;
51
73
  mcpServers?: MCPServerConfig[];
74
+
75
+ /** Enable automatic entity memory functionality (default: true) */
76
+ entityMemoryEnabled?: boolean;
77
+
78
+ /** Configuration for entity memory system */
79
+ entityMemoryConfig?: SmartMemoryConfig;
52
80
  }
53
81
 
54
82
  /**
@@ -61,15 +89,20 @@ export interface ConversationalAgentOptions {
61
89
  * @returns A new instance of the ConversationalAgent class.
62
90
  */
63
91
  export class ConversationalAgent {
64
- private agent?: ReturnType<typeof createAgent>;
92
+ protected agent?: AgentInstance;
65
93
  public hcs10Plugin: HCS10Plugin;
66
94
  public hcs2Plugin: HCS2Plugin;
67
95
  public inscribePlugin: InscribePlugin;
68
- public hbarTransferPlugin: HbarTransferPlugin;
96
+ public hbarPlugin: HbarPlugin;
69
97
  public stateManager: IStateManager;
70
98
  private options: ConversationalAgentOptions;
71
- private logger: Logger;
72
- private contentStoreManager?: ContentStoreManager;
99
+ public logger: Logger;
100
+ protected contentStoreManager?: ContentStoreManager;
101
+ public memoryManager?: SmartMemoryManager | undefined;
102
+ private entityTools?: {
103
+ resolveEntities: ResolveEntitiesTool;
104
+ extractEntities: ExtractEntitiesTool;
105
+ };
73
106
 
74
107
  constructor(options: ConversationalAgentOptions) {
75
108
  this.options = options;
@@ -77,15 +110,31 @@ export class ConversationalAgent {
77
110
  this.hcs10Plugin = new HCS10Plugin();
78
111
  this.hcs2Plugin = new HCS2Plugin();
79
112
  this.inscribePlugin = new InscribePlugin();
80
- this.hbarTransferPlugin = new HbarTransferPlugin();
113
+ this.hbarPlugin = new HbarPlugin();
81
114
  this.logger = new Logger({
82
115
  module: 'ConversationalAgent',
83
116
  silent: options.disableLogging || false,
84
117
  });
118
+
119
+ if (this.options.entityMemoryEnabled !== false) {
120
+ if (!options.openAIApiKey) {
121
+ throw new Error(
122
+ 'OpenAI API key is required when entity memory is enabled'
123
+ );
124
+ }
125
+
126
+ this.memoryManager = new SmartMemoryManager(
127
+ this.options.entityMemoryConfig
128
+ );
129
+ this.logger.info('Entity memory initialized');
130
+
131
+ this.entityTools = createEntityTools(options.openAIApiKey, 'gpt-4o-mini');
132
+ this.logger.info('LLM-based entity resolver tools initialized');
133
+ }
85
134
  }
86
135
 
87
136
  /**
88
- * Initialize the conversational agent with Hedera network connection and AI configuration
137
+ * Initialize the conversational agent with Hedera Hashgraph connection and AI configuration
89
138
  * @throws {Error} If account ID or private key is missing
90
139
  * @throws {Error} If initialization fails
91
140
  */
@@ -96,6 +145,7 @@ export class ConversationalAgent {
96
145
  network = DEFAULT_NETWORK,
97
146
  openAIApiKey,
98
147
  openAIModelName = DEFAULT_MODEL_NAME,
148
+ llmProvider = 'openai',
99
149
  } = this.options;
100
150
 
101
151
  this.validateOptions(accountId, privateKey);
@@ -110,30 +160,72 @@ export class ConversationalAgent {
110
160
  const serverSigner = new ServerSigner(
111
161
  accountId!,
112
162
  privateKeyInstance,
113
- network as 'testnet' | 'mainnet' | 'previewnet'
163
+ network as MirrorNetwork
114
164
  );
115
165
 
116
- const allPlugins = this.preparePlugins();
117
-
118
- const llm = new ChatOpenAI({
119
- apiKey: openAIApiKey,
120
- modelName: openAIModelName,
121
- temperature: DEFAULT_TEMPERATURE,
122
- });
166
+ let llm: ChatOpenAI | ChatAnthropic;
167
+ if (llmProvider === 'anthropic') {
168
+ llm = new ChatAnthropic({
169
+ apiKey: openAIApiKey,
170
+ modelName: openAIModelName || 'claude-3-5-sonnet-20241022',
171
+ temperature: DEFAULT_TEMPERATURE,
172
+ });
173
+ } else {
174
+ const modelName = openAIModelName || 'gpt-4o-mini';
175
+ const isGPT5Model =
176
+ modelName.toLowerCase().includes('gpt-5') ||
177
+ modelName.toLowerCase().includes('gpt5');
178
+ llm = new ChatOpenAI({
179
+ apiKey: openAIApiKey,
180
+ modelName: openAIModelName,
181
+ ...(isGPT5Model
182
+ ? { temperature: 1 }
183
+ : { temperature: DEFAULT_TEMPERATURE }),
184
+ });
185
+ }
123
186
 
187
+ const allPlugins = this.preparePlugins();
124
188
  const agentConfig = this.createAgentConfig(serverSigner, llm, allPlugins);
189
+
125
190
  this.agent = createAgent(agentConfig);
126
191
 
127
192
  this.configureHCS10Plugin(allPlugins);
128
193
 
129
- // Initialize ContentStoreManager if MCP servers are configured
130
- if (this.options.mcpServers && this.options.mcpServers.length > 0) {
131
- this.contentStoreManager = new ContentStoreManager();
132
- await this.contentStoreManager.initialize();
133
- this.logger.info('ContentStoreManager initialized for MCP content reference support');
134
- }
194
+ this.contentStoreManager = new ContentStoreManager();
195
+ await this.contentStoreManager.initialize();
196
+ this.logger.info(
197
+ 'ContentStoreManager initialized for content reference support'
198
+ );
135
199
 
136
200
  await this.agent.boot();
201
+
202
+ if (this.agent) {
203
+ const cfg = agentConfig;
204
+ cfg.filtering = cfg.filtering || {};
205
+ const originalPredicate = cfg.filtering.toolPredicate as
206
+ | ((t: ToolDescriptor) => boolean)
207
+ | undefined;
208
+ const userPredicate = this.options.toolFilter;
209
+ cfg.filtering.toolPredicate = (tool: ToolDescriptor): boolean => {
210
+ if (tool && tool.name === 'hedera-account-transfer-hbar') {
211
+ return false;
212
+ }
213
+ if (tool && tool.name === 'hedera-hts-airdrop-token') {
214
+ return false;
215
+ }
216
+ if (originalPredicate && !originalPredicate(tool)) {
217
+ return false;
218
+ }
219
+ if (userPredicate && !userPredicate(tool)) {
220
+ return false;
221
+ }
222
+ return true;
223
+ };
224
+ }
225
+
226
+ if (this.options.mcpServers && this.options.mcpServers.length > 0) {
227
+ this.connectMCP();
228
+ }
137
229
  } catch (error) {
138
230
  this.logger.error('Failed to initialize ConversationalAgent:', error);
139
231
  throw error;
@@ -186,33 +278,47 @@ export class ConversationalAgent {
186
278
  */
187
279
  async processMessage(
188
280
  message: string,
189
- chatHistory: {
190
- type: 'human' | 'ai';
191
- content: string;
192
- }[] = []
281
+ chatHistory: ChatHistoryItem[] = []
193
282
  ): Promise<ChatResponse> {
194
283
  if (!this.agent) {
195
284
  throw new Error('Agent not initialized. Call initialize() first.');
196
285
  }
197
286
 
198
- const messages = chatHistory.map((msg) => {
199
- if (msg.type === 'human') {
200
- return new HumanMessage(msg.content);
201
- } else {
202
- return new AIMessage(msg.content);
287
+ try {
288
+ const resolvedMessage = this.memoryManager
289
+ ? await this.resolveEntitiesInMessage(message)
290
+ : message;
291
+
292
+ const messages = chatHistory.map((msg) => {
293
+ if (msg.type === 'human') {
294
+ return new HumanMessage(msg.content);
295
+ } else {
296
+ return new AIMessage(msg.content);
297
+ }
298
+ });
299
+
300
+ const context: ConversationContext = {
301
+ messages,
302
+ };
303
+
304
+ const response = await this.agent.chat(resolvedMessage, context);
305
+
306
+ if (this.memoryManager) {
307
+ await this.extractAndStoreEntities(response, message);
203
308
  }
204
- });
205
309
 
206
- const context: ConversationContext = {
207
- messages,
208
- };
310
+ this.logger.info('Message processed successfully');
209
311
 
210
- return this.agent.chat(message, context);
312
+ return response;
313
+ } catch (error) {
314
+ this.logger.error('Error processing message:', error);
315
+ throw error;
316
+ }
211
317
  }
212
318
 
213
319
  /**
214
320
  * Validates initialization options and throws if required fields are missing.
215
- *
321
+ *
216
322
  * @param accountId - The Hedera account ID
217
323
  * @param privateKey - The private key for the account
218
324
  * @throws {Error} If required fields are missing
@@ -225,21 +331,21 @@ export class ConversationalAgent {
225
331
 
226
332
  /**
227
333
  * Prepares the list of plugins to use based on configuration.
228
- *
334
+ *
229
335
  * @returns Array of plugins to initialize with the agent
230
336
  */
231
337
  private preparePlugins(): BasePlugin[] {
232
338
  const { additionalPlugins = [], enabledPlugins } = this.options;
233
-
339
+
234
340
  const standardPlugins = [
235
341
  this.hcs10Plugin,
236
342
  this.hcs2Plugin,
237
343
  this.inscribePlugin,
238
- this.hbarTransferPlugin,
344
+ this.hbarPlugin,
239
345
  ];
240
-
346
+
241
347
  const corePlugins = getAllHederaCorePlugins();
242
-
348
+
243
349
  if (enabledPlugins) {
244
350
  const enabledSet = new Set(enabledPlugins);
245
351
  const filteredPlugins = [...standardPlugins, ...corePlugins].filter(
@@ -247,13 +353,13 @@ export class ConversationalAgent {
247
353
  );
248
354
  return [...filteredPlugins, ...additionalPlugins];
249
355
  }
250
-
356
+
251
357
  return [...standardPlugins, ...corePlugins, ...additionalPlugins];
252
358
  }
253
359
 
254
360
  /**
255
361
  * Creates the agent configuration object.
256
- *
362
+ *
257
363
  * @param serverSigner - The server signer instance
258
364
  * @param llm - The language model instance
259
365
  * @param allPlugins - Array of plugins to use
@@ -261,7 +367,7 @@ export class ConversationalAgent {
261
367
  */
262
368
  private createAgentConfig(
263
369
  serverSigner: ServerSigner,
264
- llm: ChatOpenAI,
370
+ llm: ChatOpenAI | ChatAnthropic,
265
371
  allPlugins: BasePlugin[]
266
372
  ): Parameters<typeof createAgent>[0] {
267
373
  const {
@@ -284,6 +390,8 @@ export class ConversationalAgent {
284
390
  operationalMode: operationalMode,
285
391
  ...(userAccountId && { userAccountId }),
286
392
  ...(scheduleUserTransactionsInBytesMode !== undefined && {
393
+ scheduleUserTransactionsInBytesMode:
394
+ scheduleUserTransactionsInBytesMode,
287
395
  scheduleUserTransactions: scheduleUserTransactionsInBytesMode,
288
396
  }),
289
397
  },
@@ -292,7 +400,7 @@ export class ConversationalAgent {
292
400
  temperature: DEFAULT_TEMPERATURE,
293
401
  },
294
402
  filtering: {
295
- toolPredicate: (tool) => {
403
+ toolPredicate: (tool: ToolDescriptor): boolean => {
296
404
  if (tool.name === 'hedera-account-transfer-hbar') return false;
297
405
  if (this.options.toolFilter && !this.options.toolFilter(tool)) {
298
406
  return false;
@@ -303,7 +411,9 @@ export class ConversationalAgent {
303
411
  messaging: {
304
412
  systemPreamble:
305
413
  customSystemMessagePreamble || getSystemMessage(accountId),
306
- ...(customSystemMessagePostamble && { systemPostamble: customSystemMessagePostamble }),
414
+ ...(customSystemMessagePostamble && {
415
+ systemPostamble: customSystemMessagePostamble,
416
+ }),
307
417
  conciseMode: true,
308
418
  },
309
419
  extensions: {
@@ -315,7 +425,7 @@ export class ConversationalAgent {
315
425
  ...(this.options.mcpServers && {
316
426
  mcp: {
317
427
  servers: this.options.mcpServers,
318
- autoConnect: true,
428
+ autoConnect: false,
319
429
  },
320
430
  }),
321
431
  debug: {
@@ -327,13 +437,15 @@ export class ConversationalAgent {
327
437
 
328
438
  /**
329
439
  * Configures the HCS-10 plugin with the state manager.
330
- *
440
+ *
331
441
  * @param allPlugins - Array of all plugins
332
442
  */
333
443
  private configureHCS10Plugin(allPlugins: BasePlugin[]): void {
334
444
  const hcs10 = allPlugins.find((p) => p.id === 'hcs-10');
335
445
  if (hcs10) {
336
- (hcs10 as { appConfig?: Record<string, unknown> }).appConfig = {
446
+ (
447
+ hcs10 as BasePlugin & { appConfig?: Record<string, unknown> }
448
+ ).appConfig = {
337
449
  stateManager: this.stateManager,
338
450
  };
339
451
  }
@@ -449,7 +561,7 @@ export class ConversationalAgent {
449
561
  * Detect the private key type by querying the account info from mirror node
450
562
  * @param {string} accountId - The Hedera account ID
451
563
  * @param {string} privateKey - The private key string
452
- * @param {NetworkType} network - The Hedera network
564
+ * @param {NetworkType} network - The Hedera Hashgraph
453
565
  * @returns {Promise<PrivateKey>} The appropriate PrivateKey instance
454
566
  */
455
567
  private async detectPrivateKeyType(
@@ -469,17 +581,220 @@ export class ConversationalAgent {
469
581
  }
470
582
  }
471
583
 
584
+ /**
585
+ * Resolve entity references using LLM-based resolver
586
+ * @param content - Message content to resolve
587
+ * @returns Resolved message content with entity IDs replaced
588
+ */
589
+ private async resolveEntitiesInMessage(content: string): Promise<string> {
590
+ if (!this.memoryManager || !this.entityTools) {
591
+ return content;
592
+ }
593
+
594
+ try {
595
+ const entities = this.memoryManager.getEntityAssociations();
596
+
597
+ if (entities.length === 0) {
598
+ this.logger.info('No entities in memory, skipping resolution');
599
+ return content;
600
+ }
601
+
602
+ this.logger.info(
603
+ `Starting LLM-based entity resolution for: "${content.substring(
604
+ 0,
605
+ 100
606
+ )}..."`
607
+ );
608
+
609
+ const resolvedContent = await this.entityTools.resolveEntities.call({
610
+ message: content,
611
+ entities: entities.map((e) => ({
612
+ entityId: e.entityId,
613
+ entityName: e.entityName,
614
+ entityType: e.entityType,
615
+ })),
616
+ });
617
+
618
+ if (resolvedContent !== content) {
619
+ this.logger.info(
620
+ `Entity resolution completed. Original: "${content}" -> Resolved: "${resolvedContent}"`
621
+ );
622
+ }
623
+
624
+ return resolvedContent;
625
+ } catch (error) {
626
+ this.logger.error('Entity resolution failed:', error);
627
+ throw error;
628
+ }
629
+ }
630
+
631
+ /**
632
+ * Extract and store entities from agent responses
633
+ * @param response - Agent response containing potential entity information
634
+ * @param originalMessage - Original user message for context
635
+ */
636
+ private async extractAndStoreEntities(
637
+ response: unknown,
638
+ originalMessage: string
639
+ ): Promise<void> {
640
+ if (!this.memoryManager || !this.entityTools) {
641
+ return;
642
+ }
643
+
644
+ try {
645
+ this.logger.info('Starting LLM-based entity extraction');
646
+
647
+ const responseText = this.extractResponseText(response);
648
+
649
+ const entitiesJson = await this.entityTools.extractEntities.call({
650
+ response: responseText,
651
+ userMessage: originalMessage,
652
+ });
653
+
654
+ try {
655
+ const entities = JSON.parse(entitiesJson);
656
+
657
+ for (const entity of entities) {
658
+ this.logger.info(
659
+ `Storing entity: ${entity.name} (${entity.type}) -> ${entity.id}`
660
+ );
661
+
662
+ const transactionId = this.extractTransactionId(response);
663
+ this.memoryManager.storeEntityAssociation(
664
+ entity.id,
665
+ entity.name,
666
+ entity.type,
667
+ transactionId
668
+ );
669
+ }
670
+
671
+ if (entities.length > 0) {
672
+ this.logger.info(
673
+ `Stored ${entities.length} entities via LLM extraction`
674
+ );
675
+ } else {
676
+ this.logger.info('No entities found in response via LLM extraction');
677
+ }
678
+ } catch (parseError) {
679
+ this.logger.error(
680
+ 'Failed to parse extracted entities JSON:',
681
+ parseError
682
+ );
683
+ throw parseError;
684
+ }
685
+ } catch (error) {
686
+ this.logger.error('Entity extraction failed:', error);
687
+ throw error;
688
+ }
689
+ }
690
+
691
+ /**
692
+ * Extract transaction ID from response if available
693
+ * @param response - Transaction response
694
+ * @returns Transaction ID or undefined
695
+ */
696
+ private extractTransactionId(response: unknown): string | undefined {
697
+ try {
698
+ if (
699
+ typeof response === 'object' &&
700
+ response &&
701
+ 'transactionId' in response
702
+ ) {
703
+ return (response as { transactionId?: string }).transactionId;
704
+ }
705
+ if (typeof response === 'string') {
706
+ const match = response.match(
707
+ /transaction[\s\w]*ID[\s:"]*([0-9a-fA-F@\.\-]+)/i
708
+ );
709
+ return match ? match[1] : undefined;
710
+ }
711
+ return undefined;
712
+ } catch {
713
+ return undefined;
714
+ }
715
+ }
716
+
717
+ /**
718
+ * Connect to MCP servers asynchronously
719
+ * @private
720
+ */
721
+ private connectMCP(): void {
722
+ if (!this.agent || !this.options.mcpServers) {
723
+ return;
724
+ }
725
+
726
+ this.agent
727
+ .connectMCPServers()
728
+ .catch((e) => {
729
+ this.logger.error('Failed to connect MCP servers:', e);
730
+ })
731
+ .then(() => {
732
+ this.logger.info('MCP servers connected successfully');
733
+ });
734
+ }
735
+
736
+ /**
737
+ * Get MCP connection status for all servers
738
+ * @returns {Map<string, MCPConnectionStatus>} Connection status map
739
+ */
740
+ getMCPConnectionStatus(): Map<string, MCPConnectionStatus> {
741
+ if (this.agent) {
742
+ return this.agent.getMCPConnectionStatus();
743
+ }
744
+ return new Map();
745
+ }
746
+
747
+ /**
748
+ * Check if a specific MCP server is connected
749
+ * @param {string} serverName - Name of the server to check
750
+ * @returns {boolean} True if connected, false otherwise
751
+ */
752
+ isMCPServerConnected(serverName: string): boolean {
753
+ if (this.agent) {
754
+ const statusMap = this.agent.getMCPConnectionStatus();
755
+ const status = statusMap.get(serverName);
756
+ return status?.connected ?? false;
757
+ }
758
+ return false;
759
+ }
760
+
472
761
  /**
473
762
  * Clean up resources
474
763
  */
475
764
  async cleanup(): Promise<void> {
476
- if (this.contentStoreManager) {
477
- await this.contentStoreManager.dispose();
478
- this.logger.info('ContentStoreManager cleaned up');
765
+ try {
766
+ this.logger.info('Cleaning up ConversationalAgent...');
767
+
768
+ if (this.memoryManager) {
769
+ try {
770
+ this.memoryManager.dispose();
771
+ this.logger.info('Memory manager cleaned up successfully');
772
+ } catch (error) {
773
+ this.logger.warn('Error cleaning up memory manager:', error);
774
+ }
775
+ this.memoryManager = undefined;
776
+ }
777
+
778
+ if (this.contentStoreManager) {
779
+ await this.contentStoreManager.dispose();
780
+ this.logger.info('ContentStoreManager cleaned up');
781
+ }
782
+
783
+ this.logger.info('ConversationalAgent cleanup completed');
784
+ } catch (error) {
785
+ this.logger.error('Error during cleanup:', error);
479
786
  }
480
- // Agent cleanup if needed
481
- if (this.agent) {
482
- // Add agent cleanup if available
787
+ }
788
+
789
+ private extractResponseText(response: unknown): string {
790
+ if (typeof response === 'string') {
791
+ return response;
792
+ }
793
+
794
+ if (response && typeof response === 'object' && 'output' in response) {
795
+ return String(response.output);
483
796
  }
797
+
798
+ return JSON.stringify(response);
484
799
  }
485
800
  }
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { HCS10Plugin } from './plugins/hcs-10/HCS10Plugin';
2
2
  export { HCS2Plugin } from './plugins/hcs-2/HCS2Plugin';
3
3
  export { InscribePlugin } from './plugins/inscribe/InscribePlugin';
4
- export { HbarTransferPlugin } from './plugins/hbar-transfer/HbarTransferPlugin';
4
+ export { HbarPlugin } from './plugins/hbar/HbarPlugin';
5
5
  export { HCS10Plugin as OpenConvAIPlugin } from './plugins/hcs-10/HCS10Plugin';
6
6
  export { ConversationalAgent } from './conversational-agent';
7
7
  export type { ConversationalAgentOptions } from './conversational-agent';
@@ -29,5 +29,21 @@ export * from 'hedera-agent-kit';
29
29
 
30
30
  export type { IStateManager } from '@hashgraphonline/standards-agent-kit';
31
31
 
32
- export type { MCPServerConfig, MCPConnectionStatus, MCPToolInfo } from './mcp/types';
33
- export { MCPServers, createMCPConfig, validateServerConfig } from './mcp/helpers';
32
+ export type {
33
+ MCPServerConfig,
34
+ MCPConnectionStatus,
35
+ MCPToolInfo,
36
+ } from './mcp/types';
37
+ export {
38
+ MCPServers,
39
+ createMCPConfig,
40
+ validateServerConfig,
41
+ } from './mcp/helpers';
42
+
43
+ export * from './memory';
44
+ export {
45
+ createEntityTools,
46
+ ResolveEntitiesTool,
47
+ ExtractEntitiesTool,
48
+ } from './tools/EntityResolverTool';
49
+ export { ContentStoreManager } from './services/ContentStoreManager';
@@ -1,5 +1,4 @@
1
1
  import { AgentExecutor } from 'langchain/agents';
2
- import type { ChainValues } from '@langchain/core/utils/types';
3
2
  import { Logger } from '@hashgraphonline/standards-sdk';
4
3
 
5
4
  /**