APP-Backend / src /ai /folder-agent.js
Luca448's picture
AI: Updated folder AI agent to generate contextual colors alongside icons, applying them during automated folder creations across the app
9d0d36d
Raw History Blame Contribute Delete
3.87 kB
import { gemini } from './gemini.js';
import { fsService } from '../services/file-system.js';
import { db } from '../db/database.js';
import { ICON_NAMES } from '../utils/icons.js?v=2';
export class FolderAgent {
getGeminiKey() {
return db.getSetting('gemini_api_key');
}
/**
* Analysiert den Text und schlägt 3 passende Ordner vor,
* basierend auf der bestehenden Ordnerstruktur.
*/
async suggestFolders(text) {
// Hole alle existierenden Ordner im Root
const files = await fsService.readDir('');
const existingDirs = files.filter(f => f.type === 'directory').map(f => f.name);
const prompt = `Du bist ein intelligenter Datei-Manager.
Ich habe hier ein Dokument. Bitte analysiere den Inhalt und schlage mir 3 kurze, prägnante Ordnernamen (Kategorien/Fächer) vor, in denen dieses Dokument abgelegt werden sollte.
WICHTIGE REGEL ZU EXISTIERENDEN ORDNERN:
Hier sind die bereits in meinem System existierenden Ordner: [${existingDirs.length > 0 ? existingDirs.join(', ') : 'Noch keine Ordner vorhanden'}]
Zwingende Anweisung: Wenn das Dokument auch nur im Entferntesten in einen dieser existierenden Ordner passt, dann MUSST du exakt diesen Namen als Priorität 1 verwenden! Erfinde keine neuen Namen für bestehende Kategorien (z.B. nutze existierendes "Mathe" statt neuem "Mathematik").
REGELN:
- Antworte NUR mit einem JSON Array von genau 3 Strings. Keine Erklärungen.
- Die Namen sollten wie Schulfächer oder große Kategorien klingen (z.B. "Biologie", "Informatik", "Geschichte").
- Nutze keine Schrägstriche oder Sonderzeichen.
Dokumenten-Ausschnitt:
${text.substring(0, 1500)}`;
try {
const response = await gemini.generateContent(prompt, 'gemini-2.5-flash', this.getGeminiKey());
const jsonMatch = response.match(/\[.*\]/s);
if (jsonMatch) {
return JSON.parse(jsonMatch[0]);
}
return ["Allgemein", "Dokumente", "Sonstiges"];
} catch (e) {
console.error('Folder Agent Error:', e);
return ["Allgemein", "Dokumente", "Sonstiges"];
}
}
async generateFilename(text) {
const prompt = `Generiere einen sehr kurzen, passenden Dateinamen (max 3 Worte) für diesen Text.
Antworte NUR mit dem Dateinamen. Keine Dateiendung, keine Sonderzeichen, Leerzeichen durch Unterstriche ersetzen.
Beispiel: Photosynthese_Zusammenfassung
Text:
${text.substring(0, 1000)}`;
try {
const response = await gemini.generateContent(prompt, 'gemini-2.5-flash', this.getGeminiKey());
return response.trim().replace(/ /g, '_').replace(/[^a-zA-Z0-9_-]/g, '');
} catch (e) {
return "Dokument_" + Date.now();
}
}
async generateVisualsForFolder(folderName) {
const prompt = `Wähle das passendste Icon UND eine passende Farbe (als HEX Code) für einen Ordner namens "${folderName}".
Du musst als valides JSON antworten mit den Feldern "icon" und "color".
Für "icon" darfst du NUR exakt einen dieser Namen verwenden:
${ICON_NAMES.join(', ')}
Beispiel:
"Biologie" -> {"icon": "microscope", "color": "#4caf50"}
"Mathematik" -> {"icon": "calculator", "color": "#2196f3"}
"Feuerwehr" -> {"icon": "flame", "color": "#f44336"}
Antworte NUR mit dem JSON-Objekt.`;
try {
const response = await gemini.generateContent(prompt, 'gemini-2.5-flash', this.getGeminiKey());
const jsonMatch = response.match(/\{.*\}/s);
if (jsonMatch) {
const data = JSON.parse(jsonMatch[0]);
let iconName = (data.icon || '').trim().toLowerCase();
if (!ICON_NAMES.includes(iconName)) iconName = 'folder';
return { emoji: iconName, color: data.color || '#4285f4' };
}
return { emoji: 'folder', color: '#4285f4' };
} catch (e) {
console.error('Visuals Generation Error:', e);
return { emoji: 'folder', color: '#4285f4' };
}
}
}
export const folderAgent = new FolderAgent();