"""News research: web search via Claude + author personal input.""" from rich.console import Console from rich.panel import Panel console = Console() _RESEARCH_SYSTEM = """Du bist ein erfahrener Redaktionsassistent für die LinkedIn-Kolumne KNIEPUNKT von Dr. André Knie. KNIEPUNKT richtet sich an CEOs, Führungskräfte des Mittelstands, Konzerne und öffentliche Verwaltung – alle mit Interesse an moralischer KI. Geeignete Quellen: The Decoder, Heise, ARD, ZDF, DLF, Handelsblatt, Wirtschaftswoche, Die Zeit, Der Spiegel, wissenschaftliche Publikationen, Reddit (wenn originaler Diskussionskontext), offizielle Unternehmens-Ankündigungen. Ungeeignete Quellen: Boulevardzeitungen, unbekannte Medien, reine Aggregatoren ohne eigene Recherche. Präsentiere Ergebnisse klar strukturiert auf Deutsch.""" _SOURCE_SYSTEM = """Du bist ein strenger Quellen-Prüfer für die KNIEPUNKT-Kolumne. Bewerte jede Quelle nach: Primärquelle | KI-Fachjournalismus | etablierte Qualitätspresse | Erstdiskussionsquelle | schwache Quelle | ungeeignet. Flags: [FEHLENDER BELEG] [WIDERSPRUCH] [UNKLARE FAKTENLAGE] [AUTOR-PRÜFUNG ERFORDERLICH].""" def get_author_input() -> dict: """Collect the author's personal news input and optional initial storyline.""" console.print(Panel( "[bold]Schritt 1: Ihre persönlichen Nachrichten und Notizen[/bold]\n\n" "Bitte geben Sie Ihre KI-Nachrichten der Woche ein.\n" "(URLs, Schlagzeilen, Beobachtungen – eine Leerzeile zum Abschließen)", title="KNIEPUNKT – Wöchentliche Recherche", border_style="cyan", )) lines = [] while True: line = input() if line == "" and lines: break elif line: lines.append(line) console.print("\n[dim]Haben Sie bereits eine Storyline-Idee? (Enter zum Überspringen)[/dim]") initial_storyline = input().strip() or None return {"author_news": "\n".join(lines), "initial_storyline": initial_storyline} def research_news(client, author_input: dict, episodes_context: str) -> str: """Use Claude with web search to research current AI news.""" from kniepunkt.llm import chat_with_search import datetime console.print("\n[yellow]Recherchiere aktuelle KI-Nachrichten...[/yellow]") today = datetime.date.today().strftime("%d.%m.%Y") prompt = f"""Recherchiere die wichtigsten KI-Nachrichten der aktuellen Woche (Stand: {today}) für die LinkedIn-Kolumne KNIEPUNKT. Autoreneingabe (bereits bekannte Nachrichten und Notizen): {author_input['author_news']} Frühere KNIEPUNKT-Episoden (zur Orientierung, was bereits behandelt wurde): {episodes_context[:2000]} Aufgabe: 1. Suche nach 5–8 wichtigen KI-Entwicklungen dieser Woche 2. Priorisiere: Was sollten Entscheider mit Interesse an moralischer KI unbedingt wissen? 3. Kombiniere Recherche-Ergebnisse mit den Autoreneingaben (Dopplungen vermeiden) Ausgabeformat für jeden Nachrichten-Kandidaten: ### [N]. [Titel] **Zusammenfassung:** 2-3 Sätze **Quelle(n):** Name – URL **Relevanz für KNIEPUNKT-Zielgruppe:** 1 Satz""" return chat_with_search( client, [{"role": "user", "content": prompt}], _RESEARCH_SYSTEM, ) def assess_sources(client, news_digest: str) -> str: """Assess source quality for all news items in the digest.""" from kniepunkt.llm import chat console.print("\n[yellow]Bewerte Quellen...[/yellow]") prompt = f"""Bewerte alle Quellen in diesem Nachrichten-Digest für KNIEPUNKT: {news_digest} Für jede Quelle: - Qualitätsstufe (Primärquelle / KI-Fachjournalismus / Qualitätspresse / Erstdiskussion / schwach / ungeeignet) - Kurze Begründung (1 Satz) - Relevante Flags Falls Quellen fehlen oder schwach sind: schlage konkret bessere Alternativen vor.""" return chat( client, [{"role": "user", "content": prompt}], _SOURCE_SYSTEM, )