-
Notifications
You must be signed in to change notification settings - Fork 588
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: WillShang <willshang76@gmail.com>
- Loading branch information
1 parent
c875d25
commit 27cfb19
Showing
6 changed files
with
245 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== | ||
# Licensed under the Apache License, Version 2.0 (the “License”); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an “AS IS” BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== | ||
import os | ||
from typing import TYPE_CHECKING, Optional | ||
|
||
from camel.agents import ChatAgent | ||
from camel.messages import BaseMessage | ||
|
||
# Conditionally import telebot types only for type checking | ||
if TYPE_CHECKING: | ||
from telebot.types import Message # type: ignore[import-untyped] | ||
|
||
|
||
class TelegramBot: | ||
r"""Represents a Telegram bot that is powered by an agent. | ||
Attributes: | ||
chat_agent (ChatAgent): Chat agent that will power the bot. | ||
telegram_token (str, optional): The bot token. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
chat_agent: ChatAgent, | ||
telegram_token: Optional[str] = None, | ||
) -> None: | ||
self.chat_agent = chat_agent | ||
|
||
if not telegram_token: | ||
self.token = os.getenv('TELEGRAM_TOKEN') | ||
if not self.token: | ||
raise ValueError( | ||
"`TELEGRAM_TOKEN` not found in environment variables. " | ||
"Get it from t.me/BotFather." | ||
) | ||
else: | ||
self.token = telegram_token | ||
|
||
try: | ||
import telebot # type: ignore[import-untyped] | ||
except ImportError: | ||
raise ImportError( | ||
"Please install `telegram_bot` first. " | ||
"You can install it by running " | ||
"`pip install pyTelegramBotAPI`." | ||
) | ||
self.bot = telebot.TeleBot(token=self.token) | ||
|
||
# Register the message handler within the constructor | ||
self.bot.message_handler(func=lambda message: True)(self.on_message) | ||
|
||
def run(self) -> None: | ||
r"""Start the Telegram bot.""" | ||
print("Telegram bot is running...") | ||
self.bot.infinity_polling() | ||
|
||
def on_message(self, message: 'Message') -> None: | ||
r"""Handles incoming messages from the user. | ||
Args: | ||
message (types.Message): The incoming message object. | ||
""" | ||
self.chat_agent.reset() | ||
|
||
if not message.text: | ||
return | ||
|
||
user_msg = BaseMessage.make_user_message( | ||
role_name="User", content=message.text | ||
) | ||
assistant_response = self.chat_agent.step(user_msg) | ||
|
||
self.bot.reply_to(message, assistant_response.msg.content) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== | ||
# Licensed under the Apache License, Version 2.0 (the “License”); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an “AS IS” BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== | ||
|
||
from camel.agents import ChatAgent | ||
from camel.bots.telegram_bot import TelegramBot | ||
from camel.messages import BaseMessage | ||
|
||
|
||
def main(model=None) -> None: | ||
assistant_sys_msg = BaseMessage.make_assistant_message( | ||
role_name="Assistant", | ||
content="You are a helpful assistant.", | ||
) | ||
|
||
agent = ChatAgent(assistant_sys_msg, model_type=model) | ||
bot = TelegramBot(agent) | ||
bot.run() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== | ||
# Licensed under the Apache License, Version 2.0 (the “License”); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an “AS IS” BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. =========== | ||
import unittest | ||
from unittest.mock import MagicMock, patch | ||
|
||
from camel.agents import ChatAgent | ||
from camel.bots.telegram_bot import TelegramBot | ||
from camel.messages import BaseMessage | ||
|
||
|
||
class TestTelegramBot(unittest.TestCase): | ||
def setUp(self): | ||
self.chat_agent_mock = MagicMock(spec=ChatAgent) | ||
self.telegram_token = "fake_token" | ||
|
||
def test_init_token_provided_uses_provided_token(self): | ||
bot = TelegramBot( | ||
self.chat_agent_mock, telegram_token=self.telegram_token | ||
) | ||
self.assertEqual(bot.token, self.telegram_token) | ||
|
||
@patch('telebot.TeleBot') | ||
def test_on_message(self, mock_telebot): | ||
# Setup bot and mocks for message handling | ||
bot = TelegramBot( | ||
self.chat_agent_mock, telegram_token=self.telegram_token | ||
) | ||
mock_bot_instance = mock_telebot.return_value | ||
|
||
message_mock = MagicMock() | ||
message_mock.text = "Hello, world!" | ||
|
||
user_msg_mock = BaseMessage.make_user_message( | ||
"User", content="Hello, world!" | ||
) | ||
response_msg_mock = MagicMock(msg=MagicMock(content="Hello back!")) | ||
|
||
self.chat_agent_mock.reset = MagicMock() | ||
self.chat_agent_mock.step = MagicMock(return_value=response_msg_mock) | ||
|
||
# Test the message handling | ||
bot.on_message(message_mock) | ||
|
||
# Check if the chat agent's methods are called appropriately | ||
self.chat_agent_mock.reset.assert_called_once() | ||
self.chat_agent_mock.step.assert_called_once_with(user_msg_mock) | ||
|
||
# Check if the bot replies with the correct message | ||
mock_bot_instance.reply_to.assert_called_once_with( | ||
message_mock, "Hello back!" | ||
) | ||
|
||
@patch('telebot.TeleBot') | ||
def test_run_starts_polling(self, mock_telebot): | ||
bot = TelegramBot( | ||
self.chat_agent_mock, telegram_token=self.telegram_token | ||
) | ||
mock_bot_instance = mock_telebot.return_value | ||
bot.run() | ||
mock_bot_instance.infinity_polling.assert_called_once() | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |