permamind
Version:
An MCP server that provides an immortal memory layer for AI agents and clients
297 lines (296 loc) • 13.6 kB
JavaScript
const service = (tealCompilerService, processService, aoMessageService) => {
return {
compileTealWorkflow: async (source, options = {}) => {
try {
// Compile Teal source
const compileResult = await tealCompilerService.compileTealToLua(source, options);
if (!compileResult.success || !compileResult.compiledLua) {
return {
error: compileResult.errors?.join(", ") || "Compilation failed",
success: false,
};
}
// Create process definition from compiled result
const processMetadata = {
aoVersion: "2.0.0",
author: "Unknown",
compileOptions: options,
description: "Compiled Teal Process",
version: "1.0.0",
};
const processDefinition = await tealCompilerService.createProcessDefinition(source, processMetadata);
return {
processDefinition,
success: true,
warnings: compileResult.warnings,
};
}
catch (error) {
return {
error: error instanceof Error ? error.message : "Compilation failed",
success: false,
};
}
},
createDevelopmentPipeline: async (processDefinition, configuration) => {
const stages = [
{
configuration: {
includeExamples: true,
queryPatterns: ["teal", "ao", "development"],
},
id: "docs-stage",
name: "docs",
service: "PermawebDocsService",
status: "pending",
},
{
configuration: {
compileOptions: processDefinition.metadata.compileOptions,
validateTypes: true,
},
id: "develop-stage",
name: "develop",
service: "TealCompilerService",
status: "pending",
},
{
configuration: {
coverage: true,
testSuite: "default",
},
id: "test-stage",
name: "test",
service: "AOLiteTestService",
status: "pending",
},
{
configuration: {
processId: processDefinition.id,
validate: true,
},
id: "deploy-stage",
name: "deploy",
service: "PermawebDeployService",
status: "pending",
},
];
return {
configuration,
createdAt: new Date(),
id: generatePipelineId(),
metadata: {
aoVersion: processDefinition.metadata.aoVersion,
author: processDefinition.metadata.author,
description: `Development pipeline for ${processDefinition.name}`,
processType: "teal",
tags: ["teal", "ao", "development"],
version: processDefinition.metadata.version,
},
name: `${processDefinition.name} Development Pipeline`,
stages,
status: "draft",
updatedAt: new Date(),
};
},
createTealWorkflow: async (templateType, name, metadata) => {
try {
// Create Teal template
const template = await tealCompilerService.createTealTemplate(templateType, name, metadata);
// Create process metadata
const processMetadata = {
aoVersion: metadata.aoVersion || "2.0.0",
author: metadata.author || "Unknown",
compileOptions: metadata.compileOptions || {
strict: true,
target: "lua53",
warnings: true,
},
description: metadata.description || `${name} ${templateType} process`,
version: metadata.version || "1.0.0",
};
// Create process definition
const processDefinition = await tealCompilerService.createProcessDefinition(template.source, processMetadata);
return {
processDefinition,
success: true,
template,
};
}
catch (error) {
return {
error: error instanceof Error ? error.message : "Workflow creation failed",
success: false,
};
}
},
deployTealProcess: async (processDefinition, signer) => {
try {
// Validate the process definition
const validationResult = await service(tealCompilerService, processService, aoMessageService).validateTealWorkflow(processDefinition.source, processDefinition.metadata.compileOptions);
if (!validationResult.success || !validationResult.isValid) {
return {
error: `Validation failed: ${validationResult.errors?.join(", ")}`,
success: false,
};
}
// Integrate with AO services
const integratedLua = await tealCompilerService.integrateWithAOServices(processDefinition.compiledLua, processDefinition.id);
// Deploy the process (this would integrate with actual AO deployment)
const deploymentResult = await deployToAO(integratedLua, signer);
return {
deploymentInfo: deploymentResult.deploymentInfo,
processId: deploymentResult.processId,
success: true,
transactionId: deploymentResult.transactionId,
};
}
catch (error) {
return {
error: error instanceof Error ? error.message : "Deployment failed",
success: false,
};
}
},
executeTealWorkflowRequest: async (processDefinition, userRequest, signer) => {
try {
// Generate process documentation for execution
const processMarkdown = await service(tealCompilerService, processService, aoMessageService).generateProcessDocumentation(processDefinition);
// Execute the request using ProcessCommunicationService
const executionResult = await processService.executeProcessRequest(processMarkdown, processDefinition.id, userRequest, signer);
return {
confidence: executionResult.confidence,
error: executionResult.error,
handlerUsed: executionResult.handlerUsed,
output: executionResult.data,
success: executionResult.success,
};
}
catch (error) {
return {
error: error instanceof Error ? error.message : "Execution failed",
success: false,
};
}
},
generateProcessDocumentation: async (processDefinition) => {
try {
// Extract handlers from compiled Lua
const handlers = extractHandlersFromLua(processDefinition.compiledLua);
// Generate markdown documentation
const documentation = `# ${processDefinition.name}\n\n${processDefinition.metadata.description}\n\n**Version:** ${processDefinition.metadata.version} \n**Author:** ${processDefinition.metadata.author} \n**AO Version:** ${processDefinition.metadata.aoVersion}\n\n## Handlers\n\n${handlers
.map((handler) => `\n### ${handler.name}\n\n${handler.description}\n\n${handler.parameters.map((param) => `- ${param.name}: ${param.description}`).join("\n")}\n`)
.join("\n")}\n\n## Type Definitions\n\n${processDefinition.typeDefinitions
.map((typedef) => `\n### ${typedef.name}\n\n${typedef.documentation || ""}\n\n\`\`\`teal\n${typedef.definition}\n\`\`\`\n`)
.join("\n")}\n\n## Dependencies\n\n${processDefinition.dependencies.map((dep) => `- ${dep}`).join("\n")}\n\n## Usage Examples\n\n\`\`\`teal\n${generateUsageExamples(processDefinition)}\n\`\`\`\n`;
return documentation;
}
catch (error) {
return `# ${processDefinition.name}\n\nDocumentation generation failed: ${error instanceof Error ? error.message : "Unknown error"}`;
}
},
validateTealWorkflow: async (source, options = {}) => {
try {
// Validate Teal types
const typeValidation = await tealCompilerService.validateTealTypes(source);
// Compile to check for syntax errors
const compileResult = await tealCompilerService.compileTealToLua(source, options);
const errors = [];
const warnings = [];
// Collect errors and warnings
if (typeValidation.errors) {
errors.push(...typeValidation.errors);
}
if (typeValidation.warnings) {
warnings.push(...typeValidation.warnings);
}
if (compileResult.errors) {
errors.push(...compileResult.errors);
}
if (compileResult.warnings) {
warnings.push(...compileResult.warnings);
}
// Validate AO compatibility
if (compileResult.compiledLua) {
const aoValidation = validateAOCompatibility(compileResult.compiledLua);
if (!aoValidation.isValid) {
errors.push(`AO compatibility: ${aoValidation.error}`);
}
}
return {
errors: errors.length > 0 ? errors : undefined,
isValid: errors.length === 0,
success: true,
typeChecks: compileResult.typeChecks,
warnings: warnings.length > 0 ? warnings : undefined,
};
}
catch (error) {
return {
errors: [
error instanceof Error ? error.message : "Validation failed",
],
isValid: false,
success: false,
};
}
},
};
};
// Helper functions
const deployToAO = async (lua, signer) => {
// This would integrate with actual AO deployment
// For now, we'll simulate the deployment
const processId = `teal-process-${Date.now()}`;
const transactionId = `tx-${Date.now()}`;
return {
deploymentInfo: {
module: "AOS_MODULE",
owner: signer.kty || "unknown",
processId,
scheduler: "AOS_SCHEDULER",
timestamp: Date.now(),
},
processId,
transactionId,
};
};
const validateAOCompatibility = (lua) => {
// Check for AO-specific patterns
if (!lua.includes("Handlers") && !lua.includes("ao.")) {
return { error: "No AO handler patterns found", isValid: false };
}
// Check for proper message handling
if (lua.includes("Handlers.add") && !lua.includes("msg.")) {
return {
error: "Handler functions must accept message parameter",
isValid: false,
};
}
return { isValid: true };
};
const extractHandlersFromLua = (lua) => {
const handlers = [];
// Extract handler definitions using regex
const handlerMatches = lua.match(/Handlers\.add\([^)]+\)/g);
if (handlerMatches) {
for (const match of handlerMatches) {
const parts = match.match(/Handlers\.add\("([^"]+)",\s*([^,]+),\s*([^)]+)\)/);
if (parts) {
handlers.push({
description: `Handler for ${parts[1]} operations`,
name: parts[1],
parameters: [{ description: "AO message object", name: "msg" }],
});
}
}
}
return handlers;
};
const generateUsageExamples = (processDefinition) => {
return `\n-- Example usage for ${processDefinition.name}\nlocal msg = {\n Id = "example-message-id",\n From = "sender-address",\n Tags = {\n Action = "Info"\n },\n Data = "",\n Timestamp = os.time()\n}\n\n-- Process the message\nlocal result = process(msg)\nprint(result.Output)\n`;
};
const generatePipelineId = () => {
return `pipeline-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
};
export const createTealWorkflowService = (tealCompilerService, processService, aoMessageService) => service(tealCompilerService, processService, aoMessageService);