diff --git a/.DS_Store b/.DS_Store index 5008ddf..433fa90 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/main.js b/main.js index a2c7e34..597a7c6 100644 --- a/main.js +++ b/main.js @@ -1,81 +1,72 @@ // Loading required packages -require("./requires.js") +require("./requires.js"); console.log(start); - // Initialising map to be used to store the functionality later on for reloadability -mapFunctions = new Map() - +mapFunctions = new Map(); // Loading the Function Map -var path = `${mainDir}/services/modules` +var path = `${mainDir}/services/modules`; var folders = fs.readdirSync(path).filter(function (file) { - return fs.statSync(path+'/'+file).isDirectory(); + return fs.statSync(path + "/" + file).isDirectory(); }); -folders.forEach(element => { - var commandFiles = fs.readdirSync(`${path}/${element}`).filter(file => file.endsWith('.js') && !file.startsWith("index")); - for (const file of commandFiles) { - delete require.cache[require.resolve(`${path}/${element}/${file}`)]; - const command = require(`${path}/${element}/${file}`); - mapFunctions.set(command.name, command); - } +folders.forEach((element) => { + var commandFiles = fs + .readdirSync(`${path}/${element}`) + .filter((file) => file.endsWith(".js") && !file.startsWith("index")); + for (const file of commandFiles) { + delete require.cache[require.resolve(`${path}/${element}/${file}`)]; + const command = require(`${path}/${element}/${file}`); + mapFunctions.set(command.name, command); + } }); - - // The startup information for the project, here you can add stuff that might be nice to see when the app starts -mapFunctions.get("Startup_function").function() -console.log("------------------------------------ Status ------------------------------------"); +mapFunctions.get("Startup_function").function(); +console.log( + "------------------------------------ Status ------------------------------------" +); console.log(__dirname); console.log(platform); -console.log(`The Startup took ${new Date() - start}ms`) +console.log(`The Startup took ${new Date() - start}ms`); console.log(`${mapFunctions.size} Function modules loaded`); -console.log("--------------------------------------------------------------------------------"); - - - - - +console.log( + "--------------------------------------------------------------------------------" +); // --------------------------------------------------------- CLI COMMANDS --------------------------------------------------------- // const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout + input: process.stdin, + output: process.stdout, }); - -rl.on("line", data =>{ - const args = data.trim().split(" "); - const command = args.shift().toLowerCase(); - mapFunctions.get("cliCommands").function(command, args) -}) - - - - +rl.on("line", (data) => { + const args = data.trim().split(" "); + const command = args.shift().toLowerCase(); + mapFunctions.get("cliCommands").function(command, args); +}); // ----------------------------------------------------------- ELECTRON ----------------------------------------------------------- // let mainWindow; function createWindow() { - mainWindow = new electron.BrowserWindow({ - width: 1200, - height: 800, - webPreferences: { - nodeIntegration: false, - contextIsolation: true, - preload: `${mainDir}/electron/main/preload.js` - } - }); + mainWindow = new electron.BrowserWindow({ + width: 1200, + height: 800, + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + preload: `${mainDir}/electron/main/preload.js`, + }, + }); - mainWindow.loadFile('./electron/main/index.html'); + mainWindow.loadFile("./electron/main/index.html"); } electron.app.whenReady().then(createWindow); - // electron.ipcMain.on("extract", (event, args) => { // mapFunctions.get("extraction-video-to-audio").function(args) // }) @@ -84,26 +75,31 @@ electron.app.whenReady().then(createWindow); // mainWindow.webContents.send("fuck", "worked uwu") // }, 5000); -electron.ipcMain.handle('get-module-names', async () => { - let module_array = { - "ai_modules":[], - "transcription_modules":[] +electron.ipcMain.handle("get-module-names", async () => { + let module_array = { + ai_modules: [], + transcription_modules: [], + }; + mapFunctions.forEach((e) => { + switch (e.type) { + case "llm": + module_array.ai_modules.push({ + name: e.name, + displayname: e.displayname, + }); + break; + case "transcription": + module_array.transcription_modules.push({ + name: e.name, + displayname: e.displayname, + }); + break; } - mapFunctions.forEach(e => { - switch(e.type){ - case "llm": - module_array.ai_modules.push({"name": e.name, "displayname": e.displayname}) - break; - case "transcription": - module_array.transcription_modules.push({"name": e.name, "displayname": e.displayname}) - break; - } - }) - // console.log(module_array); - return module_array + }); + // console.log(module_array); + return module_array; }); - // electron.ipcMain.on("get_modules", async (event, args) => { // let module_array = { // "ai_modules":[], @@ -124,165 +120,219 @@ electron.ipcMain.handle('get-module-names', async () => { // mainWindow.webContents.send("modules", module_array) // }) -var globalArgs = {} -var globalFinalHtmlPath = "" +var globalArgs = {}; +var globalFinalHtmlPath = ""; electron.ipcMain.on("file_submit", async (event, args) => { - try { - globalArgs = args - let curstep = 0 - let totalsteps = 4 + try { + globalArgs = args; + let curstep = 0; + let totalsteps = 4; - const TEMPLATE_MAP = { - "followup-report": "followup_report.txt", - "agenda": "agenda.txt", - "result-protocol": "result_protocol.txt", - "sprint-planning": "sprint_planning_note.txt", - "custom": "custom_document.txt" - }; + const TEMPLATE_MAP = { + "followup-report": "followup_report.txt", + agenda: "agenda.txt", + "result-protocol": "result_protocol.txt", + "sprint-planning": "sprint_planning_note.txt", + custom: "custom_document.txt", + }; - const templateFile = TEMPLATE_MAP[args.document.type]; + const templateFile = TEMPLATE_MAP[args.document.type]; - if (!templateFile) { - throw new Error("Unknown document type: " + args.document.type); - } - - console.log(args); - let audiopath = "" - let transcriptpath = "" - - console.log("\n\n Running the Video to Audio Extractor"); - // This code handles the Video to Audio extraction module call - await mapFunctions.get("module-handler").function(args.video.module, {inputVideoPath: args.video.inputVideoPath, outputType: mapFunctions.get(args.transcription.module).audioformat}).then(resp => { - console.log(resp); - audiopath = resp - curstep++ - mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) - }).catch(err => { - mainWindow.webContents.send("error", err) - console.log(err); - return - }) - - - console.log("\n\n Running the Audio to Transcription module"); - // TODO implement transcription module - // This code handles the Audio to Text transcription module call - await mapFunctions.get("module-handler").function(args.transcription.module, audiopath).then(resp => { - console.log(resp); - transcriptpath = resp - curstep++ - mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) - }).catch(err => { - mainWindow.webContents.send("error", err) - console.log(err); - return - }) - - - console.log("\n\n Running the Transcription Summarizer module"); - // This code summarises the transcript, so that it can be used by an llm - // await mapFunctions.get("summarize-transcription").function('A:\\programing\\@projects\\video2document\\storage\\transcripts\\IMG_2978.json').then(resp => { - await mapFunctions.get("summarize-transcription2").function(transcriptpath).then(resp => { - console.log(resp); - transcriptpath = resp - curstep++ - mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) - }).catch(err => { - mainWindow.webContents.send("error", err) - console.log(err); - return - }) - - console.log("\n\n Running the LLM module"); - // TODO implement documentation module - // This code handles the Text to Document processing module call - - console.log(`\n\n Running the LLM for Document Style ${args.document.type}`); - - await mapFunctions.get("module-handler").function(args.document.module, { inputTranscriptPath: transcriptpath, documentTypePath: "./storage/documentType/" + templateFile, language: "en" }).then(resp => { - console.log(resp); - globalFinalHtmlPath = resp - curstep++ - mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) - }).catch(err => { - mainWindow.webContents.send("error", err) - console.log(err); - return - }) - - - await mapFunctions.get("extract-speaker-snippets").function({audioPath: audiopath, jsonPath: transcriptpath }).then(resp => { - mainWindow.webContents.send("speakerAudios", resp) - }).catch(err => { - mainWindow.webContents.send("error", err) - console.log(err); - return - }) - } catch (error) { - console.log(error); + if (!templateFile) { + throw new Error("Unknown document type: " + args.document.type); } -}) -electron.ipcMain.on("file_download", async() => { - await mapFunctions.get("htmlDocumentConverter").convert({inputPath:globalFinalHtmlPath, format: globalArgs.document.outputType, showDialog: true}); -}) + console.log(args); + let audiopath = ""; + let transcriptpath = ""; -electron.ipcMain.on("speaker_submit", async() => { - console.log("\n\n\nJa also hier kam was an \n\n\n"); -}) + console.log("\n\n Running the Video to Audio Extractor"); + // This code handles the Video to Audio extraction module call + await mapFunctions + .get("module-handler") + .function(args.video.module, { + inputVideoPath: args.video.inputVideoPath, + outputType: mapFunctions.get(args.transcription.module).audioformat, + }) + .then((resp) => { + console.log(resp); + audiopath = resp; + curstep++; + mainWindow.webContents.send("progress", { + curstep: curstep, + totalsteps: totalsteps, + }); + }) + .catch((err) => { + mainWindow.webContents.send("error", err); + console.log(err); + return; + }); -let q = -{ - video: { - module: "String", // The name of the module, idk if we ever implement other extraction modules, the default one is extraction-video-to-audio - inputVideoPath: "String", // See script.js on line 27 for an example of what this should look like - outputType: "String" // The file format to be used for the audio output file, such as wav, mp3, flac and so on - }, - transcription:{ - module: "String" // The module name of the transcription model you want to use - }, - document:{ - module: "String", // The module name of the AI model you want to use to create the document - styles: [ // An array of all the document styles/prompts you want to have the document be processed with - { - prompt: "String", - } - ] - } -} + console.log("\n\n Running the Audio to Transcription module"); + // TODO implement transcription module + // This code handles the Audio to Text transcription module call + await mapFunctions + .get("module-handler") + .function(args.transcription.module, audiopath) + .then((resp) => { + console.log(resp); + transcriptpath = resp; + curstep++; + mainWindow.webContents.send("progress", { + curstep: curstep, + totalsteps: totalsteps, + }); + }) + .catch((err) => { + mainWindow.webContents.send("error", err); + console.log(err); + return; + }); + console.log("\n\n Running the Transcription Summarizer module"); + // This code summarises the transcript, so that it can be used by an llm + // await mapFunctions.get("summarize-transcription").function('A:\\programing\\@projects\\video2document\\storage\\transcripts\\IMG_2978.json').then(resp => { + await mapFunctions + .get("summarize-transcription2") + .function(transcriptpath) + .then((resp) => { + console.log(resp); + transcriptpath = resp; + curstep++; + mainWindow.webContents.send("progress", { + curstep: curstep, + totalsteps: totalsteps, + }); + }) + .catch((err) => { + mainWindow.webContents.send("error", err); + console.log(err); + return; + }); + + console.log("\n\n Running the LLM module"); + // TODO implement documentation module + // This code handles the Text to Document processing module call + + console.log( + `\n\n Running the LLM for Document Style ${args.document.type}` + ); + + await mapFunctions + .get("module-handler") + .function(args.document.module, { + inputTranscriptPath: transcriptpath, + documentTypePath: "./storage/documentType/" + templateFile, + language: "en", + }) + .then((resp) => { + console.log(resp); + globalFinalHtmlPath = resp; + curstep++; + mainWindow.webContents.send("progress", { + curstep: curstep, + totalsteps: totalsteps, + }); + }) + .catch((err) => { + mainWindow.webContents.send("error", err); + console.log(err); + return; + }); + + await mapFunctions + .get("extract-speaker-snippets") + .function({ audioPath: audiopath, jsonPath: transcriptpath }) + .then((resp) => { + mainWindow.webContents.send("speakerAudios", resp); + }) + .catch((err) => { + mainWindow.webContents.send("error", err); + console.log(err); + return; + }); + } catch (error) { + console.log(error); + } +}); + +electron.ipcMain.on("file_download", async () => { + await mapFunctions + .get("htmlDocumentConverter") + .convert({ + inputPath: globalFinalHtmlPath, + format: globalArgs.document.outputType, + showDialog: true, + }); +}); + +electron.ipcMain.on("speaker_submit", async (event, args) => { + console.log("\n\n\nJa also hier kam was an \n\n\n"); + console.log(args); + + try { + await mapFunctions.get("replace_speaker").function(args); + event.reply("speaker_submit_response", { success: true }); + } catch (error) { + console.error("Error:", error); + event.reply("speaker_submit_response", { + success: false, + error: error.message, + }); + } +}); + +let q = { + video: { + module: "String", // The name of the module, idk if we ever implement other extraction modules, the default one is extraction-video-to-audio + inputVideoPath: "String", // See script.js on line 27 for an example of what this should look like + outputType: "String", // The file format to be used for the audio output file, such as wav, mp3, flac and so on + }, + transcription: { + module: "String", // The module name of the transcription model you want to use + }, + document: { + module: "String", // The module name of the AI model you want to use to create the document + styles: [ + // An array of all the document styles/prompts you want to have the document be processed with + { + prompt: "String", + }, + ], + }, +}; let q1 = { - "ai_modules": [ - {name:"abc", displayname:"ABC"}, - {name:"qeg", displayname:"aqghegahu"} - ], - "transcription_modules": [ - {name:"abc", displayname:"ABC"}, - {name:"qeg", displayname:"aqghegahu"} - ] -} + ai_modules: [ + { name: "abc", displayname: "ABC" }, + { name: "qeg", displayname: "aqghegahu" }, + ], + transcription_modules: [ + { name: "abc", displayname: "ABC" }, + { name: "qeg", displayname: "aqghegahu" }, + ], +}; //gibt Documentfiles an preload zurück -electron.ipcMain.handle('get-txt-files', () => { - const storagePath = `${mainDir}/storage/documentType` +electron.ipcMain.handle("get-txt-files", () => { + const storagePath = `${mainDir}/storage/documentType`; -return fs.readdirSync(storagePath) - .filter(f => f.endsWith('.txt')) + return fs.readdirSync(storagePath).filter((f) => f.endsWith(".txt")); }); //speichern neuer document types -electron.ipcMain.handle('save-txt-file', (event, fileName, content) => { +electron.ipcMain.handle("save-txt-file", (event, fileName, content) => { const filePath = `${mainDir}/storage/documentType/${fileName}.txt`; - fs.writeFileSync(filePath, content, 'utf8'); + fs.writeFileSync(filePath, content, "utf8"); return true; }); // -electron.ipcMain.handle('read-txt-file', (event, fileName) => { +electron.ipcMain.handle("read-txt-file", (event, fileName) => { const filePath = `${mainDir}/storage/documentType/${fileName}`; - return fs.readFileSync(filePath, 'utf8'); -}); \ No newline at end of file + return fs.readFileSync(filePath, "utf8"); +}); diff --git a/services/modules/replace_speaker/replaceSpeaker.js b/services/modules/replace_speaker/replaceSpeaker.js index 34a0e44..bcc36f8 100644 --- a/services/modules/replace_speaker/replaceSpeaker.js +++ b/services/modules/replace_speaker/replaceSpeaker.js @@ -7,35 +7,54 @@ const module_exports = { displayname: "Speaker Name Replacer", description: "Replaces speaker placeholder names with actual names based on a mapping in HTML files", - async function({ inputHtmlPath, speakerMappingPath }) { - return await this.replaceNames(inputHtmlPath, speakerMappingPath); + async function(speakerMapping) { + // Relativ von dieser Datei aus + const documentsDir = path.resolve(__dirname, '../../../storage/documents'); + const inputHtmlPath = await this.getNewestFile(documentsDir, '.html'); + + if (!inputHtmlPath) { + throw new Error(`No HTML files found in ${documentsDir}`); + } + + return await this.replaceNames(inputHtmlPath, speakerMapping); }, - replaceNames: async function(inputHtmlPath, speakerMappingPath) { + getNewestFile: async function(dirPath, extension) { + try { + const files = await fs.promises.readdir(dirPath); + const filtered = files.filter(f => f.endsWith(extension)); + + if (filtered.length === 0) return null; + + const filesWithStats = await Promise.all( + filtered.map(async (f) => { + const fullPath = path.join(dirPath, f); + const stats = await fs.promises.stat(fullPath); + return { path: fullPath, time: stats.mtimeMs }; + }) + ); + + return filesWithStats.reduce((newest, curr) => + curr.time > newest.time ? curr : newest + ).path; + } catch (error) { + console.error("Error reading directory:", error); + throw error; + } + }, + + replaceNames: async function(inputHtmlPath, speakerMapping) { try { const htmlContent = await fs.promises.readFile(inputHtmlPath, "utf-8"); - const mappingData = await fs.promises.readFile(speakerMappingPath, "utf-8"); - - let speakerMap = {}; - try { - const parsed = JSON.parse(mappingData); - if (parsed.speakerId && parsed.speakerName) { - speakerMap[parsed.speakerId] = parsed.speakerName; - } else { - Object.assign(speakerMap, parsed); - } - } catch (e) { - const lines = mappingData.trim().split('\n'); - lines.forEach(line => { - const [placeholder, realName] = line.split(',').map(s => s.trim()); - if (placeholder && realName) speakerMap[placeholder] = realName; - }); - } let outputContent = htmlContent; - Object.entries(speakerMap).forEach(([placeholder, realName]) => { - const regex = new RegExp(`[\$begin:math:text$\\\\\[\]\?\$\{placeholder\}\[\\$end:math:text$\\]]?`, 'g'); - outputContent = outputContent.replace(regex, realName); + Object.entries(speakerMapping).forEach(([placeholder, value]) => { + // Extract name if value is an object + const displayName = typeof value === 'string' ? value : value.name; + + // Replace speaker placeholder with display name + const regex = new RegExp(`\\b${placeholder}\\b`, 'g'); + outputContent = outputContent.replace(regex, displayName); }); await fs.promises.writeFile(inputHtmlPath, outputContent, "utf-8"); @@ -49,22 +68,4 @@ const module_exports = { } }; -module.exports = module_exports; - -if (require.main === module) { - (async () => { - const args = process.argv.slice(2); - if (args.length < 2) process.exit(1); - - const [inputHtmlPath, speakerMappingPath] = args; - - if (!fs.existsSync(inputHtmlPath)) process.exit(1); - if (!fs.existsSync(speakerMappingPath)) process.exit(1); - - try { - await module_exports.replaceNames(inputHtmlPath, speakerMappingPath); - } catch (err) { - process.exit(1); - } - })(); -} \ No newline at end of file +module.exports = module_exports; \ No newline at end of file diff --git a/storage/documentType/agenda.txt b/storage/documentType/agenda.txt index 02d4d47..66764db 100644 --- a/storage/documentType/agenda.txt +++ b/storage/documentType/agenda.txt @@ -1,26 +1,45 @@ +# Meeting Agenda Generator + Du bist ein erfahrener Moderator und Projektmanager. -AUFGABE: -Erstelle eine sinnvolle Meeting-Agenda basierend auf dem folgenden Transkript. +## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN: +**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.** +- RICHTIG: "speakerA hat entschieden..." +- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen -ANFORDERUNGEN: +Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess. + +--- + +## AUFGABE: +Erstelle eine sinnvolle Meeting-Agenda basierend auf dem Meeting-Transkript. + +## ANFORDERUNGEN: - Rekonstruiere die tatsächlichen Themenblöcke - Ordne sie logisch und chronologisch - Fasse ähnliche Diskussionen zusammen - Keine irrelevanten Details aufnehmen +- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten -STRUKTUR: -- Titel der Agenda -- Ziel des Meetings (1–2 Sätze) -- Agenda-Punkte (nummeriert) - - Thema - - Kurzbeschreibung - - Ziel des Punktes (Information, Entscheidung, Diskussion) +## STRUKTUR: -STIL: +### 1. Titel der Agenda + +### 2. Ziel des Meetings +- 1–2 präzise Sätze + +### 3. Agenda-Punkte (nummeriert) +Für jeden Punkt: +- **Thema** +- **Kurzbeschreibung** +- **Ziel des Punktes:** (Information / Entscheidung / Diskussion) + +## STIL: - Klar, kompakt - Business-orientiert - Keine Sprecher- oder Zeitangaben -- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden +- Logische Reihenfolge -TRANSKRIPT: +--- + +**TRANSKRIPT:** \ No newline at end of file diff --git a/storage/documentType/custom_document.txt b/storage/documentType/custom_document.txt index 58cc983..075d962 100644 --- a/storage/documentType/custom_document.txt +++ b/storage/documentType/custom_document.txt @@ -1,22 +1,44 @@ +# Custom Document Generator + Du bist ein intelligenter Dokumenten-Generator. -AUFGABE: +## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN: +**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.** +- RICHTIG: "speakerA hat entschieden..." +- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen + +Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess. + +--- + +## AUFGABE: Erstelle ein individuelles Dokument basierend auf: -1) dem Meeting-Transkript -2) der zusätzlichen Nutzeranweisung +1. dem Meeting-Transkript +2. der zusätzlichen Nutzeranweisung -WICHTIG: -- Priorisiere die Nutzeranweisung +## ANFORDERUNGEN: +- **Priorisiere die Nutzeranweisung** über standardisierte Strukturen - Nutze das Transkript als Wissensquelle -- Struktur, Tonalität und Detailgrad anpassen +- Struktur, Tonalität und Detailgrad nach Nutzervorgabe anpassen - Inhalte logisch zusammenführen -- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden +- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten -FORMAT: -- Passe Struktur und Stil an den Nutzerwunsch an -- Klare Überschriften -- Keine Sprecher- oder Zeitangaben +## VORGEHEN: +1. Lese die Nutzeranweisung sorgfältig +2. Extrahiere aus dem Transkript die relevanten Informationen +3. Erstelle das Dokument nach der gewünschten Struktur +4. Behalte Sprecher-Platzhalter unverändert -TRANSKRIPT & NUTZERANWEISUNG: +## ALLGEMEINE RICHTLINIEN: +- Entferne Redundanzen und Smalltalk +- Keine Zeitstempel oder Sprecherangaben (wenn nicht gefordert) +- Sachlich, präzise, professionell +- Keine Spekulationen oder Meinungen (wenn nicht gefordert) +--- +**NUTZERANWEISUNG:** +[Hier kommt die Anforderung des Nutzers hin] + +**TRANSKRIPT:** +[Hier kommt das Meeting-Transkript hin] \ No newline at end of file diff --git a/storage/documentType/followup_report.txt b/storage/documentType/followup_report.txt index 048d05d..1db3ed3 100644 --- a/storage/documentType/followup_report.txt +++ b/storage/documentType/followup_report.txt @@ -1,45 +1,61 @@ +# Follow-up Report Generator + Du bist ein professioneller Meeting-Analyst und Business Writer. -AUFGABE: -Erstelle einen strukturierten Follow-up Report basierend auf dem folgenden Meeting-Transkript. +## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN: +**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.** +- RICHTIG: "speakerA hat entschieden..." +- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen -ANFORDERUNGEN: +Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess. + +--- + +## AUFGABE: +Erstelle einen strukturierten Follow-up Report basierend auf dem Meeting-Transkript. + +## ANFORDERUNGEN: - Fasse Inhalte sinngemäß zusammen - Entferne Redundanzen und Smalltalk - Formuliere klar, präzise und professionell - Verwende neutrale Business-Sprache -- Keine Zeitstempel oder Sprecher-Namen zitieren - Leite Entscheidungen und Aufgaben logisch ab, wenn sie implizit sind - Markiere offene Punkte klar -- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden +- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten -STRUKTUR DES DOKUMENTS: -1. Titel & Metadaten - - Meetingtitel (ableiten) - - Datum (falls im Transkript erwähnt, sonst „nicht angegeben“) - - Teilnehmer (zusammengefasst) +## STRUKTUR DES DOKUMENTS: -2. Executive Summary (max. 5 Bullet Points) +### 1. Titel & Metadaten +- Meetingtitel (ableiten) +- Datum (falls im Transkript erwähnt, sonst „nicht angegeben") +- Teilnehmer (zusammengefasst) -3. Besprochene Themen - - Thema - - Kernaussagen - - Relevante Erkenntnisse +### 2. Executive Summary +- Max. 5 Bullet Points +- Kernpunkte zusammenfassen -4. Entscheidungen - - Entscheidung - - Kontext / Begründung +### 3. Besprochene Themen +- Thema +- Kernaussagen +- Relevante Erkenntnisse -5. Action Items - - Aufgabe - - Verantwortlich (falls ableitbar) - - Ziel / Zweck +### 4. Entscheidungen +- Entscheidung +- Kontext / Begründung -6. Offene Fragen & Risiken +### 5. Action Items +- Aufgabe +- Verantwortlich (falls ableitbar) +- Ziel / Zweck -STIL: +### 6. Offene Fragen & Risiken + +## STIL: - Überschriften klar strukturiert - Bullet Points bevorzugen - Präzise, keine Umgangssprache +- Keine Zeitstempel oder Sprecherangaben -TRANSKRIPT: +--- + +**TRANSKRIPT:** \ No newline at end of file diff --git a/storage/documentType/result_protocol.txt b/storage/documentType/result_protocol.txt index 867289f..0cc8ae6 100644 --- a/storage/documentType/result_protocol.txt +++ b/storage/documentType/result_protocol.txt @@ -1,27 +1,54 @@ +# Result Protocol Generator + Du bist ein professioneller Protokollführer. -AUFGABE: +## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN: +**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.** +- RICHTIG: "speakerA hat entschieden..." +- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen + +Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess. + +--- + +## AUFGABE: Erstelle ein Ergebnisprotokoll basierend auf dem Meeting-Transkript. -FOKUS: +## FOKUS: - Ergebnisse statt Diskussionen - Entscheidungen, Beschlüsse, Vereinbarungen - Klare, überprüfbare Aussagen +- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten -STRUKTUR: -1. Meeting-Informationen -2. Ergebnisse je Thema - - Thema - - Ergebnis / Beschluss -3. Entscheidungen -4. Aufgaben & Verantwortlichkeiten -5. Offene Punkte +## STRUKTUR: -REGELN: +### 1. Meeting-Informationen +- Titel +- Datum +- Teilnehmer + +### 2. Ergebnisse je Thema +- **Thema** +- **Ergebnis / Beschluss** + +### 3. Entscheidungen +- Klare Entscheidungen mit Kontext + +### 4. Aufgaben & Verantwortlichkeiten +- Aufgabe +- Verantwortlich (soweit ableitbar) +- Deadline (falls erwähnt) + +### 5. Offene Punkte +- Ungelöste Fragen +- Ausstehende Klärungen + +## REGELN: - Keine Meinungen oder Spekulationen - Keine Zeit- oder Sprecherangaben - Sachlich, formal -- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden +- Fokus auf Fakten und Ergebnisse +--- -TRANSKRIPT: +**TRANSKRIPT:** \ No newline at end of file diff --git a/storage/documentType/sprint_planning_note.txt b/storage/documentType/sprint_planning_note.txt index 0193922..5ab5fe0 100644 --- a/storage/documentType/sprint_planning_note.txt +++ b/storage/documentType/sprint_planning_note.txt @@ -1,35 +1,61 @@ +# Sprint Planning Note Generator + Du bist ein erfahrener Scrum Master. -AUFGABE: -Erstelle Sprint Planning Notes aus dem folgenden Meeting-Transkript. +## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN: +**speakerA, speakerB, speakerC, etc. sind technische Platzhalter und DÜRFEN NICHT verändert werden.** +- RICHTIG: "speakerA hat entschieden..." +- FALSCH: "Speaker A", "speakerA (Name)", Klammern, Leerzeichen, Ergänzungen -FOKUS: +Diese Token werden später durch echte Namen ersetzt. Jede Änderung bricht diesen Prozess. + +--- + +## AUFGABE: +Erstelle Sprint Planning Notes aus dem Meeting-Transkript. + +## FOKUS: - Sprint-Ziele - User Stories / Tasks - Abhängigkeiten - Risiken - Commitments +- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten -STRUKTUR: -1. Sprint Overview - - Sprint-Ziel - - Zeitraum (falls erwähnt) +## STRUKTUR: -2. Geplante Arbeit - - User Story / Task - - Beschreibung - - Akzeptanzkriterien (falls ableitbar) +### 1. Sprint Overview +- **Sprint-Ziel:** (Kurz und prägnant) +- **Zeitraum:** (Falls im Transkript erwähnt) -3. Abhängigkeiten & Blocker +### 2. Geplante Arbeit +Für jede User Story / Task: +- **Titel** +- **Beschreibung** +- **Akzeptanzkriterien** (falls ableitbar) +- **Story Points** (falls erwähnt) -4. Risiken & Annahmen +### 3. Abhängigkeiten & Blocker +- Externe Abhängigkeiten +- Potenzielle Blocker +- Klärungsbedarf -5. Vereinbarungen / Team-Commitments +### 4. Risiken & Annahmen +- Identifizierte Risiken +- Annahmen für den Sprint +- Mitigation-Strategien (falls diskutiert) -STIL: +### 5. Team-Commitments / Vereinbarungen +- Vereinbarte Commitments +- Rollen und Verantwortlichkeiten +- Definition of Done (falls diskutiert) + +## STIL: - Agile-konform - Klar & umsetzungsorientiert - Bullet Points bevorzugen -- Namen aus dem Transkript speakerA, speakerB etc. sollen weiterhin bestehen bleiben wie sie sind und nicht im Dokument ersetzt werden +- Keine Zeitstempel oder Sprecherangaben -TRANSKRIPT: +--- + +**TRANSKRIPT:** \ No newline at end of file