From 333d825cb74fedb9e80bf76d55faa2549f2ef3e2 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Tue, 10 Jun 2025 13:13:38 +0200 Subject: [PATCH 1/5] ref: Allow passing custom prompts to Groq methods Rudimentary implementation currently. Would probably ultimately help to have a 'prompt' domain model which can be used something like this: Prompt(type=Prompt.SUGGESTIONS).leaning("left").current(2025).area("politics").view("American") That way it would be easy to build your own prompt. --- prophet/infra/llm_groq.py | 59 ++++++++++++++++++++++++++++------ templates/floating_button.html | 8 +++++ 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/prophet/infra/llm_groq.py b/prophet/infra/llm_groq.py index e3d4199..f90263e 100644 --- a/prophet/infra/llm_groq.py +++ b/prophet/infra/llm_groq.py @@ -1,9 +1,14 @@ +from typing import override + from groq import Groq from prophet.config import AiConfig +from prophet.domain.improvement import Improvement from prophet.domain.llm import LLMClient from prophet.domain.original import Original +AVOID_SHOCKING_TURN_OF_EVENTS: bool = True + class GroqClient(LLMClient): config_ai: AiConfig @@ -15,12 +20,23 @@ class GroqClient(LLMClient): self.config_ai = config_ai if config_ai else AiConfig.from_env() self.client = client if client else Groq(api_key=self.config_ai.API_KEY) - def get_alternative_title_suggestions(self, original_content: str) -> str: + @override + def get_alternative_title_suggestions( + self, original_content: str, custom_prompt: str | None = None + ) -> str: + prompt = ( + custom_prompt + if custom_prompt + else """You are a comedy writer at a satirical newspaper. Improve + on the following satirical headline. Your new headline is funny, + can involve current political events and has an edge to it. Print + only the suggestions, with one suggestion on each line.""" + ) suggestions = self.client.chat.completions.create( messages=[ { "role": "system", - "content": "You are a comedy writer at a satirical newspaper. Improve on the following satirical headline. Your new headline is funny, can involve current political events and has an edge to it. Print only the suggestions, with one suggestion on each line.", + "content": prompt, }, { "role": "user", @@ -34,16 +50,34 @@ class GroqClient(LLMClient): raise ValueError return suggestions_str + @override def rewrite_title( - self, original_content: str, suggestions: str | None = None + self, + original_content: str, + suggestions: str | None = None, + custom_prompt: str | None = None, ) -> str: + prompt = ( + custom_prompt + if custom_prompt + else """ + You are an editor at a satirical newspaper. Improve on the following + satirical headline. For a given headline, you diligently evaluate: (1) + Whether the headline is funny; (2) Whether the headline follows a clear + satirical goal; (3) Whether the headline has sufficient substance and + bite. Based on the outcomes of your review, you pick your favorite + headline from the given suggestions and you make targeted revisions to + it. Keep the length roughly to that of the original suggestions. Your + output consists solely of the revised headline. + """ + ) if not suggestions: suggestions = self.get_alternative_title_suggestions(original_content) winner = self.client.chat.completions.create( messages=[ { "role": "system", - "content": "You are an editor at a satirical newspaper. Improve on the following satirical headline. For a given headline, you diligently evaluate: (1) Whether the headline is funny; (2) Whether the headline follows a clear satirical goal; (3) Whether the headline has sufficient substance and bite. Based on the outcomes of your review, you pick your favorite headline from the given suggestions and you make targeted revisions to it. Keep the length roughly to that of the original suggestions. Your output consists solely of the revised headline.", + "content": prompt, }, { "role": "user", @@ -58,21 +92,26 @@ class GroqClient(LLMClient): raise ValueError return winner_str.strip(" \"'") + @override def rewrite_summary( - self, original: Original, improved_title: str | None = None + self, + original: Original, + improved_title: str | None = None, + custom_prompt: str | None = None, ) -> str: + prompt = ( + custom_prompt + if custom_prompt + else f""" Below there is an original title and an original summary. Then follows an improved title. Write an improved summary based on the original summary which fits to the improved title. {"Do not use the phrase: 'in a surprising turn of events' or 'in a shocking turn of events.'" if AVOID_SHOCKING_TURN_OF_EVENTS else ""} Only output the improved summary.\n\nTitle:{original.title}\nSummary:{original.summary}\n---\nTitle:{improved_title}\nSummary:""" + ) if not improved_title: improved_title = self.rewrite_title(original.title) - no_shocking_turn: bool = True summary = self.client.chat.completions.create( messages=[ { "role": "user", - "content": f""" -Below there is an original title and an original summary. Then follows an improved title. Write an improved summary based on the original summary which fits to the improved title. -{"Do not use the phrase: 'in a surprising turn of events' or 'in a shocking turn of events.'" if no_shocking_turn else ""} -Only output the improved summary.\n\nTitle:{original.title}\nSummary:{original.summary}\n---\nTitle:{improved_title}\nSummary:""", + "content": prompt, } ], model="llama-3.3-70b-versatile", diff --git a/templates/floating_button.html b/templates/floating_button.html index c86d108..f79a9a0 100644 --- a/templates/floating_button.html +++ b/templates/floating_button.html @@ -31,6 +31,14 @@ +
  • + Lefty Bee +
    +
    + +
    +
    +
  • About
    From 63131b7f115fde7c81b449772050e521bd8f294b Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Tue, 10 Jun 2025 21:27:51 +0200 Subject: [PATCH 2/5] feat: Add single rewrite method to LLM models --- prophet/domain/llm.py | 6 +++++- prophet/infra/llm_groq.py | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/prophet/domain/llm.py b/prophet/domain/llm.py index 01ff319..0f32610 100644 --- a/prophet/domain/llm.py +++ b/prophet/domain/llm.py @@ -1,10 +1,11 @@ from typing import Protocol +from prophet.domain.improvement import Improvement from prophet.domain.original import Original class LLMClient(Protocol): - def get_alternative_title_suggestions(self, original_content: str) -> str: + def rewrite(self, original: Original) -> Improvement: raise NotImplementedError def rewrite_title( @@ -16,3 +17,6 @@ class LLMClient(Protocol): self, original: Original, improved_title: str | None = None ) -> str: raise NotImplementedError + + def get_alternative_title_suggestions(self, original_content: str) -> str: + raise NotImplementedError diff --git a/prophet/infra/llm_groq.py b/prophet/infra/llm_groq.py index f90263e..e91d8f3 100644 --- a/prophet/infra/llm_groq.py +++ b/prophet/infra/llm_groq.py @@ -20,6 +20,14 @@ class GroqClient(LLMClient): self.config_ai = config_ai if config_ai else AiConfig.from_env() self.client = client if client else Groq(api_key=self.config_ai.API_KEY) + @override + def rewrite(self, original: Original) -> Improvement: + suggestions = self.get_alternative_title_suggestions(original.title) + new_title = self.rewrite_title(original.title, suggestions) + new_summary = self.rewrite_summary(original, new_title) + + return Improvement(original=original, title=new_title, summary=new_summary) + @override def get_alternative_title_suggestions( self, original_content: str, custom_prompt: str | None = None From 2514ad1296216556cbb1799ad7a1c8925f5b8bbf Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Tue, 10 Jun 2025 21:35:02 +0200 Subject: [PATCH 3/5] fix: Make prompts try to adhere to original length, more lefty --- prophet/infra/llm_groq.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/prophet/infra/llm_groq.py b/prophet/infra/llm_groq.py index e91d8f3..f528208 100644 --- a/prophet/infra/llm_groq.py +++ b/prophet/infra/llm_groq.py @@ -35,10 +35,21 @@ class GroqClient(LLMClient): prompt = ( custom_prompt if custom_prompt - else """You are a comedy writer at a satirical newspaper. Improve - on the following satirical headline. Your new headline is funny, - can involve current political events and has an edge to it. Print - only the suggestions, with one suggestion on each line.""" + else """ + + Political context: We are in the year 2025, Donald Trump is + President of the United States again. There has been a crackdown on + 'illegal' immigration, with controversial disappearings happening + almost every day. Many are calling the United States an + increasingly fascist state. + + You are a comedy writer at a left-leaning satirical newspaper. + Improve on the following satirical headline. Your new headline is + funny, can involve current political events. and has an edge to it. + It should be roughly the length of the original headline. Print + only new suggestions, with one suggestion on each line. + + """ ) suggestions = self.client.chat.completions.create( messages=[ @@ -73,10 +84,10 @@ class GroqClient(LLMClient): satirical headline. For a given headline, you diligently evaluate: (1) Whether the headline is funny; (2) Whether the headline follows a clear satirical goal; (3) Whether the headline has sufficient substance and - bite. Based on the outcomes of your review, you pick your favorite - headline from the given suggestions and you make targeted revisions to - it. Keep the length roughly to that of the original suggestions. Your - output consists solely of the revised headline. + bite; (4) Whether the headline is roughly the length of the original + suggestion. Based on the outcomes of your review, you pick your + favorite headline from the given suggestions and you make targeted + revisions to it. Your output consists solely of the revised headline. """ ) if not suggestions: From 836e7b565bfefcbd2cb7bdc1f3fed2de42077336 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Thu, 12 Jun 2025 21:07:23 +0200 Subject: [PATCH 4/5] fix: Expose app by default --- prophet/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prophet/app.py b/prophet/app.py index dccde98..b8d568d 100644 --- a/prophet/app.py +++ b/prophet/app.py @@ -122,7 +122,7 @@ async def fetch_update(debug_print: bool = True): def start() -> None: from uvicorn import run - run("prophet.app:app", reload=True) + run("prophet.app:app", reload=True, host="0.0.0.0") if __name__ == "__main__": From 9ec2f1d89aa7988d6312b25fe50296ba332fffc3 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Thu, 12 Jun 2025 21:07:23 +0200 Subject: [PATCH 5/5] feat: Add Dockerfile --- Dockerfile | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ac25ebc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,86 @@ +FROM python:3.13-slim-bookworm AS build + +SHELL ["sh", "-exc"] + +ENV DEBIAN_FRONTEND=noninteractive + +RUN <