From 08618ee9a917fff44cc4ac6ca9d97a61f373d6e9 Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Sun, 16 Nov 2025 06:56:27 +0000 Subject: [PATCH] Add historical hashtags --- station_announcer/__init__.py | 12 ++++++++++++ station_announcer/openai_client.py | 22 +++++++++++++++++++--- station_announcer/routes.py | 5 ++++- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/station_announcer/__init__.py b/station_announcer/__init__.py index 49f5339..f05ada8 100644 --- a/station_announcer/__init__.py +++ b/station_announcer/__init__.py @@ -14,6 +14,14 @@ from .mastodon import MastodonClient from .openai_client import AltTextGenerator +def _load_hashtag_counts(path: Path) -> str | None: + """Return newline-delimited hashtag counts formatted for prompts.""" + try: + return path.read_text() + except FileNotFoundError: + return None + + def create_app() -> Flask: """Create and configure the Flask application.""" package_path = Path(__file__).resolve().parent @@ -27,6 +35,10 @@ def create_app() -> Flask: settings = load_settings() app.config.update(settings) + hashtag_counts = _load_hashtag_counts(project_root / "hash_tag_counts") + if hashtag_counts: + app.config["HASHTAG_COUNTS_TEXT"] = hashtag_counts + secret_key = app.config.get("SECRET_KEY") or "dev-secret-key" app.config["SECRET_KEY"] = secret_key app.config["UNIAUTH_URL"] = "https://edwardbetts.com/UniAuth" diff --git a/station_announcer/openai_client.py b/station_announcer/openai_client.py index 1afae69..ab71f73 100644 --- a/station_announcer/openai_client.py +++ b/station_announcer/openai_client.py @@ -22,7 +22,7 @@ class TextImprovementError(OpenAIClientError): class AltTextGenerator: """Request alt text from a GPT-4o compatible OpenAI endpoint.""" - def __init__(self, api_key: str, model: str = "gpt-4o-mini") -> None: + def __init__(self, api_key: str, model: str = "gpt-4.1") -> None: if not api_key: raise ValueError("OPENAI_API_KEY is required") self.model = model @@ -102,20 +102,36 @@ class AltTextGenerator: return content_text.strip() def improve_post_text( - self, draft_text: str, instructions: Optional[str] = None + self, + draft_text: str, + instructions: Optional[str] = None, + hashtag_counts: Optional[str] = None, ) -> str: if not draft_text or not draft_text.strip(): raise TextImprovementError("Post text cannot be empty") prompt_parts = [ - "You review Mastodon drafts and rewrite them in UK English.", + "You review Mastodon drafts and improve them. Use UK English spelling.", "Keep the tone warm, accessible, and descriptive without exaggeration.", "Ensure clarity, fix spelling or grammar, and keep content suitable for social media.", + "Don't add #TravelVibes if I'm at home in Bristol, okay to add if setting off on a trip.", + "Don't add #BetterByRail if not on a rail journey, equally don't remove it if present.", + "Always format hashtags in CamelCase (e.g. #BetterByRail).", ] if instructions: prompt_parts.append(f"Additional instructions: {instructions.strip()}") + if hashtag_counts: + prompt_parts.append( + "When you add hashtags, prefer the ones from my history below, " + "but feel free to invent new ones." + ) prompt_parts.append("Return only the improved post text.") user_content = f"Draft post:\\n{draft_text.strip()}" + if hashtag_counts: + user_content = ( + f"{user_content}\n\nHashtag history (tag with past uses):\n" + f"{hashtag_counts.strip()}" + ) payload = { "model": self.model, diff --git a/station_announcer/routes.py b/station_announcer/routes.py index 0c92e73..a3c8dd1 100644 --- a/station_announcer/routes.py +++ b/station_announcer/routes.py @@ -260,6 +260,7 @@ def compose_draft(): immich_client = current_app.immich_client alt_cache = current_app.alt_text_cache generator = current_app.alt_text_generator + hashtag_counts = current_app.config.get("HASHTAG_COUNTS_TEXT") error_message = None post_text = "" @@ -351,7 +352,9 @@ def compose_draft(): action = request.form.get("action") if action == "refine": try: - post_text = generator.improve_post_text(post_text, instructions) + post_text = generator.improve_post_text( + post_text, instructions, hashtag_counts + ) flash("Post refined with ChatGPT.") except TextImprovementError as exc: error_message = str(exc)