Skip to content

Commit

Permalink
Update Langchain to 0.1 and migrate most components to CustomComponent (
Browse files Browse the repository at this point in the history
#1382)

This PR updates Langchain to 0.1.* and move components previously
created automatically to start using the CustomComponent framework.

This will improve maintainability and move Langflow to be closer to the
framework.
  • Loading branch information
ogabrielluiz authored Jan 31, 2024
2 parents b49e057 + 339029c commit e61e4ac
Show file tree
Hide file tree
Showing 81 changed files with 3,205 additions and 2,815 deletions.
2,768 changes: 1,218 additions & 1,550 deletions poetry.lock

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "langflow"
version = "0.6.5a12"
version = "0.6.5a13"
description = "A Python package with a built-in web application"
authors = ["Logspace <[email protected]>"]
maintainers = [
Expand All @@ -25,8 +25,6 @@ documentation = "https://docs.langflow.org"
langflow = "langflow.__main__:main"

[tool.poetry.dependencies]


python = ">=3.9,<3.11"
fastapi = "^0.108.0"
uvicorn = "^0.25.0"
Expand All @@ -35,8 +33,8 @@ google-search-results = "^2.4.1"
google-api-python-client = "^2.79.0"
typer = "^0.9.0"
gunicorn = "^21.2.0"
langchain = "~0.0.345"
openai = "^1.6.1"
langchain = "~0.1.0"
openai = "^1.10.0"
pandas = "2.0.3"
chromadb = "^0.4.0"
huggingface-hub = { version = "^0.19.0", extras = ["inference"] }
Expand All @@ -55,15 +53,15 @@ tiktoken = "~0.5.0"
wikipedia = "^1.4.0"
qdrant-client = "^1.7.0"
websockets = "^10.3"
weaviate-client = { version = "^4.4b6", allow-prereleases = true }
weaviate-client = "*"
jina = "*"
sentence-transformers = { version = "^2.2.2", optional = true }
ctransformers = { version = "^0.2.10", optional = true }
cohere = "^4.39.0"
python-multipart = "^0.0.6"
sqlmodel = "^0.0.14"
faiss-cpu = "^1.7.4"
anthropic = "^0.8.0"
anthropic = "^0.13.0"
orjson = "3.9.3"
multiprocess = "^0.70.14"
cachetools = "^5.3.1"
Expand Down Expand Up @@ -98,7 +96,7 @@ markupsafe = "^2.1.3"
extract-msg = "^0.45.0"
# jq is not available for windows
jq = { version = "^1.6.0", markers = "sys_platform != 'win32'" }
boto3 = "^1.28.63"
boto3 = "^1.34.0"
numexpr = "^2.8.6"
qianfan = "0.2.0"
pgvector = "^0.2.3"
Expand All @@ -107,12 +105,13 @@ langchain-google-genai = "^0.0.2"
elasticsearch = "^8.11.1"
pytube = "^15.0.0"
llama-index = "^0.9.24"
langchain-openai = "^0.0.2"

[tool.poetry.group.dev.dependencies]
pytest-asyncio = "^0.23.1"
types-redis = "^4.6.0.5"
ipykernel = "^6.27.0"
mypy = "^1.7.1"
mypy = "^1.8.0"
ruff = "^0.1.5"
httpx = "*"
pytest = "^7.4.2"
Expand Down Expand Up @@ -154,7 +153,8 @@ exclude = ["src/backend/langflow/alembic/*"]
line-length = 120

[tool.mypy]
plugins = "pydantic.mypy"
plugins = ["pydantic.mypy"]
follow_imports = "silent"

[build-system]
requires = ["poetry-core"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def upgrade() -> None:
batch_op.add_column(sa.Column('folder', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
batch_op.add_column(sa.Column('user_id', sqlmodel.sql.sqltypes.GUID(), nullable=True))
batch_op.create_index(batch_op.f('ix_flow_user_id'), ['user_id'], unique=False)
batch_op.create_foreign_key(None, 'user', ['user_id'], ['id'])
batch_op.create_foreign_key('fk_flow_user_id_user', 'user', ['user_id'], ['id'])
except Exception:
pass
# ### end Alembic commands ###
Expand All @@ -38,7 +38,7 @@ def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
try:
with op.batch_alter_table('flow', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_constraint('fk_flow_user_id_user', type_='foreignkey')
batch_op.drop_index(batch_op.f('ix_flow_user_id'))
batch_op.drop_column('user_id')
batch_op.drop_column('folder')
Expand Down
23 changes: 23 additions & 0 deletions src/backend/langflow/components/agents/CSVAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from langflow import CustomComponent
from langflow.field_typing import BaseLanguageModel, AgentExecutor
from langchain_experimental.agents.agent_toolkits.csv.base import create_csv_agent


class CSVAgentComponent(CustomComponent):
display_name = "CSVAgent"
description = "Construct a CSV agent from a CSV and tools."
documentation = "https://python.langchain.com/docs/modules/agents/toolkits/csv"

def build_config(self):
return {
"llm": {"display_name": "LLM", "type": BaseLanguageModel},
"path": {"display_name": "Path", "field_type": "file", "suffixes": [".csv"], "file_types": [".csv"]},
}

def build(
self,
llm: BaseLanguageModel,
path: str,
) -> AgentExecutor:
# Instantiate and return the CSV agent class with the provided llm and path
return create_csv_agent(llm=llm, path=path)
24 changes: 24 additions & 0 deletions src/backend/langflow/components/agents/JsonAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from langflow import CustomComponent
from langchain.agents import AgentExecutor, create_json_agent
from langflow.field_typing import (
BaseLanguageModel,
)
from langchain_community.agent_toolkits.json.toolkit import JsonToolkit


class JsonAgentComponent(CustomComponent):
display_name = "JsonAgent"
description = "Construct a json agent from an LLM and tools."

def build_config(self):
return {
"llm": {"display_name": "LLM"},
"toolkit": {"display_name": "Toolkit"},
}

def build(
self,
llm: BaseLanguageModel,
toolkit: JsonToolkit,
) -> AgentExecutor:
return create_json_agent(llm=llm, toolkit=toolkit)
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from langchain.agents.agent import AgentExecutor
from langchain.agents.agent_toolkits.conversational_retrieval.openai_functions import _get_default_system_message
from langchain.agents.openai_functions_agent.base import OpenAIFunctionsAgent
from langchain.chat_models import ChatOpenAI
from langchain_community.chat_models import ChatOpenAI
from langchain.memory.token_buffer import ConversationTokenBufferMemory
from langchain.prompts import SystemMessagePromptTemplate
from langchain.prompts.chat import MessagesPlaceholder
Expand Down
29 changes: 29 additions & 0 deletions src/backend/langflow/components/agents/SQLAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from langflow import CustomComponent
from typing import Union, Callable
from langchain.agents import AgentExecutor
from langflow.field_typing import BaseLanguageModel
from langchain_community.agent_toolkits.sql.base import create_sql_agent
from langchain.sql_database import SQLDatabase
from langchain_community.agent_toolkits import SQLDatabaseToolkit


class SQLAgentComponent(CustomComponent):
display_name = "SQLAgent"
description = "Construct an SQL agent from an LLM and tools."

def build_config(self):
return {
"llm": {"display_name": "LLM"},
"database_uri": {"display_name": "Database URI"},
"verbose": {"display_name": "Verbose", "value": False, "advanced": True},
}

def build(
self,
llm: BaseLanguageModel,
database_uri: str,
verbose: bool = False,
) -> Union[AgentExecutor, Callable]:
db = SQLDatabase.from_uri(database_uri)
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
return create_sql_agent(llm=llm, toolkit=toolkit)
23 changes: 23 additions & 0 deletions src/backend/langflow/components/agents/VectorStoreAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from langflow import CustomComponent
from langchain.agents import AgentExecutor, create_vectorstore_agent
from langchain.agents.agent_toolkits.vectorstore.toolkit import VectorStoreToolkit
from typing import Union, Callable
from langflow.field_typing import BaseLanguageModel


class VectorStoreAgentComponent(CustomComponent):
display_name = "VectorStoreAgent"
description = "Construct an agent from a Vector Store."

def build_config(self):
return {
"llm": {"display_name": "LLM"},
"vector_store_toolkit": {"display_name": "Vector Store Info"},
}

def build(
self,
llm: BaseLanguageModel,
vector_store_toolkit: VectorStoreToolkit,
) -> Union[AgentExecutor, Callable]:
return create_vectorstore_agent(llm=llm, toolkit=vector_store_toolkit)
19 changes: 19 additions & 0 deletions src/backend/langflow/components/agents/VectorStoreRouterAgent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from langflow import CustomComponent
from langchain_core.language_models.base import BaseLanguageModel
from langchain.agents.agent_toolkits.vectorstore.toolkit import VectorStoreRouterToolkit
from langchain.agents import create_vectorstore_router_agent
from typing import Callable


class VectorStoreRouterAgentComponent(CustomComponent):
display_name = "VectorStoreRouterAgent"
description = "Construct an agent from a Vector Store Router."

def build_config(self):
return {
"llm": {"display_name": "LLM"},
"vectorstoreroutertoolkit": {"display_name": "Vector Store Router Toolkit"},
}

def build(self, llm: BaseLanguageModel, vectorstoreroutertoolkit: VectorStoreRouterToolkit) -> Callable:
return create_vectorstore_router_agent(llm=llm, toolkit=vectorstoreroutertoolkit)
2 changes: 1 addition & 1 deletion src/backend/langflow/components/chains/LLMChain.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ def build(
prompt: BasePromptTemplate,
llm: BaseLanguageModel,
memory: Optional[BaseMemory] = None,
) -> Union[Chain, Callable]:
) -> Union[Chain, Callable, LLMChain]:
return LLMChain(prompt=prompt, llm=llm, memory=memory)
24 changes: 24 additions & 0 deletions src/backend/langflow/components/chains/LLMCheckerChain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from langflow import CustomComponent
from langchain.chains import LLMCheckerChain
from typing import Union, Callable
from langflow.field_typing import (
BaseLanguageModel,
Chain,
)


class LLMCheckerChainComponent(CustomComponent):
display_name = "LLMCheckerChain"
description = ""
documentation = "https://python.langchain.com/docs/modules/chains/additional/llm_checker"

def build_config(self):
return {
"llm": {"display_name": "LLM"},
}

def build(
self,
llm: BaseLanguageModel,
) -> Union[Chain, Callable]:
return LLMCheckerChain(llm=llm)
31 changes: 31 additions & 0 deletions src/backend/langflow/components/chains/LLMMathChain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import Callable, Optional, Union

from langchain.chains import LLMChain, LLMMathChain

from langflow import CustomComponent
from langflow.field_typing import BaseLanguageModel, BaseMemory, Chain


class LLMMathChainComponent(CustomComponent):
display_name = "LLMMathChain"
description = "Chain that interprets a prompt and executes python code to do math."
documentation = "https://python.langchain.com/docs/modules/chains/additional/llm_math"

def build_config(self):
return {
"llm": {"display_name": "LLM"},
"llm_chain": {"display_name": "LLM Chain"},
"memory": {"display_name": "Memory"},
"input_key": {"display_name": "Input Key"},
"output_key": {"display_name": "Output Key"},
}

def build(
self,
llm: BaseLanguageModel,
llm_chain: LLMChain,
input_key: str = "question",
output_key: str = "answer",
memory: Optional[BaseMemory] = None,
) -> Union[LLMMathChain, Callable, Chain]:
return LLMMathChain(llm=llm, llm_chain=llm_chain, input_key=input_key, output_key=output_key, memory=memory)
39 changes: 39 additions & 0 deletions src/backend/langflow/components/chains/RetrievalQA.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from typing import Callable, Optional, Union

from langchain.chains.combine_documents.base import BaseCombineDocumentsChain
from langchain.chains.retrieval_qa.base import BaseRetrievalQA, RetrievalQA
from langflow import CustomComponent
from langflow.field_typing import BaseMemory, BaseRetriever


class RetrievalQAComponent(CustomComponent):
display_name = "RetrievalQA"
description = "Chain for question-answering against an index."

def build_config(self):
return {
"combine_documents_chain": {"display_name": "Combine Documents Chain"},
"retriever": {"display_name": "Retriever"},
"memory": {"display_name": "Memory", "required": False},
"input_key": {"display_name": "Input Key", "advanced": True},
"output_key": {"display_name": "Output Key", "advanced": True},
"return_source_documents": {"display_name": "Return Source Documents"},
}

def build(
self,
combine_documents_chain: BaseCombineDocumentsChain,
retriever: BaseRetriever,
memory: Optional[BaseMemory] = None,
input_key: str = "query",
output_key: str = "result",
return_source_documents: bool = True,
) -> Union[BaseRetrievalQA, Callable]:
return RetrievalQA(
combine_documents_chain=combine_documents_chain,
retriever=retriever,
memory=memory,
input_key=input_key,
output_key=output_key,
return_source_documents=return_source_documents,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from typing import Optional

from langchain.chains import RetrievalQAWithSourcesChain
from langchain.chains.qa_with_sources.base import BaseQAWithSourcesChain
from langchain.chains.combine_documents.base import BaseCombineDocumentsChain

from langflow import CustomComponent
from langflow.field_typing import BaseLanguageModel, BaseMemory, BaseRetriever


class RetrievalQAWithSourcesChainComponent(CustomComponent):
display_name = "RetrievalQAWithSourcesChain"
description = "Question-answering with sources over an index."

def build_config(self):
return {
"llm": {"display_name": "LLM"},
"chain_type": {
"display_name": "Chain Type",
"options": ["stuff", "map_reduce", "map_rerank", "refine"],
},
"memory": {"display_name": "Memory"},
"return_source_documents": {"display_name": "Return Source Documents"},
}

def build(
self,
retriever: BaseRetriever,
llm: BaseLanguageModel,
combine_documents_chain: BaseCombineDocumentsChain,
chain_type: str,
memory: Optional[BaseMemory] = None,
return_source_documents: Optional[bool] = True,
) -> BaseQAWithSourcesChain:
return RetrievalQAWithSourcesChain.from_chain_type(
llm=llm,
chain_type=chain_type,
combine_documents_chain=combine_documents_chain,
memory=memory,
return_source_documents=return_source_documents,
retriever=retriever,
)
Loading

0 comments on commit e61e4ac

Please sign in to comment.