Hausmeister: Inline-Buttons fuer Memory-Kandidaten + /memory Befehl
This commit is contained in:
parent
1fc197dd13
commit
f9ea49013a
2 changed files with 85 additions and 3 deletions
|
|
@ -155,6 +155,32 @@ def log_message(session_id: str, role: str, content: str, source: str = None, me
|
|||
_post(f"/sessions/{session_id}/messages", data)
|
||||
|
||||
|
||||
def get_candidates() -> list[dict]:
|
||||
"""Holt alle offenen Memory-Kandidaten."""
|
||||
result = _get("/memory", {"status": "candidate", "limit": 20})
|
||||
if result and "items" in result:
|
||||
return result["items"]
|
||||
return []
|
||||
|
||||
|
||||
def activate_candidate(item_id: int) -> bool:
|
||||
"""Setzt einen Kandidaten auf aktiv."""
|
||||
result = _patch(f"/memory/{item_id}", {"status": "active"})
|
||||
return bool(result and result.get("ok"))
|
||||
|
||||
|
||||
def delete_candidate(item_id: int) -> bool:
|
||||
"""Loescht einen Kandidaten."""
|
||||
_ensure_config()
|
||||
if not _base_url:
|
||||
return False
|
||||
try:
|
||||
r = requests.delete(f"{_base_url}/memory/{item_id}", headers=_headers(), timeout=5)
|
||||
return r.ok
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def get_active_memory() -> list[dict]:
|
||||
"""Holt alle aktiven Memory-Items fuer den System-Prompt."""
|
||||
result = _get("/memory", {"status": "active", "limit": 100})
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ def _release_lock():
|
|||
except OSError:
|
||||
pass
|
||||
|
||||
from telegram import BotCommand, Update, ReplyKeyboardMarkup, KeyboardButton
|
||||
from telegram import BotCommand, Update, ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from telegram.ext import (
|
||||
Application, CommandHandler, MessageHandler, filters, ContextTypes,
|
||||
Application, CommandHandler, MessageHandler, CallbackQueryHandler, filters, ContextTypes,
|
||||
)
|
||||
|
||||
BOT_COMMANDS = [
|
||||
|
|
@ -52,6 +52,7 @@ BOT_COMMANDS = [
|
|||
BotCommand("report", "Tagesbericht"),
|
||||
BotCommand("check", "Monitoring-Check"),
|
||||
BotCommand("feeds", "Feed-Status & Artikel heute"),
|
||||
BotCommand("memory", "Offene Memory-Kandidaten"),
|
||||
BotCommand("start", "Hilfe anzeigen"),
|
||||
]
|
||||
|
||||
|
|
@ -284,6 +285,47 @@ async def cmd_feeds(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
|||
except Exception as e:
|
||||
await update.message.reply_text(f"Fehler: {e}")
|
||||
|
||||
def _memory_buttons(item_id: int) -> InlineKeyboardMarkup:
|
||||
return InlineKeyboardMarkup([[
|
||||
InlineKeyboardButton("✅ Merken", callback_data=f"mem_activate:{item_id}"),
|
||||
InlineKeyboardButton("❌ Verwerfen", callback_data=f"mem_delete:{item_id}"),
|
||||
]])
|
||||
|
||||
|
||||
async def cmd_memory(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
||||
if not _authorized(update):
|
||||
return
|
||||
candidates = memory_client.get_candidates()
|
||||
if not candidates:
|
||||
await update.message.reply_text("Keine offenen Kandidaten.")
|
||||
return
|
||||
for item in candidates:
|
||||
text = f"📝 [{item['scope']}/{item['kind']}]\n{item['content']}"
|
||||
await update.message.reply_text(text, reply_markup=_memory_buttons(item["id"]))
|
||||
|
||||
|
||||
async def handle_memory_callback(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data or ""
|
||||
|
||||
if data.startswith("mem_activate:"):
|
||||
item_id = int(data.split(":")[1])
|
||||
ok = memory_client.activate_candidate(item_id)
|
||||
if ok:
|
||||
await query.edit_message_text("✅ Aktiviert: " + query.message.text.split("\n", 1)[-1])
|
||||
else:
|
||||
await query.edit_message_text("Fehler beim Aktivieren.")
|
||||
|
||||
elif data.startswith("mem_delete:"):
|
||||
item_id = int(data.split(":")[1])
|
||||
ok = memory_client.delete_candidate(item_id)
|
||||
if ok:
|
||||
await query.edit_message_text("🗑 Verworfen.")
|
||||
else:
|
||||
await query.edit_message_text("Fehler beim Loeschen.")
|
||||
|
||||
|
||||
async def handle_message(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
||||
"""Button-Presses und Freitext-Fragen verarbeiten."""
|
||||
if not _authorized(update):
|
||||
|
|
@ -311,12 +353,24 @@ async def handle_message(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
|||
|
||||
await update.message.reply_text("🤔 Denke nach...")
|
||||
try:
|
||||
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)
|
||||
if session_id:
|
||||
memory_client.log_message(session_id, "user", text)
|
||||
memory_client.log_message(session_id, "assistant", answer)
|
||||
await update.message.reply_text(answer[:4000], reply_markup=KEYBOARD)
|
||||
|
||||
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]
|
||||
await update.message.reply_text(
|
||||
answer[:4000] + "\n\n📝 " + c["content"],
|
||||
reply_markup=_memory_buttons(c["id"]),
|
||||
)
|
||||
else:
|
||||
await update.message.reply_text(answer[:4000], reply_markup=KEYBOARD)
|
||||
except Exception as e:
|
||||
log.exception("Fehler bei Freitext")
|
||||
await update.message.reply_text(f"Fehler: {e}")
|
||||
|
|
@ -345,6 +399,8 @@ def main():
|
|||
app.add_handler(CommandHandler("report", cmd_report))
|
||||
app.add_handler(CommandHandler("check", cmd_check))
|
||||
app.add_handler(CommandHandler("feeds", cmd_feeds))
|
||||
app.add_handler(CommandHandler("memory", cmd_memory))
|
||||
app.add_handler(CallbackQueryHandler(handle_memory_callback, pattern=r"^mem_"))
|
||||
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
|
||||
|
||||
async def post_init(application):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue