13 Commits

Author SHA1 Message Date
Father Bot ba58564d29 Update README.md 2025-06-26 18:12:37 +03:00
OlegGoless 2079908ce6 Merge pull request #469 from pyranota/add-gpt-4o
Add support for GPT-4o
2024-06-13 19:11:40 +02:00
Father Bot 4066ab9a44 Update README.md 2024-06-13 19:28:55 +03:00
pyranota c017c32800 Fix defaulting 2024-05-23 23:27:27 +02:00
pyranota fff2839327 Fix not showing GPT-4o in settings 2024-05-23 18:49:59 +02:00
pyranota 752f38b348 Add support for GPT-4o 2024-05-23 17:45:28 +02:00
OlegGoless 7b5fa9a3c3 Merge pull request #453 from father-bot/fix-context
fix bug in context
2024-04-16 14:56:57 +02:00
OlegGoless 6540b28437 fix bug in context 2024-04-16 14:56:04 +02:00
OlegGoless 00c5f66be5 Merge pull request #448 from father-bot/fix-image
delete required text caption with image
2024-04-04 10:29:18 +02:00
OlegGoless 5e4552e4df delete required text caption with image 2024-04-04 10:22:53 +02:00
OlegGoless 57ee703f07 Merge pull request #444 from father-bot/fix-prints-model
fix
2024-04-02 17:23:37 +02:00
Father Bot c26829e9e3 Update README.md 2024-04-02 16:13:17 +03:00
OlegGoless d0eb9ee015 Merge pull request #442 from father-bot/vision
Vision
2024-04-02 14:52:59 +02:00
5 changed files with 62 additions and 41 deletions
Vendored
BIN
View File
Binary file not shown.
+4 -5
View File
@@ -10,21 +10,19 @@
<a href="https://t.me/chatgpt_karfly_bot?start=source=github" alt="Run Telegram Bot shield"><img src="https://img.shields.io/badge/RUN-Telegram%20Bot-blue?logo=data:image/svg+xml;base64,PHN2ZyBpZD0iTGl2ZWxsb18xIiBkYXRhLW5hbWU9IkxpdmVsbG8gMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmlld0JveD0iMCAwIDI0MCAyNDAiPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0ibGluZWFyLWdyYWRpZW50IiB4MT0iMTIwIiB5MT0iMjQwIiB4Mj0iMTIwIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjMWQ5M2QyIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMzhiMGUzIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHRpdGxlPlRlbGVncmFtX2xvZ288L3RpdGxlPjxjaXJjbGUgY3g9IjEyMCIgY3k9IjEyMCIgcj0iMTIwIiBmaWxsPSJ1cmwoI2xpbmVhci1ncmFkaWVudCkiLz48cGF0aCBkPSJNODEuMjI5LDEyOC43NzJsMTQuMjM3LDM5LjQwNnMxLjc4LDMuNjg3LDMuNjg2LDMuNjg3LDMwLjI1NS0yOS40OTIsMzAuMjU1LTI5LjQ5MmwzMS41MjUtNjAuODlMODEuNzM3LDExOC42WiIgZmlsbD0iI2M4ZGFlYSIvPjxwYXRoIGQ9Ik0xMDAuMTA2LDEzOC44NzhsLTIuNzMzLDI5LjA0NnMtMS4xNDQsOC45LDcuNzU0LDAsMTcuNDE1LTE1Ljc2MywxNy40MTUtMTUuNzYzIiBmaWxsPSIjYTljNmQ4Ii8+PHBhdGggZD0iTTgxLjQ4NiwxMzAuMTc4LDUyLjIsMTIwLjYzNnMtMy41LTEuNDItMi4zNzMtNC42NGMuMjMyLS42NjQuNy0xLjIyOSwyLjEtMi4yLDYuNDg5LTQuNTIzLDEyMC4xMDYtNDUuMzYsMTIwLjEwNi00NS4zNnMzLjIwOC0xLjA4MSw1LjEtLjM2MmEyLjc2NiwyLjc2NiwwLDAsMSwxLjg4NSwyLjA1NSw5LjM1Nyw5LjM1NywwLDAsMSwuMjU0LDIuNTg1Yy0uMDA5Ljc1Mi0uMSwxLjQ0OS0uMTY5LDIuNTQyLS42OTIsMTEuMTY1LTIxLjQsOTQuNDkzLTIxLjQsOTQuNDkzcy0xLjIzOSw0Ljg3Ni01LjY3OCw1LjA0M0E4LjEzLDguMTMsMCwwLDEsMTQ2LjEsMTcyLjVjLTguNzExLTcuNDkzLTM4LjgxOS0yNy43MjctNDUuNDcyLTMyLjE3N2ExLjI3LDEuMjcsMCwwLDEtLjU0Ni0uOWMtLjA5My0uNDY5LjQxNy0xLjA1LjQxNy0xLjA1czUyLjQyNi00Ni42LDUzLjgyMS01MS40OTJjLjEwOC0uMzc5LS4zLS41NjYtLjg0OC0uNC0zLjQ4MiwxLjI4MS02My44NDQsMzkuNC03MC41MDYsNDMuNjA3QTMuMjEsMy4yMSwwLDAsMSw4MS40ODYsMTMwLjE3OFoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=" width="230"/></a>
</p>
<p align="center">
<a href="https://github.com/karfly/chatgpt_telegram_bot/blob/main/static/donate/donate.md#%EF%B8%8F-donate" alt="Donate shield"><img src="https://img.shields.io/badge/-Donate-red?logo=undertale" width="100"/></a>
</p>
We all love [chat.openai.com](https://chat.openai.com), but... It's TERRIBLY laggy, has daily limits, and is only accessible through an archaic web interface.
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)
You can deploy your own bot, or use mine: [@jadvebot](https://t.me/jadvebot) (Our web: https://jadve.com)
## Features
- Low latency replies (it usually takes about 3-5 seconds)
- No request limits
- Message streaming (watch demo)
- GPT-4 and GPT-4 Turbo support
- GPT-4 Vision support
- Group Chat support (/help_group_chat to get instructions)
- DALLE 2 (choose 👩‍🎨 Artist mode to generate images)
- Voice message recognition
@@ -52,6 +50,7 @@ You can deploy your own bot, or use mine: [@chatgpt_karfly_bot](https://t.me/cha
- *2 Mar 2023*: Added support of [ChatGPT API](https://platform.openai.com/docs/guides/chat/introduction).
- *1 Aug 2023*: Added OpenAI API Base to config (useful while using OpenAI-compatible API like [LocalAI](https://github.com/go-skynet/LocalAI))
- *15 Nov 2023*: Added support of [GPT-4 Turbo](https://help.openai.com/en/articles/8555510-gpt-4-turbo)
- *2 Apt 2024*: Added [GPT-4 Vision](https://platform.openai.com/docs/guides/vision) support
## Bot commands
- `/retry` Regenerate last bot answer
@@ -108,7 +107,7 @@ You can be in this list:
## Contributors
- Main contributor: @karfly
- [Father.Bot](https://father.bot).
- [Jadve AI](https://jadve.com).
## References
1. [*Build ChatGPT from GPT-3*](https://learnprompting.org/docs/applied_prompting/build_chatgpt)
+13 -17
View File
@@ -185,9 +185,9 @@ async def _vision_message_handle_fn(
user_id = update.message.from_user.id
current_model = db.get_user_attribute(user_id, "current_model")
if current_model != "gpt-4-vision-preview":
if current_model != "gpt-4-vision-preview" and current_model != "gpt-4o":
await update.message.reply_text(
"🥲 Images processing is only available for <b>gpt-4-vision-preview</b> model. Please change your settings in /settings",
"🥲 Images processing is only available for <b>gpt-4-vision-preview</b> and <b>gpt-4o</b> model. Please change your settings in /settings",
parse_mode=ParseMode.HTML,
)
return
@@ -218,18 +218,11 @@ async def _vision_message_handle_fn(
try:
# send placeholder message to user
placeholder_message = await update.message.reply_text("...")
message = update.message.caption or update.message.text
message = update.message.caption or update.message.text or ''
# send typing action
await update.message.chat.send_action(action="typing")
if message is None or len(message) == 0:
await update.message.reply_text(
"🥲 You sent <b>empty message</b>. Please, try again!",
parse_mode=ParseMode.HTML,
)
return
dialog_messages = db.get_dialog_messages(user_id, dialog_id=None)
parse_mode = {"html": ParseMode.HTML, "markdown": ParseMode.MARKDOWN}[
config.chat_modes[chat_mode]["parse_mode"]
@@ -436,7 +429,7 @@ async def message_handle(update: Update, context: CallbackContext, message=None,
prev_answer = answer
# update user data
new_dialog_message = {"user": _message, "bot": answer, "date": datetime.now()}
new_dialog_message = {"user": [{"type": "text", "text": _message}], "bot": answer, "date": datetime.now()}
db.set_dialog_messages(
user_id,
@@ -466,11 +459,14 @@ async def message_handle(update: Update, context: CallbackContext, message=None,
await update.message.reply_text(text, parse_mode=ParseMode.HTML)
async with user_semaphores[user_id]:
if current_model == "gpt-4-vision-preview" or update.message.photo is not None and len(update.message.photo) > 0:
logger.error('gpt-4-vision-preview')
if current_model != "gpt-4-vision-preview":
current_model = "gpt-4-vision-preview"
db.set_user_attribute(user_id, "current_model", "gpt-4-vision-preview")
if current_model == "gpt-4-vision-preview" or current_model == "gpt-4o" or update.message.photo is not None and len(update.message.photo) > 0:
logger.error(current_model)
# What is this? ^^^
if current_model != "gpt-4o" and current_model != "gpt-4-vision-preview":
current_model = "gpt-4o"
db.set_user_attribute(user_id, "current_model", "gpt-4o")
task = asyncio.create_task(
_vision_message_handle_fn(update, context, use_new_dialog_timeout=use_new_dialog_timeout)
)
@@ -876,4 +872,4 @@ def run_bot() -> None:
if __name__ == "__main__":
run_bot()
run_bot()
+31 -17
View File
@@ -26,7 +26,7 @@ OPENAI_COMPLETION_OPTIONS = {
class ChatGPT:
def __init__(self, model="gpt-3.5-turbo"):
assert model in {"text-davinci-003", "gpt-3.5-turbo-16k", "gpt-3.5-turbo", "gpt-4", "gpt-4-1106-preview", "gpt-4-vision-preview"}, f"Unknown model: {model}"
assert model in {"text-davinci-003", "gpt-3.5-turbo-16k", "gpt-3.5-turbo", "gpt-4", "gpt-4o", "gpt-4-1106-preview", "gpt-4-vision-preview"}, f"Unknown model: {model}"
self.model = model
async def send_message(self, message, dialog_messages=[], chat_mode="assistant"):
@@ -37,7 +37,7 @@ class ChatGPT:
answer = None
while answer is None:
try:
if self.model in {"gpt-3.5-turbo-16k", "gpt-3.5-turbo", "gpt-4", "gpt-4-1106-preview", "gpt-4-vision-preview"}:
if self.model in {"gpt-3.5-turbo-16k", "gpt-3.5-turbo", "gpt-4", "gpt-4o", "gpt-4-1106-preview", "gpt-4-vision-preview"}:
messages = self._generate_prompt_messages(message, dialog_messages, chat_mode)
r = await openai.ChatCompletion.acreate(
@@ -78,7 +78,7 @@ class ChatGPT:
answer = None
while answer is None:
try:
if self.model in {"gpt-3.5-turbo-16k", "gpt-3.5-turbo", "gpt-4", "gpt-4-1106-preview"}:
if self.model in {"gpt-3.5-turbo-16k", "gpt-3.5-turbo", "gpt-4","gpt-4o", "gpt-4-1106-preview"}:
messages = self._generate_prompt_messages(message, dialog_messages, chat_mode)
r_gen = await openai.ChatCompletion.acreate(
@@ -138,7 +138,7 @@ class ChatGPT:
answer = None
while answer is None:
try:
if self.model == "gpt-4-vision-preview":
if self.model == "gpt-4-vision-preview" or self.model == "gpt-4o":
messages = self._generate_prompt_messages(
message, dialog_messages, chat_mode, image_buffer
)
@@ -186,7 +186,7 @@ class ChatGPT:
answer = None
while answer is None:
try:
if self.model == "gpt-4-vision-preview":
if self.model == "gpt-4-vision-preview" or self.model == "gpt-4o":
messages = self._generate_prompt_messages(
message, dialog_messages, chat_mode, image_buffer
)
@@ -254,25 +254,36 @@ class ChatGPT:
prompt = config.chat_modes[chat_mode]["prompt_start"]
messages = [{"role": "system", "content": prompt}]
user_messages = {"role": "user", "content": []}
for dialog_message in dialog_messages:
user_messages["content"].extend(dialog_message["user"])
messages.append({"role": "user", "content": dialog_message["user"]})
messages.append({"role": "assistant", "content": dialog_message["bot"]})
user_messages["content"].append({"type": "text", "text": message})
if image_buffer is not None:
user_messages["content"].append(
messages.append(
{
"type": "image",
"image": self._encode_image(image_buffer),
"role": "user",
"content": [
{
"type": "text",
"text": message,
},
{
"type": "image_url",
"image_url" : {
"url": f"data:image/jpeg;base64,{self._encode_image(image_buffer)}",
"detail":"high"
}
}
]
}
)
else:
messages.append({"role": "user", "content": message})
response = messages + ([user_messages] if len(user_messages["content"]) > 0 else [])
return response
return messages
def _postprocess_answer(self, answer):
answer = answer.strip()
@@ -296,6 +307,9 @@ class ChatGPT:
elif model == "gpt-4-vision-preview":
tokens_per_message = 3
tokens_per_name = 1
elif model == "gpt-4o":
tokens_per_message = 3
tokens_per_name = 1
else:
raise ValueError(f"Unknown model: {model}")
@@ -347,4 +361,4 @@ async def generate_images(prompt, n_images=4, size="512x512"):
async def is_content_acceptable(prompt):
r = await openai.Moderation.acreate(input=prompt)
return not all(r.results[0].categories.values())
return not all(r.results[0].categories.values())
+14 -2
View File
@@ -1,4 +1,4 @@
available_text_models: ["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4-1106-preview", "gpt-4-vision-preview", "gpt-4", "text-davinci-003"]
available_text_models: ["gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-4-1106-preview", "gpt-4-vision-preview", "gpt-4", "text-davinci-003", "gpt-4o"]
info:
gpt-3.5-turbo:
@@ -65,6 +65,18 @@ info:
smart: 5
fast: 4
cheap: 3
gpt-4o:
type: chat_completion
name: GPT-4o
description: GPT-4o is a special variant of GPT-4 designed for optimal performance and accuracy. Suitable for complex and detailed tasks.
price_per_1000_input_tokens: 0.03
price_per_1000_output_tokens: 0.06
scores:
smart: 5
fast: 2
cheap: 2
text-davinci-003:
type: completion
@@ -85,4 +97,4 @@ info:
whisper:
type: audio
price_per_1_min: 0.006
price_per_1_min: 0.006