diff --git a/projects/8896969833/blog b/projects/8896969833/blog new file mode 160000 index 0000000..98e0e41 --- /dev/null +++ b/projects/8896969833/blog @@ -0,0 +1 @@ +Subproject commit 98e0e41b224a62b121fabfc6c96a07e6c5974c10 diff --git a/projects/8896969833/lt-project_name-gt b/projects/8896969833/lt-project_name-gt new file mode 160000 index 0000000..7f1496c --- /dev/null +++ b/projects/8896969833/lt-project_name-gt @@ -0,0 +1 @@ +Subproject commit 7f1496ce5166909ac2b119336e36e99fdbcd3432 diff --git a/telegram-agy-bot/bot.py b/telegram-agy-bot/bot.py index fdbb6ea..fdeed06 100644 --- a/telegram-agy-bot/bot.py +++ b/telegram-agy-bot/bot.py @@ -1115,6 +1115,10 @@ def build_memory_menu(chat_id: int, view_type: str = "project", page: int = 0) - proj_name = curr_proj.name if curr_proj else "default" + # Non-admin users are strictly forbidden from viewing global memory + if view_type == "global" and not is_admin_user: + view_type = "project" if curr_proj else "user" + # Validate view_type if view_type not in ("project", "user", "global"): view_type = "project" if curr_proj else "user" @@ -1123,8 +1127,11 @@ def build_memory_menu(chat_id: int, view_type: str = "project", page: int = 0) - 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 + elif view_type == "global" and is_admin_user: memories = memory_manager.get_global_memories(limit=100) + else: + memories = memory_manager.get_user_memories(user_id=chat_id, limit=100) + view_type = "user" total_cnt = len(memories) page_size = 5 @@ -1145,11 +1152,15 @@ def build_memory_menu(chat_id: int, view_type: str = "project", page: int = 0) - tab_name = "🌐 قوانین و خاطرات عمومی (کل سرور و کاربران)" tab_desc = "این قوانین برای همه کاربران تزریق می‌شوند (ویرایش و حذف فقط توسط مدیر)." + stats_str = f"{stats['current_project_memories']} پروژه | {stats['current_user_memories']} کاربر" + if is_admin_user: + stats_str += f" | {stats['global_memories']} عمومی" + header = ( - f"🧠 کنترل‌پنل حافظه هوشمند ۳ لایه (AI Memory Dashboard)\n\n" + f"🧠 کنترل‌پنل حافظه هوشمند (AI Memory Dashboard)\n\n" f"• 📂 بخش فعال: {tab_name}\n" f"• ℹ️ {tab_desc}\n" - f"• 📊 آمار: {stats['current_project_memories']} پروژه | {stats['current_user_memories']} کاربر | {stats['global_memories']} عمومی\n\n" + f"• 📊 آمار: {stats_str}\n\n" ) if not memories: body = ( @@ -1176,11 +1187,15 @@ def build_memory_menu(chat_id: int, view_type: str = "project", page: int = 0) - tab_name = "🌐 Global System Memory" tab_desc = "Applies to all users (admin-managed)." + stats_str = f"{stats['current_project_memories']} project | {stats['current_user_memories']} user" + if is_admin_user: + stats_str += f" | {stats['global_memories']} global" + header = ( - f"🧠 3-Tier AI Memory Dashboard\n\n" + f"🧠 AI Memory Dashboard\n\n" f"• 📂 Active Tab: {tab_name}\n" f"• ℹ️ {tab_desc}\n" - f"• 📊 Stats: {stats['current_project_memories']} project | {stats['current_user_memories']} user | {stats['global_memories']} global\n\n" + f"• 📊 Stats: {stats_str}\n\n" ) if not memories: body = "ℹ️ No memories recorded in this section yet." @@ -1199,7 +1214,7 @@ def build_memory_menu(chat_id: int, view_type: str = "project", page: int = 0) - # Build keyboard keyboard = [] - # 1. 3 Tab buttons + # 1. Tab buttons (Global tab only visible to admin) 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 "🌐 عمومی" @@ -1208,11 +1223,13 @@ def build_memory_menu(chat_id: int, view_type: str = "project", page: int = 0) - t_user = "👤 User ✓" if view_type == "user" else "👤 User" t_glob = "🌐 Global ✓" if view_type == "global" else "🌐 Global" - keyboard.append([ + tab_row = [ 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"), - ]) + ] + if is_admin_user: + tab_row.append(InlineKeyboardButton(t_glob, callback_data="mem_tab:global:0")) + keyboard.append(tab_row) # 2. Item delete buttons can_delete_current = (view_type in ("project", "user")) or (view_type == "global" and is_admin_user) @@ -3438,6 +3455,13 @@ async def memory_command(update: Update, context: ContextTypes.DEFAULT_TYPE): return if subcmd in ("global", "g", "public", "system"): + if not is_admin_user: + await update.message.reply_html( + "🚫 خطای دسترسی: مشاهده و مدیریت حافظه عمومی سیستم فقط مختص مدیر است." + if is_fa + else "🚫 Access Denied: Viewing global system memory is restricted to administrators." + ) + return text, markup = build_memory_menu(chat_id, view_type="global", page=0) await update.message.reply_html(text, reply_markup=markup) return @@ -5197,8 +5221,12 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE): elif data == "btn_memory_menu" or data.startswith("mem_tab:"): parts = data.split(":") - v_type = parts[1] if len(parts) > 1 else "private" + v_type = parts[1] if len(parts) > 1 else "project" page_num = int(parts[2]) if len(parts) > 2 and parts[2].isdigit() else 0 + if v_type == "global" and not is_admin_user: + await query.answer("🚫 مشاهده حافظه عمومی فقط برای مدیر سیستم مجاز است." if is_fa else "🚫 Global memory access restricted to administrators.", show_alert=True) + v_type = "project" if session_manager.get_current_project(chat_id) else "user" + page_num = 0 text, markup = build_memory_menu(chat_id, view_type=v_type, page=page_num) try: await query.edit_message_text(text, parse_mode=constants.ParseMode.HTML, reply_markup=markup) @@ -5215,6 +5243,9 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE): await query.answer("❌ خاطره یافت نشد." if is_fa else "❌ Memory not found.", show_alert=True) text, markup = build_memory_menu(chat_id, view_type=v_type, page=p_num) await query.edit_message_text(text, parse_mode=constants.ParseMode.HTML, reply_markup=markup) + elif mem.is_global and not is_admin_user: + await query.answer("🚫 دسترسی غیرمجاز!" if is_fa else "🚫 Permission denied!", show_alert=True) + return else: confirm_text = ( f"🗑️ آیا از حذف این خاطره اطمینان دارید؟\n\n" @@ -5239,6 +5270,10 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE): m_id = int(m_id_str) p_num = int(page_str) from memory_manager import memory_manager + mem = memory_manager.get_by_id(m_id) + if mem and mem.is_global and not is_admin_user: + await query.answer("🚫 دسترسی غیرمجاز!" if is_fa else "🚫 Permission denied!", show_alert=True) + return try: ok = memory_manager.delete_by_id(m_id, user_id=chat_id, is_admin=is_admin_user) if ok: @@ -5258,6 +5293,9 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE): elif data.startswith("mem_clear_conf:"): v_type = data.split(":")[1] + if v_type == "global" and not is_admin_user: + await query.answer("🚫 دسترسی غیرمجاز!" if is_fa else "🚫 Permission denied!", show_alert=True) + return type_label = "عمومی سیستم" if v_type == "global" else "اختصاصی خودتان" confirm_text = ( f"⚠️ هشدار پاک‌سازی حافظه\n\n" @@ -5277,6 +5315,9 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE): elif data.startswith("mem_clear_do:"): v_type = data.split(":")[1] + if v_type == "global" and not is_admin_user: + await query.answer("🚫 دسترسی غیرمجاز!" if is_fa else "🚫 Permission denied!", show_alert=True) + return 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" diff --git a/telegram-agy-bot/data/memory.db b/telegram-agy-bot/data/memory.db index 2778b0c..299f54e 100644 Binary files a/telegram-agy-bot/data/memory.db and b/telegram-agy-bot/data/memory.db differ diff --git a/telegram-agy-bot/memory_manager.py b/telegram-agy-bot/memory_manager.py index b34dfee..4a9890a 100644 --- a/telegram-agy-bot/memory_manager.py +++ b/telegram-agy-bot/memory_manager.py @@ -421,10 +421,13 @@ class MemoryManager: project_name: Optional[str] = None, type_: Optional[str] = None, limit: int = 50, + is_admin: bool = False, ) -> List[MemoryItem]: q = f"%{query.strip().lower()}%" with self._get_connection() as conn: if type_ == "global": + if not is_admin: + return [] cur = conn.execute( """ SELECT * FROM memories @@ -452,16 +455,29 @@ class MemoryManager: (user_id, project_name, q, q, q, limit), ) elif user_id is not None: - cur = conn.execute( - """ - SELECT * FROM memories - WHERE (type = 'global' OR (type IN ('user', 'private') AND user_id = ?) OR (type = 'project' AND user_id = ? AND project_name = ?)) - AND (key LIKE ? OR content LIKE ? OR category LIKE ?) - ORDER BY importance DESC, updated_at DESC LIMIT ? - """, - (user_id, user_id, project_name or "", q, q, q, limit), - ) + if is_admin: + cur = conn.execute( + """ + SELECT * FROM memories + WHERE (type = 'global' OR (type IN ('user', 'private') AND user_id = ?) OR (type = 'project' AND user_id = ? AND project_name = ?)) + AND (key LIKE ? OR content LIKE ? OR category LIKE ?) + ORDER BY importance DESC, updated_at DESC LIMIT ? + """, + (user_id, user_id, project_name or "", q, q, q, limit), + ) + else: + cur = conn.execute( + """ + SELECT * FROM memories + WHERE ((type IN ('user', 'private') AND user_id = ?) OR (type = 'project' AND user_id = ? AND project_name = ?)) + AND (key LIKE ? OR content LIKE ? OR category LIKE ?) + ORDER BY importance DESC, updated_at DESC LIMIT ? + """, + (user_id, user_id, project_name or "", q, q, q, limit), + ) else: + if not is_admin: + return [] cur = conn.execute( """ SELECT * FROM memories diff --git a/telegram-agy-bot/sessions.json b/telegram-agy-bot/sessions.json index 02c7c21..1092f19 100644 --- a/telegram-agy-bot/sessions.json +++ b/telegram-agy-bot/sessions.json @@ -45,9 +45,9 @@ "model": "gemini-3.7-flash-auto", "effort": "high", "language": "fa", - "last_context_length": null, - "last_total_tokens": null, - "last_response": null, + "last_context_length": 19659, + "last_total_tokens": 179449, + "last_response": "", "created_at": 1787995349.975879, "description": "" }, @@ -74,19 +74,19 @@ } }, "turn_in_progress": true, - "last_prompt": "\u0631\u0628\u0627\u062a \u0631\u0627 \u0627\u0635\u0644\u0627\u062d \u06a9\u0646\n\u0648\u0642\u062a\u06cc \u06cc\u0647 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0645\u06cc\u0627\u062f \u0648 \u067e\u0631\u0648\u0698\u0647 \u062c\u062f\u06cc\u062f \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u06a9\u0646\u0647\n\u0647\u0648\u0634 \u0645\u0635\u0646\u0648\u0639\u06cc \u062f\u06cc\u0641\u0627\u0644\u062a \u0622\u0646 \u0631\u0648\u06cc \u0627\u062a\u0648\u0645\u0627\u062a\u06cc\u06a9 \u0641\u0644\u0634 \u0628\u0627\u0634\u062f", + "last_prompt": "\u06a9\u062f\u0647\u0627\u06cc \u0631\u0628\u0627\u062a \u0631\u0627 \u0627\u0635\u0644\u0627\u062d \u06a9\u0646\n\u0647\u06cc\u0686 \u06a9\u0627\u0631\u0628\u0631\u06cc \u06cc\u0647 \u063a\u06cc\u0631 \u0627\u0632 \u0645\u062f\u06cc\u0631\n\u062d\u0642 \u0645\u0634\u0627\u062f\u0647 \u062d\u0627\u0641\u0638\u0647 \u0639\u0645\u0648\u0645\u06cc \u0631\u0627 \u0647\u0645 \u0646\u062f\u0627\u0631\u062f", "last_response": "", - "last_status_msg_id": 1425, + "last_status_msg_id": 1430, "restart_pending": false, "last_delivered": false, - "last_update_time": 1788073778.2107773, + "last_update_time": 1788074014.25397, "workspace": "/root", "conversation_id": "1af266cc-8075-4333-b557-0ad2918fd8f0", "model": "gemini-3.7-flash-auto", "effort": "high", "language": "fa", - "last_context_length": null, - "last_total_tokens": null + "last_context_length": 19659, + "last_total_tokens": 179449 }, "232801087": { "chat_id": 232801087, @@ -160,40 +160,73 @@ }, "8896969833": { "chat_id": 8896969833, - "active_project": "test", + "active_project": "blog", "projects": { "test": { "name": "test", "workspace": "/root/projects/8896969833/test", "owner_id": 8896969833, "shared_with": [], - "conversation_id": "3f7359a9-d339-46f5-bb36-efc7cd6b6db7", + "conversation_id": "4523f854-7f58-49a5-9405-00794f746106", "conversation_history": [ - "3f7359a9-d339-46f5-bb36-efc7cd6b6db7" + "3f7359a9-d339-46f5-bb36-efc7cd6b6db7", + "4523f854-7f58-49a5-9405-00794f746106" ], - "model": "gemini-3.7-flash", + "model": "gemini-3.7-flash-auto", "effort": "high", "language": "fa", - "last_context_length": 6927, - "last_total_tokens": 85645, - "last_response": "\u062f\u0631 \u062d\u0627\u0644 \u062d\u0627\u0636\u0631 \u0631\u0648\u06cc \u067e\u0631\u0648\u0698\u0647 **`test`** \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u06cc\u0645:\n\n### \ud83d\udccb \u0645\u0634\u062e\u0635\u0627\u062a \u0648\u0636\u0639\u06cc\u062a \u0641\u0639\u0644\u06cc:\n- **\u0646\u0627\u0645 \u067e\u0631\u0648\u0698\u0647 \u0641\u0639\u0627\u0644:** `test`\n- **\u0645\u0633\u06cc\u0631 \u0645\u062d\u06cc\u0637 \u06a9\u0627\u0631\u06cc (Workspace):** `/root/projects/8896969833/test`\n- **\u0645\u062f\u0644 \u0641\u0639\u0627\u0644:** `Gemini 3.7 Flash` (\u0633\u0637\u062d \u0627\u0633\u062a\u062f\u0644\u0627\u0644: High)\n- **\u0647\u062f\u0641/\u0645\u0648\u0636\u0648\u0639 \u06af\u0641\u062a\u06af\u0648:** \u062f\u0631 \u067e\u06cc\u0627\u0645 \u0642\u0628\u0644\u06cc \u0641\u0631\u0645\u0648\u062f\u06cc\u062f \u06a9\u0647 \u0642\u0635\u062f \u062f\u0627\u0631\u06cc\u062f **\u06a9\u062f \u0648 \u0633\u0627\u062e\u062a\u0627\u0631 \u062e\u0648\u062f \u0631\u0628\u0627\u062a \u062a\u0644\u06af\u0631\u0627\u0645 (\u06a9\u0646\u062a\u0631\u0644\u200c\u06af\u0631 \u0647\u0648\u0634 \u0645\u0635\u0646\u0648\u0639\u06cc)** \u0645\u0633\u062a\u0642\u0631 \u062f\u0631 `/root/telegram-agy-bot` \u0631\u0627 \u0648\u06cc\u0631\u0627\u06cc\u0634 \u0648 \u0634\u062e\u0635\u06cc\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u062f.\n\n---\n\u0627\u06af\u0631 \u0645\u0627\u06cc\u0644\u06cc\u062f \u067e\u0631\u0648\u0698\u0647 \u062c\u062f\u06cc\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u0645 \u06cc\u0627 \u0631\u0648\u06cc \u067e\u0631\u0648\u0698\u0647 \u062e\u0627\u0635\u06cc \u0633\u0648\u0626\u06cc\u0686 \u06a9\u0646\u06cc\u0645\u060c \u06cc\u0627 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0628\u062e\u0634 \u062e\u0627\u0635\u06cc \u0627\u0632 \u06a9\u062f \u0631\u0628\u0627\u062a \u0631\u0627 \u0648\u06cc\u0631\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u0645\u060c \u0628\u0641\u0631\u0645\u0627\u06cc\u06cc\u062f \u062a\u0627 \u0627\u0642\u062f\u0627\u0645 \u06a9\u0646\u0645.\n", + "last_context_length": 2013, + "last_total_tokens": 18984, + "last_response": "\u0645\u062a\u0646 \u06a9\u0627\u0645\u0644 \u0648 \u062f\u0642\u06cc\u0642\u06cc \u06a9\u0647 \u062f\u0631 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0634\u0645\u0627 (\u0634\u0627\u0645\u0644 \u062a\u0645\u0627\u0645\u06cc \u062f\u0633\u062a\u0648\u0631\u0627\u0644\u0639\u0645\u0644\u200c\u0647\u0627\u06cc \u0633\u06cc\u0633\u062a\u0645\u06cc\u060c \u0627\u06a9\u0634\u0646\u200c\u062a\u06af\u200c\u0647\u0627\u06cc \u0631\u0628\u0627\u062a \u062a\u0644\u06af\u0631\u0627\u0645\u060c \u0642\u0648\u0627\u0646\u06cc\u0646 \u0648 \u062d\u0627\u0641\u0638\u0647\u200c\u0647\u0627\u06cc \u0639\u0645\u0648\u0645\u06cc \u062a\u0632\u0631\u06cc\u0642\u200c\u0634\u062f\u0647) \u0627\u0631\u0633\u0627\u0644 \u0634\u062f\u0647 \u0627\u0633\u062a\u060c \u0628\u0647 \u0634\u0631\u062d \u0632\u06cc\u0631 \u0627\u0633\u062a:\n\n```text\n[SYSTEM INSTRUCTION: You MUST respond and communicate in Persian / Farsi (\u0641\u0627\u0631\u0633\u06cc). All answers, greetings, comments, and explanations must be strictly written in Persian / Farsi (\u0641\u0627\u0631\u0633\u06cc), unless code syntax or the user explicitly specifies another language.]\n\n[SYSTEM INSTRUCTION: TELEGRAM BOT ACTIONS & FUNCTION CALLING]\nYou have complete access and authority to control and invoke ALL Telegram Bot features, project settings, model parameters, scheduled tasks, reverse proxies, and server operations directly from your conversation.\nWhenever the user asks (in Persian, English, or any language) to change settings, switch models, create or manage projects, schedule periodic tasks, configure subdomains on Caddy, export backups, restart the bot, or send files:\nYou MUST output the corresponding action tag(s) anywhere in your reply. You can combine multiple action tags in a single reply if necessary.\n\nAVAILABLE ACTION TAGS & SYNTAX:\n1. Change AI Model for Project:\n [[SET_MODEL: model=\"\", project=\"\"]]\n Available models: 'gemini-3.7-flash-auto' (Gemini 3.7 Flash Auto Reasoning \u26a1/\ud83e\udde0 - \u0627\u0631\u0632\u06cc\u0627\u0628\u06cc \u0647\u0648\u0634\u0645\u0646\u062f \u062e\u0648\u062f\u06a9\u0627\u0631), 'gemini-3.7-flash' (Gemini 3.7 Flash), 'gemini-3.7-flash-high' (Gemini 3.7 Flash High), 'gemini-3.1-pro' (Gemini 3.1 Pro), 'gemini-3.6-flash', 'claude-sonnet-4-6' (Claude Sonnet 4.6 Thinking), 'claude-opus-4-6-thinking' (Claude Opus 4.6 Thinking), 'gpt-oss-120b'.\n Example: [[SET_MODEL: model=\"gemini-3.7-flash-auto\"]]\n\n2. Change Reasoning Effort Level:\n [[SET_EFFORT: effort=\"low|medium|high\", project=\"\"]]\n Example: [[SET_EFFORT: effort=\"high\"]]\n\n3. Change Bot Language:\n [[SET_LANG: lang=\"fa|en|auto|...\"]]\n Example: [[SET_LANG: lang=\"fa\"]]\n\n4. Create New Project:\n [[NEW_PROJECT: name=\"\", workspace=\"\", model=\"\", effort=\"\"]]\n (Directory `/root/projects/{user_id}/{name}` is created automatically).\n Example: [[NEW_PROJECT: name=\"blog\"]]\n\n5. Switch Active Project:\n [[SWITCH_PROJECT: name=\"\"]]\n Example: [[SWITCH_PROJECT: name=\"blog\"]]\n\n6. Delete Project (Comprehensive Teardown & Resource Release):\n [[DELETE_PROJECT: name=\"\", delete_files=true|false]]\n (Automatically performs comprehensive teardown: releases Caddy subdomains/proxies, stops background processes/ports, removes systemd services, cancels scheduled cron tasks, deletes Gitea git repository, and purges physical files).\n Example: [[DELETE_PROJECT: name=\"old-project\", delete_files=true]]\n\n7. Rename Project:\n [[RENAME_PROJECT: old_name=\"\", new_name=\"\"]]\n\n8. Set Custom Workspace Directory:\n [[SET_WORKSPACE: path=\"/path/to/folder\", project=\"\"]]\n\n9. Share / Unshare Project:\n [[SHARE_PROJECT: user_id=, project=\"\"]]\n [[UNSHARE_PROJECT: user_id=, project=\"\"]]\n\n10. Reset / Clear Conversation Context:\n [[RESET_CONVERSATION: project=\"\"]]\n\n11. Switch / Delete / Clear Conversations:\n [[SWITCH_CONVERSATION: id=\"\"]]\n [[DELETE_CONVERSATION: id=\"\"]]\n [[CLEAR_CONVERSATIONS: project=\"\"]]\n\n12. Schedule Task / Timers / Cron:\n [[SCHEDULE_TASK: timing=\"\", max_runs=, type=\"prompt|command|reminder\", title=\"\", content=\"\"]]\n Timing examples: 'every 10m', 'in 15m', '14:30', 'cron: 0 23 * * *', 'every 1h (3 times)'.\n Types: 'prompt' (AI run), 'command' (bash script), 'reminder' (plain notification).\n [[CANCEL_TASK: id=\"\"]]\n [[PAUSE_TASK: id=\"\"]]\n [[RESUME_TASK: id=\"\"]]\n\n13. Project Backup & Export (Zip):\n [[BACKUP_PROJECT: project=\"\"]]\n\n14. Send File / Photo / Audio to Telegram:\n [[SEND_FILE: path=\"/path/to/file.ext\", caption=\"\"]]\n [[SEND_PHOTO: path=\"/path/to/image.png\", caption=\"\"]]\n [[SEND_AUDIO: path=\"/path/to/audio.mp3\", caption=\"\"]]\n\n15. Configure Subdomain & Caddy HTTPS Reverse Proxy (*.msa.artacloud.ir):\n [[SETUP_SUBDOMAIN: subdomain=\"\", port=]]\n Automatically links `{subdomain}.msa.artacloud.ir` to `localhost:{port}` with free SSL.\n [[REMOVE_SUBDOMAIN: subdomain=\"\"]]\n\n16. Git Version Control & Gitea Integration:\n [[GIT_SYNC: project=\"\", message=\"\"]]\n (Pulls remote changes from Gitea, commits any local modifications, and pushes to main branch).\n [[GIT_COMMIT: message=\"\", project=\"\"]]\n [[GIT_INIT: project=\"\"]]\n\n17. Restart Telegram Bot Service:\n [[RESTART_BOT]]\n\n18. Long-Term AI Memory Management (3-Tier: User & Project):\n [[SAVE_MEMORY: type=\"user|project\", key=\"\", category=\"\", content=\"\"]]\n (Use type='user' for personal user profile/habits, or type='project' for current project architecture/decisions. Global memory is read-only for AI).\n [[UPDATE_MEMORY: type=\"user|project\", key=\"\", content=\"\"]]\n [[DELETE_MEMORY: type=\"user|project\", key=\"\"]]\n [[CLEAR_MEMORY: type=\"user|project\"]]\n\nAlways explain to the user in a friendly and professional tone what actions have been performed.\n\n[SYSTEM INSTRUCTION: AI PERSISTENT HIERARCHICAL MEMORY & CONTINUOUS LEARNING]\nYou have access to persistent 3-tier long-term memory containing verified system rules, project context, and user profile.\nUse this knowledge to maintain continuity and customize all your responses accordingly.\n\n\u2696\ufe0f STRICT PRECEDENCE HIERARCHY (\u0633\u0644\u0633\u0644\u0647\u0645\u0631\u0627\u062a\u0628 \u0642\u0637\u0639\u06cc \u0627\u0648\u0644\u0648\u06cc\u062a \u0648 \u062d\u0644 \u062a\u0639\u0627\u0631\u0636):\n1. \ud83e\udd47 Tier 1 (Highest Authority): Global System Rules ALWAYS strictly supersede all Project and User instructions.\n2. \ud83e\udd48 Tier 2 (Intermediate Authority): Active Project Knowledge & Rules ALWAYS supersede general User preferences inside this project.\n3. \ud83e\udd49 Tier 3 (Baseline Authority): User Personal Preferences apply across projects as defaults when not overridden by Project or Global rules.\n\n\ud83c\udf10 1. GLOBAL SYSTEM RULES & KNOWLEDGE (\u0642\u0648\u0627\u0646\u06cc\u0646 \u0639\u0645\u0648\u0645\u06cc \u0633\u06cc\u0633\u062a\u0645 - \u0628\u0627\u0644\u0627\u062a\u0631\u06cc\u0646 \u0627\u0648\u0644\u0648\u06cc\u062a):\n\u2022 [key: precedence_hierarchy] [rule] \u0633\u0644\u0633\u0644\u0647\u0645\u0631\u0627\u062a\u0628 \u0642\u0637\u0639\u06cc \u0627\u0648\u0644\u0648\u06cc\u062a \u062f\u0633\u062a\u0648\u0631\u0627\u062a: \u06f1. \u0642\u0648\u0627\u0646\u06cc\u0646 \u0639\u0645\u0648\u0645\u06cc \u0633\u06cc\u0633\u062a\u0645 \u06f2. \u062e\u0627\u0637\u0631\u0627\u062a \u0648 \u062a\u0635\u0645\u06cc\u0645\u0627\u062a \u0627\u062e\u062a\u0635\u0627\u0635\u06cc \u0647\u0631 \u067e\u0631\u0648\u0698\u0647 \u06f3. \u062a\u0631\u062c\u06cc\u062d\u0627\u062a \u06a9\u0644\u06cc \u06a9\u0627\u0631\u0628\u0631.\n\u2022 [key: projects_directory_structure] [rule] \u067e\u0631\u0648\u0698\u0647\u0647\u0627 \u062a\u0646\u0647\u0627 \u0628\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0635\u0631\u06cc\u062d \u06a9\u0627\u0631\u0628\u0631 \u0648 \u062f\u0631 \u0633\u0627\u062e\u062a\u0627\u0631 /root/projects/{user_id}/{project_name} \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u0634\u0648\u0646\u062f.\n\u2022 [key: server_domain_caddy] [rule] \u062f\u0627\u0645\u0646\u0647 *.msa.artacloud.ir \u0628\u0647 \u0633\u0631\u0648\u0631 \u0645\u062a\u0635\u0644 \u0627\u0633\u062a \u0648 Caddy \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 Reverse Proxy \u0628\u0631\u0627\u06cc \u062a\u0645\u0627\u0645 \u067e\u0631\u0648\u0698\u0647\u0647\u0627\u060c API\u0647\u0627 \u0648 \u0648\u0628\u0647\u0648\u06a9\u0647\u0627 \u0628\u0627 SSL \u062e\u0648\u062f\u06a9\u0627\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc\u0634\u0648\u062f.\n\u2022 [key: php_preference] [rule] \u0647\u0645\u06cc\u0634\u0647 \u0628\u0631\u0627\u06cc \u0647\u0631 \u067e\u0631\u0648\u0698\u0647 \u062f\u0631 \u0635\u0648\u0631\u062a \u0627\u0645\u06a9\u0627\u0646 \u0627\u0632 PHP (PHP 8.x \u0645\u062f\u0631\u0646 / \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a\u0647\u0627 \u0648 \u0641\u0631\u06cc\u0645\u0648\u0631\u06a9\u0647\u0627\u06cc PHP) \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0632\u0628\u0627\u0646 \u0627\u0635\u0644\u06cc \u0648 \u067e\u06cc\u0634\u0641\u0631\u0636 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u0648\u062f.\n\u2022 [key: server_rule] [rule] \u0647\u0645\u06cc\u0634\u0647 \u0633\u0631\u0648\u06cc\u0633\u0647\u0627\u06cc \u0648\u0628 \u0631\u0648\u06cc \u062f\u0627\u0645\u0646\u0647 msa.artacloud.ir \u0628\u0627 Caddy \u062a\u0646\u0638\u06cc\u0645 \u0634\u0648\u0646\u062f.\n\u2022 [key: flash_auto_mode] [rule] \u062f\u0631 \u062d\u0627\u0644\u062a Flash Auto\u060c \u0628\u0627\u0632\u0628\u06cc\u0646\u06cc \u0646\u0647\u0627\u06cc\u06cc \u0648 \u0639\u06cc\u0628\u06cc\u0627\u0628\u06cc\u0647\u0627 \u0628\u0627 \u0628\u0627\u0644\u0627\u062a\u0631\u06cc\u0646 \u0633\u0637\u062d \u0627\u0633\u062a\u062f\u0644\u0627\u0644 \u0645\u062f\u0644 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc\u0634\u0648\u062f.\n\n\ud83e\udde0 AUTONOMOUS MEMORY MANAGEMENT RULES:\n1. When user shares durable facts, choose the appropriate tier:\n \u2022 User-level (developer habits, preferred tools, personal info): type=\"user\"\n \u2022 Project-level (architecture, database schema, libraries, API designs, fixed bugs in this project): type=\"project\"\n Action Tag: [[SAVE_MEMORY: type=\"user|project\", key=\"\", category=\"preference|rule|tech_stack|fact\", content=\"\"]]\n2. Note: Global memory is read-only for AI and managed exclusively by system administrators via the Telegram Bot UI.\n3. If past memory is superseded, update it: [[UPDATE_MEMORY: type=\"user|project\", key=\"\", content=\"\"]].\n4. If user asks to forget something: [[DELETE_MEMORY: type=\"user|project\", key=\"\"]].\n5. Do NOT store temporary or trivial small-talk. Only store enduring and valuable knowledge.\n\n\u062f\u0642\u06cc\u0642\u0627 \u0628\u0647\u0645 \u0628\u06af\u0648 \u0645\u062a\u0646 \u0627\u0631\u0633\u0627\u0644\u06cc \u0645\u0646 \u0628\u0647 \u062a\u0648 \u0686\u0647 \u0628\u0648\u062f\u061f \u0645\u062a\u0646 \u06a9\u0627\u0645\u0644 \u0628\u0627 \u062a\u0645\u0627\u0645 \u062d\u0627\u0641\u0638\u0647 \u0647\u0627\n```\n", "created_at": 1788069553.9717174, "description": "" + }, + "lt-project_name-gt": { + "name": "lt-project_name-gt", + "workspace": "/root/projects/8896969833/lt-project_name-gt", + "owner_id": 8896969833, + "shared_with": [], + "conversation_id": null, + "conversation_history": [], + "model": "gemini-3.7-flash-auto", + "effort": "high", + "language": "fa", + "last_context_length": null, + "last_total_tokens": null, + "last_response": null, + "created_at": 1788074106.5233963, + "description": "" + }, + "blog": { + "name": "blog", + "workspace": "/path/to/folder", + "owner_id": 8896969833, + "shared_with": [], + "conversation_id": null, + "conversation_history": [], + "model": "gemini-3.7-flash-auto", + "effort": "high", + "language": "fa", + "last_context_length": null, + "last_total_tokens": null, + "last_response": null, + "created_at": 1788074120.0401065, + "description": "" } }, "turn_in_progress": false, - "last_prompt": "\u0631\u0648\u06cc \u0686\u0647 \u067e\u0631\u0648\u0698\u0647 \u0627\u06cc \u06a9\u0627\u0631 \u0645\u06cc\u06a9\u0631\u062f\u06cc\u0645\u061f", - "last_response": "\u062f\u0631 \u062d\u0627\u0644 \u062d\u0627\u0636\u0631 \u0631\u0648\u06cc \u067e\u0631\u0648\u0698\u0647 **`test`** \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u06cc\u0645:\n\n### \ud83d\udccb \u0645\u0634\u062e\u0635\u0627\u062a \u0648\u0636\u0639\u06cc\u062a \u0641\u0639\u0644\u06cc:\n- **\u0646\u0627\u0645 \u067e\u0631\u0648\u0698\u0647 \u0641\u0639\u0627\u0644:** `test`\n- **\u0645\u0633\u06cc\u0631 \u0645\u062d\u06cc\u0637 \u06a9\u0627\u0631\u06cc (Workspace):** `/root/projects/8896969833/test`\n- **\u0645\u062f\u0644 \u0641\u0639\u0627\u0644:** `Gemini 3.7 Flash` (\u0633\u0637\u062d \u0627\u0633\u062a\u062f\u0644\u0627\u0644: High)\n- **\u0647\u062f\u0641/\u0645\u0648\u0636\u0648\u0639 \u06af\u0641\u062a\u06af\u0648:** \u062f\u0631 \u067e\u06cc\u0627\u0645 \u0642\u0628\u0644\u06cc \u0641\u0631\u0645\u0648\u062f\u06cc\u062f \u06a9\u0647 \u0642\u0635\u062f \u062f\u0627\u0631\u06cc\u062f **\u06a9\u062f \u0648 \u0633\u0627\u062e\u062a\u0627\u0631 \u062e\u0648\u062f \u0631\u0628\u0627\u062a \u062a\u0644\u06af\u0631\u0627\u0645 (\u06a9\u0646\u062a\u0631\u0644\u200c\u06af\u0631 \u0647\u0648\u0634 \u0645\u0635\u0646\u0648\u0639\u06cc)** \u0645\u0633\u062a\u0642\u0631 \u062f\u0631 `/root/telegram-agy-bot` \u0631\u0627 \u0648\u06cc\u0631\u0627\u06cc\u0634 \u0648 \u0634\u062e\u0635\u06cc\u200c\u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u062f.\n\n---\n\u0627\u06af\u0631 \u0645\u0627\u06cc\u0644\u06cc\u062f \u067e\u0631\u0648\u0698\u0647 \u062c\u062f\u06cc\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u0645 \u06cc\u0627 \u0631\u0648\u06cc \u067e\u0631\u0648\u0698\u0647 \u062e\u0627\u0635\u06cc \u0633\u0648\u0626\u06cc\u0686 \u06a9\u0646\u06cc\u0645\u060c \u06cc\u0627 \u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u0628\u062e\u0634 \u062e\u0627\u0635\u06cc \u0627\u0632 \u06a9\u062f \u0631\u0628\u0627\u062a \u0631\u0627 \u0648\u06cc\u0631\u0627\u06cc\u0634 \u06a9\u0646\u06cc\u0645\u060c \u0628\u0641\u0631\u0645\u0627\u06cc\u06cc\u062f \u062a\u0627 \u0627\u0642\u062f\u0627\u0645 \u06a9\u0646\u0645.\n", - "last_status_msg_id": null, + "last_prompt": null, + "last_response": null, + "last_status_msg_id": 1432, "restart_pending": false, - "last_delivered": true, - "last_update_time": 1788073577.193658, - "workspace": "/root/projects/8896969833/test", - "conversation_id": "3f7359a9-d339-46f5-bb36-efc7cd6b6db7", - "model": "gemini-3.7-flash", + "last_delivered": false, + "last_update_time": 1788074090.2327929, + "workspace": "/path/to/folder", + "conversation_id": null, + "model": "gemini-3.7-flash-auto", "effort": "high", "language": "fa", - "last_context_length": 6927, - "last_total_tokens": 85645 + "last_context_length": null, + "last_total_tokens": null } } \ No newline at end of file