aidn commited on
Commit
0f8e48b
·
verified ·
1 Parent(s): dda28e6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -23
app.py CHANGED
@@ -11,33 +11,33 @@ LEADERBOARD_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "lea
11
 
12
  # ── System Prompts ─────────────────────────────────────────────────────────────
13
 
14
- PROMPT_TO_LINKEDIN = """Du bist ein LinkedIn-Influencer-Generator. Deine einzige Aufgabe ist es, banale, alltaegliche Aussagen in absurd ausschweifende, klischeebeladene LinkedIn-Posts zu verwandeln.
15
 
16
  Regeln:
17
  - Alles ist eine "Journey", ein "Gamechanger" oder eine "powerful lesson"
18
  - Nutze mindestens 3 Emojis strategisch
19
- - Erwaehne "Growth", "Mindset", "Passion" oder "Impact" wo immer moeglich
20
- - Fuege eine persoenliche Anekdote hinzu, die niemand braucht
21
  - Endet mit einer rhetorischen Frage an die Community
22
- - Benutze dramatische Zeilenumbrueche fuer Effekt
23
  - Alles ist ausnahmslos positiv, auch wenn das Original negativ ist
24
  - Hashtags am Ende sind Pflicht (mindestens 5)
25
- - Klingt wie jemand, der gerade ein Buch ueber sich selbst schreiben wuerde
26
- - Formatiere mit Markdown: Eroeffnungssatz als ## Ueberschrift, Schluesselbegriffe wie **Gamechanger**, **Growth**, **Mindset**, **Journey** fett hervorheben, Abschnitte mit Leerzeilen trennen
27
 
28
- Antworte NUR mit dem LinkedIn-Post in Markdown. Kein Vorwort, keine Erklaerung."""
29
 
30
  PROMPT_FROM_LINKEDIN = """Du bist ein gnadenloser semantischer Reduzierer. Du hasst Floskeln. Deine Aufgabe: LinkedIn-Texte auf das absolute, brutalste Minimum eindampfen.
31
 
32
  Regeln:
33
  - EIN Satz. Nicht zwei. Einer.
34
- - Kuerze bis es wehtut. Dann nochmal kuerzen.
35
  - Null Emotion, null Wertung, null Kontext der niemanden interessiert
36
- - Streiche alles was keine neue Information traegt
37
  - Wenn der gesamte Post nur bedeutet "Ich hab heute Kaffee getrunken" schreib genau das
38
  - Maximal 15 Woerter
39
 
40
- Antworte NUR mit diesem einen Satz. Kein Vorwort, keine Erklaerung."""
41
 
42
  PROMPT_BINGO = """You are a precise, fair but sarcastic LinkedIn post analyst. Your job is to measure actual corporate nonsense - not just LinkedIn formatting habits.
43
 
@@ -50,15 +50,15 @@ CRITICAL: You must distinguish between FORM and SUBSTANCE.
50
  Rate on these 5 metrics (score 1-10, where 10 = maximum LinkedIn nonsense):
51
 
52
  1. label="Buzzword-Dichte": Are the buzzwords empty filler, or do they refer to real, specific concepts? Real tools and methodologies (e.g. MLflow, LiteLLM, RAG, specific frameworks) are NOT buzzwords. Empty buzzwords: "synergy", "impact", "journey", "game-changer" used without context.
53
- 2. label="Laenge vs. Inhalt": Is the length justified by actual information density? A long post with dense technical content scores LOW. A long post that repeats one obvious idea scores HIGH.
54
- 3. label="Selbstbeweihraeuche": Is the post primarily about ego ("look how great we are") or about sharing knowledge? Score HIGH only if the author is the hero, not the content.
55
  4. label="Hashtag-Overload": Score LOW for 1-6 relevant hashtags. Score HIGH for 10+ hashtags or hashtags irrelevant to the content.
56
  5. label="Sinnlosigkeits-Index": Could someone learn something concrete from this post? A post with real takeaways, named tools, or specific problems solved scores LOW. Pure inspiration porn scores HIGH.
57
 
58
  Reply ONLY with a single valid JSON object. No markdown fences, no backticks, no preamble. Raw JSON only.
59
 
60
  Use exactly this structure:
61
- {"metrics":[{"label":"Buzzword-Dichte","score":3,"comment":"kurz sarkastisch"},{"label":"Laenge vs. Inhalt","score":4,"comment":"kurz sarkastisch"},{"label":"Selbstbeweihraeuche","score":2,"comment":"kurz sarkastisch"},{"label":"Hashtag-Overload","score":5,"comment":"kurz sarkastisch"},{"label":"Sinnlosigkeits-Index","score":3,"comment":"kurz sarkastisch"}],"verdict":"Ein praezises Urteil auf Deutsch."}
62
 
63
  Rules:
64
  - score is an integer 1-10. Be calibrated: most posts will not score 8-10 on every metric. Reserve 9-10 for truly egregious cases.
@@ -98,7 +98,7 @@ def _add_to_lb(post_text: str, total: int, max_score: int, verdict: str):
98
  def _render_leaderboard() -> str:
99
  entries = _load_lb()
100
  if not entries:
101
- return "<p style='color:#888;font-size:.85rem;text-align:center;padding:20px;'>Noch keine Eintraege. Analysiere einen LinkedIn-Post um zu starten.</p>"
102
 
103
  sorted_asc = sorted(entries, key=lambda x: x["pct"])
104
  sorted_desc = sorted(entries, key=lambda x: x["pct"], reverse=True)
@@ -139,7 +139,7 @@ def _render_leaderboard() -> str:
139
  <span style="font-weight:700;font-size:.95rem;color:#004182;
140
  text-transform:uppercase;letter-spacing:.5px;">Leaderboard</span>
141
  <span style="margin-left:auto;font-size:.78rem;color:#888;">
142
- {total_count} Eintraege &nbsp;&middot;&nbsp; Ø {avg_pct}% Nonsense
143
  </span>
144
  </div>
145
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:20px;">
@@ -153,7 +153,7 @@ def _render_leaderboard() -> str:
153
  <div>
154
  <div style="font-size:.76rem;font-weight:700;text-transform:uppercase;
155
  letter-spacing:.5px;color:#C0392B;margin-bottom:10px;">
156
- 💩 Reinster LinkedIn-Nonsense (hoechster Score)
157
  </div>
158
  {worst_html}
159
  </div>
@@ -208,7 +208,7 @@ def _extract_json(raw: str) -> dict:
208
 
209
 
210
  def get_bingo(text: str):
211
- """Gibt (bingo_html, leaderboard_html) zurueck."""
212
  if not text.strip() or not HF_TOKEN:
213
  return "", _render_leaderboard()
214
  last_err = None
@@ -238,8 +238,8 @@ def _render_bingo(data):
238
 
239
  ICONS = {
240
  "Buzzword-Dichte": "🗣️",
241
- "Laenge vs. Inhalt": "📏",
242
- "Selbstbeweihraeuche": "🪞",
243
  "Hashtag-Overload": "#️⃣",
244
  "Sinnlosigkeits-Index": "🌀",
245
  }
@@ -413,12 +413,12 @@ with gr.Blocks(title="LinkedIn Translator", css=CSS) as demo:
413
  with gr.Column(scale=5):
414
  input_box = gr.Textbox(
415
  label="✍️ Normale Aussage",
416
- placeholder="z.B. 'Ich hab heute meinen Kaffee verschuettet.'",
417
  lines=10,
418
  )
419
  with gr.Column(scale=1, min_width=120):
420
  gr.HTML("<div style='height:40px'></div>")
421
- translate_btn = gr.Button("Uebersetzen", variant="primary", size="lg")
422
  gr.HTML("<div style='height:12px'></div>")
423
  swap_btn = gr.Button("🔄 → LinkedIn", variant="secondary", size="sm")
424
  with gr.Column(scale=5):
@@ -433,7 +433,7 @@ with gr.Blocks(title="LinkedIn Translator", css=CSS) as demo:
433
  with gr.Row():
434
  with gr.Column():
435
  markdown_out = gr.Markdown(
436
- value="*Noch kein Ergebnis - bitte zuerst uebersetzen.*",
437
  visible=True,
438
  )
439
  bingo_out = gr.HTML(value="", visible=False)
@@ -448,7 +448,7 @@ with gr.Blocks(title="LinkedIn Translator", css=CSS) as demo:
448
  <div style="background:#FFF4CE;border:1px solid #F9C642;border-left:4px solid #F9C642;
449
  border-radius:6px;padding:10px 14px;font-size:.85rem;color:#7A5800;margin-top:8px;">
450
  <strong>Kein HF_TOKEN gefunden.</strong>
451
- Unter <em>Settings &rarr; Variables and secrets</em> als <code>HF_TOKEN</code> hinzufuegen.
452
  </div>
453
  """)
454
 
 
11
 
12
  # ── System Prompts ─────────────────────────────────────────────────────────────
13
 
14
+ PROMPT_TO_LINKEDIN = """Du bist ein LinkedIn-Influencer-Generator. Deine einzige Aufgabe ist es, banale, alltägliche Aussagen in absurd ausschweifende, klischeebeladene LinkedIn-Posts zu verwandeln.
15
 
16
  Regeln:
17
  - Alles ist eine "Journey", ein "Gamechanger" oder eine "powerful lesson"
18
  - Nutze mindestens 3 Emojis strategisch
19
+ - Erwähne "Growth", "Mindset", "Passion" oder "Impact" wo immer moeglich
20
+ - Füge eine persoenliche Anekdote hinzu, die niemand braucht
21
  - Endet mit einer rhetorischen Frage an die Community
22
+ - Benutze dramatische Zeilenumbrüche für Effekt
23
  - Alles ist ausnahmslos positiv, auch wenn das Original negativ ist
24
  - Hashtags am Ende sind Pflicht (mindestens 5)
25
+ - Klingt wie jemand, der gerade ein Buch über sich selbst schreiben würde
26
+ - Formatiere mit Markdown: Eroeffnungssatz als ## überschrift, Schlüsselbegriffe wie **Gamechanger**, **Growth**, **Mindset**, **Journey** fett hervorheben, Abschnitte mit Leerzeilen trennen
27
 
28
+ Antworte NUR mit dem LinkedIn-Post in Markdown. Kein Vorwort, keine Erklärung."""
29
 
30
  PROMPT_FROM_LINKEDIN = """Du bist ein gnadenloser semantischer Reduzierer. Du hasst Floskeln. Deine Aufgabe: LinkedIn-Texte auf das absolute, brutalste Minimum eindampfen.
31
 
32
  Regeln:
33
  - EIN Satz. Nicht zwei. Einer.
34
+ - Kürze bis es wehtut. Dann nochmal kürzen.
35
  - Null Emotion, null Wertung, null Kontext der niemanden interessiert
36
+ - Streiche alles was keine neue Information trägt
37
  - Wenn der gesamte Post nur bedeutet "Ich hab heute Kaffee getrunken" schreib genau das
38
  - Maximal 15 Woerter
39
 
40
+ Antworte NUR mit diesem einen Satz. Kein Vorwort, keine Erklärung."""
41
 
42
  PROMPT_BINGO = """You are a precise, fair but sarcastic LinkedIn post analyst. Your job is to measure actual corporate nonsense - not just LinkedIn formatting habits.
43
 
 
50
  Rate on these 5 metrics (score 1-10, where 10 = maximum LinkedIn nonsense):
51
 
52
  1. label="Buzzword-Dichte": Are the buzzwords empty filler, or do they refer to real, specific concepts? Real tools and methodologies (e.g. MLflow, LiteLLM, RAG, specific frameworks) are NOT buzzwords. Empty buzzwords: "synergy", "impact", "journey", "game-changer" used without context.
53
+ 2. label="Länge vs. Inhalt": Is the length justified by actual information density? A long post with dense technical content scores LOW. A long post that repeats one obvious idea scores HIGH.
54
+ 3. label="Selbstbeweihräuche": Is the post primarily about ego ("look how great we are") or about sharing knowledge? Score HIGH only if the author is the hero, not the content.
55
  4. label="Hashtag-Overload": Score LOW for 1-6 relevant hashtags. Score HIGH for 10+ hashtags or hashtags irrelevant to the content.
56
  5. label="Sinnlosigkeits-Index": Could someone learn something concrete from this post? A post with real takeaways, named tools, or specific problems solved scores LOW. Pure inspiration porn scores HIGH.
57
 
58
  Reply ONLY with a single valid JSON object. No markdown fences, no backticks, no preamble. Raw JSON only.
59
 
60
  Use exactly this structure:
61
+ {"metrics":[{"label":"Buzzword-Dichte","score":3,"comment":"kurz sarkastisch"},{"label":"Länge vs. Inhalt","score":4,"comment":"kurz sarkastisch"},{"label":"Selbstbeweihräuche","score":2,"comment":"kurz sarkastisch"},{"label":"Hashtag-Overload","score":5,"comment":"kurz sarkastisch"},{"label":"Sinnlosigkeits-Index","score":3,"comment":"kurz sarkastisch"}],"verdict":"Ein präzises Urteil auf Deutsch."}
62
 
63
  Rules:
64
  - score is an integer 1-10. Be calibrated: most posts will not score 8-10 on every metric. Reserve 9-10 for truly egregious cases.
 
98
  def _render_leaderboard() -> str:
99
  entries = _load_lb()
100
  if not entries:
101
+ return "<p style='color:#888;font-size:.85rem;text-align:center;padding:20px;'>Noch keine Einträge. Analysiere einen LinkedIn-Post um zu starten.</p>"
102
 
103
  sorted_asc = sorted(entries, key=lambda x: x["pct"])
104
  sorted_desc = sorted(entries, key=lambda x: x["pct"], reverse=True)
 
139
  <span style="font-weight:700;font-size:.95rem;color:#004182;
140
  text-transform:uppercase;letter-spacing:.5px;">Leaderboard</span>
141
  <span style="margin-left:auto;font-size:.78rem;color:#888;">
142
+ {total_count} Einträge &nbsp;&middot;&nbsp; Ø {avg_pct}% Nonsense
143
  </span>
144
  </div>
145
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:20px;">
 
153
  <div>
154
  <div style="font-size:.76rem;font-weight:700;text-transform:uppercase;
155
  letter-spacing:.5px;color:#C0392B;margin-bottom:10px;">
156
+ 💩 Reinster LinkedIn-Nonsense (höchster Score)
157
  </div>
158
  {worst_html}
159
  </div>
 
208
 
209
 
210
  def get_bingo(text: str):
211
+ """Gibt (bingo_html, leaderboard_html) zurück."""
212
  if not text.strip() or not HF_TOKEN:
213
  return "", _render_leaderboard()
214
  last_err = None
 
238
 
239
  ICONS = {
240
  "Buzzword-Dichte": "🗣️",
241
+ "Länge vs. Inhalt": "📏",
242
+ "Selbstbeweihräuche": "🪞",
243
  "Hashtag-Overload": "#️⃣",
244
  "Sinnlosigkeits-Index": "🌀",
245
  }
 
413
  with gr.Column(scale=5):
414
  input_box = gr.Textbox(
415
  label="✍️ Normale Aussage",
416
+ placeholder="z.B. 'Ich hab heute meinen Kaffee verschüttet.'",
417
  lines=10,
418
  )
419
  with gr.Column(scale=1, min_width=120):
420
  gr.HTML("<div style='height:40px'></div>")
421
+ translate_btn = gr.Button("übersetzen", variant="primary", size="lg")
422
  gr.HTML("<div style='height:12px'></div>")
423
  swap_btn = gr.Button("🔄 → LinkedIn", variant="secondary", size="sm")
424
  with gr.Column(scale=5):
 
433
  with gr.Row():
434
  with gr.Column():
435
  markdown_out = gr.Markdown(
436
+ value="*Noch kein Ergebnis - bitte zuerst übersetzen.*",
437
  visible=True,
438
  )
439
  bingo_out = gr.HTML(value="", visible=False)
 
448
  <div style="background:#FFF4CE;border:1px solid #F9C642;border-left:4px solid #F9C642;
449
  border-radius:6px;padding:10px 14px;font-size:.85rem;color:#7A5800;margin-top:8px;">
450
  <strong>Kein HF_TOKEN gefunden.</strong>
451
+ Unter <em>Settings &rarr; Variables and secrets</em> als <code>HF_TOKEN</code> hinzufügen.
452
  </div>
453
  """)
454