diff --git a/handlers/__init__.py b/handlers/__init__.py index 237d6e6..7135bba 100644 --- a/handlers/__init__.py +++ b/handlers/__init__.py @@ -21,32 +21,50 @@ T = TypeVar("T", bound=Callable) BOT_MESSAGE_LENGTH = 4000 -def bot_reply_markdown(message: Message, hint: str, text: str, bot: TeleBot) -> None: +def bot_reply_first(message: Message, who: str, bot: TeleBot) -> Message: + """Create the first reply message which make user feel the bot is working.""" + return bot.reply_to( + message, f"*{who}* is _thinking_ \.\.\.", parse_mode="MarkdownV2" + ) + + +def bot_reply_markdown(reply_id: Message, who: str, text: str, bot: TeleBot) -> None: """ reply the Markdown by take care of the message length. it will fallback to plain text in case of any failure """ try: if len(text.encode("utf-8")) <= BOT_MESSAGE_LENGTH: - bot.reply_to( - message, - f"**{hint}**:\n{telegramify_markdown.convert(text)}", + bot.edit_message_text( + f"*{who}*:\n{telegramify_markdown.convert(text)}", + chat_id=reply_id.chat.id, + message_id=reply_id.message_id, parse_mode="MarkdownV2", ) return # Need a split of message msgs = smart_split(text, BOT_MESSAGE_LENGTH) - for i in range(len(msgs)): + bot.edit_message_text( + f"*{who}* \[1/{len(msgs)}\]:\n{telegramify_markdown.convert(msgs[0])}", + chat_id=reply_id.chat.id, + message_id=reply_id.message_id, + parse_mode="MarkdownV2", + ) + for i in range(1, len(msgs)): bot.reply_to( - message, - f"**{hint}** \[{i+1}/{len(msgs)}\]:\n{telegramify_markdown.convert(msgs[i])}", + reply_id.reply_to_message, + f"*{who}* \[{i+1}/{len(msgs)}\]:\n{telegramify_markdown.convert(msgs[i])}", parse_mode="MarkdownV2", ) except Exception as e: print(traceback.format_exc()) # print(f"wrong markdown format: {text}") - bot.reply_to(message, f"{hint}:\n{text}") + bot.edit_message_text( + f"*{who}*:\n{text}", + chat_id=reply_id.chat.id, + message_id=reply_id.message_id, + ) def extract_prompt(message: str, bot_name: str) -> str: @@ -133,4 +151,4 @@ def list_available_commands() -> list[str]: # `import *` will give you these -__all__ = ["bot_reply_markdown", "extract_prompt"] +__all__ = ["bot_reply_first", "bot_reply_markdown"] diff --git a/handlers/claude.py b/handlers/claude.py index 315caa6..ffae8e3 100644 --- a/handlers/claude.py +++ b/handlers/claude.py @@ -6,7 +6,7 @@ from anthropic import Anthropic, APITimeoutError from telebot import TeleBot from telebot.types import Message -from . import bot_reply_markdown +from . import * from telegramify_markdown import convert from telegramify_markdown.customize import markdown_symbol @@ -37,6 +37,7 @@ def claude_handler(message: Message, bot: TeleBot) -> None: ) else: player_message = claude_player_dict[str(message.from_user.id)] + if m.strip() == "clear": bot.reply_to( message, @@ -45,6 +46,9 @@ def claude_handler(message: Message, bot: TeleBot) -> None: player_message.clear() return + # show something, make it more responsible + reply_id = bot_reply_first(message, "Claude", bot) + player_message.append({"role": "user", "content": m}) # keep the last 5, every has two ask and answer. if len(player_message) > 10: @@ -57,7 +61,7 @@ def claude_handler(message: Message, bot: TeleBot) -> None: # tricky player_message.pop() r = client.messages.create( - max_tokens=1024, messages=player_message, model=ANTHROPIC_MODEL + max_tokens=4096, messages=player_message, model=ANTHROPIC_MODEL ) if not r.content: claude_reply_text = "Claude did not answer." @@ -81,7 +85,7 @@ def claude_handler(message: Message, bot: TeleBot) -> None: player_message.clear() return - bot_reply_markdown(message, "Claude answer", claude_reply_text, bot) + bot_reply_markdown(reply_id, "Claude", claude_reply_text, bot) def claude_pro_handler(message: Message, bot: TeleBot) -> None: @@ -94,7 +98,8 @@ def claude_pro_handler(message: Message, bot: TeleBot) -> None: ) else: player_message = claude_pro_player_dict[str(message.from_user.id)] - if m.strip() == "clear": + q = m.strip() + if q == "clear" or len(q) == 0: bot.reply_to( message, "just clear you claude opus messages history", @@ -113,7 +118,7 @@ def claude_pro_handler(message: Message, bot: TeleBot) -> None: # tricky player_message.pop() r = client.messages.create( - max_tokens=4096, + max_tokens=8192, messages=player_message, model=ANTHROPIC_PRO_MODEL, stream=True, diff --git a/handlers/gemini.py b/handlers/gemini.py index 84dc99c..ee1891c 100644 --- a/handlers/gemini.py +++ b/handlers/gemini.py @@ -6,7 +6,7 @@ from google.generativeai.types.generation_types import StopCandidateException from telebot import TeleBot from telebot.types import Message -from . import bot_reply_markdown +from . import * GOOGLE_GEMINI_KEY = environ.get("GOOGLE_GEMINI_KEY") @@ -15,7 +15,7 @@ generation_config = { "temperature": 0.7, "top_p": 1, "top_k": 1, - "max_output_tokens": 4096, + "max_output_tokens": 8192, } safety_settings = [ @@ -56,6 +56,10 @@ def gemini_handler(message: Message, bot: TeleBot) -> None: ) player.history.clear() return + + # show something, make it more responsible + reply_id = bot_reply_first(message, "Gemini", bot) + # keep the last 5, every has two ask and answer. if len(player.history) > 10: player.history = player.history[2:] @@ -64,7 +68,8 @@ def gemini_handler(message: Message, bot: TeleBot) -> None: player.send_message(m) gemini_reply_text = player.last.text.strip() # Gemini is often using ':' in **Title** which not work in Telegram Markdown - gemini_reply_text = gemini_reply_text.replace(": **", "**\: ") + gemini_reply_text = gemini_reply_text.replace(":**", "\:**") + gemini_reply_text = gemini_reply_text.replace(":**", "**\: ") except StopCandidateException as e: match = re.search(r'content\s*{\s*parts\s*{\s*text:\s*"([^"]+)"', str(e)) if match: @@ -79,7 +84,7 @@ def gemini_handler(message: Message, bot: TeleBot) -> None: return # By default markdown - bot_reply_markdown(message, "Gemini answer", gemini_reply_text, bot) + bot_reply_markdown(reply_id, "Gemini", gemini_reply_text, bot) def gemini_photo_handler(message: Message, bot: TeleBot) -> None: diff --git a/handlers/yi.py b/handlers/yi.py index 6de7164..b22b570 100644 --- a/handlers/yi.py +++ b/handlers/yi.py @@ -7,7 +7,7 @@ import requests from telebot import TeleBot from telebot.types import Message -from . import bot_reply_markdown +from . import * YI_BASE_URL = environ.get("YI_BASE_URL") YI_API_KEY = environ.get("YI_API_KEY") @@ -43,6 +43,9 @@ def yi_handler(message: Message, bot: TeleBot) -> None: player_message.clear() return + # show something, make it more responsible + reply_id = bot_reply_first(message, "Yi", bot) + player_message.append({"role": "user", "content": m}) # keep the last 5, every has two ask and answer. if len(player_message) > 10: @@ -81,7 +84,7 @@ def yi_handler(message: Message, bot: TeleBot) -> None: return # reply back as Markdown and fallback to plain text if failed. - bot_reply_markdown(message, "yi answer", yi_reply_text, bot) + bot_reply_markdown(replay_id, "Yi", yi_reply_text, bot) def _image_to_data_uri(file_path):