Compare commits

..

5 commits

Author SHA1 Message Date
909fb37f9a
chore: Stop building dockerfile
Instead of keeping the dockerfile-built docker container on the github
container repository, we make out host build it.
2025-07-22 11:25:04 +02:00
c3cfdbdc3c
feat: Indicate buttons which are not implemented
Buttons are greyed out and labelled accordingly.
2025-07-22 11:25:04 +02:00
9ee787ccce
chore: Rename visible titles to Bee's Knees 2025-07-22 11:25:03 +02:00
678382b2f7
docs: Update readme 2025-07-22 11:25:02 +02:00
0933b5f616
feat: Ensure some more consistency in headlines 2025-07-22 11:25:02 +02:00
8 changed files with 83 additions and 105 deletions

View file

@ -1,55 +0,0 @@
name: Create and publish a Docker image
# from: https://docs.github.com/en/actions/use-cases-and-examples/publishing-packages/publishing-docker-images
on:
push:
branches: ["main"]
# Defines two custom environment variables for the workflow.
# These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true

View file

@ -1,9 +1,19 @@
# Pollen Prophet
# The Bee's Knees
When fact checking is optional, but irony is not.
## Ideas
- switch on-the-fly between original and improvements
- [x] switch on-the-fly between original and improvements
- vote-mode for the best suggestion
- when opening the article shows all suggestions made
- user can vote for the best one and the one with the most votes becomes the new headline
- associated image generation?
## What is this?
The Bee's knees is a running AI rewrite of the newest Babylon Bee headlines.
Some will be on point, some will be nonsensical,
but rest assured in the knowledge that all will at least be better than the original.
You can switch back-and-forth between the original and the AI generated version with a button.

View file

@ -41,7 +41,6 @@ class GroqClient(LLMClient):
custom_prompt
if custom_prompt
else f"""
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
@ -57,11 +56,14 @@ class GroqClient(LLMClient):
Do not create a headline naming Trump if more than 2 of the
previous headlines already do so and he is not specifically
referenced in the original headline.
referenced in the original headline. Ensure you do not repeat too
much wording from your previous headlines.
{"The previous 5 headlines you created are the following:\n- " if previous_titles else ""}
{"The previous 5 headlines you created were the following:\n- " if previous_titles else ""}
{"\n- ".join(previous_titles) if previous_titles else ""}
When creating the new headline, try to stick close to the topic of
the original headline.
"""
)
suggestions = self.client.chat.completions.create(
@ -72,7 +74,7 @@ class GroqClient(LLMClient):
},
{
"role": "user",
"content": original_content,
"content": f"The headline to rewrite is the following: {original_content}",
},
],
model="llama-3.3-70b-versatile",
@ -153,3 +155,20 @@ class GroqClient(LLMClient):
raise ValueError
print("Improved summary", summary_str)
return summary_str.strip(" \"'")
if __name__ == "__main__":
from datetime import datetime
cfg = AiConfig.from_env()
llm = GroqClient(cfg)
print(
llm.rewrite(
Original(
title="Obama Argues He Cant Be Charged With Treason Since He Wasnt Born In America",
summary="WASHINGTON, D.C. — In a blow to hopes from conservatives that the former president would face severe consequences for allegedly overseeing an attempt to deligitimize the Trump presidency, Barack Obama argued that he can't be charged with treason since he wasn't born in America and isn't a legitimate American citizen.",
link="",
date=datetime.now(),
)
)
)

View file

@ -1,7 +1,7 @@
[project]
name = "pollen-prophet"
name = "bees-knees"
version = "0.1.0"
description = "Add your description here"
description = "Where fact checking is optional, but irony is not."
readme = "README.md"
requires-python = ">=3.13"
dependencies = [

View file

@ -45,6 +45,10 @@ body {
opacity: 0.8;
}
.fab-icon-holder.disabled {
background: #333333
}
.fab-icon-holder .icon {
display: flex;
align-items: center;

View file

@ -32,24 +32,24 @@
</div>
</li>
<li>
<span class="fab-label">Lefty Bee</span>
<div class="option-btn fab-icon-holder">
<span class="fab-label">Lefty Bee (not implemented)</span>
<div class="option-btn fab-icon-holder disabled">
<div class="icon">
<i class="fas fa-arrow-left"></i>
</div>
</div>
</li>
<li>
<span class="fab-label">About</span>
<div class="option-btn fab-icon-holder">
<span class="fab-label">About (not implemented)</span>
<div class="option-btn fab-icon-holder disabled">
<div class="icon">
<i class="fas fa-question"></i>
</div>
</div>
</li>
<li>
<span class="fab-label">Feedback</span>
<div class="option-btn fab-icon-holder">
<span class="fab-label">Feedback (not implemented)</span>
<div class="option-btn fab-icon-holder disabled">
<div class="icon">
<i class="fas fa-comment-alt"></i>
</div>

View file

@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
<title>The Pollen Prophet</title>
<title>The Bee's Knees</title>
<script src="https://unpkg.com/htmx.org@2.0.4/dist/htmx.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
<script
@ -12,8 +12,8 @@
<link href="static/style.css" rel="stylesheet" />
</head>
<body>
<h1>The Pollen Prophet</h1>
<h2>Making funny since 2025 what ought not bee.</h2>
<h1>The Bee's Knees</h1>
<h2>Where fact checking is optional, but irony is not.</h2>
<div class="article" x-data="{ showing_improvements: true }">
<div
hx-get="/improvements"

66
uv.lock generated
View file

@ -88,6 +88,39 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" },
]
[[package]]
name = "bees-knees"
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "fastapi", extra = ["standard"] },
{ name = "fastapi-utils", extra = ["all"] },
{ name = "feedparser" },
{ name = "groq" },
{ name = "supabase" },
]
[package.dev-dependencies]
dev = [
{ name = "mypy" },
{ name = "ruff" },
]
[package.metadata]
requires-dist = [
{ name = "fastapi", extras = ["standard"], specifier = ">=0.115.12" },
{ name = "fastapi-utils", extras = ["all"], specifier = ">=0.8.0" },
{ name = "feedparser", specifier = ">=6.0.11" },
{ name = "groq", specifier = ">=0.26.0" },
{ name = "supabase", specifier = ">=2.15.2" },
]
[package.metadata.requires-dev]
dev = [
{ name = "mypy", specifier = ">=1.16.0" },
{ name = "ruff", specifier = ">=0.11.12" },
]
[[package]]
name = "certifi"
version = "2025.4.26"
@ -602,39 +635,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
]
[[package]]
name = "pollen-prophet"
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "fastapi", extra = ["standard"] },
{ name = "fastapi-utils", extra = ["all"] },
{ name = "feedparser" },
{ name = "groq" },
{ name = "supabase" },
]
[package.dev-dependencies]
dev = [
{ name = "mypy" },
{ name = "ruff" },
]
[package.metadata]
requires-dist = [
{ name = "fastapi", extras = ["standard"], specifier = ">=0.115.12" },
{ name = "fastapi-utils", extras = ["all"], specifier = ">=0.8.0" },
{ name = "feedparser", specifier = ">=6.0.11" },
{ name = "groq", specifier = ">=0.26.0" },
{ name = "supabase", specifier = ">=2.15.2" },
]
[package.metadata.requires-dev]
dev = [
{ name = "mypy", specifier = ">=1.16.0" },
{ name = "ruff", specifier = ">=0.11.12" },
]
[[package]]
name = "postgrest"
version = "1.0.2"