feat: first version of vecstore, docloader and embeddings working

This commit is contained in:
Ibis Prevedello 2023-04-06 13:55:07 -03:00
commit cf4ceb0e1a
14 changed files with 1718 additions and 13 deletions

View file

@ -3,7 +3,7 @@ FROM python:3.10-slim
WORKDIR /app
# Install Poetry
RUN apt-get update && apt-get install gcc curl -y
RUN apt-get update && apt-get install gcc curl build-essential -y
RUN curl -sSL https://install.python-poetry.org | python3 -
# # Add Poetry to PATH
ENV PATH="${PATH}:/root/.local/bin"

1605
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -34,6 +34,7 @@ openai = "^0.27.2"
types-pyyaml = "^6.0.12.8"
dill = "^0.3.6"
pandas = "^1.5.3"
chromadb = "^0.3.21"
[tool.poetry.group.dev.dependencies]
black = "^23.1.0"

View file

@ -12,6 +12,7 @@ agents:
- JsonAgent
- CSVAgent
- initialize_agent
- VectorStoreAgent
prompts:
- PromptTemplate

View file

@ -8,6 +8,7 @@ CUSTOM_NODES = {
"JsonAgent": nodes.JsonAgentNode(),
"CSVAgent": nodes.CSVAgentNode(),
"initialize_agent": nodes.InitializeAgentNode(),
"VectorStoreAgent": nodes.VectorStoreAgentNode(),
},
}

View file

@ -185,6 +185,10 @@ class Node:
def build(self, force: bool = False) -> Any:
if not self._built or force:
self._build()
#! Deepcopy is breaking for vectorstores
if self.base_type == 'vectorstores':
return self._built_object
return deepcopy(self._built_object)
def add_edge(self, edge: "Edge") -> None:

View file

@ -32,6 +32,10 @@ class AgentNode(Node):
chain_node.build(tools=self.tools)
self._build()
#! Cannot deepcopy VectorStore
if self.node_type == "VectorStoreAgent":
return self._built_object
return deepcopy(self._built_object)

View file

@ -11,7 +11,12 @@ from langchain.llms.base import BaseLLM
from langchain.memory.chat_memory import BaseChatMemory
from langchain.schema import BaseLanguageModel
from langchain.tools.python.tool import PythonAstREPLTool
from langchain.agents.agent_toolkits import (
VectorStoreToolkit,
VectorStoreInfo,
)
from langchain.vectorstores.base import VectorStore
from langchain.agents.agent_toolkits.vectorstore.prompt import PREFIX as VECTORSTORE_PREFIX, ROUTER_PREFIX as VECTORSTORE_ROUTER_PREFIX
class JsonAgent(AgentExecutor):
"""Json agent"""
@ -97,6 +102,54 @@ class CSVAgent(AgentExecutor):
return super().run(*args, **kwargs)
class VectorStoreAgent(AgentExecutor):
"""Vector Store agent"""
@staticmethod
def function_name():
return "VectorStoreAgent"
@classmethod
def initialize(cls, *args, **kwargs):
return cls.from_toolkit_and_llm(*args, **kwargs)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@classmethod
def from_toolkit_and_llm(
cls,
llm: BaseLanguageModel,
name: str,
description: str,
vectorstore: VectorStore,
**kwargs: Any
):
"""Construct a vectorstore agent from an LLM and tools."""
vectorstore_info = VectorStoreInfo(
name=name,
description=description,
vectorstore=vectorstore
)
toolkit = VectorStoreToolkit(vectorstore_info=vectorstore_info, llm=llm)
tools = toolkit.get_tools()
prompt = ZeroShotAgent.create_prompt(tools, prefix=VECTORSTORE_PREFIX)
llm_chain = LLMChain(
llm=llm,
prompt=prompt,
callback_manager=None,
)
tool_names = [tool.name for tool in tools]
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
return AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)
def run(self, *args, **kwargs):
return super().run(*args, **kwargs)
class InitializeAgent(AgentExecutor):
"""Implementation of initialize_agent function"""
@ -128,4 +181,5 @@ CUSTOM_AGENTS = {
"JsonAgent": JsonAgent,
"CSVAgent": CSVAgent,
"initialize_agent": InitializeAgent,
"VectorStoreAgent": VectorStoreAgent,
}

View file

@ -7,7 +7,7 @@ from langchain.agents.load_tools import (
)
from langchain.tools.json.tool import JsonSpec
from langflow.interface.custom.types import PythonFunction
from langflow.interface.tools.custom import PythonFunction
FILE_TOOLS = {"JsonSpec": JsonSpec}
CUSTOM_TOOLS = {"Tool": Tool, "PythonFunction": PythonFunction}

View file

@ -1,10 +1,10 @@
from typing import Callable, Optional
from pydantic import BaseModel, validator
from langflow.utils import validate
from typing import Callable, Optional
from pydantic import BaseModel, validator
class Function(BaseModel):
code: str
function: Optional[Callable] = None
@ -30,8 +30,8 @@ class Function(BaseModel):
return validate.create_function(self.code, function_name)
class PythonFunction(Function):
"""Python function"""
code: str

View file

@ -248,6 +248,48 @@ class CSVAgentNode(FrontendNode):
return super().to_dict()
class VectorStoreAgentNode(FrontendNode):
name: str = "VectorStoreAgent"
template: Template = Template(
type_name="vectorstore_agent",
fields=[
TemplateField(
field_type="str",
required=True,
show=True,
name="name",
value="",
),
TemplateField(
field_type="str",
required=True,
show=True,
name="description",
value="",
),
TemplateField(
field_type="VectorStore",
required=True,
show=True,
name="vectorstore",
display_name="Vector Store",
),
TemplateField(
field_type="BaseLanguageModel",
required=True,
show=True,
name="llm",
display_name="LLM",
),
],
)
description: str = """Construct a json agent from a CSV and tools."""
base_classes: list[str] = ["AgentExecutor"]
def to_dict(self):
return super().to_dict()
class PromptFrontendNode(FrontendNode):
@staticmethod
def format_field(field: TemplateField, name: Optional[str] = None) -> None:

View file

@ -9,6 +9,7 @@ import {
ComputerDesktopIcon,
Bars3CenterLeftIcon,
GiftIcon,
PaperClipIcon,
QuestionMarkCircleIcon,
} from "@heroicons/react/24/outline";
import { Connection, Edge, Node, ReactFlowInstance } from "reactflow";

View file

@ -1,6 +1,6 @@
# Test this:
import pytest
from langflow.interface.custom.types import PythonFunction
from langflow.interface.tools.custom import PythonFunction
from langflow.utils import constants