From 3a3ffba6bddef9d46dc9cbe22bef693ce1cfed76 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 27 Feb 2024 14:55:23 -0300 Subject: [PATCH 1/4] Remove unused prompt.py file --- src/backend/langflow/utils/prompt.py | 58 ---------------------------- 1 file changed, 58 deletions(-) delete mode 100644 src/backend/langflow/utils/prompt.py diff --git a/src/backend/langflow/utils/prompt.py b/src/backend/langflow/utils/prompt.py deleted file mode 100644 index 871193f45..000000000 --- a/src/backend/langflow/utils/prompt.py +++ /dev/null @@ -1,58 +0,0 @@ -from typing import Any, Union - -from langchain_core.prompts import PromptTemplate as LCPromptTemplate -from llama_index.prompts import PromptTemplate as LIPromptTemplate - -PromptTemplateTypes = Union[LCPromptTemplate, LIPromptTemplate] - - -class GenericPromptTemplate: - def __init__(self, prompt_template: PromptTemplateTypes): - object.__setattr__(self, "prompt_template", prompt_template) - - @property - def input_keys(self): - prompt_template = object.__getattribute__(self, "prompt_template") - if isinstance(prompt_template, LCPromptTemplate): - return prompt_template.input_variables - elif isinstance(prompt_template, LIPromptTemplate): - return prompt_template.template_vars - else: - raise TypeError(f"Unknown prompt template type {type(prompt_template)}") - - def to_lc_prompt(self): - prompt_template = object.__getattribute__(self, "prompt_template") - if isinstance(prompt_template, LCPromptTemplate): - return prompt_template - elif isinstance(prompt_template, LIPromptTemplate): - return LCPromptTemplate.from_template(prompt_template.get_template()) - else: - raise TypeError(f"Unknown prompt template type {type(prompt_template)}") - - def to_li_prompt(self): - prompt_template = object.__getattribute__(self, "prompt_template") - if isinstance(prompt_template, LIPromptTemplate): - return prompt_template - elif isinstance(prompt_template, LCPromptTemplate): - return LIPromptTemplate(template=prompt_template.template) - else: - raise TypeError(f"Unknown prompt template type {type(prompt_template)}") - - def __or__(self, other): - prompt_template = object.__getattribute__(self, "prompt_template") - if isinstance(prompt_template, LIPromptTemplate): - return self.to_lc_prompt() | other - else: - raise TypeError(f"Unknown prompt template type {type(other)}") - - def __getattribute__(self, name: str) -> Any: - if name in { - "input_keys", - "to_lc_prompt", - "to_li_prompt", - "__or__", - "prompt_template", - }: - return object.__getattribute__(self, name) - prompt_template = object.__getattribute__(self, "prompt_template") - return getattr(prompt_template, name) From 99803c53f7ebc9fa29c80bc9def3d8cd0585e5a7 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 27 Feb 2024 15:30:47 -0300 Subject: [PATCH 2/4] Add run_id to VerticesOrderResponse --- src/backend/langflow/api/v1/chat.py | 4 +++- src/backend/langflow/api/v1/schemas.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index ca067ce6f..7f85bb211 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -1,5 +1,6 @@ import time from typing import Optional +import uuid from fastapi import ( APIRouter, @@ -120,7 +121,8 @@ async def get_vertices( # Now vertices is a list of lists # We need to get the id of each vertex # and return the same structure but only with the ids - return VerticesOrderResponse(ids=vertices) + run_id = uuid.uuid4() + return VerticesOrderResponse(ids=vertices, run_id=run_id) except Exception as exc: logger.error(f"Error checking build status: {exc}") diff --git a/src/backend/langflow/api/v1/schemas.py b/src/backend/langflow/api/v1/schemas.py index 38db8f85a..0c33fdb36 100644 --- a/src/backend/langflow/api/v1/schemas.py +++ b/src/backend/langflow/api/v1/schemas.py @@ -225,6 +225,7 @@ class ApiKeyCreateRequest(BaseModel): class VerticesOrderResponse(BaseModel): ids: List[List[str]] + run_id: UUID class ResultDataResponse(BaseModel): From ce32f49a2ebc50dbe8492a8aeec7bdfbf9c942df Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 27 Feb 2024 15:34:25 -0300 Subject: [PATCH 3/4] Refactor ChatInput and ChatOutput components --- .../langflow/components/io/ChatInput.py | 52 ++------- .../langflow/components/io/ChatOutput.py | 57 ++-------- src/backend/langflow/io/__init__.py | 0 src/backend/langflow/io/schema.py | 101 ++++++++++++++++++ 4 files changed, 120 insertions(+), 90 deletions(-) create mode 100644 src/backend/langflow/io/__init__.py create mode 100644 src/backend/langflow/io/schema.py diff --git a/src/backend/langflow/components/io/ChatInput.py b/src/backend/langflow/components/io/ChatInput.py index 0666f92d1..653054e0a 100644 --- a/src/backend/langflow/components/io/ChatInput.py +++ b/src/backend/langflow/components/io/ChatInput.py @@ -1,36 +1,14 @@ from typing import Optional, Union -from langflow import CustomComponent from langflow.field_typing import Text +from langflow.io.schema import ChatComponent from langflow.schema import Record -class ChatInput(CustomComponent): +class ChatInput(ChatComponent): display_name = "Chat Input" description = "Used to get user input from the chat." - def build_config(self): - return { - "input_value": { - "input_types": ["Text"], - "display_name": "Message", - "multiline": True, - }, - "sender": { - "options": ["Machine", "User"], - "display_name": "Sender Type", - }, - "sender_name": {"display_name": "Sender Name"}, - "session_id": { - "display_name": "Session ID", - "info": "Session ID of the chat history.", - }, - "return_record": { - "display_name": "Return Record", - "info": "Return the message as a record containing the sender, sender_name, and session_id.", - }, - } - def build( self, sender: Optional[str] = "User", @@ -39,22 +17,10 @@ class ChatInput(CustomComponent): session_id: Optional[str] = None, return_record: Optional[bool] = False, ) -> Union[Text, Record]: - if return_record: - if isinstance(input_value, Record): - # Update the data of the record - input_value.data["sender"] = sender - input_value.data["sender_name"] = sender_name - input_value.data["session_id"] = session_id - else: - input_value = Record( - text=input_value, - data={ - "sender": sender, - "sender_name": sender_name, - "session_id": session_id, - }, - ) - if not input_value: - input_value = "" - self.status = input_value - return input_value + return super().build( + sender=sender, + sender_name=sender_name, + input_value=input_value, + session_id=session_id, + return_record=return_record, + ) diff --git a/src/backend/langflow/components/io/ChatOutput.py b/src/backend/langflow/components/io/ChatOutput.py index 72667374f..e4c5d03ee 100644 --- a/src/backend/langflow/components/io/ChatOutput.py +++ b/src/backend/langflow/components/io/ChatOutput.py @@ -9,55 +9,18 @@ class ChatOutput(CustomComponent): display_name = "Chat Output" description = "Used to send a message to the chat." - field_config = { - "code": { - "show": True, - } - } - - def build_config(self): - return { - "input_value": {"input_types": ["Text"], "display_name": "Message"}, - "sender": { - "options": ["Machine", "User"], - "display_name": "Sender Type", - }, - "sender_name": {"display_name": "Sender Name"}, - "session_id": { - "display_name": "Session ID", - "info": "Session ID of the chat history.", - "input_types": ["Text"], - }, - "return_record": { - "display_name": "Return Record", - "info": "Return the message as a record containing the sender, sender_name, and session_id.", - }, - } - def build( self, - sender: Optional[str] = "Machine", - sender_name: Optional[str] = "AI", - session_id: Optional[str] = None, + sender: Optional[str] = "User", + sender_name: Optional[str] = "User", input_value: Optional[str] = None, + session_id: Optional[str] = None, return_record: Optional[bool] = False, ) -> Union[Text, Record]: - if return_record: - if isinstance(input_value, Record): - # Update the data of the record - input_value.data["sender"] = sender - input_value.data["sender_name"] = sender_name - input_value.data["session_id"] = session_id - else: - input_value = Record( - text=input_value, - data={ - "sender": sender, - "sender_name": sender_name, - "session_id": session_id, - }, - ) - if not input_value: - input_value = "" - self.status = input_value - return input_value + return super().build( + sender=sender, + sender_name=sender_name, + input_value=input_value, + session_id=session_id, + return_record=return_record, + ) diff --git a/src/backend/langflow/io/__init__.py b/src/backend/langflow/io/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/langflow/io/schema.py b/src/backend/langflow/io/schema.py new file mode 100644 index 000000000..d83d3472e --- /dev/null +++ b/src/backend/langflow/io/schema.py @@ -0,0 +1,101 @@ +import warnings +from typing import Optional, Union + +from langflow import CustomComponent +from langflow.field_typing import Text +from langflow.memory import add_messages +from langflow.schema import Record + + +class ChatComponent(CustomComponent): + display_name = "Chat Component" + description = "Use as base for chat components." + + def build_config(self): + return { + "input_value": { + "input_types": ["Text"], + "display_name": "Message", + "multiline": True, + }, + "sender": { + "options": ["Machine", "User"], + "display_name": "Sender Type", + }, + "sender_name": {"display_name": "Sender Name"}, + "session_id": { + "display_name": "Session ID", + "info": "If provided, the message will be stored in the memory.", + }, + "return_record": { + "display_name": "Return Record", + "info": "Return the message as a record containing the sender, sender_name, and session_id.", + }, + } + + def store_message( + self, + message: Union[Text, Record], + session_id: Optional[str] = None, + sender: Optional[str] = None, + sender_name: Optional[str] = None, + ) -> list[Record]: + if not message: + warnings.warn("No message provided.") + return [] + + if not session_id or not sender or not sender_name: + raise ValueError( + "All of session_id, sender, and sender_name must be provided." + ) + + if not record: + record = [] + if not session_id or not sender or not sender_name: + raise ValueError + for text in text: + record = Record( + text=text, + data={ + "session_id": session_id, + "sender": sender, + "sender_name": sender_name, + }, + ) + record.append(record) + elif isinstance(record, Record): + record = [record] + + self.status = record + record = add_messages(record) + return record + + def build( + self, + sender: Optional[str] = "User", + sender_name: Optional[str] = "User", + input_value: Optional[str] = None, + session_id: Optional[str] = None, + return_record: Optional[bool] = False, + ) -> Union[Text, Record]: + if return_record: + if isinstance(input_value, Record): + # Update the data of the record + input_value.data["sender"] = sender + input_value.data["sender_name"] = sender_name + input_value.data["session_id"] = session_id + else: + input_value = Record( + text=input_value, + data={ + "sender": sender, + "sender_name": sender_name, + "session_id": session_id, + }, + ) + if not input_value: + input_value = "" + self.status = input_value + if session_id: + self.store_message(input_value, session_id, sender, sender_name) + return input_value From 223db74410a09475c7b773ab16b205de07932c7f Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 27 Feb 2024 15:37:56 -0300 Subject: [PATCH 4/4] Add run_id to VerticesOrderTypeAPI --- src/frontend/src/types/api/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/src/types/api/index.ts b/src/frontend/src/types/api/index.ts index 3e9f4a0f5..6663692dc 100644 --- a/src/frontend/src/types/api/index.ts +++ b/src/frontend/src/types/api/index.ts @@ -135,6 +135,7 @@ export type Component = { export type VerticesOrderTypeAPI = { ids: Array>; + run_id: string; }; export type VertexBuildTypeAPI = {