Add new files and modify existing files
This commit is contained in:
parent
827d6befec
commit
73a23ca096
12 changed files with 19 additions and 241 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import time
|
||||
import uuid
|
||||
from functools import partial
|
||||
from typing import TYPE_CHECKING, Annotated, Callable, Optional
|
||||
from typing import TYPE_CHECKING, Annotated, Optional
|
||||
|
||||
from fastapi import APIRouter, BackgroundTasks, Body, Depends, HTTPException
|
||||
from fastapi.responses import StreamingResponse
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
from typing import List, Optional, Union
|
||||
from typing import List, Union
|
||||
|
||||
from langchain.agents import AgentExecutor, BaseMultiActionAgent, BaseSingleActionAgent
|
||||
|
||||
from langchain.agents.agent import AgentExecutor, BaseMultiActionAgent, BaseSingleActionAgent
|
||||
from langchain_core.runnables import Runnable
|
||||
|
||||
from langflow.custom import CustomComponent
|
||||
from langflow.field_typing import BaseMemory, Text, Tool
|
||||
from langflow.interface.custom.custom_component import CustomComponent
|
||||
|
||||
|
||||
class LCAgentComponent(CustomComponent):
|
||||
|
|
@ -44,7 +45,7 @@ class LCAgentComponent(CustomComponent):
|
|||
inputs: str,
|
||||
input_variables: list[str],
|
||||
tools: List[Tool],
|
||||
memory: Optional[BaseMemory] = None,
|
||||
memory: BaseMemory = None,
|
||||
handle_parsing_errors: bool = True,
|
||||
output_key: str = "output",
|
||||
) -> Text:
|
||||
|
|
@ -52,11 +53,7 @@ class LCAgentComponent(CustomComponent):
|
|||
runnable = agent
|
||||
else:
|
||||
runnable = AgentExecutor.from_agent_and_tools(
|
||||
agent=agent, # type: ignore
|
||||
tools=tools,
|
||||
verbose=True,
|
||||
memory=memory,
|
||||
handle_parsing_errors=handle_parsing_errors,
|
||||
agent=agent, tools=tools, verbose=True, memory=memory, handle_parsing_errors=handle_parsing_errors
|
||||
)
|
||||
input_dict = {"input": inputs}
|
||||
for var in input_variables:
|
||||
|
|
@ -72,5 +69,4 @@ class LCAgentComponent(CustomComponent):
|
|||
else:
|
||||
raise ValueError("Output key not found in result. Tried 'output'.")
|
||||
|
||||
output: str = result.get("output")
|
||||
return output
|
||||
return result.get("output")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from typing import Any, Callable, Dict, List, Optional, Union
|
||||
|
||||
from langchain_openai.embeddings.base import OpenAIEmbeddings
|
||||
from pydantic.v1.types import SecretStr
|
||||
|
||||
from langflow.field_typing import NestedDict
|
||||
from langflow.interface.custom.custom_component import CustomComponent
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Any, List, Optional
|
||||
from typing import Any, List, Optional, Text
|
||||
|
||||
from langchain_core.tools import StructuredTool
|
||||
from loguru import logger
|
||||
|
|
@ -8,7 +8,6 @@ from langflow.field_typing import Tool
|
|||
from langflow.graph.graph.base import Graph
|
||||
from langflow.helpers.flow import build_function_and_schema
|
||||
from langflow.schema.dotdict import dotdict
|
||||
from langflow.schema.schema import Record
|
||||
|
||||
|
||||
class FlowToolComponent(CustomComponent):
|
||||
|
|
@ -20,7 +19,7 @@ class FlowToolComponent(CustomComponent):
|
|||
flow_records = self.list_flows()
|
||||
return [flow_record.data["name"] for flow_record in flow_records]
|
||||
|
||||
def get_flow(self, flow_name: str) -> Optional[Record]:
|
||||
def get_flow(self, flow_name: str) -> Optional[Text]:
|
||||
"""
|
||||
Retrieves a flow by its name.
|
||||
|
||||
|
|
@ -83,4 +82,4 @@ class FlowToolComponent(CustomComponent):
|
|||
description_repr = repr(tool.description).strip("'")
|
||||
args_str = "\n".join([f"- {arg_name}: {arg_data['description']}" for arg_name, arg_data in tool.args.items()])
|
||||
self.status = f"{description_repr}\nArguments:\n{args_str}"
|
||||
return tool # type: ignore
|
||||
return tool
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
from typing import Any, List, Optional, Tuple
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from langflow.custom import CustomComponent
|
||||
from langflow.graph.graph.base import Graph
|
||||
from langflow.graph.schema import ResultData, RunOutputs
|
||||
from langflow.graph.vertex.base import Vertex
|
||||
from langflow.schema import Record
|
||||
from langflow.schema.dotdict import dotdict
|
||||
from langflow.template.field.base import TemplateField
|
||||
|
|
@ -50,7 +51,7 @@ class SubFlowComponent(CustomComponent):
|
|||
|
||||
return build_config
|
||||
|
||||
def get_flow_inputs(self, graph: Graph) -> List[Record]:
|
||||
def get_flow_inputs(self, graph: Graph) -> List[Vertex]:
|
||||
inputs = []
|
||||
for vertex in graph.vertices:
|
||||
if vertex.is_input:
|
||||
|
|
@ -58,13 +59,13 @@ class SubFlowComponent(CustomComponent):
|
|||
logger.debug(inputs)
|
||||
return inputs
|
||||
|
||||
def add_inputs_to_build_config(self, inputs: List[Tuple], build_config: dotdict):
|
||||
def add_inputs_to_build_config(self, inputs: List[Vertex], build_config: dotdict):
|
||||
new_fields: list[TemplateField] = []
|
||||
for input_id, input_display_name, input_description in inputs:
|
||||
for vertex in inputs:
|
||||
field = TemplateField(
|
||||
display_name=input_display_name,
|
||||
name=input_id,
|
||||
info=input_description,
|
||||
display_name=vertex.display_name,
|
||||
name=vertex.id,
|
||||
info=vertex.description,
|
||||
field_type="str",
|
||||
default=None,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ 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.util import get_tool_params
|
||||
from langflow.legacy_custom import customs
|
||||
from langflow.interface.tools.util import get_tool_params
|
||||
from langflow.legacy_custom import customs
|
||||
from langflow.services.deps import get_settings_service
|
||||
from langflow.template.field.base import TemplateField
|
||||
from langflow.template.template.base import Template
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
from typing import List, Union
|
||||
|
||||
from langchain.agents import (AgentExecutor, BaseMultiActionAgent,
|
||||
|
||||
from langflow.custom import CustomComponent
|
||||
from langflow.field_typing import BaseMemory, Text, Tool
|
||||
|
||||
|
||||
class LCAgentComponent(CustomComponent):
|
||||
def build_config(self):
|
||||
return {
|
||||
"lc": {
|
||||
"display_name": "LangChain",
|
||||
"info": "The LangChain to interact with.",
|
||||
},
|
||||
"handle_parsing_errors": {
|
||||
"display_name": "Handle Parsing Errors",
|
||||
"info": "If True, the agent will handle parsing errors. If False, the agent will raise an error.",
|
||||
"advanced": True,
|
||||
},
|
||||
"output_key": {
|
||||
"display_name": "Output Key",
|
||||
"info": "The key to use to get the output from the agent.",
|
||||
"advanced": True,
|
||||
},
|
||||
"memory": {
|
||||
"display_name": "Memory",
|
||||
"info": "Memory to use for the agent.",
|
||||
},
|
||||
"tools": {
|
||||
"display_name": "Tools",
|
||||
"info": "Tools the agent can use.",
|
||||
},
|
||||
"input_value": {
|
||||
"display_name": "Input",
|
||||
"info": "Input text to pass to the agent.",
|
||||
},
|
||||
}
|
||||
|
||||
async def run_agent(
|
||||
self,
|
||||
agent: Union[BaseSingleActionAgent, BaseMultiActionAgent, AgentExecutor],
|
||||
inputs: str,
|
||||
input_variables: list[str],
|
||||
tools: List[Tool],
|
||||
memory: BaseMemory = None,
|
||||
handle_parsing_errors: bool = True,
|
||||
output_key: str = "output",
|
||||
) -> Text:
|
||||
if isinstance(agent, AgentExecutor):
|
||||
runnable = agent
|
||||
else:
|
||||
runnable = AgentExecutor.from_agent_and_tools(
|
||||
agent=agent, tools=tools, verbose=True, memory=memory, handle_parsing_errors=handle_parsing_errors
|
||||
)
|
||||
input_dict = {"input": inputs}
|
||||
for var in input_variables:
|
||||
if var not in ["agent_scratchpad", "input"]:
|
||||
input_dict[var] = ""
|
||||
result = await runnable.ainvoke(input_dict)
|
||||
self.status = result
|
||||
if output_key in result:
|
||||
return result.get(output_key)
|
||||
elif "output" not in result:
|
||||
if output_key != "output":
|
||||
raise ValueError(f"Output key not found in result. Tried '{output_key}' and 'output'.")
|
||||
else:
|
||||
raise ValueError("Output key not found in result. Tried 'output'.")
|
||||
|
||||
return result.get("output")
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
from typing import Any, List, Optional, Text
|
||||
|
||||
from langchain_core.tools import StructuredTool
|
||||
from langflow.custom import CustomComponent
|
||||
from langflow.field_typing import Tool
|
||||
from langflow.graph.graph.base import Graph
|
||||
from langflow.helpers.flow import build_function_and_schema
|
||||
from langflow.schema.dotdict import dotdict
|
||||
from loguru import logger
|
||||
|
||||
|
||||
class FlowToolComponent(CustomComponent):
|
||||
display_name = "Flow as Tool"
|
||||
description = "Construct a Tool from a function that runs the loaded Flow."
|
||||
field_order = ["flow_name", "name", "description", "return_direct"]
|
||||
|
||||
def get_flow_names(self) -> List[str]:
|
||||
flow_records = self.list_flows()
|
||||
return [flow_record.data["name"] for flow_record in flow_records]
|
||||
|
||||
def get_flow(self, flow_name: str) -> Optional[Text]:
|
||||
"""
|
||||
Retrieves a flow by its name.
|
||||
|
||||
Args:
|
||||
flow_name (str): The name of the flow to retrieve.
|
||||
|
||||
Returns:
|
||||
Optional[Text]: The flow record if found, None otherwise.
|
||||
"""
|
||||
flow_records = self.list_flows()
|
||||
for flow_record in flow_records:
|
||||
if flow_record.data["name"] == flow_name:
|
||||
return flow_record
|
||||
return None
|
||||
|
||||
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None):
|
||||
logger.debug(f"Updating build config with field value {field_value} and field name {field_name}")
|
||||
if field_name == "flow_name":
|
||||
build_config["flow_name"]["options"] = self.get_flow_names()
|
||||
|
||||
return build_config
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
"flow_name": {
|
||||
"display_name": "Flow Name",
|
||||
"info": "The name of the flow to run.",
|
||||
"options": [],
|
||||
"real_time_refresh": True,
|
||||
"refresh_button": True,
|
||||
},
|
||||
"name": {
|
||||
"display_name": "Name",
|
||||
"description": "The name of the tool.",
|
||||
},
|
||||
"description": {
|
||||
"display_name": "Description",
|
||||
"description": "The description of the tool.",
|
||||
},
|
||||
"return_direct": {
|
||||
"display_name": "Return Direct",
|
||||
"description": "Return the result directly from the Tool.",
|
||||
"advanced": True,
|
||||
},
|
||||
}
|
||||
|
||||
async def build(self, flow_name: str, name: str, description: str, return_direct: bool = False) -> Tool:
|
||||
flow_record = self.get_flow(flow_name)
|
||||
if not flow_record:
|
||||
raise ValueError("Flow not found.")
|
||||
graph = Graph.from_payload(flow_record.data["data"])
|
||||
dynamic_flow_function, schema = build_function_and_schema(flow_record, graph)
|
||||
tool = StructuredTool.from_function(
|
||||
coroutine=dynamic_flow_function,
|
||||
name=name,
|
||||
description=description,
|
||||
return_direct=return_direct,
|
||||
args_schema=schema,
|
||||
)
|
||||
description_repr = repr(tool.description).strip("'")
|
||||
args_str = "\n".join([f"- {arg_name}: {arg_data['description']}" for arg_name, arg_data in tool.args.items()])
|
||||
self.status = f"{description_repr}\nArguments:\n{args_str}"
|
||||
return tool
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
from langflow.custom import CustomComponent
|
||||
|
||||
|
||||
class SchemaComponent(CustomComponent):
|
||||
display_name = "Schema"
|
||||
description = "Construct a Schema from a list of fields."
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
"fields": {
|
||||
"display_name": "Fields",
|
||||
"info": "The fields to include in the schema.",
|
||||
},
|
||||
"name": {
|
||||
"display_name": "Name",
|
||||
"info": "The name of the schema.",
|
||||
},
|
||||
}
|
||||
|
||||
def build(self, name: str, fields: list[dict]):
|
||||
# The idea for this component is to use create_model from pydantic to create a schema
|
||||
# from a list of fields. This will be useful for creating schemas for the flow tool.
|
||||
pass
|
||||
|
||||
# field is a simple list of dictionaries with the field name and
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
from langchain_community.tools.searchapi import SearchAPIRun
|
||||
from langchain_community.utilities.searchapi import SearchApiAPIWrapper
|
||||
from langflow.custom import CustomComponent
|
||||
from langflow.field_typing import Tool
|
||||
|
||||
|
||||
class SearchApiToolComponent(CustomComponent):
|
||||
display_name: str = "SearchApi Tool"
|
||||
description: str = "Real-time search engine results API."
|
||||
documentation: str = "https://www.searchapi.io/docs/google"
|
||||
field_config = {
|
||||
"engine": {
|
||||
"display_name": "Engine",
|
||||
"field_type": "str",
|
||||
"info": "The search engine to use.",
|
||||
},
|
||||
"api_key": {
|
||||
"display_name": "API Key",
|
||||
"field_type": "str",
|
||||
"required": True,
|
||||
"password": True,
|
||||
"info": "The API key to use SearchApi.",
|
||||
},
|
||||
}
|
||||
|
||||
def build(
|
||||
self,
|
||||
engine: str,
|
||||
api_key: str,
|
||||
) -> Tool:
|
||||
search_api_wrapper = SearchApiAPIWrapper(engine=engine, searchapi_api_key=api_key)
|
||||
|
||||
tool = SearchAPIRun(api_wrapper=search_api_wrapper)
|
||||
|
||||
self.status = tool
|
||||
return tool
|
||||
Loading…
Add table
Add a link
Reference in a new issue