feat: frontend_node_class property and other prompts
This commit is contained in:
parent
bb49642899
commit
08d60f18ea
6 changed files with 57 additions and 13 deletions
|
|
@ -13,6 +13,10 @@ agents:
|
||||||
prompts:
|
prompts:
|
||||||
- PromptTemplate
|
- PromptTemplate
|
||||||
- FewShotPromptTemplate
|
- FewShotPromptTemplate
|
||||||
|
- ChatPromptTemplate
|
||||||
|
- SystemMessagePromptTemplate
|
||||||
|
- AIMessagePromptTemplate
|
||||||
|
- HumanMessagePromptTemplate
|
||||||
|
|
||||||
llms:
|
llms:
|
||||||
- OpenAI
|
- OpenAI
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from langflow.template import nodes
|
from langflow.template import nodes
|
||||||
|
|
||||||
|
# These should always be instantiated
|
||||||
CUSTOM_NODES = {
|
CUSTOM_NODES = {
|
||||||
"prompts": {"ZeroShotPrompt": nodes.ZeroShotPromptNode()},
|
"prompts": {"ZeroShotPrompt": nodes.ZeroShotPromptNode()},
|
||||||
"tools": {"PythonFunction": nodes.PythonFunctionNode(), "Tool": nodes.ToolNode()},
|
"tools": {"PythonFunction": nodes.PythonFunctionNode(), "Tool": nodes.ToolNode()},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
import abc
|
||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Optional, Union
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
@ -12,6 +13,11 @@ class LangChainTypeCreator(BaseModel, ABC):
|
||||||
type_name: str
|
type_name: str
|
||||||
type_dict: Optional[Dict] = None
|
type_dict: Optional[Dict] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def frontend_node_class(self) -> str:
|
||||||
|
"""The class type of the FrontendNode created in frontend_node."""
|
||||||
|
return FrontendNode
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def type_to_loader_dict(self) -> Dict:
|
def type_to_loader_dict(self) -> Dict:
|
||||||
|
|
@ -62,7 +68,7 @@ class LangChainTypeCreator(BaseModel, ABC):
|
||||||
if key != "_type"
|
if key != "_type"
|
||||||
]
|
]
|
||||||
template = Template(type_name=name, fields=fields)
|
template = Template(type_name=name, fields=fields)
|
||||||
return FrontendNode(
|
return self.frontend_node_class(
|
||||||
template=template,
|
template=template,
|
||||||
description=signature.get("description", ""),
|
description=signature.get("description", ""),
|
||||||
base_classes=signature["base_classes"],
|
base_classes=signature["base_classes"],
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,50 @@
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from langchain.prompts import loading
|
from langchain.prompts import loading
|
||||||
|
from langchain import prompts
|
||||||
from langflow.custom.customs import get_custom_nodes
|
from langflow.custom.customs import get_custom_nodes
|
||||||
from langflow.interface.base import LangChainTypeCreator
|
from langflow.interface.base import LangChainTypeCreator
|
||||||
|
from langflow.interface.importing.utils import import_class
|
||||||
from langflow.settings import settings
|
from langflow.settings import settings
|
||||||
from langflow.utils.util import build_template_from_function
|
from langflow.template.nodes import PromptFrontendNode
|
||||||
|
from langflow.utils.util import build_template_from_class
|
||||||
|
|
||||||
|
|
||||||
class PromptCreator(LangChainTypeCreator):
|
class PromptCreator(LangChainTypeCreator):
|
||||||
type_name: str = "prompts"
|
type_name: str = "prompts"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def frontend_node_class(self) -> str:
|
||||||
|
return PromptFrontendNode
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type_to_loader_dict(self) -> Dict:
|
def type_to_loader_dict(self) -> Dict:
|
||||||
if self.type_dict is None:
|
if self.type_dict is None:
|
||||||
self.type_dict = loading.type_to_loader_dict
|
self.type_dict = {
|
||||||
|
prompt_name: import_class(f"langchain.prompts.{prompt_name}")
|
||||||
|
# if prompt_name is not lower case it is a class
|
||||||
|
for prompt_name in prompts.__all__
|
||||||
|
if not prompt_name.islower() and prompt_name in settings.prompts
|
||||||
|
}
|
||||||
return self.type_dict
|
return self.type_dict
|
||||||
|
|
||||||
def get_signature(self, name: str) -> Dict | None:
|
def get_signature(self, name: str) -> Dict | None:
|
||||||
try:
|
try:
|
||||||
if name in get_custom_nodes(self.type_name).keys():
|
if name in get_custom_nodes(self.type_name).keys():
|
||||||
return get_custom_nodes(self.type_name)[name]
|
return get_custom_nodes(self.type_name)[name]
|
||||||
return build_template_from_function(name, self.type_to_loader_dict)
|
return build_template_from_class(name, self.type_to_loader_dict)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise ValueError("Prompt not found") from exc
|
raise ValueError("Prompt not found") from exc
|
||||||
|
|
||||||
def to_list(self) -> List[str]:
|
def to_list(self) -> List[str]:
|
||||||
custom_prompts = get_custom_nodes("prompts")
|
custom_prompts = get_custom_nodes("prompts")
|
||||||
library_prompts = [
|
# library_prompts = [
|
||||||
prompt.__annotations__["return"].__name__
|
# prompt.__annotations__["return"].__name__
|
||||||
for prompt in self.type_to_loader_dict.values()
|
# for prompt in self.type_to_loader_dict.values()
|
||||||
if prompt.__annotations__["return"].__name__ in settings.prompts
|
# if prompt.__annotations__["return"].__name__ in settings.prompts
|
||||||
or settings.dev
|
# or settings.dev
|
||||||
]
|
# ]
|
||||||
return library_prompts + list(custom_prompts.keys())
|
return list(self.type_to_loader_dict.keys()) + list(custom_prompts.keys())
|
||||||
|
|
||||||
|
|
||||||
prompt_creator = PromptCreator()
|
prompt_creator = PromptCreator()
|
||||||
|
|
|
||||||
|
|
@ -219,3 +219,5 @@ class FrontendNode(BaseModel):
|
||||||
elif name == "ChatOpenAI" and key == "model_name":
|
elif name == "ChatOpenAI" and key == "model_name":
|
||||||
field.options = constants.CHAT_OPENAI_MODELS
|
field.options = constants.CHAT_OPENAI_MODELS
|
||||||
field.is_list = True
|
field.is_list = True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,17 @@ from langflow.utils.constants import DEFAULT_PYTHON_FUNCTION
|
||||||
from langchain.agents import loading
|
from langchain.agents import loading
|
||||||
|
|
||||||
|
|
||||||
class ZeroShotPromptNode(FrontendNode):
|
class BasePromptFrontendNode(FrontendNode):
|
||||||
|
name: str
|
||||||
|
template: Template
|
||||||
|
description: str
|
||||||
|
base_classes: list[str]
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return super().to_dict()
|
||||||
|
|
||||||
|
|
||||||
|
class ZeroShotPromptNode(BasePromptFrontendNode):
|
||||||
name: str = "ZeroShotPrompt"
|
name: str = "ZeroShotPrompt"
|
||||||
template: Template = Template(
|
template: Template = Template(
|
||||||
type_name="zero_shot",
|
type_name="zero_shot",
|
||||||
|
|
@ -227,3 +237,13 @@ class CSVAgentNode(FrontendNode):
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return super().to_dict()
|
return super().to_dict()
|
||||||
|
|
||||||
|
|
||||||
|
class PromptFrontendNode(FrontendNode):
|
||||||
|
@staticmethod
|
||||||
|
def format_field(field: TemplateField, name: Optional[str] = None) -> None:
|
||||||
|
# if field.field_type == "StringPromptTemplate"
|
||||||
|
# change it to str
|
||||||
|
if field.field_type == "StringPromptTemplate":
|
||||||
|
field.field_type = "str"
|
||||||
|
field.multiline = True
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue