Remade replace Speaker module which now takes the premade speaker mapping json and directly replaces speakers in the document. Also refined the Standard documents so consistency is improved

This commit is contained in:
MikeHughes-BIN
2026-01-15 10:38:28 +01:00
parent 11f7db1b1c
commit 1f96d90a2d
8 changed files with 483 additions and 322 deletions
Vendored
BIN
View File
Binary file not shown.
+174 -124
View File
@@ -1,19 +1,19 @@
// Loading required packages // Loading required packages
require("./requires.js") require("./requires.js");
console.log(start); console.log(start);
// Initialising map to be used to store the functionality later on for reloadability // Initialising map to be used to store the functionality later on for reloadability
mapFunctions = new Map() mapFunctions = new Map();
// Loading the Function Map // Loading the Function Map
var path = `${mainDir}/services/modules` var path = `${mainDir}/services/modules`;
var folders = fs.readdirSync(path).filter(function (file) { var folders = fs.readdirSync(path).filter(function (file) {
return fs.statSync(path+'/'+file).isDirectory(); return fs.statSync(path + "/" + file).isDirectory();
}); });
folders.forEach(element => { folders.forEach((element) => {
var commandFiles = fs.readdirSync(`${path}/${element}`).filter(file => file.endsWith('.js') && !file.startsWith("index")); var commandFiles = fs
.readdirSync(`${path}/${element}`)
.filter((file) => file.endsWith(".js") && !file.startsWith("index"));
for (const file of commandFiles) { for (const file of commandFiles) {
delete require.cache[require.resolve(`${path}/${element}/${file}`)]; delete require.cache[require.resolve(`${path}/${element}/${file}`)];
const command = require(`${path}/${element}/${file}`); const command = require(`${path}/${element}/${file}`);
@@ -21,39 +21,31 @@ folders.forEach(element => {
} }
}); });
// The startup information for the project, here you can add stuff that might be nice to see when the app starts // 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() mapFunctions.get("Startup_function").function();
console.log("------------------------------------ Status ------------------------------------"); console.log(
"------------------------------------ Status ------------------------------------"
);
console.log(__dirname); console.log(__dirname);
console.log(platform); 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(`${mapFunctions.size} Function modules loaded`);
console.log("--------------------------------------------------------------------------------"); console.log(
"--------------------------------------------------------------------------------"
);
// --------------------------------------------------------- CLI COMMANDS --------------------------------------------------------- // // --------------------------------------------------------- CLI COMMANDS --------------------------------------------------------- //
const rl = readline.createInterface({ const rl = readline.createInterface({
input: process.stdin, input: process.stdin,
output: process.stdout output: process.stdout,
}); });
rl.on("line", (data) => {
rl.on("line", data =>{
const args = data.trim().split(" "); const args = data.trim().split(" ");
const command = args.shift().toLowerCase(); const command = args.shift().toLowerCase();
mapFunctions.get("cliCommands").function(command, args) mapFunctions.get("cliCommands").function(command, args);
}) });
// ----------------------------------------------------------- ELECTRON ----------------------------------------------------------- // // ----------------------------------------------------------- ELECTRON ----------------------------------------------------------- //
@@ -66,16 +58,15 @@ function createWindow() {
webPreferences: { webPreferences: {
nodeIntegration: false, nodeIntegration: false,
contextIsolation: true, contextIsolation: true,
preload: `${mainDir}/electron/main/preload.js` preload: `${mainDir}/electron/main/preload.js`,
} },
}); });
mainWindow.loadFile('./electron/main/index.html'); mainWindow.loadFile("./electron/main/index.html");
} }
electron.app.whenReady().then(createWindow); electron.app.whenReady().then(createWindow);
// electron.ipcMain.on("extract", (event, args) => { // electron.ipcMain.on("extract", (event, args) => {
// mapFunctions.get("extraction-video-to-audio").function(args) // mapFunctions.get("extraction-video-to-audio").function(args)
// }) // })
@@ -84,25 +75,30 @@ electron.app.whenReady().then(createWindow);
// mainWindow.webContents.send("fuck", "worked uwu") // mainWindow.webContents.send("fuck", "worked uwu")
// }, 5000); // }, 5000);
electron.ipcMain.handle('get-module-names', async () => { electron.ipcMain.handle("get-module-names", async () => {
let module_array = { let module_array = {
"ai_modules":[], ai_modules: [],
"transcription_modules":[] transcription_modules: [],
} };
mapFunctions.forEach(e => { mapFunctions.forEach((e) => {
switch (e.type) { switch (e.type) {
case "llm": case "llm":
module_array.ai_modules.push({"name": e.name, "displayname": e.displayname}) module_array.ai_modules.push({
name: e.name,
displayname: e.displayname,
});
break; break;
case "transcription": case "transcription":
module_array.transcription_modules.push({"name": e.name, "displayname": e.displayname}) module_array.transcription_modules.push({
name: e.name,
displayname: e.displayname,
});
break; break;
} }
})
// console.log(module_array);
return module_array
}); });
// console.log(module_array);
return module_array;
});
// electron.ipcMain.on("get_modules", async (event, args) => { // electron.ipcMain.on("get_modules", async (event, args) => {
// let module_array = { // let module_array = {
@@ -124,21 +120,21 @@ electron.ipcMain.handle('get-module-names', async () => {
// mainWindow.webContents.send("modules", module_array) // mainWindow.webContents.send("modules", module_array)
// }) // })
var globalArgs = {} var globalArgs = {};
var globalFinalHtmlPath = "" var globalFinalHtmlPath = "";
electron.ipcMain.on("file_submit", async (event, args) => { electron.ipcMain.on("file_submit", async (event, args) => {
try { try {
globalArgs = args globalArgs = args;
let curstep = 0 let curstep = 0;
let totalsteps = 4 let totalsteps = 4;
const TEMPLATE_MAP = { const TEMPLATE_MAP = {
"followup-report": "followup_report.txt", "followup-report": "followup_report.txt",
"agenda": "agenda.txt", agenda: "agenda.txt",
"result-protocol": "result_protocol.txt", "result-protocol": "result_protocol.txt",
"sprint-planning": "sprint_planning_note.txt", "sprint-planning": "sprint_planning_note.txt",
"custom": "custom_document.txt" custom: "custom_document.txt",
}; };
const templateFile = TEMPLATE_MAP[args.document.type]; const templateFile = TEMPLATE_MAP[args.document.type];
@@ -148,141 +144,195 @@ electron.ipcMain.on("file_submit", async (event, args) => {
} }
console.log(args); console.log(args);
let audiopath = "" let audiopath = "";
let transcriptpath = "" let transcriptpath = "";
console.log("\n\n Running the Video to Audio Extractor"); console.log("\n\n Running the Video to Audio Extractor");
// This code handles the Video to Audio extraction module call // 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 => { await mapFunctions
console.log(resp); .get("module-handler")
audiopath = resp .function(args.video.module, {
curstep++ inputVideoPath: args.video.inputVideoPath,
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) outputType: mapFunctions.get(args.transcription.module).audioformat,
}).catch(err => {
mainWindow.webContents.send("error", err)
console.log(err);
return
}) })
.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"); console.log("\n\n Running the Audio to Transcription module");
// TODO implement transcription module // TODO implement transcription module
// This code handles the Audio to Text transcription module call // This code handles the Audio to Text transcription module call
await mapFunctions.get("module-handler").function(args.transcription.module, audiopath).then(resp => { await mapFunctions
.get("module-handler")
.function(args.transcription.module, audiopath)
.then((resp) => {
console.log(resp); console.log(resp);
transcriptpath = resp transcriptpath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
console.log("\n\n Running the Transcription Summarizer module"); console.log("\n\n Running the Transcription Summarizer module");
// This code summarises the transcript, so that it can be used by an llm // 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-transcription").function('A:\\programing\\@projects\\video2document\\storage\\transcripts\\IMG_2978.json').then(resp => {
await mapFunctions.get("summarize-transcription2").function(transcriptpath).then(resp => { await mapFunctions
.get("summarize-transcription2")
.function(transcriptpath)
.then((resp) => {
console.log(resp); console.log(resp);
transcriptpath = resp transcriptpath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
console.log(err);
return;
});
console.log("\n\n Running the LLM module"); console.log("\n\n Running the LLM module");
// TODO implement documentation module // TODO implement documentation module
// This code handles the Text to Document processing module call // This code handles the Text to Document processing module call
console.log(`\n\n Running the LLM for Document Style ${args.document.type}`); 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 => { await mapFunctions
.get("module-handler")
.function(args.document.module, {
inputTranscriptPath: transcriptpath,
documentTypePath: "./storage/documentType/" + templateFile,
language: "en",
})
.then((resp) => {
console.log(resp); console.log(resp);
globalFinalHtmlPath = resp globalFinalHtmlPath = resp;
curstep++ curstep++;
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {
}).catch(err => { curstep: curstep,
mainWindow.webContents.send("error", err) totalsteps: totalsteps,
console.log(err); });
return
}) })
.catch((err) => {
mainWindow.webContents.send("error", err);
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); console.log(err);
return 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) { } catch (error) {
console.log(error); console.log(error);
} }
}) });
electron.ipcMain.on("file_download", async () => { electron.ipcMain.on("file_download", async () => {
await mapFunctions.get("htmlDocumentConverter").convert({inputPath:globalFinalHtmlPath, format: globalArgs.document.outputType, showDialog: true}); await mapFunctions
}) .get("htmlDocumentConverter")
.convert({
inputPath: globalFinalHtmlPath,
format: globalArgs.document.outputType,
showDialog: true,
});
});
electron.ipcMain.on("speaker_submit", async() => { electron.ipcMain.on("speaker_submit", async (event, args) => {
console.log("\n\n\nJa also hier kam was an \n\n\n"); console.log("\n\n\nJa also hier kam was an \n\n\n");
}) console.log(args);
let q = 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: { video: {
module: "String", // The name of the module, idk if we ever implement other extraction modules, the default one is extraction-video-to-audio 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 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 outputType: "String", // The file format to be used for the audio output file, such as wav, mp3, flac and so on
}, },
transcription: { transcription: {
module: "String" // The module name of the transcription model you want to use module: "String", // The module name of the transcription model you want to use
}, },
document: { document: {
module: "String", // The module name of the AI model you want to use to create the 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 styles: [
// An array of all the document styles/prompts you want to have the document be processed with
{ {
prompt: "String", prompt: "String",
} },
] ],
} },
} };
let q1 = { let q1 = {
"ai_modules": [ ai_modules: [
{ name: "abc", displayname: "ABC" }, { name: "abc", displayname: "ABC" },
{name:"qeg", displayname:"aqghegahu"} { name: "qeg", displayname: "aqghegahu" },
], ],
"transcription_modules": [ transcription_modules: [
{ name: "abc", displayname: "ABC" }, { name: "abc", displayname: "ABC" },
{name:"qeg", displayname:"aqghegahu"} { name: "qeg", displayname: "aqghegahu" },
] ],
} };
//gibt Documentfiles an preload zurück //gibt Documentfiles an preload zurück
electron.ipcMain.handle('get-txt-files', () => { electron.ipcMain.handle("get-txt-files", () => {
const storagePath = `${mainDir}/storage/documentType` const storagePath = `${mainDir}/storage/documentType`;
return fs.readdirSync(storagePath) return fs.readdirSync(storagePath).filter((f) => f.endsWith(".txt"));
.filter(f => f.endsWith('.txt'))
}); });
//speichern neuer document types //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`; const filePath = `${mainDir}/storage/documentType/${fileName}.txt`;
fs.writeFileSync(filePath, content, 'utf8'); fs.writeFileSync(filePath, content, "utf8");
return true; return true;
}); });
// //
electron.ipcMain.handle('read-txt-file', (event, fileName) => { electron.ipcMain.handle("read-txt-file", (event, fileName) => {
const filePath = `${mainDir}/storage/documentType/${fileName}`; const filePath = `${mainDir}/storage/documentType/${fileName}`;
return fs.readFileSync(filePath, 'utf8'); return fs.readFileSync(filePath, "utf8");
}); });
@@ -7,35 +7,54 @@ const module_exports = {
displayname: "Speaker Name Replacer", displayname: "Speaker Name Replacer",
description: "Replaces speaker placeholder names with actual names based on a mapping in HTML files", description: "Replaces speaker placeholder names with actual names based on a mapping in HTML files",
async function({ inputHtmlPath, speakerMappingPath }) { async function(speakerMapping) {
return await this.replaceNames(inputHtmlPath, speakerMappingPath); // 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 { try {
const htmlContent = await fs.promises.readFile(inputHtmlPath, "utf-8"); 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; let outputContent = htmlContent;
Object.entries(speakerMap).forEach(([placeholder, realName]) => { Object.entries(speakerMapping).forEach(([placeholder, value]) => {
const regex = new RegExp(`[\$begin:math:text$\\\\\[\]\?\$\{placeholder\}\[\\$end:math:text$\\]]?`, 'g'); // Extract name if value is an object
outputContent = outputContent.replace(regex, realName); 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"); await fs.promises.writeFile(inputHtmlPath, outputContent, "utf-8");
@@ -50,21 +69,3 @@ const module_exports = {
}; };
module.exports = 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);
}
})();
}
+32 -13
View File
@@ -1,26 +1,45 @@
# Meeting Agenda Generator
Du bist ein erfahrener Moderator und Projektmanager. Du bist ein erfahrener Moderator und Projektmanager.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle eine sinnvolle Meeting-Agenda basierend auf dem folgenden Transkript. **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 - Rekonstruiere die tatsächlichen Themenblöcke
- Ordne sie logisch und chronologisch - Ordne sie logisch und chronologisch
- Fasse ähnliche Diskussionen zusammen - Fasse ähnliche Diskussionen zusammen
- Keine irrelevanten Details aufnehmen - Keine irrelevanten Details aufnehmen
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
- Titel der Agenda
- Ziel des Meetings (12 Sätze)
- Agenda-Punkte (nummeriert)
- Thema
- Kurzbeschreibung
- Ziel des Punktes (Information, Entscheidung, Diskussion)
STIL: ### 1. Titel der Agenda
### 2. Ziel des Meetings
- 12 präzise Sätze
### 3. Agenda-Punkte (nummeriert)
Für jeden Punkt:
- **Thema**
- **Kurzbeschreibung**
- **Ziel des Punktes:** (Information / Entscheidung / Diskussion)
## STIL:
- Klar, kompakt - Klar, kompakt
- Business-orientiert - Business-orientiert
- Keine Sprecher- oder Zeitangaben - 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:**
+34 -12
View File
@@ -1,22 +1,44 @@
# Custom Document Generator
Du bist ein intelligenter Dokumenten-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: Erstelle ein individuelles Dokument basierend auf:
1) dem Meeting-Transkript 1. dem Meeting-Transkript
2) der zusätzlichen Nutzeranweisung 2. der zusätzlichen Nutzeranweisung
WICHTIG: ## ANFORDERUNGEN:
- Priorisiere die Nutzeranweisung - **Priorisiere die Nutzeranweisung** über standardisierte Strukturen
- Nutze das Transkript als Wissensquelle - Nutze das Transkript als Wissensquelle
- Struktur, Tonalität und Detailgrad anpassen - Struktur, Tonalität und Detailgrad nach Nutzervorgabe anpassen
- Inhalte logisch zusammenführen - 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: ## VORGEHEN:
- Passe Struktur und Stil an den Nutzerwunsch an 1. Lese die Nutzeranweisung sorgfältig
- Klare Überschriften 2. Extrahiere aus dem Transkript die relevanten Informationen
- Keine Sprecher- oder Zeitangaben 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]
+31 -15
View File
@@ -1,45 +1,61 @@
# Follow-up Report Generator
Du bist ein professioneller Meeting-Analyst und Business Writer. Du bist ein professioneller Meeting-Analyst und Business Writer.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle einen strukturierten Follow-up Report basierend auf dem folgenden Meeting-Transkript. **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 - Fasse Inhalte sinngemäß zusammen
- Entferne Redundanzen und Smalltalk - Entferne Redundanzen und Smalltalk
- Formuliere klar, präzise und professionell - Formuliere klar, präzise und professionell
- Verwende neutrale Business-Sprache - Verwende neutrale Business-Sprache
- Keine Zeitstempel oder Sprecher-Namen zitieren
- Leite Entscheidungen und Aufgaben logisch ab, wenn sie implizit sind - Leite Entscheidungen und Aufgaben logisch ab, wenn sie implizit sind
- Markiere offene Punkte klar - 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: ## STRUKTUR DES DOKUMENTS:
1. Titel & Metadaten
### 1. Titel & Metadaten
- Meetingtitel (ableiten) - Meetingtitel (ableiten)
- Datum (falls im Transkript erwähnt, sonst „nicht angegeben) - Datum (falls im Transkript erwähnt, sonst „nicht angegeben")
- Teilnehmer (zusammengefasst) - Teilnehmer (zusammengefasst)
2. Executive Summary (max. 5 Bullet Points) ### 2. Executive Summary
- Max. 5 Bullet Points
- Kernpunkte zusammenfassen
3. Besprochene Themen ### 3. Besprochene Themen
- Thema - Thema
- Kernaussagen - Kernaussagen
- Relevante Erkenntnisse - Relevante Erkenntnisse
4. Entscheidungen ### 4. Entscheidungen
- Entscheidung - Entscheidung
- Kontext / Begründung - Kontext / Begründung
5. Action Items ### 5. Action Items
- Aufgabe - Aufgabe
- Verantwortlich (falls ableitbar) - Verantwortlich (falls ableitbar)
- Ziel / Zweck - Ziel / Zweck
6. Offene Fragen & Risiken ### 6. Offene Fragen & Risiken
STIL: ## STIL:
- Überschriften klar strukturiert - Überschriften klar strukturiert
- Bullet Points bevorzugen - Bullet Points bevorzugen
- Präzise, keine Umgangssprache - Präzise, keine Umgangssprache
- Keine Zeitstempel oder Sprecherangaben
TRANSKRIPT: ---
**TRANSKRIPT:**
+40 -13
View File
@@ -1,27 +1,54 @@
# Result Protocol Generator
Du bist ein professioneller Protokollführer. 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. Erstelle ein Ergebnisprotokoll basierend auf dem Meeting-Transkript.
FOKUS: ## FOKUS:
- Ergebnisse statt Diskussionen - Ergebnisse statt Diskussionen
- Entscheidungen, Beschlüsse, Vereinbarungen - Entscheidungen, Beschlüsse, Vereinbarungen
- Klare, überprüfbare Aussagen - Klare, überprüfbare Aussagen
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
1. Meeting-Informationen
2. Ergebnisse je Thema
- Thema
- Ergebnis / Beschluss
3. Entscheidungen
4. Aufgaben & Verantwortlichkeiten
5. Offene Punkte
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 Meinungen oder Spekulationen
- Keine Zeit- oder Sprecherangaben - Keine Zeit- oder Sprecherangaben
- Sachlich, formal - 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:**
+43 -17
View File
@@ -1,35 +1,61 @@
# Sprint Planning Note Generator
Du bist ein erfahrener Scrum Master. Du bist ein erfahrener Scrum Master.
AUFGABE: ## KRITISCH - SPRECHER-PLATZHALTER BEWAHREN:
Erstelle Sprint Planning Notes aus dem folgenden Meeting-Transkript. **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 - Sprint-Ziele
- User Stories / Tasks - User Stories / Tasks
- Abhängigkeiten - Abhängigkeiten
- Risiken - Risiken
- Commitments - Commitments
- Speicher-Platzhalter (speakerA, speakerB, etc.) exakt beibehalten
STRUKTUR: ## STRUKTUR:
1. Sprint Overview
- Sprint-Ziel
- Zeitraum (falls erwähnt)
2. Geplante Arbeit ### 1. Sprint Overview
- User Story / Task - **Sprint-Ziel:** (Kurz und prägnant)
- Beschreibung - **Zeitraum:** (Falls im Transkript erwähnt)
- Akzeptanzkriterien (falls ableitbar)
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 - Agile-konform
- Klar & umsetzungsorientiert - Klar & umsetzungsorientiert
- Bullet Points bevorzugen - 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:**