AI Update: روی حالت های تمامی حافظه های موجود پروژه های کاربران رو همر

This commit is contained in:
Antigravity Bot
2026-08-30 10:22:38 +03:30
parent 291a788e1e
commit f67683abdc
9 changed files with 493 additions and 168 deletions
+131 -36
View File
@@ -1105,19 +1105,26 @@ def process_ai_schedule_actions(raw_text: str, chat_id: int, project_name: str,
return processed_text, created_tasks
def build_memory_menu(chat_id: int, view_type: str = "private", page: int = 0) -> tuple[str, InlineKeyboardMarkup]:
"""Builds interactive AI Long-Term Memory manager dashboard with tabs (private vs global), pagination, and deletion."""
def build_memory_menu(chat_id: int, view_type: str = "project", page: int = 0) -> tuple[str, InlineKeyboardMarkup]:
"""Builds interactive 3-tier AI Memory manager dashboard with tabs (project, user, global), pagination, and deletion."""
from memory_manager import memory_manager
session = session_manager.get_or_create(chat_id)
curr_proj = session_manager.get_current_project(chat_id)
is_fa = (session.language or "").lower() in ("fa", "farsi", "persian", "🇮🇷 persian / farsi (فارسی)")
is_admin_user = settings.is_admin(chat_id)
view_type = "global" if view_type == "global" else "private"
proj_name = curr_proj.name if curr_proj else "default"
if view_type == "global":
memories = memory_manager.get_global_memories(limit=100)
else:
# Validate view_type
if view_type not in ("project", "user", "global"):
view_type = "project" if curr_proj else "user"
if view_type == "project":
memories = memory_manager.get_project_memories(user_id=chat_id, project_name=proj_name, limit=100)
elif view_type == "user":
memories = memory_manager.get_user_memories(user_id=chat_id, limit=100)
else: # global
memories = memory_manager.get_global_memories(limit=100)
total_cnt = len(memories)
page_size = 5
@@ -1125,19 +1132,29 @@ def build_memory_menu(chat_id: int, view_type: str = "private", page: int = 0) -
page = max(0, min(page, max_pages - 1))
paged_memories = memories[page * page_size : (page + 1) * page_size]
stats = memory_manager.get_stats()
stats = memory_manager.get_stats(user_id=chat_id, project_name=proj_name)
if is_fa:
tab_name = "🌐 خاطرات عمومی (کل سیستم)" if view_type == "global" else "👤 خاطرات خصوصی (اختصاصی شما)"
if view_type == "project":
tab_name = f"📁 خاطرات اختصاصی پروژه (<code>{escape_html(proj_name)}</code>)"
tab_desc = "این خاطرات <b>فقط هنگام فعالیت در همین پروژه</b> به هوش مصنوعی تزریق می‌شوند."
elif view_type == "user":
tab_name = "👤 خاطرات شخصی من (سراسری)"
tab_desc = "این خاطرات مربوط به شخص شماست و در <b>تمام پروژه‌ها</b> اعمال می‌گردد."
else:
tab_name = "🌐 قوانین و خاطرات عمومی (کل سرور و کاربران)"
tab_desc = "این قوانین برای <b>همه کاربران</b> تزریق می‌شوند (ویرایش و حذف فقط توسط مدیر)."
header = (
f"🧠 <b>کنترل‌پنل حافظه هوشمند هوش مصنوعی (AI Long-Term Memory)</b>\n\n"
f"🧠 <b>کنترل‌پنل حافظه هوشمند ۳ لایه (AI Memory Dashboard)</b>\n\n"
f"• 📂 <b>بخش فعال:</b> {tab_name}\n"
f"📊 <b>آمار کل:</b> <code>{stats['total_memories']}</code> خاطره (<code>{stats['global_memories']}</code> عمومی | <code>{stats['private_memories']}</code> خصوصی)\n\n"
f"{tab_desc}\n"
f"• 📊 <b>آمار:</b> <code>{stats['current_project_memories']}</code> پروژه | <code>{stats['current_user_memories']}</code> کاربر | <code>{stats['global_memories']}</code> عمومی\n\n"
)
if not memories:
body = (
f"️ <i>در این بخش هنوز هیچ خاطره‌ای ثبت نشده است.</i>\n\n"
f"💡 <b>یادگیری خودکار:</b> هوش مصنوعی به صورت خودکار در خلال گفتگوها، عادات، نام و نکات مهم شما را استخراج و ذخیره می‌کند."
f"💡 <b>یادگیری خودکار:</b> هوش مصنوعی در حین گفتگوها نکات مهم مربوط به این بخش را خودکار استخراج و ثبت می‌کند."
)
else:
body_lines = [f"<b>لیست خاطرات (صفحه {page + 1} از {max_pages}):</b>\n"]
@@ -1149,16 +1166,26 @@ def build_memory_menu(chat_id: int, view_type: str = "private", page: int = 0) -
)
body = "\n\n".join(body_lines)
else:
tab_name = "🌐 Global System Memory" if view_type == "global" else "👤 Private User Memory"
if view_type == "project":
tab_name = f"📁 Project Memory (<code>{escape_html(proj_name)}</code>)"
tab_desc = "Injected only when working in this project."
elif view_type == "user":
tab_name = "👤 User Profile Memory"
tab_desc = "Applies to you across all your projects."
else:
tab_name = "🌐 Global System Memory"
tab_desc = "Applies to all users (admin-managed)."
header = (
f"🧠 <b>AI Long-Term Memory Dashboard</b>\n\n"
f"🧠 <b>3-Tier AI Memory Dashboard</b>\n\n"
f"• 📂 <b>Active Tab:</b> {tab_name}\n"
f"📊 <b>Stats:</b> <code>{stats['total_memories']}</code> total (<code>{stats['global_memories']}</code> global | <code>{stats['private_memories']}</code> private)\n\n"
f"{tab_desc}\n"
f"• 📊 <b>Stats:</b> <code>{stats['current_project_memories']}</code> project | <code>{stats['current_user_memories']}</code> user | <code>{stats['global_memories']}</code> global\n\n"
)
if not memories:
body = "️ <i>No memories recorded in this section yet.</i>\n\n💡 <i>The AI automatically extracts durable facts and preferences during conversations.</i>"
body = "️ <i>No memories recorded in this section yet.</i>"
else:
body_lines = [f"<b>Memories list (Page {page + 1} of {max_pages}):</b>\n"]
body_lines = [f"<b>Memories (Page {page + 1} of {max_pages}):</b>\n"]
for idx, m in enumerate(paged_memories, start=page * page_size + 1):
cat_badge = f"[{m.category}]" if m.category and m.category != "general" else ""
body_lines.append(
@@ -1172,20 +1199,23 @@ def build_memory_menu(chat_id: int, view_type: str = "private", page: int = 0) -
# Build keyboard
keyboard = []
# 1. Tab buttons
tab_priv_text = "👤 خاطرات من (خصوصی) ✓" if view_type == "private" else "👤 خاطرات من (خصوصی)"
tab_glob_text = "🌐 خاطرات عمومی سیستم" if view_type == "global" else "🌐 خاطرات عمومی سیستم"
# 1. 3 Tab buttons
t_proj = f"📁 پروژه ({proj_name[:10]}) ✓" if view_type == "project" else f"📁 پروژه ({proj_name[:10]})"
t_user = "👤 کاربر (من)" if view_type == "user" else "👤 کاربر (من)"
t_glob = "🌐 عمومی ✓" if view_type == "global" else "🌐 عمومی"
if not is_fa:
tab_priv_text = "👤 My Memory" if view_type == "private" else "👤 My Memory"
tab_glob_text = "🌐 Global Memory" if view_type == "global" else "🌐 Global Memory"
t_proj = f"📁 Project" if view_type == "project" else f"📁 Project"
t_user = "👤 User" if view_type == "user" else "👤 User"
t_glob = "🌐 Global ✓" if view_type == "global" else "🌐 Global"
keyboard.append([
InlineKeyboardButton(tab_priv_text, callback_data="mem_tab:private:0"),
InlineKeyboardButton(tab_glob_text, callback_data="mem_tab:global:0"),
InlineKeyboardButton(t_proj, callback_data="mem_tab:project:0"),
InlineKeyboardButton(t_user, callback_data="mem_tab:user:0"),
InlineKeyboardButton(t_glob, callback_data="mem_tab:global:0"),
])
# 2. Item delete buttons (for paged memories)
can_delete_current = (view_type == "private") or (view_type == "global" and is_admin_user)
# 2. Item delete buttons
can_delete_current = (view_type in ("project", "user")) or (view_type == "global" and is_admin_user)
if can_delete_current and paged_memories:
del_row = []
for idx, m in enumerate(paged_memories, start=page * page_size + 1):
@@ -1206,7 +1236,7 @@ def build_memory_menu(chat_id: int, view_type: str = "private", page: int = 0) -
pag_row.append(InlineKeyboardButton("بعدی ➡️" if is_fa else "Next ➡️", callback_data=f"mem_tab:{view_type}:{page + 1}"))
keyboard.append(pag_row)
# 4. Clear memory button (if applicable)
# 4. Clear memory button
action_row = []
if can_delete_current and total_cnt > 0:
clear_label = "🧹 پاکسازی این بخش" if is_fa else "🧹 Clear this section"
@@ -3385,39 +3415,96 @@ async def usage_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
async def memory_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
chat_id = update.effective_chat.id
session = session_manager.get_or_create(chat_id)
curr_proj = session_manager.get_current_project(chat_id)
is_fa = (session.language or "").lower() in ("fa", "farsi", "persian", "🇮🇷 persian / farsi (فارسی)")
is_admin_user = settings.is_admin(chat_id)
from memory_manager import memory_manager
if not context.args:
text, markup = build_memory_menu(chat_id, view_type="private", page=0)
text, markup = build_memory_menu(chat_id, view_type="project" if curr_proj else "user", page=0)
await update.message.reply_html(text, reply_markup=markup)
return
subcmd = context.args[0].lower().strip()
from memory_manager import memory_manager
if subcmd in ("project", "proj", "p"):
text, markup = build_memory_menu(chat_id, view_type="project", page=0)
await update.message.reply_html(text, reply_markup=markup)
return
if subcmd in ("user", "u", "me", "profile", "private"):
text, markup = build_memory_menu(chat_id, view_type="user", page=0)
await update.message.reply_html(text, reply_markup=markup)
return
if subcmd in ("global", "g", "public", "system"):
text, markup = build_memory_menu(chat_id, view_type="global", page=0)
await update.message.reply_html(text, reply_markup=markup)
return
if subcmd in ("private", "p", "my", "user"):
text, markup = build_memory_menu(chat_id, view_type="private", page=0)
await update.message.reply_html(text, reply_markup=markup)
# Add memory manually: /memory add <global|user|project> <key> | <content>
if subcmd in ("add", "set", "save") and len(context.args) > 2:
target_type = context.args[1].lower().strip()
if target_type not in ("global", "user", "project"):
target_type = "user"
rest = " ".join(context.args[1:]).strip()
else:
rest = " ".join(context.args[2:]).strip()
if target_type == "global" and not is_admin_user:
await update.message.reply_html("🚫 <b>خطای دسترسی: فقط مدیر سیستم می‌تواند خاطره عمومی ثبت کند.</b>" if is_fa else "🚫 <b>Access Denied.</b>")
return
if "|" in rest:
key_part, content_part = rest.split("|", 1)
else:
parts = rest.split(None, 1)
key_part = parts[0]
content_part = parts[1] if len(parts) > 1 else ""
key_clean = key_part.strip().lower()
content_clean = content_part.strip()
if not key_clean or not content_clean:
await update.message.reply_html(
"💡 <i>راهنمای افزودن دستی خاطره:</i>\n<code>/memory add [global|user|project] &lt;key&gt; | &lt;محتوا&gt;</code>\n\n<b>مثال:</b>\n<code>/memory add global default_php | همیشه از PHP مدرن استفاده شود</code>"
if is_fa
else "💡 <i>Usage:</i> <code>/memory add [global|user|project] &lt;key&gt; | &lt;content&gt;</code>"
)
return
p_name = curr_proj.name if (curr_proj and target_type == "project") else "default"
item, is_created = memory_manager.save_or_update(
type_=target_type,
key=key_clean,
content=content_clean,
user_id=chat_id,
project_name=p_name if target_type == "project" else None,
category="rule" if target_type == "global" else "preference",
importance=5 if target_type == "global" else 3,
created_by=chat_id,
)
msg = f"✅ <b>خاطره با موفقیت ثبت شد:</b>\n• 🏷️ بخش: {item.type}\n• 🔑 کلید: <code>{escape_html(item.key)}</code>\n• 📝 محتوا: {escape_html(item.content)}" if is_fa else f"✅ <b>Memory saved:</b> [{item.type}] {item.key}"
text, markup = build_memory_menu(chat_id, view_type=target_type, page=0)
await update.message.reply_html(f"{msg}\n\n{text}", reply_markup=markup)
return
if subcmd in ("clear", "clean", "purge"):
target_type = "global" if len(context.args) > 1 and context.args[1].lower() in ("global", "g") else "private"
target_type = context.args[1].lower() if len(context.args) > 1 else "project"
if target_type not in ("global", "user", "project"):
target_type = "project" if curr_proj else "user"
p_name = curr_proj.name if curr_proj else "default"
try:
cnt = memory_manager.clear_memories(type_=target_type, user_id=chat_id, is_admin=is_admin_user)
type_label = "عمومی" if target_type == "global" else "خصوصی"
cnt = memory_manager.clear_memories(
type_=target_type, user_id=chat_id, project_name=p_name, is_admin=is_admin_user
)
type_label = f"پروژه {p_name}" if target_type == "project" else ("عمومی" if target_type == "global" else "شخصی کاربر")
msg = f"🧹 <b>تعداد {cnt} خاطره {type_label} با موفقیت پاک‌سازی شد.</b>" if is_fa else f"🧹 <b>{cnt} {target_type} memories cleared.</b>"
except PermissionError:
msg = "🚫 <b>خطای دسترسی: فقط ادمین مجاز به پاک‌سازی خاطرات عمومی است.</b>" if is_fa else "🚫 <b>Access denied.</b>"
await update.message.reply_html(msg)
return
text, markup = build_memory_menu(chat_id, view_type="private", page=0)
text, markup = build_memory_menu(chat_id, view_type="project" if curr_proj else "user", page=0)
await update.message.reply_html(text, reply_markup=markup)
@@ -4078,6 +4165,7 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
session = session_manager.get_or_create(chat_id)
curr_proj = session_manager.get_current_project(chat_id)
is_fa = (session.language or "").lower() in ("fa", "farsi", "persian", "🇮🇷 persian / farsi (فارسی)")
is_admin_user = settings.is_admin(chat_id) or settings.is_admin(user_id)
data = query.data
if data == "btn_dashboard":
@@ -5190,8 +5278,15 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
elif data.startswith("mem_clear_do:"):
v_type = data.split(":")[1]
from memory_manager import memory_manager
curr_p = session_manager.get_current_project(chat_id)
p_name = curr_p.name if curr_p else "default"
try:
cnt = memory_manager.clear_memories(type_=v_type, user_id=chat_id, is_admin=is_admin_user)
cnt = memory_manager.clear_memories(
type_=v_type,
user_id=chat_id,
project_name=p_name if v_type == "project" else None,
is_admin=is_admin_user,
)
await query.answer(f"🧹 تعداد {cnt} خاطره پاک شد." if is_fa else f"🧹 Cleared {cnt} memories.")
except PermissionError:
await query.answer("🚫 دسترسی غیرمجاز!" if is_fa else "🚫 Permission denied!", show_alert=True)