diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index f6f0eceb1..937eb2cf6 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -126,7 +126,7 @@ async def stream_build(flow_id: str): params = vertex._built_object_repr() valid = True logger.debug( - f"Building node {params[:50]}{'...' if len(params) > 50 else ''}" + f"Building node {str(params)[:50]}{'...' if len(str(params)) > 50 else ''}" ) if vertex.artifacts: # The artifacts will be prompt variables diff --git a/src/backend/langflow/graph/vertex/types.py b/src/backend/langflow/graph/vertex/types.py index 17481b8a0..effd00071 100644 --- a/src/backend/langflow/graph/vertex/types.py +++ b/src/backend/langflow/graph/vertex/types.py @@ -213,23 +213,27 @@ class PromptVertex(Vertex): def _built_object_repr(self): if ( - self.artifacts - and self._built_object is not None - and hasattr(self._built_object, "format") + not self.artifacts + or self._built_object is None + or not hasattr(self._built_object, "format") ): - # We'll build the prompt with the artifacts - # to show the user what the prompt looks like - # with the variables filled in - artifacts = self.artifacts.copy() - # Remove the handle_keys from the artifacts - # so the prompt format doesn't break - artifacts.pop("handle_keys", None) - try: - return self._built_object.format(**artifacts) - except KeyError: - return super()._built_object_repr() - else: return super()._built_object_repr() + # We'll build the prompt with the artifacts + # to show the user what the prompt looks like + # with the variables filled in + artifacts = self.artifacts.copy() + # Remove the handle_keys from the artifacts + # so the prompt format doesn't break + artifacts.pop("handle_keys", None) + try: + template = self._built_object.format(**artifacts) + return ( + template + if isinstance(template, str) + else f"{self.vertex_type}({template})" + ) + except KeyError: + return str(self._built_object) class OutputParserVertex(Vertex): diff --git a/src/backend/langflow/interface/initialize/loading.py b/src/backend/langflow/interface/initialize/loading.py index 5418f6906..ed80b0adb 100644 --- a/src/backend/langflow/interface/initialize/loading.py +++ b/src/backend/langflow/interface/initialize/loading.py @@ -1,3 +1,4 @@ +import contextlib import json from typing import Any, Callable, Dict, List, Sequence, Type @@ -196,7 +197,7 @@ def instantiate_prompt(node_type, class_object, params: Dict): if "tools" not in params: params["tools"] = [] return ZeroShotAgent.create_prompt(**params) - if "MessagePromptTemplate" in node_type: + elif "MessagePromptTemplate" in node_type: # Then we only need the template from_template_params = { "template": params.pop("prompt", params.pop("template", "")) @@ -204,12 +205,12 @@ def instantiate_prompt(node_type, class_object, params: Dict): if not from_template_params.get("template"): raise ValueError("Prompt template is required") - return class_object.from_template(**from_template_params) + prompt = class_object.from_template(**from_template_params) - if node_type == "ChatPromptTemplate": - return class_object.from_messages(**params) - - prompt = class_object(**params) + elif node_type == "ChatPromptTemplate": + prompt = class_object.from_messages(**params) + else: + prompt = class_object(**params) format_kwargs: Dict[str, Any] = {} for input_variable in prompt.input_variables: @@ -221,18 +222,23 @@ def instantiate_prompt(node_type, class_object, params: Dict): variable, "get_format_instructions" ): format_kwargs[input_variable] = variable.get_format_instructions() - # check if is a list of Document elif isinstance(variable, List) and all( isinstance(item, Document) for item in variable ): # Format document to contain page_content and metadata # as one string separated by a newline - format_kwargs[input_variable] = "\n".join( - [ - f"Document:{item.page_content}\nMetadata:{item.metadata}" - for item in variable - ] - ) + if len(variable) > 1: + content = "\n".join( + [item.page_content for item in variable if item.page_content] + ) + else: + content = variable[0].page_content + # content could be a json list of strings + with contextlib.suppress(json.JSONDecodeError): + content = json.loads(content) + if isinstance(content, list): + content = ",".join([str(item) for item in content]) + format_kwargs[input_variable] = content # handle_keys will be a list but it does not exist yet # so we need to create it diff --git a/src/backend/langflow/template/frontend_node/tools.py b/src/backend/langflow/template/frontend_node/tools.py index 6b6903fdc..ece765ed7 100644 --- a/src/backend/langflow/template/frontend_node/tools.py +++ b/src/backend/langflow/template/frontend_node/tools.py @@ -109,7 +109,7 @@ class PythonFunctionToolNode(FrontendNode): ], ) description: str = "Python function to be executed." - base_classes: list[str] = ["Tool"] + base_classes: list[str] = ["BaseTool", "Tool"] def to_dict(self): return super().to_dict() diff --git a/src/frontend/src/index.css b/src/frontend/src/index.css index 407db8fb5..9925f19f2 100644 --- a/src/frontend/src/index.css +++ b/src/frontend/src/index.css @@ -6,8 +6,8 @@ /* TODO: Confirm that all colors here are found in tailwind config */ @layer base { - -:root { + + :root { --background: 0 0% 100%; /* hsl(0 0% 100%) */ --foreground: 222.2 47.4% 11.2%; /* hsl(222 47% 11%) */ --muted: 210 40% 98%; /* hsl(210 40% 98%) */ @@ -28,21 +28,24 @@ --destructive-foreground: 210 40% 98%; /* hsl(210 40% 98%) */ --radius: 0.5rem; --ring: 215 20.2% 65.1%; /* hsl(215 20% 65%) */ - + --round-btn-shadow: #00000063; - + --error-background: #fef2f2; --error-foreground: #991b1b; - + --success-background: #f0fdf4; --success-foreground: #14532d; --info-background: #f0f4fd; --info-foreground: #141653; - + --high-indigo: #4338ca; --medium-indigo: #6366f1; + --chat-bot-icon: #afe6ef; + --chat-user-icon: #aface9; + /* Colors that are shared in dark and light mode */ --blur-shared: #151923de; --build-trigger: #dc735b; @@ -915,16 +918,16 @@ The cursor: default; property value restores the browser's default cursor style } .form-modal-lock-true { - @apply bg-input text-black dark:bg-gray-700 dark:text-gray-300 + @apply bg-input text-black } .form-modal-no-input { @apply bg-input text-center text-black dark:bg-gray-700 dark:text-gray-300 } .form-modal-lock-false { - @apply bg-white text-black dark:bg-gray-900 dark:text-gray-300 + @apply bg-white text-black } .form-modal-lockchat { - @apply form-input focus:ring-ring focus:border-ring block w-full rounded-md border-gray-300 p-4 pr-16 custom-scroll dark:border-gray-600 sm:text-sm + @apply form-input focus:ring-ring focus:border-ring block w-full rounded-md border-border p-4 pr-16 custom-scroll sm:text-sm } .form-modal-send-icon-position { @apply absolute bottom-2 right-4 @@ -954,10 +957,10 @@ The cursor: default; property value restores the browser's default cursor style @apply relative flex h-8 w-8 items-center justify-center overflow-hidden rounded-md p-5 text-2xl } .form-modal-chat-bot-icon { - @apply form-modal-chat-img-box bg-[#afe6ef] + @apply form-modal-chat-img-box bg-chat-bot-icon } .form-modal-chat-user-icon { - @apply form-modal-chat-img-box bg-[#aface9] + @apply form-modal-chat-img-box bg-chat-user-icon } .form-modal-chat-icon-img { @apply absolute scale-[60%] @@ -972,7 +975,7 @@ The cursor: default; property value restores the browser's default cursor style @apply absolute -left-6 -top-3 cursor-pointer } .form-modal-chat-icon { - @apply h-4 w-4 animate-bounce dark:text-white + @apply h-4 w-4 animate-bounce } .form-modal-chat-thought-border { @apply rounded-md border border-ring/60 @@ -1041,13 +1044,13 @@ The cursor: default; property value restores the browser's default cursor style @apply flex-max-width h-full flex-col items-center justify-center text-center align-middle } .langflow-chat-span { - @apply text-lg text-gray-600 dark:text-gray-300 + @apply text-lg text-foreground } .langflow-chat-desc { - @apply w-2/4 rounded-md border border-gray-200 bg-muted px-6 py-8 dark:border-gray-700 dark:bg-gray-900 + @apply w-2/4 rounded-md border border-border bg-muted px-6 py-8 } .langflow-chat-desc-span { - @apply text-base text-gray-500 + @apply text-base text-muted-foreground } .langflow-chat-input-div { @apply flex-max-width flex-col items-center justify-between px-8 pb-6 @@ -1060,4 +1063,4 @@ The cursor: default; property value restores the browser's default cursor style @apply max-w-[30vw] max-h-[20vh] overflow-auto } -} \ No newline at end of file +} diff --git a/src/frontend/tailwind.config.js b/src/frontend/tailwind.config.js index b3d296560..739308b92 100644 --- a/src/frontend/tailwind.config.js +++ b/src/frontend/tailwind.config.js @@ -82,6 +82,8 @@ module.exports = { "status-yellow": "var(--status-yellow)", "success-background": "var(--success-background)", "success-foreground": "var(--success-foreground)", + "chat-bot-icon": "var(--chat-bot-icon)", + "chat-user-icon": "var(--chat-user-icon)", white: "var(--white)", border: "hsl(var(--border))",