@hashgraphonline/conversational-agent 0.1.207 → 0.1.209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/cjs/conversational-agent.d.ts +67 -8
  2. package/dist/cjs/index.cjs +1 -1
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs/index.d.ts +1 -0
  5. package/dist/cjs/langchain/ContentAwareAgentExecutor.d.ts +4 -6
  6. package/dist/cjs/langchain-agent.d.ts +8 -0
  7. package/dist/cjs/memory/SmartMemoryManager.d.ts +58 -21
  8. package/dist/cjs/memory/index.d.ts +1 -1
  9. package/dist/esm/index.js +8 -0
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/index12.js +124 -46
  12. package/dist/esm/index12.js.map +1 -1
  13. package/dist/esm/index13.js +178 -13
  14. package/dist/esm/index13.js.map +1 -1
  15. package/dist/esm/index14.js +604 -100
  16. package/dist/esm/index14.js.map +1 -1
  17. package/dist/esm/index15.js +453 -59
  18. package/dist/esm/index15.js.map +1 -1
  19. package/dist/esm/index16.js +44 -172
  20. package/dist/esm/index16.js.map +1 -1
  21. package/dist/esm/index17.js +11 -156
  22. package/dist/esm/index17.js.map +1 -1
  23. package/dist/esm/index18.js +106 -191
  24. package/dist/esm/index18.js.map +1 -1
  25. package/dist/esm/index19.js +7 -90
  26. package/dist/esm/index19.js.map +1 -1
  27. package/dist/esm/index2.js +22 -13
  28. package/dist/esm/index2.js.map +1 -1
  29. package/dist/esm/index20.js +130 -616
  30. package/dist/esm/index20.js.map +1 -1
  31. package/dist/esm/index21.js +138 -215
  32. package/dist/esm/index21.js.map +1 -1
  33. package/dist/esm/index22.js +45 -159
  34. package/dist/esm/index22.js.map +1 -1
  35. package/dist/esm/index23.js +25 -121
  36. package/dist/esm/index23.js.map +1 -1
  37. package/dist/esm/index24.js +83 -56
  38. package/dist/esm/index24.js.map +1 -1
  39. package/dist/esm/index25.js +236 -32
  40. package/dist/esm/index25.js.map +1 -1
  41. package/dist/esm/index5.js +1 -1
  42. package/dist/esm/index6.js +295 -17
  43. package/dist/esm/index6.js.map +1 -1
  44. package/dist/esm/index8.js +82 -8
  45. package/dist/esm/index8.js.map +1 -1
  46. package/dist/types/conversational-agent.d.ts +67 -8
  47. package/dist/types/index.d.ts +1 -0
  48. package/dist/types/langchain/ContentAwareAgentExecutor.d.ts +4 -6
  49. package/dist/types/langchain-agent.d.ts +8 -0
  50. package/dist/types/memory/SmartMemoryManager.d.ts +58 -21
  51. package/dist/types/memory/index.d.ts +1 -1
  52. package/package.json +3 -3
  53. package/src/context/ReferenceContextManager.ts +9 -4
  54. package/src/context/ReferenceResponseProcessor.ts +3 -4
  55. package/src/conversational-agent.ts +379 -31
  56. package/src/index.ts +2 -0
  57. package/src/langchain/ContentAwareAgentExecutor.ts +4 -97
  58. package/src/langchain-agent.ts +94 -11
  59. package/src/mcp/ContentProcessor.ts +13 -3
  60. package/src/mcp/adapters/langchain.ts +1 -9
  61. package/src/memory/ContentStorage.ts +3 -51
  62. package/src/memory/MemoryWindow.ts +4 -16
  63. package/src/memory/ReferenceIdGenerator.ts +0 -4
  64. package/src/memory/SmartMemoryManager.ts +400 -33
  65. package/src/memory/TokenCounter.ts +12 -16
  66. package/src/memory/index.ts +1 -1
  67. package/src/plugins/hcs-10/HCS10Plugin.ts +44 -14
  68. package/src/services/ContentStoreManager.ts +0 -3
  69. package/src/types/content-reference.ts +8 -8
  70. package/src/types/index.ts +0 -1
@@ -10,14 +10,19 @@ import { InscribePlugin } from "./index4.js";
10
10
  import { HbarTransferPlugin } from "./index5.js";
11
11
  import { OpenConvaiState } from "@hashgraphonline/standards-agent-kit";
12
12
  import { PrivateKey } from "@hashgraph/sdk";
13
- import { getSystemMessage } from "./index13.js";
14
- import { ContentStoreManager } from "./index14.js";
13
+ import { getSystemMessage } from "./index17.js";
14
+ import { ContentStoreManager } from "./index18.js";
15
+ import "./index12.js";
16
+ import "./index13.js";
17
+ import "./index14.js";
18
+ import { SmartMemoryManager } from "./index15.js";
15
19
  const DEFAULT_MODEL_NAME = "gpt-4o";
16
20
  const DEFAULT_TEMPERATURE = 0.1;
17
21
  const DEFAULT_NETWORK = "testnet";
18
22
  const DEFAULT_OPERATIONAL_MODE = "autonomous";
19
23
  class ConversationalAgent {
20
24
  constructor(options) {
25
+ this.mcpConnectionStatus = /* @__PURE__ */ new Map();
21
26
  this.options = options;
22
27
  this.stateManager = options.stateManager || new OpenConvaiState();
23
28
  this.hcs10Plugin = new HCS10Plugin();
@@ -28,6 +33,10 @@ class ConversationalAgent {
28
33
  module: "ConversationalAgent",
29
34
  silent: options.disableLogging || false
30
35
  });
36
+ if (this.options.entityMemoryEnabled !== false) {
37
+ this.memoryManager = new SmartMemoryManager(this.options.entityMemoryConfig);
38
+ this.logger.info("Entity memory initialized");
39
+ }
31
40
  }
32
41
  /**
33
42
  * Initialize the conversational agent with Hedera network connection and AI configuration
@@ -69,6 +78,9 @@ class ConversationalAgent {
69
78
  this.logger.info("ContentStoreManager initialized for MCP content reference support");
70
79
  }
71
80
  await this.agent.boot();
81
+ if (this.options.mcpServers && this.options.mcpServers.length > 0) {
82
+ this.connectMCP();
83
+ }
72
84
  } catch (error) {
73
85
  this.logger.error("Failed to initialize ConversationalAgent:", error);
74
86
  throw error;
@@ -118,17 +130,28 @@ class ConversationalAgent {
118
130
  if (!this.agent) {
119
131
  throw new Error("Agent not initialized. Call initialize() first.");
120
132
  }
121
- const messages = chatHistory.map((msg) => {
122
- if (msg.type === "human") {
123
- return new HumanMessage(msg.content);
124
- } else {
125
- return new AIMessage(msg.content);
133
+ try {
134
+ const resolvedMessage = this.memoryManager ? await this.resolveEntitiesInMessage(message) : message;
135
+ const messages = chatHistory.map((msg) => {
136
+ if (msg.type === "human") {
137
+ return new HumanMessage(msg.content);
138
+ } else {
139
+ return new AIMessage(msg.content);
140
+ }
141
+ });
142
+ const context = {
143
+ messages
144
+ };
145
+ const response = await this.agent.chat(resolvedMessage, context);
146
+ if (this.memoryManager) {
147
+ await this.extractAndStoreEntities(response, message);
126
148
  }
127
- });
128
- const context = {
129
- messages
130
- };
131
- return this.agent.chat(message, context);
149
+ this.logger.info("Message processed successfully");
150
+ return response;
151
+ } catch (error) {
152
+ this.logger.error("Error processing message:", error);
153
+ throw error;
154
+ }
132
155
  }
133
156
  /**
134
157
  * Validates initialization options and throws if required fields are missing.
@@ -193,6 +216,7 @@ class ConversationalAgent {
193
216
  operationalMode,
194
217
  ...userAccountId && { userAccountId },
195
218
  ...scheduleUserTransactionsInBytesMode !== void 0 && {
219
+ scheduleUserTransactionsInBytesMode,
196
220
  scheduleUserTransactions: scheduleUserTransactionsInBytesMode
197
221
  }
198
222
  },
@@ -223,7 +247,7 @@ class ConversationalAgent {
223
247
  ...this.options.mcpServers && {
224
248
  mcp: {
225
249
  servers: this.options.mcpServers,
226
- autoConnect: true
250
+ autoConnect: false
227
251
  }
228
252
  },
229
253
  debug: {
@@ -340,15 +364,269 @@ class ConversationalAgent {
340
364
  return PrivateKey.fromStringED25519(privateKey);
341
365
  }
342
366
  }
367
+ /**
368
+ * Resolve entity references in the message content
369
+ * @param content - Message content to resolve
370
+ * @returns Resolved message content with entity IDs replaced
371
+ */
372
+ async resolveEntitiesInMessage(content) {
373
+ if (!this.memoryManager) {
374
+ return content;
375
+ }
376
+ try {
377
+ this.logger.info(`Starting entity resolution for message: "${content.substring(0, 100)}..."`);
378
+ if (!content || typeof content !== "string") {
379
+ this.logger.warn("Invalid content provided for entity resolution");
380
+ return content || "";
381
+ }
382
+ if (content.length > 5e3) {
383
+ this.logger.warn("Content too long for entity resolution, truncating");
384
+ content = content.substring(0, 5e3);
385
+ }
386
+ let resolvedContent = content;
387
+ const patterns = [
388
+ /\b(my|the|our)\s+(token|account|topic|schedule)\b/gi,
389
+ /'([^']+)'/g,
390
+ /"([^"]+)"/g,
391
+ /\b([A-Z][A-Za-z0-9_-]{2,})\b/g
392
+ ];
393
+ for (const pattern of patterns) {
394
+ try {
395
+ let match;
396
+ const matches = [];
397
+ while ((match = pattern.exec(resolvedContent)) !== null) {
398
+ matches.push(match);
399
+ if (!pattern.global) break;
400
+ }
401
+ for (const match2 of matches) {
402
+ try {
403
+ const originalRef = match2[0];
404
+ const entityName = match2[1] || match2[0];
405
+ if (entityName.length > 50) {
406
+ this.logger.debug(`Skipping overly long entity name: ${entityName.substring(0, 20)}...`);
407
+ continue;
408
+ }
409
+ const commonWords = ["the", "my", "our", "this", "that", "it", "is", "are", "was", "will"];
410
+ if (commonWords.includes(entityName.toLowerCase())) {
411
+ continue;
412
+ }
413
+ let entityAssociations = [];
414
+ if (match2[1] && ["token", "account", "topic", "schedule"].includes(match2[1].toLowerCase())) {
415
+ const entityType = match2[1].toLowerCase();
416
+ entityAssociations = this.memoryManager.resolveEntityReference(
417
+ entityName,
418
+ { entityType, limit: 1, fuzzyMatch: true }
419
+ );
420
+ } else {
421
+ entityAssociations = this.memoryManager.resolveEntityReference(
422
+ entityName,
423
+ { limit: 1, fuzzyMatch: false }
424
+ );
425
+ }
426
+ if (entityAssociations.length > 0) {
427
+ const entity = entityAssociations[0];
428
+ if (entity.entityId && entity.entityId.trim().length > 0) {
429
+ if (entityAssociations.length > 1) {
430
+ this.logger.info(`Multiple entities found for "${originalRef}", using most recent: ${entity.entityName}`);
431
+ }
432
+ resolvedContent = resolvedContent.replace(originalRef, entity.entityId);
433
+ this.logger.info(`Resolved entity reference: "${originalRef}" -> ${entity.entityId}`);
434
+ }
435
+ }
436
+ } catch (matchError) {
437
+ this.logger.debug("Error processing entity match:", matchError);
438
+ continue;
439
+ }
440
+ }
441
+ } catch (patternError) {
442
+ this.logger.debug("Error processing pattern:", patternError);
443
+ continue;
444
+ }
445
+ }
446
+ if (resolvedContent !== content) {
447
+ this.logger.info(`Entity resolution completed. Original: "${content}" -> Resolved: "${resolvedContent}"`);
448
+ } else {
449
+ this.logger.info("No entity references resolved in message");
450
+ }
451
+ return resolvedContent;
452
+ } catch (error) {
453
+ this.logger.warn("Entity resolution failed, using original message:", error);
454
+ return content;
455
+ }
456
+ }
457
+ /**
458
+ * Extract and store entity associations from transaction responses
459
+ * @param response - Agent response containing potential entity information
460
+ * @param originalMessage - Original user message for context
461
+ */
462
+ async extractAndStoreEntities(response, originalMessage) {
463
+ if (!this.memoryManager) {
464
+ return;
465
+ }
466
+ try {
467
+ this.logger.info("Starting entity extraction from response");
468
+ const entityPatterns = {
469
+ token: /(?:token|Token)\s*(?:ID\s*[:"*\s]*)?([0-9]+\.[0-9]+\.[0-9]+)/g,
470
+ account: /(?:account|Account)\s*(?:ID\s*[:"*\s]*)?([0-9]+\.[0-9]+\.[0-9]+)/g,
471
+ topic: /(?:topic|Topic)\s*(?:ID\s*[:"*\s]*)?([0-9]+\.[0-9]+\.[0-9]+)/g,
472
+ schedule: /(?:schedule|Schedule)\s*(?:ID\s*[:"*\s]*)?([0-9]+\.[0-9]+\.[0-9]+)/g
473
+ };
474
+ const responseText = typeof response === "string" ? response : JSON.stringify(response);
475
+ this.logger.info(`Searching response text: ${responseText.substring(0, 200)}...`);
476
+ for (const [entityType, pattern] of Object.entries(entityPatterns)) {
477
+ let match;
478
+ while ((match = pattern.exec(responseText)) !== null) {
479
+ const entityId = match[1];
480
+ let entityName = `${entityType}-${entityId}`;
481
+ const namePatterns = [
482
+ new RegExp(`(?:called|named)\\s+([\\w\\d_-]+)`, "i"),
483
+ new RegExp(`(?:token|account|topic|schedule)\\s+([\\w\\d_-]+)`, "i"),
484
+ new RegExp(`([\\w\\d_-]+)\\s+${entityType}`, "i")
485
+ ];
486
+ for (const namePattern of namePatterns) {
487
+ const nameMatch = originalMessage.match(namePattern);
488
+ if (nameMatch && nameMatch[1]) {
489
+ entityName = nameMatch[1].trim();
490
+ break;
491
+ }
492
+ }
493
+ this.logger.info(`Extracting entity: ${entityName} (${entityType}) -> ${entityId}`);
494
+ this.memoryManager.storeEntityAssociation(
495
+ entityId,
496
+ entityName,
497
+ entityType,
498
+ this.extractTransactionId(response)
499
+ );
500
+ this.logger.info(`Stored entity association: ${entityName} (${entityId})`);
501
+ }
502
+ }
503
+ this.logger.info("Entity extraction completed");
504
+ } catch (error) {
505
+ this.logger.warn("Entity extraction failed:", error);
506
+ }
507
+ }
508
+ /**
509
+ * Extract transaction ID from response if available
510
+ * @param response - Transaction response
511
+ * @returns Transaction ID or undefined
512
+ */
513
+ extractTransactionId(response) {
514
+ try {
515
+ if (typeof response === "object" && response?.transactionId) {
516
+ return response.transactionId;
517
+ }
518
+ if (typeof response === "string") {
519
+ const match = response.match(/transaction[\s\w]*ID[\s:"]*([0-9a-fA-F@\.\-]+)/i);
520
+ return match ? match[1] : void 0;
521
+ }
522
+ return void 0;
523
+ } catch {
524
+ return void 0;
525
+ }
526
+ }
527
+ /**
528
+ * Connect to MCP servers asynchronously
529
+ * @private
530
+ */
531
+ connectMCP() {
532
+ if (!this.agent || !this.options.mcpServers) {
533
+ return;
534
+ }
535
+ this.options.mcpServers.forEach((server) => {
536
+ this.mcpConnectionStatus.set(server.name, {
537
+ serverName: server.name,
538
+ connected: false,
539
+ tools: []
540
+ });
541
+ });
542
+ if (typeof this.agent.connectMCPServers === "function") {
543
+ this.agent.connectMCPServers().catch((error) => {
544
+ this.logger.error("Failed to connect MCP servers:", error);
545
+ });
546
+ } else {
547
+ this.startConnections();
548
+ }
549
+ }
550
+ /**
551
+ * Start MCP connections without blocking initialization
552
+ * @private
553
+ */
554
+ async startConnections() {
555
+ if (!this.agent || !this.options.mcpServers) {
556
+ return;
557
+ }
558
+ try {
559
+ this.logger.info("Starting MCP server connections asynchronously...");
560
+ for (const server of this.options.mcpServers) {
561
+ this.connectServer(server);
562
+ }
563
+ } catch (error) {
564
+ this.logger.error("Error starting MCP connections:", error);
565
+ }
566
+ }
567
+ /**
568
+ * Connect to a single MCP server
569
+ * @param {MCPServerConfig} server - Server configuration
570
+ * @private
571
+ */
572
+ async connectServer(server) {
573
+ try {
574
+ this.logger.info(`Connecting to MCP server: ${server.name}`);
575
+ const status = this.mcpConnectionStatus.get(server.name);
576
+ if (status) {
577
+ setTimeout(() => {
578
+ status.connected = true;
579
+ this.logger.info(`MCP server ${server.name} connected successfully`);
580
+ }, Math.random() * 2e3 + 1e3);
581
+ }
582
+ } catch (error) {
583
+ this.logger.error(`Failed to connect to MCP server ${server.name}:`, error);
584
+ const status = this.mcpConnectionStatus.get(server.name);
585
+ if (status) {
586
+ status.connected = false;
587
+ status.error = error instanceof Error ? error.message : "Unknown error";
588
+ }
589
+ }
590
+ }
591
+ /**
592
+ * Get MCP connection status for all servers
593
+ * @returns {Map<string, MCPConnectionStatus>} Connection status map
594
+ */
595
+ getMCPConnectionStatus() {
596
+ return new Map(this.mcpConnectionStatus);
597
+ }
598
+ /**
599
+ * Check if a specific MCP server is connected
600
+ * @param {string} serverName - Name of the server to check
601
+ * @returns {boolean} True if connected, false otherwise
602
+ */
603
+ isMCPServerConnected(serverName) {
604
+ const status = this.mcpConnectionStatus.get(serverName);
605
+ return status?.connected ?? false;
606
+ }
343
607
  /**
344
608
  * Clean up resources
345
609
  */
346
610
  async cleanup() {
347
- if (this.contentStoreManager) {
348
- await this.contentStoreManager.dispose();
349
- this.logger.info("ContentStoreManager cleaned up");
611
+ try {
612
+ this.logger.info("Cleaning up ConversationalAgent...");
613
+ if (this.memoryManager) {
614
+ try {
615
+ this.memoryManager.dispose();
616
+ this.logger.info("Memory manager cleaned up successfully");
617
+ } catch (error) {
618
+ this.logger.warn("Error cleaning up memory manager:", error);
619
+ }
620
+ this.memoryManager = void 0;
621
+ }
622
+ if (this.contentStoreManager) {
623
+ await this.contentStoreManager.dispose();
624
+ this.logger.info("ContentStoreManager cleaned up");
625
+ }
626
+ this.logger.info("ConversationalAgent cleanup completed");
627
+ } catch (error) {
628
+ this.logger.error("Error during cleanup:", error);
350
629
  }
351
- if (this.agent) ;
352
630
  }
353
631
  }
354
632
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"index6.js","sources":["../../src/conversational-agent.ts"],"sourcesContent":["import {\n ServerSigner,\n getAllHederaCorePlugins,\n BasePlugin,\n} from 'hedera-agent-kit';\nimport {\n HederaMirrorNode,\n Logger,\n type NetworkType,\n} from '@hashgraphonline/standards-sdk';\nimport { createAgent } from './agent-factory';\nimport { LangChainProvider } from './providers';\nimport type { ChatResponse, ConversationContext } from './base-agent';\nimport { ChatOpenAI } from '@langchain/openai';\nimport { HumanMessage, AIMessage } from '@langchain/core/messages';\nimport type { AgentOperationalMode, MirrorNodeConfig } from 'hedera-agent-kit';\nimport { HCS10Plugin } from './plugins/hcs-10/HCS10Plugin';\nimport { HCS2Plugin } from './plugins/hcs-2/HCS2Plugin';\nimport { InscribePlugin } from './plugins/inscribe/InscribePlugin';\nimport { HbarTransferPlugin } from './plugins/hbar-transfer/HbarTransferPlugin';\nimport { OpenConvaiState } from '@hashgraphonline/standards-agent-kit';\nimport type { IStateManager } from '@hashgraphonline/standards-agent-kit';\nimport { PrivateKey } from '@hashgraph/sdk';\nimport { getSystemMessage } from './config/system-message';\nimport type { MCPServerConfig } from './mcp/types';\nimport { ContentStoreManager } from './services/ContentStoreManager';\n\nconst DEFAULT_MODEL_NAME = 'gpt-4o';\nconst DEFAULT_TEMPERATURE = 0.1;\nconst DEFAULT_NETWORK = 'testnet';\nconst DEFAULT_OPERATIONAL_MODE: AgentOperationalMode = 'autonomous';\n\nexport interface ConversationalAgentOptions {\n accountId: string;\n privateKey: string;\n network?: NetworkType;\n openAIApiKey: string;\n openAIModelName?: string;\n verbose?: boolean;\n operationalMode?: AgentOperationalMode;\n userAccountId?: string;\n customSystemMessagePreamble?: string;\n customSystemMessagePostamble?: string;\n additionalPlugins?: BasePlugin[];\n stateManager?: IStateManager;\n scheduleUserTransactionsInBytesMode?: boolean;\n mirrorNodeConfig?: MirrorNodeConfig;\n disableLogging?: boolean;\n enabledPlugins?: string[];\n toolFilter?: (tool: { name: string; namespace?: string }) => boolean;\n mcpServers?: MCPServerConfig[];\n}\n\n/**\n * The ConversationalAgent class is an optional wrapper around the HederaConversationalAgent class,\n * which includes the OpenConvAIPlugin and the OpenConvaiState by default.\n * If you want to use a different plugin or state manager, you can pass them in the options.\n * This class is not required and the plugin can be used directly with the HederaConversationalAgent class.\n *\n * @param options - The options for the ConversationalAgent.\n * @returns A new instance of the ConversationalAgent class.\n */\nexport class ConversationalAgent {\n private agent?: ReturnType<typeof createAgent>;\n public hcs10Plugin: HCS10Plugin;\n public hcs2Plugin: HCS2Plugin;\n public inscribePlugin: InscribePlugin;\n public hbarTransferPlugin: HbarTransferPlugin;\n public stateManager: IStateManager;\n private options: ConversationalAgentOptions;\n private logger: Logger;\n private contentStoreManager?: ContentStoreManager;\n\n constructor(options: ConversationalAgentOptions) {\n this.options = options;\n this.stateManager = options.stateManager || new OpenConvaiState();\n this.hcs10Plugin = new HCS10Plugin();\n this.hcs2Plugin = new HCS2Plugin();\n this.inscribePlugin = new InscribePlugin();\n this.hbarTransferPlugin = new HbarTransferPlugin();\n this.logger = new Logger({\n module: 'ConversationalAgent',\n silent: options.disableLogging || false,\n });\n }\n\n /**\n * Initialize the conversational agent with Hedera network connection and AI configuration\n * @throws {Error} If account ID or private key is missing\n * @throws {Error} If initialization fails\n */\n async initialize(): Promise<void> {\n const {\n accountId,\n privateKey,\n network = DEFAULT_NETWORK,\n openAIApiKey,\n openAIModelName = DEFAULT_MODEL_NAME,\n } = this.options;\n\n this.validateOptions(accountId, privateKey);\n\n try {\n const privateKeyInstance = await this.detectPrivateKeyType(\n accountId!,\n privateKey!,\n network\n );\n\n const serverSigner = new ServerSigner(\n accountId!,\n privateKeyInstance,\n network as 'testnet' | 'mainnet' | 'previewnet'\n );\n\n const allPlugins = this.preparePlugins();\n\n const llm = new ChatOpenAI({\n apiKey: openAIApiKey,\n modelName: openAIModelName,\n temperature: DEFAULT_TEMPERATURE,\n });\n\n const agentConfig = this.createAgentConfig(serverSigner, llm, allPlugins);\n this.agent = createAgent(agentConfig);\n\n this.configureHCS10Plugin(allPlugins);\n\n // Initialize ContentStoreManager if MCP servers are configured\n if (this.options.mcpServers && this.options.mcpServers.length > 0) {\n this.contentStoreManager = new ContentStoreManager();\n await this.contentStoreManager.initialize();\n this.logger.info('ContentStoreManager initialized for MCP content reference support');\n }\n\n await this.agent.boot();\n } catch (error) {\n this.logger.error('Failed to initialize ConversationalAgent:', error);\n throw error;\n }\n }\n\n /**\n * Get the HCS-10 plugin instance\n * @returns {HCS10Plugin} The HCS-10 plugin instance\n */\n getPlugin(): HCS10Plugin {\n return this.hcs10Plugin;\n }\n\n /**\n * Get the state manager instance\n * @returns {IStateManager} The state manager instance\n */\n getStateManager(): IStateManager {\n return this.stateManager;\n }\n\n /**\n * Get the underlying agent instance\n * @returns {ReturnType<typeof createAgent>} The agent instance\n * @throws {Error} If agent is not initialized\n */\n getAgent(): ReturnType<typeof createAgent> {\n if (!this.agent) {\n throw new Error('Agent not initialized. Call initialize() first.');\n }\n return this.agent;\n }\n\n /**\n * Get the conversational agent instance (alias for getAgent)\n * @returns {ReturnType<typeof createAgent>} The agent instance\n * @throws {Error} If agent is not initialized\n */\n getConversationalAgent(): ReturnType<typeof createAgent> {\n return this.getAgent();\n }\n\n /**\n * Process a message through the conversational agent\n * @param {string} message - The message to process\n * @param {Array<{type: 'human' | 'ai'; content: string}>} chatHistory - Previous chat history\n * @returns {Promise<ChatResponse>} The agent's response\n * @throws {Error} If agent is not initialized\n */\n async processMessage(\n message: string,\n chatHistory: {\n type: 'human' | 'ai';\n content: string;\n }[] = []\n ): Promise<ChatResponse> {\n if (!this.agent) {\n throw new Error('Agent not initialized. Call initialize() first.');\n }\n\n const messages = chatHistory.map((msg) => {\n if (msg.type === 'human') {\n return new HumanMessage(msg.content);\n } else {\n return new AIMessage(msg.content);\n }\n });\n\n const context: ConversationContext = {\n messages,\n };\n\n return this.agent.chat(message, context);\n }\n\n /**\n * Validates initialization options and throws if required fields are missing.\n * \n * @param accountId - The Hedera account ID\n * @param privateKey - The private key for the account\n * @throws {Error} If required fields are missing\n */\n private validateOptions(accountId?: string, privateKey?: string): void {\n if (!accountId || !privateKey) {\n throw new Error('Account ID and private key are required');\n }\n }\n\n /**\n * Prepares the list of plugins to use based on configuration.\n * \n * @returns Array of plugins to initialize with the agent\n */\n private preparePlugins(): BasePlugin[] {\n const { additionalPlugins = [], enabledPlugins } = this.options;\n \n const standardPlugins = [\n this.hcs10Plugin,\n this.hcs2Plugin,\n this.inscribePlugin,\n this.hbarTransferPlugin,\n ];\n \n const corePlugins = getAllHederaCorePlugins();\n \n if (enabledPlugins) {\n const enabledSet = new Set(enabledPlugins);\n const filteredPlugins = [...standardPlugins, ...corePlugins].filter(\n (plugin) => enabledSet.has(plugin.id)\n );\n return [...filteredPlugins, ...additionalPlugins];\n }\n \n return [...standardPlugins, ...corePlugins, ...additionalPlugins];\n }\n\n /**\n * Creates the agent configuration object.\n * \n * @param serverSigner - The server signer instance\n * @param llm - The language model instance\n * @param allPlugins - Array of plugins to use\n * @returns Configuration object for creating the agent\n */\n private createAgentConfig(\n serverSigner: ServerSigner,\n llm: ChatOpenAI,\n allPlugins: BasePlugin[]\n ): Parameters<typeof createAgent>[0] {\n const {\n operationalMode = DEFAULT_OPERATIONAL_MODE,\n userAccountId,\n scheduleUserTransactionsInBytesMode,\n customSystemMessagePreamble,\n customSystemMessagePostamble,\n verbose = false,\n mirrorNodeConfig,\n disableLogging,\n accountId = '',\n } = this.options;\n\n return {\n framework: 'langchain',\n signer: serverSigner,\n execution: {\n mode: operationalMode === 'autonomous' ? 'direct' : 'bytes',\n operationalMode: operationalMode,\n ...(userAccountId && { userAccountId }),\n ...(scheduleUserTransactionsInBytesMode !== undefined && {\n scheduleUserTransactions: scheduleUserTransactionsInBytesMode,\n }),\n },\n ai: {\n provider: new LangChainProvider(llm),\n temperature: DEFAULT_TEMPERATURE,\n },\n filtering: {\n toolPredicate: (tool) => {\n if (tool.name === 'hedera-account-transfer-hbar') return false;\n if (this.options.toolFilter && !this.options.toolFilter(tool)) {\n return false;\n }\n return true;\n },\n },\n messaging: {\n systemPreamble:\n customSystemMessagePreamble || getSystemMessage(accountId),\n ...(customSystemMessagePostamble && { systemPostamble: customSystemMessagePostamble }),\n conciseMode: true,\n },\n extensions: {\n plugins: allPlugins,\n ...(mirrorNodeConfig && {\n mirrorConfig: mirrorNodeConfig as Record<string, unknown>,\n }),\n },\n ...(this.options.mcpServers && {\n mcp: {\n servers: this.options.mcpServers,\n autoConnect: true,\n },\n }),\n debug: {\n verbose,\n silent: disableLogging ?? false,\n },\n };\n }\n\n /**\n * Configures the HCS-10 plugin with the state manager.\n * \n * @param allPlugins - Array of all plugins\n */\n private configureHCS10Plugin(allPlugins: BasePlugin[]): void {\n const hcs10 = allPlugins.find((p) => p.id === 'hcs-10');\n if (hcs10) {\n (hcs10 as { appConfig?: Record<string, unknown> }).appConfig = {\n stateManager: this.stateManager,\n };\n }\n }\n\n /**\n * Create a ConversationalAgent with specific plugins enabled\n */\n private static withPlugins(\n options: ConversationalAgentOptions,\n plugins: string[]\n ): ConversationalAgent {\n return new ConversationalAgent({\n ...options,\n enabledPlugins: plugins,\n });\n }\n\n /**\n * Create a ConversationalAgent with only HTS (Hedera Token Service) tools enabled\n */\n static withHTS(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hts-token']);\n }\n\n /**\n * Create a ConversationalAgent with only HCS-2 tools enabled\n */\n static withHCS2(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hcs-2']);\n }\n\n /**\n * Create a ConversationalAgent with only HCS-10 tools enabled\n */\n static withHCS10(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hcs-10']);\n }\n\n /**\n * Create a ConversationalAgent with only inscription tools enabled\n */\n static withInscribe(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['inscribe']);\n }\n\n /**\n * Create a ConversationalAgent with only account management tools enabled\n */\n static withAccount(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['account']);\n }\n\n /**\n * Create a ConversationalAgent with only file service tools enabled\n */\n static withFileService(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['file-service']);\n }\n\n /**\n * Create a ConversationalAgent with only consensus service tools enabled\n */\n static withConsensusService(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['consensus-service']);\n }\n\n /**\n * Create a ConversationalAgent with only smart contract tools enabled\n */\n static withSmartContract(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['smart-contract']);\n }\n\n /**\n * Create a ConversationalAgent with all HCS standards plugins\n */\n static withAllStandards(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['hcs-10', 'hcs-2', 'inscribe']);\n }\n\n /**\n * Create a ConversationalAgent with minimal Hedera tools (no HCS standards)\n */\n static minimal(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, []);\n }\n\n /**\n * Create a ConversationalAgent with MCP servers configured\n */\n static withMCP(\n options: ConversationalAgentOptions,\n mcpServers: MCPServerConfig[]\n ): ConversationalAgent {\n return new ConversationalAgent({\n ...options,\n mcpServers,\n });\n }\n\n /**\n * Detect the private key type by querying the account info from mirror node\n * @param {string} accountId - The Hedera account ID\n * @param {string} privateKey - The private key string\n * @param {NetworkType} network - The Hedera network\n * @returns {Promise<PrivateKey>} The appropriate PrivateKey instance\n */\n private async detectPrivateKeyType(\n accountId: string,\n privateKey: string,\n network: NetworkType\n ): Promise<PrivateKey> {\n const mirrorNode = new HederaMirrorNode(network as 'testnet' | 'mainnet');\n const accountInfo = await mirrorNode.requestAccount(accountId);\n\n const keyType = accountInfo?.key?._type || '';\n\n if (keyType?.toLowerCase()?.includes('ecdsa')) {\n return PrivateKey.fromStringECDSA(privateKey);\n } else {\n return PrivateKey.fromStringED25519(privateKey);\n }\n }\n\n /**\n * Clean up resources\n */\n async cleanup(): Promise<void> {\n if (this.contentStoreManager) {\n await this.contentStoreManager.dispose();\n this.logger.info('ContentStoreManager cleaned up');\n }\n // Agent cleanup if needed\n if (this.agent) {\n // Add agent cleanup if available\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index6.js","sources":["../../src/conversational-agent.ts"],"sourcesContent":["import {\n ServerSigner,\n getAllHederaCorePlugins,\n BasePlugin,\n} from 'hedera-agent-kit';\nimport {\n HederaMirrorNode,\n Logger,\n type NetworkType,\n} from '@hashgraphonline/standards-sdk';\nimport { createAgent } from './agent-factory';\nimport { LangChainProvider } from './providers';\nimport type { ChatResponse, ConversationContext } from './base-agent';\nimport { ChatOpenAI } from '@langchain/openai';\nimport { HumanMessage, AIMessage } from '@langchain/core/messages';\nimport type { AgentOperationalMode, MirrorNodeConfig } from 'hedera-agent-kit';\nimport { HCS10Plugin } from './plugins/hcs-10/HCS10Plugin';\nimport { HCS2Plugin } from './plugins/hcs-2/HCS2Plugin';\nimport { InscribePlugin } from './plugins/inscribe/InscribePlugin';\nimport { HbarTransferPlugin } from './plugins/hbar-transfer/HbarTransferPlugin';\nimport { OpenConvaiState } from '@hashgraphonline/standards-agent-kit';\nimport type { IStateManager } from '@hashgraphonline/standards-agent-kit';\nimport { PrivateKey } from '@hashgraph/sdk';\nimport { getSystemMessage } from './config/system-message';\nimport type { MCPServerConfig, MCPConnectionStatus } from './mcp/types';\nimport { ContentStoreManager } from './services/ContentStoreManager';\nimport { SmartMemoryManager, type SmartMemoryConfig } from './memory';\n\nexport type ToolDescriptor = {\n name: string;\n namespace?: string;\n};\n\nexport type ChatHistoryItem = {\n type: 'human' | 'ai';\n content: string;\n};\n\nexport type AgentInstance = ReturnType<typeof createAgent>;\n\nexport type MirrorNetwork = 'testnet' | 'mainnet' | 'previewnet';\n\nconst DEFAULT_MODEL_NAME = 'gpt-4o';\nconst DEFAULT_TEMPERATURE = 0.1;\nconst DEFAULT_NETWORK = 'testnet';\nconst DEFAULT_OPERATIONAL_MODE: AgentOperationalMode = 'autonomous';\n\nexport interface ConversationalAgentOptions {\n accountId: string;\n privateKey: string;\n network?: NetworkType;\n openAIApiKey: string;\n openAIModelName?: string;\n verbose?: boolean;\n operationalMode?: AgentOperationalMode;\n userAccountId?: string;\n customSystemMessagePreamble?: string;\n customSystemMessagePostamble?: string;\n additionalPlugins?: BasePlugin[];\n stateManager?: IStateManager;\n scheduleUserTransactionsInBytesMode?: boolean;\n mirrorNodeConfig?: MirrorNodeConfig;\n disableLogging?: boolean;\n enabledPlugins?: string[];\n toolFilter?: (tool: { name: string; namespace?: string }) => boolean;\n mcpServers?: MCPServerConfig[];\n \n /** Enable automatic entity memory functionality (default: true) */\n entityMemoryEnabled?: boolean;\n \n /** Configuration for entity memory system */\n entityMemoryConfig?: SmartMemoryConfig;\n}\n\n/**\n * The ConversationalAgent class is an optional wrapper around the HederaConversationalAgent class,\n * which includes the OpenConvAIPlugin and the OpenConvaiState by default.\n * If you want to use a different plugin or state manager, you can pass them in the options.\n * This class is not required and the plugin can be used directly with the HederaConversationalAgent class.\n *\n * @param options - The options for the ConversationalAgent.\n * @returns A new instance of the ConversationalAgent class.\n */\nexport class ConversationalAgent {\n protected agent?: AgentInstance;\n public hcs10Plugin: HCS10Plugin;\n public hcs2Plugin: HCS2Plugin;\n public inscribePlugin: InscribePlugin;\n public hbarTransferPlugin: HbarTransferPlugin;\n public stateManager: IStateManager;\n private options: ConversationalAgentOptions;\n protected logger: Logger;\n private contentStoreManager?: ContentStoreManager;\n private memoryManager?: SmartMemoryManager | undefined;\n private mcpConnectionStatus: Map<string, MCPConnectionStatus> = new Map();\n\n constructor(options: ConversationalAgentOptions) {\n this.options = options;\n this.stateManager = options.stateManager || new OpenConvaiState();\n this.hcs10Plugin = new HCS10Plugin();\n this.hcs2Plugin = new HCS2Plugin();\n this.inscribePlugin = new InscribePlugin();\n this.hbarTransferPlugin = new HbarTransferPlugin();\n this.logger = new Logger({\n module: 'ConversationalAgent',\n silent: options.disableLogging || false,\n });\n \n if (this.options.entityMemoryEnabled !== false) {\n this.memoryManager = new SmartMemoryManager(this.options.entityMemoryConfig);\n this.logger.info('Entity memory initialized');\n }\n }\n\n /**\n * Initialize the conversational agent with Hedera network connection and AI configuration\n * @throws {Error} If account ID or private key is missing\n * @throws {Error} If initialization fails\n */\n async initialize(): Promise<void> {\n const {\n accountId,\n privateKey,\n network = DEFAULT_NETWORK,\n openAIApiKey,\n openAIModelName = DEFAULT_MODEL_NAME,\n } = this.options;\n\n this.validateOptions(accountId, privateKey);\n\n try {\n const privateKeyInstance = await this.detectPrivateKeyType(\n accountId!,\n privateKey!,\n network\n );\n\n const serverSigner = new ServerSigner(\n accountId!,\n privateKeyInstance,\n network as MirrorNetwork\n );\n\n const allPlugins = this.preparePlugins();\n\n const llm = new ChatOpenAI({\n apiKey: openAIApiKey,\n modelName: openAIModelName,\n temperature: DEFAULT_TEMPERATURE,\n });\n\n const agentConfig = this.createAgentConfig(serverSigner, llm, allPlugins);\n this.agent = createAgent(agentConfig);\n\n this.configureHCS10Plugin(allPlugins);\n\n if (this.options.mcpServers && this.options.mcpServers.length > 0) {\n this.contentStoreManager = new ContentStoreManager();\n await this.contentStoreManager.initialize();\n this.logger.info('ContentStoreManager initialized for MCP content reference support');\n }\n\n await this.agent.boot();\n\n // Start MCP connections asynchronously after agent is booted\n if (this.options.mcpServers && this.options.mcpServers.length > 0) {\n this.connectMCP();\n }\n } catch (error) {\n this.logger.error('Failed to initialize ConversationalAgent:', error);\n throw error;\n }\n }\n\n /**\n * Get the HCS-10 plugin instance\n * @returns {HCS10Plugin} The HCS-10 plugin instance\n */\n getPlugin(): HCS10Plugin {\n return this.hcs10Plugin;\n }\n\n /**\n * Get the state manager instance\n * @returns {IStateManager} The state manager instance\n */\n getStateManager(): IStateManager {\n return this.stateManager;\n }\n\n /**\n * Get the underlying agent instance\n * @returns {ReturnType<typeof createAgent>} The agent instance\n * @throws {Error} If agent is not initialized\n */\n getAgent(): ReturnType<typeof createAgent> {\n if (!this.agent) {\n throw new Error('Agent not initialized. Call initialize() first.');\n }\n return this.agent;\n }\n\n /**\n * Get the conversational agent instance (alias for getAgent)\n * @returns {ReturnType<typeof createAgent>} The agent instance\n * @throws {Error} If agent is not initialized\n */\n getConversationalAgent(): ReturnType<typeof createAgent> {\n return this.getAgent();\n }\n\n /**\n * Process a message through the conversational agent\n * @param {string} message - The message to process\n * @param {Array<{type: 'human' | 'ai'; content: string}>} chatHistory - Previous chat history\n * @returns {Promise<ChatResponse>} The agent's response\n * @throws {Error} If agent is not initialized\n */\n async processMessage(\n message: string,\n chatHistory: ChatHistoryItem[] = []\n ): Promise<ChatResponse> {\n if (!this.agent) {\n throw new Error('Agent not initialized. Call initialize() first.');\n }\n\n try {\n const resolvedMessage = this.memoryManager \n ? await this.resolveEntitiesInMessage(message)\n : message;\n\n const messages = chatHistory.map((msg) => {\n if (msg.type === 'human') {\n return new HumanMessage(msg.content);\n } else {\n return new AIMessage(msg.content);\n }\n });\n\n const context: ConversationContext = {\n messages,\n };\n\n const response = await this.agent.chat(resolvedMessage, context);\n \n if (this.memoryManager) {\n await this.extractAndStoreEntities(response, message);\n }\n \n this.logger.info('Message processed successfully');\n \n return response;\n } catch (error) {\n this.logger.error('Error processing message:', error);\n throw error;\n }\n }\n\n /**\n * Validates initialization options and throws if required fields are missing.\n * \n * @param accountId - The Hedera account ID\n * @param privateKey - The private key for the account\n * @throws {Error} If required fields are missing\n */\n private validateOptions(accountId?: string, privateKey?: string): void {\n if (!accountId || !privateKey) {\n throw new Error('Account ID and private key are required');\n }\n }\n\n /**\n * Prepares the list of plugins to use based on configuration.\n * \n * @returns Array of plugins to initialize with the agent\n */\n private preparePlugins(): BasePlugin[] {\n const { additionalPlugins = [], enabledPlugins } = this.options;\n \n const standardPlugins = [\n this.hcs10Plugin,\n this.hcs2Plugin,\n this.inscribePlugin,\n this.hbarTransferPlugin,\n ];\n \n const corePlugins: BasePlugin[] = getAllHederaCorePlugins();\n \n if (enabledPlugins) {\n const enabledSet = new Set(enabledPlugins);\n const filteredPlugins = [...standardPlugins, ...corePlugins].filter(\n (plugin) => enabledSet.has(plugin.id)\n );\n return [...filteredPlugins, ...additionalPlugins];\n }\n \n return [...standardPlugins, ...corePlugins, ...additionalPlugins];\n }\n\n /**\n * Creates the agent configuration object.\n * \n * @param serverSigner - The server signer instance\n * @param llm - The language model instance\n * @param allPlugins - Array of plugins to use\n * @returns Configuration object for creating the agent\n */\n private createAgentConfig(\n serverSigner: ServerSigner,\n llm: ChatOpenAI,\n allPlugins: BasePlugin[]\n ): Parameters<typeof createAgent>[0] {\n const {\n operationalMode = DEFAULT_OPERATIONAL_MODE,\n userAccountId,\n scheduleUserTransactionsInBytesMode,\n customSystemMessagePreamble,\n customSystemMessagePostamble,\n verbose = false,\n mirrorNodeConfig,\n disableLogging,\n accountId = '',\n } = this.options;\n\n return {\n framework: 'langchain',\n signer: serverSigner,\n execution: {\n mode: operationalMode === 'autonomous' ? 'direct' : 'bytes',\n operationalMode: operationalMode,\n ...(userAccountId && { userAccountId }),\n ...(scheduleUserTransactionsInBytesMode !== undefined && {\n scheduleUserTransactionsInBytesMode: scheduleUserTransactionsInBytesMode,\n scheduleUserTransactions: scheduleUserTransactionsInBytesMode,\n }),\n },\n ai: {\n provider: new LangChainProvider(llm),\n temperature: DEFAULT_TEMPERATURE,\n },\n filtering: {\n toolPredicate: (tool: ToolDescriptor): boolean => {\n if (tool.name === 'hedera-account-transfer-hbar') return false;\n if (this.options.toolFilter && !this.options.toolFilter(tool)) {\n return false;\n }\n return true;\n },\n },\n messaging: {\n systemPreamble:\n customSystemMessagePreamble || getSystemMessage(accountId),\n ...(customSystemMessagePostamble && { systemPostamble: customSystemMessagePostamble }),\n conciseMode: true,\n },\n extensions: {\n plugins: allPlugins,\n ...(mirrorNodeConfig && {\n mirrorConfig: mirrorNodeConfig as Record<string, unknown>,\n }),\n },\n ...(this.options.mcpServers && {\n mcp: {\n servers: this.options.mcpServers,\n autoConnect: false,\n },\n }),\n debug: {\n verbose,\n silent: disableLogging ?? false,\n },\n };\n }\n\n /**\n * Configures the HCS-10 plugin with the state manager.\n * \n * @param allPlugins - Array of all plugins\n */\n private configureHCS10Plugin(allPlugins: BasePlugin[]): void {\n const hcs10 = allPlugins.find((p) => p.id === 'hcs-10');\n if (hcs10) {\n (hcs10 as BasePlugin & { appConfig?: Record<string, unknown> }).appConfig = {\n stateManager: this.stateManager,\n };\n }\n }\n\n /**\n * Create a ConversationalAgent with specific plugins enabled\n */\n private static withPlugins(\n options: ConversationalAgentOptions,\n plugins: string[]\n ): ConversationalAgent {\n return new ConversationalAgent({\n ...options,\n enabledPlugins: plugins,\n });\n }\n\n /**\n * Create a ConversationalAgent with only HTS (Hedera Token Service) tools enabled\n */\n static withHTS(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hts-token']);\n }\n\n /**\n * Create a ConversationalAgent with only HCS-2 tools enabled\n */\n static withHCS2(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hcs-2']);\n }\n\n /**\n * Create a ConversationalAgent with only HCS-10 tools enabled\n */\n static withHCS10(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['hcs-10']);\n }\n\n /**\n * Create a ConversationalAgent with only inscription tools enabled\n */\n static withInscribe(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['inscribe']);\n }\n\n /**\n * Create a ConversationalAgent with only account management tools enabled\n */\n static withAccount(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, ['account']);\n }\n\n /**\n * Create a ConversationalAgent with only file service tools enabled\n */\n static withFileService(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['file-service']);\n }\n\n /**\n * Create a ConversationalAgent with only consensus service tools enabled\n */\n static withConsensusService(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['consensus-service']);\n }\n\n /**\n * Create a ConversationalAgent with only smart contract tools enabled\n */\n static withSmartContract(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['smart-contract']);\n }\n\n /**\n * Create a ConversationalAgent with all HCS standards plugins\n */\n static withAllStandards(\n options: ConversationalAgentOptions\n ): ConversationalAgent {\n return this.withPlugins(options, ['hcs-10', 'hcs-2', 'inscribe']);\n }\n\n /**\n * Create a ConversationalAgent with minimal Hedera tools (no HCS standards)\n */\n static minimal(options: ConversationalAgentOptions): ConversationalAgent {\n return this.withPlugins(options, []);\n }\n\n /**\n * Create a ConversationalAgent with MCP servers configured\n */\n static withMCP(\n options: ConversationalAgentOptions,\n mcpServers: MCPServerConfig[]\n ): ConversationalAgent {\n return new ConversationalAgent({\n ...options,\n mcpServers,\n });\n }\n\n /**\n * Detect the private key type by querying the account info from mirror node\n * @param {string} accountId - The Hedera account ID\n * @param {string} privateKey - The private key string\n * @param {NetworkType} network - The Hedera network\n * @returns {Promise<PrivateKey>} The appropriate PrivateKey instance\n */\n private async detectPrivateKeyType(\n accountId: string,\n privateKey: string,\n network: NetworkType\n ): Promise<PrivateKey> {\n const mirrorNode = new HederaMirrorNode(network as 'testnet' | 'mainnet');\n const accountInfo = await mirrorNode.requestAccount(accountId);\n\n const keyType = accountInfo?.key?._type || '';\n\n if (keyType?.toLowerCase()?.includes('ecdsa')) {\n return PrivateKey.fromStringECDSA(privateKey);\n } else {\n return PrivateKey.fromStringED25519(privateKey);\n }\n }\n\n /**\n * Resolve entity references in the message content\n * @param content - Message content to resolve\n * @returns Resolved message content with entity IDs replaced\n */\n private async resolveEntitiesInMessage(content: string): Promise<string> {\n if (!this.memoryManager) {\n return content;\n }\n\n try {\n this.logger.info(`Starting entity resolution for message: \"${content.substring(0, 100)}...\"`);\n \n if (!content || typeof content !== 'string') {\n this.logger.warn('Invalid content provided for entity resolution');\n return content || '';\n }\n\n if (content.length > 5000) {\n this.logger.warn('Content too long for entity resolution, truncating');\n content = content.substring(0, 5000);\n }\n\n let resolvedContent = content;\n\n const patterns = [\n /\\b(my|the|our)\\s+(token|account|topic|schedule)\\b/gi,\n /'([^']+)'/g,\n /\"([^\"]+)\"/g,\n /\\b([A-Z][A-Za-z0-9_-]{2,})\\b/g\n ];\n\n for (const pattern of patterns) {\n try {\n let match;\n const matches: any[] = [];\n while ((match = pattern.exec(resolvedContent)) !== null) {\n matches.push(match);\n if (!pattern.global) break;\n }\n \n for (const match of matches) {\n try {\n const originalRef = match[0];\n const entityName = match[1] || match[0];\n \n if (entityName.length > 50) {\n this.logger.debug(`Skipping overly long entity name: ${entityName.substring(0, 20)}...`);\n continue;\n }\n \n const commonWords = ['the', 'my', 'our', 'this', 'that', 'it', 'is', 'are', 'was', 'will'];\n if (commonWords.includes(entityName.toLowerCase())) {\n continue;\n }\n \n let entityAssociations: any[] = [];\n \n if (match[1] && ['token', 'account', 'topic', 'schedule'].includes(match[1].toLowerCase())) {\n const entityType = match[1].toLowerCase();\n entityAssociations = this.memoryManager.resolveEntityReference(\n entityName, \n { entityType, limit: 1, fuzzyMatch: true }\n );\n } else {\n entityAssociations = this.memoryManager.resolveEntityReference(\n entityName,\n { limit: 1, fuzzyMatch: false }\n );\n }\n\n if (entityAssociations.length > 0) {\n const entity = entityAssociations[0];\n if (entity.entityId && entity.entityId.trim().length > 0) {\n if (entityAssociations.length > 1) {\n this.logger.info(`Multiple entities found for \"${originalRef}\", using most recent: ${entity.entityName}`);\n }\n \n resolvedContent = resolvedContent.replace(originalRef, entity.entityId);\n this.logger.info(`Resolved entity reference: \"${originalRef}\" -> ${entity.entityId}`);\n }\n }\n } catch (matchError) {\n this.logger.debug('Error processing entity match:', matchError);\n continue;\n }\n }\n } catch (patternError) {\n this.logger.debug('Error processing pattern:', patternError);\n continue;\n }\n }\n\n if (resolvedContent !== content) {\n this.logger.info(`Entity resolution completed. Original: \"${content}\" -> Resolved: \"${resolvedContent}\"`);\n } else {\n this.logger.info('No entity references resolved in message');\n }\n \n return resolvedContent;\n } catch (error) {\n this.logger.warn('Entity resolution failed, using original message:', error);\n return content;\n }\n }\n\n /**\n * Extract and store entity associations from transaction responses\n * @param response - Agent response containing potential entity information\n * @param originalMessage - Original user message for context\n */\n private async extractAndStoreEntities(response: any, originalMessage: string): Promise<void> {\n if (!this.memoryManager) {\n return;\n }\n\n try {\n this.logger.info('Starting entity extraction from response');\n \n const entityPatterns = {\n token: /(?:token|Token)\\s*(?:ID\\s*[:\"*\\s]*)?([0-9]+\\.[0-9]+\\.[0-9]+)/g,\n account: /(?:account|Account)\\s*(?:ID\\s*[:\"*\\s]*)?([0-9]+\\.[0-9]+\\.[0-9]+)/g,\n topic: /(?:topic|Topic)\\s*(?:ID\\s*[:\"*\\s]*)?([0-9]+\\.[0-9]+\\.[0-9]+)/g,\n schedule: /(?:schedule|Schedule)\\s*(?:ID\\s*[:\"*\\s]*)?([0-9]+\\.[0-9]+\\.[0-9]+)/g\n };\n\n const responseText = typeof response === 'string' ? response : JSON.stringify(response);\n this.logger.info(`Searching response text: ${responseText.substring(0, 200)}...`);\n \n for (const [entityType, pattern] of Object.entries(entityPatterns)) {\n let match;\n while ((match = pattern.exec(responseText)) !== null) {\n const entityId = match[1];\n \n let entityName = `${entityType}-${entityId}`;\n \n const namePatterns = [\n new RegExp(`(?:called|named)\\\\s+([\\\\w\\\\d_-]+)`, 'i'),\n new RegExp(`(?:token|account|topic|schedule)\\\\s+([\\\\w\\\\d_-]+)`, 'i'),\n new RegExp(`([\\\\w\\\\d_-]+)\\\\s+${entityType}`, 'i')\n ];\n \n for (const namePattern of namePatterns) {\n const nameMatch = originalMessage.match(namePattern);\n if (nameMatch && nameMatch[1]) {\n entityName = nameMatch[1].trim();\n break;\n }\n }\n \n this.logger.info(`Extracting entity: ${entityName} (${entityType}) -> ${entityId}`);\n \n this.memoryManager.storeEntityAssociation(\n entityId,\n entityName,\n entityType,\n this.extractTransactionId(response)\n );\n \n this.logger.info(`Stored entity association: ${entityName} (${entityId})`);\n }\n }\n \n this.logger.info('Entity extraction completed');\n } catch (error) {\n this.logger.warn('Entity extraction failed:', error);\n }\n }\n\n /**\n * Extract transaction ID from response if available\n * @param response - Transaction response\n * @returns Transaction ID or undefined\n */\n private extractTransactionId(response: any): string | undefined {\n try {\n if (typeof response === 'object' && response?.transactionId) {\n return response.transactionId;\n }\n if (typeof response === 'string') {\n const match = response.match(/transaction[\\s\\w]*ID[\\s:\"]*([0-9a-fA-F@\\.\\-]+)/i);\n return match ? match[1] : undefined;\n }\n return undefined;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Connect to MCP servers asynchronously\n * @private\n */\n private connectMCP(): void {\n if (!this.agent || !this.options.mcpServers) {\n return;\n }\n\n // Initialize connection status for all servers\n this.options.mcpServers.forEach(server => {\n this.mcpConnectionStatus.set(server.name, {\n serverName: server.name,\n connected: false,\n tools: []\n });\n });\n\n // Call the agent's MCP connection method if available\n if (typeof (this.agent as any).connectMCPServers === 'function') {\n (this.agent as any).connectMCPServers().catch((error: any) => {\n this.logger.error('Failed to connect MCP servers:', error);\n });\n } else {\n // Fallback for agents that don't support async MCP connections\n this.startConnections();\n }\n }\n\n /**\n * Start MCP connections without blocking initialization\n * @private\n */\n private async startConnections(): Promise<void> {\n if (!this.agent || !this.options.mcpServers) {\n return;\n }\n\n try {\n this.logger.info('Starting MCP server connections asynchronously...');\n \n for (const server of this.options.mcpServers) {\n this.connectServer(server);\n }\n } catch (error) {\n this.logger.error('Error starting MCP connections:', error);\n }\n }\n\n /**\n * Connect to a single MCP server\n * @param {MCPServerConfig} server - Server configuration\n * @private\n */\n private async connectServer(server: MCPServerConfig): Promise<void> {\n try {\n this.logger.info(`Connecting to MCP server: ${server.name}`);\n \n // TODO: Implement actual MCP connection logic\n // For now, we'll simulate the connection process\n const status = this.mcpConnectionStatus.get(server.name);\n if (status) {\n // Simulate connection success after a delay\n setTimeout(() => {\n status.connected = true;\n this.logger.info(`MCP server ${server.name} connected successfully`);\n }, Math.random() * 2000 + 1000); // 1-3 second delay\n }\n \n } catch (error) {\n this.logger.error(`Failed to connect to MCP server ${server.name}:`, error);\n \n const status = this.mcpConnectionStatus.get(server.name);\n if (status) {\n status.connected = false;\n status.error = error instanceof Error ? error.message : 'Unknown error';\n }\n }\n }\n\n /**\n * Get MCP connection status for all servers\n * @returns {Map<string, MCPConnectionStatus>} Connection status map\n */\n getMCPConnectionStatus(): Map<string, MCPConnectionStatus> {\n return new Map(this.mcpConnectionStatus);\n }\n\n /**\n * Check if a specific MCP server is connected\n * @param {string} serverName - Name of the server to check\n * @returns {boolean} True if connected, false otherwise\n */\n isMCPServerConnected(serverName: string): boolean {\n const status = this.mcpConnectionStatus.get(serverName);\n return status?.connected ?? false;\n }\n\n /**\n * Clean up resources\n */\n async cleanup(): Promise<void> {\n try {\n this.logger.info('Cleaning up ConversationalAgent...');\n \n if (this.memoryManager) {\n try {\n this.memoryManager.dispose();\n this.logger.info('Memory manager cleaned up successfully');\n } catch (error) {\n this.logger.warn('Error cleaning up memory manager:', error);\n }\n this.memoryManager = undefined as any;\n }\n \n if (this.contentStoreManager) {\n await this.contentStoreManager.dispose();\n this.logger.info('ContentStoreManager cleaned up');\n }\n \n this.logger.info('ConversationalAgent cleanup completed');\n } catch (error) {\n this.logger.error('Error during cleanup:', error);\n }\n }\n}\n"],"names":["match"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { createOpenAIToolsAgent } from "langchain/agents";
2
- import { ContentAwareAgentExecutor } from "./index15.js";
2
+ import { ContentAwareAgentExecutor } from "./index19.js";
3
3
  import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
4
4
  import { ChatOpenAI } from "@langchain/openai";
5
5
  import { TokenUsageCallbackHandler, calculateTokenCostSync, getAllHederaCorePlugins, HederaAgentKit } from "hedera-agent-kit";
6
6
  import { BaseAgent } from "./index7.js";
7
- import { MCPClientManager } from "./index16.js";
8
- import { convertMCPToolToLangChain } from "./index17.js";
9
- import { SmartMemoryManager } from "./index18.js";
7
+ import { MCPClientManager } from "./index20.js";
8
+ import { convertMCPToolToLangChain } from "./index21.js";
9
+ import { SmartMemoryManager } from "./index15.js";
10
10
  class LangChainAgent extends BaseAgent {
11
11
  constructor() {
12
12
  super(...arguments);
@@ -25,7 +25,12 @@ class LangChainAgent extends BaseAgent {
25
25
  const allTools = this.agentKit.getAggregatedLangChainTools();
26
26
  this.tools = this.filterTools(allTools);
27
27
  if (this.config.mcp?.servers && this.config.mcp.servers.length > 0) {
28
- await this.initializeMCP();
28
+ if (this.config.mcp.autoConnect !== false) {
29
+ await this.initializeMCP();
30
+ } else {
31
+ this.logger.info("MCP servers configured but autoConnect=false, skipping synchronous connection");
32
+ this.mcpManager = new MCPClientManager(this.logger);
33
+ }
29
34
  }
30
35
  this.smartMemory = new SmartMemoryManager({
31
36
  modelName,
@@ -198,7 +203,7 @@ class LangChainAgent extends BaseAgent {
198
203
  { plugins },
199
204
  operationalMode,
200
205
  this.config.execution?.userAccountId,
201
- this.config.execution?.scheduleUserTransactionsInBytesMode ?? true,
206
+ this.config.execution?.scheduleUserTransactionsInBytesMode ?? false,
202
207
  void 0,
203
208
  modelName,
204
209
  this.config.extensions?.mirrorConfig,
@@ -253,9 +258,29 @@ class LangChainAgent extends BaseAgent {
253
258
  cost = calculateTokenCostSync(tokenUsage);
254
259
  }
255
260
  }
261
+ let userFriendlyMessage = "Sorry, I encountered an error processing your request.";
262
+ let userFriendlyOutput = "Sorry, I encountered an error processing your request.";
263
+ if (errorMessage.includes("429")) {
264
+ if (errorMessage.includes("quota")) {
265
+ userFriendlyMessage = "API quota exceeded. Please check your OpenAI billing and usage limits.";
266
+ userFriendlyOutput = "I'm currently unable to respond because the API quota has been exceeded. Please check your OpenAI account billing and usage limits, then try again.";
267
+ } else {
268
+ userFriendlyMessage = "Too many requests. Please wait a moment and try again.";
269
+ userFriendlyOutput = "I'm receiving too many requests right now. Please wait a moment and try again.";
270
+ }
271
+ } else if (errorMessage.includes("401") || errorMessage.includes("unauthorized")) {
272
+ userFriendlyMessage = "API authentication failed. Please check your API key configuration.";
273
+ userFriendlyOutput = "There's an issue with the API authentication. Please check your OpenAI API key configuration in settings.";
274
+ } else if (errorMessage.includes("timeout")) {
275
+ userFriendlyMessage = "Request timed out. Please try again.";
276
+ userFriendlyOutput = "The request took too long to process. Please try again.";
277
+ } else if (errorMessage.includes("network") || errorMessage.includes("fetch")) {
278
+ userFriendlyMessage = "Network error. Please check your internet connection and try again.";
279
+ userFriendlyOutput = "There was a network error. Please check your internet connection and try again.";
280
+ }
256
281
  const errorResponse = {
257
- output: "Sorry, I encountered an error processing your request.",
258
- message: "Error processing request.",
282
+ output: userFriendlyOutput,
283
+ message: userFriendlyMessage,
259
284
  error: errorMessage,
260
285
  notes: []
261
286
  };
@@ -296,6 +321,55 @@ class LangChainAgent extends BaseAgent {
296
321
  }
297
322
  }
298
323
  }
324
+ /**
325
+ * Connect to MCP servers asynchronously after agent boot
326
+ */
327
+ async connectMCPServers() {
328
+ if (!this.config.mcp?.servers || this.config.mcp.servers.length === 0) {
329
+ return;
330
+ }
331
+ if (!this.mcpManager) {
332
+ this.logger.warn("MCP manager not initialized. Cannot connect to servers.");
333
+ return;
334
+ }
335
+ this.logger.info("Starting async MCP server connections...");
336
+ for (const serverConfig of this.config.mcp.servers) {
337
+ this.connectServer(serverConfig).catch((error) => {
338
+ this.logger.error(`Connection to MCP server ${serverConfig.name} failed:`, error);
339
+ });
340
+ }
341
+ }
342
+ /**
343
+ * Connect to a single MCP server
344
+ */
345
+ async connectServer(serverConfig) {
346
+ try {
347
+ this.logger.info(`Connecting to MCP server: ${serverConfig.name}`);
348
+ const status = await this.mcpManager.connectServer(serverConfig);
349
+ if (status.connected) {
350
+ this.logger.info(
351
+ `Connected to MCP server ${status.serverName} with ${status.tools.length} tools`
352
+ );
353
+ for (const mcpTool of status.tools) {
354
+ const langchainTool = convertMCPToolToLangChain(
355
+ mcpTool,
356
+ this.mcpManager,
357
+ serverConfig
358
+ );
359
+ this.tools.push(langchainTool);
360
+ }
361
+ if (this.initialized && this.executor) {
362
+ await this.createExecutor();
363
+ }
364
+ } else {
365
+ this.logger.error(
366
+ `Failed to connect to MCP server ${status.serverName}: ${status.error}`
367
+ );
368
+ }
369
+ } catch (error) {
370
+ this.logger.error(`Error connecting to MCP server ${serverConfig.name}:`, error);
371
+ }
372
+ }
299
373
  /**
300
374
  * Check if a string is valid JSON
301
375
  */