@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.
- package/dist/cjs/conversational-agent.d.ts +67 -8
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/langchain/ContentAwareAgentExecutor.d.ts +4 -6
- package/dist/cjs/langchain-agent.d.ts +8 -0
- package/dist/cjs/memory/SmartMemoryManager.d.ts +58 -21
- package/dist/cjs/memory/index.d.ts +1 -1
- package/dist/esm/index.js +8 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index12.js +124 -46
- package/dist/esm/index12.js.map +1 -1
- package/dist/esm/index13.js +178 -13
- package/dist/esm/index13.js.map +1 -1
- package/dist/esm/index14.js +604 -100
- package/dist/esm/index14.js.map +1 -1
- package/dist/esm/index15.js +453 -59
- package/dist/esm/index15.js.map +1 -1
- package/dist/esm/index16.js +44 -172
- package/dist/esm/index16.js.map +1 -1
- package/dist/esm/index17.js +11 -156
- package/dist/esm/index17.js.map +1 -1
- package/dist/esm/index18.js +106 -191
- package/dist/esm/index18.js.map +1 -1
- package/dist/esm/index19.js +7 -90
- package/dist/esm/index19.js.map +1 -1
- package/dist/esm/index2.js +22 -13
- package/dist/esm/index2.js.map +1 -1
- package/dist/esm/index20.js +130 -616
- package/dist/esm/index20.js.map +1 -1
- package/dist/esm/index21.js +138 -215
- package/dist/esm/index21.js.map +1 -1
- package/dist/esm/index22.js +45 -159
- package/dist/esm/index22.js.map +1 -1
- package/dist/esm/index23.js +25 -121
- package/dist/esm/index23.js.map +1 -1
- package/dist/esm/index24.js +83 -56
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index25.js +236 -32
- package/dist/esm/index25.js.map +1 -1
- package/dist/esm/index5.js +1 -1
- package/dist/esm/index6.js +295 -17
- package/dist/esm/index6.js.map +1 -1
- package/dist/esm/index8.js +82 -8
- package/dist/esm/index8.js.map +1 -1
- package/dist/types/conversational-agent.d.ts +67 -8
- package/dist/types/index.d.ts +1 -0
- package/dist/types/langchain/ContentAwareAgentExecutor.d.ts +4 -6
- package/dist/types/langchain-agent.d.ts +8 -0
- package/dist/types/memory/SmartMemoryManager.d.ts +58 -21
- package/dist/types/memory/index.d.ts +1 -1
- package/package.json +3 -3
- package/src/context/ReferenceContextManager.ts +9 -4
- package/src/context/ReferenceResponseProcessor.ts +3 -4
- package/src/conversational-agent.ts +379 -31
- package/src/index.ts +2 -0
- package/src/langchain/ContentAwareAgentExecutor.ts +4 -97
- package/src/langchain-agent.ts +94 -11
- package/src/mcp/ContentProcessor.ts +13 -3
- package/src/mcp/adapters/langchain.ts +1 -9
- package/src/memory/ContentStorage.ts +3 -51
- package/src/memory/MemoryWindow.ts +4 -16
- package/src/memory/ReferenceIdGenerator.ts +0 -4
- package/src/memory/SmartMemoryManager.ts +400 -33
- package/src/memory/TokenCounter.ts +12 -16
- package/src/memory/index.ts +1 -1
- package/src/plugins/hcs-10/HCS10Plugin.ts +44 -14
- package/src/services/ContentStoreManager.ts +0 -3
- package/src/types/content-reference.ts +8 -8
- package/src/types/index.ts +0 -1
package/dist/esm/index6.js
CHANGED
|
@@ -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 "./
|
|
14
|
-
import { ContentStoreManager } from "./
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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:
|
|
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
|
-
|
|
348
|
-
|
|
349
|
-
this.
|
|
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 {
|
package/dist/esm/index6.js.map
CHANGED
|
@@ -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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"}
|
package/dist/esm/index8.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createOpenAIToolsAgent } from "langchain/agents";
|
|
2
|
-
import { ContentAwareAgentExecutor } from "./
|
|
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 "./
|
|
8
|
-
import { convertMCPToolToLangChain } from "./
|
|
9
|
-
import { SmartMemoryManager } from "./
|
|
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
|
-
|
|
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 ??
|
|
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:
|
|
258
|
-
message:
|
|
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
|
*/
|