Merge branch 'dev' into two_edges_dev
This commit is contained in:
commit
f0630ec870
63 changed files with 1977 additions and 2717 deletions
18
.github/workflows/docker_test.yml
vendored
18
.github/workflows/docker_test.yml
vendored
|
|
@ -24,6 +24,7 @@ env:
|
|||
jobs:
|
||||
test-docker:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test docker images
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build image
|
||||
|
|
@ -61,20 +62,3 @@ jobs:
|
|||
docker build -t langflowai/langflow-frontend:latest-dev \
|
||||
-f docker/frontend/build_and_push_frontend.Dockerfile \
|
||||
.
|
||||
test-multi-arch-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
id: qemu
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
file: ./docker/build_and_push.Dockerfile
|
||||
platforms: "linux/amd64,linux/arm64/v8"
|
||||
tags: langflowai/langflow:latest-dev
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -180,6 +180,8 @@ coverage.xml
|
|||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
*.db-shm
|
||||
*.db-wal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
|
|
|
|||
75
Makefile
75
Makefile
|
|
@ -9,17 +9,21 @@ open_browser ?= true
|
|||
path = src/backend/base/langflow/frontend
|
||||
workers ?= 1
|
||||
|
||||
|
||||
codespell:
|
||||
@poetry install --with spelling
|
||||
poetry run codespell --toml pyproject.toml
|
||||
|
||||
|
||||
fix_codespell:
|
||||
@poetry install --with spelling
|
||||
poetry run codespell --toml pyproject.toml --write
|
||||
|
||||
|
||||
setup_poetry:
|
||||
pipx install poetry
|
||||
|
||||
|
||||
add:
|
||||
@echo 'Adding dependencies'
|
||||
ifdef devel
|
||||
|
|
@ -34,45 +38,54 @@ ifdef base
|
|||
cd src/backend/base && poetry add $(base)
|
||||
endif
|
||||
|
||||
|
||||
init:
|
||||
@echo 'Installing backend dependencies'
|
||||
make install_backend
|
||||
@echo 'Installing frontend dependencies'
|
||||
make install_frontend
|
||||
|
||||
coverage:
|
||||
|
||||
coverage: ## run the tests and generate a coverage report
|
||||
poetry run pytest --cov \
|
||||
--cov-config=.coveragerc \
|
||||
--cov-report xml \
|
||||
--cov-report term-missing:skip-covered \
|
||||
--cov-report lcov:coverage/lcov-pytest.info
|
||||
|
||||
|
||||
# allow passing arguments to pytest
|
||||
tests:
|
||||
tests: ## run the tests
|
||||
poetry run pytest tests --instafail -ra -n auto -m "not api_key_required" $(args)
|
||||
|
||||
|
||||
format:
|
||||
format: ## run code formatters
|
||||
poetry run ruff check . --fix
|
||||
poetry run ruff format .
|
||||
cd src/frontend && npm run format
|
||||
|
||||
lint:
|
||||
|
||||
lint: ## run linters
|
||||
poetry run mypy --namespace-packages -p "langflow"
|
||||
|
||||
install_frontend:
|
||||
|
||||
install_frontend: ## install the frontend dependencies
|
||||
cd src/frontend && npm install
|
||||
|
||||
|
||||
install_frontendci:
|
||||
cd src/frontend && npm ci
|
||||
|
||||
|
||||
install_frontendc:
|
||||
cd src/frontend && rm -rf node_modules package-lock.json && npm install
|
||||
|
||||
|
||||
run_frontend:
|
||||
@-kill -9 `lsof -t -i:3000`
|
||||
cd src/frontend && npm start
|
||||
|
||||
|
||||
tests_frontend:
|
||||
ifeq ($(UI), true)
|
||||
cd src/frontend && npx playwright test --ui --project=chromium
|
||||
|
|
@ -80,6 +93,7 @@ else
|
|||
cd src/frontend && npx playwright test --project=chromium
|
||||
endif
|
||||
|
||||
|
||||
run_cli:
|
||||
@echo 'Running the CLI'
|
||||
@make install_frontend > /dev/null
|
||||
|
|
@ -93,6 +107,7 @@ else
|
|||
@make start host=$(host) port=$(port) log_level=$(log_level)
|
||||
endif
|
||||
|
||||
|
||||
run_cli_debug:
|
||||
@echo 'Running the CLI in debug mode'
|
||||
@make install_frontend > /dev/null
|
||||
|
|
@ -106,6 +121,7 @@ else
|
|||
@make start host=$(host) port=$(port) log_level=debug
|
||||
endif
|
||||
|
||||
|
||||
start:
|
||||
@echo 'Running the CLI'
|
||||
|
||||
|
|
@ -116,30 +132,34 @@ else
|
|||
endif
|
||||
|
||||
|
||||
|
||||
setup_devcontainer:
|
||||
make init
|
||||
make build_frontend
|
||||
poetry run langflow --path src/frontend/build
|
||||
|
||||
|
||||
setup_env:
|
||||
@sh ./scripts/setup/update_poetry.sh 1.8.2
|
||||
@sh ./scripts/setup/setup_env.sh
|
||||
|
||||
frontend:
|
||||
|
||||
frontend: ## run the frontend in development mode
|
||||
make install_frontend
|
||||
make run_frontend
|
||||
|
||||
|
||||
frontendc:
|
||||
make install_frontendc
|
||||
make run_frontend
|
||||
|
||||
|
||||
install_backend:
|
||||
@echo 'Installing backend dependencies'
|
||||
@poetry install
|
||||
@poetry run pre-commit install
|
||||
|
||||
backend:
|
||||
|
||||
backend: ## run the backend in development mode
|
||||
@echo 'Setting up the environment'
|
||||
@make setup_env
|
||||
make install_backend
|
||||
|
|
@ -152,6 +172,7 @@ else
|
|||
poetry run uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload --env-file .env --loop asyncio --workers $(workers)
|
||||
endif
|
||||
|
||||
|
||||
build_and_run:
|
||||
@echo 'Removing dist folder'
|
||||
@make setup_env
|
||||
|
|
@ -161,18 +182,21 @@ build_and_run:
|
|||
poetry run pip install dist/*.tar.gz
|
||||
poetry run langflow run
|
||||
|
||||
|
||||
build_and_install:
|
||||
@echo 'Removing dist folder'
|
||||
rm -rf dist
|
||||
rm -rf src/backend/base/dist
|
||||
make build && poetry run pip install dist/*.whl && pip install src/backend/base/dist/*.whl --force-reinstall
|
||||
|
||||
build_frontend:
|
||||
|
||||
build_frontend: ## build the frontend static files
|
||||
cd src/frontend && CI='' npm run build
|
||||
rm -rf src/backend/base/langflow/frontend
|
||||
cp -r src/frontend/build src/backend/base/langflow/frontend
|
||||
|
||||
build:
|
||||
|
||||
build: ## build the frontend static files and package the project
|
||||
@echo 'Building the project'
|
||||
@make setup_env
|
||||
ifdef base
|
||||
|
|
@ -185,13 +209,16 @@ ifdef main
|
|||
make build_langflow
|
||||
endif
|
||||
|
||||
|
||||
build_langflow_base:
|
||||
cd src/backend/base && poetry build
|
||||
rm -rf src/backend/base/langflow/frontend
|
||||
|
||||
|
||||
build_langflow_backup:
|
||||
poetry lock && poetry build
|
||||
|
||||
|
||||
build_langflow:
|
||||
cd ./scripts && poetry run python update_dependencies.py
|
||||
poetry lock
|
||||
|
|
@ -201,7 +228,8 @@ ifdef restore
|
|||
mv poetry.lock.bak poetry.lock
|
||||
endif
|
||||
|
||||
dev:
|
||||
|
||||
dev: ## run the project in development mode with docker compose
|
||||
make install_frontend
|
||||
ifeq ($(build),1)
|
||||
@echo 'Running docker compose up with build'
|
||||
|
|
@ -211,25 +239,30 @@ else
|
|||
docker compose $(if $(debug),-f docker-compose.debug.yml) up
|
||||
endif
|
||||
|
||||
|
||||
lock_base:
|
||||
cd src/backend/base && poetry lock
|
||||
|
||||
lock_langflow:
|
||||
poetry lock
|
||||
|
||||
|
||||
lock:
|
||||
# Run both in parallel
|
||||
@echo 'Locking dependencies'
|
||||
cd src/backend/base && poetry lock
|
||||
poetry lock
|
||||
|
||||
|
||||
publish_base:
|
||||
cd src/backend/base && poetry publish
|
||||
|
||||
|
||||
publish_langflow:
|
||||
poetry publish
|
||||
|
||||
publish:
|
||||
|
||||
publish: ## build the frontend static files and package the project and publish it to PyPI
|
||||
@echo 'Publishing the project'
|
||||
ifdef base
|
||||
make publish_base
|
||||
|
|
@ -239,17 +272,11 @@ ifdef main
|
|||
make publish_langflow
|
||||
endif
|
||||
|
||||
help:
|
||||
|
||||
help: ## show this help message
|
||||
@echo '----'
|
||||
@echo 'format - run code formatters'
|
||||
@echo 'lint - run linters'
|
||||
@echo 'install_frontend - install the frontend dependencies'
|
||||
@echo 'build_frontend - build the frontend static files'
|
||||
@echo 'run_frontend - run the frontend in development mode'
|
||||
@echo 'run_backend - run the backend in development mode'
|
||||
@echo 'build - build the frontend static files and package the project'
|
||||
@echo 'publish - build the frontend static files and package the project and publish it to PyPI'
|
||||
@echo 'dev - run the project in development mode with docker compose'
|
||||
@echo 'tests - run the tests'
|
||||
@echo 'coverage - run the tests and generate a coverage report'
|
||||
@echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | \
|
||||
sed -e 's/:.*##\s*/:/' \
|
||||
-e 's/^\(.\+\):\(.*\)/\\x1b[36mmake \1\\x1b[m:\2/' | \
|
||||
column -c2 -t -s :']]')"
|
||||
@echo '----'
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@
|
|||
# Used to build deps + create our virtual environment
|
||||
################################
|
||||
|
||||
# force platform to the current architecture to increase build speed time on multi-platform builds
|
||||
FROM --platform=$BUILDPLATFORM python:3.12-slim as builder-base
|
||||
# 1. use python:3.12.3-slim as the base image until https://github.com/pydantic/pydantic-core/issues/1292 gets resolved
|
||||
# 2. do not add --platform=$BUILDPLATFORM because the pydantic binaries must be resolved for the final architecture
|
||||
FROM python:3.12.3-slim as builder-base
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
\
|
||||
|
|
@ -51,15 +52,27 @@ COPY pyproject.toml poetry.lock README.md ./
|
|||
COPY src/ ./src
|
||||
COPY scripts/ ./scripts
|
||||
RUN python -m pip install requests --user && cd ./scripts && python update_dependencies.py
|
||||
|
||||
# 1. Install the dependencies using the current poetry.lock file to create reproducible builds
|
||||
# 2. Do not install dev dependencies
|
||||
# 3. Install all the extras to ensure all optionals are installed as well
|
||||
# 4. --sync to ensure nothing else is in the environment
|
||||
# 5. Build the wheel and install "langflow" package (mainly for version)
|
||||
|
||||
# Note: moving to build and installing the wheel will make the docker images not reproducible.
|
||||
RUN $POETRY_HOME/bin/poetry lock --no-update \
|
||||
# install current lock file with fixed dependencies versions \
|
||||
# do not install dev dependencies \
|
||||
&& $POETRY_HOME/bin/poetry install --without dev --sync -E deploy -E couchbase -E cassio \
|
||||
&& $POETRY_HOME/bin/poetry build -f wheel \
|
||||
&& $POETRY_HOME/bin/poetry run pip install dist/*.whl --force-reinstall
|
||||
&& $POETRY_HOME/bin/poetry run pip install dist/*.whl
|
||||
|
||||
################################
|
||||
# RUNTIME
|
||||
# Setup user, utilities and copy the virtual environment only
|
||||
################################
|
||||
FROM python:3.12-slim as runtime
|
||||
# 1. use python:3.12.3-slim as the base image until https://github.com/pydantic/pydantic-core/issues/1292 gets resolved
|
||||
FROM python:3.12.3-slim as runtime
|
||||
|
||||
RUN apt-get -y update \
|
||||
&& apt-get install --no-install-recommends -y \
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@
|
|||
# PYTHON-BASE
|
||||
# Sets up all our shared environment variables
|
||||
################################
|
||||
FROM python:3.12-slim as python-base
|
||||
|
||||
# use python:3.12.3-slim as the base image until https://github.com/pydantic/pydantic-core/issues/1292 gets resolved
|
||||
FROM python:3.12.3-slim as python-base
|
||||
|
||||
# python
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
# BUILDER-BASE
|
||||
################################
|
||||
|
||||
# force platform to the current architecture to increase build speed time on multi-platform builds
|
||||
# 1. force platform to the current architecture to increase build speed time on multi-platform builds
|
||||
FROM --platform=$BUILDPLATFORM node:lts-bookworm-slim as builder-base
|
||||
COPY src/frontend /frontend
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ server {
|
|||
gzip_vary on;
|
||||
gzip_disable "MSIE [4-6] \.";
|
||||
|
||||
listen 80;
|
||||
listen __FRONTEND_PORT__;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
|
|
|
|||
|
|
@ -4,11 +4,20 @@ trap 'kill -TERM $PID' TERM INT
|
|||
if [ -z "$BACKEND_URL" ]; then
|
||||
BACKEND_URL="$1"
|
||||
fi
|
||||
if [ -z "$FRONTEND_PORT" ]; then
|
||||
FRONTEND_PORT="$2"
|
||||
fi
|
||||
if [ -z "$FRONTEND_PORT" ]; then
|
||||
FRONTEND_PORT="80"
|
||||
fi
|
||||
if [ -z "$BACKEND_URL" ]; then
|
||||
echo "BACKEND_URL must be set as an environment variable or as first parameter. (e.g. http://localhost:7860)"
|
||||
exit 1
|
||||
fi
|
||||
echo "BACKEND_URL: $BACKEND_URL"
|
||||
echo "FRONTEND_PORT: $FRONTEND_PORT"
|
||||
sed -i "s|__BACKEND_URL__|$BACKEND_URL|g" /etc/nginx/conf.d/default.conf
|
||||
sed -i "s|__FRONTEND_PORT__|$FRONTEND_PORT|g" /etc/nginx/conf.d/default.conf
|
||||
cat /etc/nginx/conf.d/default.conf
|
||||
|
||||
|
||||
|
|
|
|||
2
poetry.lock
generated
2
poetry.lock
generated
|
|
@ -4409,7 +4409,7 @@ six = "*"
|
|||
|
||||
[[package]]
|
||||
name = "langflow-base"
|
||||
version = "0.0.63"
|
||||
version = "0.0.66"
|
||||
description = "A Python package with a built-in web application"
|
||||
optional = false
|
||||
python-versions = ">=3.10,<3.13"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "langflow"
|
||||
version = "1.0.0a52"
|
||||
version = "1.0.0a55"
|
||||
description = "A Python package with a built-in web application"
|
||||
authors = ["Langflow <contact@langflow.org>"]
|
||||
maintainers = [
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from typing import Optional
|
||||
from langchain_core.embeddings import Embeddings
|
||||
from langchain_openai import AzureOpenAIEmbeddings
|
||||
from pydantic.v1 import SecretStr
|
||||
|
|
@ -44,6 +45,11 @@ class AzureOpenAIEmbeddingsComponent(CustomComponent):
|
|||
"password": True,
|
||||
},
|
||||
"code": {"show": False},
|
||||
"dimensions": {
|
||||
"display_name": "Dimensions",
|
||||
"info": "The number of dimensions the resulting output embeddings should have. Only supported by certain models.",
|
||||
"advanced": True,
|
||||
},
|
||||
}
|
||||
|
||||
def build(
|
||||
|
|
@ -52,6 +58,7 @@ class AzureOpenAIEmbeddingsComponent(CustomComponent):
|
|||
azure_deployment: str,
|
||||
api_version: str,
|
||||
api_key: str,
|
||||
dimensions: Optional[int] = None,
|
||||
) -> Embeddings:
|
||||
if api_key:
|
||||
azure_api_key = SecretStr(api_key)
|
||||
|
|
@ -63,6 +70,7 @@ class AzureOpenAIEmbeddingsComponent(CustomComponent):
|
|||
azure_deployment=azure_deployment,
|
||||
api_version=api_version,
|
||||
api_key=azure_api_key,
|
||||
dimensions=dimensions,
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -84,6 +84,11 @@ class OpenAIEmbeddingsComponent(CustomComponent):
|
|||
"advanced": True,
|
||||
},
|
||||
"tiktoken_enable": {"display_name": "TikToken Enable", "advanced": True},
|
||||
"dimensions": {
|
||||
"display_name": "Dimensions",
|
||||
"info": "The number of dimensions the resulting output embeddings should have. Only supported by certain models.",
|
||||
"advanced": True,
|
||||
},
|
||||
}
|
||||
|
||||
def build(
|
||||
|
|
@ -109,6 +114,7 @@ class OpenAIEmbeddingsComponent(CustomComponent):
|
|||
skip_empty: bool = False,
|
||||
tiktoken_enable: bool = True,
|
||||
tiktoken_model_name: Optional[str] = None,
|
||||
dimensions: Optional[int] = None,
|
||||
) -> Embeddings:
|
||||
# This is to avoid errors with Vector Stores (e.g Chroma)
|
||||
if disallowed_special == ["all"]:
|
||||
|
|
@ -140,4 +146,5 @@ class OpenAIEmbeddingsComponent(CustomComponent):
|
|||
show_progress_bar=show_progress_bar,
|
||||
skip_empty=skip_empty,
|
||||
tiktoken_model_name=tiktoken_model_name,
|
||||
dimensions=dimensions,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class ChatOpenAIComponent(CustomComponent):
|
|||
self,
|
||||
max_tokens: Optional[int] = 0,
|
||||
model_kwargs: NestedDict = {},
|
||||
model_name: str = "gpt-4o",
|
||||
model_name: str = "gpt-3.5-turbo",
|
||||
openai_api_base: Optional[str] = None,
|
||||
openai_api_key: Optional[str] = None,
|
||||
temperature: float = 0.7,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class AstraDBSearchComponent(LCVectorStoreComponent):
|
|||
"info": "The name of the collection within Astra DB where the vectors will be stored.",
|
||||
},
|
||||
"token": {
|
||||
"display_name": "Token",
|
||||
"display_name": "Astra DB Application Token",
|
||||
"info": "Authentication token for accessing Astra DB.",
|
||||
"password": True,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ from typing import List, Optional
|
|||
import chromadb
|
||||
from chromadb.config import Settings
|
||||
from langchain_chroma import Chroma
|
||||
|
||||
from langflow.components.vectorstores.base.model import LCVectorStoreComponent
|
||||
from langflow.field_typing import Embeddings, Text
|
||||
from langflow.schema import Data
|
||||
|
|
@ -104,10 +103,11 @@ class ChromaSearchComponent(LCVectorStoreComponent):
|
|||
client = chromadb.HttpClient(settings=chroma_settings)
|
||||
if index_directory:
|
||||
index_directory = self.resolve_path(index_directory)
|
||||
|
||||
vector_store = Chroma(
|
||||
embedding_function=embedding,
|
||||
collection_name=collection_name,
|
||||
persist_directory=index_directory,
|
||||
persist_directory=index_directory or None,
|
||||
client=client,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class AstraDBVectorStoreComponent(CustomComponent):
|
|||
"info": "The name of the collection within Astra DB where the vectors will be stored.",
|
||||
},
|
||||
"token": {
|
||||
"display_name": "Token",
|
||||
"display_name": "Astra DB Application Token",
|
||||
"info": "Authentication token for accessing Astra DB.",
|
||||
"password": True,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
from typing import Any, Union
|
||||
from enum import Enum
|
||||
from typing import Any, Generator, Union
|
||||
|
||||
from langchain_core.documents import Document
|
||||
from pydantic import BaseModel
|
||||
|
||||
from langflow.interface.utils import extract_input_variables_from_prompt
|
||||
from langflow.schema.message import Message
|
||||
|
||||
|
||||
class UnbuiltObject:
|
||||
|
|
@ -14,6 +16,16 @@ class UnbuiltResult:
|
|||
pass
|
||||
|
||||
|
||||
class ArtifactType(str, Enum):
|
||||
TEXT = "text"
|
||||
RECORD = "record"
|
||||
OBJECT = "object"
|
||||
ARRAY = "array"
|
||||
STREAM = "stream"
|
||||
UNKNOWN = "unknown"
|
||||
MESSAGE = "message"
|
||||
|
||||
|
||||
def validate_prompt(prompt: str):
|
||||
"""Validate prompt."""
|
||||
if extract_input_variables_from_prompt(prompt):
|
||||
|
|
@ -50,3 +62,37 @@ def serialize_field(value):
|
|||
elif isinstance(value, str):
|
||||
return {"result": value}
|
||||
return value
|
||||
|
||||
|
||||
def get_artifact_type(value, build_result) -> str:
|
||||
result = ArtifactType.UNKNOWN
|
||||
match value:
|
||||
case Record():
|
||||
result = ArtifactType.RECORD
|
||||
|
||||
case str():
|
||||
result = ArtifactType.TEXT
|
||||
|
||||
case dict():
|
||||
result = ArtifactType.OBJECT
|
||||
|
||||
case list():
|
||||
result = ArtifactType.ARRAY
|
||||
|
||||
case Message():
|
||||
result = ArtifactType.MESSAGE
|
||||
|
||||
if result == ArtifactType.UNKNOWN:
|
||||
if isinstance(build_result, Generator):
|
||||
result = ArtifactType.STREAM
|
||||
elif isinstance(value, Message) and isinstance(value.text, Generator):
|
||||
result = ArtifactType.STREAM
|
||||
|
||||
return result.value
|
||||
|
||||
|
||||
def post_process_raw(raw, artifact_type: str):
|
||||
if artifact_type == ArtifactType.STREAM.value:
|
||||
raw = ""
|
||||
|
||||
return raw
|
||||
|
|
|
|||
|
|
@ -181,6 +181,9 @@ def update_new_output(data):
|
|||
}
|
||||
)
|
||||
deduplicated_outputs = []
|
||||
if source_node is None:
|
||||
source_node = {"data": {"node": {"outputs": []}}}
|
||||
|
||||
for output in source_node["data"]["node"]["outputs"]:
|
||||
if output["name"] not in [d["name"] for d in deduplicated_outputs]:
|
||||
deduplicated_outputs.append(output)
|
||||
|
|
|
|||
|
|
@ -2,97 +2,73 @@
|
|||
"data": {
|
||||
"edges": [
|
||||
{
|
||||
"className": "stroke-gray-900 stroke-connection",
|
||||
"className": "",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": ["object", "Text", "str"],
|
||||
"dataType": "OpenAIModel",
|
||||
"id": "OpenAIModel-k39HS",
|
||||
"name": "text_output",
|
||||
"output_types": [
|
||||
"Text"
|
||||
]
|
||||
"id": "OpenAIModel-NDBjF"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "input_value",
|
||||
"id": "ChatOutput-njtka",
|
||||
"inputTypes": [
|
||||
"Text",
|
||||
"Message"
|
||||
],
|
||||
"id": "ChatOutput-JkVmc",
|
||||
"inputTypes": ["Text"],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"id": "reactflow__edge-OpenAIModel-k39HS{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-k39HSœ}-ChatOutput-njtka{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-njtkaœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "OpenAIModel-k39HS",
|
||||
"sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-k39HSœ, œoutput_typesœ: [œTextœ], œnameœ: œtext_outputœ}",
|
||||
"id": "reactflow__edge-OpenAIModel-NDBjF{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-NDBjFœ}-ChatOutput-JkVmc{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-JkVmcœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "OpenAIModel-NDBjF",
|
||||
"sourceHandle": "{œbaseClassesœ: [œobjectœ, œTextœ, œstrœ], œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-NDBjFœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "ChatOutput-njtka",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-njtkaœ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
|
||||
"target": "ChatOutput-JkVmc",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-JkVmcœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
|
||||
},
|
||||
{
|
||||
"className": "stroke-gray-900 stroke-connection",
|
||||
"className": "",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": ["object", "str", "Text"],
|
||||
"dataType": "Prompt",
|
||||
"id": "Prompt-uxBqP",
|
||||
"name": "prompt",
|
||||
"output_types": [
|
||||
"Prompt"
|
||||
]
|
||||
"id": "Prompt-WSII4"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "input_value",
|
||||
"id": "OpenAIModel-k39HS",
|
||||
"inputTypes": [
|
||||
"Text",
|
||||
"Data",
|
||||
"Prompt"
|
||||
],
|
||||
"id": "OpenAIModel-NDBjF",
|
||||
"inputTypes": ["Text", "Record", "Prompt"],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"id": "reactflow__edge-Prompt-uxBqP{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-uxBqPœ}-OpenAIModel-k39HS{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-k39HSœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "Prompt-uxBqP",
|
||||
"sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-uxBqPœ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}",
|
||||
"id": "reactflow__edge-Prompt-WSII4{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-WSII4œ}-OpenAIModel-NDBjF{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-NDBjFœ,œinputTypesœ:[œTextœ,œRecordœ,œPromptœ],œtypeœ:œstrœ}",
|
||||
"source": "Prompt-WSII4",
|
||||
"sourceHandle": "{œbaseClassesœ: [œobjectœ, œstrœ, œTextœ], œdataTypeœ: œPromptœ, œidœ: œPrompt-WSII4œ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "OpenAIModel-k39HS",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-k39HSœ, œinputTypesœ: [œTextœ, œDataœ, œPromptœ], œtypeœ: œstrœ}"
|
||||
"target": "OpenAIModel-NDBjF",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-NDBjFœ, œinputTypesœ: [œTextœ, œRecordœ, œPromptœ], œtypeœ: œstrœ}"
|
||||
},
|
||||
{
|
||||
"className": "stroke-gray-900 stroke-connection",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": ["Message", "object", "str", "Text"],
|
||||
"dataType": "ChatInput",
|
||||
"id": "ChatInput-P3fgL",
|
||||
"name": "message",
|
||||
"output_types": [
|
||||
"Message"
|
||||
]
|
||||
"id": "ChatInput-kltLA"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "user_input",
|
||||
"id": "Prompt-uxBqP",
|
||||
"inputTypes": [
|
||||
"Document",
|
||||
"Message",
|
||||
"Record",
|
||||
"Text"
|
||||
],
|
||||
"id": "Prompt-WSII4",
|
||||
"inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"id": "reactflow__edge-ChatInput-P3fgL{œbaseClassesœ:[œobjectœ,œRecordœ,œstrœ,œTextœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-P3fgLœ}-Prompt-uxBqP{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-uxBqPœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "ChatInput-P3fgL",
|
||||
"sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-P3fgLœ, œoutput_typesœ: [œMessageœ], œnameœ: œmessageœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "Prompt-uxBqP",
|
||||
"targetHandle": "{œfieldNameœ: œuser_inputœ, œidœ: œPrompt-uxBqPœ, œinputTypesœ: [œDocumentœ, œMessageœ, œRecordœ, œTextœ], œtypeœ: œstrœ}"
|
||||
"id": "reactflow__edge-ChatInput-kltLA{œbaseClassesœ:[œMessageœ,œobjectœ,œstrœ,œTextœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-kltLAœ}-Prompt-WSII4{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-WSII4œ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "ChatInput-kltLA",
|
||||
"sourceHandle": "{œbaseClassesœ: [œMessageœ, œobjectœ, œstrœ, œTextœ], œdataTypeœ: œChatInputœ, œidœ: œChatInput-kltLAœ}",
|
||||
"target": "Prompt-WSII4",
|
||||
"targetHandle": "{œfieldNameœ: œuser_inputœ, œidœ: œPrompt-WSII4œ, œinputTypesœ: [œDocumentœ, œBaseOutputParserœ, œRecordœ, œTextœ], œtypeœ: œstrœ}"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
|
|
@ -100,18 +76,12 @@
|
|||
"data": {
|
||||
"description": "Create a prompt template with dynamic variables.",
|
||||
"display_name": "Prompt",
|
||||
"id": "Prompt-uxBqP",
|
||||
"id": "Prompt-WSII4",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"object",
|
||||
"str",
|
||||
"Text"
|
||||
],
|
||||
"base_classes": ["object", "str", "Text"],
|
||||
"beta": false,
|
||||
"custom_fields": {
|
||||
"template": [
|
||||
"user_input"
|
||||
]
|
||||
"template": ["user_input"]
|
||||
},
|
||||
"description": "Create a prompt template with dynamic variables.",
|
||||
"display_name": "Prompt",
|
||||
|
|
@ -126,33 +96,9 @@
|
|||
"is_input": null,
|
||||
"is_output": null,
|
||||
"name": "",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Prompt",
|
||||
"method": "build_prompt",
|
||||
"name": "prompt",
|
||||
"selected": "Prompt",
|
||||
"types": [
|
||||
"Prompt"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
},
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Text",
|
||||
"method": "format_prompt",
|
||||
"name": "text",
|
||||
"selected": "Text",
|
||||
"types": [
|
||||
"Text"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
],
|
||||
"output_types": ["Prompt"],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -169,7 +115,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.custom import Component\nfrom langflow.field_typing.prompt import Prompt\nfrom langflow.inputs import PromptInput\nfrom langflow.template import Output\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n kwargs = {k: v for k, v in self._arguments.items() if k != \"template\"}\n prompt = await Prompt.from_template_and_variables(self.template, kwargs)\n self.status = prompt.format_text()\n return prompt\n"
|
||||
"value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import TemplateField\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n"
|
||||
},
|
||||
"template": {
|
||||
"advanced": false,
|
||||
|
|
@ -178,9 +124,7 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -203,7 +147,7 @@
|
|||
"info": "",
|
||||
"input_types": [
|
||||
"Document",
|
||||
"Message",
|
||||
"BaseOutputParser",
|
||||
"Record",
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -224,17 +168,17 @@
|
|||
"type": "Prompt"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 383,
|
||||
"id": "Prompt-uxBqP",
|
||||
"height": 419,
|
||||
"id": "Prompt-WSII4",
|
||||
"position": {
|
||||
"x": 53.588791333410654,
|
||||
"y": -107.07318910019967
|
||||
"x": 18.562420355453696,
|
||||
"y": -284.15095348876025
|
||||
},
|
||||
"positionAbsolute": {
|
||||
"x": 53.588791333410654,
|
||||
"y": -107.07318910019967
|
||||
"x": 18.562420355453696,
|
||||
"y": -284.15095348876025
|
||||
},
|
||||
"selected": true,
|
||||
"selected": false,
|
||||
"type": "genericNode",
|
||||
"width": 384
|
||||
},
|
||||
|
|
@ -242,13 +186,9 @@
|
|||
"data": {
|
||||
"description": "Generates text using OpenAI LLMs.",
|
||||
"display_name": "OpenAI",
|
||||
"id": "OpenAIModel-k39HS",
|
||||
"id": "OpenAIModel-NDBjF",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"object",
|
||||
"Text",
|
||||
"str"
|
||||
],
|
||||
"base_classes": ["object", "Text", "str"],
|
||||
"beta": false,
|
||||
"custom_fields": {
|
||||
"input_value": null,
|
||||
|
|
@ -278,33 +218,9 @@
|
|||
],
|
||||
"frozen": false,
|
||||
"icon": "OpenAI",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Text",
|
||||
"method": "text_response",
|
||||
"name": "text_output",
|
||||
"selected": "Text",
|
||||
"types": [
|
||||
"Text"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
},
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Language Model",
|
||||
"method": "build_model",
|
||||
"name": "model_output",
|
||||
"selected": "BaseLanguageModel",
|
||||
"types": [
|
||||
"BaseLanguageModel"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
],
|
||||
"output_types": ["Text"],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -321,7 +237,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
|
||||
"value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\", \"input_types\": [\"Text\", \"Record\", \"Prompt\"]},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n \"info\": \"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": MODEL_NAMES,\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float = 0.1,\n model_name: str = \"gpt-3.5-turbo\",\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n"
|
||||
},
|
||||
"input_value": {
|
||||
"advanced": false,
|
||||
|
|
@ -330,22 +246,17 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text",
|
||||
"Data",
|
||||
"Prompt"
|
||||
],
|
||||
"input_types": ["Text", "Record", "Prompt"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "input_value",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"max_tokens": {
|
||||
"advanced": true,
|
||||
|
|
@ -354,9 +265,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -366,8 +274,8 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "int",
|
||||
"value": 256
|
||||
},
|
||||
"model_kwargs": {
|
||||
"advanced": true,
|
||||
|
|
@ -376,9 +284,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -388,8 +293,8 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "NestedDict",
|
||||
"value": {}
|
||||
},
|
||||
"model_name": {
|
||||
"advanced": false,
|
||||
|
|
@ -398,9 +303,7 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"input_types": ["Text"],
|
||||
"list": true,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -418,7 +321,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": "gpt-4o"
|
||||
"value": "gpt-3.5-turbo"
|
||||
},
|
||||
"openai_api_base": {
|
||||
"advanced": true,
|
||||
|
|
@ -427,9 +330,7 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -439,8 +340,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"openai_api_key": {
|
||||
"advanced": false,
|
||||
|
|
@ -449,20 +349,18 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "The OpenAI API Key to use for the OpenAI model.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": true,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "openai_api_key",
|
||||
"password": true,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": "OPENAI_API_KEY"
|
||||
"value": ""
|
||||
},
|
||||
"stream": {
|
||||
"advanced": true,
|
||||
|
|
@ -471,9 +369,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Stream the response from the model. Streaming works only in Chat.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -483,7 +378,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"type": "bool",
|
||||
"value": false
|
||||
},
|
||||
"system_message": {
|
||||
|
|
@ -493,9 +388,7 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "System message to pass to the model.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -505,8 +398,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"temperature": {
|
||||
"advanced": false,
|
||||
|
|
@ -515,19 +407,22 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "temperature",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"rangeSpec": {
|
||||
"max": 1,
|
||||
"min": -1,
|
||||
"step": 0.1,
|
||||
"step_type": "float"
|
||||
},
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"type": "float",
|
||||
"value": 0.1
|
||||
}
|
||||
}
|
||||
|
|
@ -535,8 +430,8 @@
|
|||
"type": "OpenAIModel"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 563,
|
||||
"id": "OpenAIModel-k39HS",
|
||||
"height": 571,
|
||||
"id": "OpenAIModel-NDBjF",
|
||||
"position": {
|
||||
"x": 634.8148772766217,
|
||||
"y": 27.035057029045305
|
||||
|
|
@ -551,14 +446,9 @@
|
|||
},
|
||||
{
|
||||
"data": {
|
||||
"id": "ChatOutput-njtka",
|
||||
"id": "ChatOutput-JkVmc",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"Record",
|
||||
"Text",
|
||||
"str",
|
||||
"object"
|
||||
],
|
||||
"base_classes": ["Record", "Text", "str", "object"],
|
||||
"beta": false,
|
||||
"custom_fields": {
|
||||
"input_value": null,
|
||||
|
|
@ -575,22 +465,9 @@
|
|||
"field_order": [],
|
||||
"frozen": false,
|
||||
"icon": "ChatOutput",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Message",
|
||||
"method": "message_response",
|
||||
"name": "message",
|
||||
"selected": "Message",
|
||||
"types": [
|
||||
"Message"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
],
|
||||
"output_types": ["Message", "Text"],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -607,7 +484,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
|
||||
"value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n files: Optional[list[str]] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n files=files,\n return_message=return_message,\n )\n"
|
||||
},
|
||||
"input_value": {
|
||||
"advanced": false,
|
||||
|
|
@ -615,11 +492,8 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Message to be passed as output.",
|
||||
"input_types": [
|
||||
"Text",
|
||||
"Message"
|
||||
],
|
||||
"info": "",
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": true,
|
||||
|
|
@ -629,8 +503,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"sender": {
|
||||
"advanced": true,
|
||||
|
|
@ -638,18 +511,13 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Type of sender.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"info": "",
|
||||
"input_types": ["Text"],
|
||||
"list": true,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "sender",
|
||||
"options": [
|
||||
"Machine",
|
||||
"User"
|
||||
],
|
||||
"options": ["Machine", "User"],
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
|
|
@ -659,15 +527,13 @@
|
|||
"value": "Machine"
|
||||
},
|
||||
"sender_name": {
|
||||
"advanced": true,
|
||||
"advanced": false,
|
||||
"display_name": "Sender Name",
|
||||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Name of the sender.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"info": "",
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -686,10 +552,8 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Session ID for the message.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"info": "If provided, the message will be stored in the memory.",
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -699,23 +563,22 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "ChatOutput"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 383,
|
||||
"id": "ChatOutput-njtka",
|
||||
"height": 391,
|
||||
"id": "ChatOutput-JkVmc",
|
||||
"position": {
|
||||
"x": 1193.250417197867,
|
||||
"y": 71.88476890163852
|
||||
"x": 1183.52086970399,
|
||||
"y": -21.518887039580306
|
||||
},
|
||||
"positionAbsolute": {
|
||||
"x": 1193.250417197867,
|
||||
"y": 71.88476890163852
|
||||
"x": 1183.52086970399,
|
||||
"y": -21.518887039580306
|
||||
},
|
||||
"selected": false,
|
||||
"type": "genericNode",
|
||||
|
|
@ -723,18 +586,14 @@
|
|||
},
|
||||
{
|
||||
"data": {
|
||||
"id": "ChatInput-P3fgL",
|
||||
"id": "ChatInput-kltLA",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"object",
|
||||
"Record",
|
||||
"str",
|
||||
"Text"
|
||||
],
|
||||
"base_classes": ["Message", "object", "str", "Text"],
|
||||
"beta": false,
|
||||
"custom_fields": {
|
||||
"files": null,
|
||||
"input_value": null,
|
||||
"return_record": null,
|
||||
"return_message": null,
|
||||
"sender": null,
|
||||
"sender_name": null,
|
||||
"session_id": null
|
||||
|
|
@ -746,22 +605,9 @@
|
|||
"field_order": [],
|
||||
"frozen": false,
|
||||
"icon": "ChatInput",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Message",
|
||||
"method": "message_response",
|
||||
"name": "message",
|
||||
"selected": "Message",
|
||||
"types": [
|
||||
"Message"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
],
|
||||
"output_types": ["Message", "Text"],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -778,7 +624,49 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n StrInput(\n name=\"sender_name\",\n type=str,\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n StrInput(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
|
||||
"value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n"
|
||||
},
|
||||
"files": {
|
||||
"advanced": true,
|
||||
"display_name": "Files",
|
||||
"dynamic": false,
|
||||
"fileTypes": [
|
||||
".txt",
|
||||
".md",
|
||||
".mdx",
|
||||
".csv",
|
||||
".json",
|
||||
".yaml",
|
||||
".yml",
|
||||
".xml",
|
||||
".html",
|
||||
".htm",
|
||||
".pdf",
|
||||
".docx",
|
||||
".py",
|
||||
".sh",
|
||||
".sql",
|
||||
".js",
|
||||
".ts",
|
||||
".tsx",
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".png",
|
||||
".bmp"
|
||||
],
|
||||
"file_path": "",
|
||||
"info": "Files to be sent with the message.",
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "files",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "file",
|
||||
"value": ""
|
||||
},
|
||||
"input_value": {
|
||||
"advanced": false,
|
||||
|
|
@ -786,7 +674,7 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Message to be passed as input.",
|
||||
"info": "",
|
||||
"input_types": [],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
|
|
@ -798,7 +686,26 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"value": "what do you see?"
|
||||
},
|
||||
"return_message": {
|
||||
"advanced": true,
|
||||
"display_name": "Return Record",
|
||||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "return_message",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "bool",
|
||||
"value": true
|
||||
},
|
||||
"sender": {
|
||||
"advanced": true,
|
||||
|
|
@ -806,18 +713,13 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Type of sender.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"info": "",
|
||||
"input_types": ["Text"],
|
||||
"list": true,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "sender",
|
||||
"options": [
|
||||
"Machine",
|
||||
"User"
|
||||
],
|
||||
"options": ["Machine", "User"],
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
|
|
@ -832,10 +734,8 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Name of the sender.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"info": "",
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -854,10 +754,8 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Session ID for the message.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"info": "If provided, the message will be stored in the memory.",
|
||||
"input_types": ["Text"],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -867,38 +765,37 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "ChatInput"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 375,
|
||||
"id": "ChatInput-P3fgL",
|
||||
"height": 289,
|
||||
"id": "ChatInput-kltLA",
|
||||
"position": {
|
||||
"x": -495.2223093083827,
|
||||
"y": -232.56998443685862
|
||||
"x": -560.3246254009209,
|
||||
"y": -435.0506368105706
|
||||
},
|
||||
"positionAbsolute": {
|
||||
"x": -495.2223093083827,
|
||||
"y": -232.56998443685862
|
||||
"x": -560.3246254009209,
|
||||
"y": -435.0506368105706
|
||||
},
|
||||
"selected": false,
|
||||
"selected": true,
|
||||
"type": "genericNode",
|
||||
"width": 384
|
||||
}
|
||||
],
|
||||
"viewport": {
|
||||
"x": 260.58251815500563,
|
||||
"y": 318.2261172111936,
|
||||
"zoom": 0.43514115784696294
|
||||
"x": 223.38563623650703,
|
||||
"y": 271.96191180648566,
|
||||
"zoom": 0.5138985141032123
|
||||
}
|
||||
},
|
||||
"description": "This flow will get you experimenting with the basics of the UI, the Chat and the Prompt component. \n\nTry changing the Template in it to see how the model behaves. \nYou can change it to this and a Text Input into the `type_of_person` variable : \"Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: \" ",
|
||||
"id": "c091a57f-43a7-4a5e-b352-035ae8d8379c",
|
||||
"id": "ad43b14f-6ec7-496f-9564-aad928603084",
|
||||
"is_component": false,
|
||||
"last_tested_version": "1.0.0a4",
|
||||
"last_tested_version": "1.0.0a52",
|
||||
"name": "Basic Prompting (Hello, World)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
"className": "stroke-gray-900 stroke-connection",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": [
|
||||
"Record"
|
||||
],
|
||||
"dataType": "URL",
|
||||
"id": "URL-HYPkR",
|
||||
"name": "record",
|
||||
"output_types": []
|
||||
"id": "URL-HYPkR"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "reference_2",
|
||||
|
|
@ -25,7 +26,7 @@
|
|||
"id": "reactflow__edge-URL-HYPkR{œbaseClassesœ:[œRecordœ],œdataTypeœ:œURLœ,œidœ:œURL-HYPkRœ}-Prompt-Rse03{œfieldNameœ:œreference_2œ,œidœ:œPrompt-Rse03œ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"selected": false,
|
||||
"source": "URL-HYPkR",
|
||||
"sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-HYPkRœ, œoutput_typesœ: [], œnameœ: œrecordœ}",
|
||||
"sourceHandle": "{œbaseClassesœ: [œRecordœ], œdataTypeœ: œURLœ, œidœ: œURL-HYPkRœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
|
|
@ -36,40 +37,41 @@
|
|||
"className": "stroke-gray-900 stroke-connection",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": [
|
||||
"str",
|
||||
"Text",
|
||||
"object"
|
||||
],
|
||||
"dataType": "OpenAIModel",
|
||||
"id": "OpenAIModel-gi29P",
|
||||
"name": "text_output",
|
||||
"output_types": [
|
||||
"Text"
|
||||
]
|
||||
"id": "OpenAIModel-gi29P"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "input_value",
|
||||
"id": "ChatOutput-JPlxl",
|
||||
"inputTypes": [
|
||||
"Text",
|
||||
"Message"
|
||||
"Text"
|
||||
],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"id": "reactflow__edge-OpenAIModel-gi29P{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-gi29Pœ}-ChatOutput-JPlxl{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-JPlxlœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "OpenAIModel-gi29P",
|
||||
"sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-gi29Pœ, œoutput_typesœ: [œTextœ], œnameœ: œtext_outputœ}",
|
||||
"sourceHandle": "{œbaseClassesœ: [œstrœ, œTextœ, œobjectœ], œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-gi29Pœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "ChatOutput-JPlxl",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-JPlxlœ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-JPlxlœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
|
||||
},
|
||||
{
|
||||
"className": "stroke-gray-900 stroke-connection",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": [
|
||||
"Record"
|
||||
],
|
||||
"dataType": "URL",
|
||||
"id": "URL-2cX90",
|
||||
"name": "record",
|
||||
"output_types": []
|
||||
"id": "URL-2cX90"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "reference_1",
|
||||
|
|
@ -85,7 +87,7 @@
|
|||
},
|
||||
"id": "reactflow__edge-URL-2cX90{œbaseClassesœ:[œRecordœ],œdataTypeœ:œURLœ,œidœ:œURL-2cX90œ}-Prompt-Rse03{œfieldNameœ:œreference_1œ,œidœ:œPrompt-Rse03œ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "URL-2cX90",
|
||||
"sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-2cX90œ, œoutput_typesœ: [], œnameœ: œrecordœ}",
|
||||
"sourceHandle": "{œbaseClassesœ: [œRecordœ], œdataTypeœ: œURLœ, œidœ: œURL-2cX90œ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
|
|
@ -96,12 +98,13 @@
|
|||
"className": "stroke-gray-900 stroke-connection",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": [
|
||||
"object",
|
||||
"Text",
|
||||
"str"
|
||||
],
|
||||
"dataType": "TextInput",
|
||||
"id": "TextInput-og8Or",
|
||||
"name": "Text",
|
||||
"output_types": [
|
||||
"Text"
|
||||
]
|
||||
"id": "TextInput-og8Or"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "instructions",
|
||||
|
|
@ -117,7 +120,7 @@
|
|||
},
|
||||
"id": "reactflow__edge-TextInput-og8Or{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œTextInputœ,œidœ:œTextInput-og8Orœ}-Prompt-Rse03{œfieldNameœ:œinstructionsœ,œidœ:œPrompt-Rse03œ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "TextInput-og8Or",
|
||||
"sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-og8Orœ, œoutput_typesœ: [œTextœ], œnameœ: œTextœ}",
|
||||
"sourceHandle": "{œbaseClassesœ: [œobjectœ, œTextœ, œstrœ], œdataTypeœ: œTextInputœ, œidœ: œTextInput-og8Orœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
|
|
@ -128,19 +131,20 @@
|
|||
"className": "stroke-gray-900 stroke-connection",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": [
|
||||
"object",
|
||||
"Text",
|
||||
"str"
|
||||
],
|
||||
"dataType": "Prompt",
|
||||
"id": "Prompt-Rse03",
|
||||
"name": "prompt",
|
||||
"output_types": [
|
||||
"Prompt"
|
||||
]
|
||||
"id": "Prompt-Rse03"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "input_value",
|
||||
"id": "OpenAIModel-gi29P",
|
||||
"inputTypes": [
|
||||
"Text",
|
||||
"Data",
|
||||
"Record",
|
||||
"Prompt"
|
||||
],
|
||||
"type": "str"
|
||||
|
|
@ -149,12 +153,12 @@
|
|||
"id": "reactflow__edge-Prompt-Rse03{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-Rse03œ}-OpenAIModel-gi29P{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-gi29Pœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
|
||||
"selected": false,
|
||||
"source": "Prompt-Rse03",
|
||||
"sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-Rse03œ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}",
|
||||
"sourceHandle": "{œbaseClassesœ: [œobjectœ, œTextœ, œstrœ], œdataTypeœ: œPromptœ, œidœ: œPrompt-Rse03œ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "OpenAIModel-gi29P",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-gi29Pœ, œinputTypesœ: [œTextœ, œDataœ, œPromptœ], œtypeœ: œstrœ}"
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-gi29Pœ, œinputTypesœ: [œTextœ, œRecordœ, œPromptœ], œtypeœ: œstrœ}"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
|
|
@ -190,33 +194,11 @@
|
|||
"is_input": null,
|
||||
"is_output": null,
|
||||
"name": "",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Prompt",
|
||||
"method": "build_prompt",
|
||||
"name": "prompt",
|
||||
"selected": "Prompt",
|
||||
"types": [
|
||||
"Prompt"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
},
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Text",
|
||||
"method": "format_prompt",
|
||||
"name": "text",
|
||||
"selected": "Text",
|
||||
"types": [
|
||||
"Text"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Prompt"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -233,7 +215,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.custom import Component\nfrom langflow.field_typing.prompt import Prompt\nfrom langflow.inputs import PromptInput\nfrom langflow.template import Output\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n kwargs = {k: v for k, v in self._arguments.items() if k != \"template\"}\n prompt = await Prompt.from_template_and_variables(self.template, kwargs)\n self.status = prompt.format_text()\n return prompt\n"
|
||||
"value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import TemplateField\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n"
|
||||
},
|
||||
"instructions": {
|
||||
"advanced": false,
|
||||
|
|
@ -372,22 +354,11 @@
|
|||
"field_order": [],
|
||||
"frozen": false,
|
||||
"icon": "layout-template",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Data",
|
||||
"method": "fetch_content",
|
||||
"name": "data",
|
||||
"selected": "Data",
|
||||
"types": [
|
||||
"Data"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Record"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -404,22 +375,31 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def fetch_content(self) -> Data:\n urls = [url.strip() for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls)\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
|
||||
"value": "from typing import Any, Dict\n\nfrom langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import CustomComponent\nfrom langflow.schema import Record\n\n\nclass URLComponent(CustomComponent):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n def build_config(self) -> Dict[str, Any]:\n return {\n \"urls\": {\"display_name\": \"URL\"},\n }\n\n def build(\n self,\n urls: list[str],\n ) -> list[Record]:\n loader = WebBaseLoader(web_paths=[url for url in urls if url])\n docs = loader.load()\n records = self.to_records(docs)\n self.status = records\n return records\n"
|
||||
},
|
||||
"urls": {
|
||||
"advanced": false,
|
||||
"display_name": "URLs",
|
||||
"display_name": "URL",
|
||||
"dynamic": false,
|
||||
"info": "Enter one or more URLs, separated by commas.",
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": true,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "urls",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"value": [
|
||||
"https://www.promptingguide.ai/techniques/prompt_chaining"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -466,22 +446,12 @@
|
|||
"field_order": [],
|
||||
"frozen": false,
|
||||
"icon": "ChatOutput",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Message",
|
||||
"method": "message_response",
|
||||
"name": "message",
|
||||
"selected": "Message",
|
||||
"types": [
|
||||
"Message"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Message",
|
||||
"Text"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -498,7 +468,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
|
||||
"value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n files: Optional[list[str]] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n files=files,\n return_message=return_message,\n )\n"
|
||||
},
|
||||
"input_value": {
|
||||
"advanced": false,
|
||||
|
|
@ -506,10 +476,9 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Message to be passed as output.",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text",
|
||||
"Message"
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
|
|
@ -520,8 +489,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"sender": {
|
||||
"advanced": true,
|
||||
|
|
@ -529,7 +497,7 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Type of sender.",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -550,12 +518,12 @@
|
|||
"value": "Machine"
|
||||
},
|
||||
"sender_name": {
|
||||
"advanced": true,
|
||||
"advanced": false,
|
||||
"display_name": "Sender Name",
|
||||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Name of the sender.",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -577,7 +545,7 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Session ID for the message.",
|
||||
"info": "If provided, the message will be stored in the memory.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -590,8 +558,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -645,33 +612,11 @@
|
|||
],
|
||||
"frozen": false,
|
||||
"icon": "OpenAI",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Text",
|
||||
"method": "text_response",
|
||||
"name": "text_output",
|
||||
"selected": "Text",
|
||||
"types": [
|
||||
"Text"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
},
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Language Model",
|
||||
"method": "build_model",
|
||||
"name": "model_output",
|
||||
"selected": "BaseLanguageModel",
|
||||
"types": [
|
||||
"BaseLanguageModel"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Text"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -688,7 +633,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
|
||||
"value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\", \"input_types\": [\"Text\", \"Record\", \"Prompt\"]},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n \"info\": \"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": MODEL_NAMES,\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float = 0.1,\n model_name: str = \"gpt-3.5-turbo\",\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n"
|
||||
},
|
||||
"input_value": {
|
||||
"advanced": false,
|
||||
|
|
@ -699,7 +644,7 @@
|
|||
"info": "",
|
||||
"input_types": [
|
||||
"Text",
|
||||
"Data",
|
||||
"Record",
|
||||
"Prompt"
|
||||
],
|
||||
"list": false,
|
||||
|
|
@ -708,11 +653,10 @@
|
|||
"name": "input_value",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"max_tokens": {
|
||||
"advanced": true,
|
||||
|
|
@ -721,9 +665,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -733,8 +674,8 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "int",
|
||||
"value": "1024"
|
||||
},
|
||||
"model_kwargs": {
|
||||
"advanced": true,
|
||||
|
|
@ -743,9 +684,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -755,8 +693,8 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "NestedDict",
|
||||
"value": {}
|
||||
},
|
||||
"model_name": {
|
||||
"advanced": false,
|
||||
|
|
@ -785,7 +723,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": "gpt-4o"
|
||||
"value": "gpt-3.5-turbo"
|
||||
},
|
||||
"openai_api_base": {
|
||||
"advanced": true,
|
||||
|
|
@ -806,8 +744,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"openai_api_key": {
|
||||
"advanced": false,
|
||||
|
|
@ -825,7 +762,7 @@
|
|||
"name": "openai_api_key",
|
||||
"password": true,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
|
|
@ -838,9 +775,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Stream the response from the model. Streaming works only in Chat.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -850,8 +784,8 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": false
|
||||
"type": "bool",
|
||||
"value": true
|
||||
},
|
||||
"system_message": {
|
||||
"advanced": true,
|
||||
|
|
@ -872,8 +806,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"temperature": {
|
||||
"advanced": false,
|
||||
|
|
@ -882,20 +815,23 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "temperature",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"rangeSpec": {
|
||||
"max": 1,
|
||||
"min": -1,
|
||||
"step": 0.1,
|
||||
"step_type": "float"
|
||||
},
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": 0.1
|
||||
"type": "float",
|
||||
"value": "0.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -934,22 +870,11 @@
|
|||
"field_order": [],
|
||||
"frozen": false,
|
||||
"icon": "layout-template",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Data",
|
||||
"method": "fetch_content",
|
||||
"name": "data",
|
||||
"selected": "Data",
|
||||
"types": [
|
||||
"Data"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Record"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -966,22 +891,31 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.inputs import StrInput\nfrom langflow.schema import Data\nfrom langflow.template import Output\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n inputs = [\n StrInput(\n name=\"urls\",\n display_name=\"URLs\",\n info=\"Enter one or more URLs, separated by commas.\",\n value=\"\",\n is_list=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n ]\n\n def fetch_content(self) -> Data:\n urls = [url.strip() for url in self.urls if url.strip()]\n loader = WebBaseLoader(web_paths=urls)\n docs = loader.load()\n data = [Data(content=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n"
|
||||
"value": "from typing import Any, Dict\n\nfrom langchain_community.document_loaders.web_base import WebBaseLoader\n\nfrom langflow.custom import CustomComponent\nfrom langflow.schema import Record\n\n\nclass URLComponent(CustomComponent):\n display_name = \"URL\"\n description = \"Fetch content from one or more URLs.\"\n icon = \"layout-template\"\n\n def build_config(self) -> Dict[str, Any]:\n return {\n \"urls\": {\"display_name\": \"URL\"},\n }\n\n def build(\n self,\n urls: list[str],\n ) -> list[Record]:\n loader = WebBaseLoader(web_paths=[url for url in urls if url])\n docs = loader.load()\n records = self.to_records(docs)\n self.status = records\n return records\n"
|
||||
},
|
||||
"urls": {
|
||||
"advanced": false,
|
||||
"display_name": "URLs",
|
||||
"display_name": "URL",
|
||||
"dynamic": false,
|
||||
"info": "Enter one or more URLs, separated by commas.",
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": true,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "urls",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"value": [
|
||||
"https://www.promptingguide.ai/introduction/basics"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1026,15 +960,6 @@
|
|||
"output_types": [
|
||||
"Text"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "Text",
|
||||
"selected": "Text",
|
||||
"types": [
|
||||
"Text"
|
||||
]
|
||||
}
|
||||
],
|
||||
"template": {
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
|
|
@ -1131,4 +1056,4 @@
|
|||
"is_component": false,
|
||||
"last_tested_version": "1.0.0a0",
|
||||
"name": "Blog Writer"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2,56 +2,45 @@
|
|||
"data": {
|
||||
"edges": [
|
||||
{
|
||||
"className": "stroke-gray-900 stroke-connection",
|
||||
"className": "",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"dataType": "MemoryComponent",
|
||||
"id": "MemoryComponent-cdA1J",
|
||||
"name": "text",
|
||||
"output_types": [
|
||||
"baseClasses": [
|
||||
"str",
|
||||
"object",
|
||||
"Text"
|
||||
]
|
||||
],
|
||||
"dataType": "OpenAIModel",
|
||||
"id": "OpenAIModel-Neuec"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "context",
|
||||
"id": "Prompt-ODkUx",
|
||||
"fieldName": "input_value",
|
||||
"id": "ChatOutput-cVR7W",
|
||||
"inputTypes": [
|
||||
"Document",
|
||||
"Message",
|
||||
"BaseOutputParser",
|
||||
"Record",
|
||||
"Text"
|
||||
],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"id": "reactflow__edge-MemoryComponent-cdA1J{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-cdA1Jœ}-Prompt-ODkUx{œfieldNameœ:œcontextœ,œidœ:œPrompt-ODkUxœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"selected": false,
|
||||
"source": "MemoryComponent-cdA1J",
|
||||
"sourceHandle": "{œdataTypeœ: œMemoryComponentœ, œidœ: œMemoryComponent-cdA1Jœ, œoutput_typesœ: [œTextœ], œnameœ: œtextœ}",
|
||||
"id": "reactflow__edge-OpenAIModel-Neuec{œbaseClassesœ:[œstrœ,œobjectœ,œTextœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Neuecœ}-ChatOutput-cVR7W{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cVR7Wœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "OpenAIModel-Neuec",
|
||||
"sourceHandle": "{œbaseClassesœ: [œstrœ, œobjectœ, œTextœ], œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-Neuecœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "Prompt-ODkUx",
|
||||
"targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-ODkUxœ, œinputTypesœ: [œDocumentœ, œMessageœ, œRecordœ, œTextœ], œtypeœ: œstrœ}"
|
||||
"target": "ChatOutput-cVR7W",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-cVR7Wœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}"
|
||||
},
|
||||
{
|
||||
"className": "stroke-gray-900 stroke-connection",
|
||||
"className": "",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"dataType": "ChatInput",
|
||||
"id": "ChatInput-t7F8v",
|
||||
"name": "message",
|
||||
"output_types": [
|
||||
"Message"
|
||||
]
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "user_message",
|
||||
"id": "Prompt-ODkUx",
|
||||
"inputTypes": [
|
||||
"Document",
|
||||
"Message",
|
||||
"Record",
|
||||
"baseClasses": [
|
||||
"object",
|
||||
"str",
|
||||
"Text"
|
||||
],
|
||||
"type": "str"
|
||||
|
|
@ -60,109 +49,108 @@
|
|||
"id": "reactflow__edge-ChatInput-t7F8v{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-t7F8vœ}-Prompt-ODkUx{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-ODkUxœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"selected": false,
|
||||
"source": "ChatInput-t7F8v",
|
||||
"sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-t7F8vœ, œoutput_typesœ: [œMessageœ], œnameœ: œmessageœ}",
|
||||
"sourceHandle": "{œbaseClassesœ: [œTextœ, œobjectœ, œRecordœ, œstrœ], œdataTypeœ: œChatInputœ, œidœ: œChatInput-t7F8vœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "Prompt-ODkUx",
|
||||
"targetHandle": "{œfieldNameœ: œuser_messageœ, œidœ: œPrompt-ODkUxœ, œinputTypesœ: [œDocumentœ, œMessageœ, œRecordœ, œTextœ], œtypeœ: œstrœ}"
|
||||
"targetHandle": "{œfieldNameœ: œuser_messageœ, œidœ: œPrompt-ODkUxœ, œinputTypesœ: [œDocumentœ, œBaseOutputParserœ, œRecordœ, œTextœ], œtypeœ: œstrœ}"
|
||||
},
|
||||
{
|
||||
"className": "stroke-gray-900 stroke-connection",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": [
|
||||
"object",
|
||||
"str",
|
||||
"Text"
|
||||
],
|
||||
"dataType": "Prompt",
|
||||
"id": "Prompt-ODkUx",
|
||||
"name": "prompt",
|
||||
"output_types": [
|
||||
"Prompt"
|
||||
]
|
||||
"id": "Prompt-kykM2"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "input_value",
|
||||
"id": "OpenAIModel-9RykF",
|
||||
"id": "OpenAIModel-Neuec",
|
||||
"inputTypes": [
|
||||
"Text",
|
||||
"Data",
|
||||
"Record",
|
||||
"Prompt"
|
||||
],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"id": "reactflow__edge-Prompt-ODkUx{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-ODkUxœ}-OpenAIModel-9RykF{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-9RykFœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "Prompt-ODkUx",
|
||||
"sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-ODkUxœ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "OpenAIModel-9RykF",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-9RykFœ, œinputTypesœ: [œTextœ, œDataœ, œPromptœ], œtypeœ: œstrœ}"
|
||||
"id": "reactflow__edge-Prompt-kykM2{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-kykM2œ}-OpenAIModel-Neuec{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Neuecœ,œinputTypesœ:[œTextœ,œRecordœ,œPromptœ],œtypeœ:œstrœ}",
|
||||
"source": "Prompt-kykM2",
|
||||
"sourceHandle": "{œbaseClassesœ: [œobjectœ, œstrœ, œTextœ], œdataTypeœ: œPromptœ, œidœ: œPrompt-kykM2œ}",
|
||||
"target": "OpenAIModel-Neuec",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-Neuecœ, œinputTypesœ: [œTextœ, œRecordœ, œPromptœ], œtypeœ: œstrœ}"
|
||||
},
|
||||
{
|
||||
"className": "stroke-gray-900 stroke-connection",
|
||||
"className": "",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"dataType": "OpenAIModel",
|
||||
"id": "OpenAIModel-9RykF",
|
||||
"name": "text_output",
|
||||
"output_types": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "input_value",
|
||||
"id": "ChatOutput-P1jEe",
|
||||
"inputTypes": [
|
||||
"baseClasses": [
|
||||
"Text",
|
||||
"Message"
|
||||
"object",
|
||||
"Record",
|
||||
"str"
|
||||
],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"id": "reactflow__edge-OpenAIModel-9RykF{œbaseClassesœ:[œstrœ,œobjectœ,œTextœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-9RykFœ}-ChatOutput-P1jEe{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-P1jEeœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "OpenAIModel-9RykF",
|
||||
"sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-9RykFœ, œoutput_typesœ: [œTextœ], œnameœ: œtext_outputœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
},
|
||||
"target": "ChatOutput-P1jEe",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-P1jEeœ, œinputTypesœ: [œTextœ, œMessageœ], œtypeœ: œstrœ}"
|
||||
},
|
||||
{
|
||||
"className": "stroke-foreground stroke-connection",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"dataType": "MemoryComponent",
|
||||
"id": "MemoryComponent-cdA1J",
|
||||
"name": "text",
|
||||
"output_types": [
|
||||
"Text"
|
||||
]
|
||||
"dataType": "ChatInput",
|
||||
"id": "ChatInput-Z9Rn6"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "input_value",
|
||||
"id": "TextOutput-vrs6T",
|
||||
"fieldName": "UserMessage",
|
||||
"id": "Prompt-kykM2",
|
||||
"inputTypes": [
|
||||
"Document",
|
||||
"Message",
|
||||
"Record",
|
||||
"Text"
|
||||
],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"id": "reactflow__edge-MemoryComponent-cdA1J{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-cdA1Jœ}-TextOutput-vrs6T{œfieldNameœ:œinput_valueœ,œidœ:œTextOutput-vrs6Tœ,œinputTypesœ:[œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "MemoryComponent-cdA1J",
|
||||
"sourceHandle": "{œdataTypeœ: œMemoryComponentœ, œidœ: œMemoryComponent-cdA1Jœ, œoutput_typesœ: [œTextœ], œnameœ: œtextœ}",
|
||||
"style": {
|
||||
"stroke": "#555"
|
||||
"id": "reactflow__edge-ChatInput-Z9Rn6{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z9Rn6œ}-Prompt-kykM2{œfieldNameœ:œUserMessageœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "ChatInput-Z9Rn6",
|
||||
"sourceHandle": "{œbaseClassesœ: [œTextœ, œobjectœ, œRecordœ, œstrœ], œdataTypeœ: œChatInputœ, œidœ: œChatInput-Z9Rn6œ}",
|
||||
"target": "Prompt-kykM2",
|
||||
"targetHandle": "{œfieldNameœ: œUserMessageœ, œidœ: œPrompt-kykM2œ, œinputTypesœ: [œDocumentœ, œMessageœ, œRecordœ, œTextœ], œtypeœ: œstrœ}"
|
||||
},
|
||||
{
|
||||
"className": "",
|
||||
"data": {
|
||||
"sourceHandle": {
|
||||
"baseClasses": [
|
||||
"str",
|
||||
"Text",
|
||||
"object"
|
||||
],
|
||||
"dataType": "MemoryComponent",
|
||||
"id": "MemoryComponent-u6m5G"
|
||||
},
|
||||
"targetHandle": {
|
||||
"fieldName": "Context",
|
||||
"id": "Prompt-kykM2",
|
||||
"inputTypes": [
|
||||
"Document",
|
||||
"Message",
|
||||
"Record",
|
||||
"Text"
|
||||
],
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
"target": "TextOutput-vrs6T",
|
||||
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œTextOutput-vrs6Tœ, œinputTypesœ: [œRecordœ, œTextœ], œtypeœ: œstrœ}"
|
||||
"id": "reactflow__edge-MemoryComponent-u6m5G{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-u6m5Gœ}-Prompt-kykM2{œfieldNameœ:œContextœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}",
|
||||
"source": "MemoryComponent-u6m5G",
|
||||
"sourceHandle": "{œbaseClassesœ: [œstrœ, œTextœ, œobjectœ], œdataTypeœ: œMemoryComponentœ, œidœ: œMemoryComponent-u6m5Gœ}",
|
||||
"target": "Prompt-kykM2",
|
||||
"targetHandle": "{œfieldNameœ: œContextœ, œidœ: œPrompt-kykM2œ, œinputTypesœ: [œDocumentœ, œMessageœ, œRecordœ, œTextœ], œtypeœ: œstrœ}"
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"data": {
|
||||
"id": "ChatInput-t7F8v",
|
||||
"id": "ChatInput-Z9Rn6",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"Text",
|
||||
|
|
@ -185,22 +173,12 @@
|
|||
"field_order": [],
|
||||
"frozen": false,
|
||||
"icon": "ChatInput",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Message",
|
||||
"method": "message_response",
|
||||
"name": "message",
|
||||
"selected": "Message",
|
||||
"types": [
|
||||
"Message"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Message",
|
||||
"Text"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -217,7 +195,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import DropdownInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n StrInput(\n name=\"input_value\",\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n StrInput(\n name=\"sender_name\",\n type=str,\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=\"User\",\n advanced=True,\n ),\n StrInput(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
|
||||
"value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n"
|
||||
},
|
||||
"input_value": {
|
||||
"advanced": false,
|
||||
|
|
@ -225,7 +203,7 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Message to be passed as input.",
|
||||
"info": "",
|
||||
"input_types": [],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
|
|
@ -237,7 +215,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"value": "do you know his name?"
|
||||
},
|
||||
"sender": {
|
||||
"advanced": true,
|
||||
|
|
@ -245,7 +223,7 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Type of sender.",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -266,12 +244,12 @@
|
|||
"value": "User"
|
||||
},
|
||||
"sender_name": {
|
||||
"advanced": true,
|
||||
"advanced": false,
|
||||
"display_name": "Sender Name",
|
||||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Name of the sender.",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -288,12 +266,12 @@
|
|||
"value": "User"
|
||||
},
|
||||
"session_id": {
|
||||
"advanced": true,
|
||||
"advanced": false,
|
||||
"display_name": "Session ID",
|
||||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Session ID for the message.",
|
||||
"info": "If provided, the message will be stored in the memory.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -307,15 +285,15 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"value": "MySessionID"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "ChatInput"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 469,
|
||||
"id": "ChatInput-t7F8v",
|
||||
"height": 477,
|
||||
"id": "ChatInput-Z9Rn6",
|
||||
"position": {
|
||||
"x": 1283.2700598313072,
|
||||
"y": 982.5953650473145
|
||||
|
|
@ -330,7 +308,7 @@
|
|||
},
|
||||
{
|
||||
"data": {
|
||||
"id": "ChatOutput-P1jEe",
|
||||
"id": "ChatOutput-cVR7W",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"Text",
|
||||
|
|
@ -353,22 +331,12 @@
|
|||
"field_order": [],
|
||||
"frozen": false,
|
||||
"icon": "ChatOutput",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Message",
|
||||
"method": "message_response",
|
||||
"name": "message",
|
||||
"selected": "Message",
|
||||
"types": [
|
||||
"Message"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Message",
|
||||
"Text"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -385,7 +353,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput, DropdownInput, MultilineInput, StrInput\nfrom langflow.schema.message import Message\nfrom langflow.template import Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n input_types=[\"Text\", \"Message\"],\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n StrInput(name=\"sender_name\", display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\", advanced=True),\n StrInput(name=\"session_id\", display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True),\n BoolInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n if isinstance(self.input_value, Message):\n message = self.input_value\n else:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, Message) and isinstance(message.text, str):\n self.store_message(message)\n self.status = message\n return message\n"
|
||||
"value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n files: Optional[list[str]] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n files=files,\n return_message=return_message,\n )\n"
|
||||
},
|
||||
"input_value": {
|
||||
"advanced": false,
|
||||
|
|
@ -393,10 +361,9 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Message to be passed as output.",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text",
|
||||
"Message"
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
|
|
@ -407,8 +374,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"sender": {
|
||||
"advanced": true,
|
||||
|
|
@ -416,7 +382,7 @@
|
|||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Type of sender.",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -437,12 +403,12 @@
|
|||
"value": "Machine"
|
||||
},
|
||||
"sender_name": {
|
||||
"advanced": true,
|
||||
"advanced": false,
|
||||
"display_name": "Sender Name",
|
||||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Name of the sender.",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -459,12 +425,12 @@
|
|||
"value": "AI"
|
||||
},
|
||||
"session_id": {
|
||||
"advanced": true,
|
||||
"advanced": false,
|
||||
"display_name": "Session ID",
|
||||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Session ID for the message.",
|
||||
"info": "If provided, the message will be stored in the memory.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
|
|
@ -478,15 +444,15 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"value": "MySessionID"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "ChatOutput"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 477,
|
||||
"id": "ChatOutput-P1jEe",
|
||||
"height": 485,
|
||||
"id": "ChatOutput-cVR7W",
|
||||
"position": {
|
||||
"x": 3154.916355514023,
|
||||
"y": 851.051882666333
|
||||
|
|
@ -503,7 +469,7 @@
|
|||
"data": {
|
||||
"description": "Retrieves stored chat messages given a specific Session ID.",
|
||||
"display_name": "Chat Memory",
|
||||
"id": "MemoryComponent-cdA1J",
|
||||
"id": "MemoryComponent-u6m5G",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"str",
|
||||
|
|
@ -529,20 +495,6 @@
|
|||
"output_types": [
|
||||
"Text"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Text",
|
||||
"hidden": null,
|
||||
"method": null,
|
||||
"name": "text",
|
||||
"selected": "Text",
|
||||
"types": [
|
||||
"Text"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
],
|
||||
"template": {
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
|
|
@ -561,7 +513,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from typing import Optional\n\nfrom langflow.base.memory.memory import BaseMemoryComponent\nfrom langflow.field_typing import Text\nfrom langflow.helpers.data import messages_to_text\nfrom langflow.memory import get_messages\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(BaseMemoryComponent):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages given a specific Session ID.\"\n beta: bool = True\n icon = \"history\"\n\n def build_config(self):\n return {\n \"sender\": {\n \"options\": [\"Machine\", \"User\", \"Machine and User\"],\n \"display_name\": \"Sender Type\",\n },\n \"sender_name\": {\"display_name\": \"Sender Name\", \"advanced\": True},\n \"n_messages\": {\n \"display_name\": \"Number of Messages\",\n \"info\": \"Number of messages to retrieve.\",\n },\n \"session_id\": {\n \"display_name\": \"Session ID\",\n \"info\": \"Session ID of the chat history.\",\n \"input_types\": [\"Text\"],\n },\n \"order\": {\n \"options\": [\"Ascending\", \"Descending\"],\n \"display_name\": \"Order\",\n \"info\": \"Order of the messages.\",\n \"advanced\": True,\n },\n \"data_template\": {\n \"display_name\": \"Data Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n \"advanced\": True,\n },\n }\n\n def get_messages(self, **kwargs) -> list[Message]:\n # Validate kwargs by checking if it contains the correct keys\n if \"sender\" not in kwargs:\n kwargs[\"sender\"] = None\n if \"sender_name\" not in kwargs:\n kwargs[\"sender_name\"] = None\n if \"session_id\" not in kwargs:\n kwargs[\"session_id\"] = None\n if \"limit\" not in kwargs:\n kwargs[\"limit\"] = 5\n if \"order\" not in kwargs:\n kwargs[\"order\"] = \"Descending\"\n\n kwargs[\"order\"] = \"DESC\" if kwargs[\"order\"] == \"Descending\" else \"ASC\"\n if kwargs[\"sender\"] == \"Machine and User\":\n kwargs[\"sender\"] = None\n return get_messages(**kwargs)\n\n def build(\n self,\n sender: Optional[str] = \"Machine and User\",\n sender_name: Optional[str] = None,\n session_id: Optional[str] = None,\n n_messages: int = 5,\n order: Optional[str] = \"Descending\",\n data_template: Optional[str] = \"{sender_name}: {text}\",\n ) -> Text:\n messages = self.get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n messages_str = messages_to_text(template=data_template or \"\", messages=messages)\n self.status = messages_str\n return messages_str\n"
|
||||
"value": "from typing import Optional\n\nfrom langflow.base.memory.memory import BaseMemoryComponent\nfrom langflow.field_typing import Text\nfrom langflow.helpers.record import messages_to_text\nfrom langflow.memory import get_messages\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(BaseMemoryComponent):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages given a specific Session ID.\"\n beta: bool = True\n icon = \"history\"\n\n def build_config(self):\n return {\n \"sender\": {\n \"options\": [\"Machine\", \"User\", \"Machine and User\"],\n \"display_name\": \"Sender Type\",\n },\n \"sender_name\": {\"display_name\": \"Sender Name\", \"advanced\": True},\n \"n_messages\": {\n \"display_name\": \"Number of Messages\",\n \"info\": \"Number of messages to retrieve.\",\n },\n \"session_id\": {\n \"display_name\": \"Session ID\",\n \"info\": \"Session ID of the chat history.\",\n \"input_types\": [\"Text\"],\n },\n \"order\": {\n \"options\": [\"Ascending\", \"Descending\"],\n \"display_name\": \"Order\",\n \"info\": \"Order of the messages.\",\n \"advanced\": True,\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def get_messages(self, **kwargs) -> list[Message]:\n # Validate kwargs by checking if it contains the correct keys\n if \"sender\" not in kwargs:\n kwargs[\"sender\"] = None\n if \"sender_name\" not in kwargs:\n kwargs[\"sender_name\"] = None\n if \"session_id\" not in kwargs:\n kwargs[\"session_id\"] = None\n if \"limit\" not in kwargs:\n kwargs[\"limit\"] = 5\n if \"order\" not in kwargs:\n kwargs[\"order\"] = \"Descending\"\n\n kwargs[\"order\"] = \"DESC\" if kwargs[\"order\"] == \"Descending\" else \"ASC\"\n if kwargs[\"sender\"] == \"Machine and User\":\n kwargs[\"sender\"] = None\n return get_messages(**kwargs)\n\n def build(\n self,\n sender: Optional[str] = \"Machine and User\",\n sender_name: Optional[str] = None,\n session_id: Optional[str] = None,\n n_messages: int = 5,\n order: Optional[str] = \"Descending\",\n record_template: Optional[str] = \"{sender_name}: {text}\",\n ) -> Text:\n messages = self.get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n messages_str = messages_to_text(template=record_template or \"\", messages=messages)\n self.status = messages_str\n return messages_str\n"
|
||||
},
|
||||
"n_messages": {
|
||||
"advanced": false,
|
||||
|
|
@ -608,6 +560,28 @@
|
|||
"type": "str",
|
||||
"value": "Descending"
|
||||
},
|
||||
"record_template": {
|
||||
"advanced": true,
|
||||
"display_name": "Record Template",
|
||||
"dynamic": false,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": true,
|
||||
"name": "record_template",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": "{sender_name}: {text}"
|
||||
},
|
||||
"sender": {
|
||||
"advanced": false,
|
||||
"display_name": "Sender Type",
|
||||
|
|
@ -683,8 +657,8 @@
|
|||
"type": "MemoryComponent"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 489,
|
||||
"id": "MemoryComponent-cdA1J",
|
||||
"height": 505,
|
||||
"id": "MemoryComponent-u6m5G",
|
||||
"position": {
|
||||
"x": 1289.9606870058817,
|
||||
"y": 442.16804561053766
|
||||
|
|
@ -699,20 +673,20 @@
|
|||
},
|
||||
{
|
||||
"data": {
|
||||
"description": "A component for creating prompt templates using dynamic variables.",
|
||||
"description": "Create a prompt template with dynamic variables.",
|
||||
"display_name": "Prompt",
|
||||
"id": "Prompt-ODkUx",
|
||||
"id": "Prompt-kykM2",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"Text",
|
||||
"object",
|
||||
"str",
|
||||
"object"
|
||||
"Text"
|
||||
],
|
||||
"beta": false,
|
||||
"custom_fields": {
|
||||
"template": [
|
||||
"context",
|
||||
"user_message"
|
||||
"Context",
|
||||
"UserMessage"
|
||||
]
|
||||
},
|
||||
"description": "Create a prompt template with dynamic variables.",
|
||||
|
|
@ -728,54 +702,13 @@
|
|||
"is_input": null,
|
||||
"is_output": null,
|
||||
"name": "",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Prompt",
|
||||
"method": "build_prompt",
|
||||
"name": "prompt",
|
||||
"selected": "Prompt",
|
||||
"types": [
|
||||
"Prompt"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
},
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Text",
|
||||
"method": "format_prompt",
|
||||
"name": "text",
|
||||
"selected": "Text",
|
||||
"types": [
|
||||
"Text"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Prompt"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": true,
|
||||
"name": "code",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.custom import Component\nfrom langflow.field_typing.prompt import Prompt\nfrom langflow.inputs import PromptInput\nfrom langflow.template import Output\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n kwargs = {k: v for k, v in self._arguments.items() if k != \"template\"}\n prompt = await Prompt.from_template_and_variables(self.template, kwargs)\n self.status = prompt.format_text()\n return prompt\n"
|
||||
},
|
||||
"context": {
|
||||
"Context": {
|
||||
"advanced": false,
|
||||
"display_name": "context",
|
||||
"display_name": "Context",
|
||||
"dynamic": false,
|
||||
"field_type": "str",
|
||||
"fileTypes": [],
|
||||
|
|
@ -790,7 +723,7 @@
|
|||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": true,
|
||||
"name": "context",
|
||||
"name": "Context",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
|
|
@ -799,14 +732,66 @@
|
|||
"type": "str",
|
||||
"value": ""
|
||||
},
|
||||
"template": {
|
||||
"UserMessage": {
|
||||
"advanced": false,
|
||||
"display_name": "Template",
|
||||
"display_name": "UserMessage",
|
||||
"dynamic": false,
|
||||
"field_type": "str",
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Document",
|
||||
"Message",
|
||||
"Record",
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": true,
|
||||
"name": "UserMessage",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
},
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": true,
|
||||
"name": "code",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import TemplateField\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n"
|
||||
},
|
||||
"template": {
|
||||
"advanced": false,
|
||||
"display_name": "Template",
|
||||
"dynamic": false,
|
||||
"field_type": "str",
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Document",
|
||||
"BaseOutputParser",
|
||||
"Record",
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
|
|
@ -819,56 +804,30 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "prompt",
|
||||
"value": "{context}\n\nUser: {user_message}\nAI: "
|
||||
},
|
||||
"user_message": {
|
||||
"advanced": false,
|
||||
"display_name": "user_message",
|
||||
"dynamic": false,
|
||||
"field_type": "str",
|
||||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Document",
|
||||
"Message",
|
||||
"Record",
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": true,
|
||||
"name": "user_message",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"value": "Previous messages:\n{Context}\n\nUser: {UserMessage}\nAI: "
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "Prompt"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 477,
|
||||
"id": "Prompt-ODkUx",
|
||||
"height": 513,
|
||||
"id": "Prompt-kykM2",
|
||||
"position": {
|
||||
"x": 1894.594426342426,
|
||||
"x": 1890.2582485007167,
|
||||
"y": 753.3797365481901
|
||||
},
|
||||
"positionAbsolute": {
|
||||
"x": 1894.594426342426,
|
||||
"x": 1890.2582485007167,
|
||||
"y": 753.3797365481901
|
||||
},
|
||||
"selected": false,
|
||||
"selected": true,
|
||||
"type": "genericNode",
|
||||
"width": 384
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"id": "OpenAIModel-9RykF",
|
||||
"id": "OpenAIModel-Neuec",
|
||||
"node": {
|
||||
"base_classes": [
|
||||
"str",
|
||||
|
|
@ -904,33 +863,11 @@
|
|||
],
|
||||
"frozen": false,
|
||||
"icon": "OpenAI",
|
||||
"output_types": [],
|
||||
"outputs": [
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Text",
|
||||
"method": "text_response",
|
||||
"name": "text_output",
|
||||
"selected": "Text",
|
||||
"types": [
|
||||
"Text"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
},
|
||||
{
|
||||
"cache": true,
|
||||
"display_name": "Language Model",
|
||||
"method": "build_model",
|
||||
"name": "model_output",
|
||||
"selected": "BaseLanguageModel",
|
||||
"types": [
|
||||
"BaseLanguageModel"
|
||||
],
|
||||
"value": "__UNDEFINED__"
|
||||
}
|
||||
"output_types": [
|
||||
"Text"
|
||||
],
|
||||
"template": {
|
||||
"_type": "Component",
|
||||
"_type": "CustomComponent",
|
||||
"code": {
|
||||
"advanced": true,
|
||||
"dynamic": true,
|
||||
|
|
@ -947,7 +884,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "code",
|
||||
"value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import BaseLanguageModel, Text\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, SecretStrInput, StrInput\nfrom langflow.inputs.inputs import IntInput\nfrom langflow.template import Output\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n inputs = [\n StrInput(name=\"input_value\", display_name=\"Input\", input_types=[\"Text\", \"Data\", \"Prompt\"]),\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n DropdownInput(\n name=\"model_name\", display_name=\"Model Name\", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"openai_api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n BoolInput(name=\"stream\", display_name=\"Stream\", info=STREAM_INFO_TEXT, advanced=True),\n StrInput(\n name=\"system_message\",\n display_name=\"System Message\",\n info=\"System message to pass to the model.\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text_output\", method=\"text_response\"),\n Output(display_name=\"Language Model\", name=\"model_output\", method=\"build_model\"),\n ]\n\n def text_response(self) -> Text:\n input_value = self.input_value\n stream = self.stream\n system_message = self.system_message\n output = self.build_model()\n result = self.get_chat_result(output, stream, input_value, system_message)\n self.status = result\n return result\n\n def build_model(self) -> BaseLanguageModel:\n openai_api_key = self.openai_api_key\n temperature = self.temperature\n model_name = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs or {},\n model=model_name or None,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature or 0.1,\n )\n return output\n"
|
||||
"value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\", \"input_types\": [\"Text\", \"Record\", \"Prompt\"]},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n \"info\": \"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": MODEL_NAMES,\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float = 0.1,\n model_name: str = \"gpt-3.5-turbo\",\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n"
|
||||
},
|
||||
"input_value": {
|
||||
"advanced": false,
|
||||
|
|
@ -958,7 +895,7 @@
|
|||
"info": "",
|
||||
"input_types": [
|
||||
"Text",
|
||||
"Data",
|
||||
"Record",
|
||||
"Prompt"
|
||||
],
|
||||
"list": false,
|
||||
|
|
@ -967,11 +904,10 @@
|
|||
"name": "input_value",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"max_tokens": {
|
||||
"advanced": true,
|
||||
|
|
@ -980,9 +916,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -992,8 +925,8 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "int",
|
||||
"value": 256
|
||||
},
|
||||
"model_kwargs": {
|
||||
"advanced": true,
|
||||
|
|
@ -1002,9 +935,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -1014,8 +944,8 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "NestedDict",
|
||||
"value": {}
|
||||
},
|
||||
"model_name": {
|
||||
"advanced": false,
|
||||
|
|
@ -1044,7 +974,7 @@
|
|||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": "gpt-4o"
|
||||
"value": "gpt-3.5-turbo"
|
||||
},
|
||||
"openai_api_base": {
|
||||
"advanced": true,
|
||||
|
|
@ -1065,8 +995,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"openai_api_key": {
|
||||
"advanced": false,
|
||||
|
|
@ -1084,7 +1013,7 @@
|
|||
"name": "openai_api_key",
|
||||
"password": true,
|
||||
"placeholder": "",
|
||||
"required": false,
|
||||
"required": true,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
|
|
@ -1097,9 +1026,6 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "Stream the response from the model. Streaming works only in Chat.",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
|
|
@ -1109,7 +1035,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"type": "bool",
|
||||
"value": false
|
||||
},
|
||||
"system_message": {
|
||||
|
|
@ -1131,8 +1057,7 @@
|
|||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": ""
|
||||
"type": "str"
|
||||
},
|
||||
"temperature": {
|
||||
"advanced": false,
|
||||
|
|
@ -1141,28 +1066,31 @@
|
|||
"fileTypes": [],
|
||||
"file_path": "",
|
||||
"info": "",
|
||||
"input_types": [
|
||||
"Text"
|
||||
],
|
||||
"list": false,
|
||||
"load_from_db": false,
|
||||
"multiline": false,
|
||||
"name": "temperature",
|
||||
"password": false,
|
||||
"placeholder": "",
|
||||
"rangeSpec": {
|
||||
"max": 1,
|
||||
"min": -1,
|
||||
"step": 0.1,
|
||||
"step_type": "float"
|
||||
},
|
||||
"required": false,
|
||||
"show": true,
|
||||
"title_case": false,
|
||||
"type": "str",
|
||||
"value": 0.1
|
||||
"type": "float",
|
||||
"value": "0.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "OpenAIModel"
|
||||
},
|
||||
"dragging": false,
|
||||
"height": 563,
|
||||
"id": "OpenAIModel-9RykF",
|
||||
"height": 571,
|
||||
"id": "OpenAIModel-Neuec",
|
||||
"position": {
|
||||
"x": 2561.5850334731617,
|
||||
"y": 553.2745131130916
|
||||
|
|
@ -1285,16 +1213,14 @@
|
|||
}
|
||||
],
|
||||
"viewport": {
|
||||
"x": -569.862554459756,
|
||||
"y": -42.08339711050985,
|
||||
"zoom": 0.4868590524514978
|
||||
"x": -511.79726701119625,
|
||||
"y": 49.514712353620894,
|
||||
"zoom": 0.4612356948928673
|
||||
}
|
||||
},
|
||||
"description": "This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.",
|
||||
"icon": "🤖",
|
||||
"icon_bg_color": "#FFD700",
|
||||
"id": "08d5cccf-d098-4367-b14b-1078429c9ed9",
|
||||
"id": "321b1bab-8691-42da-9689-1f12b5d2a48b",
|
||||
"is_component": false,
|
||||
"last_tested_version": "1.0.0a0",
|
||||
"last_tested_version": "1.0.0a54",
|
||||
"name": "Memory Chatbot"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -160,7 +160,7 @@ async def build_custom_component(params: dict, custom_component: "CustomComponen
|
|||
if raw is None and isinstance(build_result, (dict, Data, str)):
|
||||
raw = build_result.data if isinstance(build_result, Data) else build_result
|
||||
|
||||
artifact_type = get_artifact_type(custom_component.repr_value or raw, build_result)
|
||||
artifact_type = get_artifact_type(custom_component or raw, build_result)
|
||||
raw = post_process_raw(raw, artifact_type)
|
||||
artifact = {"repr": custom_repr, "raw": raw, "type": artifact_type}
|
||||
return custom_component, build_result, artifact
|
||||
|
|
|
|||
|
|
@ -91,9 +91,17 @@ class MessageModel(DefaultModel):
|
|||
files: list[str] = []
|
||||
|
||||
@field_validator("files", mode="before")
|
||||
@classmethod
|
||||
def validate_files(cls, v):
|
||||
if isinstance(v, str):
|
||||
return json.loads(v)
|
||||
v = json.loads(v)
|
||||
return v
|
||||
|
||||
@field_serializer("files")
|
||||
@classmethod
|
||||
def serialize_files(cls, v):
|
||||
if isinstance(v, list):
|
||||
return json.dumps(v)
|
||||
return v
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@ from pathlib import Path
|
|||
from typing import TYPE_CHECKING, List, Optional, Union
|
||||
|
||||
import duckdb
|
||||
from loguru import logger
|
||||
from platformdirs import user_cache_dir
|
||||
|
||||
from langflow.services.base import Service
|
||||
from langflow.services.monitor.schema import MessageModel, TransactionModel, VertexBuildModel
|
||||
from langflow.services.monitor.utils import add_row_to_table, drop_and_create_table_if_schema_mismatch
|
||||
from loguru import logger
|
||||
from platformdirs import user_cache_dir
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langflow.services.settings.manager import SettingsService
|
||||
|
|
@ -141,7 +140,7 @@ class MonitorService(Service):
|
|||
order: Optional[str] = "DESC",
|
||||
limit: Optional[int] = None,
|
||||
):
|
||||
query = "SELECT index, flow_id, sender_name, sender, session_id, text, timestamp FROM messages"
|
||||
query = "SELECT index, flow_id, sender_name, sender, session_id, text, files, timestamp FROM messages"
|
||||
conditions = []
|
||||
if sender:
|
||||
conditions.append(f"sender = '{sender}'")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "langflow-base"
|
||||
version = "0.0.63"
|
||||
version = "0.0.66"
|
||||
description = "A Python package with a built-in web application"
|
||||
authors = ["Langflow <contact@langflow.org>"]
|
||||
maintainers = [
|
||||
|
|
|
|||
963
src/frontend/package-lock.json
generated
963
src/frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -85,9 +85,6 @@
|
|||
"format": "npx prettier --write \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore",
|
||||
"type-check": "tsc --noEmit --pretty --project tsconfig.json && vite"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
"pre-commit": "npx pretty-quick --staged"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
|
|
@ -130,7 +127,6 @@
|
|||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-organize-imports": "^3.2.3",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"pretty-quick": "^3.1.3",
|
||||
"simple-git-hooks": "^2.11.1",
|
||||
"tailwindcss": "^3.3.3",
|
||||
"tailwindcss-dotted-background": "^1.1.0",
|
||||
|
|
@ -138,4 +134,4 @@
|
|||
"ua-parser-js": "^1.0.37",
|
||||
"vite": "^4.5.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -80,7 +80,6 @@ export default function App() {
|
|||
login(user["access_token"]);
|
||||
setUserData(user);
|
||||
setAutoLogin(true);
|
||||
setLoading(false);
|
||||
fetchAllData();
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { cloneDeep } from "lodash";
|
||||
import { ReactNode, useEffect, useRef, useState } from "react";
|
||||
import { useHotkeys } from "react-hotkeys-hook";
|
||||
import { Handle, Position, useUpdateNodeInternals } from "reactflow";
|
||||
import CodeAreaComponent from "../../../../components/codeAreaComponent";
|
||||
import DictComponent from "../../../../components/dictComponent";
|
||||
|
|
@ -18,7 +17,10 @@ import TextAreaComponent from "../../../../components/textAreaComponent";
|
|||
import ToggleShadComponent from "../../../../components/toggleShadComponent";
|
||||
import { Button } from "../../../../components/ui/button";
|
||||
import { RefreshButton } from "../../../../components/ui/refreshButton";
|
||||
import { LANGFLOW_SUPPORTED_TYPES } from "../../../../constants/constants";
|
||||
import {
|
||||
LANGFLOW_SUPPORTED_TYPES,
|
||||
TOOLTIP_EMPTY,
|
||||
} from "../../../../constants/constants";
|
||||
import { Case } from "../../../../shared/components/caseComponent";
|
||||
import useFlowStore from "../../../../stores/flowStore";
|
||||
import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
|
||||
|
|
@ -49,8 +51,10 @@ import useHandleNodeClass from "../../../hooks/use-handle-node-class";
|
|||
import useHandleRefreshButtonPress from "../../../hooks/use-handle-refresh-buttons";
|
||||
import HandleTooltips from "../HandleTooltipComponent";
|
||||
import OutputComponent from "../OutputComponent";
|
||||
import OutputModal from "../outputModal";
|
||||
import TooltipRenderComponent from "../tooltipRenderComponent";
|
||||
import { TEXT_FIELD_TYPES } from "./constants";
|
||||
import OutputModal from "../outputModal";
|
||||
import { useHotkeys } from "react-hotkeys-hook";
|
||||
|
||||
export default function ParameterComponent({
|
||||
left,
|
||||
|
|
@ -71,6 +75,8 @@ export default function ParameterComponent({
|
|||
selected,
|
||||
outputProxy,
|
||||
}: ParameterComponentType): JSX.Element {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const refHtml = useRef<HTMLDivElement & ReactNode>(null);
|
||||
const infoHtml = useRef<HTMLDivElement & ReactNode>(null);
|
||||
const currentFlow = useFlowsManagerStore((state) => state.currentFlow);
|
||||
const nodes = useFlowStore((state) => state.nodes);
|
||||
|
|
@ -81,13 +87,16 @@ export default function ParameterComponent({
|
|||
const [isLoading, setIsLoading] = useState(false);
|
||||
const updateNodeInternals = useUpdateNodeInternals();
|
||||
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
|
||||
const flow = currentFlow?.data?.nodes ?? null;
|
||||
const groupedEdge = useRef(null);
|
||||
const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
|
||||
const [openOutputModal, setOpenOutputModal] = useState(false);
|
||||
const flowPool = useFlowStore((state) => state.flowPool);
|
||||
|
||||
const isValid =
|
||||
const displayOutputPreview =
|
||||
!!flowPool[data.id] &&
|
||||
flowPool[data.id][flowPool[data.id].length - 1]?.valid;
|
||||
flowPool[data.id][flowPool[data.id].length - 1]?.valid &&
|
||||
flowPool[data.id][flowPool[data.id].length - 1]?.data?.logs[0]?.message;
|
||||
|
||||
const flowPoolNode = (flowPool[data.id] ?? [])[
|
||||
(flowPool[data.id]?.length ?? 1) - 1
|
||||
|
|
@ -96,7 +105,6 @@ export default function ParameterComponent({
|
|||
if (flowPoolNode?.data?.logs && outputName) {
|
||||
hasOutputs = flowPoolNode?.data?.logs[outputName] ?? null;
|
||||
}
|
||||
const displayOutputPreview = isValid && hasOutputs;
|
||||
const unknownOutput = !!(
|
||||
flowPool[data.id] &&
|
||||
flowPool[data.id][flowPool[data.id].length - 1]?.data?.logs[0]?.type ===
|
||||
|
|
@ -157,7 +165,7 @@ export default function ParameterComponent({
|
|||
|
||||
const handleOnNewValue = async (
|
||||
newValue: string | string[] | boolean | Object[],
|
||||
skipSnapshot: boolean | undefined = false
|
||||
skipSnapshot: boolean | undefined = false,
|
||||
): Promise<void> => {
|
||||
handleOnNewValueHook(newValue, skipSnapshot);
|
||||
};
|
||||
|
|
@ -270,7 +278,7 @@ export default function ParameterComponent({
|
|||
className={classNames(
|
||||
left ? "my-12 -ml-0.5 " : " my-12 -mr-0.5 ",
|
||||
"h-3 w-3 rounded-full border-2 bg-background",
|
||||
!showNode ? "mt-0" : ""
|
||||
!showNode ? "mt-0" : "",
|
||||
)}
|
||||
style={{
|
||||
borderColor: color ?? nodeColors.unknown,
|
||||
|
|
@ -287,6 +295,7 @@ export default function ParameterComponent({
|
|||
)
|
||||
) : (
|
||||
<div
|
||||
ref={ref}
|
||||
className={
|
||||
"relative mt-1 flex w-full flex-wrap items-center justify-between bg-muted px-5 py-2" +
|
||||
((name === "code" && type === "code") ||
|
||||
|
|
|
|||
|
|
@ -458,10 +458,11 @@ export default function GenericNode({
|
|||
.filter((templateField) => templateField.charAt(0) !== "_")
|
||||
.map(
|
||||
(templateField: string, idx) =>
|
||||
data.node!.template[templateField].show &&
|
||||
!data.node!.template[templateField].advanced && (
|
||||
data.node!.template[templateField]?.show &&
|
||||
!data.node!.template[templateField]?.advanced && (
|
||||
<ParameterComponent
|
||||
index={idx}
|
||||
selected={selected}
|
||||
index={idx.toString()}
|
||||
key={scapedJSONStringfy({
|
||||
inputTypes:
|
||||
data.node!.template[templateField].input_types,
|
||||
|
|
@ -545,7 +546,7 @@ export default function GenericNode({
|
|||
title={
|
||||
data.node?.output_types &&
|
||||
data.node.output_types.length > 0
|
||||
? data.node.output_types.join("|")
|
||||
? data.node.output_types.join(" | ")
|
||||
: data.type
|
||||
}
|
||||
tooltipTitle={data.node?.base_classes.join("\n")}
|
||||
|
|
@ -718,10 +719,11 @@ export default function GenericNode({
|
|||
.sort((a, b) => sortFields(a, b, data.node?.field_order ?? []))
|
||||
.map((templateField: string, idx) => (
|
||||
<div key={idx}>
|
||||
{data.node!.template[templateField].show &&
|
||||
!data.node!.template[templateField].advanced ? (
|
||||
{data.node!.template[templateField]?.show &&
|
||||
!data.node!.template[templateField]?.advanced ? (
|
||||
<ParameterComponent
|
||||
index={idx}
|
||||
selected={selected}
|
||||
index={idx.toString()}
|
||||
key={scapedJSONStringfy({
|
||||
inputTypes:
|
||||
data.node!.template[templateField].input_types,
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ export function countHandlesFn(data: NodeDataType): number {
|
|||
.filter((templateField) => templateField.charAt(0) !== "_")
|
||||
.map((templateCamp) => {
|
||||
const { template } = data.node!;
|
||||
if (template[templateCamp].input_types) return true;
|
||||
if (!template[templateCamp].show) return false;
|
||||
switch (template[templateCamp].type) {
|
||||
if (template[templateCamp]?.input_types) return true;
|
||||
if (!template[templateCamp]?.show) return false;
|
||||
switch (template[templateCamp]?.type) {
|
||||
case "str":
|
||||
case "bool":
|
||||
case "float":
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { cloneDeep } from "lodash";
|
||||
import { useEffect } from "react";
|
||||
import {
|
||||
ERROR_UPDATING_COMPONENT,
|
||||
TITLE_ERROR_UPDATING_COMPONENT,
|
||||
} from "../../constants/constants";
|
||||
import useAlertStore from "../../stores/alertStore";
|
||||
import { ResponseErrorDetailAPI } from "../../types/api";
|
||||
|
||||
|
|
@ -38,8 +42,10 @@ const useFetchDataOnMount = (
|
|||
let responseError = error as ResponseErrorDetailAPI;
|
||||
|
||||
setErrorData({
|
||||
title: "Error while updating the Component",
|
||||
list: [responseError?.response?.data?.detail ?? "Unknown error"],
|
||||
title: TITLE_ERROR_UPDATING_COMPONENT,
|
||||
list: [
|
||||
responseError?.response?.data?.detail ?? ERROR_UPDATING_COMPONENT,
|
||||
],
|
||||
});
|
||||
}
|
||||
setIsLoading(false);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import { cloneDeep } from "lodash";
|
||||
import {
|
||||
ERROR_UPDATING_COMPONENT,
|
||||
TITLE_ERROR_UPDATING_COMPONENT,
|
||||
} from "../../constants/constants";
|
||||
import useAlertStore from "../../stores/alertStore";
|
||||
import { ResponseErrorTypeAPI } from "../../types/api";
|
||||
|
||||
|
|
@ -42,9 +46,10 @@ const useHandleOnNewValue = (
|
|||
} catch (error) {
|
||||
let responseError = error as ResponseErrorTypeAPI;
|
||||
setErrorData({
|
||||
title: "Error while updating the Component",
|
||||
title: TITLE_ERROR_UPDATING_COMPONENT,
|
||||
list: [
|
||||
responseError?.response?.data?.detail.error ?? "Unknown error",
|
||||
responseError?.response?.data?.detail.error ??
|
||||
ERROR_UPDATING_COMPONENT,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import { cloneDeep } from "lodash";
|
||||
import {
|
||||
ERROR_UPDATING_COMPONENT,
|
||||
TITLE_ERROR_UPDATING_COMPONENT,
|
||||
} from "../../constants/constants";
|
||||
import useAlertStore from "../../stores/alertStore";
|
||||
import { ResponseErrorDetailAPI } from "../../types/api";
|
||||
import { handleUpdateValues } from "../../utils/parameterUtils";
|
||||
|
|
@ -25,8 +29,10 @@ const useHandleRefreshButtonPress = (setIsLoading, setNode) => {
|
|||
let responseError = error as ResponseErrorDetailAPI;
|
||||
|
||||
setErrorData({
|
||||
title: "Error while updating the Component",
|
||||
list: [responseError?.response?.data?.detail ?? "Unknown error"],
|
||||
title: TITLE_ERROR_UPDATING_COMPONENT,
|
||||
list: [
|
||||
responseError?.response?.data?.detail ?? ERROR_UPDATING_COMPONENT,
|
||||
],
|
||||
});
|
||||
}
|
||||
setIsLoading(false);
|
||||
|
|
|
|||
|
|
@ -70,7 +70,10 @@ export default function AddNewVariableButton({
|
|||
let responseError = error as ResponseErrorDetailAPI;
|
||||
setErrorData({
|
||||
title: "Error creating variable",
|
||||
list: [responseError?.response?.data?.detail ?? "Unknown error"],
|
||||
list: [
|
||||
responseError?.response?.data?.detail ??
|
||||
"An unexpected error occurred while adding a new variable. Please try again.",
|
||||
],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export default function Header(): JSX.Element {
|
|||
const location = useLocation();
|
||||
|
||||
const { logout, autoLogin, isAdmin, userData } = useContext(AuthContext);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const removeFlow = useFlowsManagerStore((store) => store.removeFlow);
|
||||
const hasStore = useStoreStore((state) => state.hasStore);
|
||||
|
|
@ -208,7 +209,7 @@ export default function Header(): JSX.Element {
|
|||
0,
|
||||
BACKEND_URL.length - 1
|
||||
)}${BASE_URL_API}files/profile_pictures/${
|
||||
userData?.profile_image ?? "Space/046-rocket.png"
|
||||
userData?.profile_image ?? "Space/046-rocket.svg"
|
||||
}` ?? profileCircle
|
||||
}
|
||||
className="h-7 w-7 shrink-0 focus-visible:outline-0"
|
||||
|
|
@ -226,7 +227,7 @@ export default function Header(): JSX.Element {
|
|||
0,
|
||||
BACKEND_URL.length - 1
|
||||
)}${BASE_URL_API}files/profile_pictures/${
|
||||
userData?.profile_image
|
||||
userData?.profile_image ?? "Space/046-rocket.svg"
|
||||
}` ?? profileCircle
|
||||
}
|
||||
className="h-5 w-5 focus-visible:outline-0 "
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export default function InputListComponent({
|
|||
<div
|
||||
className={classNames(
|
||||
value.length > 1 && editNode ? "my-1" : "",
|
||||
"flex flex-col gap-3",
|
||||
"flex flex-col gap-3"
|
||||
)}
|
||||
>
|
||||
{value.map((singleValue, idx) => {
|
||||
|
|
|
|||
|
|
@ -853,3 +853,8 @@ export const ALLOWED_IMAGE_INPUT_EXTENSIONS = ["png", "jpg", "jpeg"];
|
|||
export const FS_ERROR_TEXT =
|
||||
"Please ensure your file has one of the following extensions:";
|
||||
export const SN_ERROR_TEXT = ALLOWED_IMAGE_INPUT_EXTENSIONS.join(", ");
|
||||
|
||||
export const ERROR_UPDATING_COMPONENT =
|
||||
"An unexpected error occurred while updating the Component. Please try again.";
|
||||
export const TITLE_ERROR_UPDATING_COMPONENT =
|
||||
"Error while updating the Component";
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export function AuthProvider({ children }): React.ReactElement {
|
|||
const [apiKey, setApiKey] = useState<string | null>(
|
||||
cookies.get("apikey_tkn_lflw")
|
||||
);
|
||||
// const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
|
||||
|
||||
useEffect(() => {
|
||||
const storedAccessToken = cookies.get("access_token_lf");
|
||||
|
|
@ -59,11 +60,11 @@ export function AuthProvider({ children }): React.ReactElement {
|
|||
|
||||
function getUser() {
|
||||
getLoggedUser()
|
||||
.then((user) => {
|
||||
.then(async (user) => {
|
||||
setUserData(user);
|
||||
setLoading(false);
|
||||
const isSuperUser = user!.is_superuser;
|
||||
setIsAdmin(isSuperUser);
|
||||
// await getFoldersApi(true);
|
||||
})
|
||||
.catch((error) => {
|
||||
setLoading(false);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import CsvOutputComponent from "../../../../components/csvOutputComponent";
|
|||
import DataOutputComponent from "../../../../components/dataOutputComponent";
|
||||
import InputListComponent from "../../../../components/inputListComponent";
|
||||
import PdfViewer from "../../../../components/pdfViewer";
|
||||
import RecordsOutputComponent from "../../../../components/recordsOutputComponent";
|
||||
import { Textarea } from "../../../../components/ui/textarea";
|
||||
import { PDFViewConstant } from "../../../../constants/constants";
|
||||
import { InputOutput } from "../../../../constants/enums";
|
||||
|
|
@ -253,7 +254,7 @@ export default function IOFieldView({
|
|||
rows={
|
||||
Array.isArray(flowPoolNode?.data?.artifacts)
|
||||
? flowPoolNode?.data?.artifacts?.map(
|
||||
(artifact) => artifact.data
|
||||
(artifact) => artifact.data,
|
||||
) ?? []
|
||||
: [flowPoolNode?.data?.artifacts]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default function SessionView({ rows }: { rows: Array<any> }) {
|
|||
setSelectedRows,
|
||||
setSuccessData,
|
||||
setErrorData,
|
||||
selectedRows,
|
||||
selectedRows
|
||||
);
|
||||
|
||||
const { handleUpdate } = useUpdateMessage(setSuccessData, setErrorData);
|
||||
|
|
|
|||
|
|
@ -36,12 +36,6 @@ export default function ChatView({
|
|||
const outputTypes = outputs.map((obj) => obj.type);
|
||||
const updateFlowPool = useFlowStore((state) => state.updateFlowPool);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (!outputTypes.includes("ChatOutput")) {
|
||||
// setNoticeData({ title: NOCHATOUTPUT_NOTICE_ALERT });
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
//build chat history
|
||||
useEffect(() => {
|
||||
const chatOutputResponses: VertexBuildTypeAPI[] = [];
|
||||
|
|
@ -62,14 +56,24 @@ export default function ChatView({
|
|||
const chatMessages: ChatMessageType[] = chatOutputResponses
|
||||
.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp))
|
||||
//
|
||||
.filter((output) => output.data.message)
|
||||
.filter(
|
||||
(output) =>
|
||||
output.data.message || (!output.data.message && output.artifacts)
|
||||
)
|
||||
.map((output, index) => {
|
||||
try {
|
||||
console.log("output:", output);
|
||||
|
||||
const messageOutput = output.data.message;
|
||||
const hasMessageValue =
|
||||
messageOutput?.message ||
|
||||
messageOutput?.message === "" ||
|
||||
(messageOutput?.files ?? []).length > 0 ||
|
||||
messageOutput?.stream_url;
|
||||
|
||||
const { sender, message, sender_name, stream_url, files } =
|
||||
output.data.message;
|
||||
console.log("output.data.message:", output.data.message);
|
||||
console.log("output.data.message.files:", output.data.message.files);
|
||||
hasMessageValue ? output.data.message : output.artifacts;
|
||||
|
||||
const is_ai =
|
||||
sender === "Machine" || sender === null || sender === undefined;
|
||||
return {
|
||||
|
|
@ -136,26 +140,12 @@ export default function ChatView({
|
|||
message: string,
|
||||
stream_url?: string
|
||||
) {
|
||||
// if (message === "") return;
|
||||
chat.message = message;
|
||||
// chat is one of the chatHistory
|
||||
updateFlowPool(chat.componentId, {
|
||||
message,
|
||||
sender_name: chat.sender_name ?? "Bot",
|
||||
sender: chat.isSend ? "User" : "Machine",
|
||||
});
|
||||
// setChatHistory((oldChatHistory) => {
|
||||
// const index = oldChatHistory.findIndex((ch) => ch.id === chat.id);
|
||||
// if (index === -1) return oldChatHistory;
|
||||
// let newChatHistory = _.cloneDeep(oldChatHistory);
|
||||
// newChatHistory = [
|
||||
// ...newChatHistory.slice(0, index),
|
||||
// chat,
|
||||
// ...newChatHistory.slice(index + 1),
|
||||
// ];
|
||||
// console.log("newChatHistory:", newChatHistory);
|
||||
// return newChatHistory;
|
||||
// });
|
||||
}
|
||||
const [files, setFiles] = useState<FilePreviewType[]>([]);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
|
|
@ -190,44 +180,6 @@ export default function ChatView({
|
|||
aria-hidden="true"
|
||||
/>
|
||||
</Button>
|
||||
{/* <Select
|
||||
onValueChange={handleSelectChange}
|
||||
value=""
|
||||
disabled={lockChat}
|
||||
>
|
||||
<SelectTrigger className="">
|
||||
<button className="flex gap-1">
|
||||
<IconComponent
|
||||
name="Eraser"
|
||||
className={classNames(
|
||||
"h-5 w-5 transition-all duration-100",
|
||||
lockChat ? "animate-pulse text-primary" : "text-primary",
|
||||
)}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
</SelectTrigger>
|
||||
<SelectContent className="right-[9.5em]">
|
||||
<SelectItem value="builds" className="cursor-pointer">
|
||||
<div className="flex">
|
||||
<IconComponent
|
||||
name={"Trash2"}
|
||||
className={`relative top-0.5 mr-2 h-4 w-4`}
|
||||
/>
|
||||
<span className="">Clear Builds</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
<SelectItem value="buildsNSession" className="cursor-pointer">
|
||||
<div className="flex">
|
||||
<IconComponent
|
||||
name={"Trash2"}
|
||||
className={`relative top-0.5 mr-2 h-4 w-4`}
|
||||
/>
|
||||
<span className="">Clear Builds & Session</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select> */}
|
||||
</div>
|
||||
<div ref={messagesRef} className="chat-message-div">
|
||||
{chatHistory?.length > 0 ? (
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import IconComponent from "../../components/genericIconComponent";
|
|||
import { EXPORT_CODE_DIALOG } from "../../constants/constants";
|
||||
import { AuthContext } from "../../contexts/authContext";
|
||||
import { useTweaksStore } from "../../stores/tweaksStore";
|
||||
import { InputFieldType } from "../../types/api";
|
||||
import { TemplateVariableType } from "../../types/api";
|
||||
import { uniqueTweakType } from "../../types/components";
|
||||
import { FlowType } from "../../types/flow/index";
|
||||
import BaseModal from "../baseModal";
|
||||
|
|
@ -39,7 +39,7 @@ const ApiModal = forwardRef(
|
|||
open?: boolean;
|
||||
setOpen?: (a: boolean | ((o?: boolean) => boolean)) => void;
|
||||
},
|
||||
ref
|
||||
ref,
|
||||
) => {
|
||||
const tweak = useTweaksStore((state) => state.tweak);
|
||||
const addTweaks = useTweaksStore((state) => state.setTweak);
|
||||
|
|
@ -57,18 +57,18 @@ const ApiModal = forwardRef(
|
|||
flow?.id,
|
||||
autoLogin,
|
||||
tweak,
|
||||
flow?.endpoint_name
|
||||
flow?.endpoint_name,
|
||||
);
|
||||
const curl_run_code = getCurlRunCode(
|
||||
flow?.id,
|
||||
autoLogin,
|
||||
tweak,
|
||||
flow?.endpoint_name
|
||||
flow?.endpoint_name,
|
||||
);
|
||||
const curl_webhook_code = getCurlWebhookCode(
|
||||
flow?.id,
|
||||
autoLogin,
|
||||
flow?.endpoint_name
|
||||
flow?.endpoint_name,
|
||||
);
|
||||
const pythonCode = getPythonCode(flow?.name, tweak);
|
||||
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
||||
|
|
@ -83,7 +83,7 @@ const ApiModal = forwardRef(
|
|||
pythonCode,
|
||||
];
|
||||
const [tabs, setTabs] = useState(
|
||||
createTabsArray(codesArray, includeWebhook)
|
||||
createTabsArray(codesArray, includeWebhook),
|
||||
);
|
||||
|
||||
const canShowTweaks =
|
||||
|
|
@ -132,7 +132,7 @@ const ApiModal = forwardRef(
|
|||
buildTweakObject(
|
||||
nodeId,
|
||||
element.data.node.template[templateField].value,
|
||||
element.data.node.template[templateField]
|
||||
element.data.node.template[templateField],
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
@ -149,7 +149,7 @@ const ApiModal = forwardRef(
|
|||
async function buildTweakObject(
|
||||
tw: string,
|
||||
changes: string | string[] | boolean | number | Object[] | Object,
|
||||
template: InputFieldType
|
||||
template: TemplateVariableType,
|
||||
) {
|
||||
changes = getChangesType(changes, template);
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ const ApiModal = forwardRef(
|
|||
flow?.id,
|
||||
autoLogin,
|
||||
cloneTweak,
|
||||
flow?.endpoint_name
|
||||
flow?.endpoint_name,
|
||||
);
|
||||
const pythonCode = getPythonCode(flow?.name, cloneTweak);
|
||||
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
||||
|
|
@ -235,7 +235,7 @@ const ApiModal = forwardRef(
|
|||
</BaseModal.Content>
|
||||
</BaseModal>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export default ApiModal;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { InputFieldType } from "../../../types/api";
|
||||
import { TemplateVariableType } from "../../../types/api";
|
||||
import { convertArrayToObj } from "../../../utils/reactflowUtils";
|
||||
|
||||
export const getChangesType = (
|
||||
changes: string | string[] | boolean | number | Object[] | Object,
|
||||
template: InputFieldType
|
||||
template: TemplateVariableType,
|
||||
) => {
|
||||
if (typeof changes === "string" && template.type === "float") {
|
||||
changes = parseFloat(changes);
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ export const getNodesWithDefaultValue = (flow) => {
|
|||
.filter(
|
||||
(templateField) =>
|
||||
templateField.charAt(0) !== "_" &&
|
||||
node.data.node.template[templateField].show &&
|
||||
node.data.node.template[templateField]?.show &&
|
||||
LANGFLOW_SUPPORTED_TYPES.has(
|
||||
node.data.node.template[templateField].type
|
||||
)
|
||||
node.data.node.template[templateField].type,
|
||||
),
|
||||
)
|
||||
.map((n, i) => {
|
||||
arrNodesWithValues.push(node["id"]);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { InputFieldType } from "../../../types/api";
|
||||
import { TemplateVariableType } from "../../../types/api";
|
||||
import { NodeType } from "../../../types/flow";
|
||||
|
||||
export const getValue = (
|
||||
value: string,
|
||||
node: NodeType,
|
||||
template: InputFieldType,
|
||||
tweak: Object[]
|
||||
template: TemplateVariableType,
|
||||
tweak: Object[],
|
||||
) => {
|
||||
let returnValue = value ?? "";
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default function FlowSettingsModal({
|
|||
useEffect(() => {
|
||||
setName(currentFlow!.name);
|
||||
setDescription(currentFlow!.description);
|
||||
}, [currentFlow!.name, currentFlow!.description, open]);
|
||||
}, [currentFlow?.name, currentFlow?.description, open]);
|
||||
|
||||
const [name, setName] = useState(currentFlow!.name);
|
||||
const [description, setDescription] = useState(currentFlow!.description);
|
||||
|
|
@ -40,6 +40,7 @@ export default function FlowSettingsModal({
|
|||
list: [err?.response?.data.detail ?? ""],
|
||||
});
|
||||
console.error(err);
|
||||
setIsSaving(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import {
|
|||
generateNodeFromFlow,
|
||||
getNodeId,
|
||||
isValidConnection,
|
||||
reconnectEdges,
|
||||
scapeJSONParse,
|
||||
updateIds,
|
||||
validateSelection,
|
||||
|
|
@ -61,19 +62,19 @@ export default function Page({
|
|||
const preventDefault = true;
|
||||
const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow);
|
||||
const autoSaveCurrentFlow = useFlowsManagerStore(
|
||||
(state) => state.autoSaveCurrentFlow
|
||||
(state) => state.autoSaveCurrentFlow,
|
||||
);
|
||||
const types = useTypesStore((state) => state.types);
|
||||
const templates = useTypesStore((state) => state.templates);
|
||||
const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
|
||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||
const [showCanvas, setSHowCanvas] = useState(
|
||||
Object.keys(templates).length > 0 && Object.keys(types).length > 0
|
||||
Object.keys(templates).length > 0 && Object.keys(types).length > 0,
|
||||
);
|
||||
|
||||
const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance);
|
||||
const setReactFlowInstance = useFlowStore(
|
||||
(state) => state.setReactFlowInstance
|
||||
(state) => state.setReactFlowInstance,
|
||||
);
|
||||
const nodes = useFlowStore((state) => state.nodes);
|
||||
const edges = useFlowStore((state) => state.edges);
|
||||
|
|
@ -90,10 +91,10 @@ export default function Page({
|
|||
const paste = useFlowStore((state) => state.paste);
|
||||
const resetFlow = useFlowStore((state) => state.resetFlow);
|
||||
const lastCopiedSelection = useFlowStore(
|
||||
(state) => state.lastCopiedSelection
|
||||
(state) => state.lastCopiedSelection,
|
||||
);
|
||||
const setLastCopiedSelection = useFlowStore(
|
||||
(state) => state.setLastCopiedSelection
|
||||
(state) => state.setLastCopiedSelection,
|
||||
);
|
||||
const onConnect = useFlowStore((state) => state.onConnect);
|
||||
const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId);
|
||||
|
|
@ -116,7 +117,7 @@ export default function Page({
|
|||
clonedSelection!,
|
||||
clonedNodes,
|
||||
clonedEdges,
|
||||
getRandomName()
|
||||
getRandomName(),
|
||||
);
|
||||
const newGroupNode = generateNodeFromFlow(newFlow, getNodeId);
|
||||
// const newEdges = reconnectEdges(newGroupNode, removedEdges);
|
||||
|
|
@ -124,8 +125,8 @@ export default function Page({
|
|||
...clonedNodes.filter(
|
||||
(oldNodes) =>
|
||||
!clonedSelection?.nodes.some(
|
||||
(selectionNode) => selectionNode.id === oldNodes.id
|
||||
)
|
||||
(selectionNode) => selectionNode.id === oldNodes.id,
|
||||
),
|
||||
),
|
||||
newGroupNode,
|
||||
]);
|
||||
|
|
@ -212,7 +213,7 @@ export default function Page({
|
|||
{
|
||||
x: position.current.x,
|
||||
y: position.current.y,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -296,7 +297,7 @@ export default function Page({
|
|||
|
||||
useEffect(() => {
|
||||
setSHowCanvas(
|
||||
Object.keys(templates).length > 0 && Object.keys(types).length > 0
|
||||
Object.keys(templates).length > 0 && Object.keys(types).length > 0,
|
||||
);
|
||||
}, [templates, types]);
|
||||
|
||||
|
|
@ -305,7 +306,7 @@ export default function Page({
|
|||
takeSnapshot();
|
||||
onConnect(params);
|
||||
},
|
||||
[takeSnapshot, onConnect]
|
||||
[takeSnapshot, onConnect],
|
||||
);
|
||||
|
||||
const onNodeDragStart: NodeDragHandler = useCallback(() => {
|
||||
|
|
@ -346,7 +347,7 @@ export default function Page({
|
|||
|
||||
// Extract the data from the drag event and parse it as a JSON object
|
||||
const data: { type: string; node?: APIClassType } = JSON.parse(
|
||||
event.dataTransfer.getData("nodedata")
|
||||
event.dataTransfer.getData("nodedata"),
|
||||
);
|
||||
|
||||
const newId = getNodeId(data.type);
|
||||
|
|
@ -362,7 +363,7 @@ export default function Page({
|
|||
};
|
||||
paste(
|
||||
{ nodes: [newNode], edges: [] },
|
||||
{ x: event.clientX, y: event.clientY }
|
||||
{ x: event.clientX, y: event.clientY },
|
||||
);
|
||||
} else if (event.dataTransfer.types.some((types) => types === "Files")) {
|
||||
takeSnapshot();
|
||||
|
|
@ -391,7 +392,7 @@ export default function Page({
|
|||
}
|
||||
},
|
||||
// Specify dependencies for useCallback
|
||||
[getNodeId, setNodes, takeSnapshot, paste]
|
||||
[getNodeId, setNodes, takeSnapshot, paste],
|
||||
);
|
||||
|
||||
const onEdgeUpdateStart = useCallback(() => {
|
||||
|
|
@ -407,7 +408,7 @@ export default function Page({
|
|||
setEdges((els) => updateEdge(oldEdge, newConnection, els));
|
||||
}
|
||||
},
|
||||
[setEdges]
|
||||
[setEdges],
|
||||
);
|
||||
|
||||
const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => {
|
||||
|
|
@ -440,7 +441,7 @@ export default function Page({
|
|||
(flow: OnSelectionChangeParams): void => {
|
||||
setLastSelection(flow);
|
||||
},
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const onPaneClick = useCallback((flow) => {
|
||||
|
|
|
|||
|
|
@ -57,17 +57,17 @@ export default function NodeToolbarComponent({
|
|||
const nodeLength = Object.keys(data.node!.template).filter(
|
||||
(templateField) =>
|
||||
templateField.charAt(0) !== "_" &&
|
||||
data.node?.template[templateField].show &&
|
||||
(data.node.template[templateField].type === "str" ||
|
||||
data.node.template[templateField].type === "bool" ||
|
||||
data.node.template[templateField].type === "float" ||
|
||||
data.node.template[templateField].type === "code" ||
|
||||
data.node.template[templateField].type === "prompt" ||
|
||||
data.node.template[templateField].type === "file" ||
|
||||
data.node.template[templateField].type === "Any" ||
|
||||
data.node.template[templateField].type === "int" ||
|
||||
data.node.template[templateField].type === "dict" ||
|
||||
data.node.template[templateField].type === "NestedDict")
|
||||
data.node?.template[templateField]?.show &&
|
||||
(data.node.template[templateField]?.type === "str" ||
|
||||
data.node.template[templateField]?.type === "bool" ||
|
||||
data.node.template[templateField]?.type === "float" ||
|
||||
data.node.template[templateField]?.type === "code" ||
|
||||
data.node.template[templateField]?.type === "prompt" ||
|
||||
data.node.template[templateField]?.type === "file" ||
|
||||
data.node.template[templateField]?.type === "Any" ||
|
||||
data.node.template[templateField]?.type === "int" ||
|
||||
data.node.template[templateField]?.type === "dict" ||
|
||||
data.node.template[templateField]?.type === "NestedDict")
|
||||
).length;
|
||||
|
||||
const hasStore = useStoreStore((state) => state.hasStore);
|
||||
|
|
@ -626,7 +626,7 @@ export default function NodeToolbarComponent({
|
|||
/>
|
||||
</SelectItem>
|
||||
)}
|
||||
{(!hasStore || !hasApiKey || !validApiKey) && (
|
||||
{/* {(!hasStore || !hasApiKey || !validApiKey) && (
|
||||
<SelectItem value={"Download"}>
|
||||
<ToolbarSelectItem
|
||||
shortcut={
|
||||
|
|
@ -638,7 +638,7 @@ export default function NodeToolbarComponent({
|
|||
dataTestId="Download-button-modal"
|
||||
/>
|
||||
</SelectItem>
|
||||
)}
|
||||
)} */}
|
||||
<SelectItem
|
||||
value={"documentation"}
|
||||
disabled={data.node?.documentation === ""}
|
||||
|
|
@ -688,16 +688,19 @@ export default function NodeToolbarComponent({
|
|||
style={`${frozen ? " text-ice" : ""} transition-all`}
|
||||
/>
|
||||
</SelectItem>
|
||||
<SelectItem value="Download">
|
||||
<ToolbarSelectItem
|
||||
shortcut={
|
||||
shortcuts.find((obj) => obj.name === "Download")?.shortcut!
|
||||
}
|
||||
value={"Download"}
|
||||
icon={"Download"}
|
||||
dataTestId="download-button-modal"
|
||||
/>
|
||||
</SelectItem>
|
||||
{(!hasStore || !hasApiKey || !validApiKey) && (
|
||||
<SelectItem value="Download">
|
||||
<ToolbarSelectItem
|
||||
shortcut={
|
||||
shortcuts.find((obj) => obj.name === "Download")
|
||||
?.shortcut!
|
||||
}
|
||||
value={"Download"}
|
||||
icon={"Download"}
|
||||
dataTestId="download-button-modal"
|
||||
/>
|
||||
</SelectItem>
|
||||
)}
|
||||
<SelectItem
|
||||
value={"delete"}
|
||||
className="focus:bg-red-400/[.20]"
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ export default function LoginPage(): JSX.Element {
|
|||
useState<loginInputStateType>(CONTROL_LOGIN_STATE);
|
||||
|
||||
const { password, username } = inputState;
|
||||
const { login, isAuthenticated, setUserData, setIsAdmin } =
|
||||
useContext(AuthContext);
|
||||
const { login } = useContext(AuthContext);
|
||||
const navigate = useNavigate();
|
||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ const ProfilePictureFormComponent = ({
|
|||
} else {
|
||||
prev[folder] = [path];
|
||||
}
|
||||
setLoading(false);
|
||||
return prev;
|
||||
});
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export default function MessagesPage() {
|
|||
setSelectedRows,
|
||||
setSuccessData,
|
||||
setErrorData,
|
||||
selectedRows,
|
||||
selectedRows
|
||||
);
|
||||
|
||||
const { handleUpdate } = useUpdateMessage(setSuccessData, setErrorData);
|
||||
|
|
@ -61,7 +61,7 @@ export default function MessagesPage() {
|
|||
overlayNoRowsTemplate="No data available"
|
||||
onSelectionChanged={(event: SelectionChangedEvent) => {
|
||||
setSelectedRows(
|
||||
event.api.getSelectedRows().map((row) => row.index),
|
||||
event.api.getSelectedRows().map((row) => row.index)
|
||||
);
|
||||
}}
|
||||
rowSelection="multiple"
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ export type VertexBuildTypeAPI = {
|
|||
timestamp: string;
|
||||
params: any;
|
||||
messages: ChatOutputType[] | ChatInputType[];
|
||||
artifacts: any | ChatOutputType | ChatInputType;
|
||||
};
|
||||
|
||||
export type LogType = {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ export type ParameterComponentType = {
|
|||
info?: string;
|
||||
proxy?: { field: string; id: string };
|
||||
showNode?: boolean;
|
||||
index: number;
|
||||
index?: string;
|
||||
onCloseModal?: (close: boolean) => void;
|
||||
outputName?: string;
|
||||
outputProxy?: OutputFieldProxyType;
|
||||
|
|
@ -511,7 +511,7 @@ export type ChatInputType = {
|
|||
isDragging: boolean;
|
||||
files: FilePreviewType[];
|
||||
setFiles: (
|
||||
files: FilePreviewType[] | ((prev: FilePreviewType[]) => FilePreviewType[])
|
||||
files: FilePreviewType[] | ((prev: FilePreviewType[]) => FilePreviewType[]),
|
||||
) => void;
|
||||
chatValue: string;
|
||||
inputRef: {
|
||||
|
|
@ -614,7 +614,7 @@ export type chatMessagePropsType = {
|
|||
updateChat: (
|
||||
chat: ChatMessageType,
|
||||
message: string,
|
||||
stream_url?: string
|
||||
stream_url?: string,
|
||||
) => void;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ type BuildVerticesParams = {
|
|||
onBuildUpdate?: (
|
||||
data: VertexBuildTypeAPI,
|
||||
status: BuildStatus,
|
||||
buildId: string
|
||||
buildId: string,
|
||||
) => void; // Replace any with the actual type if it's not any
|
||||
onBuildComplete?: (allNodesValid: boolean) => void;
|
||||
onBuildError?: (title, list, idList: VertexLayerElementType[]) => void;
|
||||
|
|
@ -55,7 +55,7 @@ export async function updateVerticesOrder(
|
|||
startNodeId?: string | null,
|
||||
stopNodeId?: string | null,
|
||||
nodes?: Node[],
|
||||
edges?: Edge[]
|
||||
edges?: Edge[],
|
||||
): Promise<{
|
||||
verticesLayers: VertexLayerElementType[][];
|
||||
verticesIds: string[];
|
||||
|
|
@ -71,7 +71,7 @@ export async function updateVerticesOrder(
|
|||
startNodeId,
|
||||
stopNodeId,
|
||||
nodes,
|
||||
edges
|
||||
edges,
|
||||
);
|
||||
} catch (error: any) {
|
||||
setErrorData({
|
||||
|
|
@ -128,7 +128,7 @@ export async function buildVertices({
|
|||
startNodeId,
|
||||
stopNodeId,
|
||||
nodes,
|
||||
edges
|
||||
edges,
|
||||
);
|
||||
if (onValidateNodes) {
|
||||
try {
|
||||
|
|
@ -162,7 +162,6 @@ export async function buildVertices({
|
|||
const currentLayer =
|
||||
useFlowStore.getState().verticesBuild?.verticesLayers![currentLayerIndex];
|
||||
// If there are no more layers, we are done
|
||||
console.log("currentLayer", currentLayer);
|
||||
if (!currentLayer) {
|
||||
if (onBuildComplete) {
|
||||
const allNodesValid = buildResults.every((result) => result);
|
||||
|
|
@ -191,14 +190,14 @@ export async function buildVertices({
|
|||
onBuildUpdate(
|
||||
getInactiveVertexData(element.id),
|
||||
BuildStatus.INACTIVE,
|
||||
runId
|
||||
runId,
|
||||
);
|
||||
}
|
||||
if (element.reference) {
|
||||
onBuildUpdate(
|
||||
getInactiveVertexData(element.reference),
|
||||
BuildStatus.INACTIVE,
|
||||
runId
|
||||
runId,
|
||||
);
|
||||
}
|
||||
buildResults.push(false);
|
||||
|
|
@ -224,7 +223,7 @@ export async function buildVertices({
|
|||
if (stop) {
|
||||
return;
|
||||
}
|
||||
})
|
||||
}),
|
||||
);
|
||||
// Once the current layer is built, move to the next layer
|
||||
currentLayerIndex += 1;
|
||||
|
|
@ -289,7 +288,10 @@ async function buildVertex({
|
|||
console.error(error);
|
||||
onBuildError!(
|
||||
"Error Building Component",
|
||||
[(error as AxiosError<any>).response?.data?.detail ?? "Unknown Error"],
|
||||
[
|
||||
(error as AxiosError<any>).response?.data?.detail ??
|
||||
"An unexpected error occurred while building the Component. Please try again.",
|
||||
],
|
||||
verticesIds.map((id) => ({ id }))
|
||||
);
|
||||
stopBuild();
|
||||
|
|
|
|||
|
|
@ -237,13 +237,13 @@ export function groupByFamily(
|
|||
|
||||
const checkBaseClass = (template: InputFieldType) => {
|
||||
return (
|
||||
template.type &&
|
||||
template.show &&
|
||||
template?.type &&
|
||||
template?.show &&
|
||||
((!excludeTypes.has(template.type) &&
|
||||
baseClassesSet.has(template.type)) ||
|
||||
(template.input_types &&
|
||||
template.input_types.some((inputType) =>
|
||||
baseClassesSet.has(inputType),
|
||||
(template?.input_types &&
|
||||
template?.input_types.some((inputType) =>
|
||||
baseClassesSet.has(inputType)
|
||||
)))
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,31 +24,59 @@ test("chat_io_teste", async ({ page }) => {
|
|||
|
||||
const jsonContent = readFileSync(
|
||||
"src/frontend/tests/end-to-end/assets/ChatTest.json",
|
||||
"utf-8"
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
await page.getByTestId("blank-flow").click();
|
||||
await page.waitForTimeout(2000);
|
||||
await page.waitForTimeout(3000);
|
||||
await page.getByTestId("extended-disclosure").click();
|
||||
await page.getByPlaceholder("Search").click();
|
||||
await page.getByPlaceholder("Search").fill("chat output");
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Create the DataTransfer and File
|
||||
const dataTransfer = await page.evaluateHandle((data) => {
|
||||
const dt = new DataTransfer();
|
||||
// Convert the buffer to a hex array
|
||||
const file = new File([data], "ChatTest.json", {
|
||||
type: "application/json",
|
||||
});
|
||||
dt.items.add(file);
|
||||
return dt;
|
||||
}, jsonContent);
|
||||
await page
|
||||
.getByTestId("outputsChat Output")
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
||||
await page.getByPlaceholder("Search").click();
|
||||
await page.getByPlaceholder("Search").fill("chat input");
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page
|
||||
.getByTestId("inputsChat Input")
|
||||
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||
await page.mouse.up();
|
||||
await page.mouse.down();
|
||||
|
||||
await page.getByTitle("fit view").click();
|
||||
await page.getByTitle("zoom out").click();
|
||||
await page.getByTitle("zoom out").click();
|
||||
await page.getByTitle("zoom out").click();
|
||||
await page.getByTitle("zoom out").click();
|
||||
await page.getByTitle("zoom out").click();
|
||||
await page.getByTitle("zoom out").click();
|
||||
await page.getByTitle("zoom out").click();
|
||||
|
||||
// Click and hold on the first element
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[10]/button/div/div'
|
||||
)
|
||||
.hover();
|
||||
await page.mouse.down();
|
||||
|
||||
// Move to the second element
|
||||
await page
|
||||
.locator(
|
||||
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div[4]/div/button/div/div'
|
||||
)
|
||||
.hover();
|
||||
|
||||
// Release the mouse
|
||||
await page.mouse.up();
|
||||
|
||||
// Now dispatch
|
||||
await page.dispatchEvent(
|
||||
'//*[@id="react-flow-id"]/div[1]/div[1]/div',
|
||||
"drop",
|
||||
{
|
||||
dataTransfer,
|
||||
}
|
||||
);
|
||||
await page.getByLabel("fit view").click();
|
||||
await page.getByText("Playground", { exact: true }).click();
|
||||
await page.getByPlaceholder("Send a message...").click();
|
||||
|
|
|
|||
|
|
@ -58,8 +58,13 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
|
|||
.fill(
|
||||
"testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!"
|
||||
);
|
||||
await page.getByText("Playground", { exact: true }).last().click();
|
||||
await page.getByTestId("icon-LucideSend").click();
|
||||
await page.getByText("Close", { exact: true }).click();
|
||||
await page.getByText("Chat Input", { exact: true }).click();
|
||||
await page.getByTestId("advanced-button-modal").click();
|
||||
await page.getByTestId("showsender_name").click();
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
||||
await page
|
||||
.getByTestId("popover-anchor-input-sender_name")
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ test("CodeAreaModalComponent", async ({ page }) => {
|
|||
await page.getByTitle("zoom out").click();
|
||||
await page.getByTitle("zoom out").click();
|
||||
await page.getByTestId("div-generic-node").click();
|
||||
|
||||
await page.getByTestId("code-button-modal").click();
|
||||
|
||||
const wCode =
|
||||
|
|
|
|||
|
|
@ -71,22 +71,12 @@ test("FloatComponent", async ({ page }) => {
|
|||
|
||||
await page.getByTestId("showmirostat").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showmirostat_eta").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showmirostat_eta").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat"]').isChecked()
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showmirostat_eta").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat_eta"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat_eta"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showmirostat_eta").click();
|
||||
|
|
@ -96,12 +86,12 @@ test("FloatComponent", async ({ page }) => {
|
|||
|
||||
await page.getByTestId("showmirostat_tau").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat_tau"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat_tau"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showmirostat_tau").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showmirostat_tau"]').isChecked()
|
||||
await page.locator('//*[@id="showmirostat_tau"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByTestId("showmodel").click();
|
||||
|
|
@ -124,22 +114,22 @@ test("FloatComponent", async ({ page }) => {
|
|||
|
||||
await page.getByTestId("shownum_thread").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="shownum_thread"]').isChecked()
|
||||
await page.locator('//*[@id="shownum_thread"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("shownum_thread").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="shownum_thread"]').isChecked()
|
||||
await page.locator('//*[@id="shownum_thread"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByTestId("showrepeat_last_n").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showrepeat_last_n"]').isChecked()
|
||||
await page.locator('//*[@id="showrepeat_last_n"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByTestId("showrepeat_last_n").click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showrepeat_last_n"]').isChecked()
|
||||
await page.locator('//*[@id="showrepeat_last_n"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
@ -155,7 +145,7 @@ test("FloatComponent", async ({ page }) => {
|
|||
// showtemperature
|
||||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked()
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
|
||||
await page.getByText("Save Changes", { exact: true }).click();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue