diff --git a/handlers/help.py b/handlers/help.py
new file mode 100644
index 0000000..cd9a682
--- /dev/null
+++ b/handlers/help.py
@@ -0,0 +1,87 @@
+from telegram import Update
+from telegram.constants import ParseMode
+from telegram.ext import ContextTypes
+from services import auth, ai_client
+from config import BOT_VERSION
+
+
+HELP_TEXT = """
+πΎ Puppy Bot v{version} β Help
+
+Puppy is an AI assistant powered by Google Gemini (or OpenRouter models).
+Groups: mention me by name (Puppy / ΩΎΨ§ΩΎΫ), reply to my messages, or @mention me.
+Private: just write directly.
+
+ββββββββββββββββββββ
+π¬ Chat
+Send a message to chat.
+Send a photo or image album β I'll analyze it. Caption with OCR/read/text, describe, objects, or a question for focused image understanding.
+Reply to someone else's message and call my name β I'll respond in context.
+
+ββββββββββββββββββββ
+π Search & Images
+I auto-search the web for real-time info (news, weather, date, pricesβ¦).
+Ask for images β I'll search and send up to 5 results.
+/search <query> β Direct web search
+/ocr β Reply to an image and extract readable text
+/imagine <description> β Generate an image with Imagen 4 Fast
+
+ββββββββββββββββββββ
+βοΈ Your Settings
+/status β View your settings
+/setmaxtoken <n> β Set max reply tokens (50β4000, default 300)
+/getmaxtoken β Show current max tokens
+/resettoken β Reset to default (300)
+/setlang <auto|fa|en> β Override response language
+/togglesearch β Enable / disable auto web search
+/model β Show active AI provider and model
+/clear β Clear your conversation history
+/myhistory β View your recent conversation
+
+ββββββββββββββββββββ
+π Inline Mode
+Type @{username} your question in any chat.
+
+ββββββββββββββββββββ
+π οΈ Admin Commands (owner only)
+/unlock β Open bot to everyone (public mode)
+/lock β Restrict back to authorized users only
+/setprovider <google|openrouter> β Switch AI provider
+/setmodel [google|openrouter] <model> β Change model with validation
+/models [google|openrouter] [free] [keyword] β Browse available models
+/stats / /dashboard β Admin dashboard
+/addauth <id> β Authorize a user
+/removeauth <id> β Remove authorization
+/listauth β List authorized users
+/ban <id> β Ban a user
+/unban <id> β Unban a user
+/listban β List banned users
+/userinfo <id> β Show user info
+/broadcast <text> β Message all known users
+/clearall β Clear all histories
+/setpersonality <text> β Set custom system prompt
+/resetpersonality β Restore default personality
+/reload β Reload authorized_users.json from disk
+/uptime β Show bot uptime
+/version β Show bot version
+/ping β Health check
+/myid β Show your Telegram user ID
+
+ββββββββββββββββββββ
+Provider: {provider} | Model: {model}
+""".strip()
+
+
+async def cmd_help(update: Update, context: ContextTypes.DEFAULT_TYPE):
+ user = update.effective_user
+ if not auth.is_authorized(user.id, user.username or ""):
+ return
+
+ bot_username = context.bot.username or "PuppyBot"
+ text = HELP_TEXT.format(
+ version=BOT_VERSION,
+ username=bot_username,
+ provider=ai_client.get_provider(),
+ model=ai_client.get_model(),
+ )
+ await update.message.reply_text(text, parse_mode=ParseMode.HTML)
diff --git a/handlers/inline.py b/handlers/inline.py
new file mode 100644
index 0000000..dfac6f9
--- /dev/null
+++ b/handlers/inline.py
@@ -0,0 +1,36 @@
+import uuid
+from telegram import Update, InlineQueryResultArticle, InputTextMessageContent
+from telegram.ext import ContextTypes
+from services import auth, ai_client
+from utils.context import get_system_prompt, get_user_settings
+
+
+async def inline_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
+ query = update.inline_query.query.strip()
+ user_id = update.inline_query.from_user.id
+
+ if not auth.is_authorized(user_id):
+ await update.inline_query.answer([], cache_time=0)
+ return
+
+ if not query:
+ await update.inline_query.answer([], cache_time=0)
+ return
+
+ try:
+ settings = get_user_settings(user_id)
+ max_tokens = min(settings["max_tokens"], 300)
+ answer = await ai_client.quick_reply(query, get_system_prompt(), max_tokens=max_tokens)
+ except Exception as e:
+ answer = f"Error: {e}"
+
+ result = InlineQueryResultArticle(
+ id=str(uuid.uuid4()),
+ title="Puppy's answer",
+ description=answer[:120] + ("β¦" if len(answer) > 120 else ""),
+ input_message_content=InputTextMessageContent(
+ message_text=answer,
+ ),
+ )
+
+ await update.inline_query.answer([result], cache_time=0)