Merge branch 'ij/chatimg' into cz/inspection

This commit is contained in:
italojohnny 2024-05-28 15:59:18 -03:00
commit d575c97d15
349 changed files with 14576 additions and 21293 deletions

54
.github/workflows/docker-build.yml vendored Normal file
View file

@ -0,0 +1,54 @@
name: Docker Build and Push
on:
workflow_call:
inputs:
version:
required: true
type: string
release_type:
required: true
type: string
workflow_dispatch:
inputs:
version:
required: true
type: string
release_type:
required: true
type: choice
options:
- base
- main
jobs:
docker_build:
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set Dockerfile and Tags
id: set-vars
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
echo "DOCKERFILE=./docker/build_and_push_base.Dockerfile" >> $GITHUB_ENV
echo "TAGS=langflowai/langflow:base-${{ inputs.version }}" >> $GITHUB_ENV
else
echo "DOCKERFILE=./docker/build_and_push.Dockerfile" >> $GITHUB_ENV
echo "TAGS=langflowai/langflow:${{ inputs.version }},langflowai/langflow:1.0-alpha" >> $GITHUB_ENV
fi
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
file: ${{ env.DOCKERFILE }}
tags: ${{ env.TAGS }}

View file

@ -72,6 +72,6 @@ jobs:
with:
context: .
push: true
file: ./build_and_push_base.Dockerfile
file: ./docker/build_and_push_base.Dockerfile
tags: |
langflowai/langflow:base-${{ needs.release.outputs.version }}

View file

@ -78,7 +78,7 @@ jobs:
with:
context: .
push: true
file: ./build_and_push.Dockerfile
file: ./docker/build_and_push.Dockerfile
tags: |
langflowai/langflow:${{ needs.release.outputs.version }}
langflowai/langflow:1.0-alpha

101
.github/workflows/pre-release.yml vendored Normal file
View file

@ -0,0 +1,101 @@
name: Langflow Pre-release (Unified)
run-name: Langflow (${{inputs.release_type}}) Pre-release by @${{ github.actor }}
on:
workflow_dispatch:
inputs:
release_package:
description: "Release package"
required: true
type: boolean
default: false
release_type:
description: "Type of release (base or main)"
required: true
type: choice
options:
- base
- main
env:
POETRY_VERSION: "1.8.2"
jobs:
release:
name: Release Langflow
if: inputs.release_package == true
runs-on: ubuntu-latest
outputs:
version: ${{ steps.check-version.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Install poetry
run: pipx install poetry==$POETRY_VERSION
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "poetry"
- name: Check Version
id: check-version
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
version=$(cd src/backend/base && poetry version --short)
last_released_version=$(curl -s "https://pypi.org/pypi/langflow-base/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
else
version=$(poetry version --short)
last_released_version=$(curl -s "https://pypi.org/pypi/langflow/json" | jq -r '.releases | keys | .[]' | sort -V | tail -n 1)
fi
if [ "$version" = "$last_released_version" ]; then
echo "Version $version is already released. Skipping release."
exit 1
else
echo version=$version >> $GITHUB_OUTPUT
fi
- name: Build project for distribution
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
make build base=true
else
make build main=true
fi
- name: Publish to PyPI
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
run: |
if [ "${{ inputs.release_type }}" == "base" ]; then
make publish base=true
else
make publish main=true
fi
call_docker_build:
name: Call Docker Build Workflow
runs-on: ubuntu-latest
needs: release
steps:
- uses: actions/checkout@v4
- uses: ./.github/workflows/docker-build.yml
with:
version: ${{ needs.release.outputs.version }}
release_type: ${{ inputs.release_type }}
create_release:
name: Create Release
runs-on: ubuntu-latest
needs: [call_docker_build, release]
if: ${{ inputs.release_type == 'main' }}
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: dist
- name: Create Release
uses: ncipollo/release-action@v1
with:
artifacts: "dist/*"
token: ${{ secrets.GITHUB_TOKEN }}
draft: false
generateReleaseNotes: true
prerelease: true
tag: v${{ needs.release.outputs.version }}
commit: dev

View file

@ -50,7 +50,7 @@ jobs:
with:
context: .
push: true
file: ./build_and_push.Dockerfile
file: ./docker/build_and_push.Dockerfile
tags: |
langflowai/langflow:${{ steps.check-version.outputs.version }}
langflowai/langflow:latest

View file

@ -19,8 +19,8 @@ jobs:
strategy:
fail-fast: false
matrix:
shardIndex: [1]
shardTotal: [1]
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- name: Checkout code
uses: actions/checkout@v4
@ -30,7 +30,15 @@ jobs:
id: setup-node
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Cache Node.js dependencies
uses: actions/cache@v4
id: npm-cache
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('src/frontend/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install Node.js dependencies
run: |
@ -80,7 +88,7 @@ jobs:
- name: Run Playwright Tests
run: |
cd src/frontend
npx playwright test
npx playwright test --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2
- name: Upload blob report to GitHub Actions Artifacts
if: always()

View file

@ -18,7 +18,10 @@ repos:
hooks:
- id: check-case-conflict
- id: end-of-file-fixer
# python, js and ts only
files: \.(py|js|ts)$
- id: mixed-line-ending
files: \.(py|js|ts)$
args:
- --fix=lf
- id: trailing-whitespace

View file

@ -1,31 +0,0 @@
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# You can also specify other tool versions:
# nodejs: "19"
# rust: "1.64"
# golang: "1.19"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/conf.py
# Optionally build your docs in additional formats such as PDF and ePub
# formats:
# - pdf
# - epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
# python:
# install:
# - requirements: docs/requirements.txt

View file

@ -65,7 +65,6 @@ Each option is detailed below:
- `--workers`: Sets the number of worker processes. Can be set using the `LANGFLOW_WORKERS` environment variable. The default is `1`.
- `--timeout`: Sets the worker timeout in seconds. The default is `60`.
- `--port`: Sets the port to listen on. Can be set using the `LANGFLOW_PORT` environment variable. The default is `7860`.
- `--config`: Defines the path to the configuration file. The default is `config.yaml`.
- `--env-file`: Specifies the path to the .env file containing environment variables. The default is `.env`.
- `--log-level`: Defines the logging level. Can be set using the `LANGFLOW_LOG_LEVEL` environment variable. The default is `critical`.
- `--components-path`: Specifies the path to the directory containing custom components. Can be set using the `LANGFLOW_COMPONENTS_PATH` environment variable. The default is `langflow/components`.

View file

@ -1,99 +0,0 @@
# syntax=docker/dockerfile:1
# Keep this syntax directive! It's used to enable Docker BuildKit
# Based on https://github.com/python-poetry/poetry/discussions/1879?sort=top#discussioncomment-216865
# but I try to keep it updated (see history)
################################
# PYTHON-BASE
# Sets up all our shared environment variables
################################
FROM python:3.10-slim as python-base
# python
ENV PYTHONUNBUFFERED=1 \
# prevents python creating .pyc files
PYTHONDONTWRITEBYTECODE=1 \
\
# pip
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
\
# poetry
# https://python-poetry.org/docs/configuration/#using-environment-variables
POETRY_VERSION=1.8.2 \
# make poetry install to this location
POETRY_HOME="/opt/poetry" \
# make poetry create the virtual environment in the project's root
# it gets named `.venv`
POETRY_VIRTUALENVS_IN_PROJECT=true \
# do not ask any interactive question
POETRY_NO_INTERACTION=1 \
\
# paths
# this is where our requirements + virtual environment will live
PYSETUP_PATH="/opt/pysetup" \
VENV_PATH="/opt/pysetup/.venv"
# prepend poetry and venv to path
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"
################################
# BUILDER-BASE
# Used to build deps + create our virtual environment
################################
FROM python-base as builder-base
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
# deps for installing poetry
curl \
# deps for building python deps
build-essential
# install poetry - respects $POETRY_VERSION & $POETRY_HOME
# The --mount will mount the buildx cache directory to where
# Poetry and Pip store their cache so that they can reuse it
RUN --mount=type=cache,target=/root/.cache \
curl -sSL https://install.python-poetry.org | python3 -
# copy project requirement files here to ensure they will be cached.
WORKDIR $PYSETUP_PATH
# Copy just one file to avoid rebuilding the whole image
COPY poetry.lock pyproject.toml ./
COPY ./src/backend/langflow ./src/backend/langflow
COPY ./src/backend/base/pyproject.toml ./src/backend/base/pyproject.toml
# Copy README.md to the build context
COPY README.md .
# install runtime deps - uses $POETRY_VIRTUALENVS_IN_PROJECT internally
RUN --mount=type=cache,target=/root/.cache \
poetry install --without dev --extras deploy
################################
# DEVELOPMENT
# Image used during development / testing
################################
FROM python-base as development
WORKDIR $PYSETUP_PATH
# copy in our built poetry + venv
COPY --from=builder-base $POETRY_HOME $POETRY_HOME
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
# Copy just one file to avoid rebuilding the whole image
COPY ./src/backend/langflow ./src/backend/langflow
# quicker install as runtime deps are already installed
RUN --mount=type=cache,target=/root/.cache \
poetry install --with=dev --extras deploy
# copy in our app code
COPY ./src/backend ./src/backend
RUN --mount=type=cache,target=/root/.cache \
poetry install --with=dev --extras deploy
COPY ./tests ./tests=

View file

@ -1,33 +0,0 @@
version: "3.4"
services:
backend:
volumes:
- ./:/app
build:
context: ./
dockerfile: ./dev.Dockerfile
command:
[
"sh",
"-c",
"pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn --factory langflow.main:create_app --host 0.0.0.0 --port 7860 --reload --loop asyncio",
]
ports:
- 7860:7860
- 5678:5678
restart: on-failure
frontend:
build:
context: ./src/frontend
dockerfile: ./dev.Dockerfile
args:
- BACKEND_URL=http://backend:7860
ports:
- "3000:3000"
volumes:
- ./src/frontend/public:/home/node/app/public
- ./src/frontend/src:/home/node/app/src
- ./src/frontend/package.json:/home/node/app/package.json
restart: on-failure

View file

@ -78,9 +78,10 @@ RUN $POETRY_HOME/bin/poetry build
# Copy virtual environment and built .tar.gz from builder base
RUN useradd -m -u 1000 user
RUN chown -R user:user /app
USER user
# Install the package from the .tar.gz
RUN python -m pip install /app/dist/*.tar.gz --user
RUN python -m pip install /app/dist/*.tar.gz
ENTRYPOINT ["python", "-m", "langflow", "run"]
CMD ["--host", "0.0.0.0", "--port", "7860"]
CMD ["--host", "0.0.0.0", "--port", "7860"]

View file

@ -78,13 +78,15 @@ RUN cd src/frontend && npm run build
COPY src/backend ./src/backend
RUN cp -r src/frontend/build src/backend/base/langflow/frontend
RUN rm -rf src/backend/base/dist
RUN cd src/backend/base && $POETRY_HOME/bin/poetry build --format sdist
RUN cd src/backend/base && $POETRY_HOME/bin/poetry build
# Copy virtual environment and built .tar.gz from builder base
RUN useradd -m -u 1000 user
RUN chown -R user:user /app
USER user
# Install the package from the .tar.gz
RUN python -m pip install /app/dist/*.tar.gz --user
RUN python -m pip install /app/src/backend/base/dist/*.tar.gz
ENTRYPOINT ["python", "-m", "langflow", "run"]
CMD ["--host", "0.0.0.0", "--port", "7860"]
CMD ["--host", "0.0.0.0", "--port", "7860"]

View file

@ -10,9 +10,9 @@ services:
environment:
- LANGFLOW_DATABASE_URL=postgresql://langflow:langflow@postgres:5432/langflow
# This variable defines where the logs, file storage, monitor data and secret keys are stored.
- LANGFLOW_CONFIG_DIR=/var/lib/langflow
- LANGFLOW_CONFIG_DIR=app/langflow
volumes:
- langflow-data:/var/lib/langflow
- langflow-data:app/langflow
postgres:
image: postgres:16

View file

@ -4,15 +4,13 @@ import Admonition from "@theme/Admonition";
# API Keys
## Introduction
Langflow offers an API Key functionality that allows users to access their individual components and flows without going through traditional login authentication. The API Key is a user-specific token that can be included in the request's header or query parameter to authenticate API calls. The following documentation outlines how to generate, use, and manage these API Keys in Langflow.
Langflow provides an API key functionality that allows users to access their individual components and flows without traditional login authentication. The API key is a user-specific token that can be included in the request header or query parameter to authenticate API calls. This documentation outlines how to generate, use, and manage API keys in Langflow.
<Admonition type="warning">
This feature requires the `LANGFLOW_AUTO_LOGIN` environment variable to be set
to `False`. The default user and password are set using _`LANGFLOW_SUPERUSER`_
and _`LANGFLOW_SUPERUSER_PASSWORD`_ environment variables. Default values are
_`langflow`_ and _`langflow`_ respectively.
This feature requires the LANGFLOW_AUTO_LOGIN environment variable to be set
to False. The default user and password are set using the LANGFLOW_SUPERUSER
and LANGFLOW_SUPERUSER_PASSWORD environment variables. The default values are
langflow and langflow, respectively.
</Admonition>
## Generating an API Key
@ -93,7 +91,7 @@ print(run_flow(inputs, flow_id=FLOW_ID, tweaks=TWEAKS, apiKey=api_key))
### Using the Query Parameter
Alternatively, you can include the API key as a query parameter in the URL:
Include the API key as a query parameter in the URL:
```bash
curl -X POST \
@ -146,9 +144,9 @@ print(run_flow(inputs, flow_id=FLOW_ID, tweaks=TWEAKS, apiKey=api_key))
## Security Considerations
- **Visibility**: The API key won't be retrievable again through the UI for security reasons.
- **Scope**: The key only allows access to the flows and components of the specific user to whom it was issued.
- **Visibility**: For security reasons, the API key cannot be retrieved again through the UI.
- **Scope**: The key allows access only to the flows and components of the specific user to whom it was issued.
## Revoking an API Key
To revoke an API key, simply delete it from the UI. This will immediately invalidate the key and prevent it from being used again.
To revoke an API key, delete it from the UI. This action immediately invalidates the key and prevents it from being used again.

View file

@ -1,4 +1,4 @@
# 🖥️ Command Line Interface (CLI)
# Command Line Interface (CLI)
## Overview
@ -19,7 +19,6 @@ Each option is detailed below:
- `--workers`: Sets the number of worker processes. Can be set using the `LANGFLOW_WORKERS` environment variable. The default is `1`.
- `--timeout`: Sets the worker timeout in seconds. The default is `60`.
- `--port`: Sets the port to listen on. Can be set using the `LANGFLOW_PORT` environment variable. The default is `7860`.
- `--config`: Defines the path to the configuration file. The default is `config.yaml`.
- `--env-file`: Specifies the path to the .env file containing environment variables. The default is `.env`.
- `--log-level`: Defines the logging level. Can be set using the `LANGFLOW_LOG_LEVEL` environment variable. The default is `critical`.
- `--components-path`: Specifies the path to the directory containing custom components. Can be set using the `LANGFLOW_COMPONENTS_PATH` environment variable. The default is `langflow/components`.

View file

@ -391,13 +391,13 @@ The recommended way to load custom components is to set the _`LANGFLOW_COMPONENT
```bash
export LANGFLOW_COMPONENTS_PATH='["/path/to/components"]'
langflow
langflow run
```
Alternatively, you can specify the path to your custom components using the _`--components-path`_ argument when running the Langflow CLI, as shown below:
```bash
langflow --components-path /path/to/components
langflow run --components-path /path/to/components
```
Langflow will attempt to load all of the components found in the specified directory. If a component fails to load due to errors in the component's code, Langflow will print an error message to the console but will continue loading the rest of the components.

View file

@ -1,5 +1,6 @@
import ZoomableImage from "/src/theme/ZoomableImage.js";
import Admonition from "@theme/Admonition";
import ReactPlayer from "react-player";
# Global environment variables
@ -43,3 +44,11 @@ You now have a `openai_api_key` global environment variable for your Langflow pr
4. To view and manage your project's global environment variables, visit **Settings** > **Variables and Secrets**.
For more on variables in HuggingFace Spaces, see [Managing Secrets](https://huggingface.co/docs/hub/spaces-overview#managing-secrets).
## Video
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_global_variables.mp4" />
</div>

View file

@ -1,49 +0,0 @@
# Integrating Langfuse with Langflow
## Introduction
Langfuse is an open-source tracing and analytics tool designed for LLM applications. Integrating Langfuse with Langflow provides detailed production traces and granular insights into quality, cost, and latency. This integration allows you to monitor and debug your Langflow's chat or APIs easily.
## Step-by-Step Instructions
### Step 1: Create a Langfuse account
1. Go to [Langfuse](https://langfuse.com) and click on the "Sign In" button in the top right corner.
2. Click on the "Sign Up" button and create an account.
3. Once logged in, click on "Settings" and then on "Create new API keys."
4. Copy the Public key and the Secret Key and save them somewhere safe.
{/* Add these keys to your environment variables in the following step. */}
### Step 2: Set up Langfuse in Langflow
1. **Export the Environment Variables**: You'll need to export the environment variables `LANGFLOW_LANGFUSE_SECRET_KEY` and `LANGFLOW_LANGFUSE_PUBLIC_KEY` with the values obtained in Step 1.
You can do this by executing the following commands in your terminal:
```bash
export LANGFLOW_LANGFUSE_SECRET_KEY=<your secret key>
export LANGFLOW_LANGFUSE_PUBLIC_KEY=<your public key>
```
Alternatively, you can run the Langflow CLI command:
```bash
LANGFLOW_LANGFUSE_SECRET_KEY=<your secret key> LANGFLOW_LANGFUSE_PUBLIC_KEY=<your public key> langflow
```
If you are self-hosting Langfuse, you can also set the environment variable `LANGFLOW_LANGFUSE_HOST` to point to your Langfuse instance. By default, Langfuse points to the cloud instance at `https://cloud.langfuse.com`.
2. **Verify Integration**: Ensure that the environment variables are set correctly by checking their existence in your environment, for example by running:
```bash
echo $LANGFLOW_LANGFUSE_SECRET_KEY
echo $LANGFLOW_LANGFUSE_PUBLIC_KEY
```
3. **Monitor Langflow**: Now, whenever you use Langflow's chat or API, you will be able to see the tracing of your conversations in Langfuse.
That's it! You have successfully integrated Langfuse with Langflow, enhancing observability and debugging capabilities for your LLM application.
---
Note: For more details or customized configurations, please refer to the official [Langfuse documentation](https://langfuse.com/docs/integrations/langchain).

View file

@ -14,7 +14,7 @@ It even works for flows hosted on the Langflow store!
As long as you have a flow's environment variables set, you can run it by clicking the **Playground** button.
1. From your **Collections** page, click **Playground** in one of your flows.
1. From your **Collections** page, click the **![Playground icon](/logos/botmessage.svg)Playground** in one of your flows.
The **Playground** window opens.
<ZoomableImage
@ -27,3 +27,11 @@ As long as you have a flow's environment variables set, you can run it by clicki
/>
2. Chat with your bot as you normally would, all without having to open the editor.
## Video
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_playground.mp4" />
</div>

View file

@ -0,0 +1,217 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
# 🎨 Langflow canvas
The **Langflow canvas** is the central hub of Langflow, where you'll assemble new flows from components, run them, and see the results.
To get a feel for the canvas, we'll examine a basic prompting flow.
You can either build this flow yourself, or select **New Project** > **Basic prompting** to open a canvas with the flow pre-built.
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/basic-prompting.png",
dark: "img/basic-prompting.png",
}}
style={{ width: "30%", margin: "20px auto" }}
/>
For more on the difference between flows, components, collections, and projects, see [Flows, collections, components, and projects](./flows-components-collections.mdx).
## Components
A component is a building block of a flow.
<div style={{ marginBottom: "20px" }}>
During the flow creation process, you will notice handles (colored circles)
attached to one or both sides of a component. These handles represent the
availability to connect to other components. Hover over a handle to see
connection details.
</div>
<div style={{ marginBottom: "20px" }}>
For example, if you select a <code>ConversationChain</code> component, you
will see orange <span style={{ color: "orange" }}>o</span> and purple{" "}
<span style={{ color: "purple" }}>o</span> input handles. They indicate that
this component accepts an LLM and a Memory component as inputs. The red
asterisk <span style={{ color: "red" }}>*</span> means that at least one input
of that type is required.
</div>
{" "}
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: useBaseUrl("img/single-component.png"),
dark: useBaseUrl("img/single-component.png"),
}}
style={{ width: "50%", maxWidth: "800px", margin: "20px auto" }}
/>
<div style={{ marginBottom: "20px" }}>
In the top right corner of the component, you'll find the component status icon (![Status icon](/logos/playbutton.svg)).
Run the flow by clicking the **![Playground icon](/logos/botmessage.svg)Playground** button at the bottom right of the canvas.
Once the validation is complete, the status of each validated component should turn green (![Status icon](/logos/greencheck.svg)).
To debug, hover over the component status to see the outputs.
</div>
---
### Component menu
Each component is a little unique, but they will all have a menu bar on top that looks something like this.
The menu options are **Code**, **Save**, **Duplicate**, and **More**.
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/chat-input-with-menu.png",
dark: "img/chat-input-with-menu.png",
}}
style={{ width: "30%", margin: "20px auto" }}
/>
#### Code
The **Code** button displays your component's Python code.
You can modify the code and save it.
#### Save
Save your component to the **Saved** components folder for re-use.
#### Duplicate
Duplicate your component in the canvas.
#### More
**Advanced** - modify the parameters of your component.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_parameters.mp4" />
</div>
**Copy** - copy your component.
**Share** - share your component to the Langflow store.
**Docs** - view documentation for your component.
**Delete** - delete your component.
### Group multiple components
Components without input or output nodes can be grouped into a single component for re-use.
This is useful for combining large flows into single components (like RAG with a vector database, for example) and saves space in the canvas.
1. Hold **Shift** and drag to select the **Prompt** and **OpenAI** components.
2. Select **Group**.
3. The components merge into a single component.
4. To save the new component, select **Save**. It can now be re-used from the **Saved** components folder.
## Playground
Run your flow by clicking the **![Playground icon](/logos/botmessage.svg)Playground** button.
For more, see [Playground](../administration/playground.mdx).
## API
The **API** button opens the API window, where Langflow presents code for integrating your flow into external applications.
Modify the call's parameters in the **Tweaks** window, click the **Copy Code** or **Download** buttons, and paste your code where you want to use it.
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/api-window.png",
dark: "img/api-window.png",
}}
style={{ width: "50%", margin: "20px auto" }}
/>
### curl
The **curl** tab displays sample code for posting a query to your flow.
Modify the `input_value` to change your input message.
```curl
curl -X POST \
http://127.0.0.1:7863/api/v1/run/f2eefd80-bb91-4190-9279-0d6ffafeaac4\?stream\=false \
-H 'Content-Type: application/json'\
-d '{"input_value": "is anybody there?",
"output_type": "chat",
"input_type": "chat",
"tweaks": {
"Prompt-uxBqP": {},
"OpenAIModel-k39HS": {},
"ChatOutput-njtka": {},
"ChatInput-P3fgL": {}
}}'
```
Result:
```
{"session_id":"f2eefd80-bb91-4190-9279-0d6ffafeaac4:53856a772b8e1cfcb3dd2e71576b5215399e95bae318d3c02101c81b7c252da3","outputs":[{"inputs":{"input_value":"is anybody there?"},"outputs":[{"results":{"result":"Arrr, me hearties! Aye, this be Captain [Your Name] speakin'. What be ye needin', matey?"},"artifacts":{"message":"Arrr, me hearties! Aye, this be Captain [Your Name] speakin'. What be ye needin', matey?","sender":"Machine","sender_name":"AI"},"messages":[{"message":"Arrr, me hearties! Aye, this be Captain [Your Name] speakin'. What be ye needin', matey?","sender":"Machine","sender_name":"AI","component_id":"ChatOutput-njtka"}],"component_display_name":"Chat Output","component_id":"ChatOutput-njtka"}]}]}%
```
### Python API
The **Python API** tab displays code to interact with your flow using the Python HTTP requests library.
### Python Code
The **Python Code** tab displays code to interact with your flow's `.json` file using the Langflow runtime.
### Chat Widget HTML
The **Chat Widget HTML** tab displays code that can be inserted in the `<body>` of your HTML to interact with your flow.
For more, see the [Chat widget documentation](../administration/chat-widget.mdx).
### Tweaks
The **Tweaks** tab displays the available parameters for your flow.
Modifying the parameters changes the code parameters across all windows.
For example, changing the **Chat Input** component's `input_value` will change that value across all API calls.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_api.mp4" />
</div>
## Project options menu
To see options for your project, in the upper left corner of the canvas, select the dropdown menu.
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/project-options-menu.png",
dark: "img/project-options-menu.png",
}}
style={{ width: "30%", margin: "20px auto" }}
/>
**New** - Start a new project.
**Duplicate** - Duplicate the current flow as a new project.
**Settings** - Modify the project's **Name** or **Description**.
**Import** - Upload a flow `.json` file from your local machine.
**Export** - Download your current project to your local machine as a `.json` file.
**Undo** or **Redo** - Undo or redo your last action.

View file

@ -0,0 +1,115 @@
import ThemedImage from "@theme/ThemedImage";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
# 🖥️ Flows, components, collections, and projects
## TL;DR
A [flow](#flow) is a pipeline of components connected together in the Langflow canvas.
A [component](#component) is a single building block within a flow. A component has inputs, outputs, and parameters that define its functionality.
A [collection](#collection) is a snapshot of the flows available in your database. Collections can be downloaded to local storage and uploaded for future use.
A [project](#project) can be a component or a flow. Projects are saved as part of your collection.
For example, the **OpenAI LLM** is a **component** of the **Basic prompting** flow, and the **flow** is stored in a **collection**.
## Flow
A **flow** is a pipeline of components connected together in the Langflow canvas.
For example, the [Basic prompting](../starter-projects/basic-prompting.mdx) flow is a pipeline of four components:
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: "img/basic-prompting.png",
dark: "img/basic-prompting.png",
}}
style={{ width: "80%", margin: "20px auto" }}
/>
For example, the **OpenAI LLM component** receives input (left side) and produces output (right side) - in this case, receiving input from the **Chat Input** and **Prompt** components and producing output to the **Chat Output** component.
## Component
Components are the building blocks of flows. They consist of inputs, outputs, and parameters that define their functionality. These elements provide a convenient and straightforward way to compose LLM-based applications. Learn more about components and how they work in the LangChain [documentation](https://python.langchain.com/docs/integrations/components).
<div style={{ marginBottom: "20px" }}>
During the flow creation process, you will notice handles (colored circles)
attached to one or both sides of a component. These handles represent the
availability to connect to other components. Hover over a handle to see
connection details.
</div>
<div style={{ marginBottom: "20px" }}>
For example, if you select a <code>ConversationChain</code> component, you
will see orange <span style={{ color: "orange" }}>o</span> and purple{" "}
<span style={{ color: "purple" }}>o</span> input handles. They indicate that
this component accepts an LLM and a Memory component as inputs. The red
asterisk <span style={{ color: "red" }}>*</span> means that at least one input
of that type is required.
</div>
{" "}
<ZoomableImage
alt="Docusaurus themed image"
sources={{
light: useBaseUrl("img/single-component.png"),
dark: useBaseUrl("img/single-component.png"),
}}
style={{ width: "50%", maxWidth: "800px", margin: "20px auto" }}
/>
<div style={{ marginBottom: "20px" }}>
In the top right corner of the component, you'll find the component status icon (![Status icon](/logos/playbutton.svg)).
Build the flow by clicking the **![Playground icon](/logos/botmessage.svg)Playground** at the bottom right of the canvas.
Once the validation is complete, the status of each validated component should turn green (![Status icon](/logos/greencheck.svg)).
To debug, hover over the component status to see the outputs.
</div>
---
### Component Parameters
Langflow components can be edited by clicking the component settings button. Hide parameters to reduce complexity and keep the canvas clean and intuitive for experimentation.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_parameters.mp4" />
</div>
## Collection
A collection is a snapshot of flows available in a database.
Collections can be downloaded to local storage and uploaded for future use.
<div
style={{ marginBottom: "20px", display: "flex", justifyContent: "center" }}
>
<ReactPlayer playing controls url="/videos/langflow_collection.mp4" />
</div>
## Project
A **Project** can be a flow or a component. To view your saved projects, select **My Collection**.
Your **Projects** are displayed.
Click the **![Playground icon](/logos/botmessage.svg) Playground** button to run a flow from the **My Collection** screen.
In the top left corner of the screen are options for **Download Collection**, **Upload Collection**, and **New Project**.
Select **Download Collection** to save your project to your local machine. This downloads all flows and components as a `.json` file.
Select **Upload Collection** to upload a flow or component `.json` file from your local machine.
Select **New Project** to create a new project. In addition to a blank canvas, [starter projects](../starter-projects/basic-prompting.mdx) are also available.

View file

@ -1,4 +1,4 @@
# Common Installation Issues
# ❗️ Common Installation Issues
This is a list of possible issues that you may encounter when installing Langflow 1.0 alpha and how to solve them.
@ -25,11 +25,11 @@ ModuleNotFoundError: No module named 'langflow.__main__'
There are two possible reasons for this error:
1. You've installed Langflow using _`pip install langflow`_ but you already had a previous version of Langflow installed in your system.
In this case, you might be running the wrong executable.
To solve this issue, run the correct executable by running _`python -m langflow run`_ instead of _`langflow run`_.
If that doesn't work, try uninstalling and reinstalling Langflow with _`python -m pip install langflow --pre -U`_.
In this case, you might be running the wrong executable.
To solve this issue, run the correct executable by running _`python -m langflow run`_ instead of _`langflow run`_.
If that doesn't work, try uninstalling and reinstalling Langflow with _`python -m pip install langflow --pre -U`_.
2. Some version conflicts might have occurred during the installation process.
Run _`python -m pip install langflow --pre -U --force-reinstall`_ to reinstall Langflow and its dependencies.
Run _`python -m pip install langflow --pre -U --force-reinstall`_ to reinstall Langflow and its dependencies.
## _`Something went wrong running migrations. Please, run 'langflow migration --fix'`_
@ -45,4 +45,3 @@ There are two possible reasons for this error:
This error can occur during Langflow upgrades when the new version can't override `langflow-pre.db` in `.cache/langflow/`. Clearing the cache removes this file but will also erase your settings.
If you wish to retain your files, back them up before clearing the folder.

View file

@ -15,6 +15,9 @@ module.exports = {
"getting-started/install-langflow",
"getting-started/quickstart",
"getting-started/huggingface-spaces",
"getting-started/canvas",
"getting-started/flows-components-collections",
"migration/possible-installation-issues",
"getting-started/new-to-llms",
],
},
@ -35,15 +38,12 @@ module.exports = {
label: "Administration",
collapsed: false,
items: [
"administration/login",
"administration/api",
"administration/login",
"administration/cli",
"administration/playground",
"administration/global-env",
"administration/components",
"administration/collection",
"administration/prompt-customization",
"administration/langfuse_integration",
"administration/chat-widget",
],
},
{

File diff suppressed because one or more lines are too long

BIN
docs/static/img/api-window.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

BIN
docs/static/img/chat-input-with-menu.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

BIN
docs/static/img/project-options-menu.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
docs/static/img/single-component.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

8
docs/static/logos/botmessage.svg vendored Normal file
View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bot-message-square">
<path d="M12 6V2H8" />
<path d="m8 18-4 4V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2Z" />
<path d="M2 12h2" />
<path d="M9 11v2" />
<path d="M15 11v2" />
<path d="M20 12h2" />
</svg>

After

Width:  |  Height:  |  Size: 417 B

11
docs/static/logos/greencheck.svg vendored Normal file
View file

@ -0,0 +1,11 @@
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="green"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M20 6 9 17l-5-5" />
</svg>

After

Width:  |  Height:  |  Size: 207 B

11
docs/static/logos/playbutton.svg vendored Normal file
View file

@ -0,0 +1,11 @@
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="white"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polygon points="5,3 19,12 5,21 5,3" fill="currentColor" />
</svg>

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Binary file not shown.

932
package-lock.json generated
View file

@ -1,932 +0,0 @@
{
"name": "langflow",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"@radix-ui/react-popover": "^1.0.7",
"cmdk": "^0.2.0"
}
},
"node_modules/@babel/runtime": {
"version": "7.23.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
"integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@floating-ui/core": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz",
"integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==",
"dependencies": {
"@floating-ui/utils": "^0.1.3"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz",
"integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==",
"dependencies": {
"@floating-ui/core": "^1.4.2",
"@floating-ui/utils": "^0.1.3"
}
},
"node_modules/@floating-ui/react-dom": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz",
"integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==",
"dependencies": {
"@floating-ui/dom": "^1.5.1"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
},
"node_modules/@radix-ui/primitive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz",
"integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==",
"dependencies": {
"@babel/runtime": "^7.13.10"
}
},
"node_modules/@radix-ui/react-arrow": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz",
"integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-primitive": "1.0.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-compose-refs": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
"integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-context": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz",
"integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-dialog": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.0.tgz",
"integrity": "sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.0",
"@radix-ui/react-compose-refs": "1.0.0",
"@radix-ui/react-context": "1.0.0",
"@radix-ui/react-dismissable-layer": "1.0.0",
"@radix-ui/react-focus-guards": "1.0.0",
"@radix-ui/react-focus-scope": "1.0.0",
"@radix-ui/react-id": "1.0.0",
"@radix-ui/react-portal": "1.0.0",
"@radix-ui/react-presence": "1.0.0",
"@radix-ui/react-primitive": "1.0.0",
"@radix-ui/react-slot": "1.0.0",
"@radix-ui/react-use-controllable-state": "1.0.0",
"aria-hidden": "^1.1.1",
"react-remove-scroll": "2.5.4"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/primitive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz",
"integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==",
"dependencies": {
"@babel/runtime": "^7.13.10"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-compose-refs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz",
"integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-context": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz",
"integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz",
"integrity": "sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.0",
"@radix-ui/react-compose-refs": "1.0.0",
"@radix-ui/react-primitive": "1.0.0",
"@radix-ui/react-use-callback-ref": "1.0.0",
"@radix-ui/react-use-escape-keydown": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-guards": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz",
"integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-scope": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.0.tgz",
"integrity": "sha512-C4SWtsULLGf/2L4oGeIHlvWQx7Rf+7cX/vKOAD2dXW0A1b5QXwi3wWeaEgW+wn+SEVrraMUk05vLU9fZZz5HbQ==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.0",
"@radix-ui/react-primitive": "1.0.0",
"@radix-ui/react-use-callback-ref": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-id": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz",
"integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-layout-effect": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-portal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.0.tgz",
"integrity": "sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-primitive": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz",
"integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.0",
"@radix-ui/react-use-layout-effect": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz",
"integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-slot": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz",
"integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz",
"integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-use-controllable-state": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz",
"integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-callback-ref": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-use-escape-keydown": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz",
"integrity": "sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-callback-ref": "1.0.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-use-layout-effect": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz",
"integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
}
},
"node_modules/@radix-ui/react-dialog/node_modules/react-remove-scroll": {
"version": "2.5.4",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.4.tgz",
"integrity": "sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==",
"dependencies": {
"react-remove-scroll-bar": "^2.3.3",
"react-style-singleton": "^2.2.1",
"tslib": "^2.1.0",
"use-callback-ref": "^1.3.0",
"use-sidecar": "^1.1.2"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-dismissable-layer": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz",
"integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-callback-ref": "1.0.1",
"@radix-ui/react-use-escape-keydown": "1.0.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-focus-guards": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz",
"integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-focus-scope": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz",
"integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-callback-ref": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-id": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz",
"integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-layout-effect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popover": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz",
"integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-dismissable-layer": "1.0.5",
"@radix-ui/react-focus-guards": "1.0.1",
"@radix-ui/react-focus-scope": "1.0.4",
"@radix-ui/react-id": "1.0.1",
"@radix-ui/react-popper": "1.1.3",
"@radix-ui/react-portal": "1.0.4",
"@radix-ui/react-presence": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-slot": "1.0.2",
"@radix-ui/react-use-controllable-state": "1.0.1",
"aria-hidden": "^1.1.1",
"react-remove-scroll": "2.5.5"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popper": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
"integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@floating-ui/react-dom": "^2.0.0",
"@radix-ui/react-arrow": "1.0.3",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-use-callback-ref": "1.0.1",
"@radix-ui/react-use-layout-effect": "1.0.1",
"@radix-ui/react-use-rect": "1.0.1",
"@radix-ui/react-use-size": "1.0.1",
"@radix-ui/rect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-portal": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz",
"integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-primitive": "1.0.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-presence": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz",
"integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-use-layout-effect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-primitive": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz",
"integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-slot": "1.0.2"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-slot": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
"integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz",
"integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-controllable-state": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz",
"integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-callback-ref": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-escape-keydown": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz",
"integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-callback-ref": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-layout-effect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz",
"integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-rect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz",
"integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/rect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-use-size": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz",
"integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-layout-effect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/rect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz",
"integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==",
"dependencies": {
"@babel/runtime": "^7.13.10"
}
},
"node_modules/aria-hidden": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
"integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==",
"dependencies": {
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/cmdk": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/cmdk/-/cmdk-0.2.0.tgz",
"integrity": "sha512-JQpKvEOb86SnvMZbYaFKYhvzFntWBeSZdyii0rZPhKJj9uwJBxu4DaVYDrRN7r3mPop56oPhRw+JYWTKs66TYw==",
"dependencies": {
"@radix-ui/react-dialog": "1.0.0",
"command-score": "0.1.2"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/command-score": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/command-score/-/command-score-0.1.2.tgz",
"integrity": "sha512-VtDvQpIJBvBatnONUsPzXYFVKQQAhuf3XTNOAsdBxCNO/QCtUUd8LSgjn0GVarBkCad6aJCZfXgrjYbl/KRr7w=="
},
"node_modules/detect-node-es": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
},
"node_modules/get-nonce": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
"integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
"engines": {
"node": ">=6"
}
},
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/react": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.0"
},
"peerDependencies": {
"react": "^18.2.0"
}
},
"node_modules/react-remove-scroll": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz",
"integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==",
"dependencies": {
"react-remove-scroll-bar": "^2.3.3",
"react-style-singleton": "^2.2.1",
"tslib": "^2.1.0",
"use-callback-ref": "^1.3.0",
"use-sidecar": "^1.1.2"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/react-remove-scroll-bar": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz",
"integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==",
"dependencies": {
"react-style-singleton": "^2.2.1",
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/react-style-singleton": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
"integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==",
"dependencies": {
"get-nonce": "^1.0.0",
"invariant": "^2.2.4",
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/regenerator-runtime": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
"integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
},
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/use-callback-ref": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz",
"integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==",
"dependencies": {
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/use-sidecar": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
"integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==",
"dependencies": {
"detect-node-es": "^1.1.0",
"tslib": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}
}
}

View file

@ -1,6 +0,0 @@
{
"dependencies": {
"@radix-ui/react-popover": "^1.0.7",
"cmdk": "^0.2.0"
}
}

1108
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "langflow"
version = "1.0.0a36"
version = "1.0.0a38"
description = "A Python package with a built-in web application"
authors = ["Langflow <contact@langflow.org>"]
maintainers = [
@ -29,20 +29,20 @@ python = ">=3.10,<3.13"
langflow-base = { path = "./src/backend/base", develop = true }
beautifulsoup4 = "^4.12.2"
google-search-results = "^2.4.1"
google-api-python-client = "^2.118.0"
google-api-python-client = "^2.130.0"
huggingface-hub = { version = "^0.20.0", extras = ["inference"] }
llama-cpp-python = { version = "~0.2.0", optional = true }
networkx = "^3.1"
fake-useragent = "^1.4.0"
fake-useragent = "^1.5.0"
psycopg2-binary = "^2.9.6"
pyarrow = "^14.0.0"
wikipedia = "^1.4.0"
qdrant-client = "^1.7.0"
qdrant-client = "^1.9.0"
weaviate-client = "*"
sentence-transformers = { version = "^2.3.1", optional = true }
ctransformers = { version = "^0.2.10", optional = true }
cohere = "^5.1.7"
faiss-cpu = "^1.7.4"
cohere = "^5.5.3"
faiss-cpu = "^1.8.0"
types-cachetools = "^5.3.0.5"
pinecone-client = "^3.0.3"
pymongo = "^4.6.0"
@ -56,7 +56,7 @@ redis = { version = "^5.0.1", optional = true }
flower = { version = "^2.0.0", optional = true }
metaphor-python = "^0.1.11"
pywin32 = { version = "^306", markers = "sys_platform == 'win32'" }
langfuse = "^2.9.0"
langfuse = "^2.33.0"
metal-sdk = "^2.5.0"
markupsafe = "^2.1.3"
# jq is not available for windows
@ -69,14 +69,12 @@ langchain-google-genai = "^1.0.1"
langchain-cohere = "^0.1.0rc1"
elasticsearch = "^8.12.0"
pytube = "^15.0.0"
llama-index = "^0.10.13"
# unstructured = { extras = ["md"], version = "^0.12.4" }
dspy-ai = "^2.4.0"
assemblyai = "^0.23.1"
litellm = "^1.34.22"
chromadb = "^0.4.24"
assemblyai = "^0.26.0"
litellm = "^1.38.0"
chromadb = "^0.5.0"
langchain-anthropic = "^0.1.6"
langchain-astradb = "^0.1.0"
langchain-astradb = "^0.3.0"
langchain-openai = "^0.1.1"
zep-python = { version = "^2.0.0rc5", allow-prereleases = true }
langchain-google-vertexai = "^1.0.3"
@ -84,26 +82,29 @@ langchain-groq = "^0.1.3"
langchain-pinecone = "^0.1.0"
langchain-mistralai = "^0.1.6"
couchbase = "^4.2.1"
youtube-transcript-api = "^0.6.2"
markdown = "^3.6"
langchain-chroma = "^0.1.1"
[tool.poetry.group.dev.dependencies]
types-redis = "^4.6.0.5"
ipykernel = "^6.29.0"
mypy = "^1.9.0"
ruff = "^0.3.5"
mypy = "^1.10.0"
ruff = "^0.4.5"
httpx = "*"
pytest = "^8.1.0"
types-requests = "^2.31.0"
requests = "^2.31.0"
pytest-cov = "^4.1.0"
pytest = "^8.2.0"
types-requests = "^2.32.0"
requests = "^2.32.0"
pytest-cov = "^5.0.0"
pandas-stubs = "^2.1.4.231227"
types-pillow = "^10.2.0.20240213"
types-pyyaml = "^6.0.12.8"
types-python-jose = "^3.3.4.8"
types-passlib = "^1.7.7.13"
locust = "^2.23.1"
pytest-mock = "^3.12.0"
pytest-xdist = "^3.5.0"
pytest-mock = "^3.14.0"
pytest-xdist = "^3.6.0"
types-pywin32 = "^306.0.0.4"
types-google-cloud-ndb = "^2.2.0.0"
pytest-sugar = "^1.0.0"
@ -112,6 +113,7 @@ pytest-instafail = "^0.5.0"
pytest-asyncio = "^0.23.0"
pytest-profiling = "^1.7.0"
pre-commit = "^3.7.0"
vulture = "^2.11"
[tool.poetry.extras]
deploy = ["celery", "redis", "flower"]
@ -132,7 +134,7 @@ ignore-regex = '.*(Stati Uniti|Tense=Pres).*'
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra"
addopts = "-ra -n auto"
testpaths = ["tests", "integration"]
console_output_style = "progress"
filterwarnings = ["ignore::DeprecationWarning"]

View file

@ -3,9 +3,9 @@ services:
- type: web
name: langflow
runtime: docker
dockerfilePath: ./Dockerfile
dockerfilePath: ./docker/render.Dockerfile
repo: https://github.com/langflow-ai/langflow
branch: main
branch: dev
healthCheckPath: /health
autoDeploy: false
envVars:

View file

@ -20,8 +20,7 @@ When running as a [spot (preemptible) instance](https://cloud.google.com/compute
## Pricing (approximate)
> For a more accurate breakdown of costs, please use the [**GCP Pricing Calculator**](https://cloud.google.com/products/calculator)
> <br>
> For a more accurate breakdown of costs, please use the [**GCP Pricing Calculator**](https://cloud.google.com/products/calculator) > <br>
| Component | Regular Cost (Hourly) | Regular Cost (Monthly) | Spot/Preemptible Cost (Hourly) | Spot/Preemptible Cost (Monthly) | Notes |
| ------------------ | --------------------- | ---------------------- | ------------------------------ | ------------------------------- | -------------------------------------------------------------------------- |

View file

@ -22,7 +22,8 @@ from sqlmodel import select
from langflow.main import setup_app
from langflow.services.database.models.folder.utils import create_default_folder_if_it_doesnt_exist
from langflow.services.database.utils import session_getter
from langflow.services.deps import get_db_service
from langflow.services.deps import get_db_service, get_settings_service, session_scope
from langflow.services.settings.constants import DEFAULT_SUPERUSER
from langflow.services.utils import initialize_services
from langflow.utils.logger import configure, logger
from langflow.utils.util import update_settings
@ -83,7 +84,6 @@ def run(
help="Path to the directory containing custom components.",
envvar="LANGFLOW_COMPONENTS_PATH",
),
config: str = typer.Option(Path(__file__).parent / "config.yaml", help="Path to the configuration file."),
# .env file param
env_file: Path = typer.Option(None, help="Path to the .env file containing environment variables."),
log_level: str = typer.Option("critical", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"),
@ -132,7 +132,6 @@ def run(
load_dotenv(env_file, override=True)
update_settings(
config,
dev=dev,
remove_api_keys=remove_api_keys,
cache=cache,
@ -510,6 +509,66 @@ def migration(
display_results(results)
@app.command()
def api_key(
log_level: str = typer.Option("error", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"),
):
"""
Creates an API key for the default superuser if AUTO_LOGIN is enabled.
Args:
log_level (str, optional): Logging level. Defaults to "error".
Returns:
None
"""
configure(log_level=log_level)
initialize_services()
settings_service = get_settings_service()
auth_settings = settings_service.auth_settings
if not auth_settings.AUTO_LOGIN:
typer.echo("Auto login is disabled. API keys cannot be created through the CLI.")
return
with session_scope() as session:
from langflow.services.database.models.user.model import User
superuser = session.exec(select(User).where(User.username == DEFAULT_SUPERUSER)).first()
if not superuser:
typer.echo("Default superuser not found. This command requires a superuser and AUTO_LOGIN to be enabled.")
return
from langflow.services.database.models.api_key import ApiKey, ApiKeyCreate
from langflow.services.database.models.api_key.crud import create_api_key, delete_api_key
api_key = session.exec(select(ApiKey).where(ApiKey.user_id == superuser.id)).first()
if api_key:
delete_api_key(session, api_key.id)
api_key_create = ApiKeyCreate(name="CLI")
unmasked_api_key = create_api_key(session, api_key_create, user_id=superuser.id)
session.commit()
# Create a banner to display the API key and tell the user it won't be shown again
api_key_banner(unmasked_api_key)
def api_key_banner(unmasked_api_key):
is_mac = platform.system() == "Darwin"
import pyperclip # type: ignore
pyperclip.copy(unmasked_api_key.api_key)
panel = Panel(
f"[bold]API Key Created Successfully:[/bold]\n\n"
f"[bold blue]{unmasked_api_key.api_key}[/bold blue]\n\n"
"This is the only time the API key will be displayed. \n"
"Make sure to store it in a secure location. \n\n"
f"The API key has been copied to your clipboard. [bold]{['Ctrl','Cmd'][is_mac]} + V[/bold] to paste it.",
box=box.ROUNDED,
border_style="blue",
expand=False,
)
console = Console()
console.print(panel)
def main():
with warnings.catch_warnings():
warnings.simplefilter("ignore")

View file

@ -1,4 +1,3 @@
import os
import warnings
from pathlib import Path
from typing import TYPE_CHECKING, Optional

View file

@ -1,13 +1,12 @@
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from uuid import UUID
from langchain.schema import AgentAction, AgentFinish
from langchain_core.callbacks.base import AsyncCallbackHandler
from loguru import logger
from langflow.api.v1.schemas import ChatResponse, PromptResponse
from langflow.services.deps import get_chat_service, get_socket_service
from langflow.utils.util import remove_ansi_escape_codes
from langchain_core.agents import AgentAction, AgentFinish
if TYPE_CHECKING:
from langflow.services.socket.service import SocketIOService

View file

@ -171,7 +171,7 @@ async def build_vertex(
result_dict,
log_message,
valid,
_,
log_type,
vertex,
) = await graph.build_vertex(
lock=lock,
@ -186,6 +186,7 @@ async def build_vertex(
except Exception as exc:
logger.exception(f"Error building vertex: {exc}")
log_message = format_exception_message(exc)
log_type = type(exc).__name__
valid = False
result_data_response = ResultDataResponse(results={})
@ -193,7 +194,7 @@ async def build_vertex(
# we need to clear the cache
await chat_service.clear_cache(flow_id_str)
log_object = Log(message=log_message)
log_object = Log(message=log_message, type=log_type)
result_data_response.logs.append(log_object)
# Log the vertex build

View file

@ -18,10 +18,9 @@ from langflow.api.v1.schemas import (
UpdateCustomComponentRequest,
UploadFileResponse,
)
from langflow.custom import CustomComponent
from langflow.custom.utils import build_custom_component_template
from langflow.graph.graph.base import Graph
from langflow.graph.schema import RunOutputs
from langflow.interface.custom.custom_component import CustomComponent
from langflow.interface.custom.utils import build_custom_component_template
from langflow.processing.process import process_tweaks, run_graph_internal
from langflow.schema.graph import Tweaks
from langflow.services.auth.utils import api_key_security, get_current_active_user
@ -44,7 +43,7 @@ def get_all(
logger.debug("Building langchain types dict")
try:
all_types_dict = get_all_types_dict(settings_service.settings.COMPONENTS_PATH)
all_types_dict = get_all_types_dict(settings_service.settings.components_path)
return all_types_dict
except Exception as exc:
logger.exception(exc)

View file

@ -38,7 +38,10 @@ def create_flow(
db_flow.updated_at = datetime.now(timezone.utc)
if db_flow.folder_id is None:
default_folder = session.exec(select(Folder).where(Folder.name == DEFAULT_FOLDER_NAME)).first()
# Make sure flows always have a folder
default_folder = session.exec(
select(Folder).where(Folder.name == DEFAULT_FOLDER_NAME, Folder.user_id == current_user.id)
).first()
if default_folder:
db_flow.folder_id = default_folder.id
@ -127,7 +130,7 @@ def update_flow(
if not db_flow:
raise HTTPException(status_code=404, detail="Flow not found")
flow_data = flow.model_dump(exclude_unset=True)
if settings_service.settings.REMOVE_API_KEYS:
if settings_service.settings.remove_api_keys:
flow_data = remove_api_keys(flow_data)
for key, value in flow_data.items():
if value is not None:

View file

@ -3,12 +3,11 @@ from uuid import UUID
import orjson
from fastapi import APIRouter, Depends, File, HTTPException, Response, UploadFile, status
from sqlalchemy import update
from sqlalchemy import or_, update
from sqlmodel import Session, select
from langflow.api.v1.flows import create_flows
from langflow.api.v1.schemas import FlowListCreate, FlowListReadWithFolderName
from langflow.initial_setup.setup import STARTER_FOLDER_NAME
from langflow.services.auth.utils import get_current_active_user
from langflow.services.database.models.flow.model import Flow, FlowCreate, FlowRead
from langflow.services.database.models.folder.constants import DEFAULT_FOLDER_NAME
@ -35,6 +34,18 @@ def create_folder(
try:
new_folder = Folder.model_validate(folder, from_attributes=True)
new_folder.user_id = current_user.id
folder_results = session.exec(
select(Folder).where(
Folder.name.like(f"{new_folder.name}%"), # type: ignore
Folder.user_id == current_user.id,
)
)
existing_folder_names = [folder.name for folder in folder_results]
if existing_folder_names:
new_folder.name = f"{new_folder.name} ({len(existing_folder_names) + 1})"
session.add(new_folder)
session.commit()
session.refresh(new_folder)
@ -63,16 +74,11 @@ def read_folders(
current_user: User = Depends(get_current_active_user),
):
try:
folders = session.exec(select(Folder).where(Folder.user_id == current_user.id)).all()
return folders
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.get("/starter-projects", response_model=FolderReadWithFlows, status_code=200)
def read_starter_folders(*, session: Session = Depends(get_session)):
try:
folders = session.exec(select(Folder).where(Folder.name == STARTER_FOLDER_NAME)).first()
folders = session.exec(
select(Folder).where(
or_(Folder.user_id == current_user.id, Folder.user_id == None) # type: ignore # noqa: E711
)
).all()
return folders
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

View file

@ -247,6 +247,7 @@ class VerticesOrderResponse(BaseModel):
class Log(TypedDict):
message: str
type: str
class ResultDataResponse(BaseModel):

View file

@ -54,7 +54,7 @@ def check_if_store_is_enabled(
settings_service=Depends(get_settings_service),
):
return {
"enabled": settings_service.settings.STORE,
"enabled": settings_service.settings.store,
}

View file

@ -1,9 +1,9 @@
from typing import Optional, Union
from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES
from langflow.custom import CustomComponent
from langflow.field_typing import Text
from langflow.helpers.record import records_to_text
from langflow.interface.custom.custom_component import CustomComponent
from langflow.memory import store_message
from langflow.schema import Record

View file

@ -1,8 +1,8 @@
from typing import Optional
from langflow.custom import CustomComponent
from langflow.field_typing import Text
from langflow.helpers.record import records_to_text
from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema.schema import Record

View file

@ -1,6 +1,6 @@
from typing import Optional
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema.schema import Record

View file

@ -1,10 +1,10 @@
from fastapi import HTTPException
from langchain.prompts import PromptTemplate
from loguru import logger
from langflow.api.v1.base import INVALID_NAMES, check_input_variables
from langflow.interface.utils import extract_input_variables_from_prompt
from langflow.template.field.prompt import DefaultPromptField
from langchain_core.prompts import PromptTemplate
def validate_prompt(prompt_template: str, silent_errors: bool = False) -> list[str]:

View file

@ -1,52 +0,0 @@
from typing import Callable, List, Optional, Union
from langchain.agents import AgentExecutor, AgentType, initialize_agent, types
from langflow.field_typing import BaseChatMemory, BaseLanguageModel, Tool
from langflow.interface.custom.custom_component import CustomComponent
class AgentInitializerComponent(CustomComponent):
display_name: str = "Agent Initializer"
description: str = "Initialize a Langchain Agent."
documentation: str = "https://python.langchain.com/docs/modules/agents/agent_types/"
def build_config(self):
agents = list(types.AGENT_TO_CLASS.keys())
# field_type and required are optional
return {
"agent": {"options": agents, "value": agents[0], "display_name": "Agent Type"},
"max_iterations": {"display_name": "Max Iterations", "value": 10},
"memory": {"display_name": "Memory"},
"tools": {"display_name": "Tools"},
"llm": {"display_name": "Language Model"},
"code": {"advanced": True},
}
def build(
self,
agent: str,
llm: BaseLanguageModel,
tools: List[Tool],
max_iterations: int,
memory: Optional[BaseChatMemory] = None,
) -> Union[AgentExecutor, Callable]:
agent = AgentType(agent)
if memory:
return initialize_agent(
tools=tools,
llm=llm,
agent=agent,
memory=memory,
return_intermediate_steps=True,
handle_parsing_errors=True,
max_iterations=max_iterations,
)
return initialize_agent(
tools=tools,
llm=llm,
agent=agent,
return_intermediate_steps=True,
handle_parsing_errors=True,
max_iterations=max_iterations,
)

View file

@ -1,10 +1,9 @@
from langchain.agents import AgentExecutor, create_json_agent
from langchain.agents import AgentExecutor
from langchain_community.agent_toolkits import create_json_agent
from langchain_community.agent_toolkits.json.toolkit import JsonToolkit
from langflow.field_typing import (
BaseLanguageModel,
)
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel
class JsonAgentComponent(CustomComponent):

View file

@ -1,102 +0,0 @@
from typing import List, Optional
from langchain.agents.agent import AgentExecutor
from langchain.agents.agent_toolkits.conversational_retrieval.openai_functions import _get_default_system_message
from langchain.agents.openai_functions_agent.base import OpenAIFunctionsAgent
from langchain.memory.token_buffer import ConversationTokenBufferMemory
from langchain.prompts import SystemMessagePromptTemplate
from langchain.prompts.chat import MessagesPlaceholder
from langchain.schema.memory import BaseMemory
from langchain.tools import Tool
from langchain_openai import ChatOpenAI
from langflow.field_typing.range_spec import RangeSpec
from langflow.interface.custom.custom_component import CustomComponent
from pydantic.v1 import SecretStr
class ConversationalAgent(CustomComponent):
display_name: str = "OpenAI Conversational Agent"
description: str = "Conversational Agent that can use OpenAI's function calling API"
icon = "OpenAI"
def build_config(self):
openai_function_models = [
"gpt-4-turbo-preview",
"gpt-4-0125-preview",
"gpt-4-1106-preview",
"gpt-4-vision-preview",
"gpt-3.5-turbo-0125",
"gpt-3.5-turbo-1106",
]
return {
"tools": {"display_name": "Tools"},
"memory": {"display_name": "Memory"},
"system_message": {"display_name": "System Message"},
"max_token_limit": {"display_name": "Max Token Limit"},
"model_name": {
"display_name": "Model Name",
"options": openai_function_models,
"value": openai_function_models[0],
},
"code": {"show": False},
"temperature": {
"display_name": "Temperature",
"value": 0.2,
"rangeSpec": RangeSpec(min=0, max=2, step=0.1),
},
}
def build(
self,
model_name: str,
openai_api_key: str,
tools: List[Tool],
openai_api_base: Optional[str] = None,
memory: Optional[BaseMemory] = None,
system_message: Optional[SystemMessagePromptTemplate] = None,
max_token_limit: int = 2000,
temperature: float = 0.9,
) -> AgentExecutor:
if openai_api_key:
api_key = SecretStr(openai_api_key)
else:
api_key = None
llm = ChatOpenAI(
model=model_name,
api_key=api_key,
base_url=openai_api_base,
max_tokens=max_token_limit,
temperature=temperature,
)
if not memory:
memory_key = "chat_history"
memory = ConversationTokenBufferMemory(
memory_key=memory_key,
return_messages=True,
output_key="output",
llm=llm,
max_token_limit=max_token_limit,
)
else:
memory_key = memory.memory_key # type: ignore
_system_message = system_message or _get_default_system_message()
prompt = OpenAIFunctionsAgent.create_prompt(
system_message=_system_message, # type: ignore
extra_prompt_messages=[MessagesPlaceholder(variable_name=memory_key)],
)
agent = OpenAIFunctionsAgent(
llm=llm,
tools=tools,
prompt=prompt, # type: ignore
)
return AgentExecutor(
agent=agent,
tools=tools, # type: ignore
memory=memory,
verbose=True,
return_intermediate_steps=True,
handle_parsing_errors=True,
)

View file

@ -1,12 +1,12 @@
from typing import Callable, Union
from langchain.agents import AgentExecutor
from langchain_community.utilities import SQLDatabase
from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_community.agent_toolkits.sql.base import create_sql_agent
from langchain_community.utilities import SQLDatabase
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel
from langflow.interface.custom.custom_component import CustomComponent
class SQLAgentComponent(CustomComponent):

View file

@ -3,8 +3,8 @@ from typing import Callable, Union
from langchain.agents import AgentExecutor, create_vectorstore_agent
from langchain.agents.agent_toolkits.vectorstore.toolkit import VectorStoreToolkit
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel
from langflow.interface.custom.custom_component import CustomComponent
class VectorStoreAgentComponent(CustomComponent):

View file

@ -4,7 +4,7 @@ from langchain.agents import create_vectorstore_router_agent
from langchain.agents.agent_toolkits.vectorstore.toolkit import VectorStoreRouterToolkit
from langchain_core.language_models.base import BaseLanguageModel
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
class VectorStoreRouterAgentComponent(CustomComponent):

View file

@ -1,17 +1,13 @@
from .AgentInitializer import AgentInitializerComponent
from .CSVAgent import CSVAgentComponent
from .JsonAgent import JsonAgentComponent
from .OpenAIConversationalAgent import ConversationalAgent
from .SQLAgent import SQLAgentComponent
from .VectorStoreAgent import VectorStoreAgentComponent
from .VectorStoreRouterAgent import VectorStoreRouterAgentComponent
from .XMLAgent import XMLAgentComponent
__all__ = [
"AgentInitializerComponent",
"CSVAgentComponent",
"JsonAgentComponent",
"ConversationalAgent",
"SQLAgentComponent",
"VectorStoreAgentComponent",
"VectorStoreRouterAgentComponent",

View file

@ -2,8 +2,8 @@ from typing import Optional
from langchain.chains import ConversationChain
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel, BaseMemory, Text
from langflow.interface.custom.custom_component import CustomComponent
class ConversationChainComponent(CustomComponent):

View file

@ -1,11 +1,11 @@
from typing import Optional
from langchain.chains.llm import LLMChain
from langflow.field_typing import BaseLanguageModel, BaseMemory, Text
from langflow.interface.custom.custom_component import CustomComponent
from langchain_core.prompts import PromptTemplate
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel, BaseMemory, Text
class LLMChainComponent(CustomComponent):
display_name = "LLMChain"

View file

@ -1,7 +1,7 @@
from langchain.chains import LLMCheckerChain
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel, Text
from langflow.interface.custom.custom_component import CustomComponent
class LLMCheckerChainComponent(CustomComponent):

View file

@ -2,8 +2,8 @@ from typing import Optional
from langchain.chains import LLMChain, LLMMathChain
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel, BaseMemory, Text
from langflow.interface.custom.custom_component import CustomComponent
class LLMMathChainComponent(CustomComponent):

View file

@ -3,8 +3,8 @@ from typing import Optional
from langchain.chains.retrieval_qa.base import RetrievalQA
from langchain_core.documents import Document
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel, BaseMemory, BaseRetriever, Text
from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema.schema import Record

View file

@ -3,8 +3,8 @@ from typing import Optional
from langchain.chains import RetrievalQAWithSourcesChain
from langchain_core.documents import Document
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel, BaseMemory, BaseRetriever, Text
from langflow.interface.custom.custom_component import CustomComponent
class RetrievalQAWithSourcesChainComponent(CustomComponent):

View file

@ -5,8 +5,8 @@ from langchain_community.utilities.sql_database import SQLDatabase
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import Runnable
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel, Text
from langflow.interface.custom.custom_component import CustomComponent
class SQLGeneratorComponent(CustomComponent):

View file

@ -3,7 +3,8 @@ import json
from typing import List, Optional
import httpx
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -1,7 +1,7 @@
from typing import Any, Dict, List, Optional
from langflow.base.data.utils import parallel_load_records, parse_text_file_to_record, retrieve_file_paths
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -2,7 +2,7 @@ from pathlib import Path
from typing import Any, Dict
from langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_record
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -2,7 +2,7 @@ from typing import Any, Dict
from langchain_community.document_loaders.web_base import WebBaseLoader
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -1,9 +1,9 @@
from typing import Optional
from langchain.embeddings.base import Embeddings
from langchain_community.embeddings import BedrockEmbeddings
from langchain_core.embeddings import Embeddings
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
class AmazonBedrockEmeddingsComponent(CustomComponent):

View file

@ -1,7 +1,8 @@
from langchain.embeddings.base import Embeddings
from langchain_community.embeddings import AzureOpenAIEmbeddings
from langchain_core.embeddings import Embeddings
from langchain_openai import AzureOpenAIEmbeddings
from pydantic.v1 import SecretStr
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
class AzureOpenAIEmbeddingsComponent(CustomComponent):
@ -52,12 +53,16 @@ class AzureOpenAIEmbeddingsComponent(CustomComponent):
api_version: str,
api_key: str,
) -> Embeddings:
if api_key:
azure_api_key = SecretStr(api_key)
else:
azure_api_key = None
try:
embeddings = AzureOpenAIEmbeddings(
azure_endpoint=azure_endpoint,
azure_deployment=azure_deployment,
api_version=api_version,
api_key=api_key,
api_key=azure_api_key,
)
except Exception as e:

View file

@ -2,7 +2,7 @@ from typing import Dict, Optional
from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
class HuggingFaceEmbeddingsComponent(CustomComponent):

View file

@ -3,7 +3,7 @@ from typing import Dict, Optional
from langchain_community.embeddings.huggingface import HuggingFaceInferenceAPIEmbeddings
from pydantic.v1.types import SecretStr
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
class HuggingFaceInferenceAPIEmbeddingsComponent(CustomComponent):

View file

@ -1,7 +1,7 @@
from langchain_mistralai.embeddings import MistralAIEmbeddings
from pydantic.v1 import SecretStr
from langchain_mistralai.embeddings import MistralAIEmbeddings
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.field_typing import Embeddings

View file

@ -1,9 +1,9 @@
from typing import Optional
from langchain.embeddings.base import Embeddings
from langchain_community.embeddings import OllamaEmbeddings
from langchain_core.embeddings import Embeddings
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
class OllamaEmbeddingsComponent(CustomComponent):

View file

@ -1,10 +1,10 @@
from typing import Any, Dict, List, Optional
from typing import Dict, List, Optional
from langchain_openai.embeddings.base import OpenAIEmbeddings
from pydantic.v1 import SecretStr
from langflow.custom import CustomComponent
from langflow.field_typing import Embeddings, NestedDict
from langflow.interface.custom.custom_component import CustomComponent
class OpenAIEmbeddingsComponent(CustomComponent):
@ -94,7 +94,6 @@ class OpenAIEmbeddingsComponent(CustomComponent):
allowed_special: List[str] = [],
disallowed_special: List[str] = ["all"],
chunk_size: int = 1000,
client: Optional[Any] = None,
deployment: str = "text-embedding-ada-002",
embedding_ctx_length: int = 8191,
max_retries: int = 6,
@ -126,7 +125,6 @@ class OpenAIEmbeddingsComponent(CustomComponent):
allowed_special=set(allowed_special),
disallowed_special="all",
chunk_size=chunk_size,
client=client,
deployment=deployment,
embedding_ctx_length=embedding_ctx_length,
max_retries=max_retries,

View file

@ -2,7 +2,7 @@ from typing import List, Optional
from langchain_google_vertexai import VertexAIEmbeddings
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
class VertexAIEmbeddingsComponent(CustomComponent):

View file

@ -1,4 +1,4 @@
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.memory import delete_messages, get_messages

View file

@ -1,4 +1,4 @@
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -1,6 +1,6 @@
from typing import List
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -1,4 +1,4 @@
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -1,4 +1,4 @@
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -1,6 +1,6 @@
from typing import Optional
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.schema import Record

View file

@ -1,7 +1,8 @@
from typing import Union
from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema import Record
from langflow.custom import CustomComponent
from langflow.field_typing import Text
from langflow.schema import Record
class PassComponent(CustomComponent):

View file

@ -1,8 +1,8 @@
from typing import Callable
from langflow.custom import CustomComponent
from langflow.custom.utils import get_function
from langflow.field_typing import Code
from langflow.interface.custom.custom_component import CustomComponent
from langflow.interface.custom.utils import get_function
class PythonFunctionComponent(CustomComponent):

View file

@ -1,7 +1,7 @@
from langchain_core.runnables import Runnable
from langflow.custom import CustomComponent
from langflow.field_typing import Text
from langflow.interface.custom.custom_component import CustomComponent
class RunnableExecComponent(CustomComponent):

View file

@ -1,8 +1,8 @@
from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
from langchain_community.utilities import SQLDatabase
from langflow.custom import CustomComponent
from langflow.field_typing import Text
from langflow.interface.custom.custom_component import CustomComponent
class SQLExecutorComponent(CustomComponent):

View file

@ -1,7 +1,7 @@
from typing import Optional
from langflow.custom import CustomComponent
from langflow.field_typing import Text
from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema import Record
from langflow.utils.util import unescape_string

View file

@ -1,6 +1,6 @@
from typing import List, Optional
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.memory import get_messages, store_message
from langflow.schema import Record

View file

@ -1,8 +1,8 @@
from typing import Optional, Union
from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema import Record
from langflow.custom import CustomComponent
from langflow.field_typing import Text
from langflow.schema import Record
class TextOperatorComponent(CustomComponent):

View file

@ -1,4 +1,4 @@
from langflow.interface.custom.custom_component import CustomComponent
from langflow.custom import CustomComponent
from langflow.field_typing import Text

Some files were not shown because too many files have changed in this diff Show more