Fix various bugs and make improvements

This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-12-12 17:02:37 -03:00
commit 155e441406
34 changed files with 275 additions and 154 deletions

View file

@ -63,6 +63,8 @@ def set_var_for_macos_issue():
import os
os.environ["OBJC_DISABLE_INITIALIZE_FORK_SAFETY"] = "YES"
# https://stackoverflow.com/questions/75747888/uwsgi-segmentation-fault-with-flask-python-app-behind-nginx-after-running-for-2 # noqa
os.environ["no_proxy"] = "*" # to avoid error with gunicorn
logger.debug("Set OBJC_DISABLE_INITIALIZE_FORK_SAFETY to YES to avoid error")

View file

@ -187,7 +187,7 @@ async def stream_build(
"duration": time_elapsed,
}
yield str(StreamData(event="message", data=response))
yield str(StreamData(event="message", data=response))
langchain_object = await graph.build()
# Now we need to check the input_keys to send them to the client

View file

@ -48,10 +48,9 @@ def get_all(
logger.debug("Building langchain types dict")
try:
types_dict = get_all_types_dict(settings_service)
return get_all_types_dict(settings_service)
except Exception as exc:
raise HTTPException(status_code=500, detail=str(exc)) from exc
return types_dict
# For backwards compatibility we will keep the old endpoint
@ -64,7 +63,7 @@ def get_all(
"/process/{flow_id}",
response_model=ProcessResponse,
)
async def process_flow(
async def process(
session: Annotated[Session, Depends(get_session)],
flow_id: str,
inputs: Optional[dict] = None,

View file

@ -5,14 +5,13 @@ from uuid import UUID
import orjson
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
from fastapi.encoders import jsonable_encoder
from sqlmodel import Session, select
from langflow.api.utils import remove_api_keys, validate_is_component
from langflow.api.v1.schemas import FlowListCreate, FlowListRead
from langflow.services.auth.utils import get_current_active_user
from langflow.services.database.models.flow import Flow, FlowCreate, FlowRead, FlowUpdate
from langflow.services.database.models.user.model import User
from langflow.services.deps import get_session, get_settings_service
from sqlmodel import Session, select
# build router
router = APIRouter(prefix="/flows", tags=["Flows"])
@ -123,7 +122,7 @@ def create_flows(
db_flows = []
for flow in flow_list.flows:
flow.user_id = current_user.id
db_flow = Flow.model_validate(flow)
db_flow = Flow.from_orm(flow)
session.add(db_flow)
db_flows.append(db_flow)
session.commit()

View file

@ -1,11 +1,6 @@
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError
from sqlmodel import Session, select
from sqlmodel.sql.expression import SelectOfScalar
from langflow.api.v1.schemas import UsersResponse
from langflow.services.auth.utils import (
get_current_active_superuser,
@ -16,6 +11,10 @@ from langflow.services.auth.utils import (
from langflow.services.database.models.user import User, UserCreate, UserRead, UserUpdate
from langflow.services.database.models.user.crud import get_user_by_id, update_user
from langflow.services.deps import get_session, get_settings_service
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError
from sqlmodel import Session, select
from sqlmodel.sql.expression import SelectOfScalar
router = APIRouter(tags=["Users"], prefix="/users")
@ -29,7 +28,7 @@ def add_user(
"""
Add a new user to the database.
"""
new_user = User.model_validate(user)
new_user = User.from_orm(user)
try:
new_user.password = get_password_hash(user.password)
new_user.is_active = settings_service.auth_settings.NEW_USER_IS_ACTIVE

View file

@ -80,4 +80,5 @@ class ConversationalAgent(CustomComponent):
memory=memory,
verbose=True,
return_intermediate_steps=True,
handle_parsing_errors=True,
)

View file

@ -3,7 +3,12 @@ from typing import Callable, Optional, Union
from langchain.chains import LLMChain
from langflow import CustomComponent
from langflow.field_typing import BaseLanguageModel, BaseMemory, BasePromptTemplate, Chain
from langflow.field_typing import (
BaseLanguageModel,
BaseMemory,
BasePromptTemplate,
Chain,
)
class LLMChainComponent(CustomComponent):

View file

@ -0,0 +1,45 @@
from typing import Optional
from langflow import CustomComponent
from langchain.llms.bedrock import Bedrock
from langchain.llms.base import BaseLLM
class AmazonBedrockComponent(CustomComponent):
display_name: str = "Amazon Bedrock"
description: str = "LLM model from Amazon Bedrock."
def build_config(self):
return {
"model_id": {
"display_name": "Model Id",
"options": [
"ai21.j2-grande-instruct",
"ai21.j2-jumbo-instruct",
"ai21.j2-mid",
"ai21.j2-mid-v1",
"ai21.j2-ultra",
"ai21.j2-ultra-v1",
"anthropic.claude-instant-v1",
"anthropic.claude-v1",
"anthropic.claude-v2",
"cohere.command-text-v14",
],
},
"credentials_profile_name": {"display_name": "Credentials Profile Name"},
"streaming": {"display_name": "Streaming", "field_type": "bool"},
"code": {"show": False},
}
def build(
self,
model_id: str = "anthropic.claude-instant-v1",
credentials_profile_name: Optional[str] = None,
) -> BaseLLM:
try:
output = Bedrock(
credentials_profile_name=credentials_profile_name,
model_id=model_id,
) # type: ignore
except Exception as e:
raise ValueError("Could not connect to AmazonBedrock API.") from e
return output

View file

@ -0,0 +1,92 @@
from typing import Optional
from langflow import CustomComponent
from langchain.llms.baidu_qianfan_endpoint import QianfanLLMEndpoint
from langchain.llms.base import BaseLLM
class QianfanLLMEndpointComponent(CustomComponent):
display_name: str = "QianfanLLMEndpoint"
description: str = (
"Baidu Qianfan hosted open source or customized models. "
"Get more detail from https://python.langchain.com/docs/integrations/chat/baidu_qianfan_endpoint"
)
def build_config(self):
return {
"model": {
"display_name": "Model Name",
"options": [
"ERNIE-Bot",
"ERNIE-Bot-turbo",
"BLOOMZ-7B",
"Llama-2-7b-chat",
"Llama-2-13b-chat",
"Llama-2-70b-chat",
"Qianfan-BLOOMZ-7B-compressed",
"Qianfan-Chinese-Llama-2-7B",
"ChatGLM2-6B-32K",
"AquilaChat-7B",
],
"info": "https://python.langchain.com/docs/integrations/chat/baidu_qianfan_endpoint",
"required": True,
},
"qianfan_ak": {
"display_name": "Qianfan Ak",
"required": True,
"password": True,
"info": "which you could get from https://cloud.baidu.com/product/wenxinworkshop",
},
"qianfan_sk": {
"display_name": "Qianfan Sk",
"required": True,
"password": True,
"info": "which you could get from https://cloud.baidu.com/product/wenxinworkshop",
},
"top_p": {
"display_name": "Top p",
"field_type": "float",
"info": "Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo",
"value": 0.8,
},
"temperature": {
"display_name": "Temperature",
"field_type": "float",
"info": "Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo",
"value": 0.95,
},
"penalty_score": {
"display_name": "Penalty Score",
"field_type": "float",
"info": "Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo",
"value": 1.0,
},
"endpoint": {
"display_name": "Endpoint",
"info": "Endpoint of the Qianfan LLM, required if custom model used.",
},
"code": {"show": False},
}
def build(
self,
model: str = "ERNIE-Bot-turbo",
qianfan_ak: Optional[str] = None,
qianfan_sk: Optional[str] = None,
top_p: Optional[float] = None,
temperature: Optional[float] = None,
penalty_score: Optional[float] = None,
endpoint: Optional[str] = None,
) -> BaseLLM:
try:
output = QianfanLLMEndpoint( # type: ignore
model=model,
qianfan_ak=qianfan_ak,
qianfan_sk=qianfan_sk,
top_p=top_p,
temperature=temperature,
penalty_score=penalty_score,
endpoint=endpoint,
)
except Exception as e:
raise ValueError("Could not connect to Baidu Qianfan API.") from e
return output # type: ignore

View file

@ -1,6 +1,6 @@
from typing import Optional
from langflow import CustomComponent
from langchain.llms import HuggingFaceEndpoint
from langchain.llms.huggingface_endpoint import HuggingFaceEndpoint
from langchain.llms.base import BaseLLM
@ -13,7 +13,6 @@ class HuggingFaceEndpointsComponent(CustomComponent):
"endpoint_url": {"display_name": "Endpoint URL", "password": True},
"task": {
"display_name": "Task",
"type": "select",
"options": ["text2text-generation", "text-generation", "summarization"],
},
"huggingfacehub_api_token": {"display_name": "API token", "password": True},
@ -27,7 +26,7 @@ class HuggingFaceEndpointsComponent(CustomComponent):
def build(
self,
endpoint_url: str,
task="text2text-generation",
task: str = "text2text-generation",
huggingfacehub_api_token: Optional[str] = None,
model_kwargs: Optional[dict] = None,
) -> BaseLLM:
@ -36,6 +35,7 @@ class HuggingFaceEndpointsComponent(CustomComponent):
endpoint_url=endpoint_url,
task=task,
huggingfacehub_api_token=huggingfacehub_api_token,
model_kwargs=model_kwargs,
)
except Exception as e:
raise ValueError("Could not connect to HuggingFace Endpoints API.") from e

View file

@ -0,0 +1,48 @@
from typing import Optional
from langflow import CustomComponent
from langchain.retrievers import AmazonKendraRetriever
from langchain.schema import BaseRetriever
class AmazonKendraRetrieverComponent(CustomComponent):
display_name: str = "Amazon Kendra Retriever"
description: str = "Retriever that uses the Amazon Kendra API."
def build_config(self):
return {
"index_id": {"display_name": "Index ID"},
"region_name": {"display_name": "Region Name"},
"credentials_profile_name": {"display_name": "Credentials Profile Name"},
"attribute_filter": {
"display_name": "Attribute Filter",
"field_type": "code",
},
"top_k": {"display_name": "Top K", "field_type": "int"},
"user_context": {
"display_name": "User Context",
"field_type": "code",
},
"code": {"show": False},
}
def build(
self,
index_id: str,
top_k: int = 3,
region_name: Optional[str] = None,
credentials_profile_name: Optional[str] = None,
attribute_filter: Optional[dict] = None,
user_context: Optional[dict] = None,
) -> BaseRetriever:
try:
output = AmazonKendraRetriever(
index_id=index_id,
top_k=top_k,
region_name=region_name,
credentials_profile_name=credentials_profile_name,
attribute_filter=attribute_filter,
user_context=user_context,
) # type: ignore
except Exception as e:
raise ValueError("Could not connect to AmazonKendra API.") from e
return output

View file

@ -14,7 +14,7 @@ class ChromaComponent(CustomComponent):
A custom component for implementing a Vector Store using Chroma.
"""
display_name: str = "Chroma (Custom Component)"
display_name: str = "Chroma"
description: str = "Implementation of Vector Store using Chroma"
documentation = "https://python.langchain.com/docs/integrations/vectorstores/chroma"
beta: bool = True

View file

@ -1,62 +0,0 @@
from typing import List, Optional, Union
from langflow import CustomComponent
from langchain.vectorstores import FAISS
from langchain.vectorstores.base import VectorStore
from langchain.schema import BaseRetriever
from langchain.schema import Document
from langchain.embeddings.base import Embeddings
class FAISSComponent(CustomComponent):
"""
A custom component for implementing a Vector Store using FAISS.
"""
display_name: str = "FAISS (Custom Component)"
description: str = "Implementation of Vector Store using FAISS"
documentation = "https://python.langchain.com/docs/integrations/vectorstores/faiss"
beta = True
def build_config(self):
return {
"persistence": {
"display_name": "Persistence",
"options": ["In-Memory", "LocalDirectory"],
"value": "In-Memory",
},
"folder_path": {
"display_name": "Folder Path",
"required": False,
},
"index_name": {"display_name": "Index Name", "value": "faiss_index"},
"documents": {"display_name": "Documents", "is_list": True},
"embeddings": {"display_name": "Embeddings"},
"code": {"display_name": "Code", "show": False},
}
def build(
self,
persistence: str,
index_name: str,
embeddings: Embeddings,
folder_path: Optional[str] = None,
documents: Optional[List[Document]] = None,
) -> Union[VectorStore, BaseRetriever]:
if persistence == "LocalDirectory" and not folder_path:
raise ValueError("Folder path is required for local directory persistence")
# Load if persistence is LocalDirectory
if documents is None and folder_path is not None:
return FAISS.load_local(folder_path=folder_path, embeddings=embeddings, index_name=index_name)
if documents is None:
raise ValueError("Documents must be provided in the params")
db = FAISS.from_documents(documents=documents, embedding=embeddings)
# Save if persistence is LocalDirectory
if persistence == "LocalDirectory" and folder_path is not None:
db.save_local(folder_path=folder_path, index_name=index_name)
return db

View file

@ -1,6 +1,5 @@
from typing import Optional, Union
from langchain.embeddings.base import Embeddings
from langchain.schema import BaseRetriever, Document
from langchain.vectorstores import Vectara
from langchain.vectorstores.base import VectorStore
@ -20,7 +19,6 @@ class VectaraComponent(CustomComponent):
"vectara_api_key": {"display_name": "Vectara API Key", "password": True},
"code": {"show": False},
"documents": {"display_name": "Documents"},
"embedding": {"display_name": "Embedding"},
}
def build(
@ -28,21 +26,21 @@ class VectaraComponent(CustomComponent):
vectara_customer_id: str,
vectara_corpus_id: str,
vectara_api_key: str,
embedding: Optional[Embeddings] = None,
documents: Optional[Document] = None,
) -> Union[VectorStore, BaseRetriever]:
# If documents, then we need to create a Vectara instance using .from_documents
if documents is not None and embedding is not None:
if documents is not None:
return Vectara.from_documents(
documents=documents, # type: ignore
vectara_customer_id=vectara_customer_id,
vectara_corpus_id=vectara_corpus_id,
vectara_api_key=vectara_api_key,
embedding=embedding,
source="langflow",
)
return Vectara(
vectara_customer_id=vectara_customer_id,
vectara_corpus_id=vectara_corpus_id,
vectara_api_key=vectara_api_key,
source="langflow",
)

View file

@ -118,10 +118,10 @@ llms:
documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/ctransformers"
Cohere:
documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/cohere"
# Anthropic:
# documentation: ""
# ChatAnthropic:
# documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/integrations/anthropic"
Anthropic:
documentation: ""
ChatAnthropic:
documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/integrations/anthropic"
HuggingFaceHub:
documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/huggingface_hub"
VertexAI:
@ -266,14 +266,14 @@ retrievers:
# ZepRetriever:
# documentation: "https://python.langchain.com/docs/modules/data_connection/retrievers/integrations/zep_memorystore"
vectorstores:
Chroma:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/chroma"
# Chroma:
# documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/chroma"
Qdrant:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/qdrant"
Weaviate:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/weaviate"
# FAISS:
# documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/faiss"
FAISS:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/faiss"
Pinecone:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/pinecone"
SupabaseVectorStore:

View file

@ -1,4 +0,0 @@
from typing import Union, Dict
# Type alias for more complex dicts
NestedDict = Dict[str, Union[str, Dict]]

View file

@ -17,7 +17,7 @@ class Graph:
def __init__(
self,
nodes: List[Dict[str, Union[str, Dict[str, Union[str, List[str]]]]]],
nodes: List[Dict],
edges: List[Dict[str, str]],
) -> None:
self._vertices = nodes
@ -27,8 +27,7 @@ class Graph:
self.top_level_vertices = []
for vertex in self._vertices:
if vertex_id := vertex.get("id"):
if isinstance(vertex_id, str):
self.top_level_vertices.append(vertex_id)
self.top_level_vertices.append(vertex_id)
self._graph_data = process_flow(self.raw_graph_data)
self._vertices = self._graph_data["nodes"]
@ -59,6 +58,7 @@ class Graph:
edges = payload["edges"]
return cls(vertices, edges)
except KeyError as exc:
logger.exception(exc)
raise ValueError(
f"Invalid payload. Expected keys 'nodes' and 'edges'. Found {list(payload.keys())}"
) from exc

View file

@ -35,8 +35,9 @@ class Vertex:
self.artifacts: Dict[str, Any] = {}
self.task_id: Optional[str] = None
self.is_task = is_task
self.parent_node_id: Optional[str] = self._data.get("parent_node_id")
self.params = params or {}
self.parent_node_id: Optional[str] = self._data.get("parent_node_id")
self.parent_is_top_level = False
@property
def edges(self) -> List["Edge"]:

View file

@ -131,7 +131,6 @@ class VectorStoreVertex(Vertex):
super().__init__(data, graph=graph, base_type="vectorstores")
self.params = params or {}
self.params.pop("code", None)
# VectorStores may contain databse connections
# so we need to define the __reduce__ method and the __setstate__ method
@ -201,6 +200,9 @@ class ChainVertex(Vertex):
self.params.pop("code", None)
# Check if the chain requires a PromptVertex
# Temporarily remove "code" from the params
self.params.pop("code", None)
for key, value in self.params.items():
if isinstance(value, PromptVertex):
# Build the PromptVertex, passing the tools if available

View file

@ -21,7 +21,6 @@ from langchain.tools.sql_database.prompt import QUERY_CHECKER
from langchain_experimental.agents.agent_toolkits.pandas.prompt import PREFIX as PANDAS_PREFIX
from langchain_experimental.agents.agent_toolkits.pandas.prompt import SUFFIX_WITH_DF as PANDAS_SUFFIX
from langchain_experimental.tools.python.tool import PythonAstREPLTool
from langflow.interface.base import CustomAgentExecutor

View file

@ -1,17 +1,17 @@
import os
from typing import Any, Callable, Dict, Type
import orjson
from langchain.schema import Document
from langchain.vectorstores import (
FAISS,
Chroma,
MongoDBAtlasVectorSearch,
Pinecone,
Qdrant,
SupabaseVectorStore,
Chroma,
FAISS,
Weaviate,
SupabaseVectorStore,
MongoDBAtlasVectorSearch,
)
from langchain.schema import Document
import os
import orjson
def docs_in_params(params: dict) -> bool:
@ -26,8 +26,8 @@ def initialize_mongodb(class_object: Type[MongoDBAtlasVectorSearch], params: dic
MONGODB_ATLAS_CLUSTER_URI = params.pop("mongodb_atlas_cluster_uri")
if not MONGODB_ATLAS_CLUSTER_URI:
raise ValueError("Mongodb atlas cluster uri must be provided in the params")
import certifi
from pymongo import MongoClient
import certifi
client: MongoClient = MongoClient(MONGODB_ATLAS_CLUSTER_URI, tlsCAFile=certifi.where())
db_name = params.pop("db_name", None)
@ -116,7 +116,6 @@ def initialize_faiss(class_object: Type[FAISS], params: dict):
return class_object.load_local
save_local = params.get("save_local")
params["embedding_function"] = params.pop("embedding")
faiss_index = class_object(**params)
if save_local:
faiss_index.save_local(folder_path=save_local)

View file

@ -1,18 +1,27 @@
from typing import Dict, List, Optional
from langchain.agents.load_tools import _EXTRA_LLM_TOOLS, _EXTRA_OPTIONAL_TOOLS, _LLM_TOOLS
from langchain_experimental.tools.python.tool import PythonInputs
from langchain.agents.load_tools import (
_EXTRA_LLM_TOOLS,
_EXTRA_OPTIONAL_TOOLS,
_LLM_TOOLS,
)
from langflow.custom import customs
from langflow.interface.base import LangChainTypeCreator
from langflow.interface.tools.constants import ALL_TOOLS_NAMES, CUSTOM_TOOLS, FILE_TOOLS, OTHER_TOOLS
from langflow.interface.tools.constants import (
ALL_TOOLS_NAMES,
CUSTOM_TOOLS,
FILE_TOOLS,
OTHER_TOOLS,
)
from langflow.interface.tools.util import get_tool_params
from langflow.services.deps import get_settings_service
from langflow.template.field.base import TemplateField
from langflow.template.template.base import Template
from langflow.utils import util
from langflow.utils.logger import logger
from langflow.utils.util import build_template_from_class
from langflow.utils.logger import logger
TOOL_INPUTS = {
"str": TemplateField(
@ -156,11 +165,8 @@ class ToolCreator(LangChainTypeCreator):
template = Template(fields=fields, type_name=tool_type)
tool_params = {**tool_params, **self.type_to_loader_dict[name]["params"]}
template_dict = template.to_dict()
if "args_schema" in template_dict and template_dict.get("args_schema").get("value") == PythonInputs:
template_dict["args_schema"]["value"] = ""
return {
"template": util.format_dict(template_dict),
"template": util.format_dict(template.to_dict()),
**tool_params,
"base_classes": base_classes,
}

View file

@ -2,11 +2,10 @@ from typing import TYPE_CHECKING, List, Union
from langchain.agents.agent import AgentExecutor
from langchain.callbacks.base import BaseCallbackHandler
from loguru import logger
from langflow.api.v1.callback import AsyncStreamingLLMCallbackHandler, StreamingLLMCallbackHandler
from langflow.processing.process import fix_memory_inputs, format_actions
from langflow.services.deps import get_plugins_service
from loguru import logger
if TYPE_CHECKING:
from langfuse.callback import CallbackHandler # type: ignore
@ -28,9 +27,8 @@ def setup_callbacks(sync, trace_id, **kwargs):
def get_langfuse_callback(trace_id):
from langfuse.callback import CreateTrace
from langflow.services.deps import get_plugins_service
from langfuse.callback import CreateTrace
logger.debug("Initializing langfuse callback")
if langfuse := get_plugins_service().get("langfuse"):

View file

@ -7,12 +7,11 @@ from langchain.agents import AgentExecutor
from langchain.chains.base import Chain
from langchain.schema import AgentAction, Document
from langchain.vectorstores.base import VectorStore
from loguru import logger
from pydantic import BaseModel
from langflow.graph import Graph
from langflow.interface.run import build_sorted_vertices, get_memory_key, update_memory_keys
from langflow.services.deps import get_session_service
from loguru import logger
from pydantic import BaseModel
def fix_memory_inputs(langchain_object):

View file

@ -29,7 +29,7 @@ def create_api_key(session: Session, api_key_create: ApiKeyCreate, user_id: UUID
session.add(api_key)
session.commit()
session.refresh(api_key)
unmasked = UnmaskedApiKeyRead.model_validate(api_key)
unmasked = UnmaskedApiKeyRead.from_orm(api_key)
unmasked.api_key = generated_api_key
return unmasked

View file

@ -5,17 +5,16 @@ 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 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 inspect
from sqlalchemy.exc import OperationalError
from sqlmodel import Session, SQLModel, create_engine, select, text
if TYPE_CHECKING:
from sqlalchemy.engine import Engine

View file

@ -31,7 +31,11 @@ def initialize_database(fix_migration: bool = False):
try:
database_service.run_migrations(fix=fix_migration)
except CommandError as exc:
if "Can't locate revision identified by" not in str(exc):
# if "overlaps with other requested revisions" or "Can't locate revision identified by"
# are not in the exception, we can't handle it
if "overlaps with other requested revisions" not in str(
exc
) and "Can't locate revision identified by" not in str(exc):
raise exc
# This means there's wrong revision in the DB
# We need to delete the alembic_version table

View file

@ -1,10 +1,7 @@
import traceback
from typing import Any, Callable, Optional, Tuple
import anyio
from loguru import logger
from langflow.services.task.backends.base import TaskBackend
from loguru import logger
class AnyIOTaskResult:
@ -13,7 +10,6 @@ class AnyIOTaskResult:
self._status = "PENDING"
self._result = None
self._exception = None
self._traceback = None
@property
def status(self) -> str:
@ -21,10 +17,6 @@ class AnyIOTaskResult:
return "FAILURE" if self._exception is not None else "SUCCESS"
return self._status
@property
def traceback(self) -> Optional[str]:
return self._traceback
@property
def result(self) -> Any:
return self._result
@ -37,7 +29,6 @@ class AnyIOTaskResult:
self._result = await func(*args, **kwargs)
except Exception as e:
self._exception = e
self._traceback = traceback.format_exc()
finally:
self._status = "DONE"

View file

@ -1,11 +1,10 @@
from loguru import logger
from sqlmodel import Session, select
from langflow.services.auth.utils import create_super_user, verify_password
from langflow.services.database.utils import initialize_database
from langflow.services.manager import service_manager
from langflow.services.schema import ServiceType
from langflow.services.settings.constants import DEFAULT_SUPERUSER, DEFAULT_SUPERUSER_PASSWORD
from loguru import logger
from sqlmodel import Session, select
from .deps import get_db_service, get_session, get_settings_service

View file

@ -42,7 +42,7 @@ class FieldFormatters(BaseModel):
class FrontendNode(BaseModel):
_format_template: bool = True
template: Template
description: str
description: Optional[str] = None
base_classes: List[str]
name: str = ""
display_name: Optional[str] = ""

View file

@ -87,6 +87,8 @@ class ChainFrontendNode(FrontendNode):
field.required = True
field.show = True
field.advanced = False
field.field_type = "BaseLanguageModel" # temporary fix
field.is_list = False
if key == "return_source_documents":
field.required = False

View file

@ -65,5 +65,5 @@ class CustomComponentFrontendNode(FrontendNode):
)
],
)
description: str = "Create any custom component you want!"
description: Optional[str] = None
base_classes: list[str] = []

View file

@ -1,14 +1,14 @@
import importlib
import inspect
import re
import inspect
import importlib
from functools import wraps
from typing import Any, Dict, List, Optional, Union
from typing import List, Optional, Dict, Any, Union
from docstring_parser import parse
from langchain.schema import Document
from langflow.template.frontend_node.constants import FORCE_SHOW_FIELDS
from langflow.utils import constants
from langchain.schema import Document
def remove_ansi_escape_codes(text):