From 44641f589dd78a464ed698edd2c617437f983578 Mon Sep 17 00:00:00 2001 From: nick2day Date: Sun, 22 Mar 2026 02:12:08 -0400 Subject: [PATCH] Append-only picks store with user-initiated dismiss Pipeline: - write_picks() no longer truncates; deduplicates by artist+album key on append so the same pick is never added twice - Picks accumulate indefinitely; only the user can remove them New endpoint POST /api/fgs/picks/remove: - Accepts {artist, album}, removes matching pick from store - Also writes the removed pick to the dedup DB so it won't resurface Co-Authored-By: Claude Sonnet 4.6 --- agent.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/agent.py b/agent.py index c23f6ba..855d810 100644 --- a/agent.py +++ b/agent.py @@ -749,7 +749,17 @@ async def write_picks(new_picks: list[dict], run_stats: dict): "candidatesFiltered": run_stats.get("filtered", 0), } store["runs"] = ([run] + store.get("runs", []))[:10] - store["allPicks"] = (new_picks + store.get("allPicks", []))[:200] + # Append-only — never remove existing picks; dedup by artist+album key + existing = store.get("allPicks", []) + existing_keys = { + (p.get("artist", "").lower(), p.get("album", "").lower()) + for p in existing + } + truly_new = [ + p for p in new_picks + if (p.get("artist", "").lower(), p.get("album", "").lower()) not in existing_keys + ] + store["allPicks"] = truly_new + existing store["lastUpdated"] = run["timestamp"] with open(settings.picks_path, "w") as f: @@ -889,6 +899,38 @@ async def get_picks(): return JSONResponse({"error": str(e)}, status_code=500) +class RemoveRequest(BaseModel): + artist: str + album: str + + +@app.post("/api/fgs/picks/remove") +async def remove_pick(req: RemoveRequest): + """User-initiated pick removal. Writes the pick key to dedup so it won't return.""" + try: + with open(settings.picks_path, "r") as f: + store = json.load(f) + except Exception as e: + return JSONResponse({"error": str(e)}, status_code=500) + + key_a = req.artist.lower() + key_b = req.album.lower() + before = len(store.get("allPicks", [])) + store["allPicks"] = [ + p for p in store.get("allPicks", []) + if not (p.get("artist", "").lower() == key_a and p.get("album", "").lower() == key_b) + ] + after = len(store["allPicks"]) + + with open(settings.picks_path, "w") as f: + json.dump(store, f, indent=2) + + # Also add to dedup so it won't come back + await mark_seen([{"artist": req.artist, "album": req.album}]) + + return {"removed": before - after, "total": after} + + @app.get("/api/fgs/health") async def health(): return {"status": "ok", "agent": "fgs-agent"}