From 22404bdccca898343260b82662e17614a95b87de Mon Sep 17 00:00:00 2001 From: root Date: Sun, 15 Mar 2026 13:18:20 +0700 Subject: [PATCH] Memory: Duplikat-Handling mit statusabhaengiger Rueckmeldung + Buttons bei bestehendem Kandidat --- homelab-ai-bot/context.py | 35 +++++++++++++++++++++++++++++++++- homelab-ai-bot/telegram_bot.py | 34 ++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/homelab-ai-bot/context.py b/homelab-ai-bot/context.py index 87255abd..79b15d42 100644 --- a/homelab-ai-bot/context.py +++ b/homelab-ai-bot/context.py @@ -294,8 +294,15 @@ def _tool_memory_read(scope=""): return "\n".join(lines) +last_suggest_result = {"type": None, "candidate_id": None} + + def _tool_memory_suggest(scope, kind, content, memory_type="temporary", expires_at=None): import memory_client + from datetime import datetime + global last_suggest_result + last_suggest_result = {"type": None, "candidate_id": None} + if memory_type not in ("temporary", "permanent"): memory_type = "temporary" @@ -321,8 +328,34 @@ def _tool_memory_suggest(scope, kind, content, memory_type="temporary", expires_ result = memory_client._post("/memory", data) if result and result.get("duplicate"): - return f"Bereits gespeichert (ID {result.get('existing_id')})." + ex_status = result.get("existing_status", "?") + ex_type = result.get("existing_memory_type", "") + ex_exp = result.get("existing_expires_at") + ex_id = result.get("existing_id") + + if ex_status == "candidate": + last_suggest_result = {"type": "existing_candidate", "candidate_id": ex_id} + return "Noch nicht bestaetigt — zeige Auswahl erneut." + elif ex_status == "active": + if ex_type == "temporary" and ex_exp: + exp_str = datetime.fromtimestamp(ex_exp).strftime("%d.%m.%Y") + last_suggest_result = {"type": "active_temporary", "candidate_id": None} + return f"Schon temporaer gespeichert bis {exp_str}." + elif ex_type == "permanent": + last_suggest_result = {"type": "active_permanent", "candidate_id": None} + return "Schon dauerhaft gespeichert." + else: + last_suggest_result = {"type": "active_other", "candidate_id": None} + return "Bereits aktiv gespeichert." + elif ex_status == "archived": + last_suggest_result = {"type": "existing_candidate", "candidate_id": ex_id} + memory_client._patch(f"/memory/{ex_id}", {"status": "candidate"}) + return "War archiviert — erneut als Kandidat vorgeschlagen." + else: + return "Bereits vorhanden." + if result and result.get("ok"): + last_suggest_result = {"type": "new_candidate", "candidate_id": None} type_label = "temporaer" if memory_type == "temporary" else "dauerhaft" return f"Vorschlag gespeichert als Kandidat ({type_label})." return "Konnte Vorschlag nicht speichern." diff --git a/homelab-ai-bot/telegram_bot.py b/homelab-ai-bot/telegram_bot.py index 414aad57..f2cbfc81 100644 --- a/homelab-ai-bot/telegram_bot.py +++ b/homelab-ai-bot/telegram_bot.py @@ -384,6 +384,7 @@ async def handle_message(update: Update, ctx: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("🤔 Denke nach...") try: + context.last_suggest_result = {"type": None, "candidate_id": None} candidates_before = {c["id"] for c in memory_client.get_candidates()} handlers = context.get_tool_handlers(session_id=session_id) answer = llm.ask_with_tools(text, handlers, session_id=session_id) @@ -391,16 +392,31 @@ async def handle_message(update: Update, ctx: ContextTypes.DEFAULT_TYPE): memory_client.log_message(session_id, "user", text) memory_client.log_message(session_id, "assistant", answer) - candidates_after = memory_client.get_candidates() - new_candidates = [c for c in candidates_after if c["id"] not in candidates_before] + suggest = context.last_suggest_result - if new_candidates: - c = new_candidates[0] - type_icon = "🕒" if c.get("memory_type") == "temporary" else "📌" if c.get("memory_type") == "permanent" else "📝" - await update.message.reply_text( - answer[:4000] + "\n\n" + type_icon + " " + c["content"], - reply_markup=_memory_buttons(c["id"]), - ) + if suggest["type"] == "existing_candidate" and suggest["candidate_id"]: + candidates = memory_client.get_candidates() + item = next((c for c in candidates if c["id"] == suggest["candidate_id"]), None) + if item: + await update.message.reply_text( + answer[:4000] + "\n\n" + _format_candidate(item), + reply_markup=_memory_buttons(item["id"]), + ) + else: + await update.message.reply_text(answer[:4000], reply_markup=KEYBOARD) + + elif suggest["type"] == "new_candidate": + candidates_after = memory_client.get_candidates() + new_candidates = [c for c in candidates_after if c["id"] not in candidates_before] + if new_candidates: + c = new_candidates[0] + type_icon = "🕒" if c.get("memory_type") == "temporary" else "📌" if c.get("memory_type") == "permanent" else "📝" + await update.message.reply_text( + answer[:4000] + "\n\n" + type_icon + " " + c["content"], + reply_markup=_memory_buttons(c["id"]), + ) + else: + await update.message.reply_text(answer[:4000], reply_markup=KEYBOARD) else: await update.message.reply_text(answer[:4000], reply_markup=KEYBOARD) except Exception as e: