@hashgraphonline/conversational-agent 0.1.204 → 0.1.206

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 (87) hide show
  1. package/dist/cjs/base-agent.d.ts +6 -0
  2. package/dist/cjs/context/ReferenceContextManager.d.ts +84 -0
  3. package/dist/cjs/context/ReferenceResponseProcessor.d.ts +76 -0
  4. package/dist/cjs/conversational-agent.d.ts +34 -0
  5. package/dist/cjs/index.cjs +1 -1
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs/langchain-agent.d.ts +1 -0
  8. package/dist/cjs/mcp/ContentProcessor.d.ts +37 -0
  9. package/dist/cjs/mcp/MCPClientManager.d.ts +19 -1
  10. package/dist/cjs/memory/ContentStorage.d.ts +205 -0
  11. package/dist/cjs/memory/MemoryWindow.d.ts +114 -0
  12. package/dist/cjs/memory/ReferenceIdGenerator.d.ts +45 -0
  13. package/dist/cjs/memory/SmartMemoryManager.d.ts +201 -0
  14. package/dist/cjs/memory/TokenCounter.d.ts +61 -0
  15. package/dist/cjs/memory/index.d.ts +7 -0
  16. package/dist/cjs/plugins/hbar-transfer/TransferHbarTool.d.ts +18 -0
  17. package/dist/cjs/services/ContentStoreManager.d.ts +54 -0
  18. package/dist/cjs/types/content-reference.d.ts +213 -0
  19. package/dist/cjs/types/index.d.ts +4 -0
  20. package/dist/esm/index12.js +15 -2
  21. package/dist/esm/index12.js.map +1 -1
  22. package/dist/esm/index14.js +119 -95
  23. package/dist/esm/index14.js.map +1 -1
  24. package/dist/esm/index15.js +159 -114
  25. package/dist/esm/index15.js.map +1 -1
  26. package/dist/esm/index16.js +122 -81
  27. package/dist/esm/index16.js.map +1 -1
  28. package/dist/esm/index17.js +236 -0
  29. package/dist/esm/index17.js.map +1 -0
  30. package/dist/esm/index18.js +95 -0
  31. package/dist/esm/index18.js.map +1 -0
  32. package/dist/esm/index19.js +663 -0
  33. package/dist/esm/index19.js.map +1 -0
  34. package/dist/esm/index2.js +3 -1
  35. package/dist/esm/index2.js.map +1 -1
  36. package/dist/esm/index20.js +233 -0
  37. package/dist/esm/index20.js.map +1 -0
  38. package/dist/esm/index21.js +182 -0
  39. package/dist/esm/index21.js.map +1 -0
  40. package/dist/esm/index22.js +126 -0
  41. package/dist/esm/index22.js.map +1 -0
  42. package/dist/esm/index23.js +68 -0
  43. package/dist/esm/index23.js.map +1 -0
  44. package/dist/esm/index24.js +38 -0
  45. package/dist/esm/index24.js.map +1 -0
  46. package/dist/esm/index6.js +143 -84
  47. package/dist/esm/index6.js.map +1 -1
  48. package/dist/esm/index7.js.map +1 -1
  49. package/dist/esm/index8.js +69 -5
  50. package/dist/esm/index8.js.map +1 -1
  51. package/dist/types/base-agent.d.ts +6 -0
  52. package/dist/types/context/ReferenceContextManager.d.ts +84 -0
  53. package/dist/types/context/ReferenceResponseProcessor.d.ts +76 -0
  54. package/dist/types/conversational-agent.d.ts +34 -0
  55. package/dist/types/langchain-agent.d.ts +1 -0
  56. package/dist/types/mcp/ContentProcessor.d.ts +37 -0
  57. package/dist/types/mcp/MCPClientManager.d.ts +19 -1
  58. package/dist/types/memory/ContentStorage.d.ts +205 -0
  59. package/dist/types/memory/MemoryWindow.d.ts +114 -0
  60. package/dist/types/memory/ReferenceIdGenerator.d.ts +45 -0
  61. package/dist/types/memory/SmartMemoryManager.d.ts +201 -0
  62. package/dist/types/memory/TokenCounter.d.ts +61 -0
  63. package/dist/types/memory/index.d.ts +7 -0
  64. package/dist/types/plugins/hbar-transfer/TransferHbarTool.d.ts +18 -0
  65. package/dist/types/services/ContentStoreManager.d.ts +54 -0
  66. package/dist/types/types/content-reference.d.ts +213 -0
  67. package/dist/types/types/index.d.ts +4 -0
  68. package/package.json +30 -26
  69. package/src/base-agent.ts +6 -0
  70. package/src/context/ReferenceContextManager.ts +345 -0
  71. package/src/context/ReferenceResponseProcessor.ts +296 -0
  72. package/src/conversational-agent.ts +166 -92
  73. package/src/langchain-agent.ts +89 -2
  74. package/src/mcp/ContentProcessor.ts +317 -0
  75. package/src/mcp/MCPClientManager.ts +61 -1
  76. package/src/mcp/adapters/langchain.ts +9 -4
  77. package/src/memory/ContentStorage.ts +954 -0
  78. package/src/memory/MemoryWindow.ts +247 -0
  79. package/src/memory/ReferenceIdGenerator.ts +84 -0
  80. package/src/memory/SmartMemoryManager.ts +323 -0
  81. package/src/memory/TokenCounter.ts +152 -0
  82. package/src/memory/index.ts +8 -0
  83. package/src/plugins/hbar-transfer/TransferHbarTool.ts +19 -1
  84. package/src/plugins/hcs-10/HCS10Plugin.ts +5 -4
  85. package/src/services/ContentStoreManager.ts +199 -0
  86. package/src/types/content-reference.ts +281 -0
  87. package/src/types/index.ts +6 -0
@@ -0,0 +1,126 @@
1
+ import { encoding_for_model } from "tiktoken";
2
+ const _TokenCounter = class _TokenCounter {
3
+ // Additional token for role specification
4
+ constructor(modelName = "gpt-4o") {
5
+ this.modelName = modelName;
6
+ try {
7
+ this.encoding = encoding_for_model(modelName);
8
+ } catch (error) {
9
+ console.warn(`Model ${modelName} not found, falling back to gpt-4o encoding`);
10
+ this.encoding = encoding_for_model("gpt-4o");
11
+ this.modelName = "gpt-4o";
12
+ }
13
+ }
14
+ /**
15
+ * Count tokens in raw text content
16
+ * @param text - The text to count tokens for
17
+ * @returns Number of tokens
18
+ */
19
+ countTokens(text) {
20
+ if (!text || text.trim() === "") {
21
+ return 0;
22
+ }
23
+ try {
24
+ const tokens = this.encoding.encode(text);
25
+ return tokens.length;
26
+ } catch (error) {
27
+ console.warn("Error counting tokens, falling back to word-based estimation:", error);
28
+ return Math.ceil(text.split(/\s+/).length * 1.3);
29
+ }
30
+ }
31
+ /**
32
+ * Count tokens for a single chat message including role overhead
33
+ * @param message - The message to count tokens for
34
+ * @returns Number of tokens including message formatting overhead
35
+ */
36
+ countMessageTokens(message) {
37
+ const contentTokens = this.countTokens(message.content);
38
+ const roleTokens = this.countTokens(this.getMessageRole(message));
39
+ return contentTokens + roleTokens + _TokenCounter.MESSAGE_OVERHEAD + _TokenCounter.ROLE_OVERHEAD;
40
+ }
41
+ /**
42
+ * Count tokens for multiple messages
43
+ * @param messages - Array of messages to count
44
+ * @returns Total token count for all messages
45
+ */
46
+ countMessagesTokens(messages) {
47
+ if (!messages || messages.length === 0) {
48
+ return 0;
49
+ }
50
+ return messages.reduce((total, message) => {
51
+ return total + this.countMessageTokens(message);
52
+ }, 0);
53
+ }
54
+ /**
55
+ * Estimate tokens for system prompt
56
+ * System prompts have slightly different overhead in chat completions
57
+ * @param systemPrompt - The system prompt text
58
+ * @returns Estimated token count
59
+ */
60
+ estimateSystemPromptTokens(systemPrompt) {
61
+ if (!systemPrompt || systemPrompt.trim() === "") {
62
+ return 0;
63
+ }
64
+ const contentTokens = this.countTokens(systemPrompt);
65
+ const roleTokens = this.countTokens("system");
66
+ return contentTokens + roleTokens + _TokenCounter.MESSAGE_OVERHEAD + _TokenCounter.ROLE_OVERHEAD;
67
+ }
68
+ /**
69
+ * Get total context size estimate including system prompt and messages
70
+ * @param systemPrompt - System prompt text
71
+ * @param messages - Conversation messages
72
+ * @returns Total estimated token count
73
+ */
74
+ estimateContextSize(systemPrompt, messages) {
75
+ const systemTokens = this.estimateSystemPromptTokens(systemPrompt);
76
+ const messageTokens = this.countMessagesTokens(messages);
77
+ const completionOverhead = 10;
78
+ return systemTokens + messageTokens + completionOverhead;
79
+ }
80
+ /**
81
+ * Get the role string for a message
82
+ * @param message - The message to get the role for
83
+ * @returns Role string ('user', 'assistant', 'system', etc.)
84
+ */
85
+ getMessageRole(message) {
86
+ const messageType = message._getType();
87
+ switch (messageType) {
88
+ case "human":
89
+ return "user";
90
+ case "ai":
91
+ return "assistant";
92
+ case "system":
93
+ return "system";
94
+ case "function":
95
+ return "function";
96
+ case "tool":
97
+ return "tool";
98
+ default:
99
+ return "user";
100
+ }
101
+ }
102
+ /**
103
+ * Get the model name being used for token counting
104
+ * @returns The tiktoken model name
105
+ */
106
+ getModelName() {
107
+ return this.modelName;
108
+ }
109
+ /**
110
+ * Clean up encoding resources
111
+ */
112
+ dispose() {
113
+ try {
114
+ this.encoding.free();
115
+ } catch (error) {
116
+ console.warn("Error disposing encoding:", error);
117
+ }
118
+ }
119
+ };
120
+ _TokenCounter.MESSAGE_OVERHEAD = 3;
121
+ _TokenCounter.ROLE_OVERHEAD = 1;
122
+ let TokenCounter = _TokenCounter;
123
+ export {
124
+ TokenCounter
125
+ };
126
+ //# sourceMappingURL=index22.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index22.js","sources":["../../src/memory/TokenCounter.ts"],"sourcesContent":["import { encoding_for_model } from 'tiktoken';\nimport type { TiktokenModel } from 'tiktoken';\nimport type { BaseMessage } from '@langchain/core/messages';\n\n/**\n * Token counter utility for OpenAI models using tiktoken encoding\n * Provides accurate token counting for text content and chat messages\n */\nexport class TokenCounter {\n private encoding: ReturnType<typeof encoding_for_model>;\n private modelName: TiktokenModel;\n\n // Token overhead per message for chat completion format\n private static readonly MESSAGE_OVERHEAD = 3; // <|start|>role<|end|>content<|end|>\n private static readonly ROLE_OVERHEAD = 1; // Additional token for role specification\n\n constructor(modelName: TiktokenModel = 'gpt-4o') {\n this.modelName = modelName;\n try {\n this.encoding = encoding_for_model(modelName);\n } catch (error) {\n // Fallback to gpt-4o if specific model encoding is not available\n console.warn(`Model ${modelName} not found, falling back to gpt-4o encoding`);\n this.encoding = encoding_for_model('gpt-4o');\n this.modelName = 'gpt-4o';\n }\n }\n\n /**\n * Count tokens in raw text content\n * @param text - The text to count tokens for\n * @returns Number of tokens\n */\n countTokens(text: string): number {\n if (!text || text.trim() === '') {\n return 0;\n }\n\n try {\n const tokens = this.encoding.encode(text);\n return tokens.length;\n } catch (error) {\n console.warn('Error counting tokens, falling back to word-based estimation:', error);\n // Fallback: rough estimation based on words (typically 1.3 tokens per word)\n return Math.ceil(text.split(/\\s+/).length * 1.3);\n }\n }\n\n /**\n * Count tokens for a single chat message including role overhead\n * @param message - The message to count tokens for\n * @returns Number of tokens including message formatting overhead\n */\n countMessageTokens(message: BaseMessage): number {\n const contentTokens = this.countTokens(message.content as string);\n const roleTokens = this.countTokens(this.getMessageRole(message));\n \n // Add overhead for message structure and role\n return contentTokens + roleTokens + TokenCounter.MESSAGE_OVERHEAD + TokenCounter.ROLE_OVERHEAD;\n }\n\n /**\n * Count tokens for multiple messages\n * @param messages - Array of messages to count\n * @returns Total token count for all messages\n */\n countMessagesTokens(messages: BaseMessage[]): number {\n if (!messages || messages.length === 0) {\n return 0;\n }\n\n return messages.reduce((total, message) => {\n return total + this.countMessageTokens(message);\n }, 0);\n }\n\n /**\n * Estimate tokens for system prompt\n * System prompts have slightly different overhead in chat completions\n * @param systemPrompt - The system prompt text\n * @returns Estimated token count\n */\n estimateSystemPromptTokens(systemPrompt: string): number {\n if (!systemPrompt || systemPrompt.trim() === '') {\n return 0;\n }\n\n const contentTokens = this.countTokens(systemPrompt);\n const roleTokens = this.countTokens('system');\n \n // System messages have similar overhead to regular messages\n return contentTokens + roleTokens + TokenCounter.MESSAGE_OVERHEAD + TokenCounter.ROLE_OVERHEAD;\n }\n\n /**\n * Get total context size estimate including system prompt and messages\n * @param systemPrompt - System prompt text\n * @param messages - Conversation messages\n * @returns Total estimated token count\n */\n estimateContextSize(systemPrompt: string, messages: BaseMessage[]): number {\n const systemTokens = this.estimateSystemPromptTokens(systemPrompt);\n const messageTokens = this.countMessagesTokens(messages);\n \n // Add a small buffer for chat completion overhead\n const completionOverhead = 10;\n \n return systemTokens + messageTokens + completionOverhead;\n }\n\n /**\n * Get the role string for a message\n * @param message - The message to get the role for\n * @returns Role string ('user', 'assistant', 'system', etc.)\n */\n private getMessageRole(message: BaseMessage): string {\n const messageType = message._getType();\n switch (messageType) {\n case 'human':\n return 'user';\n case 'ai':\n return 'assistant';\n case 'system':\n return 'system';\n case 'function':\n return 'function';\n case 'tool':\n return 'tool';\n default:\n return 'user'; // Default fallback\n }\n }\n\n /**\n * Get the model name being used for token counting\n * @returns The tiktoken model name\n */\n getModelName(): string {\n return this.modelName;\n }\n\n /**\n * Clean up encoding resources\n */\n dispose(): void {\n try {\n this.encoding.free();\n } catch (error) {\n console.warn('Error disposing encoding:', error);\n }\n }\n}"],"names":[],"mappings":";AAQO,MAAM,gBAAN,MAAM,cAAa;AAAA;AAAA,EAQxB,YAAY,YAA2B,UAAU;AAC/C,SAAK,YAAY;AACjB,QAAI;AACF,WAAK,WAAW,mBAAmB,SAAS;AAAA,IAC9C,SAAS,OAAO;AAEd,cAAQ,KAAK,SAAS,SAAS,6CAA6C;AAC5E,WAAK,WAAW,mBAAmB,QAAQ;AAC3C,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,MAAsB;AAChC,QAAI,CAAC,QAAQ,KAAK,KAAA,MAAW,IAAI;AAC/B,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,SAAS,KAAK,SAAS,OAAO,IAAI;AACxC,aAAO,OAAO;AAAA,IAChB,SAAS,OAAO;AACd,cAAQ,KAAK,iEAAiE,KAAK;AAEnF,aAAO,KAAK,KAAK,KAAK,MAAM,KAAK,EAAE,SAAS,GAAG;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,SAA8B;AAC/C,UAAM,gBAAgB,KAAK,YAAY,QAAQ,OAAiB;AAChE,UAAM,aAAa,KAAK,YAAY,KAAK,eAAe,OAAO,CAAC;AAGhE,WAAO,gBAAgB,aAAa,cAAa,mBAAmB,cAAa;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,oBAAoB,UAAiC;AACnD,QAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,aAAO;AAAA,IACT;AAEA,WAAO,SAAS,OAAO,CAAC,OAAO,YAAY;AACzC,aAAO,QAAQ,KAAK,mBAAmB,OAAO;AAAA,IAChD,GAAG,CAAC;AAAA,EACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,2BAA2B,cAA8B;AACvD,QAAI,CAAC,gBAAgB,aAAa,KAAA,MAAW,IAAI;AAC/C,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,KAAK,YAAY,YAAY;AACnD,UAAM,aAAa,KAAK,YAAY,QAAQ;AAG5C,WAAO,gBAAgB,aAAa,cAAa,mBAAmB,cAAa;AAAA,EACnF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAoB,cAAsB,UAAiC;AACzE,UAAM,eAAe,KAAK,2BAA2B,YAAY;AACjE,UAAM,gBAAgB,KAAK,oBAAoB,QAAQ;AAGvD,UAAM,qBAAqB;AAE3B,WAAO,eAAe,gBAAgB;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,eAAe,SAA8B;AACnD,UAAM,cAAc,QAAQ,SAAA;AAC5B,YAAQ,aAAA;AAAA,MACN,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IAAA;AAAA,EAEb;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,QAAI;AACF,WAAK,SAAS,KAAA;AAAA,IAChB,SAAS,OAAO;AACd,cAAQ,KAAK,6BAA6B,KAAK;AAAA,IACjD;AAAA,EACF;AACF;AA1IE,cAAwB,mBAAmB;AAC3C,cAAwB,gBAAgB;AANnC,IAAM,eAAN;"}
@@ -0,0 +1,68 @@
1
+ import { createHash } from "crypto";
2
+ class ReferenceIdGenerator {
3
+ /**
4
+ * Generate a content-based reference ID using SHA-256 hashing
5
+ *
6
+ * @param content The content to generate a reference ID for
7
+ * @returns Deterministic reference ID based on content hash
8
+ */
9
+ static generateId(content) {
10
+ const hash = createHash("sha256");
11
+ hash.update(content);
12
+ return hash.digest("base64url");
13
+ }
14
+ /**
15
+ * Validate that a string is a properly formatted reference ID
16
+ *
17
+ * @param id The ID to validate
18
+ * @returns true if the ID is valid format
19
+ */
20
+ static isValidReferenceId(id) {
21
+ if (!id || typeof id !== "string") {
22
+ return false;
23
+ }
24
+ if (id.length !== 43) {
25
+ return false;
26
+ }
27
+ return /^[A-Za-z0-9_-]+$/.test(id);
28
+ }
29
+ /**
30
+ * Extract reference ID from ref:// format
31
+ *
32
+ * @param input Input string that may contain a reference ID
33
+ * @returns Extracted reference ID or null if not found
34
+ */
35
+ static extractReferenceId(input) {
36
+ if (!input || typeof input !== "string") {
37
+ return null;
38
+ }
39
+ const refFormatMatch = input.match(/^ref:\/\/([A-Za-z0-9_-]{43})$/);
40
+ if (refFormatMatch) {
41
+ return refFormatMatch[1];
42
+ }
43
+ return this.isValidReferenceId(input) ? input : null;
44
+ }
45
+ /**
46
+ * Format a reference ID in the standard ref:// format
47
+ *
48
+ * @param referenceId The reference ID to format
49
+ * @returns Formatted reference string
50
+ */
51
+ static formatReference(referenceId) {
52
+ return `ref://${referenceId}`;
53
+ }
54
+ /**
55
+ * Generate a test reference ID (for testing purposes only)
56
+ *
57
+ * @param testSeed A test seed to generate a fake but valid ID format
58
+ * @returns A valid format reference ID for testing
59
+ */
60
+ static generateTestId(testSeed) {
61
+ const content = Buffer.from(`test-${testSeed}-${Date.now()}`);
62
+ return this.generateId(content);
63
+ }
64
+ }
65
+ export {
66
+ ReferenceIdGenerator
67
+ };
68
+ //# sourceMappingURL=index23.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index23.js","sources":["../../src/memory/ReferenceIdGenerator.ts"],"sourcesContent":["import { createHash } from 'crypto';\nimport { ReferenceId } from '../types/content-reference';\n\n/**\n * Content-based reference ID generator using SHA-256 (HCS-1 style)\n * \n * Generates deterministic reference IDs based on content hashing.\n * Same content always produces the same reference ID.\n */\nexport class ReferenceIdGenerator {\n /**\n * Generate a content-based reference ID using SHA-256 hashing\n * \n * @param content The content to generate a reference ID for\n * @returns Deterministic reference ID based on content hash\n */\n static generateId(content: Buffer): ReferenceId {\n const hash = createHash('sha256');\n hash.update(content);\n return hash.digest('base64url');\n }\n \n /**\n * Validate that a string is a properly formatted reference ID\n * \n * @param id The ID to validate\n * @returns true if the ID is valid format\n */\n static isValidReferenceId(id: string): id is ReferenceId {\n if (!id || typeof id !== 'string') {\n return false;\n }\n \n // Check length (base64url encoding of SHA-256 hash = 43 chars)\n if (id.length !== 43) {\n return false;\n }\n \n // Check character set (base64url: A-Z, a-z, 0-9, -, _)\n return /^[A-Za-z0-9_-]+$/.test(id);\n }\n \n /**\n * Extract reference ID from ref:// format\n * \n * @param input Input string that may contain a reference ID\n * @returns Extracted reference ID or null if not found\n */\n static extractReferenceId(input: string): ReferenceId | null {\n if (!input || typeof input !== 'string') {\n return null;\n }\n \n // Check for ref:// format\n const refFormatMatch = input.match(/^ref:\\/\\/([A-Za-z0-9_-]{43})$/);\n if (refFormatMatch) {\n return refFormatMatch[1] as ReferenceId;\n }\n \n // Check if input is directly a valid reference ID\n return this.isValidReferenceId(input) ? input : null;\n }\n \n /**\n * Format a reference ID in the standard ref:// format\n * \n * @param referenceId The reference ID to format\n * @returns Formatted reference string\n */\n static formatReference(referenceId: ReferenceId): string {\n return `ref://${referenceId}`;\n }\n \n /**\n * Generate a test reference ID (for testing purposes only)\n * \n * @param testSeed A test seed to generate a fake but valid ID format\n * @returns A valid format reference ID for testing\n */\n static generateTestId(testSeed: string): ReferenceId {\n const content = Buffer.from(`test-${testSeed}-${Date.now()}`);\n return this.generateId(content);\n }\n}"],"names":[],"mappings":";AASO,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhC,OAAO,WAAW,SAA8B;AAC9C,UAAM,OAAO,WAAW,QAAQ;AAChC,SAAK,OAAO,OAAO;AACnB,WAAO,KAAK,OAAO,WAAW;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,mBAAmB,IAA+B;AACvD,QAAI,CAAC,MAAM,OAAO,OAAO,UAAU;AACjC,aAAO;AAAA,IACT;AAGA,QAAI,GAAG,WAAW,IAAI;AACpB,aAAO;AAAA,IACT;AAGA,WAAO,mBAAmB,KAAK,EAAE;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,mBAAmB,OAAmC;AAC3D,QAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,aAAO;AAAA,IACT;AAGA,UAAM,iBAAiB,MAAM,MAAM,+BAA+B;AAClE,QAAI,gBAAgB;AAClB,aAAO,eAAe,CAAC;AAAA,IACzB;AAGA,WAAO,KAAK,mBAAmB,KAAK,IAAI,QAAQ;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,gBAAgB,aAAkC;AACvD,WAAO,SAAS,WAAW;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,eAAe,UAA+B;AACnD,UAAM,UAAU,OAAO,KAAK,QAAQ,QAAQ,IAAI,KAAK,IAAA,CAAK,EAAE;AAC5D,WAAO,KAAK,WAAW,OAAO;AAAA,EAChC;AACF;"}
@@ -0,0 +1,38 @@
1
+ const DEFAULT_CONTENT_REFERENCE_CONFIG = {
2
+ sizeThresholdBytes: 10 * 1024,
3
+ // 10KB
4
+ maxAgeMs: 60 * 60 * 1e3,
5
+ // 1 hour
6
+ maxReferences: 100,
7
+ maxTotalStorageBytes: 100 * 1024 * 1024,
8
+ // 100MB
9
+ enableAutoCleanup: true,
10
+ cleanupIntervalMs: 5 * 60 * 1e3,
11
+ // 5 minutes
12
+ enablePersistence: false,
13
+ storageBackend: "memory",
14
+ cleanupPolicies: {
15
+ recent: { maxAgeMs: 30 * 60 * 1e3, priority: 1 },
16
+ // 30 minutes, highest priority
17
+ userContent: { maxAgeMs: 2 * 60 * 60 * 1e3, priority: 2 },
18
+ // 2 hours
19
+ agentGenerated: { maxAgeMs: 60 * 60 * 1e3, priority: 3 },
20
+ // 1 hour
21
+ default: { maxAgeMs: 60 * 60 * 1e3, priority: 4 }
22
+ // 1 hour, lowest priority
23
+ }
24
+ };
25
+ class ContentReferenceError extends Error {
26
+ constructor(message, type, referenceId, suggestedActions) {
27
+ super(message);
28
+ this.type = type;
29
+ this.referenceId = referenceId;
30
+ this.suggestedActions = suggestedActions;
31
+ this.name = "ContentReferenceError";
32
+ }
33
+ }
34
+ export {
35
+ ContentReferenceError,
36
+ DEFAULT_CONTENT_REFERENCE_CONFIG
37
+ };
38
+ //# sourceMappingURL=index24.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index24.js","sources":["../../src/types/content-reference.ts"],"sourcesContent":["/**\n * Content Reference System Types\n * \n * Shared interfaces for the Reference-Based Content System that handles\n * large content storage with unique reference IDs to optimize context window usage.\n */\n\n/**\n * Unique identifier for stored content references\n * Format: Cryptographically secure 32-byte identifier with base64url encoding\n */\nexport type ReferenceId = string;\n\n/**\n * Lifecycle state of a content reference\n */\nexport type ReferenceLifecycleState = 'active' | 'expired' | 'cleanup_pending' | 'invalid';\n\n/**\n * Content types supported by the reference system\n */\nexport type ContentType = 'text' | 'json' | 'html' | 'markdown' | 'binary' | 'unknown';\n\n/**\n * Sources that created the content reference\n */\nexport type ContentSource = 'mcp_tool' | 'user_upload' | 'agent_generated' | 'system';\n\n/**\n * Metadata associated with stored content\n */\nexport interface ContentMetadata {\n /** Content type classification */\n contentType: ContentType;\n \n /** MIME type of the original content */\n mimeType?: string;\n \n /** Size in bytes of the stored content */\n sizeBytes: number;\n \n /** When the content was originally stored */\n createdAt: Date;\n \n /** Last time the content was accessed via reference resolution */\n lastAccessedAt: Date;\n \n /** Source that created this content reference */\n source: ContentSource;\n \n /** Name of the MCP tool that generated the content (if applicable) */\n mcpToolName?: string;\n \n /** Original filename or suggested name for the content */\n fileName?: string;\n \n /** Number of times this reference has been resolved */\n accessCount: number;\n \n /** Tags for categorization and cleanup policies */\n tags?: string[];\n \n /** Custom metadata from the source */\n customMetadata?: Record<string, unknown>;\n}\n\n/**\n * Core content reference object passed through agent context\n * Designed to be lightweight (<100 tokens) while providing enough \n * information for agent decision-making\n */\nexport interface ContentReference {\n /** Unique identifier for resolving the content */\n referenceId: ReferenceId;\n \n /** Current lifecycle state */\n state: ReferenceLifecycleState;\n \n /** Brief description or preview of the content (max 200 chars) */\n preview: string;\n \n /** Essential metadata for agent decision-making */\n metadata: Pick<ContentMetadata, 'contentType' | 'sizeBytes' | 'source' | 'fileName' | 'mimeType'>;\n \n /** When this reference was created */\n createdAt: Date;\n \n /** Special format indicator for reference IDs in content */\n readonly format: 'ref://{id}';\n}\n\n/**\n * Result of attempting to resolve a content reference\n */\nexport interface ReferenceResolutionResult {\n /** Whether the resolution was successful */\n success: boolean;\n \n /** The resolved content if successful */\n content?: Buffer;\n \n /** Complete metadata if successful */\n metadata?: ContentMetadata;\n \n /** Error message if resolution failed */\n error?: string;\n \n /** Specific error type for targeted error handling */\n errorType?: 'not_found' | 'expired' | 'corrupted' | 'access_denied' | 'system_error';\n \n /** Suggested actions for recovery */\n suggestedActions?: string[];\n}\n\n/**\n * Configuration for content reference storage and lifecycle\n */\nexport interface ContentReferenceConfig {\n /** Size threshold above which content should be stored as references (default: 10KB) */\n sizeThresholdBytes: number;\n \n /** Maximum age for unused references before cleanup (default: 1 hour) */\n maxAgeMs: number;\n \n /** Maximum number of references to store simultaneously */\n maxReferences: number;\n \n /** Maximum total storage size for all references */\n maxTotalStorageBytes: number;\n \n /** Whether to enable automatic cleanup */\n enableAutoCleanup: boolean;\n \n /** Interval for cleanup checks in milliseconds */\n cleanupIntervalMs: number;\n \n /** Whether to persist references across restarts */\n enablePersistence: boolean;\n \n /** Storage backend configuration */\n storageBackend: 'memory' | 'filesystem' | 'hybrid';\n \n /** Cleanup policies for different content types */\n cleanupPolicies: {\n /** Policy for content marked as \"recent\" from MCP tools */\n recent: { maxAgeMs: number; priority: number };\n \n /** Policy for user-uploaded content */\n userContent: { maxAgeMs: number; priority: number };\n \n /** Policy for agent-generated content */\n agentGenerated: { maxAgeMs: number; priority: number };\n \n /** Default policy for other content */\n default: { maxAgeMs: number; priority: number };\n };\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONTENT_REFERENCE_CONFIG: ContentReferenceConfig = {\n sizeThresholdBytes: 10 * 1024, // 10KB\n maxAgeMs: 60 * 60 * 1000, // 1 hour\n maxReferences: 100,\n maxTotalStorageBytes: 100 * 1024 * 1024, // 100MB\n enableAutoCleanup: true,\n cleanupIntervalMs: 5 * 60 * 1000, // 5 minutes\n enablePersistence: false,\n storageBackend: 'memory',\n cleanupPolicies: {\n recent: { maxAgeMs: 30 * 60 * 1000, priority: 1 }, // 30 minutes, highest priority\n userContent: { maxAgeMs: 2 * 60 * 60 * 1000, priority: 2 }, // 2 hours\n agentGenerated: { maxAgeMs: 60 * 60 * 1000, priority: 3 }, // 1 hour\n default: { maxAgeMs: 60 * 60 * 1000, priority: 4 } // 1 hour, lowest priority\n }\n};\n\n/**\n * Statistics about content reference usage and storage\n */\nexport interface ContentReferenceStats {\n /** Total number of active references */\n activeReferences: number;\n \n /** Total storage used by all references in bytes */\n totalStorageBytes: number;\n \n /** Number of references cleaned up in last cleanup cycle */\n recentlyCleanedUp: number;\n \n /** Number of successful reference resolutions since startup */\n totalResolutions: number;\n \n /** Number of failed resolution attempts */\n failedResolutions: number;\n \n /** Average content size in bytes */\n averageContentSize: number;\n \n /** Most frequently accessed reference ID */\n mostAccessedReferenceId?: ReferenceId;\n \n /** Storage utilization percentage */\n storageUtilization: number;\n \n /** Performance metrics */\n performanceMetrics: {\n /** Average time to create a reference in milliseconds */\n averageCreationTimeMs: number;\n \n /** Average time to resolve a reference in milliseconds */\n averageResolutionTimeMs: number;\n \n /** Average cleanup time in milliseconds */\n averageCleanupTimeMs: number;\n };\n}\n\n/**\n * Error types for content reference operations\n */\nexport class ContentReferenceError extends Error {\n constructor(\n message: string,\n public readonly type: ReferenceResolutionResult['errorType'],\n public readonly referenceId?: ReferenceId,\n public readonly suggestedActions?: string[]\n ) {\n super(message);\n this.name = 'ContentReferenceError';\n }\n}\n\n/**\n * Interface for content reference storage implementations\n */\nexport interface ContentReferenceStore {\n /**\n * Store content and return a reference\n */\n storeContent(\n content: Buffer,\n metadata: Omit<ContentMetadata, 'createdAt' | 'lastAccessedAt' | 'accessCount'>\n ): Promise<ContentReference>;\n \n /**\n * Resolve a reference to its content\n */\n resolveReference(referenceId: ReferenceId): Promise<ReferenceResolutionResult>;\n \n /**\n * Check if a reference exists and is valid\n */\n hasReference(referenceId: ReferenceId): Promise<boolean>;\n \n /**\n * Mark a reference for cleanup\n */\n cleanupReference(referenceId: ReferenceId): Promise<boolean>;\n \n /**\n * Get current storage statistics\n */\n getStats(): Promise<ContentReferenceStats>;\n \n /**\n * Update configuration\n */\n updateConfig(config: Partial<ContentReferenceConfig>): Promise<void>;\n \n /**\n * Perform cleanup based on current policies\n */\n performCleanup(): Promise<{ cleanedUp: number; errors: string[] }>;\n \n /**\n * Dispose of resources\n */\n dispose(): Promise<void>;\n}"],"names":[],"mappings":"AAiKO,MAAM,mCAA2D;AAAA,EACtE,oBAAoB,KAAK;AAAA;AAAA,EACzB,UAAU,KAAK,KAAK;AAAA;AAAA,EACpB,eAAe;AAAA,EACf,sBAAsB,MAAM,OAAO;AAAA;AAAA,EACnC,mBAAmB;AAAA,EACnB,mBAAmB,IAAI,KAAK;AAAA;AAAA,EAC5B,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,IACf,QAAQ,EAAE,UAAU,KAAK,KAAK,KAAM,UAAU,EAAA;AAAA;AAAA,IAC9C,aAAa,EAAE,UAAU,IAAI,KAAK,KAAK,KAAM,UAAU,EAAA;AAAA;AAAA,IACvD,gBAAgB,EAAE,UAAU,KAAK,KAAK,KAAM,UAAU,EAAA;AAAA;AAAA,IACtD,SAAS,EAAE,UAAU,KAAK,KAAK,KAAM,UAAU,EAAA;AAAA;AAAA,EAAE;AAErD;AA8CO,MAAM,8BAA8B,MAAM;AAAA,EAC/C,YACE,SACgB,MACA,aACA,kBAChB;AACA,UAAM,OAAO;AAJG,SAAA,OAAA;AACA,SAAA,cAAA;AACA,SAAA,mBAAA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;"}
@@ -11,6 +11,7 @@ import { HbarTransferPlugin } from "./index5.js";
11
11
  import { OpenConvaiState } from "@hashgraphonline/standards-agent-kit";
12
12
  import { PrivateKey } from "@hashgraph/sdk";
13
13
  import { getSystemMessage } from "./index13.js";
14
+ import { ContentStoreManager } from "./index14.js";
14
15
  const DEFAULT_MODEL_NAME = "gpt-4o";
15
16
  const DEFAULT_TEMPERATURE = 0.1;
16
17
  const DEFAULT_NETWORK = "testnet";
@@ -39,20 +40,9 @@ class ConversationalAgent {
39
40
  privateKey,
40
41
  network = DEFAULT_NETWORK,
41
42
  openAIApiKey,
42
- openAIModelName = DEFAULT_MODEL_NAME,
43
- verbose = false,
44
- operationalMode = DEFAULT_OPERATIONAL_MODE,
45
- userAccountId,
46
- customSystemMessagePreamble,
47
- customSystemMessagePostamble,
48
- additionalPlugins = [],
49
- mirrorNodeConfig,
50
- disableLogging,
51
- scheduleUserTransactionsInBytesMode
43
+ openAIModelName = DEFAULT_MODEL_NAME
52
44
  } = this.options;
53
- if (!accountId || !privateKey) {
54
- throw new Error("Account ID and private key are required");
55
- }
45
+ this.validateOptions(accountId, privateKey);
56
46
  try {
57
47
  const privateKeyInstance = await this.detectPrivateKeyType(
58
48
  accountId,
@@ -64,79 +54,19 @@ class ConversationalAgent {
64
54
  privateKeyInstance,
65
55
  network
66
56
  );
67
- const standardPlugins = [
68
- this.hcs10Plugin,
69
- this.hcs2Plugin,
70
- this.inscribePlugin,
71
- this.hbarTransferPlugin
72
- ];
73
- const corePlugins = getAllHederaCorePlugins();
74
- let allPlugins;
75
- if (this.options.enabledPlugins) {
76
- const enabledSet = new Set(this.options.enabledPlugins);
77
- const filteredPlugins = [...standardPlugins, ...corePlugins].filter(
78
- (plugin) => enabledSet.has(plugin.id)
79
- );
80
- allPlugins = [...filteredPlugins, ...additionalPlugins];
81
- } else {
82
- allPlugins = [...standardPlugins, ...corePlugins, ...additionalPlugins];
83
- }
57
+ const allPlugins = this.preparePlugins();
84
58
  const llm = new ChatOpenAI({
85
59
  apiKey: openAIApiKey,
86
60
  modelName: openAIModelName,
87
61
  temperature: DEFAULT_TEMPERATURE
88
62
  });
89
- this.agent = createAgent({
90
- framework: "langchain",
91
- signer: serverSigner,
92
- execution: {
93
- mode: operationalMode === "autonomous" ? "direct" : "bytes",
94
- operationalMode,
95
- ...userAccountId && { userAccountId },
96
- ...scheduleUserTransactionsInBytesMode !== void 0 && {
97
- scheduleUserTransactions: scheduleUserTransactionsInBytesMode
98
- }
99
- },
100
- ai: {
101
- provider: new LangChainProvider(llm),
102
- temperature: DEFAULT_TEMPERATURE
103
- },
104
- filtering: {
105
- toolPredicate: (tool) => {
106
- if (tool.name === "hedera-account-transfer-hbar") return false;
107
- if (this.options.toolFilter && !this.options.toolFilter(tool)) {
108
- return false;
109
- }
110
- return true;
111
- }
112
- },
113
- messaging: {
114
- systemPreamble: customSystemMessagePreamble || getSystemMessage(accountId),
115
- ...customSystemMessagePostamble && { systemPostamble: customSystemMessagePostamble },
116
- conciseMode: true
117
- },
118
- extensions: {
119
- plugins: allPlugins,
120
- ...mirrorNodeConfig && {
121
- mirrorConfig: mirrorNodeConfig
122
- }
123
- },
124
- ...this.options.mcpServers && {
125
- mcp: {
126
- servers: this.options.mcpServers,
127
- autoConnect: true
128
- }
129
- },
130
- debug: {
131
- verbose,
132
- silent: disableLogging ?? false
133
- }
134
- });
135
- const hcs10 = allPlugins.find((p) => p.id === "hcs-10");
136
- if (hcs10) {
137
- hcs10.appConfig = {
138
- stateManager: this.stateManager
139
- };
63
+ const agentConfig = this.createAgentConfig(serverSigner, llm, allPlugins);
64
+ this.agent = createAgent(agentConfig);
65
+ this.configureHCS10Plugin(allPlugins);
66
+ if (this.options.mcpServers && this.options.mcpServers.length > 0) {
67
+ this.contentStoreManager = new ContentStoreManager();
68
+ await this.contentStoreManager.initialize();
69
+ this.logger.info("ContentStoreManager initialized for MCP content reference support");
140
70
  }
141
71
  await this.agent.boot();
142
72
  } catch (error) {
@@ -188,14 +118,133 @@ class ConversationalAgent {
188
118
  if (!this.agent) {
189
119
  throw new Error("Agent not initialized. Call initialize() first.");
190
120
  }
191
- const messages = chatHistory.map(
192
- (msg) => msg.type === "human" ? new HumanMessage(msg.content) : new AIMessage(msg.content)
193
- );
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);
126
+ }
127
+ });
194
128
  const context = {
195
129
  messages
196
130
  };
197
131
  return this.agent.chat(message, context);
198
132
  }
133
+ /**
134
+ * Validates initialization options and throws if required fields are missing.
135
+ *
136
+ * @param accountId - The Hedera account ID
137
+ * @param privateKey - The private key for the account
138
+ * @throws {Error} If required fields are missing
139
+ */
140
+ validateOptions(accountId, privateKey) {
141
+ if (!accountId || !privateKey) {
142
+ throw new Error("Account ID and private key are required");
143
+ }
144
+ }
145
+ /**
146
+ * Prepares the list of plugins to use based on configuration.
147
+ *
148
+ * @returns Array of plugins to initialize with the agent
149
+ */
150
+ preparePlugins() {
151
+ const { additionalPlugins = [], enabledPlugins } = this.options;
152
+ const standardPlugins = [
153
+ this.hcs10Plugin,
154
+ this.hcs2Plugin,
155
+ this.inscribePlugin,
156
+ this.hbarTransferPlugin
157
+ ];
158
+ const corePlugins = getAllHederaCorePlugins();
159
+ if (enabledPlugins) {
160
+ const enabledSet = new Set(enabledPlugins);
161
+ const filteredPlugins = [...standardPlugins, ...corePlugins].filter(
162
+ (plugin) => enabledSet.has(plugin.id)
163
+ );
164
+ return [...filteredPlugins, ...additionalPlugins];
165
+ }
166
+ return [...standardPlugins, ...corePlugins, ...additionalPlugins];
167
+ }
168
+ /**
169
+ * Creates the agent configuration object.
170
+ *
171
+ * @param serverSigner - The server signer instance
172
+ * @param llm - The language model instance
173
+ * @param allPlugins - Array of plugins to use
174
+ * @returns Configuration object for creating the agent
175
+ */
176
+ createAgentConfig(serverSigner, llm, allPlugins) {
177
+ const {
178
+ operationalMode = DEFAULT_OPERATIONAL_MODE,
179
+ userAccountId,
180
+ scheduleUserTransactionsInBytesMode,
181
+ customSystemMessagePreamble,
182
+ customSystemMessagePostamble,
183
+ verbose = false,
184
+ mirrorNodeConfig,
185
+ disableLogging,
186
+ accountId = ""
187
+ } = this.options;
188
+ return {
189
+ framework: "langchain",
190
+ signer: serverSigner,
191
+ execution: {
192
+ mode: operationalMode === "autonomous" ? "direct" : "bytes",
193
+ operationalMode,
194
+ ...userAccountId && { userAccountId },
195
+ ...scheduleUserTransactionsInBytesMode !== void 0 && {
196
+ scheduleUserTransactions: scheduleUserTransactionsInBytesMode
197
+ }
198
+ },
199
+ ai: {
200
+ provider: new LangChainProvider(llm),
201
+ temperature: DEFAULT_TEMPERATURE
202
+ },
203
+ filtering: {
204
+ toolPredicate: (tool) => {
205
+ if (tool.name === "hedera-account-transfer-hbar") return false;
206
+ if (this.options.toolFilter && !this.options.toolFilter(tool)) {
207
+ return false;
208
+ }
209
+ return true;
210
+ }
211
+ },
212
+ messaging: {
213
+ systemPreamble: customSystemMessagePreamble || getSystemMessage(accountId),
214
+ ...customSystemMessagePostamble && { systemPostamble: customSystemMessagePostamble },
215
+ conciseMode: true
216
+ },
217
+ extensions: {
218
+ plugins: allPlugins,
219
+ ...mirrorNodeConfig && {
220
+ mirrorConfig: mirrorNodeConfig
221
+ }
222
+ },
223
+ ...this.options.mcpServers && {
224
+ mcp: {
225
+ servers: this.options.mcpServers,
226
+ autoConnect: true
227
+ }
228
+ },
229
+ debug: {
230
+ verbose,
231
+ silent: disableLogging ?? false
232
+ }
233
+ };
234
+ }
235
+ /**
236
+ * Configures the HCS-10 plugin with the state manager.
237
+ *
238
+ * @param allPlugins - Array of all plugins
239
+ */
240
+ configureHCS10Plugin(allPlugins) {
241
+ const hcs10 = allPlugins.find((p) => p.id === "hcs-10");
242
+ if (hcs10) {
243
+ hcs10.appConfig = {
244
+ stateManager: this.stateManager
245
+ };
246
+ }
247
+ }
199
248
  /**
200
249
  * Create a ConversationalAgent with specific plugins enabled
201
250
  */
@@ -291,6 +340,16 @@ class ConversationalAgent {
291
340
  return PrivateKey.fromStringED25519(privateKey);
292
341
  }
293
342
  }
343
+ /**
344
+ * Clean up resources
345
+ */
346
+ async cleanup() {
347
+ if (this.contentStoreManager) {
348
+ await this.contentStoreManager.dispose();
349
+ this.logger.info("ContentStoreManager cleaned up");
350
+ }
351
+ if (this.agent) ;
352
+ }
294
353
  }
295
354
  export {
296
355
  ConversationalAgent
@@ -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';\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\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 verbose = false,\n operationalMode = DEFAULT_OPERATIONAL_MODE,\n userAccountId,\n customSystemMessagePreamble,\n customSystemMessagePostamble,\n additionalPlugins = [],\n mirrorNodeConfig,\n disableLogging,\n scheduleUserTransactionsInBytesMode,\n } = this.options;\n\n if (!accountId || !privateKey) {\n throw new Error('Account ID and private key are required');\n }\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 standardPlugins = [\n this.hcs10Plugin,\n this.hcs2Plugin,\n this.inscribePlugin,\n this.hbarTransferPlugin,\n ];\n\n const corePlugins = getAllHederaCorePlugins();\n\n let allPlugins: BasePlugin[];\n\n if (this.options.enabledPlugins) {\n const enabledSet = new Set(this.options.enabledPlugins);\n const filteredPlugins = [...standardPlugins, ...corePlugins].filter(\n (plugin) => enabledSet.has(plugin.id)\n );\n allPlugins = [...filteredPlugins, ...additionalPlugins];\n } else {\n allPlugins = [...standardPlugins, ...corePlugins, ...additionalPlugins];\n }\n\n const llm = new ChatOpenAI({\n apiKey: openAIApiKey,\n modelName: openAIModelName,\n temperature: DEFAULT_TEMPERATURE,\n });\n\n this.agent = createAgent({\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 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 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 msg.type === 'human'\n ? new HumanMessage(msg.content)\n : new AIMessage(msg.content)\n );\n\n const context: ConversationContext = {\n messages,\n };\n\n return this.agent.chat(message, context);\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"],"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 } 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":";;;;;;;;;;;;;;AA2BA,MAAM,qBAAqB;AAC3B,MAAM,sBAAsB;AAC5B,MAAM,kBAAkB;AACxB,MAAM,2BAAiD;AAgChD,MAAM,oBAAoB;AAAA,EAW/B,YAAY,SAAqC;AAC/C,SAAK,UAAU;AACf,SAAK,eAAe,QAAQ,gBAAgB,IAAI,gBAAA;AAChD,SAAK,cAAc,IAAI,YAAA;AACvB,SAAK,aAAa,IAAI,WAAA;AACtB,SAAK,iBAAiB,IAAI,eAAA;AAC1B,SAAK,qBAAqB,IAAI,mBAAA;AAC9B,SAAK,SAAS,IAAI,OAAO;AAAA,MACvB,QAAQ;AAAA,MACR,QAAQ,QAAQ,kBAAkB;AAAA,IAAA,CACnC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAA4B;AAChC,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,kBAAkB;AAAA,IAAA,IAChB,KAAK;AAET,SAAK,gBAAgB,WAAW,UAAU;AAE1C,QAAI;AACF,YAAM,qBAAqB,MAAM,KAAK;AAAA,QACpC;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAGF,YAAM,eAAe,IAAI;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAGF,YAAM,aAAa,KAAK,eAAA;AAExB,YAAM,MAAM,IAAI,WAAW;AAAA,QACzB,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,aAAa;AAAA,MAAA,CACd;AAED,YAAM,cAAc,KAAK,kBAAkB,cAAc,KAAK,UAAU;AACxE,WAAK,QAAQ,YAAY,WAAW;AAEpC,WAAK,qBAAqB,UAAU;AAGpC,UAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,WAAW,SAAS,GAAG;AACjE,aAAK,sBAAsB,IAAI,oBAAA;AAC/B,cAAM,KAAK,oBAAoB,WAAA;AAC/B,aAAK,OAAO,KAAK,mEAAmE;AAAA,MACtF;AAEA,YAAM,KAAK,MAAM,KAAA;AAAA,IACnB,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,6CAA6C,KAAK;AACpE,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAyB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAiC;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAA2C;AACzC,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAAyD;AACvD,WAAO,KAAK,SAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eACJ,SACA,cAGM,IACiB;AACvB,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAEA,UAAM,WAAW,YAAY,IAAI,CAAC,QAAQ;AACxC,UAAI,IAAI,SAAS,SAAS;AACxB,eAAO,IAAI,aAAa,IAAI,OAAO;AAAA,MACrC,OAAO;AACL,eAAO,IAAI,UAAU,IAAI,OAAO;AAAA,MAClC;AAAA,IACF,CAAC;AAED,UAAM,UAA+B;AAAA,MACnC;AAAA,IAAA;AAGF,WAAO,KAAK,MAAM,KAAK,SAAS,OAAO;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,gBAAgB,WAAoB,YAA2B;AACrE,QAAI,CAAC,aAAa,CAAC,YAAY;AAC7B,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,iBAA+B;AACrC,UAAM,EAAE,oBAAoB,CAAA,GAAI,eAAA,IAAmB,KAAK;AAExD,UAAM,kBAAkB;AAAA,MACtB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IAAA;AAGP,UAAM,cAAc,wBAAA;AAEpB,QAAI,gBAAgB;AAClB,YAAM,aAAa,IAAI,IAAI,cAAc;AACzC,YAAM,kBAAkB,CAAC,GAAG,iBAAiB,GAAG,WAAW,EAAE;AAAA,QAC3D,CAAC,WAAW,WAAW,IAAI,OAAO,EAAE;AAAA,MAAA;AAEtC,aAAO,CAAC,GAAG,iBAAiB,GAAG,iBAAiB;AAAA,IAClD;AAEA,WAAO,CAAC,GAAG,iBAAiB,GAAG,aAAa,GAAG,iBAAiB;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,kBACN,cACA,KACA,YACmC;AACnC,UAAM;AAAA,MACJ,kBAAkB;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IAAA,IACV,KAAK;AAET,WAAO;AAAA,MACL,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,WAAW;AAAA,QACT,MAAM,oBAAoB,eAAe,WAAW;AAAA,QACpD;AAAA,QACA,GAAI,iBAAiB,EAAE,cAAA;AAAA,QACvB,GAAI,wCAAwC,UAAa;AAAA,UACvD,0BAA0B;AAAA,QAAA;AAAA,MAC5B;AAAA,MAEF,IAAI;AAAA,QACF,UAAU,IAAI,kBAAkB,GAAG;AAAA,QACnC,aAAa;AAAA,MAAA;AAAA,MAEf,WAAW;AAAA,QACT,eAAe,CAAC,SAAS;AACvB,cAAI,KAAK,SAAS,+BAAgC,QAAO;AACzD,cAAI,KAAK,QAAQ,cAAc,CAAC,KAAK,QAAQ,WAAW,IAAI,GAAG;AAC7D,mBAAO;AAAA,UACT;AACA,iBAAO;AAAA,QACT;AAAA,MAAA;AAAA,MAEF,WAAW;AAAA,QACT,gBACE,+BAA+B,iBAAiB,SAAS;AAAA,QAC3D,GAAI,gCAAgC,EAAE,iBAAiB,6BAAA;AAAA,QACvD,aAAa;AAAA,MAAA;AAAA,MAEf,YAAY;AAAA,QACV,SAAS;AAAA,QACT,GAAI,oBAAoB;AAAA,UACtB,cAAc;AAAA,QAAA;AAAA,MAChB;AAAA,MAEF,GAAI,KAAK,QAAQ,cAAc;AAAA,QAC7B,KAAK;AAAA,UACH,SAAS,KAAK,QAAQ;AAAA,UACtB,aAAa;AAAA,QAAA;AAAA,MACf;AAAA,MAEF,OAAO;AAAA,QACL;AAAA,QACA,QAAQ,kBAAkB;AAAA,MAAA;AAAA,IAC5B;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,qBAAqB,YAAgC;AAC3D,UAAM,QAAQ,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AACtD,QAAI,OAAO;AACR,YAAkD,YAAY;AAAA,QAC7D,cAAc,KAAK;AAAA,MAAA;AAAA,IAEvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,YACb,SACA,SACqB;AACrB,WAAO,IAAI,oBAAoB;AAAA,MAC7B,GAAG;AAAA,MACH,gBAAgB;AAAA,IAAA,CACjB;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,QAAQ,SAA0D;AACvE,WAAO,KAAK,YAAY,SAAS,CAAC,WAAW,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,SAAS,SAA0D;AACxE,WAAO,KAAK,YAAY,SAAS,CAAC,OAAO,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,UAAU,SAA0D;AACzE,WAAO,KAAK,YAAY,SAAS,CAAC,QAAQ,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,aACL,SACqB;AACrB,WAAO,KAAK,YAAY,SAAS,CAAC,UAAU,CAAC;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,YAAY,SAA0D;AAC3E,WAAO,KAAK,YAAY,SAAS,CAAC,SAAS,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,gBACL,SACqB;AACrB,WAAO,KAAK,YAAY,SAAS,CAAC,cAAc,CAAC;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,qBACL,SACqB;AACrB,WAAO,KAAK,YAAY,SAAS,CAAC,mBAAmB,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,kBACL,SACqB;AACrB,WAAO,KAAK,YAAY,SAAS,CAAC,gBAAgB,CAAC;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,iBACL,SACqB;AACrB,WAAO,KAAK,YAAY,SAAS,CAAC,UAAU,SAAS,UAAU,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,QAAQ,SAA0D;AACvE,WAAO,KAAK,YAAY,SAAS,EAAE;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,QACL,SACA,YACqB;AACrB,WAAO,IAAI,oBAAoB;AAAA,MAC7B,GAAG;AAAA,MACH;AAAA,IAAA,CACD;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,qBACZ,WACA,YACA,SACqB;AACrB,UAAM,aAAa,IAAI,iBAAiB,OAAgC;AACxE,UAAM,cAAc,MAAM,WAAW,eAAe,SAAS;AAE7D,UAAM,UAAU,aAAa,KAAK,SAAS;AAE3C,QAAI,SAAS,YAAA,GAAe,SAAS,OAAO,GAAG;AAC7C,aAAO,WAAW,gBAAgB,UAAU;AAAA,IAC9C,OAAO;AACL,aAAO,WAAW,kBAAkB,UAAU;AAAA,IAChD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC7B,QAAI,KAAK,qBAAqB;AAC5B,YAAM,KAAK,oBAAoB,QAAA;AAC/B,WAAK,OAAO,KAAK,gCAAgC;AAAA,IACnD;AAEA,QAAI,KAAK,MAAO;AAAA,EAGlB;AACF;"}