Merge pull request #26 from linuxyz/main

Make bot react more actively
This commit is contained in:
yihong 2024-04-02 21:23:31 +08:00 committed by GitHub
commit 529a5de0ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 20 deletions

View File

@ -21,32 +21,50 @@ T = TypeVar("T", bound=Callable)
BOT_MESSAGE_LENGTH = 4000 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. reply the Markdown by take care of the message length.
it will fallback to plain text in case of any failure it will fallback to plain text in case of any failure
""" """
try: try:
if len(text.encode("utf-8")) <= BOT_MESSAGE_LENGTH: if len(text.encode("utf-8")) <= BOT_MESSAGE_LENGTH:
bot.reply_to( bot.edit_message_text(
message, f"*{who}*:\n{telegramify_markdown.convert(text)}",
f"**{hint}**:\n{telegramify_markdown.convert(text)}", chat_id=reply_id.chat.id,
message_id=reply_id.message_id,
parse_mode="MarkdownV2", parse_mode="MarkdownV2",
) )
return return
# Need a split of message # Need a split of message
msgs = smart_split(text, BOT_MESSAGE_LENGTH) 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( bot.reply_to(
message, reply_id.reply_to_message,
f"**{hint}** \[{i+1}/{len(msgs)}\]:\n{telegramify_markdown.convert(msgs[i])}", f"*{who}* \[{i+1}/{len(msgs)}\]:\n{telegramify_markdown.convert(msgs[i])}",
parse_mode="MarkdownV2", parse_mode="MarkdownV2",
) )
except Exception as e: except Exception as e:
print(traceback.format_exc()) print(traceback.format_exc())
# print(f"wrong markdown format: {text}") # 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: def extract_prompt(message: str, bot_name: str) -> str:
@ -133,4 +151,4 @@ def list_available_commands() -> list[str]:
# `import *` will give you these # `import *` will give you these
__all__ = ["bot_reply_markdown", "extract_prompt"] __all__ = ["bot_reply_first", "bot_reply_markdown"]

View File

@ -6,7 +6,7 @@ from anthropic import Anthropic, APITimeoutError
from telebot import TeleBot from telebot import TeleBot
from telebot.types import Message from telebot.types import Message
from . import bot_reply_markdown from . import *
from telegramify_markdown import convert from telegramify_markdown import convert
from telegramify_markdown.customize import markdown_symbol from telegramify_markdown.customize import markdown_symbol
@ -37,6 +37,7 @@ def claude_handler(message: Message, bot: TeleBot) -> None:
) )
else: else:
player_message = claude_player_dict[str(message.from_user.id)] player_message = claude_player_dict[str(message.from_user.id)]
if m.strip() == "clear": if m.strip() == "clear":
bot.reply_to( bot.reply_to(
message, message,
@ -45,6 +46,9 @@ def claude_handler(message: Message, bot: TeleBot) -> None:
player_message.clear() player_message.clear()
return return
# show something, make it more responsible
reply_id = bot_reply_first(message, "Claude", bot)
player_message.append({"role": "user", "content": m}) player_message.append({"role": "user", "content": m})
# keep the last 5, every has two ask and answer. # keep the last 5, every has two ask and answer.
if len(player_message) > 10: if len(player_message) > 10:
@ -57,7 +61,7 @@ def claude_handler(message: Message, bot: TeleBot) -> None:
# tricky # tricky
player_message.pop() player_message.pop()
r = client.messages.create( 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: if not r.content:
claude_reply_text = "Claude did not answer." claude_reply_text = "Claude did not answer."
@ -81,7 +85,7 @@ def claude_handler(message: Message, bot: TeleBot) -> None:
player_message.clear() player_message.clear()
return 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: def claude_pro_handler(message: Message, bot: TeleBot) -> None:
@ -94,7 +98,8 @@ def claude_pro_handler(message: Message, bot: TeleBot) -> None:
) )
else: else:
player_message = claude_pro_player_dict[str(message.from_user.id)] 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( bot.reply_to(
message, message,
"just clear you claude opus messages history", "just clear you claude opus messages history",
@ -113,7 +118,7 @@ def claude_pro_handler(message: Message, bot: TeleBot) -> None:
# tricky # tricky
player_message.pop() player_message.pop()
r = client.messages.create( r = client.messages.create(
max_tokens=4096, max_tokens=8192,
messages=player_message, messages=player_message,
model=ANTHROPIC_PRO_MODEL, model=ANTHROPIC_PRO_MODEL,
stream=True, stream=True,

View File

@ -6,7 +6,7 @@ from google.generativeai.types.generation_types import StopCandidateException
from telebot import TeleBot from telebot import TeleBot
from telebot.types import Message from telebot.types import Message
from . import bot_reply_markdown from . import *
GOOGLE_GEMINI_KEY = environ.get("GOOGLE_GEMINI_KEY") GOOGLE_GEMINI_KEY = environ.get("GOOGLE_GEMINI_KEY")
@ -15,7 +15,7 @@ generation_config = {
"temperature": 0.7, "temperature": 0.7,
"top_p": 1, "top_p": 1,
"top_k": 1, "top_k": 1,
"max_output_tokens": 4096, "max_output_tokens": 8192,
} }
safety_settings = [ safety_settings = [
@ -56,6 +56,10 @@ def gemini_handler(message: Message, bot: TeleBot) -> None:
) )
player.history.clear() player.history.clear()
return 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. # keep the last 5, every has two ask and answer.
if len(player.history) > 10: if len(player.history) > 10:
player.history = player.history[2:] player.history = player.history[2:]
@ -64,7 +68,8 @@ def gemini_handler(message: Message, bot: TeleBot) -> None:
player.send_message(m) player.send_message(m)
gemini_reply_text = player.last.text.strip() gemini_reply_text = player.last.text.strip()
# Gemini is often using ':' in **Title** which not work in Telegram Markdown # 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: except StopCandidateException as e:
match = re.search(r'content\s*{\s*parts\s*{\s*text:\s*"([^"]+)"', str(e)) match = re.search(r'content\s*{\s*parts\s*{\s*text:\s*"([^"]+)"', str(e))
if match: if match:
@ -79,7 +84,7 @@ def gemini_handler(message: Message, bot: TeleBot) -> None:
return return
# By default markdown # 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: def gemini_photo_handler(message: Message, bot: TeleBot) -> None:

View File

@ -7,7 +7,7 @@ import requests
from telebot import TeleBot from telebot import TeleBot
from telebot.types import Message from telebot.types import Message
from . import bot_reply_markdown from . import *
YI_BASE_URL = environ.get("YI_BASE_URL") YI_BASE_URL = environ.get("YI_BASE_URL")
YI_API_KEY = environ.get("YI_API_KEY") YI_API_KEY = environ.get("YI_API_KEY")
@ -43,6 +43,9 @@ def yi_handler(message: Message, bot: TeleBot) -> None:
player_message.clear() player_message.clear()
return return
# show something, make it more responsible
reply_id = bot_reply_first(message, "Yi", bot)
player_message.append({"role": "user", "content": m}) player_message.append({"role": "user", "content": m})
# keep the last 5, every has two ask and answer. # keep the last 5, every has two ask and answer.
if len(player_message) > 10: if len(player_message) > 10:
@ -81,7 +84,7 @@ def yi_handler(message: Message, bot: TeleBot) -> None:
return return
# reply back as Markdown and fallback to plain text if failed. # 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): def _image_to_data_uri(file_path):