Merge branch 'two_edges_merge' into two_edges
This commit is contained in:
commit
fde9a77035
385 changed files with 7922 additions and 2254 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -267,4 +267,6 @@ src/frontend/playwright-report/index.html
|
|||
*.bak
|
||||
prof/*
|
||||
|
||||
src/frontend/temp
|
||||
src/frontend/temp
|
||||
*.db-shm
|
||||
*.db-wal
|
||||
|
|
@ -181,9 +181,8 @@ Use the widget API to customize your Chat Widget:
|
|||
format {<span>"key":"value"</span>}.
|
||||
</Admonition>
|
||||
|
||||
|
||||
| Prop | Type | Required | Description |
|
||||
|-----------------------|---------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| --------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| bot_message_style | JSON | No | Applies custom formatting to bot messages. |
|
||||
| chat_input_field | String | Yes | Defines the type of the input field for chat messages. |
|
||||
| chat_inputs | JSON | Yes | Determines the chat input elements and their respective values. |
|
||||
|
|
@ -207,4 +206,3 @@ Use the widget API to customize your Chat Widget:
|
|||
| user_message_style | JSON | No | Determines the formatting for user messages in the chat window. |
|
||||
| width | Number | No | Sets the width of the chat window in pixels. |
|
||||
| window_title | String | No | Sets the title displayed in the chat window's header or title bar. |
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ With _`LANGFLOW_AUTO_LOGIN`_ set to _`False`_, Langflow requires users to sign u
|
|||
light: useBaseUrl("img/sign-up.png"),
|
||||
dark: useBaseUrl("img/sign-up.png"),
|
||||
}}
|
||||
style={{ width: "40%", margin: "20px auto" }}
|
||||
style={{ width: "40%", margin: "20px auto" }}
|
||||
/>
|
||||
|
||||
## Profile settings
|
||||
|
|
|
|||
|
|
@ -40,14 +40,13 @@ The Playground's appearance changes depending on what components are in your can
|
|||
|
||||
Adding or removing any of the below components modifies your Playground so you can monitor the inputs and outputs.
|
||||
|
||||
* Chat Input
|
||||
* Text Input
|
||||
* Chat Output
|
||||
* Text Output
|
||||
* Records Output
|
||||
* Inspect Memory
|
||||
- Chat Input
|
||||
- Text Input
|
||||
- Chat Output
|
||||
- Text Output
|
||||
- Records Output
|
||||
- Inspect Memory
|
||||
|
||||
You can also select **Options** > **Logs** to see your flow's logs.
|
||||
|
||||
For more information, see [Inputs and Outputs](../components/inputs-and-outputs.mdx).
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ One significant capability of the Chat Input component is its ability to transfo
|
|||
<ZoomableImage
|
||||
alt="Docusaurus themed image"
|
||||
sources={{
|
||||
light: ("img/playground-chat.png"),
|
||||
dark: ("img/playground-chat.png"),
|
||||
light: "img/playground-chat.png",
|
||||
dark: "img/playground-chat.png",
|
||||
}}
|
||||
style={{ width: "100%", maxWidth: "800px", margin: "0 auto" }}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ For example, the [Basic prompting](../starter-projects/basic-prompting.mdx) flow
|
|||
style={{ width: "100%", maxWidth: "800px", margin: "0 auto" }}
|
||||
/>
|
||||
|
||||
|
||||
In this flow, 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
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ You'll be presented with the following screen:
|
|||
light: "img/duplicate-space.png",
|
||||
dark: "img/duplicate-space.png",
|
||||
}}
|
||||
style={{ width: "80%", maxWidth: "800px", margin: "0 auto" }}
|
||||
style={{ width: "80%", maxWidth: "800px", margin: "0 auto" }}
|
||||
/>
|
||||
|
||||
Name your Space, define the visibility (Public or Private), and click on **Duplicate Space** to start the installation process. When installation is finished, you'll be redirected to the Space's main page to start using Langflow right away!
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ There are two possible reasons for this error:
|
|||
Clear the cache by deleting the contents of the cache folder.
|
||||
|
||||
This folder can be found at:
|
||||
- **Linux or WSL2 on Windows**: `home/<username>/.cache/langflow/`
|
||||
- **MacOS**: `/Users/<username>/Library/Caches/langflow/`
|
||||
|
||||
- **Linux or WSL2 on Windows**: `home/<username>/.cache/langflow/`
|
||||
- **MacOS**: `/Users/<username>/Library/Caches/langflow/`
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ Build a question-and-answer chatbot with a document loaded from local memory.
|
|||
light: "img/document-qa.png",
|
||||
dark: "img/document-qa.png",
|
||||
}}
|
||||
style={{ width: "100%", maxWidth: "800px", margin: "0 auto" }}
|
||||
style={{ width: "100%", maxWidth: "800px", margin: "0 auto" }}
|
||||
/>
|
||||
|
||||
This flow creates a basic chatbot with the **Chat Input**, **Prompt**, **OpenAI**, and **Chat Output** components.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ In this guide, we will use Astra DB as a vector store to store and retrieve the
|
|||
|
||||
<Admonition type="tip">
|
||||
This guide assumes that you have Langflow up and running. If you are new to
|
||||
Langflow, you can check out the [Getting Started](../getting-started/install-langflow.mdx) guide.
|
||||
Langflow, you can check out the [Getting
|
||||
Started](../getting-started/install-langflow.mdx) guide.
|
||||
</Admonition>
|
||||
|
||||
TLDR;
|
||||
|
|
|
|||
49
poetry.lock
generated
49
poetry.lock
generated
|
|
@ -471,17 +471,17 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "boto3"
|
||||
version = "1.34.123"
|
||||
version = "1.34.124"
|
||||
description = "The AWS SDK for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "boto3-1.34.123-py3-none-any.whl", hash = "sha256:56bec52d485d5670ce96d53ae7b2cd4ae4e8a705fb2298a21093cdd77d642331"},
|
||||
{file = "boto3-1.34.123.tar.gz", hash = "sha256:42b140fc850cf261ee4b1e8ef527fa071b1f1592a6d6a68d34b29f37cc46b4dd"},
|
||||
{file = "boto3-1.34.124-py3-none-any.whl", hash = "sha256:549d9735bbb7cf8e1a2f4b3b676be32946717c59f33c47234586835dc904d04e"},
|
||||
{file = "boto3-1.34.124.tar.gz", hash = "sha256:a91ee58fa54b170f17b2e144f038e155f92cf515f1c073ac2595e9ee45f125a8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
botocore = ">=1.34.123,<1.35.0"
|
||||
botocore = ">=1.34.124,<1.35.0"
|
||||
jmespath = ">=0.7.1,<2.0.0"
|
||||
s3transfer = ">=0.10.0,<0.11.0"
|
||||
|
||||
|
|
@ -490,13 +490,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
|
|||
|
||||
[[package]]
|
||||
name = "botocore"
|
||||
version = "1.34.123"
|
||||
version = "1.34.124"
|
||||
description = "Low-level, data-driven core of boto 3."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "botocore-1.34.123-py3-none-any.whl", hash = "sha256:8c34ada2a708c82e7174bff700611643db7ce2cb18f1130c35045c24310d299d"},
|
||||
{file = "botocore-1.34.123.tar.gz", hash = "sha256:a8577f6574600c4d159b5cd103ee05744a443d77f7778304e17307940b369c4f"},
|
||||
{file = "botocore-1.34.124-py3-none-any.whl", hash = "sha256:fede092c7f8f414f78f3e7991e47cb0cf2279d90c027606ad7cba79fa370b827"},
|
||||
{file = "botocore-1.34.124.tar.gz", hash = "sha256:3f0bf79c17d656acdfdb53581224f6a38867ff2829f7428c586198f67a90ea26"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -2616,13 +2616,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
|
|||
|
||||
[[package]]
|
||||
name = "google-api-python-client"
|
||||
version = "2.132.0"
|
||||
version = "2.133.0"
|
||||
description = "Google API Client Library for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "google-api-python-client-2.132.0.tar.gz", hash = "sha256:d6340dc83b72d72333cee5d50f7dcfecbff66a8783164090e945f985ec4c374d"},
|
||||
{file = "google_api_python_client-2.132.0-py2.py3-none-any.whl", hash = "sha256:cde87700bd4d37f39f5e940292c1c6cd0910990b5b01f50b1332a8cea38e8595"},
|
||||
{file = "google-api-python-client-2.133.0.tar.gz", hash = "sha256:293092905b66a046d3187a99ac454e12b00cc2c70444f26eb2f1f9c1a82720b4"},
|
||||
{file = "google_api_python_client-2.133.0-py2.py3-none-any.whl", hash = "sha256:396fe676ea0dfed066654dcf9f8dea77a1342f9d9bb23bb88e45b7b81e773926"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -3057,13 +3057,13 @@ test = ["objgraph", "psutil"]
|
|||
|
||||
[[package]]
|
||||
name = "groq"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0"
|
||||
description = "The official Python library for the groq API"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "groq-0.8.0-py3-none-any.whl", hash = "sha256:f5e4e892d45001241a930db451e633ca1f0007e3f749deaa5d7360062fcd61e3"},
|
||||
{file = "groq-0.8.0.tar.gz", hash = "sha256:37ceb2f706bd516d0bfcac8e89048a24b375172987a0d6bd9efb521c54f6deff"},
|
||||
{file = "groq-0.9.0-py3-none-any.whl", hash = "sha256:d0e46f4ad645504672bb09c8100af3ced3a7db0d5119dc13e4aca535fc455874"},
|
||||
{file = "groq-0.9.0.tar.gz", hash = "sha256:130ed5e35d3acfaab46b9e7a078eeaebf91052f4a9d71f86f87fb319b5fec332"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -4409,7 +4409,7 @@ six = "*"
|
|||
|
||||
[[package]]
|
||||
name = "langflow-base"
|
||||
version = "0.0.61"
|
||||
version = "0.0.63"
|
||||
description = "A Python package with a built-in web application"
|
||||
optional = false
|
||||
python-versions = ">=3.10,<3.13"
|
||||
|
|
@ -4466,13 +4466,13 @@ url = "src/backend/base"
|
|||
|
||||
[[package]]
|
||||
name = "langfuse"
|
||||
version = "2.35.2"
|
||||
version = "2.36.1"
|
||||
description = "A client library for accessing langfuse"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.8.1"
|
||||
files = [
|
||||
{file = "langfuse-2.35.2-py3-none-any.whl", hash = "sha256:d01a23842cab484594f03878aacb9732ef8fd361158eb819c7bf43f758a0954b"},
|
||||
{file = "langfuse-2.35.2.tar.gz", hash = "sha256:32b2e6c5bc71b4efdc430c6b964ab1c1e1ba1e105a4a73912c38b3959dc4502d"},
|
||||
{file = "langfuse-2.36.1-py3-none-any.whl", hash = "sha256:2cba244024bdf63aa3295bffada6b257497f9d18a3ca09026595470f46e09e5b"},
|
||||
{file = "langfuse-2.36.1.tar.gz", hash = "sha256:5117038d35d4629cfa37e8d89986132c926c52c05631cdfef4f9d54bc05591d8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -6966,13 +6966,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
|||
|
||||
[[package]]
|
||||
name = "pydantic-settings"
|
||||
version = "2.3.1"
|
||||
version = "2.3.2"
|
||||
description = "Settings management using Pydantic"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pydantic_settings-2.3.1-py3-none-any.whl", hash = "sha256:acb2c213140dfff9669f4fe9f8180d43914f51626db28ab2db7308a576cce51a"},
|
||||
{file = "pydantic_settings-2.3.1.tar.gz", hash = "sha256:e34bbd649803a6bb3e2f0f58fb0edff1f0c7f556849fda106cc21bcce12c30ab"},
|
||||
{file = "pydantic_settings-2.3.2-py3-none-any.whl", hash = "sha256:ae06e44349e4c7bff8d57aff415dfd397ae75c217a098d54e9e6990ad7594ac7"},
|
||||
{file = "pydantic_settings-2.3.2.tar.gz", hash = "sha256:05d33003c74c2cd585de97b59eb17b6ed67181bc8a3ce594d74b5d24e4df7323"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -8662,13 +8662,13 @@ typing = ["mypy (>=1.4)", "rich", "twisted"]
|
|||
|
||||
[[package]]
|
||||
name = "supabase"
|
||||
version = "2.5.0"
|
||||
version = "2.5.1"
|
||||
description = "Supabase client for Python."
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.8"
|
||||
files = [
|
||||
{file = "supabase-2.5.0-py3-none-any.whl", hash = "sha256:13e5ed9e9377a1a69e70ad18ed7b82997cf13ffcd28173952f7503e4d5067771"},
|
||||
{file = "supabase-2.5.0.tar.gz", hash = "sha256:133dc832dfdd617f2f90ac5b52664df96ac8a9302ac6656ee769dc3f545812f0"},
|
||||
{file = "supabase-2.5.1-py3-none-any.whl", hash = "sha256:74a1f24f04fede1967ef084b50dea688228f7b10eb2f9d73350fe2251a865188"},
|
||||
{file = "supabase-2.5.1.tar.gz", hash = "sha256:c50e0eba5b03de3abd5ac0f887957ca43558ba44c4d17bb44e73ec454b41734c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
@ -10505,6 +10505,7 @@ test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
|||
testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
||||
|
||||
[extras]
|
||||
cassio = ["cassio"]
|
||||
couchbase = ["couchbase"]
|
||||
deploy = ["celery", "flower", "redis"]
|
||||
local = ["ctransformers", "llama-cpp-python", "sentence-transformers"]
|
||||
|
|
@ -10512,4 +10513,4 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.10,<3.13"
|
||||
content-hash = "07b4a3ead472c37bcbb6179ac2802907c39688c50a6e36ddb41690b1c8e09b2d"
|
||||
content-hash = "6f5103d7e9f32094f0ebe8f192b1b967043382a1b2b97db42c3680cd0bc11efd"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "langflow"
|
||||
version = "1.0.0a50"
|
||||
version = "1.0.0a52"
|
||||
description = "A Python package with a built-in web application"
|
||||
authors = ["Langflow <contact@langflow.org>"]
|
||||
maintainers = [
|
||||
|
|
@ -87,7 +87,7 @@ markdown = "^3.6"
|
|||
langchain-chroma = "^0.1.1"
|
||||
upstash-vector = "^0.4.0"
|
||||
gitpython = "^3.1.43"
|
||||
cassio = "^0.1.7"
|
||||
cassio = { extras = ["cassio"], version = "^0.1.7", optional = true }
|
||||
unstructured = {extras = ["docx", "md", "pptx"], version = "^0.14.4"}
|
||||
|
||||
|
||||
|
|
@ -123,6 +123,7 @@ dictdiffer = "^0.9.0"
|
|||
[tool.poetry.extras]
|
||||
deploy = ["celery", "redis", "flower"]
|
||||
couchbase = ["couchbase"]
|
||||
cassio = ["cassio"]
|
||||
local = ["llama-cpp-python", "sentence-transformers", "ctransformers"]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,25 +31,60 @@ def create_flow(
|
|||
flow: FlowCreate,
|
||||
current_user: User = Depends(get_current_active_user),
|
||||
):
|
||||
"""Create a new flow."""
|
||||
if flow.user_id is None:
|
||||
flow.user_id = current_user.id
|
||||
try:
|
||||
"""Create a new flow."""
|
||||
if flow.user_id is None:
|
||||
flow.user_id = current_user.id
|
||||
|
||||
db_flow = Flow.model_validate(flow, from_attributes=True)
|
||||
db_flow.updated_at = datetime.now(timezone.utc)
|
||||
# First check if the flow.name is unique
|
||||
# there might be flows with name like: "MyFlow", "MyFlow (1)", "MyFlow (2)"
|
||||
# so we need to check if the name is unique with `like` operator
|
||||
# if we find a flow with the same name, we add a number to the end of the name
|
||||
# based on the highest number found
|
||||
if session.exec(select(Flow).where(Flow.name == flow.name).where(Flow.user_id == current_user.id)).first():
|
||||
flows = session.exec(
|
||||
select(Flow).where(Flow.name.like(f"{flow.name} (%")).where(Flow.user_id == current_user.id)
|
||||
).all()
|
||||
if flows:
|
||||
numbers = [int(flow.name.split("(")[1].split(")")[0]) for flow in flows]
|
||||
flow.name = f"{flow.name} ({max(numbers) + 1})"
|
||||
else:
|
||||
flow.name = f"{flow.name} (1)"
|
||||
|
||||
if db_flow.folder_id is None:
|
||||
# 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
|
||||
db_flow = Flow.model_validate(flow, from_attributes=True)
|
||||
db_flow.updated_at = datetime.now(timezone.utc)
|
||||
|
||||
session.add(db_flow)
|
||||
session.commit()
|
||||
session.refresh(db_flow)
|
||||
return db_flow
|
||||
if db_flow.folder_id is None:
|
||||
# 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
|
||||
|
||||
session.add(db_flow)
|
||||
session.commit()
|
||||
session.refresh(db_flow)
|
||||
return db_flow
|
||||
except Exception as e:
|
||||
# If it is a validation error, return the error message
|
||||
if hasattr(e, "errors"):
|
||||
raise HTTPException(status_code=400, detail=str(e)) from e
|
||||
elif "UNIQUE constraint failed" in str(e):
|
||||
# Get the name of the column that failed
|
||||
columns = str(e).split("UNIQUE constraint failed: ")[1].split(".")[1].split("\n")[0]
|
||||
# UNIQUE constraint failed: flow.user_id, flow.name
|
||||
# or UNIQUE constraint failed: flow.name
|
||||
# if the column has id in it, we want the other column
|
||||
column = columns.split(",")[1] if "id" in columns.split(",")[0] else columns.split(",")[0]
|
||||
|
||||
raise HTTPException(
|
||||
status_code=400, detail=f"{column.capitalize().replace('_', ' ')} must be unique"
|
||||
) from e
|
||||
elif isinstance(e, HTTPException):
|
||||
raise e
|
||||
else:
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/", response_model=list[FlowRead], status_code=200)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
from typing import List
|
||||
|
||||
from langflow.helpers.flow import generate_unique_flow_name
|
||||
from langflow.helpers.folders import generate_unique_folder_name
|
||||
import orjson
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, Response, UploadFile, status
|
||||
from sqlalchemy import or_, update
|
||||
|
|
@ -9,6 +7,8 @@ from sqlmodel import Session, select
|
|||
|
||||
from langflow.api.v1.flows import create_flows
|
||||
from langflow.api.v1.schemas import FlowListCreate, FlowListReadWithFolderName
|
||||
from langflow.helpers.flow import generate_unique_flow_name
|
||||
from langflow.helpers.folders import generate_unique_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,17 +35,27 @@ 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,
|
||||
# First check if the folder.name is unique
|
||||
# there might be flows with name like: "MyFlow", "MyFlow (1)", "MyFlow (2)"
|
||||
# so we need to check if the name is unique with `like` operator
|
||||
# if we find a flow with the same name, we add a number to the end of the name
|
||||
# based on the highest number found
|
||||
if session.exec(
|
||||
statement=select(Folder).where(Folder.name == new_folder.name).where(Folder.user_id == current_user.id)
|
||||
).first():
|
||||
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})"
|
||||
if folder_results:
|
||||
folder_names = [folder.name for folder in folder_results]
|
||||
folder_numbers = [int(name.split("(")[-1].split(")")[0]) for name in folder_names if "(" in name]
|
||||
if folder_numbers:
|
||||
new_folder.name = f"{new_folder.name} ({max(folder_numbers) + 1})"
|
||||
else:
|
||||
new_folder.name = f"{new_folder.name} (1)"
|
||||
|
||||
session.add(new_folder)
|
||||
session.commit()
|
||||
|
|
|
|||
|
|
@ -23,15 +23,15 @@ class ChatComponent(Component):
|
|||
"display_name": "Sender Type",
|
||||
"advanced": True,
|
||||
},
|
||||
"sender_name": {"display_name": "Sender Name"},
|
||||
"sender_name": {"display_name": "Sender Name", "advanced": True},
|
||||
"session_id": {
|
||||
"display_name": "Session ID",
|
||||
"info": "If provided, the message will be stored in the memory.",
|
||||
"advanced": True,
|
||||
},
|
||||
"return_record": {
|
||||
"display_name": "Return Record",
|
||||
"info": "Return the message as a record containing the sender, sender_name, and session_id.",
|
||||
"return_message": {
|
||||
"display_name": "Return Message",
|
||||
"info": "Return the message as a Message containing the sender, sender_name, and session_id.",
|
||||
"advanced": True,
|
||||
},
|
||||
"record_template": {
|
||||
|
|
@ -68,6 +68,7 @@ class ChatComponent(Component):
|
|||
input_value: Optional[Union[str, Record, Message]] = None,
|
||||
files: Optional[list[str]] = None,
|
||||
session_id: Optional[str] = None,
|
||||
return_message: Optional[bool] = False,
|
||||
) -> Message:
|
||||
message: Message | None = None
|
||||
|
||||
|
|
@ -78,7 +79,12 @@ class ChatComponent(Component):
|
|||
message = Message(
|
||||
text=input_value, sender=sender, sender_name=sender_name, files=files, session_id=session_id
|
||||
)
|
||||
self.status = message
|
||||
if session_id and isinstance(message, Message):
|
||||
if not return_message:
|
||||
message_text = message.text
|
||||
else:
|
||||
message_text = message
|
||||
|
||||
self.status = message_text
|
||||
if session_id and isinstance(message, Message) and isinstance(message.text, str):
|
||||
self.store_message(message)
|
||||
return message
|
||||
return message_text
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class URLComponent(CustomComponent):
|
|||
self,
|
||||
urls: list[str],
|
||||
) -> list[Record]:
|
||||
loader = WebBaseLoader(web_paths=urls)
|
||||
loader = WebBaseLoader(web_paths=[url for url in urls if url])
|
||||
docs = loader.load()
|
||||
records = self.to_records(docs)
|
||||
self.status = records
|
||||
|
|
|
|||
15
src/backend/base/langflow/components/experimental/Embed.py
Normal file
15
src/backend/base/langflow/components/experimental/Embed.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from langflow.custom import CustomComponent
|
||||
from langflow.schema import Record
|
||||
from langflow.field_typing import Embeddings
|
||||
|
||||
|
||||
class EmbedComponent(CustomComponent):
|
||||
display_name = "Embed Texts"
|
||||
|
||||
def build_config(self):
|
||||
return {"texts": {"display_name": "Texts"}, "embbedings": {"display_name": "Embeddings"}}
|
||||
|
||||
def build(self, texts: list[str], embbedings: Embeddings) -> Embeddings:
|
||||
vectors = Record(vector=embbedings.embed_documents(texts))
|
||||
self.status = vectors
|
||||
return vectors
|
||||
38
src/backend/base/langflow/components/experimental/Message.py
Normal file
38
src/backend/base/langflow/components/experimental/Message.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
from typing import Optional
|
||||
|
||||
from langflow.custom import CustomComponent
|
||||
from langflow.schema.message import Message
|
||||
|
||||
|
||||
class MessageComponent(CustomComponent):
|
||||
display_name = "Message"
|
||||
description = "Creates a Message object given a Session ID."
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
"sender": {
|
||||
"options": ["Machine", "User"],
|
||||
"display_name": "Sender Type",
|
||||
},
|
||||
"sender_name": {"display_name": "Sender Name"},
|
||||
"text": {"display_name": "Text"},
|
||||
"session_id": {
|
||||
"display_name": "Session ID",
|
||||
"info": "Session ID of the chat history.",
|
||||
"input_types": ["Text"],
|
||||
},
|
||||
}
|
||||
|
||||
def build(
|
||||
self,
|
||||
sender: str = "User",
|
||||
sender_name: Optional[str] = None,
|
||||
session_id: Optional[str] = None,
|
||||
text: str = "",
|
||||
) -> Message:
|
||||
message = Message(
|
||||
text=text, sender=sender, sender_name=sender_name, flow_id=self.graph.flow_id, session_id=session_id
|
||||
)
|
||||
|
||||
self.status = message
|
||||
return message
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from langflow.custom import CustomComponent
|
||||
from langflow.memory import get_messages, store_message
|
||||
from langflow.schema.message import Message
|
||||
|
|
@ -7,36 +5,18 @@ from langflow.schema.message import Message
|
|||
|
||||
class StoreMessageComponent(CustomComponent):
|
||||
display_name = "Store Message"
|
||||
description = "Stores a chat message given a Session ID."
|
||||
beta: bool = True
|
||||
description = "Stores a chat message."
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
"sender": {
|
||||
"options": ["Machine", "User"],
|
||||
"display_name": "Sender Type",
|
||||
},
|
||||
"sender_name": {"display_name": "Sender Name"},
|
||||
"message": {"display_name": "Message"},
|
||||
"session_id": {
|
||||
"display_name": "Session ID",
|
||||
"info": "Session ID of the chat history.",
|
||||
"input_types": ["Text"],
|
||||
},
|
||||
}
|
||||
|
||||
def build(
|
||||
self,
|
||||
sender: str = "User",
|
||||
sender_name: Optional[str] = None,
|
||||
session_id: Optional[str] = None,
|
||||
message: str = "",
|
||||
) -> List[Message]:
|
||||
store_message(
|
||||
message=Message(
|
||||
text=message, sender=sender, sender_name=sender_name, flow_id=self.graph.flow_id, session_id=session_id
|
||||
)
|
||||
)
|
||||
message: Message,
|
||||
) -> Message:
|
||||
store_message(message, flow_id=self.graph.flow_id)
|
||||
self.status = get_messages()
|
||||
|
||||
self.status = get_messages(session_id=session_id)
|
||||
return get_messages(session_id=session_id)
|
||||
return message
|
||||
|
|
|
|||
|
|
@ -6,25 +6,27 @@ from langflow.schema import Record
|
|||
|
||||
|
||||
class MessageHistoryComponent(CustomComponent):
|
||||
display_name = "Message History"
|
||||
description = "Retrieves stored chat messages given a specific Session ID."
|
||||
beta: bool = True
|
||||
display_name = "Memory"
|
||||
description = "Retrieves stored chat messages."
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
"sender": {
|
||||
"options": ["Machine", "User", "Machine and User"],
|
||||
"display_name": "Sender Type",
|
||||
"advanced": True,
|
||||
},
|
||||
"sender_name": {"display_name": "Sender Name", "advanced": True},
|
||||
"n_messages": {
|
||||
"display_name": "Number of Messages",
|
||||
"info": "Number of messages to retrieve.",
|
||||
"advanced": True,
|
||||
},
|
||||
"session_id": {
|
||||
"display_name": "Session ID",
|
||||
"info": "Session ID of the chat history.",
|
||||
"input_types": ["Text"],
|
||||
"advanced": True,
|
||||
},
|
||||
"order": {
|
||||
"options": ["Ascending", "Descending"],
|
||||
|
|
@ -39,7 +41,7 @@ class MessageHistoryComponent(CustomComponent):
|
|||
sender: Optional[str] = "Machine and User",
|
||||
sender_name: Optional[str] = None,
|
||||
session_id: Optional[str] = None,
|
||||
n_messages: int = 5,
|
||||
n_messages: int = 100,
|
||||
order: Optional[str] = "Descending",
|
||||
) -> List[Record]:
|
||||
order = "DESC" if order == "Descending" else "ASC"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue