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.
+179 -129
View File
@@ -1,19 +1,19 @@
// 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"));
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}`);
@@ -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
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
output: process.stdout,
});
rl.on("line", data =>{
rl.on("line", (data) => {
const args = data.trim().split(" ");
const command = args.shift().toLowerCase();
mapFunctions.get("cliCommands").function(command, args)
})
mapFunctions.get("cliCommands").function(command, args);
});
// ----------------------------------------------------------- ELECTRON ----------------------------------------------------------- //
@@ -66,16 +58,15 @@ function createWindow() {
webPreferences: {
nodeIntegration: false,
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.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 () => {
electron.ipcMain.handle("get-module-names", async () => {
let module_array = {
"ai_modules":[],
"transcription_modules":[]
}
mapFunctions.forEach(e => {
switch(e.type){
ai_modules: [],
transcription_modules: [],
};
mapFunctions.forEach((e) => {
switch (e.type) {
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;
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;
}
})
});
// console.log(module_array);
return module_array
return module_array;
});
// electron.ipcMain.on("get_modules", async (event, args) => {
// let module_array = {
// "ai_modules":[],
@@ -124,21 +120,21 @@ 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
globalArgs = args;
let curstep = 0;
let totalsteps = 4;
const TEMPLATE_MAP = {
"followup-report": "followup_report.txt",
"agenda": "agenda.txt",
agenda: "agenda.txt",
"result-protocol": "result_protocol.txt",
"sprint-planning": "sprint_planning_note.txt",
"custom": "custom_document.txt"
custom: "custom_document.txt",
};
const templateFile = TEMPLATE_MAP[args.document.type];
@@ -148,141 +144,195 @@ electron.ipcMain.on("file_submit", async (event, args) => {
}
console.log(args);
let audiopath = ""
let transcriptpath = ""
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
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 => {
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
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 => {
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
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}`);
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);
globalFinalHtmlPath = resp
curstep++
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
}).catch(err => {
mainWindow.webContents.send("error", err)
console.log(err);
return
globalFinalHtmlPath = resp;
curstep++;
mainWindow.webContents.send("progress", {
curstep: curstep,
totalsteps: totalsteps,
});
})
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)
.catch((err) => {
mainWindow.webContents.send("error", 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) {
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("file_download", async () => {
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(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: {
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
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
transcription: {
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
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",
}
]
}
}
},
],
},
};
let q1 = {
"ai_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"}
]
}
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');
return fs.readFileSync(filePath, "utf8");
});
@@ -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");
@@ -50,21 +69,3 @@ 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);
}
})();
}
+32 -13
View File
@@ -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 (12 Sätze)
- Agenda-Punkte (nummeriert)
- Thema
- Kurzbeschreibung
- Ziel des Punktes (Information, Entscheidung, Diskussion)
## STRUKTUR:
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
- 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:**
+34 -12
View File
@@ -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]
+41 -25
View File
@@ -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:**
+40 -13
View File
@@ -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:**
+43 -17
View File
@@ -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:**