Skip to content

Commit 5143628

Browse files
committed
💻 Code: Refactor code, use ModelMerge as the model Q&A backend.
1 parent 223cc38 commit 5143628

12 files changed

+39
-3091
lines changed

README.md

+1-21
Original file line numberDiff line numberDiff line change
@@ -46,26 +46,6 @@ The ChatGPT Telegram Bot is a powerful Telegram bot that utilizes the latest GPT
4646
| GOOGLE_AI_API_KEY | Google AI offical API key. | No |
4747
| GROQ_API_KEY | Groq AI offical API key. | No |
4848

49-
## 🔌 Plugins
50-
51-
Our plugin system has been successfully developed and is now fully operational. We welcome everyone to contribute their code to enrich our plugin library. All plugins can be activated or deactivated using the `/info` command. The following plugins are currently supported:
52-
53-
- **Web Search**: By default, DuckDuckGo search is provided. Google search is automatically activated when the `GOOGLE_CSE_ID` and `GOOGLE_API_KEY` environment variables are set.
54-
- **Time Retrieval**: Retrieves the current time, date, and day of the week in the GMT+8 time zone.
55-
- **URL Summary**: Automatically extracts URLs from queries and responds based on the content of the URLs.
56-
- **Version Information**: Displays the current version of the bot, commit hash, update time, and developer name.
57-
58-
To develop plugins, please follow the steps outlined below:
59-
60-
- Initially, you need to add the environment variable for the plugin in the `config.PLUGINS` dictionary located in the `config.py` file. The value can be customized to be either enabled or disabled by default. It is advisable to use uppercase letters for the entire environment variable.
61-
- Subsequently, append the function's name and description in the `utils/function_call.py` file.
62-
- Then, enhance the `ask_stream` function in the `utils/chatgpt2api.py` file with the function's processing logic. You can refer to the existing examples within the `ask_stream` method for guidance on how to write it.
63-
- Following that, write the function, as mentioned in the `utils/function_call.py` file, in the `utils/plugins.py` file.
64-
- Next, in the `bot.py` file, augment the `update_first_buttons_message` function with buttons, enabling users to freely toggle plugins using the `info` command.
65-
- Lastly, don't forget to add the plugin's description in the plugins section of the README.
66-
67-
Please note that the above steps are a general guide and may need to be adjusted based on the specific requirements of your plugin.
68-
6949
## Zeabur Remote Deployment (Recommended)
7050

7151
One-click deployment:
@@ -272,7 +252,7 @@ In a group chat scenario, if the environment variable `NICK` is not set, the bot
272252

273253
- How many messages will the history keep?
274254

275-
Apart from the latest `gpt-4-turbo-preview` model, the official context supports 128k tokens, but this project limits it to 16k tokens. All other models use the official context length settings, for example, the `gpt-3.5-turbo-16k` context is 16k, the `gpt-4-32k` context is 32k, and the `Claude2` context is 200k. This limitation is implemented to save user costs, as most scenarios do not require a high context. If you have specific needs, you can modify the context limits for each model in the `utils/chatgpt2api.py` file.
255+
Apart from the latest `gpt-4-turbo-preview` model, the official context supports 128k tokens, but this project limits it to 16k tokens. All other models use the official context length settings, for example, the `gpt-3.5-turbo-16k` context is 16k, the `gpt-4-32k` context is 32k, and the `Claude2` context is 200k. This limitation is implemented to save user costs, as most scenarios do not require a high context.
276256

277257
## References
278258

bot.py

+21-19
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import re
2-
import os
32
import sys
43
sys.dont_write_bytecode = True
5-
import config
64
import logging
75
import traceback
86
import utils.decorators as decorators
97
from md2tgmd import escape
10-
from utils.chatgpt2api import Chatbot as GPT
11-
from utils.chatgpt2api import claudebot, groqbot, claude3bot, gemini_bot
12-
from utils.prompt import translator_en2zh_prompt, translator_prompt, claude3_doc_assistant_prompt
8+
9+
from ModelMerge.models import chatgpt, claude, groq, claude3, gemini
10+
from ModelMerge.models.config import PLUGINS
11+
from ModelMerge.utils.prompt import translator_en2zh_prompt, translator_prompt, claude3_doc_assistant_prompt
12+
from ModelMerge.utils.scripts import Document_extract, get_encode_image, claude_replace
13+
14+
import config
15+
from config import WEB_HOOK, PORT, BOT_TOKEN, update_first_buttons_message, buttons
16+
1317
from telegram.constants import ChatAction
14-
from utils.plugins import Document_extract, get_encode_image, claude_replace
1518
from telegram import BotCommand, InlineKeyboardMarkup, InlineQueryResultArticle, InputTextMessageContent
1619
from telegram.ext import CommandHandler, MessageHandler, ApplicationBuilder, filters, CallbackQueryHandler, Application, AIORateLimiter, InlineQueryHandler
17-
from config import WEB_HOOK, PORT, BOT_TOKEN, update_first_buttons_message, buttons
1820

1921

2022
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
@@ -269,7 +271,7 @@ async def image(update, context):
269271
start_messageid = message.message_id
270272

271273
try:
272-
for data in robot.dall_e_3(text):
274+
for data in robot.generate(text):
273275
result = data
274276
await context.bot.delete_message(chat_id=chatid, message_id=start_messageid)
275277
await context.bot.send_photo(chat_id=chatid, photo=result, reply_to_message_id=messageid)
@@ -329,16 +331,16 @@ async def button_press(update, context):
329331
config.GPT_ENGINE = data
330332
# print("config.GPT_ENGINE", config.GPT_ENGINE)
331333
if (config.API and "gpt-" in data) or (config.API and not config.ClaudeAPI) or (config.API and config.CUSTOM_MODELS and data in config.CUSTOM_MODELS):
332-
config.ChatGPTbot = GPT(api_key=f"{config.API}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
334+
config.ChatGPTbot = chatgpt(api_key=f"{config.API}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
333335
config.ChatGPTbot.reset(convo_id=str(update.effective_chat.id), system_prompt=config.systemprompt)
334336
if config.ClaudeAPI and "claude-2.1" in data:
335-
config.claudeBot = claudebot(api_key=f"{config.ClaudeAPI}", engine=config.GPT_ENGINE, system_prompt=config.claude_systemprompt, temperature=config.temperature)
337+
config.claudeBot = claude(api_key=f"{config.ClaudeAPI}", engine=config.GPT_ENGINE, system_prompt=config.claude_systemprompt, temperature=config.temperature)
336338
if config.ClaudeAPI and "claude-3" in data:
337-
config.claude3Bot = claude3bot(api_key=f"{config.ClaudeAPI}", engine=config.GPT_ENGINE, system_prompt=config.claude_systemprompt, temperature=config.temperature)
339+
config.claude3Bot = claude3(api_key=f"{config.ClaudeAPI}", engine=config.GPT_ENGINE, system_prompt=config.claude_systemprompt, temperature=config.temperature)
338340
if config.GROQ_API_KEY and ("mixtral" in data or "llama" in data):
339-
config.groqBot = groqbot(api_key=f"{config.GROQ_API_KEY}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
341+
config.groqBot = groq(api_key=f"{config.GROQ_API_KEY}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
340342
if config.GOOGLE_AI_API_KEY and "gemini" in data:
341-
config.gemini_Bot = gemini_bot(api_key=f"{config.GOOGLE_AI_API_KEY}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
343+
config.gemini_Bot = gemini(api_key=f"{config.GOOGLE_AI_API_KEY}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
342344
try:
343345
info_message = update_info_message(update)
344346
if info_message + banner != callback_query.message.text:
@@ -373,15 +375,15 @@ async def button_press(update, context):
373375
config.claude_systemprompt = config.claude_systemprompt.replace("English", "Simplified Chinese")
374376
# config.systemprompt = f"You are ChatGPT, a large language model trained by OpenAI. Respond conversationally in {config.LANGUAGE}. Knowledge cutoff: 2021-09. Current date: [ {config.Current_Date} ]"
375377
if config.API:
376-
config.ChatGPTbot = GPT(api_key=f"{config.API}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
378+
config.ChatGPTbot = chatgpt(api_key=f"{config.API}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
377379
config.ChatGPTbot.reset(convo_id=str(update.effective_chat.id), system_prompt=config.systemprompt)
378380
if config.ClaudeAPI:
379-
config.claudeBot = claudebot(api_key=f"{config.ClaudeAPI}", engine=config.GPT_ENGINE, system_prompt=config.claude_systemprompt, temperature=config.temperature)
380-
config.claude3Bot = claude3bot(api_key=f"{config.ClaudeAPI}", engine=config.GPT_ENGINE, system_prompt=config.claude_systemprompt, temperature=config.temperature)
381+
config.claudeBot = claude(api_key=f"{config.ClaudeAPI}", engine=config.GPT_ENGINE, system_prompt=config.claude_systemprompt, temperature=config.temperature)
382+
config.claude3Bot = claude3(api_key=f"{config.ClaudeAPI}", engine=config.GPT_ENGINE, system_prompt=config.claude_systemprompt, temperature=config.temperature)
381383
if config.GROQ_API_KEY:
382-
config.groqBot = groqbot(api_key=f"{config.GROQ_API_KEY}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
384+
config.groqBot = groq(api_key=f"{config.GROQ_API_KEY}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
383385
if config.GOOGLE_AI_API_KEY:
384-
config.gemini_Bot = gemini_bot(api_key=f"{config.GOOGLE_AI_API_KEY}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
386+
config.gemini_Bot = gemini(api_key=f"{config.GOOGLE_AI_API_KEY}", engine=config.GPT_ENGINE, system_prompt=config.systemprompt, temperature=config.temperature)
385387

386388
info_message = update_info_message(update)
387389
message = await callback_query.edit_message_text(
@@ -391,7 +393,7 @@ async def button_press(update, context):
391393
)
392394
else:
393395
try:
394-
config.PLUGINS[data] = not config.PLUGINS[data]
396+
PLUGINS[data] = not PLUGINS[data]
395397
except:
396398
setattr(config, data, not getattr(config, data))
397399
info_message = update_info_message(update)

config.py

+13-36
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
from dotenv import load_dotenv
33
load_dotenv()
4-
import utils.prompt as prompt
4+
55
from telegram import InlineKeyboardButton
66

77
WEB_HOOK = os.environ.get('WEB_HOOK', None)
@@ -28,32 +28,32 @@
2828
CUSTOM_MODELS_LIST = None
2929

3030

31+
from ModelMerge.utils import prompt
3132
from datetime import datetime
3233
current_date = datetime.now()
3334
Current_Date = current_date.strftime("%Y-%m-%d")
3435
systemprompt = os.environ.get('SYSTEMPROMPT', prompt.system_prompt.format(LANGUAGE, Current_Date))
3536
claude_systemprompt = os.environ.get('SYSTEMPROMPT', prompt.claude_system_prompt)
3637

37-
from utils.chatgpt2api import Chatbot as GPT
38-
from utils.chatgpt2api import Imagebot, claudebot, groqbot, claude3bot, gemini_bot
38+
from ModelMerge.models import chatgpt, claude, groq, claude3, gemini, dalle3
3939
if API:
40-
ChatGPTbot = GPT(api_key=f"{API}", engine=GPT_ENGINE, system_prompt=systemprompt, temperature=temperature)
40+
ChatGPTbot = chatgpt(api_key=f"{API}", engine=GPT_ENGINE, system_prompt=systemprompt, temperature=temperature)
4141

42-
translate_bot = GPT(api_key=f"{API}", engine=GPT_ENGINE, system_prompt=systemprompt, temperature=temperature)
43-
copilot_bot = GPT(api_key=f"{API}", engine=GPT_ENGINE, system_prompt=prompt.search_system_prompt.format(LANGUAGE), temperature=temperature)
44-
dallbot = Imagebot(api_key=f"{API}")
42+
translate_bot = chatgpt(api_key=f"{API}", engine=GPT_ENGINE, system_prompt=systemprompt, temperature=temperature)
43+
copilot_bot = chatgpt(api_key=f"{API}", engine=GPT_ENGINE, system_prompt=prompt.search_system_prompt.format(LANGUAGE), temperature=temperature)
44+
dallbot = dalle3(api_key=f"{API}")
4545
else:
4646
ChatGPTbot = None
4747

4848
ClaudeAPI = os.environ.get('claude_api_key', None)
4949
if ClaudeAPI:
50-
claudeBot = claudebot(api_key=f"{ClaudeAPI}", system_prompt=claude_systemprompt)
51-
claude3Bot = claude3bot(api_key=f"{ClaudeAPI}", system_prompt=claude_systemprompt)
50+
claudeBot = claude(api_key=f"{ClaudeAPI}", system_prompt=claude_systemprompt)
51+
claude3Bot = claude3(api_key=f"{ClaudeAPI}", system_prompt=claude_systemprompt)
5252

5353
if GROQ_API_KEY:
54-
groqBot = groqbot(api_key=f"{GROQ_API_KEY}")
54+
groqBot = groq(api_key=f"{GROQ_API_KEY}")
5555
if GOOGLE_AI_API_KEY:
56-
gemini_Bot = gemini_bot(api_key=f"{GOOGLE_AI_API_KEY}")
56+
gemini_Bot = gemini(api_key=f"{GOOGLE_AI_API_KEY}")
5757

5858
whitelist = os.environ.get('whitelist', None)
5959
if whitelist:
@@ -65,14 +65,6 @@
6565
if GROUP_LIST:
6666
GROUP_LIST = [int(id) for id in GROUP_LIST.split(",")]
6767

68-
PLUGINS = {
69-
"SEARCH_USE_GPT": (os.environ.get('SEARCH_USE_GPT', "True") == "False") == False,
70-
# "USE_G4F": (os.environ.get('USE_G4F', "False") == "False") == False,
71-
"DATE": True,
72-
"URL": True,
73-
"VERSION": True,
74-
}
75-
7668
class userConfig:
7769
def __init__(self, user_id: int):
7870
self.user_id = user_id
@@ -83,21 +75,7 @@ def __init__(self, user_id: int):
8375
self.search_system_prompt = prompt.search_system_prompt.format(self.language)
8476
self.search_model = "gpt-3.5-turbo-1106"
8577

86-
class openaiAPI:
87-
def __init__(
88-
self,
89-
api_url: str = (os.environ.get("API_URL") or "https://api.openai.com/v1/chat/completions"),
90-
):
91-
from urllib.parse import urlparse, urlunparse
92-
self.source_api_url: str = api_url
93-
parsed_url = urlparse(self.source_api_url)
94-
self.base_url: str = urlunparse(parsed_url[:2] + ("",) * 4)
95-
self.v1_url: str = urlunparse(parsed_url[:2] + ("/v1",) + ("",) * 3)
96-
self.chat_url: str = urlunparse(parsed_url[:2] + ("/v1/chat/completions",) + ("",) * 3)
97-
self.image_url: str = urlunparse(parsed_url[:2] + ("/v1/images/generations",) + ("",) * 3)
98-
99-
bot_api_url = openaiAPI()
100-
78+
from ModelMerge.models.config import PLUGINS
10179
def get_plugins_status(item):
10280
return "✅" if PLUGINS[item] else "☑️"
10381

@@ -181,13 +159,12 @@ def update_first_buttons_message():
181159
InlineKeyboardButton(f"历史记录 {history}", callback_data="PASS_HISTORY"),
182160
],
183161
[
184-
InlineKeyboardButton(f"搜索 {get_plugins_status('SEARCH_USE_GPT')}", callback_data='SEARCH_USE_GPT'),
162+
InlineKeyboardButton(f"搜索 {get_plugins_status('SEARCH')}", callback_data='SEARCH'),
185163
InlineKeyboardButton(f"当前时间 {get_plugins_status('DATE')}", callback_data='DATE'),
186164
],
187165
[
188166
InlineKeyboardButton(f"URL 总结 {get_plugins_status('URL')}", callback_data='URL'),
189167
InlineKeyboardButton(f"版本信息 {get_plugins_status('VERSION')}", callback_data='VERSION'),
190-
# InlineKeyboardButton(f"gpt4free {get_plugins_status('USE_G4F')}", callback_data='USE_G4F'),
191168
],
192169
]
193170
return first_buttons

requirements.txt

+4-21
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,8 @@
11
--index-url https://pypi.python.org/simple/
2-
requests
3-
tiktoken==0.6.0
4-
md2tgmd==0.1.9
5-
# jieba
2+
pytz
63
python-dotenv
7-
beautifulsoup4
8-
lxml
9-
python-telegram-bot[webhooks,rate-limiter]==21.0.1
10-
# python-telegram-bot[webhooks,rate-limiter]==20.6
11-
12-
# langchain
13-
# chromadb
14-
# unstructured[md,pdf]
4+
md2tgmd==0.1.9
155
fake_useragent
16-
openai==0.28.1
17-
google-api-python-client
18-
duckduckgo-search==5.3.0
19-
langchain==0.0.271
6+
ModelMerge==0.2.9
207
oauth2client==3.0.0
21-
pdfminer.six
22-
# g4f==0.1.9.6
23-
24-
# plugin
25-
pytz
8+
python-telegram-bot[webhooks,rate-limiter]==21.0.1

0 commit comments

Comments
 (0)