Merge branch 'python_custom_node_component' of personal:logspace-ai/langflow into python_custom_node_component
This commit is contained in:
commit
8fe7cd3472
9 changed files with 144 additions and 26 deletions
|
|
@ -71,10 +71,14 @@ class ClassCodeExtractor:
|
|||
self.function_entrypoint_name), None
|
||||
)
|
||||
|
||||
funtion_args = build_function.get("arguments", None)
|
||||
return_type = build_function.get("return_type", None)
|
||||
if build_function:
|
||||
function_args = build_function.get("arguments", None)
|
||||
return_type = build_function.get("return_type", None)
|
||||
else:
|
||||
function_args = None
|
||||
return_type = None
|
||||
|
||||
return funtion_args, return_type
|
||||
return function_args, return_type
|
||||
|
||||
|
||||
def is_valid_class_template(code: dict):
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ tools:
|
|||
- Calculator
|
||||
- Serper Search
|
||||
- Tool
|
||||
- CustomComponent
|
||||
- PythonFunctionTool
|
||||
- PythonFunction
|
||||
- JsonSpec
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ CUSTOM_NODES = {
|
|||
"tools": {
|
||||
"PythonFunctionTool": frontend_node.tools.PythonFunctionToolNode(),
|
||||
"PythonFunction": frontend_node.tools.PythonFunctionNode(),
|
||||
"CustomComponent": frontend_node.tools.CustomComponentNode(),
|
||||
"Tool": frontend_node.tools.ToolNode(),
|
||||
},
|
||||
"agents": {
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ def instantiate_tool(node_type, class_object, params):
|
|||
if node_type == "JsonSpec":
|
||||
params["dict_"] = load_file_into_dict(params.pop("path"))
|
||||
return class_object(**params)
|
||||
elif node_type == "PythonFunctionTool":
|
||||
elif node_type in ["PythonFunctionTool", "CustomComponent"]:
|
||||
params["func"] = get_function(params.get("code"))
|
||||
return class_object(**params)
|
||||
# For backward compatibility
|
||||
|
|
@ -243,7 +243,8 @@ def replace_zero_shot_prompt_with_prompt_template(nodes):
|
|||
if tool["type"] != "chatOutputNode"
|
||||
and "Tool" in tool["data"]["node"]["base_classes"]
|
||||
]
|
||||
node["data"] = build_prompt_template(prompt=node["data"], tools=tools)
|
||||
node["data"] = build_prompt_template(
|
||||
prompt=node["data"], tools=tools)
|
||||
break
|
||||
return nodes
|
||||
|
||||
|
|
@ -260,7 +261,8 @@ def load_agent_executor(agent_class: type[agent_module.Agent], params, **kwargs)
|
|||
tool_names = [tool.name for tool in allowed_tools]
|
||||
# Agent class requires an output_parser but Agent classes
|
||||
# have a default output_parser.
|
||||
agent = agent_class(allowed_tools=tool_names, llm_chain=llm_chain) # type: ignore
|
||||
agent = agent_class(allowed_tools=tool_names,
|
||||
llm_chain=llm_chain) # type: ignore
|
||||
return AgentExecutor.from_agent_and_tools(
|
||||
agent=agent,
|
||||
tools=allowed_tools,
|
||||
|
|
|
|||
|
|
@ -9,16 +9,22 @@ from langchain.agents.load_tools import (
|
|||
from langchain.tools.json.tool import JsonSpec
|
||||
|
||||
from langflow.interface.importing.utils import import_class
|
||||
from langflow.interface.tools.custom import PythonFunctionTool, PythonFunction
|
||||
from langflow.interface.tools.custom import (
|
||||
PythonFunctionTool,
|
||||
PythonFunction,
|
||||
CustomComponent
|
||||
)
|
||||
|
||||
FILE_TOOLS = {"JsonSpec": JsonSpec}
|
||||
CUSTOM_TOOLS = {
|
||||
"Tool": Tool,
|
||||
"CustomComponent": CustomComponent,
|
||||
"PythonFunctionTool": PythonFunctionTool,
|
||||
"PythonFunction": PythonFunction,
|
||||
}
|
||||
|
||||
OTHER_TOOLS = {tool: import_class(f"langchain.tools.{tool}") for tool in tools.__all__}
|
||||
OTHER_TOOLS = {tool: import_class(f"langchain.tools.{tool}")
|
||||
for tool in tools.__all__}
|
||||
|
||||
ALL_TOOLS_NAMES = {
|
||||
**_BASE_TOOLS,
|
||||
|
|
|
|||
|
|
@ -52,3 +52,9 @@ class PythonFunction(Function):
|
|||
"""Python function"""
|
||||
|
||||
code: str
|
||||
|
||||
|
||||
class CustomComponent(Function):
|
||||
"""Python function"""
|
||||
|
||||
code: str
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ from langflow.interface.utilities.base import utility_creator
|
|||
from langflow.interface.vector_store.base import vectorstore_creator
|
||||
from langflow.interface.wrappers.base import wrapper_creator
|
||||
|
||||
from langflow.template.field.base import TemplateField
|
||||
from langflow.template.frontend_node.tools import CustomComponentNode
|
||||
|
||||
|
||||
def get_type_list():
|
||||
"""Get a list of all langchain types"""
|
||||
|
|
@ -54,6 +57,7 @@ def build_langchain_types_dict(): # sourcery skip: dict-assign-update-to-union
|
|||
return all_types
|
||||
|
||||
|
||||
# TODO: Move to correct place
|
||||
def find_class_type(class_name, classes_dict):
|
||||
return next(
|
||||
(
|
||||
|
|
@ -65,10 +69,23 @@ def find_class_type(class_name, classes_dict):
|
|||
)
|
||||
|
||||
|
||||
def build_langchain_template_custom_component(raw_code, function_args, function_return_type):
|
||||
type_list = get_type_list()
|
||||
type_and_class = find_class_type("Tool", type_list)
|
||||
# TODO: Move to correct place
|
||||
def add_new_custom_field(template, field_name: str, field_type: str):
|
||||
new_field = TemplateField(
|
||||
name=field_name,
|
||||
field_type=field_type,
|
||||
show=True,
|
||||
advanced=False
|
||||
)
|
||||
template.get('template')[field_name] = new_field.to_dict()
|
||||
template.get('custom_fields').append(field_name)
|
||||
|
||||
return template
|
||||
|
||||
# TODO: Move to correct place
|
||||
|
||||
|
||||
def add_code_field(template, raw_code):
|
||||
# Field with the Python code to allow update
|
||||
code_field = {
|
||||
"code": {
|
||||
|
|
@ -84,13 +101,47 @@ def build_langchain_template_custom_component(raw_code, function_args, function_
|
|||
"list": False
|
||||
}
|
||||
}
|
||||
template.get('template')['code'] = code_field.get('code')
|
||||
|
||||
return template
|
||||
|
||||
|
||||
def build_langchain_template_custom_component(raw_code, function_args, function_return_type):
|
||||
# type_list = get_type_list()
|
||||
# type_and_class = find_class_type("Tool", type_list)
|
||||
# node = get_custom_nodes(node_type: str)
|
||||
|
||||
# TODO: Build base template
|
||||
template = llm_creator.to_dict()['llms']['ChatOpenAI']
|
||||
|
||||
template = CustomComponentNode().to_dict().get('CustomComponent')
|
||||
|
||||
# TODO: Add extra fields
|
||||
template = add_new_custom_field(
|
||||
template,
|
||||
"my_id",
|
||||
"str"
|
||||
)
|
||||
|
||||
# TODO: Build template result
|
||||
template = chain_creator.to_dict()['chains']['ConversationChain']
|
||||
template = add_new_custom_field(
|
||||
template,
|
||||
"year",
|
||||
"int"
|
||||
)
|
||||
|
||||
template.get('template')['code'] = code_field.get('code')
|
||||
template = add_new_custom_field(
|
||||
template,
|
||||
"other_field",
|
||||
"bool"
|
||||
)
|
||||
|
||||
template = add_code_field(
|
||||
template,
|
||||
raw_code
|
||||
)
|
||||
|
||||
# criar um vertex
|
||||
# olhar loading.py
|
||||
|
||||
return template
|
||||
# return globals()['tool_creator'].to_dict()[type_and_class['type']][type_and_class['class']]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
from langflow.template.field.base import TemplateField
|
||||
from langflow.template.frontend_node.base import FrontendNode
|
||||
from langflow.template.template.base import Template
|
||||
from langflow.utils.constants import DEFAULT_PYTHON_FUNCTION
|
||||
from langflow.utils.constants import (
|
||||
DEFAULT_PYTHON_FUNCTION,
|
||||
DEFAULT_CUSTOM_COMPONENT_CODE
|
||||
)
|
||||
|
||||
|
||||
class ToolNode(FrontendNode):
|
||||
|
|
@ -137,3 +140,27 @@ class PythonFunctionNode(FrontendNode):
|
|||
|
||||
def to_dict(self):
|
||||
return super().to_dict()
|
||||
|
||||
|
||||
class CustomComponentNode(FrontendNode):
|
||||
name: str = "CustomComponent"
|
||||
template: Template = Template(
|
||||
type_name="CustomComponent",
|
||||
fields=[
|
||||
TemplateField(
|
||||
field_type="code",
|
||||
required=True,
|
||||
placeholder="",
|
||||
is_list=False,
|
||||
show=True,
|
||||
value=DEFAULT_CUSTOM_COMPONENT_CODE,
|
||||
name="code",
|
||||
advanced=False,
|
||||
)
|
||||
],
|
||||
)
|
||||
description: str = "Python Class to be executed."
|
||||
base_classes: list[str] = []
|
||||
|
||||
def to_dict(self):
|
||||
return super().to_dict()
|
||||
|
|
|
|||
|
|
@ -17,18 +17,30 @@ CHAT_OPENAI_MODELS = [
|
|||
]
|
||||
|
||||
ANTHROPIC_MODELS = [
|
||||
"claude-v1", # largest model, ideal for a wide range of more complex tasks.
|
||||
"claude-v1-100k", # An enhanced version of claude-v1 with a 100,000 token (roughly 75,000 word) context window.
|
||||
"claude-instant-v1", # A smaller model with far lower latency, sampling at roughly 40 words/sec!
|
||||
"claude-instant-v1-100k", # Like claude-instant-v1 with a 100,000 token context window but retains its performance.
|
||||
# largest model, ideal for a wide range of more complex tasks.
|
||||
"claude-v1",
|
||||
# An enhanced version of claude-v1 with a 100,000 token (roughly 75,000 word) context window.
|
||||
"claude-v1-100k",
|
||||
# A smaller model with far lower latency, sampling at roughly 40 words/sec!
|
||||
"claude-instant-v1",
|
||||
# Like claude-instant-v1 with a 100,000 token context window but retains its performance.
|
||||
"claude-instant-v1-100k",
|
||||
|
||||
# Specific sub-versions of the above models:
|
||||
"claude-v1.3", # Vs claude-v1.2: better instruction-following, code, and non-English dialogue and writing.
|
||||
"claude-v1.3-100k", # An enhanced version of claude-v1.3 with a 100,000 token (roughly 75,000 word) context window.
|
||||
"claude-v1.2", # Vs claude-v1.1: small adv in general helpfulness, instruction following, coding, and other tasks.
|
||||
"claude-v1.0", # An earlier version of claude-v1.
|
||||
"claude-instant-v1.1", # Latest version of claude-instant-v1. Better than claude-instant-v1.0 at most tasks.
|
||||
"claude-instant-v1.1-100k", # Version of claude-instant-v1.1 with a 100K token context window.
|
||||
"claude-instant-v1.0", # An earlier version of claude-instant-v1.
|
||||
# Vs claude-v1.2: better instruction-following, code, and non-English dialogue and writing.
|
||||
"claude-v1.3",
|
||||
# An enhanced version of claude-v1.3 with a 100,000 token (roughly 75,000 word) context window.
|
||||
"claude-v1.3-100k",
|
||||
# Vs claude-v1.1: small adv in general helpfulness, instruction following, coding, and other tasks.
|
||||
"claude-v1.2",
|
||||
# An earlier version of claude-v1.
|
||||
"claude-v1.0",
|
||||
# Latest version of claude-instant-v1. Better than claude-instant-v1.0 at most tasks.
|
||||
"claude-instant-v1.1",
|
||||
# Version of claude-instant-v1.1 with a 100K token context window.
|
||||
"claude-instant-v1.1-100k",
|
||||
# An earlier version of claude-instant-v1.
|
||||
"claude-instant-v1.0",
|
||||
]
|
||||
|
||||
DEFAULT_PYTHON_FUNCTION = """
|
||||
|
|
@ -36,4 +48,12 @@ def python_function(text: str) -> str:
|
|||
\"\"\"This is a default python function that returns the input text\"\"\"
|
||||
return text
|
||||
"""
|
||||
|
||||
DEFAULT_CUSTOM_COMPONENT_CODE = """
|
||||
def custom_component(text: str) -> str:
|
||||
\"\"\"This is a default custom component function that returns the input text\"\"\"
|
||||
\"\"\"TODO: Add a Class template\"\"\"
|
||||
return text
|
||||
"""
|
||||
|
||||
DIRECT_TYPES = ["str", "bool", "code", "int", "float", "Any", "prompt"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue