@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.
99 lines (98 loc) • 4.28 kB
JavaScript
import { StructuredTool } from "@langchain/core/tools";
import { z } from "zod";
import { Logger } from "@hashgraphonline/standards-sdk";
class InitiateConnectionTool extends StructuredTool {
constructor({
hcsClient,
stateManager,
...rest
}) {
super(rest);
this.name = "initiate_connection";
this.description = "Actively STARTS a NEW HCS-10 connection TO a specific target agent identified by their account ID. Requires the targetAccountId parameter. Use this ONLY to INITIATE an OUTGOING connection request.";
this.schema = z.object({
targetAccountId: z.string().describe(
"The Hedera account ID (e.g., 0.0.12345) of the agent you want to connect with."
)
});
this.hcsClient = hcsClient;
this.stateManager = stateManager;
this.logger = Logger.getInstance({ module: "InitiateConnectionTool" });
}
async _call({
targetAccountId
}) {
const currentAgent = this.stateManager.getCurrentAgent();
if (!currentAgent) {
return "Error: Cannot initiate connection. No agent is currently active. Please register or select an agent first.";
}
this.logger.info(
`Attempting connection from ${currentAgent.accountId} to ${targetAccountId}`
);
try {
this.logger.debug(`Retrieving profile for ${targetAccountId}...`);
const targetProfile = await this.hcsClient.getAgentProfile(
targetAccountId
);
if (!targetProfile?.topicInfo?.inboundTopic) {
return `Error: Could not retrieve profile or find inbound topic ID for target agent ${targetAccountId}. They might not be registered or have a public profile.`;
}
const targetInboundTopicId = targetProfile.topicInfo.inboundTopic;
const targetAgentName = targetProfile.profile.name || `Agent ${targetAccountId}`;
const requestResult = await this.hcsClient.submitConnectionRequest(
targetInboundTopicId,
currentAgent.name
);
const sequenceNumberLong = requestResult?.topicSequenceNumber;
if (!sequenceNumberLong) {
throw new Error("Connection request sequence number not found.");
}
let connectionRequestId;
try {
connectionRequestId = sequenceNumberLong.toNumber();
if (isNaN(connectionRequestId)) {
throw new Error("Converted sequence number is NaN.");
}
} catch (conversionError) {
throw new Error(
`Failed to convert connection request sequence number: ${conversionError}`
);
}
const confirmationTimeoutMs = 6e4;
const delayMs = 2e3;
const maxAttempts = Math.ceil(confirmationTimeoutMs / delayMs);
const confirmationResult = await this.hcsClient.waitForConnectionConfirmation(
targetInboundTopicId,
connectionRequestId,
maxAttempts,
delayMs
);
if (!confirmationResult?.connectionTopicId) {
return `Error: Connection confirmation not received from ${targetAccountId} (for request ${connectionRequestId}) within ${confirmationTimeoutMs / 1e3} seconds.`;
}
const connectionTopicId = confirmationResult.connectionTopicId;
this.logger.info(`Connection confirmed! Topic ID: ${connectionTopicId}`);
const newConnection = {
targetAccountId,
targetAgentName,
targetInboundTopicId,
connectionTopicId
};
this.stateManager.addActiveConnection(newConnection);
const connections = this.stateManager.listConnections();
const addedEntry = connections.find(
(c) => c.connectionTopicId === connectionTopicId
);
const localConnectionId = addedEntry ? connections.indexOf(addedEntry) + 1 : null;
const idString = localConnectionId ? `#${localConnectionId}` : "";
return `Successfully established connection ${idString} with ${targetAgentName} (${targetAccountId}). Connection Topic: ${connectionTopicId}. You can now send messages using this connection.`;
} catch (error) {
this.logger.error(`Connection initiation failed: ${error}`);
return `Error initiating connection with ${targetAccountId}: ${error instanceof Error ? error.message : String(error)}`;
}
}
}
export {
InitiateConnectionTool
};
//# sourceMappingURL=standards-agent-kit.es7.js.map