From fd26e4e0a8a3f1cbadb1dc8e26f03fbd8284ac3d Mon Sep 17 00:00:00 2001 From: Antigravity Bot Date: Sun, 30 Aug 2026 16:19:39 +0330 Subject: [PATCH] =?UTF-8?q?AI=20Update:=20=D8=A7=D9=84=D8=A7=D9=86=20?= =?UTF-8?q?=DA=A9=D8=AC=D8=A7=DB=8C=DB=8C=D9=85=D8=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- telegram-agy-bot/agy_engine.py | 93 ++++++++++++++++++++-------------- telegram-agy-bot/bot.py | 8 +-- telegram-agy-bot/sessions.json | 58 ++++++++------------- 3 files changed, 81 insertions(+), 78 deletions(-) diff --git a/telegram-agy-bot/agy_engine.py b/telegram-agy-bot/agy_engine.py index 9052437..3670f68 100644 --- a/telegram-agy-bot/agy_engine.py +++ b/telegram-agy-bot/agy_engine.py @@ -856,51 +856,81 @@ class SessionManager: def switch_conversation(self, chat_id: int, conv_id: str) -> tuple[bool, str, Dict[str, Any]]: session = self.get_or_create(chat_id) curr = self.get_current_project(chat_id) - if not curr: - return False, "⚠️ پروژه‌ای یافت نشد.", {} - clean_id = str(conv_id).strip() - convs = self.get_project_conversations(chat_id) matched_cid = None + target_proj = curr - if clean_id.isdigit(): - idx = int(clean_id) - 1 - if 0 <= idx < len(convs): - matched_cid = convs[idx]["id"] + # 1. First check if it's a numeric index or ID in current project's conversation list + if curr: + convs = self.get_project_conversations(chat_id) + if clean_id.isdigit(): + idx = int(clean_id) - 1 + if 0 <= idx < len(convs): + matched_cid = convs[idx]["id"] + if not matched_cid: + for c in convs: + if c["id"] == clean_id or c["id"].lower().startswith(clean_id.lower()): + matched_cid = c["id"] + break + + if not matched_cid: + for c_id in curr.conversation_history: + if c_id == clean_id or (c_id and c_id.lower().startswith(clean_id.lower())): + matched_cid = c_id + break + + # 2. If not found in current project, search across all accessible projects of this user if not matched_cid: - for c in convs: - if c["id"] == clean_id or c["id"].lower().startswith(clean_id.lower()): - matched_cid = c["id"] - break - - if not matched_cid: - for c_id in curr.conversation_history: - if c_id == clean_id or (c_id and c_id.lower().startswith(clean_id.lower())): - matched_cid = c_id + accessible = self.get_all_accessible_projects(chat_id) + for p_name, p_obj in accessible.items(): + all_p_cids = list(p_obj.conversation_history) + if p_obj.conversation_id and p_obj.conversation_id not in all_p_cids: + all_p_cids.append(p_obj.conversation_id) + + for c_id in all_p_cids: + if c_id == clean_id or (c_id and c_id.lower().startswith(clean_id.lower())): + matched_cid = c_id + target_proj = p_obj + break + if matched_cid: break + # 3. Fallback: check if valid conversation exists on disk if not matched_cid: meta = get_conversation_metadata(clean_id) if meta.get("file_exists"): matched_cid = clean_id + target_proj = curr - if not matched_cid: + if not matched_cid or not target_proj: return False, f"⚠️ گفتگویی با شناسه یا شماره «{clean_id}» یافت نشد.", {} + # If switching to a conversation belonging to another project, automatically switch active project + project_switched = False + if session.active_project != target_proj.name: + session.active_project = target_proj.name + project_switched = True + meta = get_conversation_metadata(matched_cid) - if curr.conversation_id and curr.conversation_id != matched_cid and curr.conversation_id not in curr.conversation_history: - curr.conversation_history.append(curr.conversation_id) + if target_proj.conversation_id and target_proj.conversation_id != matched_cid and target_proj.conversation_id not in target_proj.conversation_history: + target_proj.conversation_history.append(target_proj.conversation_id) - curr.conversation_id = matched_cid - if matched_cid not in curr.conversation_history: - curr.conversation_history.append(matched_cid) + target_proj.conversation_id = matched_cid + if matched_cid not in target_proj.conversation_history: + target_proj.conversation_history.append(matched_cid) output_data = get_conversation_last_output(matched_cid) - curr.last_response = output_data.get("text") or meta.get("last_response") + target_proj.last_response = output_data.get("text") or meta.get("last_response") self.save() - return True, f"✅ با موفقیت به گفتگوی {matched_cid[:8]}... سوییچ کردید.", meta + + if project_switched: + msg = f"✅ با موفقیت به گفتگوی {matched_cid[:8]}... در پروژه {escape_html(target_proj.name)} سوییچ کردید." + else: + msg = f"✅ با موفقیت به گفتگوی {matched_cid[:8]}... سوییچ کردید." + + return True, msg, meta def delete_conversation(self, chat_id: int, conv_id: str) -> tuple[bool, str]: session = self.get_or_create(chat_id) @@ -1069,19 +1099,6 @@ class SessionManager: if curr.conversation_id and curr.conversation_id not in conv_ids: conv_ids.append(curr.conversation_id) - # For admin or default project, also discover existing brain directories if list is small - is_admin_user = settings.is_admin(chat_id) - if is_admin_user or curr.name == "default" or len(conv_ids) < 3: - try: - brain_p = Path("/root/.gemini/antigravity-cli/brain") - if brain_p.exists(): - for d in brain_p.iterdir(): - if d.is_dir() and len(d.name) > 30 and (d / ".system_generated/logs/transcript.jsonl").exists(): - if d.name not in conv_ids: - conv_ids.append(d.name) - except Exception as e: - logger.debug(f"Error scanning brain dir: {e}") - result = [] titles_map = getattr(curr, "conversation_titles", {}) or {} for cid in conv_ids: diff --git a/telegram-agy-bot/bot.py b/telegram-agy-bot/bot.py index 192dcdd..2f545d8 100644 --- a/telegram-agy-bot/bot.py +++ b/telegram-agy-bot/bot.py @@ -3134,14 +3134,15 @@ async def switch_conv_command(update: Update, context: ContextTypes.DEFAULT_TYPE await update.message.reply_html(msg_text) return - target_cid = curr_proj.conversation_id or target + curr_proj = session_manager.get_current_project(chat_id) + target_cid = (curr_proj.conversation_id if curr_proj else target) or target first_prompt = meta.get("first_prompt") or "(شروع مکالمه)" turns = meta.get("turns_count", 0) if is_fa: text = ( f"💬 با موفقیت به گفتگو سوییچ کردید!\n\n" - f"• 📁 پروژه فعال: {escape_html(curr_proj.name)}\n" + f"• 📁 پروژه فعال: {escape_html(curr_proj.name if curr_proj else 'default')}\n" f"• 💬 شناسه مکالمه فعال: {target_cid}\n" f"• 🔢 تعداد نوبت‌ها: {turns} نوبت\n" f"• 📝 موضوع/اولین پیام: {escape_html(first_prompt[:120])}\n\n" @@ -5323,13 +5324,14 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE): if not success: await query.answer(strip_ansi(msg_text), show_alert=True) return + curr_proj = session_manager.get_current_project(chat_id) await query.answer("✅ گفتگو با موفقیت تغییر یافت.") first_prompt = meta.get("first_prompt") or "(شروع مکالمه)" turns = meta.get("turns_count", 0) if is_fa: text = ( f"💬 گفتگو تغییر یافت!\n\n" - f"• 📁 پروژه فعال: {escape_html(curr_proj.name)}\n" + f"• 📁 پروژه فعال: {escape_html(curr_proj.name if curr_proj else 'default')}\n" f"• 💬 شناسه مکالمه فعال: {target_cid}\n" f"• 🔢 تعداد نوبت‌ها: {turns} نوبت\n" f"• 📝 موضوع/اولین پیام: {escape_html(first_prompt[:120])}\n\n" diff --git a/telegram-agy-bot/sessions.json b/telegram-agy-bot/sessions.json index ba5c784..3aa6154 100644 --- a/telegram-agy-bot/sessions.json +++ b/telegram-agy-bot/sessions.json @@ -1,59 +1,43 @@ { "78649634": { "chat_id": 78649634, - "active_project": "copykar", + "active_project": "default", "projects": { "default": { "name": "default", "workspace": "/root", "owner_id": 78649634, "shared_with": [], - "conversation_id": "91a25f26-0939-44f5-a90e-3b7432c17580", + "conversation_id": "0c1bd37f-4121-422c-aa1c-49b0c7345e7a", "conversation_history": [ - "4acc374a-5742-40fe-b5ec-b8b3d1b14e68", - "53d25c60-73ee-4c35-a218-a52e3d11817e", - "b0235b6f-a4af-4526-a344-b48e92fd1a08", - "ad39c983-09f1-4042-889f-681049b0de26", - "91a25f26-0939-44f5-a90e-3b7432c17580" + "0c1bd37f-4121-422c-aa1c-49b0c7345e7a" ], "model": "gemini-3.7-flash-auto", "effort": "high", "language": "fa", - "last_context_length": 7635, - "last_total_tokens": 93876, - "last_response": "", + "last_context_length": 1986, + "last_total_tokens": 31891, + "last_response": "\u062f\u0631 \u062d\u0627\u0644 \u062d\u0627\u0636\u0631 \u062f\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0627\u0635\u0644\u06cc \u0631\u0648\u062a \u0633\u0631\u0648\u0631 (`/root`) \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u06cc\u0645.\n\n### \ud83d\udccd \u0648\u0636\u0639\u06cc\u062a \u0641\u0639\u0644\u06cc \u0633\u06cc\u0633\u062a\u0645 \u0648 \u0645\u062d\u06cc\u0637 \u06a9\u0627\u0631\u06cc:\n* **\u0645\u062d\u06cc\u0637 \u0641\u0639\u0627\u0644:** \u0631\u0648\u062a \u0633\u0631\u0648\u0631 (`/root`)\n* **\u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627\u06cc \u0627\u0635\u0644\u06cc:**\n * \u0631\u0628\u0627\u062a \u062a\u0644\u06af\u0631\u0627\u0645: `/root/telegram-agy-bot`\n * \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646: `/root/projects/`\n* **\u0645\u062f\u0644 \u0647\u0648\u0634 \u0645\u0635\u0646\u0648\u0639\u06cc:** Gemini 3.7 Flash (\u062d\u0627\u0644\u062a Flash Auto Reasoning)\n\n\u0627\u06af\u0631 \u0645\u0627\u06cc\u0644\u06cc\u062f \u0631\u0648\u06cc \u067e\u0631\u0648\u0698\u0647 \u062e\u0627\u0635\u06cc \u06a9\u0627\u0631 \u06a9\u0646\u06cc\u0645\u060c \u067e\u0631\u0648\u0698\u0647 \u062c\u062f\u06cc\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u0645 \u06cc\u0627 \u0648\u0636\u0639\u06cc\u062a \u062e\u0627\u0635\u06cc \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645\u060c \u0628\u0641\u0631\u0645\u0627\u06cc\u06cc\u062f \u062a\u0627 \u0627\u0642\u062f\u0627\u0645 \u0634\u0648\u062f.\n\n---\n\u2022 \u0646\u0627\u0645 \u067e\u0631\u0648\u0698\u0647: \u0633\u0631\u0648\u0631 \u0627\u0635\u0644\u06cc (`root`)\n\u2022 \u0622\u062f\u0631\u0633 \u0645\u062e\u0632\u0646: https://git.msa.artacloud.ir/root/default\n\n[[BUTTONS: layout=[\n [{\"text\": \"\ud83d\udcca \u0648\u0636\u0639\u06cc\u062a \u0633\u0647\u0645\u06cc\u0647 \u0648 \u0645\u0635\u0631\u0641\", \"cmd\": \"/usage\"}, {\"text\": \"\ud83d\udcc2 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\", \"cmd\": \"/projects\"}]\n]]]\n", "created_at": 1787995349.975879, "description": "", - "conversation_titles": { - "4acc374a-5742-40fe-b5ec-b8b3d1b14e68": "\u0633\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0627\u0633\u062a\u0631\u06cc\u0645 \u0632\u0646\u062f\u0647 \u0648 \u0646\u0645\u0627\u06cc\u0634 \u0645\u062f\u0644", - "b0235b6f-a4af-4526-a344-b48e92fd1a08": "\u0634\u062e\u0635\u06cc\u200c\u0633\u0627\u0632\u06cc \u06a9\u06cc\u0628\u0648\u0631\u062f \u0648 \u0645\u0646\u0648\u0647\u0627\u06cc \u0631\u0628\u0627\u062a", - "ad39c983-09f1-4042-889f-681049b0de26": "\u0646\u0645\u0627\u06cc\u0634 \u0645\u0648\u0636\u0648\u0639 \u06af\u0641\u062a\u06af\u0648 \u062f\u0631 \u0627\u0633\u062a\u0631\u06cc\u0645 \u0632\u0646\u062f\u0647" - } + "conversation_titles": {} }, "copykar": { "name": "copykar", "workspace": "/root/projects/78649634/copykar", "owner_id": 78649634, "shared_with": [], - "conversation_id": "b0235b6f-a4af-4526-a344-b48e92fd1a08", - "conversation_history": [ - "80e74c43-2afd-41d5-8afa-641d91d11a31", - "0a01cbd3-d8bf-4b60-a984-11d3c1b79e3b", - "69a8bfd8-9fb0-47c4-9c2e-d34530817421", - "b0235b6f-a4af-4526-a344-b48e92fd1a08", - "7957ad8b-75bc-452e-b661-ed2468135f36" - ], + "conversation_id": null, + "conversation_history": [], "model": "gemini-3.7-flash-auto", "effort": "high", "language": "fa", - "last_context_length": 29246, - "last_total_tokens": 3723, - "last_response": "", + "last_context_length": null, + "last_total_tokens": null, + "last_response": null, "created_at": 1788031971.6031597, "description": "", - "conversation_titles": { - "b0235b6f-a4af-4526-a344-b48e92fd1a08": "\u062b\u0628\u062a \u062e\u0627\u0637\u0631\u0627\u062a \u0648 \u062a\u062d\u0644\u06cc\u0644 \u0633\u0627\u062e\u062a\u0627\u0631 \u067e\u0631\u0648\u0698\u0647" - } + "conversation_titles": {} }, "hamed-site": { "name": "hamed-site", @@ -97,19 +81,19 @@ } }, "turn_in_progress": false, - "last_prompt": "\u0647\u0645\u0647 \u06af\u0641\u062a\u06af\u0648 \u0647\u0627 \u0628\u0627\u06cc\u062f \u0628\u0631 \u0627\u0633\u0627\u0633 \u067e\u0631\u0648\u0698\u0647 \u0627\u0646\u062a\u062e\u0627\u0628\u06cc \u0641\u0639\u0644\u06cc \u06a9\u0627\u0631\u0628\u0631 \u062a\u0642\u0633\u06cc\u0645 \u0628\u0646\u062f\u06cc \u0634\u0648\u0646\u062f\n\u0647\u0631 \u0632\u0645\u0627\u0646 \u06a9\u0627\u0631\u0628\u0631 \u0648\u0627\u0631\u062f \u06cc\u06a9 \u06af\u0641\u062a\u06af\u0648 \u0634\u062f \u0628\u0631 \u0627\u0633\u0627\u0633 \u067e\u0631\u0648\u0698\u0647 \u0645\u0631\u0628\u0648\u0637 \u0628\u0647 \u0627\u0648\u0646 \u06af\u0641\u062a\u06af\u0648 \u067e\u0631\u0648\u0698\u0647 \u0627\u0646\u062a\u062e\u0627\u0628\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0647\u0645 \u0639\u0648\u0636 \u0634\u0648\u062f", - "last_response": "", - "last_status_msg_id": 1664, + "last_prompt": "\u0627\u0644\u0627\u0646 \u06a9\u062c\u0627\u06cc\u06cc\u0645\u061f", + "last_response": "\u062f\u0631 \u062d\u0627\u0644 \u062d\u0627\u0636\u0631 \u062f\u0631 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0627\u0635\u0644\u06cc \u0631\u0648\u062a \u0633\u0631\u0648\u0631 (`/root`) \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u06cc\u0645.\n\n### \ud83d\udccd \u0648\u0636\u0639\u06cc\u062a \u0641\u0639\u0644\u06cc \u0633\u06cc\u0633\u062a\u0645 \u0648 \u0645\u062d\u06cc\u0637 \u06a9\u0627\u0631\u06cc:\n* **\u0645\u062d\u06cc\u0637 \u0641\u0639\u0627\u0644:** \u0631\u0648\u062a \u0633\u0631\u0648\u0631 (`/root`)\n* **\u0633\u0631\u0648\u06cc\u0633\u200c\u0647\u0627\u06cc \u0627\u0635\u0644\u06cc:**\n * \u0631\u0628\u0627\u062a \u062a\u0644\u06af\u0631\u0627\u0645: `/root/telegram-agy-bot`\n * \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631\u0627\u0646: `/root/projects/`\n* **\u0645\u062f\u0644 \u0647\u0648\u0634 \u0645\u0635\u0646\u0648\u0639\u06cc:** Gemini 3.7 Flash (\u062d\u0627\u0644\u062a Flash Auto Reasoning)\n\n\u0627\u06af\u0631 \u0645\u0627\u06cc\u0644\u06cc\u062f \u0631\u0648\u06cc \u067e\u0631\u0648\u0698\u0647 \u062e\u0627\u0635\u06cc \u06a9\u0627\u0631 \u06a9\u0646\u06cc\u0645\u060c \u067e\u0631\u0648\u0698\u0647 \u062c\u062f\u06cc\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u0645 \u06cc\u0627 \u0648\u0636\u0639\u06cc\u062a \u062e\u0627\u0635\u06cc \u0631\u0627 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u0645\u060c \u0628\u0641\u0631\u0645\u0627\u06cc\u06cc\u062f \u062a\u0627 \u0627\u0642\u062f\u0627\u0645 \u0634\u0648\u062f.\n\n---\n\u2022 \u0646\u0627\u0645 \u067e\u0631\u0648\u0698\u0647: \u0633\u0631\u0648\u0631 \u0627\u0635\u0644\u06cc (`root`)\n\u2022 \u0622\u062f\u0631\u0633 \u0645\u062e\u0632\u0646: https://git.msa.artacloud.ir/root/default\n\n[[BUTTONS: layout=[\n [{\"text\": \"\ud83d\udcca \u0648\u0636\u0639\u06cc\u062a \u0633\u0647\u0645\u06cc\u0647 \u0648 \u0645\u0635\u0631\u0641\", \"cmd\": \"/usage\"}, {\"text\": \"\ud83d\udcc2 \u067e\u0631\u0648\u0698\u0647\u200c\u0647\u0627\", \"cmd\": \"/projects\"}]\n]]]\n", + "last_status_msg_id": null, "restart_pending": false, "last_delivered": true, - "last_update_time": 1788093692.4675694, - "workspace": "/root/projects/78649634/copykar", - "conversation_id": "b0235b6f-a4af-4526-a344-b48e92fd1a08", + "last_update_time": 1788094178.8477302, + "workspace": "/root", + "conversation_id": "0c1bd37f-4121-422c-aa1c-49b0c7345e7a", "model": "gemini-3.7-flash-auto", "effort": "high", "language": "fa", - "last_context_length": 29246, - "last_total_tokens": 3723 + "last_context_length": 1986, + "last_total_tokens": 31891 }, "232801087": { "chat_id": 232801087,