permamind
Version:
An MCP server that provides an immortal memory layer for AI agents and clients
97 lines (93 loc) • 4.28 kB
JavaScript
import { z } from "zod";
import { defaultProcessService } from "../../../services/DefaultProcessService.js";
import { processCommunicationService, } from "../../../services/ProcessCommunicationService.js";
import { TokenProcessTemplateService } from "../../../services/TokenProcessTemplateService.js";
import { CommonSchemas, ToolCommand, } from "../../core/index.js";
export class ExecuteActionCommand extends ToolCommand {
context;
metadata = {
description: `Execute actions on AO processes using natural language. This is the core tool for AO process communication -
provide process documentation in markdown format and make natural language requests. The service automatically parses
process handlers, understands your request, formats AO messages, and executes them. Essential for interactive AO process
communication in the decentralized computing environment.`,
name: "executeAction",
openWorldHint: false,
readOnlyHint: false,
title: "Execute Action",
};
parametersSchema = z.object({
processId: CommonSchemas.processId.describe("The AO process ID to communicate with"),
processMarkdown: z
.string()
.optional()
.describe("Markdown documentation describing the process handlers and parameters"),
processType: z
.string()
.optional()
.describe("Optional process type hint (e.g., 'token') to use embedded templates"),
request: z
.string()
.describe("Natural language request describing what action to perform"),
});
constructor(context) {
super();
this.context = context;
}
async execute(args) {
try {
let processMarkdown = args.processMarkdown;
// If processMarkdown not provided but processType is, use embedded template
if (!processMarkdown && args.processType) {
// Check if it's a token process type
if (TokenProcessTemplateService.isSupported(args.processType)) {
processMarkdown =
TokenProcessTemplateService.getTokenTemplateAsMarkdown(args.processId);
}
else {
// Fallback to default process service for other types
const template = defaultProcessService.getDefaultProcess(args.processType, args.processId);
if (template) {
// Convert template to markdown format
processMarkdown = this.convertTemplateToMarkdown(template);
}
}
}
// Use ProcessCommunicationService to execute the request
const result = await processCommunicationService.executeSmartRequest(args.processId, args.request, this.context.keyPair, processMarkdown, this.context.embeddedTemplates);
return JSON.stringify(result);
}
catch (error) {
return JSON.stringify({
error: error instanceof Error ? error.message : "Unknown error",
success: false,
});
}
}
convertTemplateToMarkdown(template) {
// Use the same markdown generation logic as TokenProcessTemplateService
// to maintain consistency across template conversions
let markdown = `# ${template.name}
`;
for (const handler of template.handlers) {
markdown += `## ${handler.action}
`;
markdown += `${handler.description}
`;
if (handler.parameters && handler.parameters.length > 0) {
for (const param of handler.parameters) {
const required = param.required ? "required" : "optional";
markdown += `- ${param.name}: ${param.description} (${required})\n`;
}
markdown += "\n";
}
if (handler.examples && handler.examples.length > 0) {
markdown += "Examples:\n";
for (const example of handler.examples) {
markdown += `- ${example}\n`;
}
markdown += "\n";
}
}
return markdown;
}
}