diff --git a/requirements.txt b/requirements.txt index ab0638f..6f056cb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,4 +21,4 @@ psycopg2==2.9.7 openai==0.27.8 tiktoken==0.4.0 google-search-results==2.4.2 -flake8==6.1.0 +flake8==6.1.0 \ No newline at end of file diff --git a/src/app/flask_postgresql/api/response.py b/src/app/flask_postgresql/api/response.py index 8567bd0..f09303f 100644 --- a/src/app/flask_postgresql/api/response.py +++ b/src/app/flask_postgresql/api/response.py @@ -1,29 +1,15 @@ -from typing import List - from linebot.v3.messaging import ( ApiClient, Configuration, MessagingApi, ReplyMessageRequest, + TextMessage, ) from linebot.v3.messaging.api_response import ApiResponse -from linebot.v3.messaging.models.message import Message - - -def create_response( - configuration: Configuration, reply_token: str, messages: List[Message] -) -> ApiResponse: - """ - Creates a response using the Line Bot API. - Args: - configuration (Configuration): The configuration object for the API client. - reply_token (str): The token used to identify the reply message. - messages (List[Message]): The list of messages to be included in the response. - Returns: - ApiResponse: The API response object. - """ +def create_response(configuration: Configuration, reply_token: str, *results) -> ApiResponse: + messages = [TextMessage(text=result) for result in results] with ApiClient(configuration) as api_client: line_bot_api = MessagingApi(api_client) diff --git a/src/app/flask_postgresql/presenters/message_reply_presenter.py b/src/app/flask_postgresql/presenters/message_reply_presenter.py index cf39dfd..a97bdf0 100644 --- a/src/app/flask_postgresql/presenters/message_reply_presenter.py +++ b/src/app/flask_postgresql/presenters/message_reply_presenter.py @@ -1,10 +1,6 @@ """ Module for the EventPresenter """ -from typing import List - -from linebot.v3.messaging.models.message import Message - from src.interactor.dtos.event_dto import EventOutputDto from src.interactor.interfaces.presenters.message_reply_presenter import EventPresenterInterface @@ -12,7 +8,7 @@ class EventPresenter(EventPresenterInterface): """Class for the EventPresenter""" - def present(self, output_dto: EventOutputDto) -> List[Message]: + def present(self, output_dto: EventOutputDto) -> str: """ Present the output DTO. diff --git a/src/infrastructure/tools/__init__.py b/src/infrastructure/tools/__init__.py index 87f3d5f..f58f44b 100644 --- a/src/infrastructure/tools/__init__.py +++ b/src/infrastructure/tools/__init__.py @@ -3,7 +3,6 @@ from src.app.flask_postgresql.configs import Config -from .google_calendar import GoogleCalendarTool from .stock import CurrentStockPriceTool, StockPerformanceTool # initialize LangChain services @@ -17,5 +16,4 @@ ), CurrentStockPriceTool(), StockPerformanceTool(), - GoogleCalendarTool(), ] diff --git a/src/infrastructure/tools/google_calendar.py b/src/infrastructure/tools/google_calendar.py deleted file mode 100644 index a304fe7..0000000 --- a/src/infrastructure/tools/google_calendar.py +++ /dev/null @@ -1,70 +0,0 @@ -import datetime -import urllib -from typing import Optional, Type - -from langchain.tools import BaseTool -from pydantic import BaseModel, Field - - -def create_gcal_url( - title="What?", date="20230524T180000/20230524T220000", location="Where?", description="" -): - """ - Generate a Google Calendar URL for creating a new event. - - Args: - title (str): The title of the event. Defaults to "What?". - date (str): The date and time of the event in the format "yyyyMMddTHHmmss/yyyyMMddTHHmmss". - Defaults to "20230524T180000/20230524T220000". - location (str): The location of the event. Defaults to "Where?". - description (str): The description of the event. Defaults to an empty string. - - Returns: - str: The URL for creating a new event in Google Calendar. - - """ - - base_url = "https://www.google.com/calendar/render?action=TEMPLATE" - event_url = f"{base_url}&text={urllib.parse.quote(title)}&dates={date}\ - &location={urllib.parse.quote(location)}&details={urllib.parse.quote(description)}" - - return event_url + "&openExternalBrowser=1" - - -class GoogleCalendarGeneratorInput(BaseModel): - """Input for Google Calendar Generator.""" - - dates: str = Field( - ..., - description=f"Datetime symbol if text contained. format should be \ - 'YYYYMMDDTHHMMSS/YYYYMMDDTHHMMSS'. Current time is {datetime.date.today()}", - ) - title: str = Field(..., description="Calendar Title symbol for reserve schedule.") - description: str = Field( - ..., description="Calendar Summary text symbol for schedule description." - ) - location: str = Field(..., description="Calendar location symbol for reservation.") - - -class GoogleCalendarTool(BaseTool): - name = "google_calendar_reservation" - description = "Generate Google Calendar url from user text first when containing time, date." - args_schema: Optional[Type[BaseModel]] = GoogleCalendarGeneratorInput - - def _run(self, dates: str, title: str, description: str, location: str): - """ - Generates a Google Calendar URL based on the given parameters. - - Args: - dates (str): The dates of the event. - title (str): The title of the event. - description (str): The description of the event. - location (str): The location of the event. - - Returns: - str: The generated Google Calendar URL. - """ - - result = self.create_gcal_url(title, dates, location, description) - - return result diff --git a/src/interactor/dtos/event_dto.py b/src/interactor/dtos/event_dto.py index cee0ac6..669fa7f 100644 --- a/src/interactor/dtos/event_dto.py +++ b/src/interactor/dtos/event_dto.py @@ -3,9 +3,7 @@ from dataclasses import asdict, dataclass -from typing import Dict, List - -from linebot.v3.messaging.models.message import Message +from typing import Dict @dataclass @@ -26,7 +24,7 @@ class EventOutputDto: window: Dict user_input: str - response: List[Message] + response: str def to_dict(self): """Convert data into dictionary""" diff --git a/src/interactor/interfaces/presenters/message_reply_presenter.py b/src/interactor/interfaces/presenters/message_reply_presenter.py index a159c2e..a6a1c47 100644 --- a/src/interactor/interfaces/presenters/message_reply_presenter.py +++ b/src/interactor/interfaces/presenters/message_reply_presenter.py @@ -3,9 +3,7 @@ from abc import ABC, abstractmethod -from typing import List - -from linebot.v3.messaging.models.message import Message +from typing import Dict from src.interactor.dtos.event_dto import EventOutputDto @@ -14,5 +12,5 @@ class EventPresenterInterface(ABC): """Class for the Interface of the WindowPresenter""" @abstractmethod - def present(self, output_dto: EventOutputDto) -> List[Message]: + def present(self, output_dto: EventOutputDto) -> Dict: """Present the Window""" diff --git a/src/interactor/use_cases/create_text_message_reply.py b/src/interactor/use_cases/create_text_message_reply.py index cc3b998..0d24e36 100644 --- a/src/interactor/use_cases/create_text_message_reply.py +++ b/src/interactor/use_cases/create_text_message_reply.py @@ -1,10 +1,6 @@ """ This module is responsible for creating a new window. """ -from typing import List - from langchain.agents import AgentExecutor -from linebot.v3.messaging.models import TextMessage -from linebot.v3.messaging.models.message import Message from src.interactor.dtos.event_dto import EventInputDto, EventOutputDto from src.interactor.interfaces.logger.logger import LoggerInterface @@ -47,30 +43,15 @@ def _get_agent_executor(self, input_dto: EventInputDto) -> AgentExecutor: ) return agent_executor - def execute(self, input_dto: EventInputDto): - """ - Executes the given event input DTO. - - Args: - input_dto (EventInputDto): The event input DTO containing the necessary information for execution. - - Returns: - EventOutputDto: The output DTO containing the result of the execution. - - Raises: - None. - """ + def execute(self, input_dto: EventInputDto) -> str: validator = EventInputDtoValidator(input_dto.to_dict()) validator.validate() - response: List[Message] = [] - if input_dto.window.get("is_muting") is True: - response.append(TextMessage(text="靜悄悄的,什麼都沒有發生。")) + response = "靜悄悄的,什麼都沒有發生。" else: agent_executor = self._get_agent_executor(input_dto) - result = agent_executor.run(input=input_dto.user_input) - response.append(TextMessage(text=result)) + response = agent_executor.run(input=input_dto.user_input) output_dto = EventOutputDto( window=input_dto.window, diff --git a/src/interactor/use_cases/create_text_message_reply_test.py b/src/interactor/use_cases/create_text_message_reply_test.py index 47bc4de..836cec1 100644 --- a/src/interactor/use_cases/create_text_message_reply_test.py +++ b/src/interactor/use_cases/create_text_message_reply_test.py @@ -1,7 +1,5 @@ from unittest import mock -from linebot.v3.messaging.models import TextMessage - from src.interactor.dtos.event_dto import EventInputDto, EventOutputDto from src.interactor.interfaces.logger.logger import LoggerInterface from src.interactor.interfaces.presenters.message_reply_presenter import EventPresenterInterface @@ -37,7 +35,7 @@ def test_new_user_create_text_message_reply(mocker: mock, fixture_window): logger_mock.log_info.assert_called_once_with("Create reply successfully") output_dto = EventOutputDto( - window=fixture_window, user_input="Test input", response=[TextMessage(text="Test output")] + window=fixture_window, user_input="Test input", response="Test output" ) presenter_mock.present.assert_called_once_with(output_dto) assert result == "Test output" @@ -71,7 +69,7 @@ def test_regular_create_text_message_reply(mocker: mock, fixture_window): logger_mock.log_info.assert_called_once_with("Create reply successfully") output_dto = EventOutputDto( - window=fixture_window, user_input="Test input", response=[TextMessage(text="Test output")] + window=fixture_window, user_input="Test input", response="Test output" ) presenter_mock.present.assert_called_once_with(output_dto) assert result == "Test output" @@ -106,7 +104,7 @@ def test_create_text_message_reply_if_window_is_muting(mocker: mock, fixture_win logger_mock.log_info.assert_called_once_with("Create reply successfully") output_dto = EventOutputDto( - window=fixture_window, user_input="Test input", response=[TextMessage(text="靜悄悄的,什麼都沒有發生。")] + window=fixture_window, user_input="Test input", response="靜悄悄的,什麼都沒有發生。" ) presenter_mock.present.assert_called_once_with(output_dto) assert result == "Test output"