mirror of
https://github.com/father-bot/chatgpt_telegram_bot.git
synced 2026-06-13 03:54:57 +03:00
Remove trailing whitespaces
This commit is contained in:
@@ -21,7 +21,7 @@ This repo is ChatGPT re-created as Telegram Bot. **And it works great.**
|
||||
You can deploy your own bot, or use mine: [@chatgpt_karfly_bot](https://t.me/chatgpt_karfly_bot)
|
||||
|
||||
## Features
|
||||
- Low latency replies (it usually takes about 3-5 seconds)
|
||||
- Low latency replies (it usually takes about 3-5 seconds)
|
||||
- No request limits
|
||||
- Message streaming (watch demo)
|
||||
- GPT-4 support
|
||||
|
||||
+21
-21
@@ -11,10 +11,10 @@ from datetime import datetime
|
||||
|
||||
import telegram
|
||||
from telegram import (
|
||||
Update,
|
||||
User,
|
||||
InlineKeyboardButton,
|
||||
InlineKeyboardMarkup,
|
||||
Update,
|
||||
User,
|
||||
InlineKeyboardButton,
|
||||
InlineKeyboardMarkup,
|
||||
BotCommand
|
||||
)
|
||||
from telegram.ext import (
|
||||
@@ -93,15 +93,15 @@ async def register_user_if_not_exists(update: Update, context: CallbackContext,
|
||||
async def start_handle(update: Update, context: CallbackContext):
|
||||
await register_user_if_not_exists(update, context, update.message.from_user)
|
||||
user_id = update.message.from_user.id
|
||||
|
||||
|
||||
db.set_user_attribute(user_id, "last_interaction", datetime.now())
|
||||
db.start_new_dialog(user_id)
|
||||
|
||||
|
||||
reply_text = "Hi! I'm <b>ChatGPT</b> bot implemented with GPT-3.5 OpenAI API 🤖\n\n"
|
||||
reply_text += HELP_MESSAGE
|
||||
|
||||
reply_text += "\nAnd now... ask me anything!"
|
||||
|
||||
|
||||
await update.message.reply_text(reply_text, parse_mode=ParseMode.HTML)
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ async def help_handle(update: Update, context: CallbackContext):
|
||||
async def retry_handle(update: Update, context: CallbackContext):
|
||||
await register_user_if_not_exists(update, context, update.message.from_user)
|
||||
if await is_previous_message_not_answered_yet(update, context): return
|
||||
|
||||
|
||||
user_id = update.message.from_user.id
|
||||
db.set_user_attribute(user_id, "last_interaction", datetime.now())
|
||||
|
||||
@@ -135,13 +135,13 @@ async def message_handle(update: Update, context: CallbackContext, message=None,
|
||||
if update.edited_message is not None:
|
||||
await edited_message_handle(update, context)
|
||||
return
|
||||
|
||||
|
||||
await register_user_if_not_exists(update, context, update.message.from_user)
|
||||
if await is_previous_message_not_answered_yet(update, context): return
|
||||
|
||||
user_id = update.message.from_user.id
|
||||
chat_mode = db.get_user_attribute(user_id, "current_chat_mode")
|
||||
|
||||
|
||||
async with user_semaphores[user_id]:
|
||||
# new dialog timeout
|
||||
if use_new_dialog_timeout:
|
||||
@@ -194,7 +194,7 @@ async def message_handle(update: Update, context: CallbackContext, message=None,
|
||||
|
||||
answer = answer[:4096] # telegram message limit
|
||||
if i == 0: # send first message (then it'll be edited if message streaming is enabled)
|
||||
try:
|
||||
try:
|
||||
sent_message = await update.message.reply_text(answer, parse_mode=parse_mode)
|
||||
except telegram.error.BadRequest as e:
|
||||
if str(e).startswith("Message must be non-empty"): # first answer chunk from openai was empty
|
||||
@@ -207,7 +207,7 @@ async def message_handle(update: Update, context: CallbackContext, message=None,
|
||||
if abs(len(answer) - len(prev_answer)) < 100 and status != "finished":
|
||||
continue
|
||||
|
||||
try:
|
||||
try:
|
||||
await context.bot.edit_message_text(answer, chat_id=sent_message.chat_id, message_id=sent_message.message_id, parse_mode=parse_mode)
|
||||
except telegram.error.BadRequest as e:
|
||||
if str(e).startswith("Message is not modified"):
|
||||
@@ -216,7 +216,7 @@ async def message_handle(update: Update, context: CallbackContext, message=None,
|
||||
await context.bot.edit_message_text(answer, chat_id=sent_message.chat_id, message_id=sent_message.message_id)
|
||||
|
||||
await asyncio.sleep(0.01) # wait a bit to avoid flooding
|
||||
|
||||
|
||||
prev_answer = answer
|
||||
|
||||
# update user data
|
||||
@@ -227,7 +227,7 @@ async def message_handle(update: Update, context: CallbackContext, message=None,
|
||||
dialog_id=None
|
||||
)
|
||||
|
||||
db.update_n_used_tokens(user_id, current_model, n_input_tokens, n_output_tokens)
|
||||
db.update_n_used_tokens(user_id, current_model, n_input_tokens, n_output_tokens)
|
||||
except Exception as e:
|
||||
error_text = f"Something went wrong during completion. Reason: {e}"
|
||||
logger.error(error_text)
|
||||
@@ -381,12 +381,12 @@ async def set_settings_handle(update: Update, context: CallbackContext):
|
||||
db.start_new_dialog(user_id)
|
||||
|
||||
text, reply_markup = get_settings_menu(user_id)
|
||||
try:
|
||||
try:
|
||||
await query.edit_message_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML)
|
||||
except telegram.error.BadRequest as e:
|
||||
if str(e).startswith("Message is not modified"):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
async def show_balance_handle(update: Update, context: CallbackContext):
|
||||
await register_user_if_not_exists(update, context, update.message.from_user)
|
||||
@@ -415,8 +415,8 @@ async def show_balance_handle(update: Update, context: CallbackContext):
|
||||
voice_recognition_n_spent_dollars = config.models["info"]["whisper"]["price_per_1_min"] * (n_transcribed_seconds / 60)
|
||||
if n_transcribed_seconds != 0:
|
||||
details_text += f"- Whisper (voice recognition): <b>{voice_recognition_n_spent_dollars:.03f}$</b> / <b>{n_transcribed_seconds:.01f} seconds</b>\n"
|
||||
|
||||
total_n_spent_dollars += voice_recognition_n_spent_dollars
|
||||
|
||||
total_n_spent_dollars += voice_recognition_n_spent_dollars
|
||||
|
||||
text = f"You spent <b>{total_n_spent_dollars:.03f}$</b>\n"
|
||||
text += f"You used <b>{total_n_used_tokens}</b> tokens\n\n"
|
||||
@@ -490,7 +490,7 @@ def run_bot() -> None:
|
||||
application.add_handler(CommandHandler("new", new_dialog_handle, filters=user_filter))
|
||||
|
||||
application.add_handler(MessageHandler(filters.VOICE & user_filter, voice_message_handle))
|
||||
|
||||
|
||||
application.add_handler(CommandHandler("mode", show_chat_modes_handle, filters=user_filter))
|
||||
application.add_handler(CallbackQueryHandler(set_chat_mode_handle, pattern="^set_chat_mode"))
|
||||
|
||||
@@ -498,9 +498,9 @@ def run_bot() -> None:
|
||||
application.add_handler(CallbackQueryHandler(set_settings_handle, pattern="^set_settings"))
|
||||
|
||||
application.add_handler(CommandHandler("balance", show_balance_handle, filters=user_filter))
|
||||
|
||||
|
||||
application.add_error_handler(error_handle)
|
||||
|
||||
|
||||
# start the bot
|
||||
application.run_polling()
|
||||
|
||||
|
||||
+4
-4
@@ -23,7 +23,7 @@ class Database:
|
||||
raise ValueError(f"User {user_id} does not exist")
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def add_new_user(
|
||||
self,
|
||||
user_id: int,
|
||||
@@ -42,7 +42,7 @@ class Database:
|
||||
|
||||
"last_interaction": datetime.now(),
|
||||
"first_seen": datetime.now(),
|
||||
|
||||
|
||||
"current_dialog_id": None,
|
||||
"current_chat_mode": "assistant",
|
||||
"current_model": config.models["available_text_models"][0],
|
||||
@@ -112,7 +112,7 @@ class Database:
|
||||
if dialog_id is None:
|
||||
dialog_id = self.get_user_attribute(user_id, "current_dialog_id")
|
||||
|
||||
dialog_dict = self.dialog_collection.find_one({"_id": dialog_id, "user_id": user_id})
|
||||
dialog_dict = self.dialog_collection.find_one({"_id": dialog_id, "user_id": user_id})
|
||||
return dialog_dict["messages"]
|
||||
|
||||
def set_dialog_messages(self, user_id: int, dialog_messages: list, dialog_id: Optional[str] = None):
|
||||
@@ -120,7 +120,7 @@ class Database:
|
||||
|
||||
if dialog_id is None:
|
||||
dialog_id = self.get_user_attribute(user_id, "current_dialog_id")
|
||||
|
||||
|
||||
self.dialog_collection.update_one(
|
||||
{"_id": dialog_id, "user_id": user_id},
|
||||
{"$set": {"messages": dialog_messages}}
|
||||
|
||||
+10
-10
@@ -20,7 +20,7 @@ class ChatGPT:
|
||||
def __init__(self, model="gpt-3.5-turbo"):
|
||||
assert model in {"text-davinci-003", "gpt-3.5-turbo", "gpt-4"}, f"Unknown model: {model}"
|
||||
self.model = model
|
||||
|
||||
|
||||
async def send_message(self, message, dialog_messages=[], chat_mode="assistant"):
|
||||
if chat_mode not in CHAT_MODES.keys():
|
||||
raise ValueError(f"Chat mode {chat_mode} is not supported")
|
||||
@@ -94,7 +94,7 @@ class ChatGPT:
|
||||
stream=True,
|
||||
**OPENAI_COMPLETION_OPTIONS
|
||||
)
|
||||
|
||||
|
||||
answer = ""
|
||||
async for r_item in r_gen:
|
||||
answer += r_item.choices[0].text
|
||||
@@ -103,7 +103,7 @@ class ChatGPT:
|
||||
n_input_tokens, n_output_tokens = self._count_tokens_from_prompt(prompt, answer, model=self.model)
|
||||
|
||||
answer = self._postprocess_answer(answer)
|
||||
|
||||
|
||||
except openai.error.InvalidRequestError as e: # too many tokens
|
||||
if len(dialog_messages) == 0:
|
||||
raise ValueError("Dialog messages is reduced to zero, but still has too many tokens to make completion") from e
|
||||
@@ -134,7 +134,7 @@ class ChatGPT:
|
||||
|
||||
def _generate_prompt_messages(self, message, dialog_messages, chat_mode):
|
||||
prompt = CHAT_MODES[chat_mode]["prompt_start"]
|
||||
|
||||
|
||||
messages = [{"role": "system", "content": prompt}]
|
||||
for dialog_message in dialog_messages:
|
||||
messages.append({"role": "user", "content": dialog_message["user"]})
|
||||
@@ -158,7 +158,7 @@ class ChatGPT:
|
||||
tokens_per_name = 1
|
||||
else:
|
||||
raise ValueError(f"Unknown model: {model}")
|
||||
|
||||
|
||||
# input
|
||||
n_input_tokens = 0
|
||||
for message in messages:
|
||||
@@ -167,20 +167,20 @@ class ChatGPT:
|
||||
n_input_tokens += len(encoding.encode(value))
|
||||
if key == "name":
|
||||
n_input_tokens += tokens_per_name
|
||||
|
||||
|
||||
n_input_tokens += 2
|
||||
|
||||
# output
|
||||
n_output_tokens = 1 + len(encoding.encode(answer))
|
||||
|
||||
|
||||
return n_input_tokens, n_output_tokens
|
||||
|
||||
|
||||
def _count_tokens_from_prompt(self, prompt, answer, model="text-davinci-003"):
|
||||
encoding = tiktoken.encoding_for_model(model)
|
||||
|
||||
|
||||
n_input_tokens = len(encoding.encode(prompt)) + 1
|
||||
n_output_tokens = len(encoding.encode(answer))
|
||||
|
||||
|
||||
return n_input_tokens, n_output_tokens
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ text_improver:
|
||||
welcome_message: 📝 Hi, I'm <b>Text Improver</b>. Send me any text – I'll improve it and correct all the mistakes
|
||||
prompt_start: |
|
||||
As an advanced chatbot Text Improver Assistant, your primary goal is to correct spelling, fix mistakes and improve text sent by user. Your goal is to edit text, but not to change it's meaning. You can replace simplified A0-level words and sentences with more beautiful and elegant, upper level words and sentences.
|
||||
|
||||
|
||||
All your answers strictly follows the structure (keep html tags):
|
||||
<b>Edited text:</b>
|
||||
{EDITED TEXT}
|
||||
|
||||
Reference in New Issue
Block a user