merged chat_and_cache into dev
This commit is contained in:
commit
8a169c9782
35 changed files with 1632 additions and 966 deletions
15
.devcontainer/demo/README.md
Normal file
15
.devcontainer/demo/README.md
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# LangFlow Demo Codespace Readme
|
||||||
|
|
||||||
|
These instructions will walk you through the process of running a LangFlow demo via GitHub Codespaces.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
### Create a Codespace in GitHub
|
||||||
|
|
||||||
|
To setup the demo, simply navigate to the Langflow repo, click the "+" button, and select "Create new Codespace". This will automatically create a new codespace in your browser, which you can use for the demo.
|
||||||
|
|
||||||
|
### Wait for everything to install
|
||||||
|
|
||||||
|
After the codespace is opened, you should see a new Terminal window in VS Code where langflow is installed. Once the install completes, `langflow` will launch the webserver and your application will be available via devcontainer port.
|
||||||
|
|
||||||
|
Note: VS Code should prompt you with a button to push once the port is available.
|
||||||
32
.devcontainer/demo/devcontainer.json
Normal file
32
.devcontainer/demo/devcontainer.json
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||||
|
// README at: https://github.com/devcontainers/templates/tree/main/src/universal
|
||||||
|
{
|
||||||
|
"name": "LangChain Demo Container",
|
||||||
|
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/python:3.10",
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/aws-cli:1": {},
|
||||||
|
"ghcr.io/devcontainers/features/docker-in-docker": {},
|
||||||
|
"ghcr.io/devcontainers/features/node": {}
|
||||||
|
},
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"actboy168.tasks",
|
||||||
|
"GitHub.copilot",
|
||||||
|
"ms-python.python",
|
||||||
|
"eamodio.gitlens"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||||
|
// "features": {},
|
||||||
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
|
// "forwardPorts": [],
|
||||||
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
"postCreateCommand": "pipx install 'langflow>=0.0.33' && langflow --host 0.0.0.0"
|
||||||
|
// Configure tool-specific properties.
|
||||||
|
// "customizations": {},
|
||||||
|
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||||
|
// "remoteUser": "root"
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||||
// README at: https://github.com/devcontainers/templates/tree/main/src/universal
|
// README at: https://github.com/devcontainers/templates/tree/main/src/universal
|
||||||
{
|
{
|
||||||
"name": "Default Linux Universal",
|
"name": "LangChain Dev Container",
|
||||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||||
"image": "mcr.microsoft.com/devcontainers/universal:2-linux",
|
"image": "mcr.microsoft.com/devcontainers/universal:2-linux",
|
||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/aws-cli:1": {}
|
"ghcr.io/devcontainers/features/aws-cli:1": {},
|
||||||
|
"ghcr.io/devcontainers/features/docker-in-docker": {}
|
||||||
},
|
},
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {"extensions": [
|
"vscode": {"extensions": [
|
||||||
|
|
@ -15,7 +16,7 @@
|
||||||
"sourcery.sourcery",
|
"sourcery.sourcery",
|
||||||
"eamodio.gitlens"
|
"eamodio.gitlens"
|
||||||
]}
|
]}
|
||||||
}
|
},
|
||||||
|
|
||||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||||
// "features": {},
|
// "features": {},
|
||||||
|
|
@ -24,7 +25,7 @@
|
||||||
// "forwardPorts": [],
|
// "forwardPorts": [],
|
||||||
|
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
// "postCreateCommand": "uname -a",
|
"postCreateCommand": "poetry install"
|
||||||
|
|
||||||
// Configure tool-specific properties.
|
// Configure tool-specific properties.
|
||||||
// "customizations": {},
|
// "customizations": {},
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
~ A User Interface For [LangChain](https://github.com/hwchase17/langchain) ~
|
~ A User Interface For [LangChain](https://github.com/hwchase17/langchain) ~
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
<a href="https://huggingface.co/spaces/Logspace/LangFlow"><img src="https://huggingface.co/datasets/huggingface/badges/raw/main/open-in-hf-spaces-sm.svg" alt="HuggingFace Spaces"></a>
|
||||||
<img alt="GitHub Contributors" src="https://img.shields.io/github/contributors/logspace-ai/langflow" />
|
<img alt="GitHub Contributors" src="https://img.shields.io/github/contributors/logspace-ai/langflow" />
|
||||||
<img alt="GitHub Last Commit" src="https://img.shields.io/github/last-commit/logspace-ai/langflow" />
|
<img alt="GitHub Last Commit" src="https://img.shields.io/github/last-commit/logspace-ai/langflow" />
|
||||||
<img alt="" src="https://img.shields.io/github/repo-size/logspace-ai/langflow" />
|
<img alt="" src="https://img.shields.io/github/repo-size/logspace-ai/langflow" />
|
||||||
|
|
@ -31,7 +32,7 @@ Next, run:
|
||||||
```shell
|
```shell
|
||||||
python -m langflow
|
python -m langflow
|
||||||
```
|
```
|
||||||
or
|
or
|
||||||
```shell
|
```shell
|
||||||
langflow
|
langflow
|
||||||
```
|
```
|
||||||
|
|
|
||||||
764
poetry.lock
generated
764
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "langflow"
|
name = "langflow"
|
||||||
version = "0.0.57"
|
version = "0.0.59"
|
||||||
description = "A Python package with a built-in web application"
|
description = "A Python package with a built-in web application"
|
||||||
authors = ["Logspace <contact@logspace.ai>"]
|
authors = ["Logspace <contact@logspace.ai>"]
|
||||||
maintainers = [
|
maintainers = [
|
||||||
|
|
@ -29,7 +29,7 @@ google-search-results = "^2.4.1"
|
||||||
google-api-python-client = "^2.79.0"
|
google-api-python-client = "^2.79.0"
|
||||||
typer = "^0.7.0"
|
typer = "^0.7.0"
|
||||||
gunicorn = "^20.1.0"
|
gunicorn = "^20.1.0"
|
||||||
langchain = "^0.0.131"
|
langchain = "~0.0.150"
|
||||||
openai = "^0.27.2"
|
openai = "^0.27.2"
|
||||||
types-pyyaml = "^6.0.12.8"
|
types-pyyaml = "^6.0.12.8"
|
||||||
dill = "^0.3.6"
|
dill = "^0.3.6"
|
||||||
|
|
@ -58,6 +58,8 @@ httpx = "^0.23.3"
|
||||||
pytest = "^7.2.2"
|
pytest = "^7.2.2"
|
||||||
types-requests = "^2.28.11"
|
types-requests = "^2.28.11"
|
||||||
requests = "^2.28.0"
|
requests = "^2.28.0"
|
||||||
|
pytest-cov = "^4.0.0"
|
||||||
|
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 120
|
line-length = 120
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,11 @@ CUSTOM_NODES = {
|
||||||
"utilities": {
|
"utilities": {
|
||||||
"SQLDatabase": nodes.SQLDatabaseNode(),
|
"SQLDatabase": nodes.SQLDatabaseNode(),
|
||||||
},
|
},
|
||||||
|
"chains": {
|
||||||
|
"SeriesCharacterChain": nodes.SeriesCharacterChainNode(),
|
||||||
|
"TimeTravelGuideChain": nodes.TimeTravelGuideChainNode(),
|
||||||
|
"MidJourneyPromptChain": nodes.MidJourneyPromptChainNode(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ class SQLAgent(AgentExecutor):
|
||||||
def from_toolkit_and_llm(cls, llm: BaseLLM, database_uri: str, **kwargs: Any):
|
def from_toolkit_and_llm(cls, llm: BaseLLM, database_uri: str, **kwargs: Any):
|
||||||
"""Construct a sql agent from an LLM and tools."""
|
"""Construct a sql agent from an LLM and tools."""
|
||||||
db = SQLDatabase.from_uri(database_uri)
|
db = SQLDatabase.from_uri(database_uri)
|
||||||
toolkit = SQLDatabaseToolkit(db=db)
|
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
|
||||||
|
|
||||||
# The right code should be this, but there is a problem with tools = toolkit.get_tools()
|
# The right code should be this, but there is a problem with tools = toolkit.get_tools()
|
||||||
# related to `OPENAI_API_KEY`
|
# related to `OPENAI_API_KEY`
|
||||||
|
|
@ -274,7 +274,11 @@ class InitializeAgent(AgentExecutor):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def initialize(
|
def initialize(
|
||||||
cls, llm: BaseLLM, tools: List[Tool], agent: str, memory: BaseChatMemory
|
cls,
|
||||||
|
llm: BaseLLM,
|
||||||
|
tools: List[Tool],
|
||||||
|
agent: str,
|
||||||
|
memory: Optional[BaseChatMemory] = None,
|
||||||
):
|
):
|
||||||
return initialize_agent(
|
return initialize_agent(
|
||||||
tools=tools,
|
tools=tools,
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,9 @@ def load_agent_executor(agent_class: type[agent_module.Agent], params, **kwargs)
|
||||||
allowed_tools = params["allowed_tools"]
|
allowed_tools = params["allowed_tools"]
|
||||||
llm_chain = params["llm_chain"]
|
llm_chain = params["llm_chain"]
|
||||||
tool_names = [tool.name for tool in allowed_tools]
|
tool_names = [tool.name for tool in allowed_tools]
|
||||||
agent = agent_class(allowed_tools=tool_names, llm_chain=llm_chain)
|
# 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
|
||||||
return AgentExecutor.from_agent_and_tools(
|
return AgentExecutor.from_agent_and_tools(
|
||||||
agent=agent,
|
agent=agent,
|
||||||
tools=allowed_tools,
|
tools=allowed_tools,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
import io
|
import io
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
from chromadb.errors import NotEnoughElementsException
|
from chromadb.errors import NotEnoughElementsException # type: ignore
|
||||||
|
|
||||||
from langflow.cache.base import compute_dict_hash, load_cache, memoize_dict
|
from langflow.cache.base import compute_dict_hash, load_cache, memoize_dict
|
||||||
from langflow.graph.graph import Graph
|
from langflow.graph.graph import Graph
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ class TemplateFieldCreator(BaseModel, ABC):
|
||||||
options: list[str] = []
|
options: list[str] = []
|
||||||
name: str = ""
|
name: str = ""
|
||||||
display_name: Optional[str] = None
|
display_name: Optional[str] = None
|
||||||
|
advanced: bool = True
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
result = self.dict()
|
result = self.dict()
|
||||||
|
|
@ -225,6 +226,19 @@ class FrontendNode(BaseModel):
|
||||||
field.is_list = True
|
field.is_list = True
|
||||||
if "api_key" in key and "OpenAI" in str(name):
|
if "api_key" in key and "OpenAI" in str(name):
|
||||||
field.display_name = "OpenAI API Key"
|
field.display_name = "OpenAI API Key"
|
||||||
field.required = True
|
field.required = False
|
||||||
if field.value is None:
|
if field.value is None:
|
||||||
field.value = ""
|
field.value = ""
|
||||||
|
# If the field.name contains api or api and key, then it might be an api key
|
||||||
|
# other conditions are to make sure that it is not an input or output variable
|
||||||
|
if "api" in key.lower() and "key" in key.lower():
|
||||||
|
field.required = False
|
||||||
|
|
||||||
|
if "kwargs" in field.name.lower():
|
||||||
|
field.advanced = True
|
||||||
|
field.required = False
|
||||||
|
field.show = False
|
||||||
|
# If the field.name contains api or api and key, then it might be an api key
|
||||||
|
# other conditions are to make sure that it is not an input or output variable
|
||||||
|
if "api" in key.lower() and "key" in key.lower():
|
||||||
|
field.required = False
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,107 @@ class PythonFunctionNode(FrontendNode):
|
||||||
return super().to_dict()
|
return super().to_dict()
|
||||||
|
|
||||||
|
|
||||||
|
class MidJourneyPromptChainNode(FrontendNode):
|
||||||
|
name: str = "MidJourneyPromptChain"
|
||||||
|
template: Template = Template(
|
||||||
|
type_name="MidJourneyPromptChain",
|
||||||
|
fields=[
|
||||||
|
TemplateField(
|
||||||
|
field_type="BaseLanguageModel",
|
||||||
|
required=True,
|
||||||
|
placeholder="",
|
||||||
|
is_list=False,
|
||||||
|
show=True,
|
||||||
|
advanced=False,
|
||||||
|
multiline=False,
|
||||||
|
name="llm",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
description: str = "MidJourneyPromptChain is a chain you can use to generate new MidJourney prompts."
|
||||||
|
base_classes: list[str] = [
|
||||||
|
"LLMChain",
|
||||||
|
"BaseCustomChain",
|
||||||
|
"Chain",
|
||||||
|
"ConversationChain",
|
||||||
|
"MidJourneyPromptChain",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class TimeTravelGuideChainNode(FrontendNode):
|
||||||
|
name: str = "TimeTravelGuideChain"
|
||||||
|
template: Template = Template(
|
||||||
|
type_name="TimeTravelGuideChain",
|
||||||
|
fields=[
|
||||||
|
TemplateField(
|
||||||
|
field_type="BaseLanguageModel",
|
||||||
|
required=True,
|
||||||
|
placeholder="",
|
||||||
|
is_list=False,
|
||||||
|
show=True,
|
||||||
|
advanced=False,
|
||||||
|
multiline=False,
|
||||||
|
name="llm",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
description: str = "Time travel guide chain to be used in the flow."
|
||||||
|
base_classes: list[str] = [
|
||||||
|
"LLMChain",
|
||||||
|
"BaseCustomChain",
|
||||||
|
"TimeTravelGuideChain",
|
||||||
|
"Chain",
|
||||||
|
"ConversationChain",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class SeriesCharacterChainNode(FrontendNode):
|
||||||
|
name: str = "SeriesCharacterChain"
|
||||||
|
template: Template = Template(
|
||||||
|
type_name="SeriesCharacterChain",
|
||||||
|
fields=[
|
||||||
|
TemplateField(
|
||||||
|
field_type="str",
|
||||||
|
required=True,
|
||||||
|
placeholder="",
|
||||||
|
is_list=False,
|
||||||
|
show=True,
|
||||||
|
advanced=False,
|
||||||
|
multiline=False,
|
||||||
|
name="character",
|
||||||
|
),
|
||||||
|
TemplateField(
|
||||||
|
field_type="str",
|
||||||
|
required=True,
|
||||||
|
placeholder="",
|
||||||
|
is_list=False,
|
||||||
|
show=True,
|
||||||
|
advanced=False,
|
||||||
|
multiline=False,
|
||||||
|
name="series",
|
||||||
|
),
|
||||||
|
TemplateField(
|
||||||
|
field_type="BaseLanguageModel",
|
||||||
|
required=True,
|
||||||
|
placeholder="",
|
||||||
|
is_list=False,
|
||||||
|
show=True,
|
||||||
|
advanced=False,
|
||||||
|
multiline=False,
|
||||||
|
name="llm",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
description: str = "SeriesCharacterChain is a chain you can use to have a conversation with a character from a series." # noqa
|
||||||
|
base_classes: list[str] = [
|
||||||
|
"LLMChain",
|
||||||
|
"BaseCustomChain",
|
||||||
|
"Chain",
|
||||||
|
"ConversationChain",
|
||||||
|
"SeriesCharacterChain",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class ToolNode(FrontendNode):
|
class ToolNode(FrontendNode):
|
||||||
name: str = "Tool"
|
name: str = "Tool"
|
||||||
template: Template = Template(
|
template: Template = Template(
|
||||||
|
|
@ -418,17 +519,29 @@ class ChainFrontendNode(FrontendNode):
|
||||||
def format_field(field: TemplateField, name: Optional[str] = None) -> None:
|
def format_field(field: TemplateField, name: Optional[str] = None) -> None:
|
||||||
FrontendNode.format_field(field, name)
|
FrontendNode.format_field(field, name)
|
||||||
|
|
||||||
|
field.advanced = False
|
||||||
if "key" in field.name:
|
if "key" in field.name:
|
||||||
field.password = False
|
field.password = False
|
||||||
field.show = False
|
field.show = False
|
||||||
if field.name in ["input_key", "output_key"]:
|
if field.name in ["input_key", "output_key"]:
|
||||||
field.required = True
|
field.required = True
|
||||||
field.show = True
|
field.show = True
|
||||||
|
field.advanced = True
|
||||||
|
|
||||||
# Separated for possible future changes
|
# Separated for possible future changes
|
||||||
if field.name == "prompt" and field.value is None:
|
if field.name == "prompt" and field.value is None:
|
||||||
# if no prompt is provided, use the default prompt
|
# if no prompt is provided, use the default prompt
|
||||||
field.required = False
|
field.required = False
|
||||||
field.show = True
|
field.show = True
|
||||||
|
field.advanced = False
|
||||||
|
if field.name == "memory":
|
||||||
|
field.required = False
|
||||||
|
field.show = True
|
||||||
|
field.advanced = False
|
||||||
|
if field.name == "verbose":
|
||||||
|
field.required = False
|
||||||
|
field.show = True
|
||||||
|
field.advanced = True
|
||||||
|
|
||||||
|
|
||||||
class LLMFrontendNode(FrontendNode):
|
class LLMFrontendNode(FrontendNode):
|
||||||
|
|
@ -438,22 +551,31 @@ class LLMFrontendNode(FrontendNode):
|
||||||
"huggingfacehub_api_token": "HuggingFace Hub API Token",
|
"huggingfacehub_api_token": "HuggingFace Hub API Token",
|
||||||
}
|
}
|
||||||
FrontendNode.format_field(field, name)
|
FrontendNode.format_field(field, name)
|
||||||
SHOW_FIELDS = ["repo_id", "task", "model_kwargs"]
|
SHOW_FIELDS = ["repo_id"]
|
||||||
if field.name in SHOW_FIELDS:
|
if field.name in SHOW_FIELDS:
|
||||||
field.show = True
|
field.show = True
|
||||||
|
|
||||||
if "api" in field.name and ("key" in field.name or "token" in field.name):
|
if "api" in field.name and ("key" in field.name or "token" in field.name):
|
||||||
field.password = True
|
field.password = True
|
||||||
field.show = True
|
field.show = True
|
||||||
field.required = True
|
# Required should be False to support
|
||||||
|
# loading the API key from environment variables
|
||||||
|
field.required = False
|
||||||
|
field.advanced = False
|
||||||
|
|
||||||
if field.name == "task":
|
if field.name == "task":
|
||||||
field.required = True
|
field.required = True
|
||||||
field.show = True
|
field.show = True
|
||||||
field.is_list = True
|
field.is_list = True
|
||||||
field.options = ["text-generation", "text2text-generation"]
|
field.options = ["text-generation", "text2text-generation"]
|
||||||
|
field.advanced = True
|
||||||
|
|
||||||
if display_name := display_names_dict.get(field.name):
|
if display_name := display_names_dict.get(field.name):
|
||||||
field.display_name = display_name
|
field.display_name = display_name
|
||||||
if field.name == "model_kwargs":
|
if field.name == "model_kwargs":
|
||||||
field.field_type = "code"
|
field.field_type = "code"
|
||||||
|
field.advanced = True
|
||||||
|
field.show = True
|
||||||
|
elif field.name in ["model_name", "temperature"]:
|
||||||
|
field.advanced = False
|
||||||
|
field.show = True
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { TrashIcon } from "@heroicons/react/24/outline";
|
import { Cog6ToothIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
import { useDebouncedCallback } from "use-debounce";
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
import {
|
import {
|
||||||
classNames,
|
classNames,
|
||||||
|
|
@ -11,6 +11,8 @@ import { typesContext } from "../../contexts/typesContext";
|
||||||
import { useContext, useState, useEffect, useRef } from "react";
|
import { useContext, useState, useEffect, useRef } from "react";
|
||||||
import { NodeDataType } from "../../types/flow";
|
import { NodeDataType } from "../../types/flow";
|
||||||
import { alertContext } from "../../contexts/alertContext";
|
import { alertContext } from "../../contexts/alertContext";
|
||||||
|
import { PopUpContext } from "../../contexts/popUpContext";
|
||||||
|
import NodeModal from "../../modals/NodeModal";
|
||||||
import { useCallback } from "react";
|
import { useCallback } from "react";
|
||||||
import { TabsContext } from "../../contexts/tabsContext";
|
import { TabsContext } from "../../contexts/tabsContext";
|
||||||
export default function GenericNode({
|
export default function GenericNode({
|
||||||
|
|
@ -23,6 +25,7 @@ export default function GenericNode({
|
||||||
const { setErrorData } = useContext(alertContext);
|
const { setErrorData } = useContext(alertContext);
|
||||||
const showError = useRef(true);
|
const showError = useRef(true);
|
||||||
const { types, deleteNode } = useContext(typesContext);
|
const { types, deleteNode } = useContext(typesContext);
|
||||||
|
const { openPopUp } = useContext(PopUpContext);
|
||||||
const Icon = nodeIcons[types[data.type]];
|
const Icon = nodeIcons[types[data.type]];
|
||||||
const [validationStatus, setValidationStatus] = useState("idle");
|
const [validationStatus, setValidationStatus] = useState("idle");
|
||||||
// State for outline color
|
// State for outline color
|
||||||
|
|
@ -101,17 +104,46 @@ export default function GenericNode({
|
||||||
/>
|
/>
|
||||||
<div className="truncate">{data.type}</div>
|
<div className="truncate">{data.type}</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<div className="flex gap-3">
|
||||||
onClick={() => {
|
<button
|
||||||
deleteNode(data.id);
|
className="relative"
|
||||||
}}
|
onClick={(event) => {
|
||||||
>
|
event.preventDefault();
|
||||||
<TrashIcon className="w-6 h-6 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-500"></TrashIcon>
|
openPopUp(<NodeModal data={data} />);
|
||||||
</button>
|
}}
|
||||||
|
>
|
||||||
|
<div className=" absolute text-red-600 -top-2 -right-1">
|
||||||
|
{Object.keys(data.node.template).some(
|
||||||
|
(t) =>
|
||||||
|
data.node.template[t].advanced &&
|
||||||
|
data.node.template[t].required
|
||||||
|
)
|
||||||
|
? " *"
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
<Cog6ToothIcon
|
||||||
|
className={classNames(
|
||||||
|
Object.keys(data.node.template).some(
|
||||||
|
(t) => data.node.template[t].advanced && data.node.template[t].show
|
||||||
|
)
|
||||||
|
? ""
|
||||||
|
: "hidden",
|
||||||
|
"w-6 h-6 dark:text-gray-500 hover:animate-spin"
|
||||||
|
)}
|
||||||
|
></Cog6ToothIcon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
deleteNode(data.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TrashIcon className="w-6 h-6 hover:text-red-500 dark:text-gray-500 dark:hover:text-red-500"></TrashIcon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="w-full h-full py-5">
|
<div className="w-full h-full py-5">
|
||||||
<div className="w-full text-gray-500 px-5 text-sm">
|
<div className="w-full text-gray-500 px-5 pb-3 text-sm">
|
||||||
{data.node.description}
|
{data.node.description}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -120,7 +152,7 @@ export default function GenericNode({
|
||||||
.filter((t) => t.charAt(0) !== "_")
|
.filter((t) => t.charAt(0) !== "_")
|
||||||
.map((t: string, idx) => (
|
.map((t: string, idx) => (
|
||||||
<div key={idx}>
|
<div key={idx}>
|
||||||
{idx === 0 ? (
|
{/* {idx === 0 ? (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"px-5 py-2 mt-2 dark:text-white text-center",
|
"px-5 py-2 mt-2 dark:text-white text-center",
|
||||||
|
|
@ -138,8 +170,8 @@ export default function GenericNode({
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
)}
|
)} */}
|
||||||
{data.node.template[t].show ? (
|
{data.node.template[t].show && !data.node.template[t].advanced ? (
|
||||||
<ParameterComponent
|
<ParameterComponent
|
||||||
data={data}
|
data={data}
|
||||||
color={
|
color={
|
||||||
|
|
@ -169,9 +201,17 @@ export default function GenericNode({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
<div className="px-5 py-2 mt-2 dark:text-white text-center">
|
<div
|
||||||
Output
|
className={classNames(
|
||||||
|
Object.keys(data.node.template).length < 1 ? "hidden" : "",
|
||||||
|
"w-full flex justify-center"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
</div>
|
</div>
|
||||||
|
{/* <div className="px-5 py-2 mt-2 dark:text-white text-center">
|
||||||
|
Output
|
||||||
|
</div> */}
|
||||||
<ParameterComponent
|
<ParameterComponent
|
||||||
data={data}
|
data={data}
|
||||||
color={nodeColors[types[data.type]] ?? nodeColors.unknown}
|
color={nodeColors[types[data.type]] ?? nodeColors.unknown}
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,24 @@ export default function CodeAreaComponent({
|
||||||
}
|
}
|
||||||
}, [disabled, onChange]);
|
}, [disabled, onChange]);
|
||||||
return (
|
return (
|
||||||
<div className={disabled ? "pointer-events-none cursor-not-allowed w-full" : "w-full"}>
|
<div
|
||||||
|
className={
|
||||||
|
disabled ? "pointer-events-none cursor-not-allowed w-full" : "w-full"
|
||||||
|
}
|
||||||
|
>
|
||||||
<div className="w-full flex items-center gap-3">
|
<div className="w-full flex items-center gap-3">
|
||||||
<span
|
<span
|
||||||
|
onClick={() => {
|
||||||
|
openPopUp(
|
||||||
|
<CodeAreaModal
|
||||||
|
value={myValue}
|
||||||
|
setValue={(t: string) => {
|
||||||
|
setMyValue(t);
|
||||||
|
onChange(t);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
className={
|
className={
|
||||||
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
||||||
(disabled ? " bg-gray-200" : "")
|
(disabled ? " bg-gray-200" : "")
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ export default function InputFileComponent({
|
||||||
>
|
>
|
||||||
<div className="w-full flex items-center gap-3">
|
<div className="w-full flex items-center gap-3">
|
||||||
<span
|
<span
|
||||||
|
onClick={handleButtonClick}
|
||||||
className={
|
className={
|
||||||
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
||||||
(disabled ? " bg-gray-200" : "")
|
(disabled ? " bg-gray-200" : "")
|
||||||
|
|
|
||||||
|
|
@ -6,30 +6,61 @@ import TextAreaModal from "../../modals/textAreaModal";
|
||||||
import { TextAreaComponentType } from "../../types/components";
|
import { TextAreaComponentType } from "../../types/components";
|
||||||
import PromptAreaModal from "../../modals/promptModal";
|
import PromptAreaModal from "../../modals/promptModal";
|
||||||
|
|
||||||
export default function PromptAreaComponent({ value, onChange, disabled }:TextAreaComponentType) {
|
export default function PromptAreaComponent({
|
||||||
const [myValue, setMyValue] = useState(value);
|
value,
|
||||||
const { openPopUp } = useContext(PopUpContext);
|
onChange,
|
||||||
useEffect(() => {
|
disabled,
|
||||||
if (disabled) {
|
}: TextAreaComponentType) {
|
||||||
setMyValue("");
|
const [myValue, setMyValue] = useState(value);
|
||||||
onChange("");
|
const { openPopUp } = useContext(PopUpContext);
|
||||||
}
|
useEffect(() => {
|
||||||
}, [disabled, onChange]);
|
if (disabled) {
|
||||||
return (
|
setMyValue("");
|
||||||
<div className={disabled ? "pointer-events-none cursor-not-allowed w-full" : " w-full"}>
|
onChange("");
|
||||||
<div className="w-full flex items-center gap-3">
|
}
|
||||||
<span
|
}, [disabled, onChange]);
|
||||||
className={
|
return (
|
||||||
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
<div
|
||||||
(disabled ? " bg-gray-200" : "")
|
className={
|
||||||
}
|
disabled ? "pointer-events-none cursor-not-allowed w-full" : " w-full"
|
||||||
>
|
}
|
||||||
{myValue !== "" ? myValue : 'Text empty'}
|
>
|
||||||
</span>
|
<div className="w-full flex items-center gap-3">
|
||||||
<button onClick={()=>{openPopUp(<PromptAreaModal value={myValue} setValue={(t:string) => {setMyValue(t); onChange(t);}}/>)}}>
|
<span
|
||||||
<ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-blue-600" />
|
onClick={() => {
|
||||||
</button>
|
openPopUp(
|
||||||
</div>
|
<PromptAreaModal
|
||||||
</div>
|
value={myValue}
|
||||||
);
|
setValue={(t: string) => {
|
||||||
|
setMyValue(t);
|
||||||
|
onChange(t);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
className={
|
||||||
|
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
||||||
|
(disabled ? " bg-gray-200" : "")
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{myValue !== "" ? myValue : "Text empty"}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
openPopUp(
|
||||||
|
<PromptAreaModal
|
||||||
|
value={myValue}
|
||||||
|
setValue={(t: string) => {
|
||||||
|
setMyValue(t);
|
||||||
|
onChange(t);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ArrowTopRightOnSquareIcon className="w-6 h-6 hover:text-blue-600" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline";
|
import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { PopUpContext } from "../../contexts/popUpContext";
|
import { PopUpContext } from "../../contexts/popUpContext";
|
||||||
import CodeAreaModal from "../../modals/codeAreaModal";
|
|
||||||
import TextAreaModal from "../../modals/textAreaModal";
|
import TextAreaModal from "../../modals/textAreaModal";
|
||||||
import { TextAreaComponentType } from "../../types/components";
|
import { TextAreaComponentType } from "../../types/components";
|
||||||
|
|
||||||
|
|
@ -17,7 +16,7 @@ export default function TextAreaComponent({ value, onChange, disabled }:TextArea
|
||||||
return (
|
return (
|
||||||
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
|
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
|
||||||
<div className="w-full flex items-center gap-3">
|
<div className="w-full flex items-center gap-3">
|
||||||
<span
|
<span onClick={()=>{openPopUp(<TextAreaModal value={myValue} setValue={(t:string) => {setMyValue(t); onChange(t);}}/>)}}
|
||||||
className={
|
className={
|
||||||
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
"truncate block w-full text-gray-500 px-3 py-2 rounded-md border border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" +
|
||||||
(disabled ? " bg-gray-200" : "")
|
(disabled ? " bg-gray-200" : "")
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,15 @@ export default function ContextWrapper({ children }: { children: ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DarkProvider>
|
<DarkProvider>
|
||||||
<LocationProvider>
|
<TypesProvider>
|
||||||
<AlertProvider>
|
<LocationProvider>
|
||||||
<TabsProvider>
|
<AlertProvider>
|
||||||
<TypesProvider>
|
<TabsProvider>
|
||||||
<PopUpProvider>{children}</PopUpProvider>
|
<PopUpProvider>{children}</PopUpProvider>
|
||||||
</TypesProvider>
|
</TabsProvider>
|
||||||
</TabsProvider>
|
</AlertProvider>
|
||||||
</AlertProvider>
|
</LocationProvider>
|
||||||
</LocationProvider>
|
</TypesProvider>
|
||||||
</DarkProvider>
|
</DarkProvider>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,33 @@
|
||||||
import { createContext } from "react";
|
import { createContext } from "react";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
//context to set JSX element on the DOM
|
// context to set JSX element on the DOM
|
||||||
export const PopUpContext = createContext({
|
export const PopUpContext = createContext({
|
||||||
openPopUp: (popUpElement: JSX.Element) => {},
|
openPopUp: (popUpElement: JSX.Element) => {},
|
||||||
closePopUp: () => {},
|
closePopUp: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface PopUpProviderProps {
|
interface PopUpProviderProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PopUpProvider = ({ children }: PopUpProviderProps) => {
|
const PopUpProvider = ({ children }: PopUpProviderProps) => {
|
||||||
const [popUpElement, setPopUpElement] = useState<JSX.Element | null>(null);
|
const [popUpElements, setPopUpElements] = useState<JSX.Element[]>([]);
|
||||||
|
|
||||||
const openPopUp = (element: JSX.Element) => {
|
const openPopUp = (element: JSX.Element) => {
|
||||||
setPopUpElement(element);
|
setPopUpElements(prevPopUps => [element, ...prevPopUps]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const closePopUp = () => {
|
const closePopUp = () => {
|
||||||
setPopUpElement(null);
|
setPopUpElements(prevPopUps => prevPopUps.slice(1));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopUpContext.Provider value={{ openPopUp, closePopUp }}>
|
<PopUpContext.Provider value={{ openPopUp, closePopUp }}>
|
||||||
{children}
|
{children}
|
||||||
{popUpElement}
|
{popUpElements[0]}
|
||||||
</PopUpContext.Provider>
|
</PopUpContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PopUpProvider;
|
export default PopUpProvider;
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@ import {
|
||||||
useContext,
|
useContext,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { FlowType } from "../types/flow";
|
import { FlowType } from "../types/flow";
|
||||||
import { TabsContextType } from "../types/tabs";
|
import { LangFlowState, TabsContextType } from "../types/tabs";
|
||||||
import { normalCaseToSnakeCase } from "../utils";
|
import { normalCaseToSnakeCase, updateObject } from "../utils";
|
||||||
import { alertContext } from "./alertContext";
|
import { alertContext } from "./alertContext";
|
||||||
|
import { typesContext } from "./typesContext";
|
||||||
|
import { TemplateVariableType } from "../types/api";
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
const TabsContextInitialValue: TabsContextType = {
|
const TabsContextInitialValue: TabsContextType = {
|
||||||
|
|
@ -35,6 +37,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
const [tabIndex, setTabIndex] = useState(0);
|
const [tabIndex, setTabIndex] = useState(0);
|
||||||
const [flows, setFlows] = useState<Array<FlowType>>([]);
|
const [flows, setFlows] = useState<Array<FlowType>>([]);
|
||||||
const [id, setId] = useState("");
|
const [id, setId] = useState("");
|
||||||
|
const { templates } = useContext(typesContext);
|
||||||
|
|
||||||
const newNodeId = useRef(0);
|
const newNodeId = useRef(0);
|
||||||
function incrementNodeId() {
|
function incrementNodeId() {
|
||||||
|
|
@ -56,19 +59,31 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
//get tabs locally saved
|
//get tabs locally saved
|
||||||
let cookie = window.localStorage.getItem("tabsData");
|
let cookie = window.localStorage.getItem("tabsData");
|
||||||
if (cookie) {
|
if (cookie && Object.keys(templates).length > 0) {
|
||||||
let cookieObject = JSON.parse(cookie);
|
let cookieObject: LangFlowState = JSON.parse(cookie);
|
||||||
|
cookieObject.flows.forEach((flow) => {
|
||||||
|
flow.data.nodes.forEach((node) => {
|
||||||
|
if (Object.keys(templates[node.data.type]["template"]).length>0) {
|
||||||
|
node.data.node.template = updateObject(
|
||||||
|
node.data.node.template as TemplateVariableType,
|
||||||
|
templates[node.data.type][
|
||||||
|
"template"
|
||||||
|
] as unknown as TemplateVariableType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
setTabIndex(cookieObject.tabIndex);
|
setTabIndex(cookieObject.tabIndex);
|
||||||
setFlows(cookieObject.flows);
|
setFlows(cookieObject.flows);
|
||||||
setId(cookieObject.id);
|
setId(cookieObject.id);
|
||||||
newNodeId.current = cookieObject.nodeId;
|
newNodeId.current = cookieObject.nodeId;
|
||||||
}
|
}
|
||||||
}, []);
|
}, [templates]);
|
||||||
function hardReset() {
|
function hardReset() {
|
||||||
newNodeId.current = 0;
|
newNodeId.current = 0;
|
||||||
setTabIndex(0);
|
setTabIndex(0);
|
||||||
setFlows([]);
|
setFlows([]);
|
||||||
setId(uuidv4());
|
setId("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -110,7 +125,19 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
// read the file as text
|
// read the file as text
|
||||||
file.text().then((text) => {
|
file.text().then((text) => {
|
||||||
// parse the text into a JSON object
|
// parse the text into a JSON object
|
||||||
addFlow(JSON.parse(text));
|
let flow: FlowType = JSON.parse(text);
|
||||||
|
flow.data.nodes.forEach((node) => {
|
||||||
|
if (Object.keys(templates[node.data.type]["template"]).length>0) {
|
||||||
|
node.data.node.template = updateObject(
|
||||||
|
node.data.node.template as TemplateVariableType,
|
||||||
|
templates[node.data.type][
|
||||||
|
"template"
|
||||||
|
] as unknown as TemplateVariableType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addFlow();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import { createContext, ReactNode, useState } from "react";
|
import { createContext, ReactNode, useEffect, useState } from "react";
|
||||||
import { Node} from "reactflow";
|
import { Node} from "reactflow";
|
||||||
import { typesContextType } from "../types/typesContext";
|
import { typesContextType } from "../types/typesContext";
|
||||||
|
import { getAll } from "../controllers/API";
|
||||||
|
import { APIKindType } from "../types/api";
|
||||||
|
|
||||||
//context to share types adn functions from nodes to flow
|
//context to share types adn functions from nodes to flow
|
||||||
|
|
||||||
|
|
@ -10,6 +12,10 @@ const initialValue:typesContextType = {
|
||||||
deleteNode: () => {},
|
deleteNode: () => {},
|
||||||
types: {},
|
types: {},
|
||||||
setTypes: () => {},
|
setTypes: () => {},
|
||||||
|
templates: {},
|
||||||
|
setTemplates: () => {},
|
||||||
|
data:{},
|
||||||
|
setData:()=>{}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const typesContext = createContext<typesContextType>(initialValue);
|
export const typesContext = createContext<typesContextType>(initialValue);
|
||||||
|
|
@ -17,6 +23,42 @@ export const typesContext = createContext<typesContextType>(initialValue);
|
||||||
export function TypesProvider({ children }:{children:ReactNode}) {
|
export function TypesProvider({ children }:{children:ReactNode}) {
|
||||||
const [types, setTypes] = useState({});
|
const [types, setTypes] = useState({});
|
||||||
const [reactFlowInstance, setReactFlowInstance] = useState(null);
|
const [reactFlowInstance, setReactFlowInstance] = useState(null);
|
||||||
|
const [templates, setTemplates] = useState({});
|
||||||
|
const [data, setData] = useState({});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function getTypes(): Promise<void> {
|
||||||
|
// Make an asynchronous API call to retrieve all data.
|
||||||
|
let result = await getAll();
|
||||||
|
|
||||||
|
// Update the state of the component with the retrieved data.
|
||||||
|
setData(result.data);
|
||||||
|
setTemplates(
|
||||||
|
Object.keys(result.data).reduce((acc, curr) => {
|
||||||
|
Object.keys(result.data[curr]).forEach((c: keyof APIKindType)=>{
|
||||||
|
acc[c] = result.data[curr][c]
|
||||||
|
})
|
||||||
|
return acc;
|
||||||
|
},{})
|
||||||
|
);
|
||||||
|
// Set the types by reducing over the keys of the result data and updating the accumulator.
|
||||||
|
setTypes(
|
||||||
|
Object.keys(result.data).reduce((acc, curr) => {
|
||||||
|
Object.keys(result.data[curr]).forEach((c: keyof APIKindType) => {
|
||||||
|
acc[c] = curr;
|
||||||
|
// Add the base classes to the accumulator as well.
|
||||||
|
result.data[curr][c].base_classes?.forEach((b) => {
|
||||||
|
acc[b] = curr;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Call the getTypes function.
|
||||||
|
getTypes();
|
||||||
|
}, [setTypes]);
|
||||||
|
|
||||||
function deleteNode(idx:string) {
|
function deleteNode(idx:string) {
|
||||||
reactFlowInstance.setNodes(
|
reactFlowInstance.setNodes(
|
||||||
reactFlowInstance.getNodes().filter((n:Node) => n.id !== idx)
|
reactFlowInstance.getNodes().filter((n:Node) => n.id !== idx)
|
||||||
|
|
@ -31,6 +73,10 @@ export function TypesProvider({ children }:{children:ReactNode}) {
|
||||||
reactFlowInstance,
|
reactFlowInstance,
|
||||||
setReactFlowInstance,
|
setReactFlowInstance,
|
||||||
deleteNode,
|
deleteNode,
|
||||||
|
setTemplates,
|
||||||
|
templates,
|
||||||
|
data,
|
||||||
|
setData
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,166 @@
|
||||||
|
import { useContext, useState } from "react";
|
||||||
|
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||||
|
import InputListComponent from "../../../../components/inputListComponent";
|
||||||
|
import Dropdown from "../../../../components/dropdownComponent";
|
||||||
|
import TextAreaComponent from "../../../../components/textAreaComponent";
|
||||||
|
import InputComponent from "../../../../components/inputComponent";
|
||||||
|
import ToggleComponent from "../../../../components/toggleComponent";
|
||||||
|
import FloatComponent from "../../../../components/floatComponent";
|
||||||
|
import IntComponent from "../../../../components/intComponent";
|
||||||
|
import InputFileComponent from "../../../../components/inputFileComponent";
|
||||||
|
import PromptAreaComponent from "../../../../components/promptComponent";
|
||||||
|
import CodeAreaComponent from "../../../../components/codeAreaComponent";
|
||||||
|
import { classNames } from "../../../../utils";
|
||||||
|
|
||||||
|
export default function ModalField({ data, title, required, id, name, type }) {
|
||||||
|
const { save } = useContext(TabsContext);
|
||||||
|
const [enabled, setEnabled] = useState(
|
||||||
|
data.node.template[name]?.value ?? false
|
||||||
|
);
|
||||||
|
const display =
|
||||||
|
type === "str" ||
|
||||||
|
type === "int" ||
|
||||||
|
type === "prompt" ||
|
||||||
|
type === "bool" ||
|
||||||
|
type === "float" ||
|
||||||
|
type === "file" ||
|
||||||
|
type === "code";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
"flex flex-row w-full items-center justify-between",
|
||||||
|
display ? "" : "hidden"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{display && (
|
||||||
|
<div>
|
||||||
|
<span className="mx-2">{title}</span>
|
||||||
|
<span className="text-red-600">{required ? " *" : ""}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{type === "str" && !data.node.template[name].options ? (
|
||||||
|
<div className="w-1/2">
|
||||||
|
{data.node.template[name].list ? (
|
||||||
|
<InputListComponent
|
||||||
|
disabled={false}
|
||||||
|
value={
|
||||||
|
!data.node.template[name].value ||
|
||||||
|
data.node.template[name].value === ""
|
||||||
|
? [""]
|
||||||
|
: data.node.template[name].value
|
||||||
|
}
|
||||||
|
onChange={(t: string[]) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : data.node.template[name].multiline ? (
|
||||||
|
<TextAreaComponent
|
||||||
|
disabled={false}
|
||||||
|
value={data.node.template[name].value ?? ""}
|
||||||
|
onChange={(t: string) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<InputComponent
|
||||||
|
disabled={false}
|
||||||
|
password={data.node.template[name].password ?? false}
|
||||||
|
value={data.node.template[name].value ?? ""}
|
||||||
|
onChange={(t) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : type === "bool" ? (
|
||||||
|
<div className="ml-auto">
|
||||||
|
{" "}
|
||||||
|
<ToggleComponent
|
||||||
|
disabled={false}
|
||||||
|
enabled={enabled}
|
||||||
|
setEnabled={(t) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
setEnabled(t);
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : type === "float" ? (
|
||||||
|
<div className="w-1/2">
|
||||||
|
<FloatComponent
|
||||||
|
disabled={false}
|
||||||
|
value={data.node.template[name].value ?? ""}
|
||||||
|
onChange={(t) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : type === "str" && data.node.template[name].options ? (
|
||||||
|
<div className="w-1/2">
|
||||||
|
<Dropdown
|
||||||
|
options={data.node.template[name].options}
|
||||||
|
onSelect={(newValue) => (data.node.template[name].value = newValue)}
|
||||||
|
value={data.node.template[name].value ?? "Choose an option"}
|
||||||
|
></Dropdown>
|
||||||
|
</div>
|
||||||
|
) : type === "int" ? (
|
||||||
|
<div className="w-1/2">
|
||||||
|
<IntComponent
|
||||||
|
disabled={false}
|
||||||
|
value={data.node.template[name].value ?? ""}
|
||||||
|
onChange={(t) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : type === "file" ? (
|
||||||
|
<div className="w-1/2">
|
||||||
|
<InputFileComponent
|
||||||
|
disabled={false}
|
||||||
|
value={data.node.template[name].value ?? ""}
|
||||||
|
onChange={(t: string) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
}}
|
||||||
|
fileTypes={data.node.template[name].fileTypes}
|
||||||
|
suffixes={data.node.template[name].suffixes}
|
||||||
|
onFileChange={(t: string) => {
|
||||||
|
data.node.template[name].content = t;
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
></InputFileComponent>
|
||||||
|
</div>
|
||||||
|
) : type === "prompt" ? (
|
||||||
|
<div className="w-1/2">
|
||||||
|
<PromptAreaComponent
|
||||||
|
disabled={false}
|
||||||
|
value={data.node.template[name].value ?? ""}
|
||||||
|
onChange={(t: string) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : type === "code" ? (
|
||||||
|
<div className="w-1/2">
|
||||||
|
<CodeAreaComponent
|
||||||
|
disabled={false}
|
||||||
|
value={data.node.template[name].value ?? ""}
|
||||||
|
onChange={(t: string) => {
|
||||||
|
data.node.template[name].value = t;
|
||||||
|
save();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="hidden"></div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
144
src/frontend/src/modals/NodeModal/index.tsx
Normal file
144
src/frontend/src/modals/NodeModal/index.tsx
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
|
import { XMarkIcon } from "@heroicons/react/24/outline";
|
||||||
|
import { Fragment, useContext, useRef, useState } from "react";
|
||||||
|
import { PopUpContext } from "../../contexts/popUpContext";
|
||||||
|
import { NodeDataType } from "../../types/flow";
|
||||||
|
import { nodeColors, nodeIcons, snakeToNormalCase } from "../../utils";
|
||||||
|
import { typesContext } from "../../contexts/typesContext";
|
||||||
|
import ModalField from "./components/ModalField";
|
||||||
|
|
||||||
|
export default function NodeModal({ data }: { data: NodeDataType }) {
|
||||||
|
const [open, setOpen] = useState(true);
|
||||||
|
const { closePopUp } = useContext(PopUpContext);
|
||||||
|
const { types } = useContext(typesContext);
|
||||||
|
const ref = useRef();
|
||||||
|
function setModalOpen(x: boolean) {
|
||||||
|
setOpen(x);
|
||||||
|
if (x === false) {
|
||||||
|
setTimeout(() => {
|
||||||
|
closePopUp();
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const Icon = nodeIcons[types[data.type]];
|
||||||
|
return (
|
||||||
|
<Transition.Root show={open} appear={true} as={Fragment}>
|
||||||
|
<Dialog
|
||||||
|
as="div"
|
||||||
|
className="relative z-10"
|
||||||
|
onClose={setModalOpen}
|
||||||
|
initialFocus={ref}
|
||||||
|
>
|
||||||
|
<Transition.Child
|
||||||
|
as={Fragment}
|
||||||
|
enter="ease-out duration-300"
|
||||||
|
enterFrom="opacity-0"
|
||||||
|
enterTo="opacity-100"
|
||||||
|
leave="ease-in duration-200"
|
||||||
|
leaveFrom="opacity-100"
|
||||||
|
leaveTo="opacity-0"
|
||||||
|
>
|
||||||
|
<div className="fixed inset-0 bg-gray-500 dark:bg-gray-600 dark:bg-opacity-75 bg-opacity-75 transition-opacity" />
|
||||||
|
</Transition.Child>
|
||||||
|
|
||||||
|
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||||
|
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||||
|
<Transition.Child
|
||||||
|
as={Fragment}
|
||||||
|
enter="ease-out duration-300"
|
||||||
|
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||||
|
leave="ease-in duration-200"
|
||||||
|
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||||
|
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
>
|
||||||
|
<Dialog.Panel className="relative flex flex-col justify-between transform h-[600px] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[700px]">
|
||||||
|
<div className=" z-50 absolute top-0 right-0 hidden pt-4 pr-4 sm:block">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||||
|
onClick={() => {
|
||||||
|
setModalOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
<XMarkIcon className="h-6 w-6" aria-hidden="true" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="h-full w-full flex flex-col justify-center items-center">
|
||||||
|
<div className="flex w-full pb-4 z-10 justify-center shadow-sm">
|
||||||
|
<Icon
|
||||||
|
className="w-10 mt-4 h-10 p-1 rounded"
|
||||||
|
style={{
|
||||||
|
color:
|
||||||
|
nodeColors[types[data.type]] ?? nodeColors.unknown,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="mt-4 text-center sm:ml-4 sm:text-left">
|
||||||
|
<Dialog.Title
|
||||||
|
as="h3"
|
||||||
|
className="text-lg font-medium dark:text-white leading-10 text-gray-900"
|
||||||
|
>
|
||||||
|
{data.type}
|
||||||
|
</Dialog.Title>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="h-full w-full bg-gray-200 dark:bg-gray-900 p-4 gap-4 flex flex-row justify-center items-center">
|
||||||
|
<div className="flex h-full w-full">
|
||||||
|
<div className="overflow-hidden px-4 sm:p-4 w-full rounded-lg bg-white dark:bg-gray-800 shadow">
|
||||||
|
<div className="flex flex-col h-full gap-5">
|
||||||
|
{
|
||||||
|
Object.keys(data.node.template)
|
||||||
|
.filter((t) => t.charAt(0) !== "_"&& data.node.template[t].advanced && data.node.template[t].show)
|
||||||
|
.map((t: string, idx) => {
|
||||||
|
return (
|
||||||
|
<ModalField
|
||||||
|
key={idx}
|
||||||
|
data={data}
|
||||||
|
title={
|
||||||
|
data.node.template[t].display_name
|
||||||
|
? data.node.template[t].display_name
|
||||||
|
: data.node.template[t].name
|
||||||
|
? snakeToNormalCase(
|
||||||
|
data.node.template[t].name
|
||||||
|
)
|
||||||
|
: snakeToNormalCase(t)
|
||||||
|
}
|
||||||
|
required={data.node.template[t].required}
|
||||||
|
id={
|
||||||
|
data.node.template[t].type +
|
||||||
|
"|" +
|
||||||
|
t +
|
||||||
|
"|" +
|
||||||
|
data.id
|
||||||
|
}
|
||||||
|
name={t}
|
||||||
|
type={data.node.template[t].type}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="bg-gray-200 dark:bg-gray-900 w-full pb-3 flex flex-row-reverse px-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="inline-flex w-full justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:ml-3 sm:w-auto sm:text-sm"
|
||||||
|
onClick={() => {
|
||||||
|
setModalOpen(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Done
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog.Panel>
|
||||||
|
</Transition.Child>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</Transition.Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { Dialog, Transition } from "@headlessui/react";
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
import {
|
import {
|
||||||
XMarkIcon,
|
XMarkIcon,
|
||||||
ArrowDownTrayIcon,
|
ArrowDownTrayIcon,
|
||||||
DocumentDuplicateIcon,
|
DocumentDuplicateIcon,
|
||||||
ComputerDesktopIcon,
|
ComputerDesktopIcon,
|
||||||
ArrowUpTrayIcon,
|
ArrowUpTrayIcon,
|
||||||
ArrowLeftIcon,
|
ArrowLeftIcon,
|
||||||
} from "@heroicons/react/24/outline";
|
} from "@heroicons/react/24/outline";
|
||||||
import { Fragment, useContext, useRef, useState } from "react";
|
import { Fragment, useContext, useRef, useState } from "react";
|
||||||
import { PopUpContext } from "../../contexts/popUpContext";
|
import { PopUpContext } from "../../contexts/popUpContext";
|
||||||
|
|
@ -19,211 +19,214 @@ import { FlowType } from "../../types/flow";
|
||||||
import { classNames } from "../../utils";
|
import { classNames } from "../../utils";
|
||||||
|
|
||||||
export default function ImportModal() {
|
export default function ImportModal() {
|
||||||
const [open, setOpen] = useState(true);
|
const [open, setOpen] = useState(true);
|
||||||
const { setErrorData } = useContext(alertContext);
|
const { setErrorData } = useContext(alertContext);
|
||||||
const { closePopUp } = useContext(PopUpContext);
|
const { closePopUp } = useContext(PopUpContext);
|
||||||
const ref = useRef();
|
const ref = useRef();
|
||||||
const [showExamples, setShowExamples] = useState(false);
|
const [showExamples, setShowExamples] = useState(false);
|
||||||
const [loadingExamples, setLoadingExamples] = useState(false);
|
const [loadingExamples, setLoadingExamples] = useState(false);
|
||||||
const [examples, setExamples] = useState<FlowType[]>([]);
|
const [examples, setExamples] = useState<FlowType[]>([]);
|
||||||
const { uploadFlow, addFlow } = useContext(TabsContext);
|
const { uploadFlow, addFlow } = useContext(TabsContext);
|
||||||
function setModalOpen(x: boolean) {
|
function setModalOpen(x: boolean) {
|
||||||
setOpen(x);
|
setOpen(x);
|
||||||
if (x === false) {
|
if (x === false) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
closePopUp();
|
closePopUp();
|
||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleExamples() {
|
function handleExamples() {
|
||||||
setLoadingExamples(true);
|
setLoadingExamples(true);
|
||||||
getExamples()
|
getExamples()
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
setLoadingExamples(false);
|
setLoadingExamples(false);
|
||||||
setExamples(result);
|
setExamples(result);
|
||||||
})
|
})
|
||||||
.catch((error) =>
|
.catch((error) =>
|
||||||
setErrorData({
|
setErrorData({
|
||||||
title: "there was an error loading examples, please try again",
|
title: "there was an error loading examples, please try again",
|
||||||
list: [error.message],
|
list: [error.message],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Transition.Root show={open} appear={true} as={Fragment}>
|
<Transition.Root show={open} appear={true} as={Fragment}>
|
||||||
<Dialog
|
<Dialog
|
||||||
as="div"
|
as="div"
|
||||||
className="relative z-10"
|
className="relative z-10"
|
||||||
onClose={setModalOpen}
|
onClose={setModalOpen}
|
||||||
initialFocus={ref}
|
initialFocus={ref}
|
||||||
>
|
>
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={Fragment}
|
as={Fragment}
|
||||||
enter="ease-out duration-300"
|
enter="ease-out duration-300"
|
||||||
enterFrom="opacity-0"
|
enterFrom="opacity-0"
|
||||||
enterTo="opacity-100"
|
enterTo="opacity-100"
|
||||||
leave="ease-in duration-200"
|
leave="ease-in duration-200"
|
||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 bg-gray-500 dark:bg-gray-600 dark:bg-opacity-75 bg-opacity-75 transition-opacity" />
|
<div className="fixed inset-0 bg-gray-500 dark:bg-gray-600 dark:bg-opacity-75 bg-opacity-75 transition-opacity" />
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
|
||||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||||
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={Fragment}
|
as={Fragment}
|
||||||
enter="ease-out duration-300"
|
enter="ease-out duration-300"
|
||||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||||
leave="ease-in duration-200"
|
leave="ease-in duration-200"
|
||||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
>
|
>
|
||||||
<Dialog.Panel className="relative flex flex-col justify-between transform h-[600px] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[700px]">
|
<Dialog.Panel className="relative flex flex-col justify-between transform h-[600px] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[700px]">
|
||||||
<div className=" z-50 absolute top-0 right-0 hidden pt-4 pr-4 sm:block">
|
<div className=" z-50 absolute top-0 right-0 hidden pt-4 pr-4 sm:block">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setModalOpen(false);
|
setModalOpen(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="sr-only">Close</span>
|
<span className="sr-only">Close</span>
|
||||||
<XMarkIcon className="h-6 w-6" aria-hidden="true" />
|
<XMarkIcon className="h-6 w-6" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{showExamples && (
|
{showExamples && (
|
||||||
<>
|
<>
|
||||||
<div className="z-50 absolute top-2 left-0 hidden pt-4 pl-4 sm:block">
|
<div className="z-50 absolute top-2 left-0 hidden pt-4 pl-4 sm:block">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
className="rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowExamples(false);
|
setShowExamples(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="sr-only">Close</span>
|
<span className="sr-only">Close</span>
|
||||||
<ArrowLeftIcon className="h-6 w-6" aria-hidden="true" />
|
<ArrowLeftIcon className="h-6 w-6" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="z-50 absolute bottom-2 left-0 hidden pt-4 pl-2 sm:block">
|
<div className="z-50 absolute bottom-2 left-1/2 transform -translate-x-1/2 hidden pt-4 pl-2 sm:block text-center">
|
||||||
<a
|
<a
|
||||||
href="https://github.com/logspace-ai/langflow_examples"
|
href="https://github.com/logspace-ai/langflow_examples"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
className="flex items-center justify-center"
|
||||||
<svg
|
rel="noreferrer"
|
||||||
width="24"
|
>
|
||||||
viewBox="0 0 98 96"
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
width="24"
|
||||||
>
|
viewBox="0 0 98 96"
|
||||||
<path
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill-rule="evenodd"
|
>
|
||||||
clip-rule="evenodd"
|
<path
|
||||||
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
|
fill-rule="evenodd"
|
||||||
fill="#24292f"
|
clip-rule="evenodd"
|
||||||
/>
|
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
|
||||||
</svg>
|
fill="#24292f"
|
||||||
</a>
|
/>
|
||||||
</div>
|
</svg>
|
||||||
</>
|
<span className="ml-2">LangFlow Examples</span>
|
||||||
)}
|
</a>
|
||||||
<div className="h-full w-full flex flex-col justify-center items-center">
|
</div>
|
||||||
<div className="flex w-full pb-4 z-10 justify-center shadow-sm">
|
</>
|
||||||
<div className="mx-auto mt-4 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 dark:bg-gray-900 sm:mx-0 sm:h-10 sm:w-10">
|
)}
|
||||||
<ArrowUpTrayIcon
|
<div className="h-full w-full flex flex-col justify-center items-center">
|
||||||
className="h-6 w-6 text-blue-600"
|
<div className="flex w-full pb-4 z-10 justify-center shadow-sm">
|
||||||
aria-hidden="true"
|
<div className="mx-auto mt-4 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-blue-100 dark:bg-gray-900 sm:mx-0 sm:h-10 sm:w-10">
|
||||||
/>
|
<ArrowUpTrayIcon
|
||||||
</div>
|
className="h-6 w-6 text-blue-600"
|
||||||
<div className="mt-4 text-center sm:ml-4 sm:text-left">
|
aria-hidden="true"
|
||||||
<Dialog.Title
|
/>
|
||||||
as="h3"
|
</div>
|
||||||
className="text-lg font-medium dark:text-white leading-10 text-gray-900"
|
<div className="mt-4 text-center sm:ml-4 sm:text-left">
|
||||||
>
|
<Dialog.Title
|
||||||
{showExamples ?"Select an example":"Import from"}
|
as="h3"
|
||||||
</Dialog.Title>
|
className="text-lg font-medium dark:text-white leading-10 text-gray-900"
|
||||||
</div>
|
>
|
||||||
</div>
|
{showExamples ? "Select an example" : "Import from"}
|
||||||
<div
|
</Dialog.Title>
|
||||||
className={classNames(
|
</div>
|
||||||
"h-full w-full bg-gray-200 dark:bg-gray-900 gap-4",
|
</div>
|
||||||
showExamples && !loadingExamples
|
<div
|
||||||
? "flex flex-row start justify-start items-start p-9 flex-wrap overflow-auto"
|
className={classNames(
|
||||||
: "flex flex-row justify-center items-center p-4"
|
"h-full w-full bg-gray-200 dark:bg-gray-900 gap-4",
|
||||||
)}
|
showExamples && !loadingExamples
|
||||||
>
|
? "flex flex-row start justify-start items-start p-9 flex-wrap overflow-auto"
|
||||||
{!showExamples && (
|
: "flex flex-row justify-center items-center p-4"
|
||||||
<div className="flex h-full w-full justify-evenly items-center">
|
)}
|
||||||
<ButtonBox
|
>
|
||||||
size="big"
|
{!showExamples && (
|
||||||
bgColor="bg-emerald-500"
|
<div className="flex h-full w-full justify-evenly items-center">
|
||||||
description="Prebuilt Examples"
|
<ButtonBox
|
||||||
icon={
|
size="big"
|
||||||
<DocumentDuplicateIcon className="h-10 w-10 flex-shrink-0" />
|
bgColor="bg-emerald-500"
|
||||||
}
|
description="Prebuilt Examples"
|
||||||
onClick={() => {
|
icon={
|
||||||
setShowExamples(true);
|
<DocumentDuplicateIcon className="h-10 w-10 flex-shrink-0" />
|
||||||
handleExamples();
|
}
|
||||||
}}
|
onClick={() => {
|
||||||
textColor="text-emerald-400"
|
setShowExamples(true);
|
||||||
title="Examples"
|
handleExamples();
|
||||||
></ButtonBox>
|
}}
|
||||||
<ButtonBox
|
textColor="text-emerald-400"
|
||||||
size="big"
|
title="Examples"
|
||||||
bgColor="bg-blue-500"
|
></ButtonBox>
|
||||||
description="Import from Local"
|
<ButtonBox
|
||||||
icon={
|
size="big"
|
||||||
<ComputerDesktopIcon className="h-10 w-10 flex-shrink-0" />
|
bgColor="bg-blue-500"
|
||||||
}
|
description="Import from Local"
|
||||||
onClick={() => {
|
icon={
|
||||||
uploadFlow();
|
<ComputerDesktopIcon className="h-10 w-10 flex-shrink-0" />
|
||||||
setModalOpen(false);
|
}
|
||||||
}}
|
onClick={() => {
|
||||||
textColor="text-blue-500"
|
uploadFlow();
|
||||||
title="Local file"
|
setModalOpen(false);
|
||||||
></ButtonBox>
|
}}
|
||||||
</div>
|
textColor="text-blue-500"
|
||||||
)}
|
title="Local file"
|
||||||
{showExamples && loadingExamples && (
|
></ButtonBox>
|
||||||
<div className="flex align-middle justify-center items-center">
|
</div>
|
||||||
<LoadingComponent remSize={30} />
|
)}
|
||||||
</div>
|
{showExamples && loadingExamples && (
|
||||||
)}
|
<div className="flex align-middle justify-center items-center">
|
||||||
{showExamples &&
|
<LoadingComponent remSize={30} />
|
||||||
!loadingExamples &&
|
</div>
|
||||||
examples.map((example, index) => {
|
)}
|
||||||
return (
|
{showExamples &&
|
||||||
<div id="index">
|
!loadingExamples &&
|
||||||
{" "}
|
examples.map((example, index) => {
|
||||||
<ButtonBox
|
return (
|
||||||
size="small"
|
<div id="index">
|
||||||
bgColor="bg-emerald-500"
|
{" "}
|
||||||
description={
|
<ButtonBox
|
||||||
example.description ?? "Prebuilt Examples"
|
size="small"
|
||||||
}
|
bgColor="bg-emerald-500"
|
||||||
icon={
|
description={
|
||||||
<DocumentDuplicateIcon className="h-6 w-6 flex-shrink-0" />
|
example.description ?? "Prebuilt Examples"
|
||||||
}
|
}
|
||||||
onClick={() => {
|
icon={
|
||||||
addFlow(example);
|
<DocumentDuplicateIcon className="h-6 w-6 flex-shrink-0" />
|
||||||
setModalOpen(false);
|
}
|
||||||
}}
|
onClick={() => {
|
||||||
textColor="text-emerald-400"
|
addFlow(example);
|
||||||
title={example.name}
|
setModalOpen(false);
|
||||||
></ButtonBox>
|
}}
|
||||||
</div>
|
textColor="text-emerald-400"
|
||||||
);
|
title={example.name}
|
||||||
})}
|
></ButtonBox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
</Dialog.Panel>
|
})}
|
||||||
</Transition.Child>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Dialog.Panel>
|
||||||
</Dialog>
|
</Transition.Child>
|
||||||
</Transition.Root>
|
</div>
|
||||||
);
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</Transition.Root>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,43 +2,14 @@ import { Bars2Icon } from "@heroicons/react/24/outline";
|
||||||
import DisclosureComponent from "../DisclosureComponent";
|
import DisclosureComponent from "../DisclosureComponent";
|
||||||
import { nodeColors, nodeIcons, nodeNames } from "../../../../utils";
|
import { nodeColors, nodeIcons, nodeNames } from "../../../../utils";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { getAll } from "../../../../controllers/API";
|
|
||||||
import { typesContext } from "../../../../contexts/typesContext";
|
import { typesContext } from "../../../../contexts/typesContext";
|
||||||
import {
|
import {
|
||||||
APIClassType,
|
APIClassType,
|
||||||
APIKindType,
|
|
||||||
APIObjectType,
|
APIObjectType,
|
||||||
} from "../../../../types/api";
|
} from "../../../../types/api";
|
||||||
|
|
||||||
export default function ExtraSidebar() {
|
export default function ExtraSidebar() {
|
||||||
const [data, setData] = useState({});
|
const {data} = useContext(typesContext)
|
||||||
const { setTypes } = useContext(typesContext);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function getTypes(): Promise<void> {
|
|
||||||
// Make an asynchronous API call to retrieve all data.
|
|
||||||
let result = await getAll();
|
|
||||||
|
|
||||||
// Update the state of the component with the retrieved data.
|
|
||||||
setData(result.data);
|
|
||||||
|
|
||||||
// Set the types by reducing over the keys of the result data and updating the accumulator.
|
|
||||||
setTypes(
|
|
||||||
Object.keys(result.data).reduce((acc, curr) => {
|
|
||||||
Object.keys(result.data[curr]).forEach((c: keyof APIKindType) => {
|
|
||||||
acc[c] = curr;
|
|
||||||
// Add the base classes to the accumulator as well.
|
|
||||||
result.data[curr][c].base_classes?.forEach((b) => {
|
|
||||||
acc[b] = curr;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return acc;
|
|
||||||
}, {})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Call the getTypes function.
|
|
||||||
getTypes();
|
|
||||||
}, [setTypes]);
|
|
||||||
|
|
||||||
function onDragStart(
|
function onDragStart(
|
||||||
event: React.DragEvent<any>,
|
event: React.DragEvent<any>,
|
||||||
|
|
@ -84,7 +55,9 @@ export default function ExtraSidebar() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{Object.keys(data[d]).length===0 && <div className="text-gray-400 text-center">Coming soon</div>}
|
{Object.keys(data[d]).length === 0 && (
|
||||||
|
<div className="text-gray-400 text-center">Coming soon</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</DisclosureComponent>
|
</DisclosureComponent>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -16,21 +16,23 @@ import AlertDropdown from "../../../../alerts/alertDropDown";
|
||||||
import { alertContext } from "../../../../contexts/alertContext";
|
import { alertContext } from "../../../../contexts/alertContext";
|
||||||
import ImportModal from "../../../../modals/importModal";
|
import ImportModal from "../../../../modals/importModal";
|
||||||
import ExportModal from "../../../../modals/exportModal";
|
import ExportModal from "../../../../modals/exportModal";
|
||||||
|
import { typesContext } from "../../../../contexts/typesContext";
|
||||||
|
|
||||||
export default function TabsManagerComponent() {
|
export default function TabsManagerComponent() {
|
||||||
const { flows, addFlow, tabIndex, setTabIndex, uploadFlow, downloadFlow } =
|
const { flows, addFlow, tabIndex, setTabIndex, uploadFlow, downloadFlow } =
|
||||||
useContext(TabsContext);
|
useContext(TabsContext);
|
||||||
const { openPopUp } = useContext(PopUpContext);
|
const { openPopUp } = useContext(PopUpContext);
|
||||||
const AlertWidth = 256;
|
const {templates} = useContext(typesContext)
|
||||||
const { dark, setDark } = useContext(darkContext);
|
const AlertWidth = 256;
|
||||||
const { notificationCenter, setNotificationCenter } =
|
const { dark, setDark } = useContext(darkContext);
|
||||||
useContext(alertContext);
|
const { notificationCenter, setNotificationCenter } =
|
||||||
useEffect(() => {
|
useContext(alertContext);
|
||||||
//create the first flow
|
useEffect(() => {
|
||||||
if (flows.length === 0) {
|
//create the first flow
|
||||||
addFlow();
|
if (flows.length === 0&& Object.keys(templates).length>0) {
|
||||||
}
|
addFlow();
|
||||||
}, [addFlow, flows.length]);
|
}
|
||||||
|
}, [addFlow, flows.length,templates]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full w-full flex flex-col">
|
<div className="h-full w-full flex flex-col">
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,12 @@ const nodeTypes = {
|
||||||
|
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
|
|
||||||
export default function FlowPage({ flow }: { flow: FlowType }) {
|
export default function FlowPage({ flow }:{flow:FlowType}) {
|
||||||
let { updateFlow, incrementNodeId } = useContext(TabsContext);
|
let { updateFlow, incrementNodeId} =
|
||||||
const { types, reactFlowInstance, setReactFlowInstance } =
|
useContext(TabsContext);
|
||||||
useContext(typesContext);
|
const { types, reactFlowInstance, setReactFlowInstance, templates } =
|
||||||
const reactFlowWrapper = useRef(null);
|
useContext(typesContext);
|
||||||
|
const reactFlowWrapper = useRef(null);
|
||||||
|
|
||||||
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
|
||||||
const { setErrorData } = useContext(alertContext);
|
const { setErrorData } = useContext(alertContext);
|
||||||
|
|
@ -176,46 +177,47 @@ export default function FlowPage({ flow }: { flow: FlowType }) {
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onEdgeUpdateEnd = useCallback((_, edge) => {
|
const onEdgeUpdateEnd = useCallback((_, edge) => {
|
||||||
if (!edgeUpdateSuccessful.current) {
|
if (!edgeUpdateSuccessful.current) {
|
||||||
setEdges((eds) => eds.filter((e) => e.id !== edge.id));
|
setEdges((eds) => eds.filter((e) => e.id !== edge.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
edgeUpdateSuccessful.current = true;
|
edgeUpdateSuccessful.current = true;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full" ref={reactFlowWrapper}>
|
<div className="w-full h-full" ref={reactFlowWrapper}>
|
||||||
{Object.keys(types).length > 0 ? (
|
{Object.keys(templates).length > 0 && Object.keys(types).length > 0 ? (
|
||||||
<>
|
<>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
nodes={nodes}
|
nodes={nodes}
|
||||||
onMove={() =>
|
onMove={() =>
|
||||||
updateFlow({ ...flow, data: reactFlowInstance.toObject() })
|
updateFlow({ ...flow, data: reactFlowInstance.toObject() })
|
||||||
}
|
}
|
||||||
edges={edges}
|
edges={edges}
|
||||||
onNodesChange={onNodesChange}
|
onNodesChange={onNodesChange}
|
||||||
onEdgesChange={onEdgesChangeMod}
|
onEdgesChange={onEdgesChangeMod}
|
||||||
onConnect={onConnect}
|
onConnect={onConnect}
|
||||||
onLoad={setReactFlowInstance}
|
onLoad={setReactFlowInstance}
|
||||||
onInit={setReactFlowInstance}
|
onInit={setReactFlowInstance}
|
||||||
nodeTypes={nodeTypes}
|
nodeTypes={nodeTypes}
|
||||||
onEdgeUpdate={onEdgeUpdate}
|
onEdgeUpdate={onEdgeUpdate}
|
||||||
onEdgeUpdateStart={onEdgeUpdateStart}
|
onEdgeUpdateStart={onEdgeUpdateStart}
|
||||||
onEdgeUpdateEnd={onEdgeUpdateEnd}
|
onEdgeUpdateEnd={onEdgeUpdateEnd}
|
||||||
connectionLineComponent={ConnectionLineComponent}
|
connectionLineComponent={ConnectionLineComponent}
|
||||||
onDragOver={onDragOver}
|
onDragOver={onDragOver}
|
||||||
onDrop={onDrop}
|
onDrop={onDrop}
|
||||||
onNodesDelete={onDelete}
|
onNodesDelete={onDelete}
|
||||||
>
|
>
|
||||||
<Background className="dark:bg-gray-900" />
|
<Background className="dark:bg-gray-900"/>
|
||||||
<Controls className="[&>button]:text-black [&>button]:dark:bg-gray-800 hover:[&>button]:dark:bg-gray-700 [&>button]:dark:text-gray-400 [&>button]:dark:fill-gray-400 [&>button]:dark:border-gray-600"></Controls>
|
<Controls className="[&>button]:text-black [&>button]:dark:bg-gray-800 hover:[&>button]:dark:bg-gray-700 [&>button]:dark:text-gray-400 [&>button]:dark:fill-gray-400 [&>button]:dark:border-gray-600">
|
||||||
</ReactFlow>
|
</Controls>
|
||||||
<Chat flow={flow} reactFlowInstance={reactFlowInstance} />
|
</ReactFlow>
|
||||||
</>
|
<Chat flow={flow} reactFlowInstance={reactFlowInstance} />
|
||||||
) : (
|
</>
|
||||||
<></>
|
) : (
|
||||||
)}
|
<></>
|
||||||
</div>
|
)}
|
||||||
);
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,3 +13,5 @@ export type TabsContextType = {
|
||||||
uploadFlow: () => void;
|
uploadFlow: () => void;
|
||||||
hardReset: () => void;
|
hardReset: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type LangFlowState={ tabIndex:number, flows:FlowType[], id:string, nodeId:number }
|
||||||
7
src/frontend/src/types/templatesContext/index.ts
Normal file
7
src/frontend/src/types/templatesContext/index.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
const template:{[char: string]: string}={}
|
||||||
|
|
||||||
|
export type TemplateContextType = {
|
||||||
|
templates: typeof template;
|
||||||
|
setTemplates: (newState: {}) => void;
|
||||||
|
};
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
import { ReactFlowInstance } from "reactflow";
|
import { ReactFlowInstance } from "reactflow";
|
||||||
|
|
||||||
const types: { [char: string]: string } = {};
|
const types:{[char: string]: string}={};
|
||||||
|
const template:{[char: string]: string}={}
|
||||||
|
const data:{[char: string]: string}={}
|
||||||
|
|
||||||
|
|
||||||
export type typesContextType = {
|
export type typesContextType = {
|
||||||
reactFlowInstance: ReactFlowInstance | null;
|
reactFlowInstance: ReactFlowInstance|null;
|
||||||
setReactFlowInstance: any;
|
setReactFlowInstance: any;
|
||||||
deleteNode: (idx: string) => void;
|
deleteNode: (idx: string) => void;
|
||||||
types: typeof types;
|
types: typeof types;
|
||||||
setTypes: (newState: {}) => void;
|
setTypes: (newState: {}) => void;
|
||||||
|
templates: typeof template;
|
||||||
|
setTemplates: (newState: {}) => void;
|
||||||
|
data: typeof data;
|
||||||
|
setData: (newState: {}) => void;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -398,3 +398,22 @@ export function removeApiKeys(flow: FlowType): FlowType {
|
||||||
});
|
});
|
||||||
return cleanFLow;
|
return cleanFLow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateObject<T extends Record<string, any>>(reference: T, objectToUpdate: T): T {
|
||||||
|
let clonedObject = _.cloneDeep(objectToUpdate)
|
||||||
|
// Loop through each key in the object to update
|
||||||
|
for (const key in clonedObject) {
|
||||||
|
// If the key is not in the reference object, delete it
|
||||||
|
if (!(key in reference)) {
|
||||||
|
delete clonedObject[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Loop through each key in the reference object
|
||||||
|
for (const key in reference) {
|
||||||
|
// If the key is not in the object to update, add it
|
||||||
|
if (!(key in clonedObject)) {
|
||||||
|
clonedObject[key] = reference[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clonedObject;
|
||||||
|
}
|
||||||
|
|
@ -36,6 +36,7 @@ def test_zero_shot_agent(client: TestClient):
|
||||||
"name": "llm_chain",
|
"name": "llm_chain",
|
||||||
"type": "LLMChain",
|
"type": "LLMChain",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["allowed_tools"] == {
|
assert template["allowed_tools"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -46,6 +47,7 @@ def test_zero_shot_agent(client: TestClient):
|
||||||
"name": "allowed_tools",
|
"name": "allowed_tools",
|
||||||
"type": "Tool",
|
"type": "Tool",
|
||||||
"list": True,
|
"list": True,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -68,6 +70,7 @@ def test_json_agent(client: TestClient):
|
||||||
"name": "toolkit",
|
"name": "toolkit",
|
||||||
"type": "BaseToolkit",
|
"type": "BaseToolkit",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -78,6 +81,7 @@ def test_json_agent(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -104,6 +108,7 @@ def test_csv_agent(client: TestClient):
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"list": False,
|
"list": False,
|
||||||
"content": None,
|
"content": None,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -114,6 +119,7 @@ def test_csv_agent(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -143,6 +149,7 @@ def test_initialize_agent(client: TestClient):
|
||||||
"name": "agent",
|
"name": "agent",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": True,
|
"list": True,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["memory"] == {
|
assert template["memory"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -153,6 +160,7 @@ def test_initialize_agent(client: TestClient):
|
||||||
"name": "memory",
|
"name": "memory",
|
||||||
"type": "BaseChatMemory",
|
"type": "BaseChatMemory",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["tools"] == {
|
assert template["tools"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -163,6 +171,7 @@ def test_initialize_agent(client: TestClient):
|
||||||
"name": "tools",
|
"name": "tools",
|
||||||
"type": "Tool",
|
"type": "Tool",
|
||||||
"list": True,
|
"list": True,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -173,4 +182,5 @@ def test_initialize_agent(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,16 +31,18 @@ def test_conversation_chain(client: TestClient):
|
||||||
"name": "memory",
|
"name": "memory",
|
||||||
"type": "BaseMemory",
|
"type": "BaseMemory",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["verbose"] == {
|
assert template["verbose"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"show": False,
|
"show": True,
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
"password": False,
|
"password": False,
|
||||||
"name": "verbose",
|
"name": "verbose",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -51,6 +53,7 @@ def test_conversation_chain(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["input_key"] == {
|
assert template["input_key"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -62,6 +65,7 @@ def test_conversation_chain(client: TestClient):
|
||||||
"name": "input_key",
|
"name": "input_key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["output_key"] == {
|
assert template["output_key"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -73,6 +77,7 @@ def test_conversation_chain(client: TestClient):
|
||||||
"name": "output_key",
|
"name": "output_key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["_type"] == "ConversationChain"
|
assert template["_type"] == "ConversationChain"
|
||||||
|
|
||||||
|
|
@ -102,17 +107,19 @@ def test_llm_chain(client: TestClient):
|
||||||
"name": "memory",
|
"name": "memory",
|
||||||
"type": "BaseMemory",
|
"type": "BaseMemory",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["verbose"] == {
|
assert template["verbose"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"show": False,
|
"show": True,
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
"value": False,
|
"value": False,
|
||||||
"password": False,
|
"password": False,
|
||||||
"name": "verbose",
|
"name": "verbose",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -123,6 +130,7 @@ def test_llm_chain(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["output_key"] == {
|
assert template["output_key"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -134,6 +142,7 @@ def test_llm_chain(client: TestClient):
|
||||||
"name": "output_key",
|
"name": "output_key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -156,17 +165,19 @@ def test_llm_checker_chain(client: TestClient):
|
||||||
"name": "memory",
|
"name": "memory",
|
||||||
"type": "BaseMemory",
|
"type": "BaseMemory",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["verbose"] == {
|
assert template["verbose"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"show": False,
|
"show": True,
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
"value": False,
|
"value": False,
|
||||||
"password": False,
|
"password": False,
|
||||||
"name": "verbose",
|
"name": "verbose",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -177,6 +188,7 @@ def test_llm_checker_chain(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLLM",
|
"type": "BaseLLM",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["input_key"] == {
|
assert template["input_key"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -188,6 +200,7 @@ def test_llm_checker_chain(client: TestClient):
|
||||||
"name": "input_key",
|
"name": "input_key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["output_key"] == {
|
assert template["output_key"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -199,6 +212,7 @@ def test_llm_checker_chain(client: TestClient):
|
||||||
"name": "output_key",
|
"name": "output_key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["_type"] == "LLMCheckerChain"
|
assert template["_type"] == "LLMCheckerChain"
|
||||||
|
|
||||||
|
|
@ -228,17 +242,19 @@ def test_llm_math_chain(client: TestClient):
|
||||||
"name": "memory",
|
"name": "memory",
|
||||||
"type": "BaseMemory",
|
"type": "BaseMemory",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["verbose"] == {
|
assert template["verbose"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"show": False,
|
"show": True,
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
"value": False,
|
"value": False,
|
||||||
"password": False,
|
"password": False,
|
||||||
"name": "verbose",
|
"name": "verbose",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -249,6 +265,7 @@ def test_llm_math_chain(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["input_key"] == {
|
assert template["input_key"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -260,6 +277,7 @@ def test_llm_math_chain(client: TestClient):
|
||||||
"name": "input_key",
|
"name": "input_key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["output_key"] == {
|
assert template["output_key"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -271,6 +289,7 @@ def test_llm_math_chain(client: TestClient):
|
||||||
"name": "output_key",
|
"name": "output_key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["_type"] == "LLMMathChain"
|
assert template["_type"] == "LLMMathChain"
|
||||||
|
|
||||||
|
|
@ -298,35 +317,7 @@ def test_series_character_chain(client: TestClient):
|
||||||
"SeriesCharacterChain",
|
"SeriesCharacterChain",
|
||||||
}
|
}
|
||||||
template = chain["template"]
|
template = chain["template"]
|
||||||
assert template["memory"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": {
|
|
||||||
"chat_memory": {"messages": []},
|
|
||||||
"output_key": None,
|
|
||||||
"input_key": None,
|
|
||||||
"return_messages": False,
|
|
||||||
"human_prefix": "Human",
|
|
||||||
"ai_prefix": "AI",
|
|
||||||
"memory_key": "history",
|
|
||||||
},
|
|
||||||
"password": False,
|
|
||||||
"name": "memory",
|
|
||||||
"type": "BaseMemory",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["verbose"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": False,
|
|
||||||
"password": False,
|
|
||||||
"name": "verbose",
|
|
||||||
"type": "bool",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
|
|
@ -336,50 +327,7 @@ def test_series_character_chain(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
}
|
"advanced": False,
|
||||||
assert template["input_key"] == {
|
|
||||||
"required": True,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": "input",
|
|
||||||
"password": False,
|
|
||||||
"name": "input_key",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["output_key"] == {
|
|
||||||
"required": True,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": "response",
|
|
||||||
"password": False,
|
|
||||||
"name": "output_key",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["template"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": True,
|
|
||||||
"value": "I want you to act like {character} from {series}.\nI want you to respond and answer like {character}. do not write any explanations. only answer like {character}.\nYou must know all of the knowledge of {character}.\nCurrent conversation:\n{history}\nHuman: {input}\n{character}:", # noqa: E501
|
|
||||||
"password": False,
|
|
||||||
"name": "template",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["ai_prefix_value"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": False,
|
|
||||||
"value": "character",
|
|
||||||
"password": False,
|
|
||||||
"name": "ai_prefix_value",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
}
|
||||||
assert template["character"] == {
|
assert template["character"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -390,6 +338,7 @@ def test_series_character_chain(client: TestClient):
|
||||||
"name": "character",
|
"name": "character",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["series"] == {
|
assert template["series"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -400,6 +349,7 @@ def test_series_character_chain(client: TestClient):
|
||||||
"name": "series",
|
"name": "series",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["_type"] == "SeriesCharacterChain"
|
assert template["_type"] == "SeriesCharacterChain"
|
||||||
|
|
||||||
|
|
@ -429,55 +379,7 @@ def test_mid_journey_prompt_chain(client: TestClient):
|
||||||
|
|
||||||
# Test the template object
|
# Test the template object
|
||||||
template = chain["template"]
|
template = chain["template"]
|
||||||
assert template["memory"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": {
|
|
||||||
"chat_memory": {"messages": []},
|
|
||||||
"output_key": None,
|
|
||||||
"input_key": None,
|
|
||||||
"return_messages": False,
|
|
||||||
"human_prefix": "Human",
|
|
||||||
"ai_prefix": "AI",
|
|
||||||
"memory_key": "history",
|
|
||||||
},
|
|
||||||
"password": False,
|
|
||||||
"name": "memory",
|
|
||||||
"type": "BaseMemory",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["verbose"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": False,
|
|
||||||
"password": False,
|
|
||||||
"name": "verbose",
|
|
||||||
"type": "bool",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
# Continue with other template object assertions
|
|
||||||
assert template["prompt"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": False,
|
|
||||||
"value": {
|
|
||||||
"input_variables": ["history", "input"],
|
|
||||||
"output_parser": None,
|
|
||||||
"partial_variables": {},
|
|
||||||
"template": "The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n\nCurrent conversation:\n{history}\nHuman: {input}\nAI:", # noqa: E501
|
|
||||||
"template_format": "f-string",
|
|
||||||
"validate_template": True,
|
|
||||||
"_type": "prompt",
|
|
||||||
},
|
|
||||||
"password": False,
|
|
||||||
"name": "prompt",
|
|
||||||
"type": "BasePromptTemplate",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
|
|
@ -487,49 +389,7 @@ def test_mid_journey_prompt_chain(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
}
|
"advanced": False,
|
||||||
assert template["output_key"] == {
|
|
||||||
"required": True,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": "response",
|
|
||||||
"password": False,
|
|
||||||
"name": "output_key",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["input_key"] == {
|
|
||||||
"required": True,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": "input",
|
|
||||||
"password": False,
|
|
||||||
"name": "input_key",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["template"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": True,
|
|
||||||
"value": 'I want you to act as a prompt generator for Midjourney\'s artificial intelligence program.\n Your job is to provide detailed and creative descriptions that will inspire unique and interesting images from the AI.\n Keep in mind that the AI is capable of understanding a wide range of language and can interpret abstract concepts, so feel free to be as imaginative and descriptive as possible.\n For example, you could describe a scene from a futuristic city, or a surreal landscape filled with strange creatures.\n The more detailed and imaginative your description, the more interesting the resulting image will be. Here is your first prompt:\n "A field of wildflowers stretches out as far as the eye can see, each one a different color and shape. In the distance, a massive tree towers over the landscape, its branches reaching up to the sky like tentacles."\n\n Current conversation:\n {history}\n Human: {input}\n AI:', # noqa: E501
|
|
||||||
"password": False,
|
|
||||||
"name": "template",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["ai_prefix_value"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": False,
|
|
||||||
"password": False,
|
|
||||||
"name": "ai_prefix_value",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
}
|
||||||
# Test the description object
|
# Test the description object
|
||||||
assert (
|
assert (
|
||||||
|
|
@ -557,55 +417,7 @@ def test_time_travel_guide_chain(client: TestClient):
|
||||||
|
|
||||||
# Test the template object
|
# Test the template object
|
||||||
template = chain["template"]
|
template = chain["template"]
|
||||||
assert template["memory"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": {
|
|
||||||
"chat_memory": {"messages": []},
|
|
||||||
"output_key": None,
|
|
||||||
"input_key": None,
|
|
||||||
"return_messages": False,
|
|
||||||
"human_prefix": "Human",
|
|
||||||
"ai_prefix": "AI",
|
|
||||||
"memory_key": "history",
|
|
||||||
},
|
|
||||||
"password": False,
|
|
||||||
"name": "memory",
|
|
||||||
"type": "BaseMemory",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["verbose"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": False,
|
|
||||||
"password": False,
|
|
||||||
"name": "verbose",
|
|
||||||
"type": "bool",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert template["prompt"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": False,
|
|
||||||
"value": {
|
|
||||||
"input_variables": ["history", "input"],
|
|
||||||
"output_parser": None,
|
|
||||||
"partial_variables": {},
|
|
||||||
"template": "The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n\nCurrent conversation:\n{history}\nHuman: {input}\nAI:", # noqa: E501
|
|
||||||
"template_format": "f-string",
|
|
||||||
"validate_template": True,
|
|
||||||
"_type": "prompt",
|
|
||||||
},
|
|
||||||
"password": False,
|
|
||||||
"name": "prompt",
|
|
||||||
"type": "BasePromptTemplate",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["llm"] == {
|
assert template["llm"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
|
|
@ -615,50 +427,7 @@ def test_time_travel_guide_chain(client: TestClient):
|
||||||
"name": "llm",
|
"name": "llm",
|
||||||
"type": "BaseLanguageModel",
|
"type": "BaseLanguageModel",
|
||||||
"list": False,
|
"list": False,
|
||||||
}
|
"advanced": False,
|
||||||
assert template["output_key"] == {
|
|
||||||
"required": True,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": "response",
|
|
||||||
"password": False,
|
|
||||||
"name": "output_key",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert template["input_key"] == {
|
assert chain["description"] == "Time travel guide chain to be used in the flow."
|
||||||
"required": True,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": True,
|
|
||||||
"multiline": False,
|
|
||||||
"value": "input",
|
|
||||||
"password": False,
|
|
||||||
"name": "input_key",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert template["template"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": True,
|
|
||||||
"value": "I want you to act as my time travel guide. You are helpful and creative. I will provide you with the historical period or future time I want to visit and you will suggest the best events, sights, or people to experience. Provide the suggestions and any necessary information.\n Current conversation:\n {history}\n Human: {input}\n AI:", # noqa: E501
|
|
||||||
"password": False,
|
|
||||||
"name": "template",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert template["ai_prefix_value"] == {
|
|
||||||
"required": False,
|
|
||||||
"placeholder": "",
|
|
||||||
"show": False,
|
|
||||||
"multiline": False,
|
|
||||||
"password": False,
|
|
||||||
"name": "ai_prefix_value",
|
|
||||||
"type": "str",
|
|
||||||
"list": False,
|
|
||||||
}
|
|
||||||
assert chain["description"] == ""
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ def test_hugging_face_hub(client: TestClient):
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["verbose"] == {
|
assert template["verbose"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -39,6 +40,7 @@ def test_hugging_face_hub(client: TestClient):
|
||||||
"name": "verbose",
|
"name": "verbose",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["client"] == {
|
assert template["client"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -49,6 +51,7 @@ def test_hugging_face_hub(client: TestClient):
|
||||||
"name": "client",
|
"name": "client",
|
||||||
"type": "Any",
|
"type": "Any",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["repo_id"] == {
|
assert template["repo_id"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -60,6 +63,7 @@ def test_hugging_face_hub(client: TestClient):
|
||||||
"name": "repo_id",
|
"name": "repo_id",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["task"] == {
|
assert template["task"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -71,6 +75,7 @@ def test_hugging_face_hub(client: TestClient):
|
||||||
"name": "task",
|
"name": "task",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": True,
|
"list": True,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["model_kwargs"] == {
|
assert template["model_kwargs"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -81,9 +86,10 @@ def test_hugging_face_hub(client: TestClient):
|
||||||
"name": "model_kwargs",
|
"name": "model_kwargs",
|
||||||
"type": "code",
|
"type": "code",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["huggingfacehub_api_token"] == {
|
assert template["huggingfacehub_api_token"] == {
|
||||||
"required": True,
|
"required": False,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"show": True,
|
"show": True,
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
|
|
@ -92,6 +98,7 @@ def test_hugging_face_hub(client: TestClient):
|
||||||
"display_name": "HuggingFace Hub API Token",
|
"display_name": "HuggingFace Hub API Token",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -113,6 +120,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "cache",
|
"name": "cache",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["verbose"] == {
|
assert template["verbose"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -123,6 +131,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "verbose",
|
"name": "verbose",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["client"] == {
|
assert template["client"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -133,6 +142,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "client",
|
"name": "client",
|
||||||
"type": "Any",
|
"type": "Any",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["model_name"] == {
|
assert template["model_name"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -151,6 +161,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "model_name",
|
"name": "model_name",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": True,
|
"list": True,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
# Add more assertions for other properties here
|
# Add more assertions for other properties here
|
||||||
assert template["temperature"] == {
|
assert template["temperature"] == {
|
||||||
|
|
@ -163,6 +174,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "temperature",
|
"name": "temperature",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["max_tokens"] == {
|
assert template["max_tokens"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -174,6 +186,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "max_tokens",
|
"name": "max_tokens",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["top_p"] == {
|
assert template["top_p"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -185,6 +198,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "top_p",
|
"name": "top_p",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["frequency_penalty"] == {
|
assert template["frequency_penalty"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -196,6 +210,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "frequency_penalty",
|
"name": "frequency_penalty",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["presence_penalty"] == {
|
assert template["presence_penalty"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -207,6 +222,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "presence_penalty",
|
"name": "presence_penalty",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["n"] == {
|
assert template["n"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -218,6 +234,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "n",
|
"name": "n",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["best_of"] == {
|
assert template["best_of"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -229,6 +246,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "best_of",
|
"name": "best_of",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["model_kwargs"] == {
|
assert template["model_kwargs"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -239,9 +257,10 @@ def test_openai(client: TestClient):
|
||||||
"name": "model_kwargs",
|
"name": "model_kwargs",
|
||||||
"type": "code",
|
"type": "code",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["openai_api_key"] == {
|
assert template["openai_api_key"] == {
|
||||||
"required": True,
|
"required": False,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"show": True,
|
"show": True,
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
|
|
@ -251,6 +270,7 @@ def test_openai(client: TestClient):
|
||||||
"display_name": "OpenAI API Key",
|
"display_name": "OpenAI API Key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["batch_size"] == {
|
assert template["batch_size"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -262,6 +282,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "batch_size",
|
"name": "batch_size",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["request_timeout"] == {
|
assert template["request_timeout"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -272,6 +293,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "request_timeout",
|
"name": "request_timeout",
|
||||||
"type": "Union[float, Tuple[float, float], NoneType]",
|
"type": "Union[float, Tuple[float, float], NoneType]",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["logit_bias"] == {
|
assert template["logit_bias"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -282,6 +304,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "logit_bias",
|
"name": "logit_bias",
|
||||||
"type": "code",
|
"type": "code",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["max_retries"] == {
|
assert template["max_retries"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -293,6 +316,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "max_retries",
|
"name": "max_retries",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["streaming"] == {
|
assert template["streaming"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -304,6 +328,7 @@ def test_openai(client: TestClient):
|
||||||
"name": "streaming",
|
"name": "streaming",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -326,6 +351,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "verbose",
|
"name": "verbose",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["client"] == {
|
assert template["client"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -336,6 +362,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "client",
|
"name": "client",
|
||||||
"type": "Any",
|
"type": "Any",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["model_name"] == {
|
assert template["model_name"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -348,6 +375,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "model_name",
|
"name": "model_name",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": True,
|
"list": True,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["temperature"] == {
|
assert template["temperature"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -359,6 +387,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "temperature",
|
"name": "temperature",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["model_kwargs"] == {
|
assert template["model_kwargs"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -369,9 +398,10 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "model_kwargs",
|
"name": "model_kwargs",
|
||||||
"type": "code",
|
"type": "code",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["openai_api_key"] == {
|
assert template["openai_api_key"] == {
|
||||||
"required": True,
|
"required": False,
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"show": True,
|
"show": True,
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
|
|
@ -381,6 +411,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"display_name": "OpenAI API Key",
|
"display_name": "OpenAI API Key",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": False,
|
||||||
}
|
}
|
||||||
assert template["request_timeout"] == {
|
assert template["request_timeout"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -392,6 +423,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "request_timeout",
|
"name": "request_timeout",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["max_retries"] == {
|
assert template["max_retries"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -403,6 +435,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "max_retries",
|
"name": "max_retries",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["streaming"] == {
|
assert template["streaming"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -414,6 +447,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "streaming",
|
"name": "streaming",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["n"] == {
|
assert template["n"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -425,6 +459,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "n",
|
"name": "n",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert template["max_tokens"] == {
|
assert template["max_tokens"] == {
|
||||||
|
|
@ -436,6 +471,7 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"name": "max_tokens",
|
"name": "max_tokens",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["_type"] == "ChatOpenAI"
|
assert template["_type"] == "ChatOpenAI"
|
||||||
assert (
|
assert (
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ def test_prompt_template(client: TestClient):
|
||||||
"name": "input_variables",
|
"name": "input_variables",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": True,
|
"list": True,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["output_parser"] == {
|
assert template["output_parser"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -37,6 +38,7 @@ def test_prompt_template(client: TestClient):
|
||||||
"name": "output_parser",
|
"name": "output_parser",
|
||||||
"type": "BaseOutputParser",
|
"type": "BaseOutputParser",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["partial_variables"] == {
|
assert template["partial_variables"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -47,6 +49,7 @@ def test_prompt_template(client: TestClient):
|
||||||
"name": "partial_variables",
|
"name": "partial_variables",
|
||||||
"type": "code",
|
"type": "code",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["template"] == {
|
assert template["template"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -57,6 +60,7 @@ def test_prompt_template(client: TestClient):
|
||||||
"name": "template",
|
"name": "template",
|
||||||
"type": "prompt",
|
"type": "prompt",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["template_format"] == {
|
assert template["template_format"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -68,6 +72,7 @@ def test_prompt_template(client: TestClient):
|
||||||
"name": "template_format",
|
"name": "template_format",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["validate_template"] == {
|
assert template["validate_template"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -79,6 +84,7 @@ def test_prompt_template(client: TestClient):
|
||||||
"name": "validate_template",
|
"name": "validate_template",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -100,6 +106,7 @@ def test_few_shot_prompt_template(client: TestClient):
|
||||||
"name": "examples",
|
"name": "examples",
|
||||||
"type": "prompt",
|
"type": "prompt",
|
||||||
"list": True,
|
"list": True,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["example_selector"] == {
|
assert template["example_selector"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -110,6 +117,7 @@ def test_few_shot_prompt_template(client: TestClient):
|
||||||
"name": "example_selector",
|
"name": "example_selector",
|
||||||
"type": "BaseExampleSelector",
|
"type": "BaseExampleSelector",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["example_prompt"] == {
|
assert template["example_prompt"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -120,6 +128,7 @@ def test_few_shot_prompt_template(client: TestClient):
|
||||||
"name": "example_prompt",
|
"name": "example_prompt",
|
||||||
"type": "PromptTemplate",
|
"type": "PromptTemplate",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["suffix"] == {
|
assert template["suffix"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -130,6 +139,7 @@ def test_few_shot_prompt_template(client: TestClient):
|
||||||
"name": "suffix",
|
"name": "suffix",
|
||||||
"type": "prompt",
|
"type": "prompt",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["example_separator"] == {
|
assert template["example_separator"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -141,6 +151,7 @@ def test_few_shot_prompt_template(client: TestClient):
|
||||||
"name": "example_separator",
|
"name": "example_separator",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["prefix"] == {
|
assert template["prefix"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -152,6 +163,7 @@ def test_few_shot_prompt_template(client: TestClient):
|
||||||
"name": "prefix",
|
"name": "prefix",
|
||||||
"type": "prompt",
|
"type": "prompt",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -172,6 +184,7 @@ def test_zero_shot_prompt(client: TestClient):
|
||||||
"name": "prefix",
|
"name": "prefix",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["suffix"] == {
|
assert template["suffix"] == {
|
||||||
"required": True,
|
"required": True,
|
||||||
|
|
@ -183,6 +196,7 @@ def test_zero_shot_prompt(client: TestClient):
|
||||||
"name": "suffix",
|
"name": "suffix",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
assert template["format_instructions"] == {
|
assert template["format_instructions"] == {
|
||||||
"required": False,
|
"required": False,
|
||||||
|
|
@ -194,4 +208,5 @@ def test_zero_shot_prompt(client: TestClient):
|
||||||
"name": "format_instructions",
|
"name": "format_instructions",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"list": False,
|
"list": False,
|
||||||
|
"advanced": True,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue