Make protocol language follow meeting language
This commit is contained in:
@@ -108,7 +108,9 @@ def validate_meeting_context(data: dict[str, Any]) -> None:
|
||||
meeting = _require_mapping(data, "meeting")
|
||||
_require_non_empty_string(meeting, "meeting.meeting_id")
|
||||
_require_non_empty_string(meeting, "meeting.title")
|
||||
_require_non_empty_string(meeting, "meeting.language")
|
||||
# Legacy contexts may omit language; protocol generation defaults to German.
|
||||
if "language" in meeting:
|
||||
_require_non_empty_string(meeting, "meeting.language")
|
||||
|
||||
organization = _optional_mapping(data.get("organization"), "organization")
|
||||
departments = _optional_list(organization.get("departments"), "organization.departments")
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DIRECT_PROTOCOL_INSTRUCTION = """Erstelle aus dem vollständigen Transkript und dem Meeting-Kontext ein vollständiges, strukturiertes und professionelles internes Besprechungsprotokoll in deutscher Sprache.
|
||||
DIRECT_PROTOCOL_INSTRUCTION = """Erstelle aus dem vollständigen Transkript und dem Meeting-Kontext ein vollständiges, strukturiertes und professionelles internes Besprechungsprotokoll.
|
||||
|
||||
Das Protokoll muss themenorientiert sein, nicht chronologisch und nicht nach technischen Kategorien gegliedert. Beginne mit # Meeting Protocol. Verwende für jedes kohärente Thema eine Überschrift ## <Thema> und darunter eine strukturierte Synthese der Diskussion. Bewahre relevante Diskussionsverläufe, unterschiedliche Positionen, offene Punkte und Entscheidungsgrundlagen. Dokumentiere die wesentlichen Inhalte nachvollziehbar und fasse Themenblöcke so zusammen, dass auch Personen, die nicht am Meeting teilgenommen haben, den Kontext und die Entwicklung der Diskussion verstehen können. Nenne Entscheidungen oder abgestimmte Positionen nur, wenn sie tatsächlich belegt sind. Führe Maßnahmen nur auf, wenn eine konkrete zukünftige Handlung gestützt ist; nenne verantwortliche Personen und Fristen ausschließlich bei expliziter Zuweisung, Annahme oder Bestätigung im Transkript. Vorschläge, Einwände, Möglichkeiten und vorläufige Ideen sind keine Entscheidungen oder Verpflichtungen. Bewahre relevante Einschränkungen und ungelöste Meinungsverschiedenheiten. Nenne offene Punkte nur, wenn sie wirklich offen bleiben. Nicht jedes Thema benötigt Entscheidungen, Maßnahmen oder offene Punkte.
|
||||
|
||||
Erzeuge keine reine Wiedergabe des Transkripts und verlängere das Protokoll nicht unnötig durch Wiederholungen. Synthetisiere zusammengehörige Aussagen, entferne Füllwörter und Gesprächsrauschen und erfinde keine Fakten, Entscheidungen, Zustimmungen, Verantwortlichen oder Fristen. Gib kein JSON, keine internen Labels und keine Analyse oder Denkprotokolle aus. Das Ergebnis soll als Markdown-Protokoll nach geringfügiger menschlicher Redaktion intern versendbar sein. Eine kompakte themenübergreifende Maßnahmenliste am Ende ist optional, wenn sie nützlich und vollständig belegt ist."""
|
||||
|
||||
COMPACT_DIARIZED_PROTOCOL_INSTRUCTION = """Erstelle aus dem vollständigen Transkript und Meeting-Kontext ein vollständiges, professionelles internes Besprechungsprotokoll auf Deutsch. Das Transkript ist in aufeinanderfolgende anonyme Sprecherblöcke gegliedert.
|
||||
COMPACT_DIARIZED_PROTOCOL_INSTRUCTION = """Erstelle aus dem vollständigen Transkript und Meeting-Kontext ein vollständiges, professionelles internes Besprechungsprotokoll. Das Transkript ist in aufeinanderfolgende anonyme Sprecherblöcke gegliedert.
|
||||
|
||||
Beginne mit # Meeting Protocol. Gliedere themenorientiert mit ## <Thema> und synthetisiere je Thema den relevanten Diskussionsverlauf, Kontext, unterschiedliche Positionen, Entscheidungsgrundlagen, Einschränkungen und ungelöste Meinungsverschiedenheiten so, dass Dritte ihn nachvollziehen können. Nenne Entscheidungen nur bei Beleg. Nenne Maßnahmen, Verantwortliche und Fristen nur bei expliziter Zuweisung, Annahme oder Bestätigung; Vorschläge sind keine Verpflichtungen.
|
||||
|
||||
@@ -23,10 +23,14 @@ def build_direct_protocol_prompt(
|
||||
meeting_context: str | None = None,
|
||||
*,
|
||||
instruction: str = DIRECT_PROTOCOL_INSTRUCTION,
|
||||
meeting_language: str = "de",
|
||||
) -> str:
|
||||
context = meeting_context.strip() if meeting_context else "Kein Meeting-Kontext bereitgestellt."
|
||||
language = {"de": "German", "en": "English"}.get(meeting_language, meeting_language)
|
||||
return (
|
||||
f"{instruction}\n\n"
|
||||
f"Write the meeting protocol in {language}. "
|
||||
"Preserve speaker and person names exactly as supplied.\n\n"
|
||||
f"MEETING-KONTEXT:\n{context}\n\n"
|
||||
f"VOLLSTAENDIGES TRANSKRIPT:\n{transcript.strip()}\n"
|
||||
)
|
||||
|
||||
@@ -96,6 +96,7 @@ def select_transcript_input(
|
||||
rendered_context: str | None,
|
||||
*,
|
||||
safe_input_token_budget: int = DEFAULT_SAFE_INPUT_TOKEN_BUDGET,
|
||||
meeting_language: str = "de",
|
||||
) -> SelectedTranscriptInput:
|
||||
"""Select complete prompt input without allowing silent tail truncation."""
|
||||
if safe_input_token_budget <= 0:
|
||||
@@ -117,6 +118,7 @@ def select_transcript_input(
|
||||
compact.text,
|
||||
rendered_context,
|
||||
instruction=instruction,
|
||||
meeting_language=meeting_language,
|
||||
)
|
||||
compact_estimate = estimate_input_tokens(compact_prompt)
|
||||
if compact_estimate <= safe_input_token_budget:
|
||||
@@ -138,7 +140,9 @@ def select_transcript_input(
|
||||
representation = "plain_transcript"
|
||||
fallback_used = False
|
||||
|
||||
plain_prompt = build_direct_protocol_prompt(plain_text, rendered_context)
|
||||
plain_prompt = build_direct_protocol_prompt(
|
||||
plain_text, rendered_context, meeting_language=meeting_language
|
||||
)
|
||||
plain_estimate = estimate_input_tokens(plain_prompt)
|
||||
if plain_estimate > safe_input_token_budget:
|
||||
raise DirectProtocolError(
|
||||
@@ -175,10 +179,15 @@ def generate_direct_protocol(
|
||||
load_meeting_context(context_path) if context_path is not None else None
|
||||
)
|
||||
rendered_context = render_meeting_context_for_prompt(context) if context else None
|
||||
# Older runs without a meeting language retain the historical German output.
|
||||
meeting_language = (
|
||||
str(context.data["meeting"].get("language") or "de") if context else "de"
|
||||
)
|
||||
selected = select_transcript_input(
|
||||
transcript,
|
||||
rendered_context,
|
||||
safe_input_token_budget=safe_input_token_budget,
|
||||
meeting_language=meeting_language,
|
||||
)
|
||||
|
||||
model_metadata = model_check(endpoint, model, 10)
|
||||
@@ -192,6 +201,7 @@ def generate_direct_protocol(
|
||||
)
|
||||
data = generation.raw_response
|
||||
runtime_metadata = {
|
||||
"output_language": meeting_language,
|
||||
"model": model,
|
||||
"prompt_token_count": data.get("prompt_eval_count"),
|
||||
"output_token_count": data.get("eval_count"),
|
||||
|
||||
Reference in New Issue
Block a user