"""Storyline generation across all configured providers and author selection.""" from rich.console import Console from rich.panel import Panel from rich.prompt import IntPrompt, Prompt console = Console() _SYSTEM = """Du bist ein erfahrener Redaktionsassistent für die LinkedIn-Kolumne KNIEPUNKT von Dr. André Knie. KNIEPUNKT ist kolumnenhaft, glossenhaft, amüsant, kulturell gebildet und meinungsstark. Erlaubt: griechische/römische Mythologie, Kanonliteratur, klassische deutsche Literatur. Zielgruppe: hochgebildete Entscheider aus Mittelstand, Konzernen und öffentlicher Verwaltung mit Interesse an moralischer KI. Eine Storyline verbindet ausgewählte Nachrichten zu einem kohärenten redaktionellen Blickwinkel – kein neutrales Nachrichtenreferat.""" def _build_prompt(news_digest: str, source_assessment: str, author_input: dict, episodes_context: str) -> str: initial = ( f"\nVorläufige Autorenstoryline: {author_input['initial_storyline']}" if author_input.get("initial_storyline") else "" ) return f"""Entwickle 3 klar unterschiedliche Storyline-Optionen für die nächste KNIEPUNKT-Episode. Nachrichten dieser Woche: {news_digest} Quellenbewertung (berücksichtigen): {source_assessment[:800]} Frühere Episoden – Redundanzvermeidung: {episodes_context[:2000]} {initial} Für jede Storyline: **Option [N]: [Arbeitstitel]** - **Kernwinkel:** Was ist der redaktionelle Blickwinkel? (2-3 Sätze) - **Nachrichten-Auswahl:** Welche 2-3 Nachrichten werden verwendet und wie verknüpft? - **Einstiegsidee:** Konkrete Idee für den ersten Satz oder Absatz - **Allegorischer Rahmen:** Mythologie, Literatur oder kulturelle Referenz (falls passend) - **Unterschied** zu den anderen Optionen - **Stärken / Risiken** Vermeide: Redundanzen zu früheren Episoden, reines Nachrichtenreferat ohne Meinung, zu technische Tiefe.""" def generate_storylines( providers: list, news_digest: str, source_assessment: str, author_input: dict, episodes_context: str, ) -> dict[str, str]: """Run storyline generation on all providers. Returns {provider_name: result}.""" prompt = _build_prompt(news_digest, source_assessment, author_input, episodes_context) messages = [{"role": "user", "content": prompt}] results = {} for provider in providers: console.print(f"\n[yellow]Generiere Storylines mit {provider.name}...[/yellow]") try: results[provider.name] = provider.chat(messages, _SYSTEM, max_tokens=4096) except Exception as e: console.print(f"[red]{provider.name} übersprungen: {e}[/red]") return results def select_storyline(results: dict[str, str]) -> tuple[str, int, str, str]: """Show all provider results, return (provider_name, choice, selected_text, adjustments).""" if not results: raise RuntimeError("Kein Modell hat Storylines geliefert. API-Keys und Verbindung prüfen.") provider_names = list(results.keys()) for name, text in results.items(): console.print(Panel(text, title=f"Storylines – {name}", border_style="cyan")) console.print() if len(provider_names) > 1: provider_choice = Prompt.ask( "Von welchem Modell möchten Sie eine Storyline wählen?", choices=provider_names, default=provider_names[0], ) else: provider_choice = provider_names[0] option_choice = IntPrompt.ask( f"Welche Storyline von {provider_choice}? (1/2/3)", choices=["1", "2", "3"], default=1, ) console.print("\n[dim]Anpassungen oder zusätzliche Hinweise zur gewählten Storyline? (Enter zum Überspringen)[/dim]") adjustments = input().strip() return provider_choice, option_choice, results[provider_choice], adjustments