index.ts•8.68 kB
import { DalleService } from '../services/dalle-service.js';
import { 
  GenerateImageArgs, 
  EditImageArgs, 
  VariationArgs, 
  ValidateKeyArgs, 
  ToolResponse 
} from '../types/index.js';
import path from 'path';
// Initialize service
const dalleService = new DalleService({
  apiKey: process.env.OPENAI_API_KEY || ''
});
export const tools = [
  {
    name: "generate_image",
    description: "Generate an image using DALL-E based on a text prompt",
    inputSchema: {
      type: "object",
      properties: {
        prompt: {
          type: "string",
          description: "Text description of the desired image"
        },
        model: {
          type: "string",
          description: "DALL-E model to use (dall-e-2 or dall-e-3)",
          enum: ["dall-e-2", "dall-e-3"]
        },
        size: {
          type: "string",
          description: "Size of the generated image",
          enum: ["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]
        },
        quality: {
          type: "string",
          description: "Quality of the generated image (dall-e-3 only)",
          enum: ["standard", "hd"]
        },
        style: {
          type: "string",
          description: "Style of the generated image (dall-e-3 only)",
          enum: ["vivid", "natural"]
        },
        n: {
          type: "number",
          description: "Number of images to generate (1-10)",
          minimum: 1,
          maximum: 10
        },
        saveDir: {
          type: "string",
          description: "Directory to save the generated images"
        },
        fileName: {
          type: "string",
          description: "Base filename for the generated images (without extension)"
        }
      },
      required: ["prompt"]
    },
    handler: async (args: GenerateImageArgs): Promise<ToolResponse> => {
      const result = await dalleService.generateImage(args.prompt, {
        model: args.model,
        size: args.size,
        quality: args.quality,
        style: args.style,
        n: args.n,
        saveDir: args.saveDir,
        fileName: args.fileName
      });
      if (!result.success) {
        return {
          content: [{
            type: "text",
            text: `Error generating image: ${result.error}`
          }]
        };
      }
      const imagePaths = result.imagePaths || [];
      const imageCount = imagePaths.length;
      const model = result.model || 'dall-e-3';
      let responseText = `Successfully generated ${imageCount} image${imageCount !== 1 ? 's' : ''} using ${model}.\n\n`;
      responseText += `Prompt: "${result.prompt}"\n\n`;
      responseText += `Image${imageCount !== 1 ? 's' : ''} saved to:\n`;
      
      imagePaths.forEach(imagePath => {
        responseText += `- ${imagePath}\n`;
      });
      return {
        content: [{
          type: "text",
          text: responseText
        }]
      };
    }
  },
  {
    name: "edit_image",
    description: "Edit an existing image using DALL-E based on a text prompt",
    inputSchema: {
      type: "object",
      properties: {
        prompt: {
          type: "string",
          description: "Text description of the desired edits"
        },
        imagePath: {
          type: "string",
          description: "Path to the image to edit"
        },
        mask: {
          type: "string",
          description: "Path to the mask image (white areas will be edited, black areas preserved)"
        },
        model: {
          type: "string",
          description: "DALL-E model to use (currently only dall-e-2 supports editing)",
          enum: ["dall-e-2"]
        },
        size: {
          type: "string",
          description: "Size of the generated image",
          enum: ["256x256", "512x512", "1024x1024"]
        },
        n: {
          type: "number",
          description: "Number of images to generate (1-10)",
          minimum: 1,
          maximum: 10
        },
        saveDir: {
          type: "string",
          description: "Directory to save the edited images"
        },
        fileName: {
          type: "string",
          description: "Base filename for the edited images (without extension)"
        }
      },
      required: ["prompt", "imagePath"]
    },
    handler: async (args: EditImageArgs): Promise<ToolResponse> => {
      // Resolve relative paths to absolute paths
      const imagePath = path.isAbsolute(args.imagePath) 
        ? args.imagePath 
        : path.resolve(process.cwd(), args.imagePath);
      
      const mask = args.mask && !path.isAbsolute(args.mask)
        ? path.resolve(process.cwd(), args.mask)
        : args.mask;
      const result = await dalleService.editImage(args.prompt, imagePath, {
        mask,
        model: args.model,
        size: args.size,
        n: args.n,
        saveDir: args.saveDir,
        fileName: args.fileName
      });
      if (!result.success) {
        return {
          content: [{
            type: "text",
            text: `Error editing image: ${result.error}`
          }]
        };
      }
      const imagePaths = result.imagePaths || [];
      const imageCount = imagePaths.length;
      const model = result.model || 'dall-e-2';
      let responseText = `Successfully edited image and generated ${imageCount} variation${imageCount !== 1 ? 's' : ''} using ${model}.\n\n`;
      responseText += `Original image: ${imagePath}\n`;
      if (mask) {
        responseText += `Mask: ${mask}\n`;
      }
      responseText += `Prompt: "${result.prompt}"\n\n`;
      responseText += `Edited image${imageCount !== 1 ? 's' : ''} saved to:\n`;
      
      imagePaths.forEach(imagePath => {
        responseText += `- ${imagePath}\n`;
      });
      return {
        content: [{
          type: "text",
          text: responseText
        }]
      };
    }
  },
  {
    name: "create_variation",
    description: "Create variations of an existing image using DALL-E",
    inputSchema: {
      type: "object",
      properties: {
        imagePath: {
          type: "string",
          description: "Path to the image to create variations of"
        },
        model: {
          type: "string",
          description: "DALL-E model to use (currently only dall-e-2 supports variations)",
          enum: ["dall-e-2"]
        },
        size: {
          type: "string",
          description: "Size of the generated image",
          enum: ["256x256", "512x512", "1024x1024"]
        },
        n: {
          type: "number",
          description: "Number of variations to generate (1-10)",
          minimum: 1,
          maximum: 10
        },
        saveDir: {
          type: "string",
          description: "Directory to save the variation images"
        },
        fileName: {
          type: "string",
          description: "Base filename for the variation images (without extension)"
        }
      },
      required: ["imagePath"]
    },
    handler: async (args: VariationArgs): Promise<ToolResponse> => {
      // Resolve relative path to absolute path
      const imagePath = path.isAbsolute(args.imagePath) 
        ? args.imagePath 
        : path.resolve(process.cwd(), args.imagePath);
      const result = await dalleService.createVariation(imagePath, {
        model: args.model,
        size: args.size,
        n: args.n,
        saveDir: args.saveDir,
        fileName: args.fileName
      });
      if (!result.success) {
        return {
          content: [{
            type: "text",
            text: `Error creating image variations: ${result.error}`
          }]
        };
      }
      const imagePaths = result.imagePaths || [];
      const imageCount = imagePaths.length;
      const model = result.model || 'dall-e-2';
      let responseText = `Successfully created ${imageCount} variation${imageCount !== 1 ? 's' : ''} using ${model}.\n\n`;
      responseText += `Original image: ${imagePath}\n\n`;
      responseText += `Variation${imageCount !== 1 ? 's' : ''} saved to:\n`;
      
      imagePaths.forEach(imagePath => {
        responseText += `- ${imagePath}\n`;
      });
      return {
        content: [{
          type: "text",
          text: responseText
        }]
      };
    }
  },
  {
    name: "validate_key",
    description: "Validate the OpenAI API key",
    inputSchema: {
      type: "object",
      properties: {},
      required: []
    },
    handler: async (_args: ValidateKeyArgs): Promise<ToolResponse> => {
      const isValid = await dalleService.validateApiKey();
      return {
        content: [{
          type: "text",
          text: isValid ? "API key is valid" : "API key is invalid"
        }]
      };
    }
  }
];