@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.13 kB
JavaScript
import { StructuredTool } from "@langchain/core/tools";
import { z } from "zod";
import { Logger } from "@hashgraphonline/standards-sdk";
class SendMessageToConnectionTool extends StructuredTool {
constructor({
hcsClient,
stateManager,
...rest
}) {
super(rest);
this.name = "send_message_to_connection";
this.description = "Sends a text message to another agent using an existing active connection. Identify the target agent using their account ID (e.g., 0.0.12345) or the connection number shown in 'list_connections'. Return back the reply from the target agent if possible";
this.schema = z.object({
targetIdentifier: z.string().describe(
"The account ID (e.g., 0.0.12345) of the target agent OR the connection number (e.g., '1', '2') from the 'list_connections' tool."
),
message: z.string().describe("The text message content to send."),
disableMonitoring: z.boolean().optional().default(false)
});
this.hcsClient = hcsClient;
this.stateManager = stateManager;
this.logger = Logger.getInstance({ module: "SendMessageToConnectionTool" });
}
async _call({
targetIdentifier,
message,
disableMonitoring
}) {
const currentAgent = this.stateManager.getCurrentAgent();
if (!currentAgent) {
return "Error: Cannot send message. No agent is currently active. Please register or select an agent first.";
}
const connection = this.stateManager.getConnectionByIdentifier(targetIdentifier);
if (!connection) {
return `Error: Could not find an active connection matching identifier "${targetIdentifier}". Use 'list_connections' to see active connections.`;
}
const connectionTopicId = connection.connectionTopicId;
const targetAgentName = connection.targetAgentName;
const operatorId = `${currentAgent.inboundTopicId}@${currentAgent.accountId}`;
this.logger.info(
`Sending message from ${operatorId} to ${targetAgentName} (${connection.targetAccountId}) via connection topic ${connectionTopicId}`
);
try {
const sequenceNumber = await this.hcsClient.sendMessage(
connectionTopicId,
message,
// Message content as 'data'
`Agent message from ${currentAgent.name}`
// Optional memo
);
if (!sequenceNumber) {
throw new Error("Failed to send message");
}
if (!disableMonitoring) {
return `Message sent to ${targetAgentName} (${connection.targetAccountId}) via connection ${connectionTopicId}. Sequence Number: ${sequenceNumber}`;
}
const replyBack = await this.monitorResponses(
connectionTopicId,
operatorId,
sequenceNumber
);
if (replyBack) {
this.logger.info(`Got reply from ${targetAgentName}`, replyBack);
return `Received reply from ${targetAgentName}: ${replyBack}`;
}
return `Message sent to ${targetAgentName} (${connection.targetAccountId}) via connection ${connectionTopicId}. Sequence Number: ${sequenceNumber}`;
} catch (error) {
this.logger.error(
`Failed to send message via connection ${connectionTopicId}: ${error}`
);
return `Error sending message to ${targetAgentName}: ${error instanceof Error ? error.message : String(error)}`;
}
}
async monitorResponses(topicId, operatorId, sequenceNumber) {
const maxAttempts = 30;
const attempts = 0;
while (attempts < maxAttempts) {
try {
const messages = await this.hcsClient.getMessageStream(topicId);
for (const message of messages.messages) {
if (message.sequence_number < sequenceNumber || message.operator_id === operatorId) {
continue;
}
const content = await this.hcsClient.getMessageContent(message.data || "");
return content;
}
} catch (error) {
this.logger.error(`Error monitoring responses: ${error}`);
}
await new Promise((resolve) => setTimeout(resolve, 4e3));
}
return null;
}
}
export {
SendMessageToConnectionTool
};
//# sourceMappingURL=standards-agent-kit.es6.js.map