@hashgraphonline/conversational-agent 0.0.3 → 0.1.1

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 (78) hide show
  1. package/README.md +79 -0
  2. package/dist/cjs/agent-factory.d.ts +5 -0
  3. package/dist/cjs/base-agent.d.ts +95 -0
  4. package/dist/cjs/conversational-agent.d.ts +62 -5
  5. package/dist/cjs/index.cjs +1 -1
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs/index.d.ts +8 -0
  8. package/dist/cjs/langchain-agent.d.ts +22 -0
  9. package/dist/cjs/mcp/MCPClientManager.d.ts +40 -0
  10. package/dist/cjs/mcp/adapters/langchain.d.ts +8 -0
  11. package/dist/cjs/mcp/helpers.d.ts +45 -0
  12. package/dist/cjs/mcp/types.d.ts +27 -0
  13. package/dist/cjs/plugins/hbar-transfer/AccountBuilder.d.ts +13 -0
  14. package/dist/cjs/plugins/hbar-transfer/HbarTransferPlugin.d.ts +15 -0
  15. package/dist/cjs/plugins/hbar-transfer/TransferHbarTool.d.ts +61 -0
  16. package/dist/cjs/plugins/hbar-transfer/index.d.ts +1 -0
  17. package/dist/cjs/plugins/hbar-transfer/types.d.ts +10 -0
  18. package/dist/cjs/plugins/index.d.ts +1 -0
  19. package/dist/cjs/providers.d.ts +48 -0
  20. package/dist/esm/index.js +18 -3
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/index10.js +22 -0
  23. package/dist/esm/index10.js.map +1 -0
  24. package/dist/esm/index11.js +104 -0
  25. package/dist/esm/index11.js.map +1 -0
  26. package/dist/esm/index12.js +36 -0
  27. package/dist/esm/index12.js.map +1 -0
  28. package/dist/esm/index13.js +16 -0
  29. package/dist/esm/index13.js.map +1 -0
  30. package/dist/esm/index14.js +127 -0
  31. package/dist/esm/index14.js.map +1 -0
  32. package/dist/esm/index15.js +132 -0
  33. package/dist/esm/index15.js.map +1 -0
  34. package/dist/esm/index16.js +95 -0
  35. package/dist/esm/index16.js.map +1 -0
  36. package/dist/esm/index5.js +42 -202
  37. package/dist/esm/index5.js.map +1 -1
  38. package/dist/esm/index6.js +295 -13
  39. package/dist/esm/index6.js.map +1 -1
  40. package/dist/esm/index7.js +87 -0
  41. package/dist/esm/index7.js.map +1 -0
  42. package/dist/esm/index8.js +255 -0
  43. package/dist/esm/index8.js.map +1 -0
  44. package/dist/esm/index9.js +18 -0
  45. package/dist/esm/index9.js.map +1 -0
  46. package/dist/types/agent-factory.d.ts +5 -0
  47. package/dist/types/base-agent.d.ts +95 -0
  48. package/dist/types/conversational-agent.d.ts +62 -5
  49. package/dist/types/index.d.ts +8 -0
  50. package/dist/types/langchain-agent.d.ts +22 -0
  51. package/dist/types/mcp/MCPClientManager.d.ts +40 -0
  52. package/dist/types/mcp/adapters/langchain.d.ts +8 -0
  53. package/dist/types/mcp/helpers.d.ts +45 -0
  54. package/dist/types/mcp/types.d.ts +27 -0
  55. package/dist/types/plugins/hbar-transfer/AccountBuilder.d.ts +13 -0
  56. package/dist/types/plugins/hbar-transfer/HbarTransferPlugin.d.ts +15 -0
  57. package/dist/types/plugins/hbar-transfer/TransferHbarTool.d.ts +61 -0
  58. package/dist/types/plugins/hbar-transfer/index.d.ts +1 -0
  59. package/dist/types/plugins/hbar-transfer/types.d.ts +10 -0
  60. package/dist/types/plugins/index.d.ts +1 -0
  61. package/dist/types/providers.d.ts +48 -0
  62. package/package.json +12 -6
  63. package/src/agent-factory.ts +21 -0
  64. package/src/base-agent.ts +222 -0
  65. package/src/conversational-agent.ts +204 -102
  66. package/src/index.ts +24 -0
  67. package/src/langchain-agent.ts +333 -0
  68. package/src/mcp/MCPClientManager.ts +148 -0
  69. package/src/mcp/adapters/langchain.ts +185 -0
  70. package/src/mcp/helpers.ts +122 -0
  71. package/src/mcp/types.ts +29 -0
  72. package/src/plugins/hbar-transfer/AccountBuilder.ts +154 -0
  73. package/src/plugins/hbar-transfer/HbarTransferPlugin.ts +66 -0
  74. package/src/plugins/hbar-transfer/TransferHbarTool.ts +49 -0
  75. package/src/plugins/hbar-transfer/index.ts +1 -0
  76. package/src/plugins/hbar-transfer/types.ts +11 -0
  77. package/src/plugins/index.ts +2 -1
  78. package/src/providers.ts +82 -0
package/README.md CHANGED
@@ -137,6 +137,7 @@ When using `returnBytes` mode:
137
137
  - **TypeScript Support**: Full type definitions for all components
138
138
  - **State Management**: Integrated state management for agent operations
139
139
  - **CLI Interface**: Beautiful terminal interface for interactive agent communication
140
+ - **MCP Support**: Extend agent capabilities with Model Context Protocol servers
140
141
 
141
142
  ## Available Tools
142
143
 
@@ -469,8 +470,86 @@ const agent = new HederaConversationalAgent(signer, {
469
470
  - [Conversational Agent Documentation](https://hashgraphonline.com/docs/libraries/conversational-agent/)
470
471
  - [Standards Agent Kit Documentation](https://hashgraphonline.com/docs/libraries/standards-agent-kit/)
471
472
  - [HCS Standards Documentation](https://hcs-improvement-proposals.pages.dev/docs/standards)
473
+ - [MCP Integration Guide](./docs/MCP_INTEGRATION.md)
472
474
  - [GitHub Repository](https://github.com/hashgraph-online/conversational-agent)
473
475
 
476
+ ## Contributing
477
+
478
+ We welcome contributions from the community! Whether you're fixing bugs, adding features, or creating new plugins, your contributions help make the Conversational Agent better for everyone.
479
+
480
+ ### Contributing a Plugin
481
+
482
+ If you've created a plugin that extends the Conversational Agent's capabilities, we'd love to include it in the repository. Here's how:
483
+
484
+ 1. **Fork the Repository**
485
+ ```bash
486
+ git clone https://github.com/hashgraph-online/conversational-agent.git
487
+ cd conversational-agent
488
+ pnpm install
489
+ ```
490
+
491
+ 2. **Create Your Plugin**
492
+ - Place your plugin in `src/plugins/community/[your-plugin-name]/`
493
+ - Follow the plugin structure outlined in the [Plugin Development Guide](docs/PLUGIN_DEVELOPMENT.md)
494
+ - Include comprehensive tests in `src/plugins/community/[your-plugin-name]/__tests__/`
495
+ - Add documentation in `src/plugins/community/[your-plugin-name]/README.md`
496
+
497
+ 3. **Plugin Requirements**
498
+ - Must extend `BasePlugin` from hedera-agent-kit
499
+ - Include clear tool descriptions for AI understanding
500
+ - Add proper error handling and validation
501
+ - Follow TypeScript best practices
502
+ - Include unit tests with >80% coverage
503
+ - Document all configuration options
504
+ - Add usage examples
505
+
506
+ 4. **Submit a Pull Request**
507
+ - Create a feature branch: `git checkout -b feature/add-[plugin-name]-plugin`
508
+ - Commit your changes with clear messages
509
+ - Push to your fork and create a PR
510
+ - Include a description of what your plugin does and why it's useful
511
+ - Link to any relevant HCS standards or documentation
512
+
513
+ ### Plugin Review Process
514
+
515
+ 1. **Code Review**: Maintainers will review your code for quality, security, and adherence to standards
516
+ 2. **Testing**: All tests must pass, and the plugin must work with the latest agent version
517
+ 3. **Documentation**: Clear documentation and examples are required
518
+ 4. **Integration**: Once approved, your plugin will be added to the community plugins directory
519
+
520
+ ### Example Plugin Structure
521
+
522
+ ```
523
+ src/plugins/community/your-plugin/
524
+ ├── index.ts # Main plugin export
525
+ ├── YourPlugin.ts # Plugin implementation
526
+ ├── tools/ # Tool implementations
527
+ │ ├── YourTool1.ts
528
+ │ └── YourTool2.ts
529
+ ├── __tests__/ # Test files
530
+ │ ├── YourPlugin.test.ts
531
+ │ └── tools/
532
+ │ ├── YourTool1.test.ts
533
+ │ └── YourTool2.test.ts
534
+ ├── README.md # Plugin documentation
535
+ └── package.json # Plugin metadata (optional)
536
+ ```
537
+
538
+ ### General Contribution Guidelines
539
+
540
+ - **Code Style**: Follow the existing code style and linting rules
541
+ - **Commits**: Use clear, descriptive commit messages
542
+ - **Documentation**: Update relevant documentation for any changes
543
+ - **Tests**: Add tests for new functionality
544
+ - **Issues**: Open an issue before working on major changes
545
+
546
+ ### Getting Help
547
+
548
+ - Join our [Discord community](https://discord.gg/hashgraphonline) for discussions
549
+ - Check existing issues and PRs before starting work
550
+ - Ask questions in the #development channel
551
+ - Review the [HCS Standards](https://hcs-improvement-proposals.pages.dev/docs/standards) for protocol details
552
+
474
553
  ## License
475
554
 
476
555
  Apache-2.0
@@ -0,0 +1,5 @@
1
+ import { BaseAgent, HederaAgentConfiguration } from './base-agent';
2
+
3
+ export declare function createAgent(config: HederaAgentConfiguration & {
4
+ framework?: 'langchain' | 'vercel' | 'baml';
5
+ }): BaseAgent;
@@ -0,0 +1,95 @@
1
+ import { BaseMessage } from '@langchain/core/messages';
2
+ import { StructuredTool } from '@langchain/core/tools';
3
+ import { TransactionReceipt } from '@hashgraph/sdk';
4
+ import { HederaAgentKit, ServerSigner, TokenUsageCallbackHandler, TokenUsage, BasePlugin, CostCalculation } from 'hedera-agent-kit';
5
+ import { AIProvider, VercelAIProvider, BAMLProvider } from './providers';
6
+ import { Logger } from '@hashgraphonline/standards-sdk';
7
+ import { MCPServerConfig } from './mcp/types';
8
+
9
+ export interface ToolFilterConfig {
10
+ namespaceWhitelist?: string[];
11
+ toolBlacklist?: string[];
12
+ toolPredicate?: (tool: StructuredTool) => boolean;
13
+ }
14
+ export type ExecutionMode = 'direct' | 'bytes';
15
+ export type OperationalMode = 'autonomous' | 'returnBytes';
16
+ export interface HederaAgentConfiguration {
17
+ signer: ServerSigner;
18
+ execution?: {
19
+ mode?: ExecutionMode;
20
+ operationalMode?: OperationalMode;
21
+ userAccountId?: string;
22
+ scheduleUserTransactions?: boolean;
23
+ scheduleUserTransactionsInBytesMode?: boolean;
24
+ };
25
+ ai?: {
26
+ provider?: AIProvider;
27
+ llm?: unknown;
28
+ apiKey?: string;
29
+ modelName?: string;
30
+ temperature?: number;
31
+ };
32
+ filtering?: ToolFilterConfig;
33
+ messaging?: {
34
+ systemPreamble?: string;
35
+ systemPostamble?: string;
36
+ conciseMode?: boolean;
37
+ };
38
+ extensions?: {
39
+ plugins?: BasePlugin[];
40
+ mirrorConfig?: Record<string, unknown>;
41
+ modelCapability?: string;
42
+ };
43
+ mcp?: {
44
+ servers?: MCPServerConfig[];
45
+ autoConnect?: boolean;
46
+ };
47
+ debug?: {
48
+ verbose?: boolean;
49
+ silent?: boolean;
50
+ };
51
+ }
52
+ export interface ConversationContext {
53
+ messages: BaseMessage[];
54
+ metadata?: Record<string, unknown>;
55
+ }
56
+ export interface ChatResponse {
57
+ output: string;
58
+ message?: string;
59
+ transactionBytes?: string;
60
+ receipt?: TransactionReceipt | object;
61
+ scheduleId?: string;
62
+ transactionId?: string;
63
+ notes?: string[];
64
+ error?: string;
65
+ intermediateSteps?: unknown;
66
+ rawToolOutput?: unknown;
67
+ tokenUsage?: TokenUsage;
68
+ cost?: CostCalculation;
69
+ metadata?: Record<string, unknown>;
70
+ [key: string]: unknown;
71
+ }
72
+ export interface UsageStats extends TokenUsage {
73
+ cost: CostCalculation;
74
+ }
75
+ export declare abstract class BaseAgent {
76
+ protected config: HederaAgentConfiguration;
77
+ protected logger: Logger;
78
+ protected agentKit: HederaAgentKit | undefined;
79
+ protected tools: StructuredTool[];
80
+ protected initialized: boolean;
81
+ protected tokenTracker: TokenUsageCallbackHandler | undefined;
82
+ constructor(config: HederaAgentConfiguration);
83
+ abstract boot(): Promise<void>;
84
+ abstract chat(message: string, context?: ConversationContext): Promise<ChatResponse>;
85
+ abstract shutdown(): Promise<void>;
86
+ abstract switchMode(mode: OperationalMode): void;
87
+ abstract getUsageStats(): UsageStats;
88
+ abstract getUsageLog(): UsageStats[];
89
+ abstract clearUsageStats(): void;
90
+ getCore(): HederaAgentKit | undefined;
91
+ protected filterTools(tools: StructuredTool[]): StructuredTool[];
92
+ protected buildSystemPrompt(): string;
93
+ isReady(): boolean;
94
+ }
95
+ export type { AIProvider, VercelAIProvider, BAMLProvider };
@@ -1,9 +1,13 @@
1
- import { HederaConversationalAgent, BasePlugin, AgentOperationalMode, AgentResponse, MirrorNodeConfig } from 'hedera-agent-kit';
1
+ import { BasePlugin, AgentOperationalMode, MirrorNodeConfig } from 'hedera-agent-kit';
2
+ import { NetworkType } from '@hashgraphonline/standards-sdk';
3
+ import { createAgent } from './agent-factory';
4
+ import { ChatResponse } from './base-agent';
2
5
  import { HCS10Plugin } from './plugins/hcs-10/HCS10Plugin';
3
6
  import { HCS2Plugin } from './plugins/hcs-2/HCS2Plugin';
4
7
  import { InscribePlugin } from './plugins/inscribe/InscribePlugin';
8
+ import { HbarTransferPlugin } from './plugins/hbar-transfer/HbarTransferPlugin';
5
9
  import { IStateManager } from '@hashgraphonline/standards-agent-kit';
6
- import { NetworkType } from '@hashgraphonline/standards-sdk';
10
+ import { MCPServerConfig } from './mcp/types';
7
11
 
8
12
  export interface ConversationalAgentOptions {
9
13
  accountId: string;
@@ -22,6 +26,11 @@ export interface ConversationalAgentOptions {
22
26
  mirrorNodeConfig?: MirrorNodeConfig;
23
27
  disableLogging?: boolean;
24
28
  enabledPlugins?: string[];
29
+ toolFilter?: (tool: {
30
+ name: string;
31
+ namespace?: string;
32
+ }) => boolean;
33
+ mcpServers?: MCPServerConfig[];
25
34
  }
26
35
  /**
27
36
  * The ConversationalAgent class is an optional wrapper around the HederaConversationalAgent class,
@@ -33,22 +42,58 @@ export interface ConversationalAgentOptions {
33
42
  * @returns A new instance of the ConversationalAgent class.
34
43
  */
35
44
  export declare class ConversationalAgent {
36
- conversationalAgent?: HederaConversationalAgent;
45
+ private agent?;
37
46
  hcs10Plugin: HCS10Plugin;
38
47
  hcs2Plugin: HCS2Plugin;
39
48
  inscribePlugin: InscribePlugin;
49
+ hbarTransferPlugin: HbarTransferPlugin;
40
50
  stateManager: IStateManager;
41
51
  private options;
42
52
  private logger;
43
53
  constructor(options: ConversationalAgentOptions);
54
+ /**
55
+ * Initialize the conversational agent with Hedera network connection and AI configuration
56
+ * @throws {Error} If account ID or private key is missing
57
+ * @throws {Error} If initialization fails
58
+ */
44
59
  initialize(): Promise<void>;
60
+ /**
61
+ * Get the HCS-10 plugin instance
62
+ * @returns {HCS10Plugin} The HCS-10 plugin instance
63
+ */
45
64
  getPlugin(): HCS10Plugin;
65
+ /**
66
+ * Get the state manager instance
67
+ * @returns {IStateManager} The state manager instance
68
+ */
46
69
  getStateManager(): IStateManager;
47
- getConversationalAgent(): HederaConversationalAgent;
70
+ /**
71
+ * Get the underlying agent instance
72
+ * @returns {ReturnType<typeof createAgent>} The agent instance
73
+ * @throws {Error} If agent is not initialized
74
+ */
75
+ getAgent(): ReturnType<typeof createAgent>;
76
+ /**
77
+ * Get the conversational agent instance (alias for getAgent)
78
+ * @returns {ReturnType<typeof createAgent>} The agent instance
79
+ * @throws {Error} If agent is not initialized
80
+ */
81
+ getConversationalAgent(): ReturnType<typeof createAgent>;
82
+ /**
83
+ * Process a message through the conversational agent
84
+ * @param {string} message - The message to process
85
+ * @param {Array<{type: 'human' | 'ai'; content: string}>} chatHistory - Previous chat history
86
+ * @returns {Promise<ChatResponse>} The agent's response
87
+ * @throws {Error} If agent is not initialized
88
+ */
48
89
  processMessage(message: string, chatHistory?: {
49
90
  type: 'human' | 'ai';
50
91
  content: string;
51
- }[]): Promise<AgentResponse>;
92
+ }[]): Promise<ChatResponse>;
93
+ /**
94
+ * Create a ConversationalAgent with specific plugins enabled
95
+ */
96
+ private static withPlugins;
52
97
  /**
53
98
  * Create a ConversationalAgent with only HTS (Hedera Token Service) tools enabled
54
99
  */
@@ -89,4 +134,16 @@ export declare class ConversationalAgent {
89
134
  * Create a ConversationalAgent with minimal Hedera tools (no HCS standards)
90
135
  */
91
136
  static minimal(options: ConversationalAgentOptions): ConversationalAgent;
137
+ /**
138
+ * Create a ConversationalAgent with MCP servers configured
139
+ */
140
+ static withMCP(options: ConversationalAgentOptions, mcpServers: MCPServerConfig[]): ConversationalAgent;
141
+ /**
142
+ * Detect the private key type by querying the account info from mirror node
143
+ * @param {string} accountId - The Hedera account ID
144
+ * @param {string} privateKey - The private key string
145
+ * @param {NetworkType} network - The Hedera network
146
+ * @returns {Promise<PrivateKey>} The appropriate PrivateKey instance
147
+ */
148
+ private detectPrivateKeyType;
92
149
  }
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("hedera-agent-kit"),t=require("@hashgraphonline/standards-agent-kit"),i=require("@hashgraphonline/standards-sdk"),n=require("@hashgraph/sdk");class o extends e.BasePlugin{constructor(){super(...arguments),this.id="hcs-10",this.name="HCS-10 Plugin",this.description="HCS-10 agent tools for decentralized agent registration, connections, and messaging on Hedera",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="hcs10",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.stateManager=e.stateManager||new t.OpenConvaiState,this.initializeTools(),this.context.logger.info("HCS-10 Plugin initialized successfully")}catch(i){this.context.logger.error("Failed to initialize HCS-10 plugin:",i)}else this.context.logger.warn("HederaKit not found in context. HCS-10 tools will not be available.")}initializeTools(){if(!this.stateManager)throw new Error("StateManager must be initialized before creating tools");const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const i=new t.HCS10Builder(e,this.stateManager);this.tools=[new t.RegisterAgentTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.FindRegistrationsTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.RetrieveProfileTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.InitiateConnectionTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.ListConnectionsTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.SendMessageToConnectionTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.CheckMessagesTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.ConnectionMonitorTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.ManageConnectionRequestsTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.AcceptConnectionRequestTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger}),new t.ListUnapprovedConnectionRequestsTool({hederaKit:e,hcs10Builder:i,logger:this.context.logger})]}getTools(){return this.tools}getStateManager(){return this.stateManager}async cleanup(){this.tools=[],delete this.stateManager,this.context?.logger&&this.context.logger.info("HCS-10 Plugin cleaned up")}}class s extends e.BasePlugin{constructor(){super(...arguments),this.id="hcs-2",this.name="HCS-2 Plugin",this.description="HCS-2 registry management tools for decentralized registries on Hedera",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="hcs2",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.initializeTools(),this.context.logger.info("HCS-2 Plugin initialized successfully")}catch(t){this.context.logger.error("Failed to initialize HCS-2 plugin:",t)}else this.context.logger.warn("HederaKit not found in context. HCS-2 tools will not be available.")}initializeTools(){const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const i=new t.HCS2Builder(e);this.tools=[new t.CreateRegistryTool({hederaKit:e,hcs2Builder:i,logger:this.context.logger}),new t.RegisterEntryTool({hederaKit:e,hcs2Builder:i,logger:this.context.logger}),new t.UpdateEntryTool({hederaKit:e,hcs2Builder:i,logger:this.context.logger}),new t.DeleteEntryTool({hederaKit:e,hcs2Builder:i,logger:this.context.logger}),new t.MigrateRegistryTool({hederaKit:e,hcs2Builder:i,logger:this.context.logger}),new t.QueryRegistryTool({hederaKit:e,hcs2Builder:i,logger:this.context.logger})]}getTools(){return this.tools}async cleanup(){this.tools=[],this.context?.logger&&this.context.logger.info("HCS-2 Plugin cleaned up")}}class r extends e.BasePlugin{constructor(){super(...arguments),this.id="inscribe",this.name="Inscribe Plugin",this.description="Content inscription tools for storing data on Hedera Consensus Service",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="inscribe",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.initializeTools(),this.context.logger.info("Inscribe Plugin initialized successfully")}catch(t){this.context.logger.error("Failed to initialize Inscribe plugin:",t)}else this.context.logger.warn("HederaKit not found in context. Inscription tools will not be available.")}initializeTools(){const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const i=new t.InscriberBuilder(e);this.tools=[new t.InscribeFromUrlTool({hederaKit:e,inscriberBuilder:i,logger:this.context.logger}),new t.InscribeFromFileTool({hederaKit:e,inscriberBuilder:i,logger:this.context.logger}),new t.InscribeFromBufferTool({hederaKit:e,inscriberBuilder:i,logger:this.context.logger}),new t.InscribeHashinalTool({hederaKit:e,inscriberBuilder:i,logger:this.context.logger}),new t.RetrieveInscriptionTool({hederaKit:e,inscriberBuilder:i,logger:this.context.logger})]}getTools(){return this.tools}async cleanup(){this.tools=[],this.context?.logger&&this.context.logger.info("Inscribe Plugin cleaned up")}}const a=e=>`You are a helpful assistant managing Hashgraph Online HCS-10 connections, messages, HCS-2 registries, and content inscription.\n\nYou have access to tools for:\n- HCS-10: registering agents, finding registered agents, initiating connections, listing active connections, sending messages over connections, and checking for new messages\n- HCS-2: creating registries, registering entries, updating entries, deleting entries, migrating registries, and querying registry contents\n- Inscription: inscribing content from URLs, files, or buffers, creating Hashinal NFTs, and retrieving inscriptions\n\n*** IMPORTANT CONTEXT ***\nYou are currently operating as agent: ${e} on the Hashgraph Online network\nWhen users ask about "my profile", "my account", "my connections", etc., use this account ID: ${e}\n\nRemember the connection numbers when listing connections, as users might refer to them.`;class l{constructor(e){this.options=e,this.stateManager=e.stateManager||new t.OpenConvaiState,this.hcs10Plugin=new o,this.hcs2Plugin=new s,this.inscribePlugin=new r,this.logger=new i.Logger({module:"ConversationalAgent"})}async initialize(){const{accountId:t,privateKey:o,network:s="testnet",openAIApiKey:r,openAIModelName:l="gpt-4o",verbose:g=!1,operationalMode:c="autonomous",userAccountId:h,customSystemMessagePreamble:u,customSystemMessagePostamble:d,additionalPlugins:w=[],scheduleUserTransactionsInBytesMode:p,mirrorNodeConfig:f,disableLogging:b}=this.options;if(!t||!o)throw new Error("Account ID and private key are required");try{const x=new i.HederaMirrorNode(s,this.logger),C=await x.requestAccount(t),m=C?.key?._type||"";let y;y=m?.toLowerCase()?.includes("ecdsa")?n.PrivateKey.fromStringECDSA(o):n.PrivateKey.fromStringED25519(o);const P=new e.ServerSigner(t,y,s),S=[this.hcs10Plugin,this.hcs2Plugin,this.inscribePlugin],v=e.getAllHederaCorePlugins();let H;if(this.options.enabledPlugins){const e=new Set(this.options.enabledPlugins);H=[...[...S,...v].filter(t=>e.has(t.id)),...w]}else H=[...S,...v,...w];const T={pluginConfig:{plugins:H,appConfig:{stateManager:this.stateManager}},openAIApiKey:r,openAIModelName:l,verbose:g,operationalMode:c,userAccountId:h,customSystemMessagePreamble:u||a(t),...void 0!==d&&{customSystemMessagePostamble:d},...void 0!==p&&{scheduleUserTransactionsInBytesMode:p},...void 0!==f&&{mirrorNodeConfig:f},...void 0!==b&&{disableLogging:b}};this.conversationalAgent=new e.HederaConversationalAgent(P,T),await this.conversationalAgent.initialize()}catch(x){throw this.logger.error("Failed to initialize ConversationalAgent:",x),x}}getPlugin(){return this.hcs10Plugin}getStateManager(){return this.stateManager}getConversationalAgent(){if(!this.conversationalAgent)throw new Error("ConversationalAgent not initialized. Call initialize() first.");return this.conversationalAgent}async processMessage(e,t=[]){if(!this.conversationalAgent)throw new Error("ConversationalAgent not initialized. Call initialize() first.");return this.conversationalAgent.processMessage(e,t)}static withHTS(e){return new l({...e,enabledPlugins:["hts-token"]})}static withHCS2(e){return new l({...e,enabledPlugins:["hcs-2"]})}static withHCS10(e){return new l({...e,enabledPlugins:["hcs-10"]})}static withInscribe(e){return new l({...e,enabledPlugins:["inscribe"]})}static withAccount(e){return new l({...e,enabledPlugins:["account"]})}static withFileService(e){return new l({...e,enabledPlugins:["file-service"]})}static withConsensusService(e){return new l({...e,enabledPlugins:["consensus-service"]})}static withSmartContract(e){return new l({...e,enabledPlugins:["smart-contract"]})}static withAllStandards(e){return new l({...e,enabledPlugins:["hcs-10","hcs-2","inscribe"]})}static minimal(e){return new l({...e,enabledPlugins:[]})}}exports.ConversationalAgent=l,exports.HCS10Plugin=o,exports.HCS2Plugin=s,exports.InscribePlugin=r,Object.keys(e).forEach(t=>{"default"===t||Object.prototype.hasOwnProperty.call(exports,t)||Object.defineProperty(exports,t,{enumerable:!0,get:()=>e[t]})});
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("hedera-agent-kit"),t=require("@hashgraphonline/standards-agent-kit"),n=require("zod"),r=require("@hashgraph/sdk"),o=require("bignumber.js"),i=require("@hashgraphonline/standards-sdk"),s=require("langchain/agents"),a=require("@langchain/core/prompts"),c=require("@langchain/openai"),l=require("@modelcontextprotocol/sdk/client/index.js"),g=require("@modelcontextprotocol/sdk/client/stdio.js"),h=require("@langchain/core/tools"),u=require("@langchain/core/messages");class d extends e.BasePlugin{constructor(){super(...arguments),this.id="hcs-10",this.name="HCS-10 Plugin",this.description="HCS-10 agent tools for decentralized agent registration, connections, and messaging on Hedera",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="hcs10",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.stateManager=e.stateManager||new t.OpenConvaiState,this.initializeTools(),this.context.logger.info("HCS-10 Plugin initialized successfully")}catch(n){this.context.logger.error("Failed to initialize HCS-10 plugin:",n)}else this.context.logger.warn("HederaKit not found in context. HCS-10 tools will not be available.")}initializeTools(){if(!this.stateManager)throw new Error("StateManager must be initialized before creating tools");const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const n=new t.HCS10Builder(e,this.stateManager);this.tools=[new t.RegisterAgentTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.FindRegistrationsTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.RetrieveProfileTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.InitiateConnectionTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.ListConnectionsTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.SendMessageToConnectionTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.CheckMessagesTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.ConnectionMonitorTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.ManageConnectionRequestsTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.AcceptConnectionRequestTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.ListUnapprovedConnectionRequestsTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger})]}getTools(){return this.tools}getStateManager(){return this.stateManager}async cleanup(){this.tools=[],delete this.stateManager,this.context?.logger&&this.context.logger.info("HCS-10 Plugin cleaned up")}}class m extends e.BasePlugin{constructor(){super(...arguments),this.id="hcs-2",this.name="HCS-2 Plugin",this.description="HCS-2 registry management tools for decentralized registries on Hedera",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="hcs2",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.initializeTools(),this.context.logger.info("HCS-2 Plugin initialized successfully")}catch(t){this.context.logger.error("Failed to initialize HCS-2 plugin:",t)}else this.context.logger.warn("HederaKit not found in context. HCS-2 tools will not be available.")}initializeTools(){const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const n=new t.HCS2Builder(e);this.tools=[new t.CreateRegistryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.RegisterEntryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.UpdateEntryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.DeleteEntryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.MigrateRegistryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.QueryRegistryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger})]}getTools(){return this.tools}async cleanup(){this.tools=[],this.context?.logger&&this.context.logger.info("HCS-2 Plugin cleaned up")}}class p extends e.BasePlugin{constructor(){super(...arguments),this.id="inscribe",this.name="Inscribe Plugin",this.description="Content inscription tools for storing data on Hedera Consensus Service",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="inscribe",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.initializeTools(),this.context.logger.info("Inscribe Plugin initialized successfully")}catch(t){this.context.logger.error("Failed to initialize Inscribe plugin:",t)}else this.context.logger.warn("HederaKit not found in context. Inscription tools will not be available.")}initializeTools(){const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const n=new t.InscriberBuilder(e);this.tools=[new t.InscribeFromUrlTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger}),new t.InscribeFromFileTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger}),new t.InscribeFromBufferTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger}),new t.InscribeHashinalTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger}),new t.RetrieveInscriptionTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger})]}getTools(){return this.tools}async cleanup(){this.tools=[],this.context?.logger&&this.context.logger.info("Inscribe Plugin cleaned up")}}class f extends e.BaseServiceBuilder{constructor(e){super(e)}transferHbar(e,t=!0){this.clearNotes();const n=new r.TransferTransaction;if(!e.transfers||0===e.transfers.length)throw new Error("HbarTransferParams must include at least one transfer.");let i=new o(0),s=!1;if(t&&this.kit.userAccountId&&"provideBytes"===this.kit.operationalMode&&1===e.transfers.length){const t=e.transfers[0],i="string"==typeof t.amount||"number"==typeof t.amount?t.amount:t.amount.toString(),a=new o(i);if(a.isPositive()){const e="string"==typeof t.accountId?r.AccountId.fromString(t.accountId):t.accountId,i=a.toFixed(8,o.ROUND_DOWN),c=r.Hbar.fromString(i);this.logger.info(`[AccountBuilder.transferHbar] Configuring user-initiated scheduled transfer: ${c.toString()} from ${this.kit.userAccountId} to ${e.toString()}`),this.addNote(`Configured HBAR transfer from your account (${this.kit.userAccountId}) to ${e.toString()} for ${c.toString()}.`),n.addHbarTransfer(e,c),n.addHbarTransfer(r.AccountId.fromString(this.kit.userAccountId),c.negated()),s=!0}}if(!s){const t=[];for(const n of e.transfers){const e="string"==typeof n.accountId?r.AccountId.fromString(n.accountId):n.accountId,s="string"==typeof n.amount||"number"==typeof n.amount?n.amount:n.amount.toString(),a=new o(s),c=a.toFixed(8,o.ROUND_DOWN);this.logger.info(`Processing transfer: ${s} HBAR (rounded to ${c}) for account ${e.toString()}`);const l=r.Hbar.fromString(c);t.push({accountId:e,amount:a,hbar:l});const g=l.toTinybars();i=i.plus(g.toString())}if(!i.isZero()&&(this.logger.warn(`Transfer sum not zero: ${i.toString()} tinybars off. Adjusting last transfer.`),t.length>0)){const e=t[t.length-1],n=i.dividedBy(-1e8),s=e.amount.plus(n).toFixed(8,o.ROUND_DOWN);e.hbar=r.Hbar.fromString(s),this.logger.info(`Adjusted last transfer for ${e.accountId.toString()} to ${s} HBAR`)}for(const e of t)n.addHbarTransfer(e.accountId,e.hbar)}return void 0!==e.memo&&(null===e.memo?this.logger.warn("Received null for memo in transferHbar."):n.setTransactionMemo(e.memo)),this.setCurrentTransaction(n),this}}const y=n.z.object({accountId:n.z.string().describe('Account ID for the transfer (e.g., "0.0.xxxx").'),amount:n.z.union([n.z.number(),n.z.string()]).describe("HBAR amount. Positive for credit, negative for debit. Builder handles Hbar unit & sum validation.")}),w=n.z.object({transfers:n.z.array(y).min(1).describe('Array of ALL transfers for this transaction. For multi-party transfers (e.g., "A sends 5 to C and B sends 3 to C"), include all transfers here: [{accountId: "A", amount: -5}, {accountId: "B", amount: -3}, {accountId: "C", amount: 8}]. Amounts must sum to zero.'),memo:n.z.string().optional().describe("Optional. Memo for the transaction.")});class b extends e.BaseHederaTransactionTool{constructor(){super(...arguments),this.name="hedera-account-transfer-hbar-v2",this.description='PRIMARY TOOL FOR HBAR TRANSFERS: Transfers HBAR between accounts. Supports multiple transfers in a single transaction - when multiple accounts need to send/receive HBAR (e.g., "A sends 5 HBAR to C and B sends 3 HBAR to C"), include ALL transfers in one transfers array. The sum of all transfers must equal zero. Use this for scheduled transactions and multi-signature scenarios.',this.specificInputSchema=w,this.namespace="account"}getServiceBuilder(){return new f(this.hederaKit)}async callBuilderMethod(e,t){await e.transferHbar(t)}}class x extends e.BasePlugin{constructor(){super(...arguments),this.id="hbar-transfer",this.name="HBAR Transfer Plugin",this.description="HBAR transfer tool with proper decimal handling for multi-signature transactions",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="account",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.initializeTools(),this.context.logger.info("HBAR Transfer Plugin initialized successfully")}catch(t){this.context.logger.error("Failed to initialize HBAR Transfer plugin:",t)}else this.context.logger.warn("HederaKit not found in context. HBAR transfer tools will not be available.")}initializeTools(){const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");this.tools=[new b({hederaKit:e,logger:this.context.logger})]}getTools(){return this.tools}async shutdown(){this.tools=[]}}class v{constructor(e){this.config=e,this.tools=[],this.initialized=!1,this.logger=new i.Logger({module:"BaseAgent",silent:e.debug?.silent||!1})}getCore(){return this.agentKit}filterTools(e){let t=[...e];const n=this.config.filtering;return n?(n.namespaceWhitelist?.length&&(t=t.filter(e=>{const t=e.namespace;return!t||n.namespaceWhitelist.includes(t)})),n.toolBlacklist?.length&&(t=t.filter(e=>!n.toolBlacklist.includes(e.name))),n.toolPredicate&&(t=t.filter(n.toolPredicate)),this.logger.debug(`Filtered tools: ${e.length} → ${t.length}`),t):t}buildSystemPrompt(){const e=[],t=this.config.signer.getAccountId().toString(),n=this.config.execution?.userAccountId;this.config.messaging?.systemPreamble&&e.push(this.config.messaging.systemPreamble),e.push(`You are a helpful Hedera assistant. Your primary operator account is ${t}. You have tools to interact with the Hedera network. When using any tool, provide all necessary parameters as defined by that tool's schema and description.`),n&&e.push(`The user you are assisting has a personal Hedera account ID: ${n}. IMPORTANT: When the user says things like "I want to send HBAR" or "transfer my tokens", you MUST use ${n} as the sender/from account. For example, if user says "I want to send 2 HBAR to 0.0.800", you must set up a transfer where ${n} sends the HBAR, not your operator account.`);return"autonomous"===(this.config.execution?.operationalMode||"returnBytes")?e.push(`\nOPERATIONAL MODE: 'autonomous'. Your goal is to execute transactions directly using your tools. Your account ${t} will be the payer for these transactions. Even if the user's account (${n||"a specified account"}) is the actor in the transaction body (e.g., sender of HBAR), you (the agent with operator ${t}) are still executing and paying. For HBAR transfers, ensure the amounts in the 'transfers' array sum to zero (as per tool schema), balancing with your operator account if necessary.`):this.config.execution?.scheduleUserTransactionsInBytesMode&&n?e.push(`\nOPERATIONAL MODE: 'returnBytes' with scheduled transactions for user actions. When a user asks for a transaction to be prepared (e.g., creating a token, topic, transferring assets for them to sign, etc), you MUST default to creating a Scheduled Transaction using the appropriate tool with the metaOption 'schedule: true'. The user (with account ID ${n}) will be the one to ultimately pay for and (if needed) sign the inner transaction. Your operator account (${t}) will pay for creating the schedule entity itself. You MUST return the ScheduleId and details of the scheduled operation in a structured JSON format with these fields: success, op, schedule_id, description, payer_account_id_scheduled_tx, and scheduled_transaction_details.`):e.push(`\nOPERATIONAL MODE: 'returnBytes'. Your goal is to provide transaction bytes directly. When a user asks for a transaction to be prepared (e.g., for them to sign, or for scheduling without the default scheduling flow), you MUST call the appropriate tool. If you want raw bytes for the user to sign for their own account ${n||"if specified"}, ensure the tool constructs the transaction body accordingly and use metaOption 'returnBytes: true' if available, or ensure the builder is configured for the user.`),!1!==this.config.messaging?.conciseMode&&e.push("\nAlways be concise. If the tool provides a JSON string as its primary output (especially in returnBytes mode), make your accompanying text brief. If the tool does not provide JSON output or an error occurs, your narrative becomes primary; if notes were generated by the tool in such cases, append them to your textual response."),this.config.messaging?.systemPostamble&&e.push(this.config.messaging.systemPostamble),e.join("\n")}isReady(){return this.initialized}}class T{constructor(e){this.clients=new Map,this.tools=new Map,this.logger=e}async connectServer(e){try{if(this.isServerConnected(e.name))return{serverName:e.name,connected:!1,error:`Server ${e.name} is already connected`,tools:[]};if(e.transport&&"stdio"!==e.transport)throw new Error(`Transport ${e.transport} not yet supported`);const t=new g.StdioClientTransport({command:e.command,args:e.args,...e.env&&{env:e.env}}),n=new l.Client({name:`conversational-agent-${e.name}`,version:"1.0.0"},{capabilities:{}});await n.connect(t),this.clients.set(e.name,n);const r=(await n.listTools()).tools.map(t=>({...t,serverName:e.name}));return this.tools.set(e.name,r),this.logger.info(`Connected to MCP server ${e.name} with ${r.length} tools`),{serverName:e.name,connected:!0,tools:r}}catch(t){return this.logger.error(`Failed to connect to MCP server ${e.name}:`,t),{serverName:e.name,connected:!1,error:t instanceof Error?t.message:"Unknown error",tools:[]}}}async executeTool(e,t,n){const r=this.clients.get(e);if(!r)throw new Error(`MCP server ${e} not connected`);this.logger.debug(`Executing MCP tool ${t} on server ${e}`,n);try{return await r.callTool({name:t,arguments:n})}catch(o){throw this.logger.error(`Error executing MCP tool ${t}:`,o),o}}async disconnectAll(){for(const[t,n]of this.clients)try{await n.close(),this.logger.info(`Disconnected from MCP server ${t}`)}catch(e){this.logger.error(`Error disconnecting MCP server ${t}:`,e)}this.clients.clear(),this.tools.clear()}getAllTools(){const e=[];for(const t of this.tools.values())e.push(...t);return e}getServerTools(e){return this.tools.get(e)||[]}isServerConnected(e){return this.clients.has(e)}getConnectedServers(){return Array.from(this.clients.keys())}}function C(e,t,n){const r=S(e.inputSchema),o=`${e.serverName}_${e.name}`.replace(/[^a-zA-Z0-9_]/g,"_");let i=e.description||`MCP tool ${e.name} from ${e.serverName}`;return n?.toolDescriptions?.[e.name]&&(i=`${i}\n\n${n.toolDescriptions[e.name]}`),n?.additionalContext&&(i=`${i}\n\nContext: ${n.additionalContext}`),new h.DynamicStructuredTool({name:o,description:i,schema:r,func:async n=>{try{const r=await t.executeTool(e.serverName,e.name,n);if("string"==typeof r)return r;if(r&&"object"==typeof r&&"content"in r){const e=r.content;if(Array.isArray(e)){return e.filter(e=>"object"==typeof e&&null!==e&&"type"in e&&"text"===e.type&&"text"in e).map(e=>e.text).join("\n")}return JSON.stringify(e)}return JSON.stringify(r)}catch(r){const t=r instanceof Error?r.message:"Unknown error";return`Error executing MCP tool ${e.name}: ${t}`}}})}function S(e){if(!e||"object"!=typeof e)return n.z.object({});const t=e;if(t.type&&"object"!==t.type)return A(t);if(!t.properties||"object"!=typeof t.properties)return n.z.object({});const r={};for(const[n,o]of Object.entries(t.properties)){let e=A(o);Array.isArray(t.required)&&t.required.includes(n)||(e=e.optional()),r[n]=e}return n.z.object(r)}function A(e){if(!e||"object"!=typeof e||!("type"in e))return n.z.unknown();const t=e;let r;switch(t.type){case"string":r=n.z.string(),t.enum&&Array.isArray(t.enum)&&(r=n.z.enum(t.enum));break;case"number":r=n.z.number(),"minimum"in t&&"number"==typeof t.minimum&&(r=r.min(t.minimum)),"maximum"in t&&"number"==typeof t.maximum&&(r=r.max(t.maximum));break;case"integer":r=n.z.number().int(),"minimum"in t&&"number"==typeof t.minimum&&(r=r.min(t.minimum)),"maximum"in t&&"number"==typeof t.maximum&&(r=r.max(t.maximum));break;case"boolean":r=n.z.boolean();break;case"array":r=t.items?n.z.array(A(t.items)):n.z.array(n.z.unknown());break;case"object":r="properties"in t?S(t):n.z.object({}).passthrough();break;default:r=n.z.unknown()}return"description"in t&&"string"==typeof t.description&&(r=r.describe(t.description)),r}class P extends v{constructor(){super(...arguments),this.systemMessage=""}async boot(){if(this.initialized)this.logger.warn("Agent already initialized");else try{this.agentKit=await this.createAgentKit(),await this.agentKit.initialize();const t=this.config.ai?.modelName||process.env.OPENAI_MODEL_NAME||"gpt-4o-mini";this.tokenTracker=new e.TokenUsageCallbackHandler(t);const n=this.agentKit.getAggregatedLangChainTools();this.tools=this.filterTools(n),this.config.mcp?.servers&&this.config.mcp.servers.length>0&&await this.initializeMCP(),this.systemMessage=this.buildSystemPrompt(),await this.createExecutor(),this.initialized=!0,this.logger.info("LangChain Hedera agent initialized")}catch(t){throw this.logger.error("Failed to initialize agent:",t),t}}async chat(t,n){if(!this.initialized||!this.executor)throw new Error("Agent not initialized. Call boot() first.");try{const o=await this.executor.invoke({input:t,chat_history:n?.messages||[]});let i={output:o.output||"",message:o.output||"",notes:[]};const s=o?.intermediateSteps?.[0]?.observation;if(s&&"string"==typeof s&&this.isJSON(s))try{const e=JSON.parse(s);i={...i,...e}}catch(r){this.logger.error("Error parsing intermediate steps:",r)}if(i.output&&""!==i.output.trim()||(i.output="Agent action complete."),this.tokenTracker){const t=this.tokenTracker.getLatestTokenUsage();t&&(i.tokenUsage=t,i.cost=e.calculateTokenCostSync(t))}return i}catch(r){return this.handleError(r)}}async shutdown(){this.mcpManager&&await this.mcpManager.disconnectAll(),this.executor=void 0,this.agentKit=void 0,this.tools=[],this.initialized=!1,this.logger.info("Agent cleaned up")}switchMode(e){this.config.execution?this.config.execution.operationalMode=e:this.config.execution={operationalMode:e},this.agentKit&&(this.agentKit.operationalMode=e),this.systemMessage=this.buildSystemPrompt(),this.logger.info(`Operational mode switched to: ${e}`)}getUsageStats(){if(!this.tokenTracker)return{promptTokens:0,completionTokens:0,totalTokens:0,cost:{totalCost:0}};const t=this.tokenTracker.getTotalTokenUsage(),n=e.calculateTokenCostSync(t);return{...t,cost:n}}getUsageLog(){return this.tokenTracker?this.tokenTracker.getTokenUsageHistory().map(t=>({...t,cost:e.calculateTokenCostSync(t)})):[]}clearUsageStats(){this.tokenTracker&&(this.tokenTracker.reset(),this.logger.info("Usage statistics cleared"))}async createAgentKit(){const t=[...e.getAllHederaCorePlugins(),...this.config.extensions?.plugins||[]],n=this.config.execution?.operationalMode||"returnBytes",r=this.config.ai?.modelName||"gpt-4o";return new e.HederaAgentKit(this.config.signer,{plugins:t},n,this.config.execution?.userAccountId,this.config.execution?.scheduleUserTransactionsInBytesMode??!0,void 0,r,this.config.extensions?.mirrorConfig,this.config.debug?.silent??!1)}async createExecutor(){let e;if(this.config.ai?.provider&&this.config.ai.provider.getModel)e=this.config.ai.provider.getModel();else if(this.config.ai?.llm)e=this.config.ai.llm;else{const t=this.config.ai?.apiKey||process.env.OPENAI_API_KEY;if(!t)throw new Error("OpenAI API key required");e=new c.ChatOpenAI({apiKey:t,modelName:this.config.ai?.modelName||"gpt-4o-mini",temperature:this.config.ai?.temperature??.1,callbacks:this.tokenTracker?[this.tokenTracker]:[]})}const t=a.ChatPromptTemplate.fromMessages([["system",this.systemMessage],new a.MessagesPlaceholder("chat_history"),["human","{input}"],new a.MessagesPlaceholder("agent_scratchpad")]),n=this.tools,r=await s.createOpenAIToolsAgent({llm:e,tools:n,prompt:t});this.executor=new s.AgentExecutor({agent:r,tools:n,verbose:this.config.debug?.verbose??!1,returnIntermediateSteps:!0})}handleError(t){const n=t instanceof Error?t.message:"Unknown error";let r,o;this.logger.error("Chat error:",t),this.tokenTracker&&(r=this.tokenTracker.getLatestTokenUsage(),r&&(o=e.calculateTokenCostSync(r)));const i={output:"Sorry, I encountered an error processing your request.",message:"Error processing request.",error:n,notes:[]};return r&&(i.tokenUsage=r),o&&(i.cost=o),i}async initializeMCP(){this.mcpManager=new T(this.logger);for(const e of this.config.mcp.servers){if(!1===e.autoConnect){this.logger.info(`Skipping MCP server ${e.name} (autoConnect=false)`);continue}const t=await this.mcpManager.connectServer(e);if(t.connected){this.logger.info(`Connected to MCP server ${t.serverName} with ${t.tools.length} tools`);for(const n of t.tools){const t=C(n,this.mcpManager,e);this.tools.push(t)}}else this.logger.error(`Failed to connect to MCP server ${t.serverName}: ${t.error}`)}}isJSON(e){if("string"!=typeof e)return!1;const t=e.trim();if(!t)return!1;if(!(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]")))return!1;try{return JSON.parse(t),!0}catch{return!1}}}function k(e){const t=e.framework||"langchain";switch(t){case"langchain":return new P(e);case"vercel":throw new Error("Vercel AI SDK support coming soon");case"baml":throw new Error("BAML support coming soon");default:throw new Error(`Unknown framework: ${t}`)}}class M{constructor(e){this.model=e}async generate(e,t){const n=await this.model.invoke(e,t);return"string"==typeof n?n:n.toString()}async*stream(e,t){const n=await this.model.stream(e,t);for await(const r of n)yield"string"==typeof r?r:r.toString()}getModel(){return this.model}}const H=e=>`You are a helpful assistant managing Hashgraph Online HCS-10 connections, messages, HCS-2 registries, and content inscription.\n\nYou have access to tools for:\n- HCS-10: registering agents, finding registered agents, initiating connections, listing active connections, sending messages over connections, and checking for new messages\n- HCS-2: creating registries, registering entries, updating entries, deleting entries, migrating registries, and querying registry contents\n- Inscription: inscribing content from URLs, files, or buffers, creating Hashinal NFTs, and retrieving inscriptions\n\n*** IMPORTANT CONTEXT ***\nYou are currently operating as agent: ${e} on the Hashgraph Online network\nWhen users ask about "my profile", "my account", "my connections", etc., use this account ID: ${e}\n\nRemember the connection numbers when listing connections, as users might refer to them.`,I="gpt-4o",B="testnet",z="autonomous";class K{constructor(e){this.options=e,this.stateManager=e.stateManager||new t.OpenConvaiState,this.hcs10Plugin=new d,this.hcs2Plugin=new m,this.inscribePlugin=new p,this.hbarTransferPlugin=new x,this.logger=new i.Logger({module:"ConversationalAgent",silent:e.disableLogging||!1})}async initialize(){const{accountId:t,privateKey:n,network:r=B,openAIApiKey:o,openAIModelName:i=I,verbose:s=!1,operationalMode:a=z,userAccountId:l,customSystemMessagePreamble:g,customSystemMessagePostamble:h,additionalPlugins:u=[],mirrorNodeConfig:d,disableLogging:m,scheduleUserTransactionsInBytesMode:p}=this.options;if(!t||!n)throw new Error("Account ID and private key are required");try{const f=await this.detectPrivateKeyType(t,n,r),y=new e.ServerSigner(t,f,r),w=[this.hcs10Plugin,this.hcs2Plugin,this.inscribePlugin,this.hbarTransferPlugin],b=e.getAllHederaCorePlugins();let x;if(this.options.enabledPlugins){const e=new Set(this.options.enabledPlugins);x=[...[...w,...b].filter(t=>e.has(t.id)),...u]}else x=[...w,...b,...u];const v=new c.ChatOpenAI({apiKey:o,modelName:i,temperature:.1});this.agent=k({framework:"langchain",signer:y,execution:{mode:"autonomous"===a?"direct":"bytes",operationalMode:a,...l&&{userAccountId:l},...void 0!==p&&{scheduleUserTransactions:p}},ai:{provider:new M(v),temperature:.1},filtering:{toolPredicate:e=>"hedera-account-transfer-hbar"!==e.name&&!(this.options.toolFilter&&!this.options.toolFilter(e))},messaging:{systemPreamble:g||H(t),...h&&{systemPostamble:h},conciseMode:!0},extensions:{plugins:x,...d&&{mirrorConfig:d}},...this.options.mcpServers&&{mcp:{servers:this.options.mcpServers,autoConnect:!0}},debug:{verbose:s,silent:m??!1}});const T=x.find(e=>"hcs-10"===e.id);T&&(T.appConfig={stateManager:this.stateManager}),await this.agent.boot()}catch(f){throw this.logger.error("Failed to initialize ConversationalAgent:",f),f}}getPlugin(){return this.hcs10Plugin}getStateManager(){return this.stateManager}getAgent(){if(!this.agent)throw new Error("Agent not initialized. Call initialize() first.");return this.agent}getConversationalAgent(){return this.getAgent()}async processMessage(e,t=[]){if(!this.agent)throw new Error("Agent not initialized. Call initialize() first.");const n={messages:t.map(e=>"human"===e.type?new u.HumanMessage(e.content):new u.AIMessage(e.content))};return this.agent.chat(e,n)}static withPlugins(e,t){return new K({...e,enabledPlugins:t})}static withHTS(e){return this.withPlugins(e,["hts-token"])}static withHCS2(e){return this.withPlugins(e,["hcs-2"])}static withHCS10(e){return this.withPlugins(e,["hcs-10"])}static withInscribe(e){return this.withPlugins(e,["inscribe"])}static withAccount(e){return this.withPlugins(e,["account"])}static withFileService(e){return this.withPlugins(e,["file-service"])}static withConsensusService(e){return this.withPlugins(e,["consensus-service"])}static withSmartContract(e){return this.withPlugins(e,["smart-contract"])}static withAllStandards(e){return this.withPlugins(e,["hcs-10","hcs-2","inscribe"])}static minimal(e){return this.withPlugins(e,[])}static withMCP(e,t){return new K({...e,mcpServers:t})}async detectPrivateKeyType(e,t,n){const o=new i.HederaMirrorNode(n),s=await o.requestAccount(e),a=s?.key?._type||"";return a?.toLowerCase()?.includes("ecdsa")?r.PrivateKey.fromStringECDSA(t):r.PrivateKey.fromStringED25519(t)}}exports.BaseAgent=v,exports.ConversationalAgent=K,exports.HCS10Plugin=d,exports.HCS2Plugin=m,exports.HbarTransferPlugin=x,exports.InscribePlugin=p,exports.LangChainAgent=P,exports.LangChainProvider=M,exports.MCPServers={filesystem:e=>({name:"filesystem",command:"npx",args:["-y","@modelcontextprotocol/server-filesystem",e],transport:"stdio",autoConnect:!0,additionalContext:"This server provides access to files and directories in the current working directory.",toolDescriptions:{list_directory:'Use this tool when users ask about files in the "current directory" or "working directory".',read_file:"Use this tool when users ask to see or check files in the current directory."}}),github:e=>({name:"github",command:"npx",args:["-y","@modelcontextprotocol/server-github"],...e&&{env:{GITHUB_TOKEN:e}},transport:"stdio",autoConnect:!0}),slack:e=>({name:"slack",command:"npx",args:["-y","@modelcontextprotocol/server-slack"],env:{SLACK_TOKEN:e},transport:"stdio",autoConnect:!0}),googleDrive:e=>({name:"google-drive",command:"npx",args:["-y","@modelcontextprotocol/server-google-drive"],env:{GOOGLE_CREDENTIALS:e},transport:"stdio",autoConnect:!0}),postgres:e=>({name:"postgres",command:"npx",args:["-y","@modelcontextprotocol/server-postgres",e],transport:"stdio",autoConnect:!0}),sqlite:e=>({name:"sqlite",command:"npx",args:["-y","@modelcontextprotocol/server-sqlite",e],transport:"stdio",autoConnect:!0}),custom:e=>e},exports.OpenConvAIPlugin=d,exports.createAgent=k,exports.createMCPConfig=function(e,t=!0){return{mcpServers:e.map(e=>({...e,autoConnect:e.autoConnect??t}))}},exports.validateServerConfig=function(e){const t=[];return e.name||t.push("Server name is required"),e.command||t.push("Server command is required"),e.args&&Array.isArray(e.args)||t.push("Server args must be an array"),e.transport&&!["stdio","http","websocket"].includes(e.transport)&&t.push("Invalid transport type. Must be stdio, http, or websocket"),t},Object.keys(e).forEach(t=>{"default"===t||Object.prototype.hasOwnProperty.call(exports,t)||Object.defineProperty(exports,t,{enumerable:!0,get:()=>e[t]})});
2
2
  //# sourceMappingURL=index.cjs.map