Adds an Info button that links to docs (#539)

This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-06-26 23:16:58 +00:00 committed by GitHub
commit e362cfcf16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 393 additions and 270 deletions

View file

@ -1,141 +1,247 @@
---
agents:
- ZeroShotAgent
- JsonAgent
- CSVAgent
- AgentInitializer
- VectorStoreAgent
- VectorStoreRouterAgent
- SQLAgent
ZeroShotAgent:
documentation: "https://python.langchain.com/docs/modules/agents/how_to/custom_mrkl_agent"
JsonAgent:
documentation: "https://python.langchain.com/docs/modules/agents/toolkits/openapi"
CSVAgent:
documentation: "https://python.langchain.com/docs/modules/agents/toolkits/csv"
AgentInitializer:
documentation: "https://python.langchain.com/docs/modules/agents/agent_types/"
VectorStoreAgent:
documentation: ""
VectorStoreRouterAgent:
documentation: ""
SQLAgent:
documentation: ""
chains:
- LLMChain
- LLMMathChain
- LLMCheckerChain
- ConversationChain
- SeriesCharacterChain
- MidJourneyPromptChain
- TimeTravelGuideChain
- SQLDatabaseChain
- RetrievalQA
- RetrievalQAWithSourcesChain
- ConversationalRetrievalChain
- CombineDocsChain
LLMChain:
documentation: "https://python.langchain.com/docs/modules/chains/foundational/llm_chain"
LLMMathChain:
documentation: "https://python.langchain.com/docs/modules/chains/additional/llm_math"
LLMCheckerChain:
documentation: "https://python.langchain.com/docs/modules/chains/additional/llm_checker"
ConversationChain:
documentation: ""
SeriesCharacterChain:
documentation: ""
MidJourneyPromptChain:
documentation: ""
TimeTravelGuideChain:
documentation: ""
SQLDatabaseChain:
documentation: ""
RetrievalQA:
documentation: "https://python.langchain.com/docs/modules/chains/popular/vector_db_qa"
RetrievalQAWithSourcesChain:
documentation: ""
ConversationalRetrievalChain:
documentation: "https://python.langchain.com/docs/modules/chains/popular/chat_vector_db"
CombineDocsChain:
documentation: ""
documentloaders:
- AirbyteJSONLoader
- CoNLLULoader
- CSVLoader
- UnstructuredEmailLoader
- EverNoteLoader
- FacebookChatLoader
- GutenbergLoader
- BSHTMLLoader
- UnstructuredHTMLLoader
# - UnstructuredImageLoader # Issue with Python 3.11 (https://github.com/Unstructured-IO/unstructured-inference/issues/83)
- UnstructuredMarkdownLoader
- PyPDFLoader
- UnstructuredPowerPointLoader
- SRTLoader
- TelegramChatLoader
- TextLoader
- UnstructuredWordDocumentLoader
- WebBaseLoader
- AZLyricsLoader
- CollegeConfidentialLoader
- HNLoader
- IFixitLoader
- IMSDbLoader
- GitbookLoader
- ReadTheDocsLoader
- SlackDirectoryLoader
- NotionDirectoryLoader
- DirectoryLoader
- GitLoader
AirbyteJSONLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/airbyte_json"
CoNLLULoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/conll-u"
CSVLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/csv"
UnstructuredEmailLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/email"
EverNoteLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/evernote"
FacebookChatLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/facebook_chat"
GutenbergLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/gutenberg"
BSHTMLLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/how_to/html"
UnstructuredHTMLLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/how_to/html"
UnstructuredMarkdownLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/how_to/markdown"
PyPDFLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/how_to/pdf"
UnstructuredPowerPointLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/microsoft_powerpoint"
SRTLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/subtitle"
TelegramChatLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/telegram"
TextLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/"
UnstructuredWordDocumentLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/microsoft_word"
WebBaseLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/web_base"
AZLyricsLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/azlyrics"
CollegeConfidentialLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/college_confidential"
HNLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/hacker_news"
IFixitLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/ifixit"
IMSDbLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/imsdb"
GitbookLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/gitbook"
ReadTheDocsLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/readthedocs_documentation"
SlackDirectoryLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/slack"
NotionDirectoryLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/notion"
DirectoryLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/how_to/file_directory"
GitLoader:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/git"
embeddings:
- OpenAIEmbeddings
- HuggingFaceEmbeddings
- CohereEmbeddings
OpenAIEmbeddings:
documentation: "https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/openai"
HuggingFaceEmbeddings:
documentation: "https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/sentence_transformers"
CohereEmbeddings:
documentation: "https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/cohere"
llms:
- OpenAI
# - AzureOpenAI
# - AzureChatOpenAI
- ChatOpenAI
- LlamaCpp
- CTransformers
- Cohere
- Anthropic
- ChatAnthropic
- HuggingFaceHub
OpenAI:
documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/openai"
ChatOpenAI:
documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/integrations/openai"
LlamaCpp:
documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/llamacpp"
CTransformers:
documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/ctransformers"
Cohere:
documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/cohere"
Anthropic:
documentation: ""
ChatAnthropic:
documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/integrations/anthropic"
HuggingFaceHub:
documentation: "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/huggingface_hub"
memories:
- ConversationBufferMemory
- ConversationSummaryMemory
- ConversationKGMemory
ConversationBufferMemory:
documentation: "https://python.langchain.com/docs/modules/memory/how_to/summary"
ConversationSummaryMemory:
documentation: "https://python.langchain.com/docs/modules/memory/how_to/summary"
ConversationKGMemory:
documentation: "https://python.langchain.com/docs/modules/memory/how_to/kg"
ConversationBufferWindowMemory:
documentation: "https://python.langchain.com/docs/modules/memory/how_to/buffer_window"
VectorStoreRetrieverMemory:
documentation: "https://python.langchain.com/docs/modules/memory/how_to/vectorstore_retriever_memory"
prompts:
- PromptTemplate
- FewShotPromptTemplate
- ZeroShotPrompt
PromptTemplate:
documentation: "https://python.langchain.com/docs/modules/model_io/prompts/prompt_templates/"
ZeroShotPrompt:
documentation: "https://python.langchain.com/docs/modules/agents/how_to/custom_mrkl_agent"
textsplitters:
- CharacterTextSplitter
- RecursiveCharacterTextSplitter
# - LatexTextSplitter
# - PythonCodeTextSplitter
CharacterTextSplitter:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_transformers/text_splitters/character_text_splitter"
RecursiveCharacterTextSplitter:
documentation: "https://python.langchain.com/docs/modules/data_connection/document_transformers/text_splitters/recursive_text_splitter"
toolkits:
- OpenAPIToolkit
- JsonToolkit
- VectorStoreInfo
- VectorStoreRouterToolkit
- VectorStoreToolkit
OpenAPIToolkit:
documentation: ""
JsonToolkit:
documentation: ""
VectorStoreInfo:
documentation: ""
VectorStoreRouterToolkit:
documentation: ""
VectorStoreToolkit:
documentation: ""
tools:
- Search
- PAL-MATH
- Calculator
- Serper Search
- Tool
- PythonFunctionTool
- PythonFunction
- JsonSpec
- News API
- TMDB API
- Podcast API
- QuerySQLDataBaseTool
- InfoSQLDatabaseTool
- ListSQLDatabaseTool
# - QueryCheckerTool
- BingSearchRun
- GoogleSearchRun
- GoogleSearchResults
- GoogleSerperRun
- JsonListKeysTool
- JsonGetValueTool
- PythonREPLTool
- PythonAstREPLTool
- RequestsGetTool
- RequestsPostTool
- RequestsPatchTool
- RequestsPutTool
- RequestsDeleteTool
- WikipediaQueryRun
- WolframAlphaQueryRun
Search:
documentation: ""
PAL-MATH:
documentation: ""
Calculator:
documentation: ""
Serper Search:
documentation: ""
Tool:
documentation: ""
PythonFunctionTool:
documentation: ""
PythonFunction:
documentation: ""
JsonSpec:
documentation: ""
News API:
documentation: ""
TMDB API:
documentation: ""
Podcast API:
documentation: ""
QuerySQLDataBaseTool:
documentation: ""
InfoSQLDatabaseTool:
documentation: ""
ListSQLDatabaseTool:
documentation: ""
BingSearchRun:
documentation: ""
GoogleSearchRun:
documentation: ""
GoogleSearchResults:
documentation: ""
GoogleSerperRun:
documentation: ""
JsonListKeysTool:
documentation: ""
JsonGetValueTool:
documentation: ""
PythonREPLTool:
documentation: ""
PythonAstREPLTool:
documentation: ""
RequestsGetTool:
documentation: ""
RequestsPostTool:
documentation: ""
RequestsPatchTool:
documentation: ""
RequestsPutTool:
documentation: ""
RequestsDeleteTool:
documentation: ""
WikipediaQueryRun:
documentation: ""
WolframAlphaQueryRun:
documentation: ""
utilities:
- BingSearchAPIWrapper
- GoogleSearchAPIWrapper
- GoogleSerperAPIWrapper
- SearxResults
- SearxSearchWrapper
- SerpAPIWrapper
- WikipediaAPIWrapper
- WolframAlphaAPIWrapper
# - ZapierNLAWrapper
- SQLDatabase
BingSearchAPIWrapper:
documentation: ""
GoogleSearchAPIWrapper:
documentation: ""
GoogleSerperAPIWrapper:
documentation: ""
SearxResults:
documentation: ""
SearxSearchWrapper:
documentation: ""
SerpAPIWrapper:
documentation: ""
WikipediaAPIWrapper:
documentation: ""
WolframAlphaAPIWrapper:
documentation: ""
vectorstores:
- Chroma
- Qdrant
- Weaviate
- FAISS
- Pinecone
- SupabaseVectorStore
- MongoDBAtlasVectorSearch
Chroma:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/chroma"
Qdrant:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/qdrant"
Weaviate:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/weaviate"
FAISS:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/faiss"
Pinecone:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/pinecone"
SupabaseVectorStore:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/supabase"
MongoDBAtlasVectorSearch:
documentation: "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/mongodb_atlas_vector_search"
wrappers:
- RequestsWrapper
# - ChatPromptTemplate
# - SystemMessagePromptTemplate
# - HumanMessagePromptTemplate
RequestsWrapper:
documentation: ""

View file

@ -8,6 +8,7 @@ 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.logger import logger
from langflow.settings import settings
# Assuming necessary imports for Field, Template, and FrontendNode classes
@ -15,12 +16,29 @@ from langflow.utils.logger import logger
class LangChainTypeCreator(BaseModel, ABC):
type_name: str
type_dict: Optional[Dict] = None
name_docs_dict: Optional[Dict[str, str]] = None
@property
def frontend_node_class(self) -> Type[FrontendNode]:
"""The class type of the FrontendNode created in frontend_node."""
return FrontendNode
@property
def docs_map(self) -> Dict[str, str]:
"""A dict with the name of the component as key and the documentation link as value."""
if self.name_docs_dict is None:
try:
type_settings = getattr(settings, self.type_name)
self.name_docs_dict = {
name: value_dict["documentation"]
for name, value_dict in type_settings.items()
}
except AttributeError as exc:
logger.error(exc)
self.name_docs_dict = {}
return self.name_docs_dict
@property
@abstractmethod
def type_to_loader_dict(self) -> Dict:
@ -83,7 +101,7 @@ class LangChainTypeCreator(BaseModel, ABC):
signature.add_extra_fields()
signature.add_extra_base_classes()
signature.set_documentation(self.docs_map.get(name, ""))
return signature

View file

@ -1,5 +1,5 @@
import json
from typing import Any, Callable, Dict, Sequence
from typing import Any, Callable, Dict, Sequence, Type
from langchain.agents import ZeroShotAgent
from langchain.agents import agent as agent_module
@ -16,6 +16,10 @@ from langflow.interface.toolkits.base import toolkits_creator
from langflow.interface.chains.base import chain_creator
from langflow.interface.utils import load_file_into_dict
from langflow.utils import validate
from langchain.chains.base import Chain
from langchain.vectorstores.base import VectorStore
from langchain.document_loaders.base import BaseLoader
from langchain.prompts.base import BasePromptTemplate
def instantiate_class(node_type: str, base_type: str, params: Dict) -> Any:
@ -76,7 +80,7 @@ def instantiate_based_on_type(class_object, base_type, node_type, params):
return class_object(**params)
def instantiate_chains(node_type, class_object, params):
def instantiate_chains(node_type, class_object: Type[Chain], params: Dict):
if "retriever" in params and hasattr(params["retriever"], "as_retriever"):
params["retriever"] = params["retriever"].as_retriever()
if node_type in chain_creator.from_method_nodes:
@ -88,11 +92,11 @@ def instantiate_chains(node_type, class_object, params):
return class_object(**params)
def instantiate_agent(class_object, params):
def instantiate_agent(class_object: Type[agent_module.Agent], params: Dict):
return load_agent_executor(class_object, params)
def instantiate_prompt(node_type, class_object, params):
def instantiate_prompt(node_type, class_object: Type[BasePromptTemplate], params: Dict):
if node_type == "ZeroShotPrompt":
if "tools" not in params:
params["tools"] = []
@ -100,7 +104,7 @@ def instantiate_prompt(node_type, class_object, params):
return class_object(**params)
def instantiate_tool(node_type, class_object, params):
def instantiate_tool(node_type, class_object: Type[BaseTool], params: Dict):
if node_type == "JsonSpec":
params["dict_"] = load_file_into_dict(params.pop("path"))
return class_object(**params)
@ -118,7 +122,7 @@ def instantiate_tool(node_type, class_object, params):
return class_object(**params)
def instantiate_toolkit(node_type, class_object, params):
def instantiate_toolkit(node_type, class_object: Type[BaseToolkit], params: Dict):
loaded_toolkit = class_object(**params)
# Commenting this out for now to use toolkits as normal tools
# if toolkits_creator.has_create_function(node_type):
@ -128,7 +132,7 @@ def instantiate_toolkit(node_type, class_object, params):
return loaded_toolkit
def instantiate_embedding(class_object, params):
def instantiate_embedding(class_object, params: Dict):
params.pop("model", None)
params.pop("headers", None)
try:
@ -142,7 +146,7 @@ def instantiate_embedding(class_object, params):
return class_object(**params)
def instantiate_vectorstore(class_object, params):
def instantiate_vectorstore(class_object: Type[VectorStore], params: Dict):
search_kwargs = params.pop("search_kwargs", {})
if initializer := vecstore_initializer.get(class_object.__name__):
vecstore = initializer(class_object, params)
@ -158,7 +162,7 @@ def instantiate_vectorstore(class_object, params):
return vecstore
def instantiate_documentloader(class_object, params):
def instantiate_documentloader(class_object: Type[BaseLoader], params: Dict):
if "file_filter" in params:
# file_filter will be a string but we need a function
# that will be used to filter the files using file_filter
@ -187,19 +191,29 @@ def instantiate_documentloader(class_object, params):
return docs
def instantiate_textsplitter(class_object, params):
def instantiate_textsplitter(
class_object,
params: Dict,
):
try:
documents = params.pop("documents")
except KeyError as e:
except KeyError as exc:
raise ValueError(
"The source you provided did not load correctly or was empty."
"Try changing the chunk_size of the Text Splitter."
) from e
text_splitter = class_object(**params)
) from exc
if "separator_type" in params and params["separator_type"] == "Text":
text_splitter = class_object(**params)
else:
params["language"] = params.pop("separator_type", None)
params.pop("separators", None)
text_splitter = class_object.from_language(**params)
return text_splitter.split_documents(documents)
def instantiate_utility(node_type, class_object, params):
def instantiate_utility(node_type, class_object, params: Dict):
if node_type == "SQLDatabase":
return class_object.from_uri(params.pop("uri"))
return class_object(**params)

View file

@ -1,24 +1,23 @@
import os
from typing import List
import yaml
from pydantic import BaseSettings, root_validator
class Settings(BaseSettings):
chains: List[str] = []
agents: List[str] = []
prompts: List[str] = []
llms: List[str] = []
tools: List[str] = []
memories: List[str] = []
embeddings: List[str] = []
vectorstores: List[str] = []
documentloaders: List[str] = []
wrappers: List[str] = []
toolkits: List[str] = []
textsplitters: List[str] = []
utilities: List[str] = []
chains: dict = {}
agents: dict = {}
prompts: dict = {}
llms: dict = {}
tools: dict = {}
memories: dict = {}
embeddings: dict = {}
vectorstores: dict = {}
documentloaders: dict = {}
wrappers: dict = {}
toolkits: dict = {}
textsplitters: dict = {}
utilities: dict = {}
dev: bool = False
database_url: str = "sqlite:///./langflow.db"
cache: str = "InMemoryCache"
@ -38,16 +37,16 @@ class Settings(BaseSettings):
def update_from_yaml(self, file_path: str, dev: bool = False):
new_settings = load_settings_from_yaml(file_path)
self.chains = new_settings.chains or []
self.agents = new_settings.agents or []
self.prompts = new_settings.prompts or []
self.llms = new_settings.llms or []
self.tools = new_settings.tools or []
self.memories = new_settings.memories or []
self.wrappers = new_settings.wrappers or []
self.toolkits = new_settings.toolkits or []
self.textsplitters = new_settings.textsplitters or []
self.utilities = new_settings.utilities or []
self.chains = new_settings.chains or {}
self.agents = new_settings.agents or {}
self.prompts = new_settings.prompts or {}
self.llms = new_settings.llms or {}
self.tools = new_settings.tools or {}
self.memories = new_settings.memories or {}
self.wrappers = new_settings.wrappers or {}
self.toolkits = new_settings.toolkits or {}
self.textsplitters = new_settings.textsplitters or {}
self.utilities = new_settings.utilities or {}
self.dev = dev
def update_settings(self, **kwargs):

View file

@ -15,14 +15,21 @@ class FrontendNode(BaseModel):
base_classes: List[str]
name: str = ""
display_name: str = ""
documentation: str = ""
def set_documentation(self, documentation: str) -> None:
"""Sets the documentation of the frontend node."""
self.documentation = documentation
def to_dict(self) -> dict:
"""Returns a dict representation of the frontend node."""
return {
self.name: {
"template": self.template.to_dict(self.format_field),
"description": self.description,
"base_classes": self.base_classes,
"display_name": self.display_name or self.name,
"documentation": self.documentation,
},
}

View file

@ -1,5 +1,6 @@
from langflow.template.field.base import TemplateField
from langflow.template.frontend_node.base import FrontendNode
from langchain.text_splitter import Language
class TextSplittersFrontendNode(FrontendNode):
@ -17,6 +18,22 @@ class TextSplittersFrontendNode(FrontendNode):
name = "separator"
elif self.template.type_name == "RecursiveCharacterTextSplitter":
name = "separators"
# Add a field for type of separator
# which will have Text or any value from the
# Language enum
self.template.add_field(
TemplateField(
field_type="str",
required=True,
show=True,
name="separator_type",
advanced=False,
is_list=True,
options=[x.value for x in Language],
value="Text",
display_name="Separator Type",
)
)
self.template.add_field(
TemplateField(
field_type="str",

View file

@ -200,7 +200,7 @@ class VectorStoreFrontendNode(FrontendNode):
self.template.add_field(field)
def add_extra_base_classes(self) -> None:
self.base_classes.append("BaseRetriever")
self.base_classes.extend(("BaseRetriever", "VectorStoreRetriever"))
@staticmethod
def format_field(field: TemplateField, name: Optional[str] = None) -> None:

View file

@ -6,16 +6,7 @@ import {
} from "../../utils";
import ParameterComponent from "./components/parameterComponent";
import { typesContext } from "../../contexts/typesContext";
import {
useContext,
useState,
useEffect,
useRef,
ForwardRefExoticComponent,
ComponentType,
SVGProps,
ReactNode,
} from "react";
import { useContext, useState, useEffect, useRef } from "react";
import { NodeDataType } from "../../types/flow";
import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
@ -23,10 +14,9 @@ import NodeModal from "../../modals/NodeModal";
import Tooltip from "../../components/TooltipComponent";
import { NodeToolbar } from "reactflow";
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
import { FileText, Info } from "lucide-react";
import ShadTooltip from "../../components/ShadTooltipComponent";
import { useSSE } from "../../contexts/SSEContext";
import { ReactElement } from "react-markdown/lib/react-markdown";
export default function GenericNode({
data,
@ -46,6 +36,7 @@ export default function GenericNode({
const [validationStatus, setValidationStatus] = useState(null);
// State for outline color
const { sseData, isBuilding } = useSSE();
const refHtml = useRef(null);
// useEffect(() => {
// if (reactFlowInstance) {
@ -79,6 +70,22 @@ export default function GenericNode({
useEffect(() => {}, [closePopUp, data.node.template]);
useEffect(() => {
refHtml.current = (
<div className="flex">
<span>{`${data.node.display_name} Documentation`}</span>
<span
className="self-center"
style={{
color: nodeColors[types[data.type]] ?? nodeColors.unknown,
}}
>
<FileText className="h-4 w-4 ml-2" />
</span>
</div>
);
}, []);
return (
<>
<NodeToolbar>
@ -103,7 +110,7 @@ export default function GenericNode({
color: nodeColors[types[data.type]] ?? nodeColors.unknown,
}}
/>
<div className="ml-2 truncate">
<div className="ml-2 truncate flex">
<ShadTooltip
delayDuration={1500}
content={data.node.display_name}
@ -112,6 +119,29 @@ export default function GenericNode({
{data.node.display_name}
</div>
</ShadTooltip>
<div className="">
{data.node.documentation !== "" && (
<ShadTooltip
open={true}
delayDuration={1000}
content={refHtml.current}
>
<a
href={data.node.documentation}
target="_blank"
rel="noopener noreferrer"
>
<Info
style={{
color:
nodeColors[types[data.type]] ?? nodeColors.unknown,
}}
className="ml-2 self-center w-4 h-4"
/>
</a>
</ShadTooltip>
)}
</div>
</div>
</div>
<div className="flex gap-3">

View file

@ -192,39 +192,49 @@ export function TabsProvider({ children }: { children: ReactNode }) {
}
function processFlowEdges(flow) {
if(!flow.data || !flow.data.edges) return;
if (!flow.data || !flow.data.edges) return;
flow.data.edges.forEach((edge) => {
edge.className = "";
edge.style = { stroke: "#555555" };
});
}
function updateDisplay_name(node:NodeType,template:APIClassType) {
node.data.node.display_name = template["display_name"]?template["display_name"]:node.data.type;
function updateDisplay_name(node: NodeType, template: APIClassType) {
node.data.node.display_name = template["display_name"] || node.data.type;
}
function updateNodeDocumentation(node: NodeType, template: APIClassType) {
node.data.node.documentation = template["documentation"];
}
function processFlowNodes(flow) {
if(!flow.data || !flow.data.nodes) return;
flow.data.nodes.forEach((node:NodeType) => {
if (!flow.data || !flow.data.nodes) return;
flow.data.nodes.forEach((node: NodeType) => {
const template = templates[node.data.type];
if (!template) {
setErrorData({ title: `Unknown node type: ${node.data.type}` });
return;
}
if (Object.keys(template["template"]).length > 0) {
updateDisplay_name(node,template);
updateDisplay_name(node, template);
updateNodeBaseClasses(node, template);
updateNodeEdges(flow, node, template);
updateNodeDescription(node, template);
updateNodeTemplate(node, template);
updateNodeDocumentation(node, template);
}
});
}
function updateNodeBaseClasses(node:NodeType,template:APIClassType) {
function updateNodeBaseClasses(node: NodeType, template: APIClassType) {
node.data.node.base_classes = template["base_classes"];
}
function updateNodeEdges(flow:FlowType, node:NodeType,template:APIClassType) {
function updateNodeEdges(
flow: FlowType,
node: NodeType,
template: APIClassType
) {
flow.data.edges.forEach((edge) => {
if (edge.source === node.id) {
edge.sourceHandle = edge.sourceHandle
@ -236,11 +246,11 @@ export function TabsProvider({ children }: { children: ReactNode }) {
});
}
function updateNodeDescription(node:NodeType,template:APIClassType) {
function updateNodeDescription(node: NodeType, template: APIClassType) {
node.data.node.description = template["description"];
}
function updateNodeTemplate(node:NodeType,template:APIClassType) {
function updateNodeTemplate(node: NodeType, template: APIClassType) {
node.data.node.template = updateTemplate(
template["template"] as unknown as APITemplateType,
node.data.node.template as APITemplateType

View file

@ -12,6 +12,7 @@ export type APIClassType = {
description: string;
template: APITemplateType;
display_name: string;
documentation: string;
[key: string]: Array<string> | string | APITemplateType;
};
export type TemplateVariableType = {

View file

@ -88,85 +88,6 @@ def test_prompt_template(client: TestClient):
}
def test_few_shot_prompt_template(client: TestClient):
response = client.get("api/v1/all")
assert response.status_code == 200
json_response = response.json()
prompts = json_response["prompts"]
prompt = prompts["FewShotPromptTemplate"]
template = prompt["template"]
# Test other fields in the template similar to PromptTemplate
assert template["examples"] == {
"required": False,
"placeholder": "",
"show": True,
"multiline": True,
"password": False,
"name": "examples",
"type": "prompt",
"list": True,
"advanced": False,
}
assert template["example_selector"] == {
"required": False,
"placeholder": "",
"show": False,
"multiline": False,
"password": False,
"name": "example_selector",
"type": "BaseExampleSelector",
"list": False,
"advanced": False,
}
assert template["example_prompt"] == {
"required": True,
"placeholder": "",
"show": True,
"multiline": False,
"password": False,
"name": "example_prompt",
"type": "PromptTemplate",
"list": False,
"advanced": False,
}
assert template["suffix"] == {
"required": True,
"placeholder": "",
"show": True,
"multiline": True,
"password": False,
"name": "suffix",
"type": "prompt",
"list": False,
"advanced": False,
}
assert template["example_separator"] == {
"required": False,
"placeholder": "",
"show": False,
"multiline": False,
"value": "\n\n",
"password": False,
"name": "example_separator",
"type": "str",
"list": False,
"advanced": False,
}
assert template["prefix"] == {
"required": False,
"placeholder": "",
"show": True,
"multiline": True,
"value": "",
"password": False,
"name": "prefix",
"type": "prompt",
"list": False,
"advanced": False,
}
def test_zero_shot_prompt(client: TestClient):
response = client.get("api/v1/all")
assert response.status_code == 200