import { z } from "zod";
/**
* Visualization Tools - Generate visual representations of code and systems
*/
// ============================================
// Generate Diagram Tool
// ============================================
export const generateDiagramSchema = {
name: "generate_diagram",
description:
"Generates Mermaid.js diagrams to visualize code, systems, or flows",
inputSchema: z.object({
type: z
.enum([
"flowchart",
"sequence",
"class",
"state",
"erd",
"gantt",
"mindmap",
"pie",
])
.describe("Type of diagram to generate"),
description: z
.string()
.describe("Description of the system or flow to visualize"),
direction: z
.enum(["TB", "LR", "RL", "BT"])
.optional()
.default("TB")
.describe("Direction (Top-Bottom, Left-Right)"),
}),
};
export function generateDiagramHandler(args: {
type: string;
description: string;
direction?: string;
}) {
const { type, description, direction = "TB" } = args;
// In a real implementation, this would use the LLM to process the description into Mermaid syntax.
// Since we are simulating the *tool* response that guides the AI, we return instructions or a template.
// However, since the AI *calling* this tool is the one generating the content,
// we should return a prompt that helps the AI generate specific Mermaid syntax.
// BUT, if this tool is meant to *produce* the diagram for the user,
// the handler itself should ideally do the work or return the structure.
// Let's return a structured response that acts as a "Diagram Builder"
const templates: Record<string, string> = {
flowchart: `graph ${direction}
Start([Start]) --> Process[Process]
Process --> Decision{Decision?}
Decision -- Yes --> End([End])
Decision -- No --> Process`,
sequence: `sequenceDiagram
participant User
participant System
User->>System: Request
System-->>User: Response`,
class: `classDiagram
class Animal {
+String name
+eat()
}
class Dog {
+bark()
}
Animal <|-- Dog`,
state: `stateDiagram-v2
[*] --> Idle
Idle --> Processing : Event
Processing --> [*]`,
erd: `erDiagram
USER ||--o{ POST : writes
USER {
string name
string email
}
POST {
string title
string content
}`,
gantt: `gantt
title Project Schedule
dateFormat YYYY-MM-DD
section Section
Task :a1, 2024-01-01, 30d`,
mindmap: `mindmap
root((Central Idea))
Topic 1
Subtopic A
Topic 2`,
};
return {
content: [
{
type: "text",
text: `# Mermaid Diagram: ${type}\n\nUse this syntax in your markdown files:\n\n\`\`\`mermaid\n${templates[type] || "graph TD; A-->B;"}\n\`\`\`\n\n**Instructions for AI**: Replace the placeholder content above with the specific logic described in: "${description}".`,
},
],
};
}
// ============================================
// Visualize System Tool
// ============================================
export const visualizeSystemSchema = {
name: "visualize_system",
description: "Visualizes the high-level architecture of the current project",
inputSchema: z.object({
components: z.array(z.string()).describe("List of system components"),
relationships: z
.array(z.string())
.describe("List of connections (e.g. 'Web -> API')"),
style: z.enum(["simple", "detailed", "c4"]).optional().default("simple"),
}),
};
export function visualizeSystemHandler(args: {
components: string[];
relationships: string[];
style?: string;
}) {
const { components, relationships, style } = args;
const graph = `graph ${style === "simple" ? "LR" : "TB"}
%% Components
${components.map((c) => ` ${c.replace(/\s+/g, "")}[${c}]`).join("\n")}
%% Relationships
${relationships
.map((r) => {
const [from, to] = r.split("->").map((s) => s.trim().replace(/\s+/g, ""));
return ` ${from} --> ${to}`;
})
.join("\n")}`;
return {
content: [
{
type: "text",
text: `# System Architecture (${style})\n\n\`\`\`mermaid\n${graph}\n\`\`\``,
},
],
};
}
// Export all
export const visualizationTools = {
generateDiagramSchema,
generateDiagramHandler,
visualizeSystemSchema,
visualizeSystemHandler,
};