| 9774 | const handler = createPuterIPCHandler(event); |
| 9775 | return await handler(prompt, imageUrl, model); |
| 9776 | }); |
| 9777 | |
| 9778 | ipcMain.handle('generate-tags', async (event, filePath) => { |
| 9779 | try { |
| 9780 | const aitagging = require('./aitagging'); |
| 9781 | const settings = getSettings(); |
| 9782 | |
| 9783 | // Create puter IPC handler if service is puter |
| 9784 | // Pass event so it can route to the correct client (WebSocket in server mode, IPC in normal mode) |
| 9785 | const puterIPCHandler = settings.aiService === 'puter' ? createPuterIPCHandler(event) : null; |
| 9786 | |
| 9787 | // Initialize OpenAI with the API key |
| 9788 | aitagging.initializeOpenAI(settings.apiKey, settings.apiEndpoint, settings.aiService, puterIPCHandler); |
| 9789 | |
| 9790 | // Get the model from the database to access its thumbnail |
| 9791 | const model = getModelByFilePath(filePath, { includeThumbnail: true }); |
| 9792 | |
| 9793 | if (!model) { |
| 9794 | console.log(`Model not found in database: ${filePath}`); |
| 9795 | return []; |
| 9796 | } |
| 9797 | |
| 9798 | // Get the model tags from the database |
| 9799 | const modelTagRows = db.prepare(` |
| 9800 | SELECT t.name |
| 9801 | FROM tags t |
| 9802 | JOIN model_tags mt ON mt.tag_id = t.id |
| 9803 | WHERE mt.model_id = ? |
| 9804 | `).all(model.id); |
| 9805 | |
| 9806 | const modelTags = modelTagRows.map(row => row.name); |
| 9807 | |
| 9808 | // Check if model already has the "AI Tagged" tag (unless retagging is allowed) |
| 9809 | if (!settings.aiTagAllowRetagging && modelTags.includes("AI Tagged")) { |
| 9810 | console.log(`Model ${filePath} already has AI Tagged tag, skipping generation`); |
| 9811 | return []; |
| 9812 | } |
| 9813 | |
| 9814 | // Prepare tag generation options (read aiTagPrompt from DB so we always have latest) |
| 9815 | const aiTagPromptValue = db.prepare('SELECT value FROM settings WHERE key = ?').get('aiTagPrompt')?.value ?? null; |
| 9816 | const tagOptions = { |
| 9817 | maxTags: settings.aiTagMaxTags, |
| 9818 | useCategories: settings.aiTagUseCategories, |
| 9819 | useJsonResponse: settings.aiTagUseJsonResponse, |
| 9820 | detailLevel: settings.aiTagDetailLevel, |
| 9821 | customPrompt: (aiTagPromptValue != null && String(aiTagPromptValue).trim() !== '') ? String(aiTagPromptValue).trim() : null |
| 9822 | }; |
| 9823 | |
| 9824 | if (!model.thumbnail) { |
| 9825 | // If no thumbnail exists, we need to generate one or use a default image |
| 9826 | console.log('No thumbnail found for model, using default image'); |
| 9827 | try { |
| 9828 | const fs = require('fs').promises; |
| 9829 | const defaultImagePath = './logo.png'; // Use a default image that's guaranteed to be in PNG format |
| 9830 | const data = await fs.readFile(defaultImagePath, { encoding: 'base64' }); |
| 9831 | const tags = await aitagging.generateTagsForImage(data, settings.aiModel, tagOptions, 2000, 5, filePath); |
| 9832 | return tags; |
| 9833 | } catch (error) { |