AI Update: تایید مینمایم

This commit is contained in:
Antigravity Bot
2026-08-31 12:31:58 +03:30
parent eaf8aef993
commit a0094b4188
5 changed files with 118 additions and 59 deletions
+15
View File
@@ -1626,6 +1626,21 @@ class AGYEngine:
except Exception as pe:
logger.debug(f"Pre-prompt git pull skipped: {pe}")
if not auth_manager.has_custom_account(session.chat_id):
is_fa = (session.language or "").lower() in ("fa", "farsi", "persian", "🇮🇷 persian / farsi (فارسی)")
msg = (
"⚠️ <b>حساب کاربری هوش مصنوعی شما متصل نیست!</b>\n\n"
"در این ربات حساب‌های اشتراکی غیرفعال هستند و هر کاربر ملزم به استفاده از حساب شخصی خود می‌باشد.\n"
"👉 لطفاً با دستور <code>/login</code> وارد حساب اختصاصی گوگل خود شوید یا فایل توکن را ارسال کنید."
if is_fa else
"⚠️ <b>AGY Account Not Connected!</b>\n\nShared accounts are disabled. Please log in with your own account via /login."
)
return AGYResult(
text=msg,
success=False,
error="Account not connected"
)
user_env = auth_manager.get_user_env(session.chat_id)
start_time = time.time()
proc = await asyncio.create_subprocess_exec(
+13 -27
View File
@@ -53,10 +53,8 @@ class AuthManager:
return False
def get_user_home(self, user_id: int) -> str:
"""Returns the HOME directory path to use for this user."""
if self.has_custom_account(user_id):
return str(self.get_profile_dir(user_id))
return "/root"
"""Returns the isolated HOME directory path to use for this user."""
return str(self.get_profile_dir(user_id))
def get_user_env(self, user_id: int) -> Dict[str, str]:
"""Returns environment variables dictionary with the proper HOME set for the user."""
@@ -67,10 +65,10 @@ class AuthManager:
def get_account_status(self, user_id: int) -> Dict[str, Any]:
"""Returns detailed status of the user's active account."""
has_custom = self.has_custom_account(user_id)
token_path = self.get_token_path(user_id) if has_custom else MASTER_TOKEN_PATH
token_path = self.get_token_path(user_id)
modified_time_str = "نامشخص"
if token_path.exists():
modified_time_str = "تنظیم نشده"
if has_custom and token_path.exists():
try:
mtime = token_path.stat().st_mtime
modified_time_str = datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M:%S")
@@ -80,9 +78,9 @@ class AuthManager:
return {
"user_id": user_id,
"has_custom_account": has_custom,
"is_default_server": not has_custom,
"account_type": "حساب اختصاصی (Custom Account)" if has_custom else "حساب پیش‌فرض سرور (Server Default)",
"token_path": str(token_path),
"is_default_server": False,
"account_type": "حساب اختصاصی (Custom Account)" if has_custom else "حساب متصل نیست (Disconnected)",
"token_path": str(token_path) if has_custom else "تنظیم نشده",
"last_modified": modified_time_str,
"is_login_in_progress": user_id in self.active_logins,
}
@@ -276,34 +274,22 @@ class AuthManager:
def logout_user(self, user_id: int) -> Tuple[bool, str]:
"""
Logs out a user by removing their custom token, falling back to server default.
Logs out a user by removing their custom token.
"""
self.cancel_oauth_login(user_id)
token_file = self.get_token_path(user_id)
if token_file.exists():
try:
token_file.unlink()
return True, "حساب اختصاصی شما با موفقیت خارج شد. از این پس درخواست‌های شما با حساب پیش‌فرض سرور اجرا می‌شوند."
return True, "حساب اختصاصی شما با موفقیت خارج شد. برای ارسال دستورات، ورود مجدد با حساب شخصی الزامی است."
except Exception as e:
return False, f"خطا در حذف توکن اختصاصی: {e}"
return True, "شما از قبل در حال استفاده از حساب پیش‌فرض سرور هستید."
return True, "شما در حال حاضر حساب متصلی ندارید."
def copy_master_token_to_user(self, user_id: int) -> Tuple[bool, str]:
"""
Copies the current active server master token to a specific user's profile.
Disabled: Shared accounts are completely removed.
"""
if not MASTER_TOKEN_PATH.exists():
return False, "توکن فعال سرور یافت نشد."
config_dir = self.get_config_dir(user_id)
config_dir.mkdir(parents=True, exist_ok=True)
dst = self.get_token_path(user_id)
try:
shutil.copy2(MASTER_TOKEN_PATH, dst)
dst.chmod(0o600)
return True, "توکن فعال سرور با موفقیت در پروفایل شما ثبت گردید."
except Exception as e:
return False, f"خطا در کپی توکن سرور: {e}"
return False, "حساب‌های اشتراکی در این ربات غیرفعال شده‌اند و هر کاربر باید با حساب اختصاصی خود وارد شود."
auth_manager = AuthManager()
+69 -24
View File
@@ -1051,10 +1051,10 @@ def build_account_menu(chat_id: int) -> tuple[str, InlineKeyboardMarkup]:
f"• 📅 <i>تاریخ ثبت/بروزرسانی توکن:</i> <code>{status['last_modified']}</code>\n"
)
else:
acc_type_badge = "🟡 <b>حساب پیش‌فرض سرور (Server Shared)</b>"
acc_type_badge = "🔴 <b>حساب متصل نیست (Disconnected)</b>"
desc = (
"شما هم‌اکنون از حساب عمومی سرور استفاده می‌کنید.\n"
"برای استفاده از سهمیه‌های اختصاصی، اعتبارات شخصی و حفظ کامل حریم کوتای خود، می‌توانید با حساب گوگل خود لاگین کنید.\n"
"⚠️ <b>هیچ حساب کاربری فعالی متصل نشده است.</b>\n"
"در این ربات حساب‌های عمومی/اشتراکی غیرفعال هستند و برای استفاده از هوش مصنوعی و ارسال دستورات، اتصال حساب اختصاصی گوگل الزامی است.\n"
)
text = (
@@ -1062,9 +1062,9 @@ def build_account_menu(chat_id: int) -> tuple[str, InlineKeyboardMarkup]:
f"• 🆔 <b>شناسه کاربر:</b> <code>{chat_id}</code>\n"
f"• 👤 <b>وضعیت حساب:</b> {acc_type_badge}\n\n"
f"{desc}\n"
f"💡 <i>روش‌های ورود و اتصال:</i>\n"
f"۱. <b>ورود اینتراکتیو با گوگل:</b> دکمه «🔑 ورود به حساب گوگل» را بزنید.\n"
f"۲. <b>ارسال مستقیم فایل یا متن توکن:</b> می‌توانید فایل <code>antigravity-oauth-token</code> یا محتوای JSON توکن خود را در چت ارسال کنید."
f"💡 <i>روش‌های اتصال حساب اختصاصی:</i>\n"
f"۱. <b>ورود اینتراکتیو با گوگل:</b> دکمه «🔑 ورود با حساب گوگل (OAuth)» را بزنید.\n"
f"۲. <b>ارسال مستقیم فایل یا متن توکن:</b> فایل <code>antigravity-oauth-token</code> یا متن JSON توکن خود را در چت ارسال کنید."
)
buttons = []
@@ -1081,10 +1081,6 @@ def build_account_menu(chat_id: int) -> tuple[str, InlineKeyboardMarkup]:
buttons.append([
InlineKeyboardButton("🚪 خروج از حساب شخصی", callback_data="btn_account_logout"),
])
elif is_admin_user:
buttons.append([
InlineKeyboardButton("📋 کپی توکن فعال سرور برای من", callback_data="btn_account_copy_server"),
])
buttons.append([
InlineKeyboardButton("📊 استعلام سهمیه حساب", callback_data="btn_usage_menu"),
@@ -1098,8 +1094,8 @@ def build_account_menu(chat_id: int) -> tuple[str, InlineKeyboardMarkup]:
acc_type_badge = "🟢 <b>Active Custom Account</b>"
desc = f"All AI interactions are using your personal Google account quota.\n• 📅 <i>Last modified:</i> <code>{status['last_modified']}</code>\n"
else:
acc_type_badge = "🟡 <b>Server Default Account (Shared)</b>"
desc = "You are using the shared server account.\nLog in with your own Google account for isolated personal quotas.\n"
acc_type_badge = "🔴 <b>No Account Connected</b>"
desc = "Shared accounts are disabled. You must log in with your own Google account to use the bot.\n"
text = (
f"🔑 <b>AGY Account Management</b>\n\n"
@@ -1119,8 +1115,6 @@ def build_account_menu(chat_id: int) -> tuple[str, InlineKeyboardMarkup]:
if has_custom:
buttons.append([InlineKeyboardButton("🚪 Log out from Custom Account", callback_data="btn_account_logout")])
elif is_admin_user:
buttons.append([InlineKeyboardButton("📋 Copy Server Master Token to Me", callback_data="btn_account_copy_server")])
buttons.append([
InlineKeyboardButton("📊 Check Quota", callback_data="btn_usage_menu"),
@@ -3058,6 +3052,17 @@ async def process_agent_turn_by_chat_id(
if not curr_proj:
return
if not auth_manager.has_custom_account(chat_id):
warn_text = (
"⚠️ <b>حساب کاربری هوش مصنوعی شما متصل نیست!</b>\n\n"
"در این ربات حساب‌های اشتراکی غیرفعال هستند. لطفاً ابتدا از طریق دستور <code>/login</code> با حساب اختصاصی خود وارد شوید."
if is_fa else
"⚠️ <b>AGY Account Not Connected!</b>\n\nShared accounts are disabled. Please connect your personal Google account via /login."
)
keyboard = [[InlineKeyboardButton("🔑 ورود به حساب گوگل (/login)" if is_fa else "🔑 Log in with Google", callback_data="btn_account_start_login")]]
await app.bot.send_message(chat_id=chat_id, text=warn_text, parse_mode=constants.ParseMode.HTML, reply_markup=InlineKeyboardMarkup(keyboard))
return
# Create dummy update/context wrapper or send initial status message
if initial_status_text:
initial_status = initial_status_text
@@ -5975,16 +5980,7 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
await query.message.reply_html(text, reply_markup=markup)
elif data == "btn_account_copy_server":
if not is_admin_user:
await query.answer("⛔ فقط مدیر مجاز به کپی توکن سرور است.", show_alert=True)
return
success, msg = auth_manager.copy_master_token_to_user(chat_id)
await query.answer(msg, show_alert=True)
text, markup = build_account_menu(chat_id)
try:
await query.edit_message_text(text, parse_mode=constants.ParseMode.HTML, reply_markup=markup)
except Exception:
await query.message.reply_html(text, reply_markup=markup)
await query.answer("⛔ حساب‌های اشتراکی غیرفعال شده‌اند و استفاده از حساب اختصاصی الزامی است.", show_alert=True)
elif data == "btn_status_menu":
accessible = session_manager.get_all_accessible_projects(chat_id)
@@ -7557,6 +7553,30 @@ async def message_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_html(msg, reply_markup=InlineKeyboardMarkup(keyboard))
return
if not auth_manager.has_custom_account(chat_id):
if is_fa:
msg = (
"⚠️ <b>حساب کاربری هوش مصنوعی شما متصل نیست!</b>\n\n"
"در این ربات حساب‌های اشتراکی غیرفعال هستند و هر کاربر ملزم به استفاده از حساب اختصاصی گوگل خود می‌باشد.\n\n"
"👉 لطفاً با دستور <code>/login</code> یا دکمه زیر وارد حساب اختصاصی گوگل خود شوید یا فایل توکن را ارسال فرمایید."
)
keyboard = [
[InlineKeyboardButton("🔑 ورود با حساب گوگل (/login)", callback_data="btn_account_start_login")],
[InlineKeyboardButton("📋 منوی حساب کاربری (/account)", callback_data="btn_account_menu")],
]
else:
msg = (
"⚠️ <b>AGY Account Not Connected!</b>\n\n"
"Shared accounts are disabled. You must connect your personal Google account to interact with the AI.\n\n"
"👉 Send <code>/login</code> or tap the button below."
)
keyboard = [
[InlineKeyboardButton("🔑 Log in with Google (/login)", callback_data="btn_account_start_login")],
[InlineKeyboardButton("📋 Account Menu (/account)", callback_data="btn_account_menu")],
]
await update.message.reply_html(msg, reply_markup=InlineKeyboardMarkup(keyboard))
return
prompt = update.message.text.strip()
await process_agent_turn(update, context, prompt)
@@ -7584,6 +7604,17 @@ async def file_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
except Exception as ex:
logger.error(f"Failed to process uploaded token file: {ex}")
if not auth_manager.has_custom_account(chat_id):
msg = (
"⚠️ <b>حساب کاربری هوش مصنوعی شما متصل نیست!</b>\n\n"
"برای ارسال فایل و تعامل با هوش مصنوعی، لطفاً ابتدا با حساب اختصاصی خود وارد شوید (/login)."
if is_fa else
"⚠️ <b>AGY Account Not Connected!</b>\n\nPlease connect your personal Google account first via /login."
)
keyboard = [[InlineKeyboardButton("🔑 ورود به حساب گوگل (/login)" if is_fa else "🔑 Log in with Google", callback_data="btn_account_start_login")]]
await update.message.reply_html(msg, reply_markup=InlineKeyboardMarkup(keyboard))
return
if not curr_proj:
msg = (
"⚠️ <b>شما هنوز هیچ پروژه‌ای ایجاد نکرده‌اید!</b>\n\n"
@@ -7778,6 +7809,20 @@ async def process_agent_turn(
await update.effective_message.reply_html(msg, reply_markup=InlineKeyboardMarkup(keyboard))
return
if not auth_manager.has_custom_account(chat_id):
msg = (
"⚠️ <b>حساب کاربری هوش مصنوعی شما متصل نیست!</b>\n\n"
"در این ربات حساب‌های عمومی و اشتراکی غیرفعال هستند. برای استفاده از هوش مصنوعی، لطفاً با دستور <code>/login</code> یا دکمه زیر وارد حساب اختصاصی گوگل خود شوید."
if is_fa else
"⚠️ <b>AGY Account Not Connected!</b>\n\nShared accounts are disabled. Please connect your personal Google account via /login."
)
keyboard = [[InlineKeyboardButton("🔑 ورود به حساب گوگل (/login)" if is_fa else "🔑 Log in with Google", callback_data="btn_account_start_login")]]
if status_msg_to_reuse:
await status_msg_to_reuse.edit_text(msg, parse_mode=constants.ParseMode.HTML, reply_markup=InlineKeyboardMarkup(keyboard))
else:
await update.effective_message.reply_html(msg, reply_markup=InlineKeyboardMarkup(keyboard))
return
session_manager.cancel_active_task(chat_id)
model_to_use = getattr(curr_proj, "model", None) or getattr(session, "model", None) or settings.default_model or "gemini-3.7-flash-auto"
File diff suppressed because one or more lines are too long
+13
View File
@@ -126,6 +126,19 @@ def parse_agy_usage_output(usage_raw: str, credits_raw: str) -> Dict[str, Any]:
async def fetch_and_render_usage_report(is_fa: bool = True, user_id: Optional[int] = None) -> str:
"""Executes agy /usage and /credits and formats with visual progress bars."""
from auth_manager import auth_manager
if user_id and not auth_manager.has_custom_account(user_id):
if is_fa:
return (
"⚠️ <b>حساب کاربری هوش مصنوعی متصل نیست!</b>\n\n"
"در این ربات حساب‌های اشتراکی غیرفعال هستند و هر کاربر باید حساب گوگل اختصاصی خود را متصل کند.\n\n"
"👉 برای ورود و استعلام سهمیه اختصاصی، لطفاً دستور <code>/login</code> را ارسال کنید یا از منوی <code>/account</code> وارد شوید."
)
else:
return (
"⚠️ <b>AGY Account Not Connected!</b>\n\n"
"Shared accounts are disabled. Please log in with your own Google account using <code>/login</code> or <code>/account</code>."
)
env = auth_manager.get_user_env(user_id) if user_id else os.environ.copy()
usage_raw = ""
credits_raw = ""