UNPKG

@hashgraphonline/standards-agent-kit

Version:

A modular SDK for building on-chain autonomous agents using Hashgraph Online Standards, including HCS-10 for agent discovery and communication.

159 lines (132 loc) 5.14 kB
import { StructuredTool, ToolParams } from '@langchain/core/tools'; import { z } from 'zod'; import { IStateManager, ActiveConnection } from '../state/state-types'; import { HCS10Client } from '../hcs10/HCS10Client'; import { Connection, Logger } from '@hashgraphonline/standards-sdk'; export interface ListConnectionsToolParams extends ToolParams { stateManager: IStateManager; hcsClient?: HCS10Client; } /** * A tool to list currently active HCS-10 connections stored in the state manager. * Enhanced to show more details similar to moonscape's implementation. */ export class ListConnectionsTool extends StructuredTool { name = 'list_connections'; description = 'Lists the currently active HCS-10 connections with detailed information. Shows connection status, agent details, and recent activity. Use this to get a comprehensive view of all active connections.'; schema = z.object({ includeDetails: z .boolean() .optional() .describe( 'Whether to include detailed information about each connection' ), showPending: z .boolean() .optional() .describe('Whether to include pending connection requests'), }); private stateManager: IStateManager; private hcsClient?: HCS10Client; private logger: Logger; constructor({ stateManager, hcsClient, ...rest }: ListConnectionsToolParams) { super(rest); this.stateManager = stateManager; this.hcsClient = hcsClient; this.logger = new Logger({ module: 'ListConnectionsTool' }); } protected async _call(args: z.infer<this['schema']>): Promise<string> { const includeDetails = args.includeDetails ?? true; const showPending = args.showPending ?? true; const connections = await this.getEnhancedConnections(); if (connections.length === 0) { return 'There are currently no active connections.'; } const activeConnections = connections.filter( (c) => c.status === 'established' ); const pendingConnections = connections.filter((c) => c.isPending); const needsConfirmation = connections.filter((c) => c.needsConfirmation); let output = ''; if (activeConnections.length > 0) { output += `🟢 Active Connections (${activeConnections.length}):\n`; activeConnections.forEach((conn, index) => { output += this.formatConnection(conn, index, includeDetails); }); output += '\n'; } if (showPending && needsConfirmation.length > 0) { output += `🟠 Connections Needing Confirmation (${needsConfirmation.length}):\n`; needsConfirmation.forEach((conn, index) => { output += this.formatConnection(conn, index, includeDetails); }); output += '\n'; } if (showPending && pendingConnections.length > 0) { output += `⚪ Pending Connection Requests (${pendingConnections.length}):\n`; pendingConnections.forEach((conn, index) => { output += this.formatConnection(conn, index, includeDetails); }); } return output.trim(); } private formatConnection( conn: Connection, index: number, includeDetails: boolean ): string { let output = `${index + 1}. ${ conn.profileInfo?.display_name || conn.targetAgentName || 'Unknown Agent' } (${conn.targetAccountId})\n`; const displayTopicId = conn.isPending ? '(Pending Request)' : conn.connectionTopicId; output += ` Topic: ${displayTopicId}\n`; const statusText = conn.status || 'unknown'; output += ` Status: ${statusText}\n`; if (includeDetails) { if (conn.profileInfo?.bio) { output += ` Bio: ${conn.profileInfo.bio.substring(0, 100)}${ conn.profileInfo.bio.length > 100 ? '...' : '' }\n`; } if (conn.created) { const createdLabel = conn.isPending ? 'Request sent' : 'Connection established'; output += ` ${createdLabel}: ${conn.created.toLocaleString()}\n`; } if (conn.lastActivity) { output += ` Last activity: ${conn.lastActivity.toLocaleString()}\n`; } } return output; } private async getEnhancedConnections(): Promise<Connection[]> { if (!this.hcsClient) { return this.stateManager.listConnections() as Connection[]; } try { const { accountId } = this.hcsClient.getAccountAndSigner(); if (!accountId) { return this.stateManager.listConnections() as Connection[]; } const connectionManager = this.stateManager.getConnectionsManager(); if (!connectionManager) { this.logger.error('ConnectionsManager not initialized'); return this.stateManager.listConnections() as Connection[]; } const connections = await connectionManager.fetchConnectionData( accountId ); for (const connection of connections) { this.stateManager.updateOrAddConnection(connection as ActiveConnection); } return connections; } catch (error) { console.error('Error fetching connection data:', error); return this.stateManager.listConnections() as Connection[]; } } }