Merge remote-tracking branch 'origin/two_edges_dev' into two_edges

This commit is contained in:
ogabrielluiz 2024-06-14 14:09:12 -03:00
commit 6f40941925
83 changed files with 1427 additions and 2465 deletions

View file

@ -1,3 +1,4 @@
from typing import Optional
from langchain_core.embeddings import Embeddings
from langchain_openai import AzureOpenAIEmbeddings
from pydantic.v1 import SecretStr
@ -44,6 +45,11 @@ class AzureOpenAIEmbeddingsComponent(CustomComponent):
"password": True,
},
"code": {"show": False},
"dimensions": {
"display_name": "Dimensions",
"info": "The number of dimensions the resulting output embeddings should have. Only supported by certain models.",
"advanced": True,
},
}
def build(
@ -52,6 +58,7 @@ class AzureOpenAIEmbeddingsComponent(CustomComponent):
azure_deployment: str,
api_version: str,
api_key: str,
dimensions: Optional[int] = None,
) -> Embeddings:
if api_key:
azure_api_key = SecretStr(api_key)
@ -63,6 +70,7 @@ class AzureOpenAIEmbeddingsComponent(CustomComponent):
azure_deployment=azure_deployment,
api_version=api_version,
api_key=azure_api_key,
dimensions=dimensions,
)
except Exception as e:

View file

@ -84,6 +84,11 @@ class OpenAIEmbeddingsComponent(CustomComponent):
"advanced": True,
},
"tiktoken_enable": {"display_name": "TikToken Enable", "advanced": True},
"dimensions": {
"display_name": "Dimensions",
"info": "The number of dimensions the resulting output embeddings should have. Only supported by certain models.",
"advanced": True,
},
}
def build(
@ -109,6 +114,7 @@ class OpenAIEmbeddingsComponent(CustomComponent):
skip_empty: bool = False,
tiktoken_enable: bool = True,
tiktoken_model_name: Optional[str] = None,
dimensions: Optional[int] = None,
) -> Embeddings:
# This is to avoid errors with Vector Stores (e.g Chroma)
if disallowed_special == ["all"]:
@ -140,4 +146,5 @@ class OpenAIEmbeddingsComponent(CustomComponent):
show_progress_bar=show_progress_bar,
skip_empty=skip_empty,
tiktoken_model_name=tiktoken_model_name,
dimensions=dimensions,
)

View file

@ -53,7 +53,7 @@ class ChatOpenAIComponent(CustomComponent):
self,
max_tokens: Optional[int] = 0,
model_kwargs: NestedDict = {},
model_name: str = "gpt-4o",
model_name: str = "gpt-3.5-turbo",
openai_api_base: Optional[str] = None,
openai_api_key: Optional[str] = None,
temperature: float = 0.7,

View file

@ -28,7 +28,7 @@ class AstraDBSearchComponent(LCVectorStoreComponent):
"info": "The name of the collection within Astra DB where the vectors will be stored.",
},
"token": {
"display_name": "Token",
"display_name": "Astra DB Application Token",
"info": "Authentication token for accessing Astra DB.",
"password": True,
},

View file

@ -3,7 +3,6 @@ from typing import List, Optional
import chromadb
from chromadb.config import Settings
from langchain_chroma import Chroma
from langflow.components.vectorstores.base.model import LCVectorStoreComponent
from langflow.field_typing import Embeddings, Text
from langflow.schema import Data
@ -104,10 +103,11 @@ class ChromaSearchComponent(LCVectorStoreComponent):
client = chromadb.HttpClient(settings=chroma_settings)
if index_directory:
index_directory = self.resolve_path(index_directory)
vector_store = Chroma(
embedding_function=embedding,
collection_name=collection_name,
persist_directory=index_directory,
persist_directory=index_directory or None,
client=client,
)

View file

@ -25,7 +25,7 @@ class AstraDBVectorStoreComponent(CustomComponent):
"info": "The name of the collection within Astra DB where the vectors will be stored.",
},
"token": {
"display_name": "Token",
"display_name": "Astra DB Application Token",
"info": "Authentication token for accessing Astra DB.",
"password": True,
},

View file

@ -1,9 +1,11 @@
from typing import Any, Union
from enum import Enum
from typing import Any, Generator, Union
from langchain_core.documents import Document
from pydantic import BaseModel
from langflow.interface.utils import extract_input_variables_from_prompt
from langflow.schema.message import Message
class UnbuiltObject:
@ -14,6 +16,16 @@ class UnbuiltResult:
pass
class ArtifactType(str, Enum):
TEXT = "text"
RECORD = "record"
OBJECT = "object"
ARRAY = "array"
STREAM = "stream"
UNKNOWN = "unknown"
MESSAGE = "message"
def validate_prompt(prompt: str):
"""Validate prompt."""
if extract_input_variables_from_prompt(prompt):
@ -50,3 +62,37 @@ def serialize_field(value):
elif isinstance(value, str):
return {"result": value}
return value
def get_artifact_type(value, build_result) -> str:
result = ArtifactType.UNKNOWN
match value:
case Record():
result = ArtifactType.RECORD
case str():
result = ArtifactType.TEXT
case dict():
result = ArtifactType.OBJECT
case list():
result = ArtifactType.ARRAY
case Message():
result = ArtifactType.MESSAGE
if result == ArtifactType.UNKNOWN:
if isinstance(build_result, Generator):
result = ArtifactType.STREAM
elif isinstance(value, Message) and isinstance(value.text, Generator):
result = ArtifactType.STREAM
return result.value
def post_process_raw(raw, artifact_type: str):
if artifact_type == ArtifactType.STREAM.value:
raw = ""
return raw

View file

@ -181,6 +181,9 @@ def update_new_output(data):
}
)
deduplicated_outputs = []
if source_node is None:
source_node = {"data": {"node": {"outputs": []}}}
for output in source_node["data"]["node"]["outputs"]:
if output["name"] not in [d["name"] for d in deduplicated_outputs]:
deduplicated_outputs.append(output)

View file

@ -8,17 +8,12 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-k39HS",
"name": "text_output",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-njtka",
"inputTypes": [
"Text",
"Message"
],
"inputTypes": ["Text", "Message"],
"type": "str"
}
},
@ -38,18 +33,12 @@
"dataType": "Prompt",
"id": "Prompt-uxBqP",
"name": "prompt",
"output_types": [
"Prompt"
]
"output_types": ["Prompt"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-k39HS",
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"inputTypes": ["Text", "Data", "Prompt"],
"type": "str"
}
},
@ -69,19 +58,12 @@
"dataType": "ChatInput",
"id": "ChatInput-P3fgL",
"name": "message",
"output_types": [
"Message"
]
"output_types": ["Message"]
},
"targetHandle": {
"fieldName": "user_input",
"id": "Prompt-uxBqP",
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"inputTypes": ["Document", "Message", "Record", "Text"],
"type": "str"
}
},
@ -102,16 +84,10 @@
"display_name": "Prompt",
"id": "Prompt-uxBqP",
"node": {
"base_classes": [
"object",
"str",
"Text"
],
"base_classes": ["object", "str", "Text"],
"beta": false,
"custom_fields": {
"template": [
"user_input"
]
"template": ["user_input"]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -134,9 +110,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": [
"Prompt"
],
"types": ["Prompt"],
"value": "__UNDEFINED__"
},
{
@ -145,9 +119,7 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
}
],
@ -178,9 +150,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -201,12 +171,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"input_types": ["Document", "Message", "Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -244,11 +209,7 @@
"display_name": "OpenAI",
"id": "OpenAIModel-k39HS",
"node": {
"base_classes": [
"object",
"Text",
"str"
],
"base_classes": ["object", "Text", "str"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -286,9 +247,7 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
},
{
@ -297,9 +256,7 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": [
"BaseLanguageModel"
],
"types": ["BaseLanguageModel"],
"value": "__UNDEFINED__"
}
],
@ -330,11 +287,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text",
"Data",
"Prompt"
],
"input_types": ["Text", "Data", "Prompt"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -354,9 +307,7 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -376,9 +327,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -398,9 +347,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
@ -418,7 +365,7 @@
"show": true,
"title_case": false,
"type": "str",
"value": "gpt-4o"
"value": "gpt-3.5-turbo"
},
"openai_api_base": {
"advanced": true,
@ -427,9 +374,7 @@
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -449,9 +394,7 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": true,
"multiline": false,
@ -471,9 +414,7 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -493,9 +434,7 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -515,9 +454,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -553,12 +490,7 @@
"data": {
"id": "ChatOutput-njtka",
"node": {
"base_classes": [
"Record",
"Text",
"str",
"object"
],
"base_classes": ["Record", "Text", "str", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -583,9 +515,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -616,10 +546,7 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": [
"Text",
"Message"
],
"input_types": ["Text", "Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -639,17 +566,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -665,9 +587,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -687,9 +607,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -725,12 +643,7 @@
"data": {
"id": "ChatInput-P3fgL",
"node": {
"base_classes": [
"object",
"Record",
"str",
"Text"
],
"base_classes": ["object", "Record", "str", "Text"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -754,9 +667,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -807,17 +718,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -833,9 +739,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -855,9 +759,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -901,4 +803,4 @@
"is_component": false,
"last_tested_version": "1.0.0a4",
"name": "Basic Prompting (Hello, World)"
}
}

View file

@ -13,12 +13,7 @@
"targetHandle": {
"fieldName": "reference_2",
"id": "Prompt-Rse03",
"inputTypes": [
"Document",
"BaseOutputParser",
"Record",
"Text"
],
"inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
"type": "str"
}
},
@ -39,17 +34,12 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-gi29P",
"name": "text_output",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-JPlxl",
"inputTypes": [
"Text",
"Message"
],
"inputTypes": ["Text", "Message"],
"type": "str"
}
},
@ -74,12 +64,7 @@
"targetHandle": {
"fieldName": "reference_1",
"id": "Prompt-Rse03",
"inputTypes": [
"Document",
"BaseOutputParser",
"Record",
"Text"
],
"inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
"type": "str"
}
},
@ -99,19 +84,12 @@
"dataType": "TextInput",
"id": "TextInput-og8Or",
"name": "Text",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "instructions",
"id": "Prompt-Rse03",
"inputTypes": [
"Document",
"BaseOutputParser",
"Record",
"Text"
],
"inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
"type": "str"
}
},
@ -131,18 +109,12 @@
"dataType": "Prompt",
"id": "Prompt-Rse03",
"name": "prompt",
"output_types": [
"Prompt"
]
"output_types": ["Prompt"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-gi29P",
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"inputTypes": ["Text", "Data", "Prompt"],
"type": "str"
}
},
@ -164,18 +136,10 @@
"display_name": "Prompt",
"id": "Prompt-Rse03",
"node": {
"base_classes": [
"object",
"Text",
"str"
],
"base_classes": ["object", "Text", "str"],
"beta": false,
"custom_fields": {
"template": [
"reference_1",
"reference_2",
"instructions"
]
"template": ["reference_1", "reference_2", "instructions"]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -198,9 +162,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": [
"Prompt"
],
"types": ["Prompt"],
"value": "__UNDEFINED__"
},
{
@ -209,9 +171,7 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
}
],
@ -320,9 +280,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -358,9 +316,7 @@
"data": {
"id": "URL-HYPkR",
"node": {
"base_classes": [
"Record"
],
"base_classes": ["Record"],
"beta": false,
"custom_fields": {
"urls": null
@ -380,9 +336,7 @@
"method": "fetch_content",
"name": "data",
"selected": "Data",
"types": [
"Data"
],
"types": ["Data"],
"value": "__UNDEFINED__"
}
],
@ -404,7 +358,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def fetch_content(self) -> Data:\n urls = [url.strip() for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls)\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\nimport re\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(http://|https://)?\" # http:// or https://\n r\"(([a-zA-Z0-9\\.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,}))\" # top-level domain\n r\"(:[0-9]{1,5})?\" # optional port\n r\"(\\/.*)?$\" # optional path\n )\n\n if not re.match(url_regex, string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> Data:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls)\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
},
"urls": {
"advanced": false,
@ -444,12 +398,7 @@
"data": {
"id": "ChatOutput-JPlxl",
"node": {
"base_classes": [
"Text",
"Record",
"object",
"str"
],
"base_classes": ["Text", "Record", "object", "str"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -474,9 +423,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -507,10 +454,7 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": [
"Text",
"Message"
],
"input_types": ["Text", "Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -530,17 +474,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -556,9 +495,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -578,9 +515,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -611,11 +546,7 @@
"data": {
"id": "OpenAIModel-gi29P",
"node": {
"base_classes": [
"str",
"Text",
"object"
],
"base_classes": ["str", "Text", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -653,9 +584,7 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
},
{
@ -664,9 +593,7 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": [
"BaseLanguageModel"
],
"types": ["BaseLanguageModel"],
"value": "__UNDEFINED__"
}
],
@ -697,11 +624,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text",
"Data",
"Prompt"
],
"input_types": ["Text", "Data", "Prompt"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -721,9 +644,7 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -743,9 +664,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -765,9 +684,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
@ -785,7 +702,7 @@
"show": true,
"title_case": false,
"type": "str",
"value": "gpt-4o"
"value": "gpt-3.5-turbo"
},
"openai_api_base": {
"advanced": true,
@ -794,9 +711,7 @@
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -816,9 +731,7 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": true,
"multiline": false,
@ -838,9 +751,7 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -860,9 +771,7 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -882,9 +791,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -920,9 +827,7 @@
"data": {
"id": "URL-2cX90",
"node": {
"base_classes": [
"Record"
],
"base_classes": ["Record"],
"beta": false,
"custom_fields": {
"urls": null
@ -942,9 +847,7 @@
"method": "fetch_content",
"name": "data",
"selected": "Data",
"types": [
"Data"
],
"types": ["Data"],
"value": "__UNDEFINED__"
}
],
@ -966,7 +869,7 @@
"show": true,
"title_case": false,
"type": "code",
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def fetch_content(self) -> Data:\n urls = [url.strip() for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls)\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\nimport re\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"\n Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(http://|https://)?\" # http:// or https://\n r\"(([a-zA-Z0-9\\.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,}))\" # top-level domain\n r\"(:[0-9]{1,5})?\" # optional port\n r\"(\\/.*)?$\" # optional path\n )\n\n if not re.match(url_regex, string):\n raise ValueError(f\"Invalid URL: {string}\")\n\n return string\n\n def fetch_content(self) -> Data:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls)\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
},
"urls": {
"advanced": false,
@ -1006,11 +909,7 @@
"data": {
"id": "TextInput-og8Or",
"node": {
"base_classes": [
"object",
"Text",
"str"
],
"base_classes": ["object", "Text", "str"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -1023,16 +922,12 @@
"field_order": [],
"frozen": false,
"icon": "type",
"output_types": [
"Text"
],
"output_types": ["Text"],
"outputs": [
{
"name": "Text",
"selected": "Text",
"types": [
"Text"
]
"types": ["Text"]
}
],
"template": {
@ -1062,10 +957,7 @@
"fileTypes": [],
"file_path": "",
"info": "Text or Record to be passed as input.",
"input_types": [
"Record",
"Text"
],
"input_types": ["Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1085,9 +977,7 @@
"fileTypes": [],
"file_path": "",
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1131,4 +1021,4 @@
"is_component": false,
"last_tested_version": "1.0.0a0",
"name": "Blog Writer"
}
}

View file

@ -7,19 +7,12 @@
"dataType": "File",
"id": "File-BzIs2",
"name": "data",
"output_types": [
"Data"
]
"output_types": ["Data"]
},
"targetHandle": {
"fieldName": "Document",
"id": "Prompt-9DNZG",
"inputTypes": [
"Document",
"Message",
"Data",
"Text"
],
"inputTypes": ["Document", "Message", "Data", "Text"],
"type": "str"
}
},
@ -35,19 +28,12 @@
"dataType": "ChatInput",
"id": "ChatInput-27Usy",
"name": "message",
"output_types": [
"Message"
]
"output_types": ["Message"]
},
"targetHandle": {
"fieldName": "Question",
"id": "Prompt-9DNZG",
"inputTypes": [
"Document",
"Message",
"Data",
"Text"
],
"inputTypes": ["Document", "Message", "Data", "Text"],
"type": "str"
}
},
@ -63,18 +49,12 @@
"dataType": "Prompt",
"id": "Prompt-9DNZG",
"name": "prompt",
"output_types": [
"Prompt"
]
"output_types": ["Prompt"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-8b6nG",
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"inputTypes": ["Text", "Data", "Prompt"],
"type": "str"
}
},
@ -90,17 +70,12 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-8b6nG",
"name": "text_output",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-y4SCS",
"inputTypes": [
"Text",
"Message"
],
"inputTypes": ["Text", "Message"],
"type": "str"
}
},
@ -118,18 +93,11 @@
"display_name": "Prompt",
"id": "Prompt-9DNZG",
"node": {
"base_classes": [
"object",
"str",
"Text"
],
"base_classes": ["object", "str", "Text"],
"beta": false,
"conditional_paths": [],
"custom_fields": {
"template": [
"Document",
"Question"
]
"template": ["Document", "Question"]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -151,9 +119,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": [
"Prompt"
],
"types": ["Prompt"],
"value": "__UNDEFINED__"
},
{
@ -162,9 +128,7 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
}
],
@ -178,12 +142,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Document",
"Message",
"Data",
"Text"
],
"input_types": ["Document", "Message", "Data", "Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -204,12 +163,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Document",
"Message",
"Data",
"Text"
],
"input_types": ["Document", "Message", "Data", "Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -248,9 +202,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -286,12 +238,7 @@
"data": {
"id": "ChatInput-27Usy",
"node": {
"base_classes": [
"str",
"Record",
"Text",
"object"
],
"base_classes": ["str", "Record", "Text", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -315,9 +262,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -368,17 +313,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -394,9 +334,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -416,9 +354,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -454,12 +390,7 @@
"data": {
"id": "ChatOutput-y4SCS",
"node": {
"base_classes": [
"str",
"Record",
"Text",
"object"
],
"base_classes": ["str", "Record", "Text", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -483,9 +414,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -516,10 +445,7 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": [
"Text",
"Message"
],
"input_types": ["Text", "Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -539,17 +465,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -565,9 +486,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -587,9 +506,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -627,9 +544,7 @@
"display_name": "File",
"id": "File-BzIs2",
"node": {
"base_classes": [
"Data"
],
"base_classes": ["Data"],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -637,10 +552,7 @@
"display_name": "File",
"documentation": "",
"edited": true,
"field_order": [
"path",
"silent_errors"
],
"field_order": ["path", "silent_errors"],
"frozen": false,
"icon": "file-text",
"output_types": [],
@ -651,9 +563,7 @@
"method": "load_file",
"name": "data",
"selected": "Data",
"types": [
"Data"
],
"types": ["Data"],
"value": "__UNDEFINED__"
}
],
@ -750,10 +660,7 @@
"data": {
"id": "OpenAIModel-8b6nG",
"node": {
"base_classes": [
"BaseLanguageModel",
"Text"
],
"base_classes": ["BaseLanguageModel", "Text"],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -781,9 +688,7 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
},
{
@ -792,9 +697,7 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": [
"BaseLanguageModel"
],
"types": ["BaseLanguageModel"],
"value": "__UNDEFINED__"
}
],
@ -824,11 +727,7 @@
"display_name": "Input",
"dynamic": false,
"info": "",
"input_types": [
"Text",
"Data",
"Prompt"
],
"input_types": ["Text", "Data", "Prompt"],
"list": false,
"load_from_db": false,
"name": "input_value",
@ -883,7 +782,7 @@
"show": true,
"title_case": false,
"type": "str",
"value": "gpt-4o"
"value": "gpt-3.5-turbo"
},
"openai_api_base": {
"advanced": true,
@ -905,9 +804,7 @@
"display_name": "OpenAI API Key",
"dynamic": false,
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"load_from_db": true,
"name": "openai_api_key",
"password": true,
@ -992,4 +889,4 @@
"is_component": false,
"last_tested_version": "1.0.0a52",
"name": "Document QA"
}
}

View file

@ -8,19 +8,12 @@
"dataType": "MemoryComponent",
"id": "MemoryComponent-cdA1J",
"name": "text",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "context",
"id": "Prompt-ODkUx",
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"inputTypes": ["Document", "Message", "Record", "Text"],
"type": "str"
}
},
@ -41,19 +34,12 @@
"dataType": "ChatInput",
"id": "ChatInput-t7F8v",
"name": "message",
"output_types": [
"Message"
]
"output_types": ["Message"]
},
"targetHandle": {
"fieldName": "user_message",
"id": "Prompt-ODkUx",
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"inputTypes": ["Document", "Message", "Record", "Text"],
"type": "str"
}
},
@ -74,18 +60,12 @@
"dataType": "Prompt",
"id": "Prompt-ODkUx",
"name": "prompt",
"output_types": [
"Prompt"
]
"output_types": ["Prompt"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-9RykF",
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"inputTypes": ["Text", "Data", "Prompt"],
"type": "str"
}
},
@ -105,17 +85,12 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-9RykF",
"name": "text_output",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-P1jEe",
"inputTypes": [
"Text",
"Message"
],
"inputTypes": ["Text", "Message"],
"type": "str"
}
},
@ -135,17 +110,12 @@
"dataType": "MemoryComponent",
"id": "MemoryComponent-cdA1J",
"name": "text",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "TextOutput-vrs6T",
"inputTypes": [
"Record",
"Text"
],
"inputTypes": ["Record", "Text"],
"type": "str"
}
},
@ -164,12 +134,7 @@
"data": {
"id": "ChatInput-t7F8v",
"node": {
"base_classes": [
"Text",
"object",
"Record",
"str"
],
"base_classes": ["Text", "object", "Record", "str"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -193,9 +158,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -246,17 +209,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -272,9 +230,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -294,9 +250,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -332,12 +286,7 @@
"data": {
"id": "ChatOutput-P1jEe",
"node": {
"base_classes": [
"Text",
"object",
"Record",
"str"
],
"base_classes": ["Text", "object", "Record", "str"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -361,9 +310,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -394,10 +341,7 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": [
"Text",
"Message"
],
"input_types": ["Text", "Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -417,17 +361,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -443,9 +382,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -465,9 +402,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -505,11 +440,7 @@
"display_name": "Chat Memory",
"id": "MemoryComponent-cdA1J",
"node": {
"base_classes": [
"str",
"Text",
"object"
],
"base_classes": ["str", "Text", "object"],
"beta": true,
"custom_fields": {
"n_messages": null,
@ -526,9 +457,7 @@
"field_order": [],
"frozen": false,
"icon": "history",
"output_types": [
"Text"
],
"output_types": ["Text"],
"outputs": [
{
"cache": true,
@ -537,9 +466,7 @@
"method": null,
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
}
],
@ -589,17 +516,12 @@
"fileTypes": [],
"file_path": "",
"info": "Order of the messages.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "order",
"options": [
"Ascending",
"Descending"
],
"options": ["Ascending", "Descending"],
"password": false,
"placeholder": "",
"required": false,
@ -615,18 +537,12 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User",
"Machine and User"
],
"options": ["Machine", "User", "Machine and User"],
"password": false,
"placeholder": "",
"required": false,
@ -642,9 +558,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -663,9 +577,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID of the chat history.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -703,17 +615,10 @@
"display_name": "Prompt",
"id": "Prompt-ODkUx",
"node": {
"base_classes": [
"Text",
"str",
"object"
],
"base_classes": ["Text", "str", "object"],
"beta": false,
"custom_fields": {
"template": [
"context",
"user_message"
]
"template": ["context", "user_message"]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -736,9 +641,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": [
"Prompt"
],
"types": ["Prompt"],
"value": "__UNDEFINED__"
},
{
@ -747,9 +650,7 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
}
],
@ -781,12 +682,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"input_types": ["Document", "Message", "Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -806,9 +702,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -829,12 +723,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"input_types": ["Document", "Message", "Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -870,11 +759,7 @@
"data": {
"id": "OpenAIModel-9RykF",
"node": {
"base_classes": [
"str",
"object",
"Text"
],
"base_classes": ["str", "object", "Text"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -912,9 +797,7 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
},
{
@ -923,9 +806,7 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": [
"BaseLanguageModel"
],
"types": ["BaseLanguageModel"],
"value": "__UNDEFINED__"
}
],
@ -956,11 +837,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text",
"Data",
"Prompt"
],
"input_types": ["Text", "Data", "Prompt"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -980,9 +857,7 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1002,9 +877,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1024,9 +897,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
@ -1044,7 +915,7 @@
"show": true,
"title_case": false,
"type": "str",
"value": "gpt-4o"
"value": "gpt-3.5-turbo"
},
"openai_api_base": {
"advanced": true,
@ -1053,9 +924,7 @@
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1075,9 +944,7 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": true,
"multiline": false,
@ -1097,9 +964,7 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1119,9 +984,7 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1141,9 +1004,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1179,11 +1040,7 @@
"data": {
"id": "TextOutput-vrs6T",
"node": {
"base_classes": [
"str",
"object",
"Text"
],
"base_classes": ["str", "object", "Text"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -1196,9 +1053,7 @@
"field_order": [],
"frozen": false,
"icon": "type",
"output_types": [
"Text"
],
"output_types": ["Text"],
"template": {
"_type": "CustomComponent",
"code": {
@ -1226,10 +1081,7 @@
"fileTypes": [],
"file_path": "",
"info": "Text or Record to be passed as output.",
"input_types": [
"Record",
"Text"
],
"input_types": ["Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1249,9 +1101,7 @@
"fileTypes": [],
"file_path": "",
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1297,4 +1147,4 @@
"is_component": false,
"last_tested_version": "1.0.0a0",
"name": "Memory Chatbot"
}
}

View file

@ -8,19 +8,12 @@
"dataType": "TextInput",
"id": "TextInput-sptaH",
"name": "text",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "document",
"id": "Prompt-amqBu",
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"inputTypes": ["Document", "Message", "Record", "Text"],
"type": "str"
}
},
@ -40,17 +33,12 @@
"dataType": "Prompt",
"id": "Prompt-amqBu",
"name": "text",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "TextOutput-2MS4a",
"inputTypes": [
"Record",
"Text"
],
"inputTypes": ["Record", "Text"],
"type": "str"
}
},
@ -70,18 +58,12 @@
"dataType": "Prompt",
"id": "Prompt-amqBu",
"name": "prompt",
"output_types": [
"Prompt"
]
"output_types": ["Prompt"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-uYXZJ",
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"inputTypes": ["Text", "Data", "Prompt"],
"type": "str"
}
},
@ -101,19 +83,12 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-uYXZJ",
"name": "text_output",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "summary",
"id": "Prompt-gTNiz",
"inputTypes": [
"Document",
"Message",
"Record",
"Text"
],
"inputTypes": ["Document", "Message", "Record", "Text"],
"type": "str"
}
},
@ -133,17 +108,12 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-uYXZJ",
"name": "text_output",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-EJkG3",
"inputTypes": [
"Text",
"Message"
],
"inputTypes": ["Text", "Message"],
"type": "str"
}
},
@ -163,17 +133,12 @@
"dataType": "Prompt",
"id": "Prompt-gTNiz",
"name": "text",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "TextOutput-MUDOR",
"inputTypes": [
"Record",
"Text"
],
"inputTypes": ["Record", "Text"],
"type": "str"
}
},
@ -193,18 +158,12 @@
"dataType": "Prompt",
"id": "Prompt-gTNiz",
"name": "prompt",
"output_types": [
"Prompt"
]
"output_types": ["Prompt"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "OpenAIModel-XawYB",
"inputTypes": [
"Text",
"Data",
"Prompt"
],
"inputTypes": ["Text", "Data", "Prompt"],
"type": "str"
}
},
@ -224,17 +183,12 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-XawYB",
"name": "text_output",
"output_types": [
"Text"
]
"output_types": ["Text"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-DNmvg",
"inputTypes": [
"Text",
"Message"
],
"inputTypes": ["Text", "Message"],
"type": "str"
}
},
@ -255,16 +209,10 @@
"display_name": "Prompt",
"id": "Prompt-amqBu",
"node": {
"base_classes": [
"object",
"str",
"Text"
],
"base_classes": ["object", "str", "Text"],
"beta": false,
"custom_fields": {
"template": [
"document"
]
"template": ["document"]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -287,9 +235,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": [
"Prompt"
],
"types": ["Prompt"],
"value": "__UNDEFINED__"
},
{
@ -298,9 +244,7 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
}
],
@ -332,12 +276,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"input_types": ["Document", "Message", "Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -357,9 +296,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -397,16 +334,10 @@
"display_name": "Prompt",
"id": "Prompt-gTNiz",
"node": {
"base_classes": [
"object",
"str",
"Text"
],
"base_classes": ["object", "str", "Text"],
"beta": false,
"custom_fields": {
"template": [
"summary"
]
"template": ["summary"]
},
"description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt",
@ -429,9 +360,7 @@
"method": "build_prompt",
"name": "prompt",
"selected": "Prompt",
"types": [
"Prompt"
],
"types": ["Prompt"],
"value": "__UNDEFINED__"
},
{
@ -440,9 +369,7 @@
"method": "format_prompt",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
}
],
@ -474,12 +401,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Document",
"Message",
"Record",
"Text"
],
"input_types": ["Document", "Message", "Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -499,9 +421,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -533,12 +453,7 @@
"data": {
"id": "ChatOutput-EJkG3",
"node": {
"base_classes": [
"object",
"Record",
"Text",
"str"
],
"base_classes": ["object", "Record", "Text", "str"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -563,9 +478,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -596,10 +509,7 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": [
"Text",
"Message"
],
"input_types": ["Text", "Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -619,17 +529,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -645,9 +550,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -667,9 +570,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -701,12 +602,7 @@
"data": {
"id": "ChatOutput-DNmvg",
"node": {
"base_classes": [
"object",
"Record",
"Text",
"str"
],
"base_classes": ["object", "Record", "Text", "str"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -731,9 +627,7 @@
"method": "message_response",
"name": "message",
"selected": "Message",
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -764,10 +658,7 @@
"fileTypes": [],
"file_path": "",
"info": "Message to be passed as output.",
"input_types": [
"Text",
"Message"
],
"input_types": ["Text", "Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -787,17 +678,12 @@
"fileTypes": [],
"file_path": "",
"info": "Type of sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"password": false,
"placeholder": "",
"required": false,
@ -813,9 +699,7 @@
"fileTypes": [],
"file_path": "",
"info": "Name of the sender.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -835,9 +719,7 @@
"fileTypes": [],
"file_path": "",
"info": "Session ID for the message.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -868,11 +750,7 @@
"data": {
"id": "TextInput-sptaH",
"node": {
"base_classes": [
"str",
"Text",
"object"
],
"base_classes": ["str", "Text", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -893,9 +771,7 @@
"method": "text_response",
"name": "text",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
}
],
@ -926,10 +802,7 @@
"fileTypes": [],
"file_path": "",
"info": "Text to be passed as input.",
"input_types": [
"Data",
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -965,11 +838,7 @@
"data": {
"id": "TextOutput-2MS4a",
"node": {
"base_classes": [
"str",
"Text",
"object"
],
"base_classes": ["str", "Text", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -982,9 +851,7 @@
"field_order": [],
"frozen": false,
"icon": "type",
"output_types": [
"Text"
],
"output_types": ["Text"],
"template": {
"_type": "CustomComponent",
"code": {
@ -1012,10 +879,7 @@
"fileTypes": [],
"file_path": "",
"info": "Text or Record to be passed as output.",
"input_types": [
"Record",
"Text"
],
"input_types": ["Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1035,9 +899,7 @@
"fileTypes": [],
"file_path": "",
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1073,11 +935,7 @@
"data": {
"id": "OpenAIModel-uYXZJ",
"node": {
"base_classes": [
"str",
"Text",
"object"
],
"base_classes": ["str", "Text", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -1115,9 +973,7 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
},
{
@ -1126,9 +982,7 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": [
"BaseLanguageModel"
],
"types": ["BaseLanguageModel"],
"value": "__UNDEFINED__"
}
],
@ -1159,11 +1013,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text",
"Data",
"Prompt"
],
"input_types": ["Text", "Data", "Prompt"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1183,9 +1033,7 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1205,9 +1053,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1227,9 +1073,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
@ -1247,7 +1091,7 @@
"show": true,
"title_case": false,
"type": "str",
"value": "gpt-4o"
"value": "gpt-3.5-turbo"
},
"openai_api_base": {
"advanced": true,
@ -1256,9 +1100,7 @@
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1278,9 +1120,7 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": true,
"multiline": false,
@ -1300,9 +1140,7 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1322,9 +1160,7 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1344,9 +1180,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1382,11 +1216,7 @@
"data": {
"id": "TextOutput-MUDOR",
"node": {
"base_classes": [
"str",
"Text",
"object"
],
"base_classes": ["str", "Text", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -1399,9 +1229,7 @@
"field_order": [],
"frozen": false,
"icon": "type",
"output_types": [
"Text"
],
"output_types": ["Text"],
"template": {
"_type": "CustomComponent",
"code": {
@ -1429,10 +1257,7 @@
"fileTypes": [],
"file_path": "",
"info": "Text or Record to be passed as output.",
"input_types": [
"Record",
"Text"
],
"input_types": ["Record", "Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1452,9 +1277,7 @@
"fileTypes": [],
"file_path": "",
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1490,11 +1313,7 @@
"data": {
"id": "OpenAIModel-XawYB",
"node": {
"base_classes": [
"str",
"Text",
"object"
],
"base_classes": ["str", "Text", "object"],
"beta": false,
"custom_fields": {
"input_value": null,
@ -1532,9 +1351,7 @@
"method": "text_response",
"name": "text_output",
"selected": "Text",
"types": [
"Text"
],
"types": ["Text"],
"value": "__UNDEFINED__"
},
{
@ -1543,9 +1360,7 @@
"method": "build_model",
"name": "model_output",
"selected": "BaseLanguageModel",
"types": [
"BaseLanguageModel"
],
"types": ["BaseLanguageModel"],
"value": "__UNDEFINED__"
}
],
@ -1576,11 +1391,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text",
"Data",
"Prompt"
],
"input_types": ["Text", "Data", "Prompt"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1600,9 +1411,7 @@
"fileTypes": [],
"file_path": "",
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1622,9 +1431,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1644,9 +1451,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": true,
"load_from_db": false,
"multiline": false,
@ -1673,9 +1478,7 @@
"fileTypes": [],
"file_path": "",
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1695,9 +1498,7 @@
"fileTypes": [],
"file_path": "",
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": true,
"multiline": false,
@ -1717,9 +1518,7 @@
"fileTypes": [],
"file_path": "",
"info": "Stream the response from the model. Streaming works only in Chat.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1739,9 +1538,7 @@
"fileTypes": [],
"file_path": "",
"info": "System message to pass to the model.",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1761,9 +1558,7 @@
"fileTypes": [],
"file_path": "",
"info": "",
"input_types": [
"Text"
],
"input_types": ["Text"],
"list": false,
"load_from_db": false,
"multiline": false,
@ -1807,4 +1602,4 @@
"is_component": false,
"last_tested_version": "1.0.0a0",
"name": "Prompt Chaining"
}
}

File diff suppressed because one or more lines are too long

View file

@ -160,7 +160,7 @@ async def build_custom_component(params: dict, custom_component: "CustomComponen
if raw is None and isinstance(build_result, (dict, Data, str)):
raw = build_result.data if isinstance(build_result, Data) else build_result
artifact_type = get_artifact_type(custom_component.repr_value or raw, build_result)
artifact_type = get_artifact_type(custom_component or raw, build_result)
raw = post_process_raw(raw, artifact_type)
artifact = {"repr": custom_repr, "raw": raw, "type": artifact_type}
return custom_component, build_result, artifact

View file

@ -1,14 +1,13 @@
import warnings
from datetime import datetime, timedelta, timezone
from typing import Annotated, Coroutine, Optional, Union
from uuid import UUID
import warnings
from cryptography.fernet import Fernet
from fastapi import Depends, HTTPException, Security, status
from fastapi.security import APIKeyHeader, APIKeyQuery, OAuth2PasswordBearer
from jose import JWTError, jwt
from loguru import logger
from sqlmodel import Session
from starlette.websockets import WebSocket
@ -92,44 +91,58 @@ async def get_current_user_by_jwt(
) -> User:
settings_service = get_settings_service()
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
if isinstance(token, Coroutine):
token = await token
if settings_service.auth_settings.SECRET_KEY.get_secret_value() is None:
raise credentials_exception
secret_key = settings_service.auth_settings.SECRET_KEY.get_secret_value()
if secret_key is None:
logger.error("Secret key is not set in settings.")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
# Careful not to leak sensitive information
detail="Authentication failure: Verify authentication settings.",
headers={"WWW-Authenticate": "Bearer"},
)
try:
# Ignore warning about datetime.utcnow
with warnings.catch_warnings():
warnings.simplefilter("ignore")
payload = jwt.decode(
token,
settings_service.auth_settings.SECRET_KEY.get_secret_value(),
algorithms=[settings_service.auth_settings.ALGORITHM],
)
user_id: UUID = payload.get("sub") # type: ignore
token_type: str = payload.get("type") # type: ignore
payload = jwt.decode(token, secret_key, algorithms=[settings_service.auth_settings.ALGORITHM])
user_id: UUID = payload.get("sub")
token_type: str = payload.get("type")
if expires := payload.get("exp", None):
expires_datetime = datetime.fromtimestamp(expires, timezone.utc)
# TypeError: can't compare offset-naive and offset-aware datetimes
if datetime.now(timezone.utc) > expires_datetime:
raise credentials_exception
logger.info("Token expired for user")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Token has expired.",
headers={"WWW-Authenticate": "Bearer"},
)
if user_id is None or token_type:
raise credentials_exception
logger.info(f"Invalid token payload. Token type: {token_type}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token details.",
headers={"WWW-Authenticate": "Bearer"},
)
except JWTError as e:
raise credentials_exception from e
logger.error(f"JWT decoding error: {e}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
) from e
user = get_user_by_id(db, user_id) # type: ignore
user = get_user_by_id(db, user_id)
if user is None or not user.is_active:
raise credentials_exception
logger.info("User not found or inactive.")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="User not found or is inactive.",
headers={"WWW-Authenticate": "Bearer"},
)
return user

View file

@ -6,24 +6,21 @@ from typing import TYPE_CHECKING
import sqlalchemy as sa
from alembic import command, util
from alembic.config import Config
from loguru import logger
from sqlalchemy import inspect
from sqlalchemy.exc import OperationalError
from sqlalchemy.engine import Engine
from sqlalchemy import event
from sqlmodel import Session, SQLModel, create_engine, select, text
from langflow.services.base import Service
from langflow.services.database import models # noqa
from langflow.services.database.models.user.crud import get_user_by_username
from langflow.services.database.utils import Result, TableResults
from langflow.services.deps import get_settings_service
from langflow.services.utils import teardown_superuser
from loguru import logger
from sqlalchemy import event, inspect
from sqlalchemy.engine import Engine
from sqlalchemy.exc import OperationalError
from sqlmodel import Session, SQLModel, create_engine, select, text
if TYPE_CHECKING:
from sqlalchemy.engine import Engine
from langflow.services.settings.service import SettingsService
from sqlalchemy.engine import Engine
class DatabaseService(Service):
@ -48,12 +45,23 @@ class DatabaseService(Service):
connect_args = {"check_same_thread": False}
else:
connect_args = {}
return create_engine(
self.database_url,
connect_args=connect_args,
pool_size=self.settings_service.settings.pool_size,
max_overflow=self.settings_service.settings.max_overflow,
)
try:
return create_engine(
self.database_url,
connect_args=connect_args,
pool_size=self.settings_service.settings.pool_size,
max_overflow=self.settings_service.settings.max_overflow,
)
except sa.exc.NoSuchModuleError as exc:
# sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres
if "postgres" in str(exc) and not self.database_url.startswith("postgresql"):
# https://stackoverflow.com/questions/62688256/sqlalchemy-exc-nosuchmoduleerror-cant-load-plugin-sqlalchemy-dialectspostgre
self.database_url = self.database_url.replace("postgres://", "postgresql://")
logger.warning(
"Fixed postgres dialect in database URL. Replacing postgres:// with postgresql://. To avoid this warning, update the database URL."
)
return self._create_engine()
raise RuntimeError("Error creating database engine") from exc
@event.listens_for(Engine, "connect")
def on_connection(dbapi_connection, connection_record):

View file

@ -91,9 +91,17 @@ class MessageModel(DefaultModel):
files: list[str] = []
@field_validator("files", mode="before")
@classmethod
def validate_files(cls, v):
if isinstance(v, str):
return json.loads(v)
v = json.loads(v)
return v
@field_serializer("files")
@classmethod
def serialize_files(cls, v):
if isinstance(v, list):
return json.dumps(v)
return v
@classmethod

View file

@ -3,12 +3,11 @@ from pathlib import Path
from typing import TYPE_CHECKING, List, Optional, Union
import duckdb
from loguru import logger
from platformdirs import user_cache_dir
from langflow.services.base import Service
from langflow.services.monitor.schema import MessageModel, TransactionModel, VertexBuildModel
from langflow.services.monitor.utils import add_row_to_table, drop_and_create_table_if_schema_mismatch
from loguru import logger
from platformdirs import user_cache_dir
if TYPE_CHECKING:
from langflow.services.settings.manager import SettingsService
@ -141,7 +140,7 @@ class MonitorService(Service):
order: Optional[str] = "DESC",
limit: Optional[int] = None,
):
query = "SELECT index, flow_id, sender_name, sender, session_id, text, timestamp FROM messages"
query = "SELECT index, flow_id, sender_name, sender, session_id, text, files, timestamp FROM messages"
conditions = []
if sender:
conditions.append(f"sender = '{sender}'")

View file

@ -1158,22 +1158,25 @@ files = [
[[package]]
name = "langchain"
version = "0.2.3"
version = "0.2.4"
description = "Building applications with LLMs through composability"
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
{file = "langchain-0.2.3-py3-none-any.whl", hash = "sha256:5dc33cd9c8008693d328b7cb698df69073acecc89ad9c2a95f243b3314f8d834"},
{file = "langchain-0.2.3.tar.gz", hash = "sha256:81962cc72cce6515f7bd71e01542727870789bf8b666c6913d85559080c1a201"},
{file = "langchain-0.2.4-py3-none-any.whl", hash = "sha256:a04813215c30f944df006031e2febde872af8fab628dcee825d969e07b6cd621"},
{file = "langchain-0.2.4.tar.gz", hash = "sha256:e704b5b06222d5eba2d02c76f891321d1bac8952ed54e093831b2bdabf99dcd5"},
]
[package.dependencies]
aiohttp = ">=3.8.3,<4.0.0"
async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""}
langchain-core = ">=0.2.0,<0.3.0"
langchain-core = ">=0.2.6,<0.3.0"
langchain-text-splitters = ">=0.2.0,<0.3.0"
langsmith = ">=0.1.17,<0.2.0"
numpy = ">=1,<2"
numpy = [
{version = ">=1,<2", markers = "python_version < \"3.12\""},
{version = ">=1.26.0,<2.0.0", markers = "python_version >= \"3.12\""},
]
pydantic = ">=1,<3"
PyYAML = ">=5.3"
requests = ">=2,<3"
@ -1205,19 +1208,19 @@ tenacity = ">=8.1.0,<9.0.0"
[[package]]
name = "langchain-core"
version = "0.2.5"
version = "0.2.6"
description = "Building applications with LLMs through composability"
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
{file = "langchain_core-0.2.5-py3-none-any.whl", hash = "sha256:abe5138f22acff23a079ec538be5268bbf97cf023d51987a0dd474d2a16cae3e"},
{file = "langchain_core-0.2.5.tar.gz", hash = "sha256:4a5c2f56b22396a63ef4790043660e393adbfa6832b978f023ca996a04b8e752"},
{file = "langchain_core-0.2.6-py3-none-any.whl", hash = "sha256:90521c9fc95d8f925e0d2e2d952382676aea6d3f8de611eda1b1810874c31e5d"},
{file = "langchain_core-0.2.6.tar.gz", hash = "sha256:9f0e38da722a558a6e95b6d86de01bd92e84558c47ac8ba599f02eab70a1c873"},
]
[package.dependencies]
jsonpatch = ">=1.33,<2.0"
langsmith = ">=0.1.66,<0.2.0"
packaging = ">=23.2,<24.0"
langsmith = ">=0.1.75,<0.2.0"
packaging = ">=23.2,<25"
pydantic = ">=1,<3"
PyYAML = ">=5.3"
tenacity = ">=8.1.0,<9.0.0"
@ -1859,13 +1862,13 @@ files = [
[[package]]
name = "packaging"
version = "23.2"
version = "24.1"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
{file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
]
[[package]]

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "langflow-base"
version = "0.0.63"
version = "0.0.68"
description = "A Python package with a built-in web application"
authors = ["Langflow <contact@langflow.org>"]
maintainers = [