Merge branch 'main' into feat/firecrawl-integration

This commit is contained in:
Rafael Miller 2024-06-25 17:25:58 -03:00 • committed by GitHub
commit 9373749163
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 773 additions and 518 deletions

47
.github/workflows/docs_test.yml vendored Normal file
View file

@ -0,0 +1,47 @@
name: Test Docs Build
on:
pull_request:
paths:
- "docs/**"
merge_group:
types: [checks_requested]
env:
NODE_VERSION: "21"
jobs:
test-docs-build:
name: Test Docs Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
id: setup-node
with:
node-version: ${{ env.NODE_VERSION }}
- name: Cache Node.js dependencies
uses: actions/cache@v4
id: npm-cache
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('docs/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install Node.js dependencies
run: |
cd docs
npm install
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
- name: Build Docs
run: |
cd docs
npm run build

View file

@ -2,19 +2,20 @@ name: Lint Python
on: on:
pull_request: pull_request:
types: [opened, synchronize, reopened]
paths: paths:
- "poetry.lock" - "poetry.lock"
- "pyproject.toml" - "pyproject.toml"
- "src/backend/**" - "src/backend/**"
- "tests/**" - "tests/**"
merge_group: merge_group:
branches: [dev] types: [checks_requested]
env: env:
POETRY_VERSION: "1.8.2" POETRY_VERSION: "1.8.2"
jobs: jobs:
lint: lint:
name: Run Mypy
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
@ -34,6 +35,8 @@ jobs:
run: | run: |
poetry env use ${{ matrix.python-version }} poetry env use ${{ matrix.python-version }}
poetry install poetry install
- name: Run Mypy
run: |
make lint make lint
env: env:
GITHUB_TOKEN: ${{ secrets.github_token }} GITHUB_TOKEN: ${{ secrets.github_token }}

View file

@ -1,26 +1,21 @@
name: Python tests name: Python tests
on: on:
push:
branches: [main]
paths:
- "poetry.lock"
- "pyproject.toml"
- "src/backend/**"
pull_request: pull_request:
branches: [dev] types: [opened, synchronize, reopened]
branches: [dev, main]
paths: paths:
- "poetry.lock" - "poetry.lock"
- "pyproject.toml" - "pyproject.toml"
- "src/backend/**" - "src/backend/**"
merge_group: merge_group:
branches: [dev] types: [checks_requested]
env: env:
POETRY_VERSION: "1.8.2" POETRY_VERSION: "1.8.2"
jobs: jobs:
build: build:
name: Run Unit Tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
@ -50,7 +45,7 @@ jobs:
poetry run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only & poetry run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only &
SERVER_PID=$! SERVER_PID=$!
# Wait for the server to start # Wait for the server to start
timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
# Terminate the server # Terminate the server
kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
sleep 10 # give the server some time to terminate sleep 10 # give the server some time to terminate

View file

@ -14,11 +14,7 @@ on:
required: false required: false
type: boolean type: boolean
default: true default: true
branch:
description: "Branch to release from"
required: true
type: string
default: "main"
env: env:
POETRY_VERSION: "1.8.2" POETRY_VERSION: "1.8.2"
@ -62,7 +58,7 @@ jobs:
python -m langflow run --host 127.0.0.1 --port 7860 & python -m langflow run --host 127.0.0.1 --port 7860 &
SERVER_PID=$! SERVER_PID=$!
# Wait for the server to start # Wait for the server to start
timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
# Terminate the server # Terminate the server
kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
sleep 10 # give the server some time to terminate sleep 10 # give the server some time to terminate
@ -124,7 +120,7 @@ jobs:
python -m langflow run --host 127.0.0.1 --port 7860 & python -m langflow run --host 127.0.0.1 --port 7860 &
SERVER_PID=$! SERVER_PID=$!
# Wait for the server to start # Wait for the server to start
timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/health; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1) timeout 120 bash -c 'until curl -f http://127.0.0.1:7860/auto_login; do sleep 2; done' || (echo "Server did not start in time" && kill $SERVER_PID && exit 1)
# Terminate the server # Terminate the server
kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1)
sleep 10 # give the server some time to terminate sleep 10 # give the server some time to terminate
@ -180,4 +176,4 @@ jobs:
generateReleaseNotes: true generateReleaseNotes: true
prerelease: ${{ inputs.pre_release }} prerelease: ${{ inputs.pre_release }}
tag: v${{ needs.release-main.outputs.version }} tag: v${{ needs.release-main.outputs.version }}
commit: ${{ inputs.branch }} commit: ${{ github.ref }}

View file

@ -1,9 +1,13 @@
name: Run Frontend Tests name: Run Frontend Tests
on: on:
pull_request: workflow_dispatch:
paths: inputs:
- "src/frontend/**" branch:
description: "Branch to run tests on"
required: true
type: string
env: env:
POETRY_VERSION: "1.8.2" POETRY_VERSION: "1.8.2"
@ -15,6 +19,7 @@ env:
jobs: jobs:
setup-and-test: setup-and-test:
name: Run Frontend Tests on branch ${{ inputs.branch }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
@ -24,6 +29,8 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
ref: ${{ inputs.branch }}
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
@ -88,7 +95,7 @@ jobs:
- name: Run Playwright Tests - name: Run Playwright Tests
run: | run: |
cd src/frontend cd src/frontend
npx playwright test --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2 npx playwright test --trace on --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --workers 2
- name: Upload blob report to GitHub Actions Artifacts - name: Upload blob report to GitHub Actions Artifacts
if: always() if: always()

10
.vscode/launch.json vendored
View file

@ -34,14 +34,12 @@
"args": [ "args": [
"run", "run",
"--path", "--path",
"${workspaceFolder}/src/backend/base/langflow/frontend" "${workspaceFolder}/src/backend/base/langflow/frontend",
"--env-file",
"${workspaceFolder}/.env"
], ],
"jinja": true, "jinja": true,
"justMyCode": false, "justMyCode": false
"env": {
"LANGFLOW_LOG_LEVEL": "debug"
},
"envFile": "${workspaceFolder}/.env"
}, },
{ {
"name": "Python: Remote Attach", "name": "Python: Remote Attach",

344
poetry.lock generated
View file

@ -368,13 +368,13 @@ files = [
[[package]] [[package]]
name = "bce-python-sdk" name = "bce-python-sdk"
version = "0.9.14" version = "0.9.17"
description = "BCE SDK for python" description = "BCE SDK for python"
optional = false optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,<4,>=2.7" python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,<4,>=2.7"
files = [ files = [
{file = "bce_python_sdk-0.9.14-py3-none-any.whl", hash = "sha256:5704aa454151ee608b01ddda7531457433f9b4bb8afbd00706dd368f3b4339a1"}, {file = "bce_python_sdk-0.9.17-py3-none-any.whl", hash = "sha256:6c5995d60edad3f6771b83ccd79197fc00d88081e3175ca8eecad8a29551ad75"},
{file = "bce_python_sdk-0.9.14.tar.gz", hash = "sha256:7cbd182ec1e21034f10d3cdb812f3171d31908f1a783d6cf643039272942d8e8"}, {file = "bce_python_sdk-0.9.17.tar.gz", hash = "sha256:aaece4c590b859ad6bc2d6a04b4a01308ac781ef1d539116b299ec50d62e1ca1"},
] ]
[package.dependencies] [package.dependencies]
@ -461,17 +461,17 @@ files = [
[[package]] [[package]]
name = "boto3" name = "boto3"
version = "1.34.131" version = "1.34.132"
description = "The AWS SDK for Python" description = "The AWS SDK for Python"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "boto3-1.34.131-py3-none-any.whl", hash = "sha256:05e388cb937e82be70bfd7eb0c84cf8011ff35cf582a593873ac21675268683b"}, {file = "boto3-1.34.132-py3-none-any.whl", hash = "sha256:b5d1681a0d8bf255787c8b37f911d706672d5722c9ace5342cd283a3cdb04820"},
{file = "boto3-1.34.131.tar.gz", hash = "sha256:dab8f72a6c4e62b4fd70da09e08a6b2a65ea2115b27dd63737142005776ef216"}, {file = "boto3-1.34.132.tar.gz", hash = "sha256:3b2964060620f1bbe9574b5f8d3fb2a4e087faacfc6023c24154b184f1b16443"},
] ]
[package.dependencies] [package.dependencies]
botocore = ">=1.34.131,<1.35.0" botocore = ">=1.34.132,<1.35.0"
jmespath = ">=0.7.1,<2.0.0" jmespath = ">=0.7.1,<2.0.0"
s3transfer = ">=0.10.0,<0.11.0" s3transfer = ">=0.10.0,<0.11.0"
@ -480,13 +480,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
[[package]] [[package]]
name = "botocore" name = "botocore"
version = "1.34.131" version = "1.34.132"
description = "Low-level, data-driven core of boto 3." description = "Low-level, data-driven core of boto 3."
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "botocore-1.34.131-py3-none-any.whl", hash = "sha256:13b011d7b206ce00727dcee26548fa3b550db9046d5a0e90ac25a6e6c8fde6ef"}, {file = "botocore-1.34.132-py3-none-any.whl", hash = "sha256:06ef8b4bd3b3cb5a9b9a4273a543b257be3304030978ba51516b576a65156c39"},
{file = "botocore-1.34.131.tar.gz", hash = "sha256:502ddafe1d627fcf1e4c007c86454e5dd011dba7c58bd8e8a5368a79f3e387dc"}, {file = "botocore-1.34.132.tar.gz", hash = "sha256:372a6cfce29e5de9bcf8c95af901d0bc3e27d8aa2295fadee295424f95f43f16"},
] ]
[package.dependencies] [package.dependencies]
@ -2576,13 +2576,13 @@ test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit",
[[package]] [[package]]
name = "google-ai-generativelanguage" name = "google-ai-generativelanguage"
version = "0.6.4" version = "0.6.5"
description = "Google Ai Generativelanguage API client library" description = "Google Ai Generativelanguage API client library"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "google-ai-generativelanguage-0.6.4.tar.gz", hash = "sha256:1750848c12af96cb24ae1c3dd05e4bfe24867dc4577009ed03e1042d8421e874"}, {file = "google-ai-generativelanguage-0.6.5.tar.gz", hash = "sha256:c4089c277fa4e26722f76ab03ee3039f28be8bf1c9be282948b9583a154c6d79"},
{file = "google_ai_generativelanguage-0.6.4-py3-none-any.whl", hash = "sha256:730e471aa549797118fb1c88421ba1957741433ada575cf5dd08d3aebf903ab1"}, {file = "google_ai_generativelanguage-0.6.5-py3-none-any.whl", hash = "sha256:236875bb4a6d6ebdba2f12bd9d5e776100fd913402157a47b5e9fb80a13f25a7"},
] ]
[package.dependencies] [package.dependencies]
@ -2896,16 +2896,16 @@ testing = ["pytest"]
[[package]] [[package]]
name = "google-generativeai" name = "google-generativeai"
version = "0.5.4" version = "0.7.0"
description = "Google Generative AI High level API client library and tools." description = "Google Generative AI High level API client library and tools."
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.9"
files = [ files = [
{file = "google_generativeai-0.5.4-py3-none-any.whl", hash = "sha256:036d63ee35e7c8aedceda4f81c390a5102808af09ff3a6e57e27ed0be0708f3c"}, {file = "google_generativeai-0.7.0-py3-none-any.whl", hash = "sha256:7be4b634afeb8b6bebde1af7271e94d2af84d2d28b5988c7ed9921733c40fe63"},
] ]
[package.dependencies] [package.dependencies]
google-ai-generativelanguage = "0.6.4" google-ai-generativelanguage = "0.6.5"
google-api-core = "*" google-api-core = "*"
google-api-python-client = "*" google-api-python-client = "*"
google-auth = ">=2.15.0" google-auth = ">=2.15.0"
@ -3812,72 +3812,72 @@ i18n = ["Babel (>=2.7)"]
[[package]] [[package]]
name = "jiter" name = "jiter"
version = "0.4.2" version = "0.5.0"
description = "Fast iterable JSON parser." description = "Fast iterable JSON parser."
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "jiter-0.4.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c2b003ff58d14f5e182b875acd5177b2367245c19a03be9a2230535d296f7550"}, {file = "jiter-0.5.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b599f4e89b3def9a94091e6ee52e1d7ad7bc33e238ebb9c4c63f211d74822c3f"},
{file = "jiter-0.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b48c77c25f094707731cd5bad6b776046846b60a27ee20efc8fadfb10a89415f"}, {file = "jiter-0.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a063f71c4b06225543dddadbe09d203dc0c95ba352d8b85f1221173480a71d5"},
{file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f50ad6b172bde4d45f4d4ea10c49282a337b8bb735afc99763dfa55ea84a743"}, {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc0d5b8b3dd12e91dd184b87273f864b363dfabc90ef29a1092d269f18c7e28"},
{file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95f6001e86f525fbbc9706db2078dc22be078b0950de55b92d37041930f5f940"}, {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c22541f0b672f4d741382a97c65609332a783501551445ab2df137ada01e019e"},
{file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16646ef23b62b007de80460d303ebb2d81e355dac9389c787cec87cdd7ffef2f"}, {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63314832e302cc10d8dfbda0333a384bf4bcfce80d65fe99b0f3c0da8945a91a"},
{file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b4e847c13b0bf1255c711a92330e7a8cb8b5cdd1e37d7db309627bcdd3367ff"}, {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a25fbd8a5a58061e433d6fae6d5298777c0814a8bcefa1e5ecfff20c594bd749"},
{file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c536589be60e4c5f2b20fadc4db7e9f55d4c9df3551f29ddf1c4a18dcc9dd54"}, {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:503b2c27d87dfff5ab717a8200fbbcf4714516c9d85558048b1fc14d2de7d8dc"},
{file = "jiter-0.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3b2763996167830889a854b4ded30bb90897f9b76be78069c50c3ec4540950e"}, {file = "jiter-0.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d1f3d27cce923713933a844872d213d244e09b53ec99b7a7fdf73d543529d6d"},
{file = "jiter-0.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:675e8ab98c99495091af6b6e9bf2b6353bcf81f25ab6ce27d36127e315b4505d"}, {file = "jiter-0.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c95980207b3998f2c3b3098f357994d3fd7661121f30669ca7cb945f09510a87"},
{file = "jiter-0.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e48e43d9d999aaf55f53406b8846ff8cbe3e47ee4b9dc37e5a10a65ce760809f"}, {file = "jiter-0.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:afa66939d834b0ce063f57d9895e8036ffc41c4bd90e4a99631e5f261d9b518e"},
{file = "jiter-0.4.2-cp310-none-win32.whl", hash = "sha256:881b6e67c50bc36acb3570eda693763c8cd77d590940e06fa6d325d0da52ec1b"}, {file = "jiter-0.5.0-cp310-none-win32.whl", hash = "sha256:f16ca8f10e62f25fd81d5310e852df6649af17824146ca74647a018424ddeccf"},
{file = "jiter-0.4.2-cp310-none-win_amd64.whl", hash = "sha256:bb8f7b43259efc6add0d721ade2953e064b24e2026d26d979bc09ec080844cef"}, {file = "jiter-0.5.0-cp310-none-win_amd64.whl", hash = "sha256:b2950e4798e82dd9176935ef6a55cf6a448b5c71515a556da3f6b811a7844f1e"},
{file = "jiter-0.4.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:24ad336ac47f274fa83f6fbedcabff9d3387c80f67c66b992688e6a8ba2c47e9"}, {file = "jiter-0.5.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4c8e1ed0ef31ad29cae5ea16b9e41529eb50a7fba70600008e9f8de6376d553"},
{file = "jiter-0.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fc392a220095730afe365ce1516f2f88bb085a2fd29ea191be9c6e3c71713d9a"}, {file = "jiter-0.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c6f16e21276074a12d8421692515b3fd6d2ea9c94fd0734c39a12960a20e85f3"},
{file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1fdc408de36c81460896de0176f2f7b9f3574dcd35693a0b2c00f4ca34c98e4"}, {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5280e68e7740c8c128d3ae5ab63335ce6d1fb6603d3b809637b11713487af9e6"},
{file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c10ad76722ee6a8c820b0db06a793c08b7d679e5201b9563015bd1e06c959a09"}, {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:583c57fc30cc1fec360e66323aadd7fc3edeec01289bfafc35d3b9dcb29495e4"},
{file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbb46d1e9c82bba87f0cbda38413e49448a7df35b1e55917124bff9f38974a23"}, {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26351cc14507bdf466b5f99aba3df3143a59da75799bf64a53a3ad3155ecded9"},
{file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:194e28ef4b5f3b61408cb2ee6b6dcbcdb0c9063d01b92b01345b7605692849f5"}, {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829df14d656b3fb87e50ae8b48253a8851c707da9f30d45aacab2aa2ba2d614"},
{file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0a447533eccd62748a727e058efa10a8d7cf1de8ffe1a4d705ecb41dad9090"}, {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42a4bdcf7307b86cb863b2fb9bb55029b422d8f86276a50487982d99eed7c6e"},
{file = "jiter-0.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5f7704d7260bbb88cca3453951af739589132b26e896a3144fa2dae2263716d7"}, {file = "jiter-0.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04d461ad0aebf696f8da13c99bc1b3e06f66ecf6cfd56254cc402f6385231c06"},
{file = "jiter-0.4.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:01427458bc9550f2eda09d425755330e7d0eb09adce099577433bebf05d28d59"}, {file = "jiter-0.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6375923c5f19888c9226582a124b77b622f8fd0018b843c45eeb19d9701c403"},
{file = "jiter-0.4.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:159b8416879c0053b17c352f70b67b749ef5b2924c6154318ecf71918aab0905"}, {file = "jiter-0.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cec323a853c24fd0472517113768c92ae0be8f8c384ef4441d3632da8baa646"},
{file = "jiter-0.4.2-cp311-none-win32.whl", hash = "sha256:f2445234acfb79048ce1a0d5d0e181abb9afd9e4a29d8d9988fe26cc5773a81a"}, {file = "jiter-0.5.0-cp311-none-win32.whl", hash = "sha256:aa1db0967130b5cab63dfe4d6ff547c88b2a394c3410db64744d491df7f069bb"},
{file = "jiter-0.4.2-cp311-none-win_amd64.whl", hash = "sha256:e15a65f233b6b0e5ac10ddf3b97ceb18aa9ffba096259961641d78b4ee321bd5"}, {file = "jiter-0.5.0-cp311-none-win_amd64.whl", hash = "sha256:aa9d2b85b2ed7dc7697597dcfaac66e63c1b3028652f751c81c65a9f220899ae"},
{file = "jiter-0.4.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d61d59521aea9745447ce50f74d39a16ef74ec9d6477d9350d77e75a3d774ad2"}, {file = "jiter-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9f664e7351604f91dcdd557603c57fc0d551bc65cc0a732fdacbf73ad335049a"},
{file = "jiter-0.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eef607dc0acc251923427808dbd017f1998ae3c1a0430a261527aa5cbb3a942"}, {file = "jiter-0.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:044f2f1148b5248ad2c8c3afb43430dccf676c5a5834d2f5089a4e6c5bbd64df"},
{file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af6bf39954646e374fc47429c656372ac731a6a26b644158a5a84bcdbed33a47"}, {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:702e3520384c88b6e270c55c772d4bd6d7b150608dcc94dea87ceba1b6391248"},
{file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f509d23606e476852ee46a2b65b5c4ad3905f17424d9cc19c1dffa1c94ba3c6"}, {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:528d742dcde73fad9d63e8242c036ab4a84389a56e04efd854062b660f559544"},
{file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59672774daa44ee140aada0c781c82bee4d9ac5e522966186cfb6b3c217d8a51"}, {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cf80e5fe6ab582c82f0c3331df27a7e1565e2dcf06265afd5173d809cdbf9ba"},
{file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24a0458efac5afeca254cf557b8a654e17013075a69905c78f88d557f129d871"}, {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:44dfc9ddfb9b51a5626568ef4e55ada462b7328996294fe4d36de02fce42721f"},
{file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8860766d1c293e75c1bb4e25b74fa987e3adf199cac3f5f9e6e49c2bebf092f"}, {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c451f7922992751a936b96c5f5b9bb9312243d9b754c34b33d0cb72c84669f4e"},
{file = "jiter-0.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a109f3281b72bbf4921fe43db1005c004a38559ca0b6c4985add81777dfe0a44"}, {file = "jiter-0.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:308fce789a2f093dca1ff91ac391f11a9f99c35369117ad5a5c6c4903e1b3e3a"},
{file = "jiter-0.4.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:faa7e667454b77ad2f0ef87db39f4944de759617aadf210ea2b73f26bb24755f"}, {file = "jiter-0.5.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7f5ad4a7c6b0d90776fdefa294f662e8a86871e601309643de30bf94bb93a64e"},
{file = "jiter-0.4.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3512f8b00cafb6780b427cb6282800d2bf8277161d9c917830661bd4ed1d3528"}, {file = "jiter-0.5.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ea189db75f8eca08807d02ae27929e890c7d47599ce3d0a6a5d41f2419ecf338"},
{file = "jiter-0.4.2-cp312-none-win32.whl", hash = "sha256:853b35d508ee5b66d06630473c1c0b7bb5e29bf4785c9d2202437116c94f7e21"}, {file = "jiter-0.5.0-cp312-none-win32.whl", hash = "sha256:e3bbe3910c724b877846186c25fe3c802e105a2c1fc2b57d6688b9f8772026e4"},
{file = "jiter-0.4.2-cp312-none-win_amd64.whl", hash = "sha256:4a3a8197784278eb8b24cb02c45e1cad67c2ce5b5b758adfb19b87f74bbdff9c"}, {file = "jiter-0.5.0-cp312-none-win_amd64.whl", hash = "sha256:a586832f70c3f1481732919215f36d41c59ca080fa27a65cf23d9490e75b2ef5"},
{file = "jiter-0.4.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ca2a4d750aed3154b89f2efb148609fc985fad8db739460797aaf9b478acedda"}, {file = "jiter-0.5.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f04bc2fc50dc77be9d10f73fcc4e39346402ffe21726ff41028f36e179b587e6"},
{file = "jiter-0.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0e6c304b3cc6896256727e1fb8991c7179a345eca8224e201795e9cacf4683b0"}, {file = "jiter-0.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6f433a4169ad22fcb550b11179bb2b4fd405de9b982601914ef448390b2954f3"},
{file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cc34ac708ae1750d077e490321761ec4b9a055b994cbdd1d6fbd37099e4aa7b"}, {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad4a6398c85d3a20067e6c69890ca01f68659da94d74c800298581724e426c7e"},
{file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c93383875ab8d2e4f760aaff335b4a12ff32d4f9cf49c4498d657734f611466"}, {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6baa88334e7af3f4d7a5c66c3a63808e5efbc3698a1c57626541ddd22f8e4fbf"},
{file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce197ee044add576afca0955b42142dd0312639adb6ebadbdbe4277f2855614f"}, {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ece0a115c05efca597c6d938f88c9357c843f8c245dbbb53361a1c01afd7148"},
{file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a427716813ff65480ca5b5117cfa099f49b49cd38051f8609bd0d5493013ca0"}, {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:335942557162ad372cc367ffaf93217117401bf930483b4b3ebdb1223dbddfa7"},
{file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:479990218353356234669e70fac53e5eb6f739a10db25316171aede2c97d9364"}, {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649b0ee97a6e6da174bffcb3c8c051a5935d7d4f2f52ea1583b5b3e7822fbf14"},
{file = "jiter-0.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d35a91ec5ac74cf33234c431505299fa91c0a197c2dbafd47400aca7c69489d4"}, {file = "jiter-0.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f4be354c5de82157886ca7f5925dbda369b77344b4b4adf2723079715f823989"},
{file = "jiter-0.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b27189847193708c94ad10ca0d891309342ae882725d2187cf5d2db02bde8d1b"}, {file = "jiter-0.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5206144578831a6de278a38896864ded4ed96af66e1e63ec5dd7f4a1fce38a3a"},
{file = "jiter-0.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:76c255308cd1093fb411a03756b7bb220e48d4a98c30cbc79ed448bf3978e27d"}, {file = "jiter-0.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8120c60f8121ac3d6f072b97ef0e71770cc72b3c23084c72c4189428b1b1d3b6"},
{file = "jiter-0.4.2-cp38-none-win32.whl", hash = "sha256:bb77438060bad49cc251941e6701b31138365c8a0ddaf10cdded2fcc6dd30701"}, {file = "jiter-0.5.0-cp38-none-win32.whl", hash = "sha256:6f1223f88b6d76b519cb033a4d3687ca157c272ec5d6015c322fc5b3074d8a5e"},
{file = "jiter-0.4.2-cp38-none-win_amd64.whl", hash = "sha256:ce858af19f7ce0d4b51c9f6c0c9d08f1e9dcef1986c5875efd0674a7054292ca"}, {file = "jiter-0.5.0-cp38-none-win_amd64.whl", hash = "sha256:c59614b225d9f434ea8fc0d0bec51ef5fa8c83679afedc0433905994fb36d631"},
{file = "jiter-0.4.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:6128838a2f357b3921b2a3242d5dc002ae4255ecc8f9f05c20d56d7d2d79c5ad"}, {file = "jiter-0.5.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0af3838cfb7e6afee3f00dc66fa24695199e20ba87df26e942820345b0afc566"},
{file = "jiter-0.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f2420cebb9ba856cb57dcab1d2d8def949b464b0db09c22a4e4dbd52fff7b200"}, {file = "jiter-0.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:550b11d669600dbc342364fd4adbe987f14d0bbedaf06feb1b983383dcc4b961"},
{file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5d13d8128e853b320e00bb18bd4bb8b136cc0936091dc87633648fc688eb705"}, {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:489875bf1a0ffb3cb38a727b01e6673f0f2e395b2aad3c9387f94187cb214bbf"},
{file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eba5d6e54f149c508ba88677f97d3dc7dd75e9980d234bbac8027ac6db0763a3"}, {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b250ca2594f5599ca82ba7e68785a669b352156260c5362ea1b4e04a0f3e2389"},
{file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0fad5d64af0bc0545237419bf4150d8de56f0bd217434bdd1a59730327252bef"}, {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ea18e01f785c6667ca15407cd6dabbe029d77474d53595a189bdc813347218e"},
{file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d179e7bca89cf5719bd761dd37a341ff0f98199ecaa9c14af09792e47e977cc"}, {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:462a52be85b53cd9bffd94e2d788a09984274fe6cebb893d6287e1c296d50653"},
{file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36353caee9f103d8ee7bda077f6400505b0f370e27eabcab33a33d21de12a2a6"}, {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92cc68b48d50fa472c79c93965e19bd48f40f207cb557a8346daa020d6ba973b"},
{file = "jiter-0.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dd146c25bce576ca5db64fc7eccb8862af00f1f0e30108796953f12a53660e4c"}, {file = "jiter-0.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c834133e59a8521bc87ebcad773608c6fa6ab5c7a022df24a45030826cf10bc"},
{file = "jiter-0.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:14b7c08cadbcd703041c66dc30e24e17de2f340281cac0e69374223ecf153aa4"}, {file = "jiter-0.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab3a71ff31cf2d45cb216dc37af522d335211f3a972d2fe14ea99073de6cb104"},
{file = "jiter-0.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a90f1a8b3d29aea198f8ea2b01148276ced8056e5103f32525266b3d880e65c9"}, {file = "jiter-0.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cccd3af9c48ac500c95e1bcbc498020c87e1781ff0345dd371462d67b76643eb"},
{file = "jiter-0.4.2-cp39-none-win32.whl", hash = "sha256:25b174997c780337b61ae57b1723455eecae9a17a9659044fd3c3b369190063f"}, {file = "jiter-0.5.0-cp39-none-win32.whl", hash = "sha256:368084d8d5c4fc40ff7c3cc513c4f73e02c85f6009217922d0823a48ee7adf61"},
{file = "jiter-0.4.2-cp39-none-win_amd64.whl", hash = "sha256:bef62cea18521c5b99368147040c7e560c55098a35c93456f110678a2d34189a"}, {file = "jiter-0.5.0-cp39-none-win_amd64.whl", hash = "sha256:ce03f7b4129eb72f1687fa11300fbf677b02990618428934662406d2a76742a1"},
{file = "jiter-0.4.2.tar.gz", hash = "sha256:29b9d44f23f0c05f46d482f4ebf03213ee290d77999525d0975a17f875bf1eea"}, {file = "jiter-0.5.0.tar.gz", hash = "sha256:1d916ba875bcab5c5f7d927df998c4cb694d27dceddf3392e58beaf10563368a"},
] ]
[[package]] [[package]]
@ -4292,40 +4292,40 @@ langchain-core = ">=0.2.7,<0.3.0"
[[package]] [[package]]
name = "langchain-google-genai" name = "langchain-google-genai"
version = "1.0.6" version = "1.0.7"
description = "An integration package connecting Google's genai package and LangChain" description = "An integration package connecting Google's genai package and LangChain"
optional = false optional = false
python-versions = "<4.0,>=3.9" python-versions = "<4.0,>=3.9"
files = [ files = [
{file = "langchain_google_genai-1.0.6-py3-none-any.whl", hash = "sha256:65188b3c2867efda78e09c29371499ab0d25c6a111b175365fdae2b5be1502e6"}, {file = "langchain_google_genai-1.0.7-py3-none-any.whl", hash = "sha256:8fc03a0b5f635d369d1eec25076921ea7a472a1cb96dbea8e8ff2c2cdce58650"},
{file = "langchain_google_genai-1.0.6.tar.gz", hash = "sha256:7c964117fa385c490b323ee50ab46907229823d3678b80bfacc8fa0a237fb0b9"}, {file = "langchain_google_genai-1.0.7.tar.gz", hash = "sha256:6522da59720ad551867e278d63c053e0fb65fa4fa1d65382aacedca5293930fa"},
] ]
[package.dependencies] [package.dependencies]
google-generativeai = ">=0.5.2,<0.6.0" google-generativeai = ">=0.7.0,<0.8.0"
langchain-core = ">=0.2.2,<0.3" langchain-core = ">=0.2.9,<0.3"
[package.extras] [package.extras]
images = ["pillow (>=10.1.0,<11.0.0)"] images = ["pillow (>=10.1.0,<11.0.0)"]
[[package]] [[package]]
name = "langchain-google-vertexai" name = "langchain-google-vertexai"
version = "1.0.5" version = "1.0.6"
description = "An integration package connecting Google VertexAI and LangChain" description = "An integration package connecting Google VertexAI and LangChain"
optional = false optional = false
python-versions = "<4.0,>=3.8.1" python-versions = "<4.0,>=3.8.1"
files = [ files = [
{file = "langchain_google_vertexai-1.0.5-py3-none-any.whl", hash = "sha256:38f4a39bf35927d744d0883907c4d4a59eef059e9b36f28bb5c737c2aae6963b"}, {file = "langchain_google_vertexai-1.0.6-py3-none-any.whl", hash = "sha256:240a9be3ae749335ec9a495502ca8f2bff60a432b8400a21cbd93b415e4d166d"},
{file = "langchain_google_vertexai-1.0.5.tar.gz", hash = "sha256:50005dc12ff9d66bbbab9e1ab660574b1584eee3e7b5a647dc8a009a94f0c500"}, {file = "langchain_google_vertexai-1.0.6.tar.gz", hash = "sha256:000c4cfd0dee73317e1752dfeec76a08c5bf24f7a134d79b9905a720ac886b11"},
] ]
[package.dependencies] [package.dependencies]
google-cloud-aiplatform = ">=1.47.0,<2.0.0" google-cloud-aiplatform = ">=1.56.0,<2.0.0"
google-cloud-storage = ">=2.14.0,<3.0.0" google-cloud-storage = ">=2.17.0,<3.0.0"
langchain-core = ">=0.2.2,<0.3" langchain-core = ">=0.2.9,<0.3"
[package.extras] [package.extras]
anthropic = ["anthropic[vertexai] (>=0.23.0,<1)"] anthropic = ["anthropic[vertexai] (>=0.29.0,<1)"]
[[package]] [[package]]
name = "langchain-groq" name = "langchain-groq"
@ -4456,7 +4456,7 @@ six = "*"
[[package]] [[package]]
name = "langflow-base" name = "langflow-base"
version = "0.0.78" version = "0.0.80"
description = "A Python package with a built-in web application" description = "A Python package with a built-in web application"
optional = false optional = false
python-versions = ">=3.10,<3.13" python-versions = ">=3.10,<3.13"
@ -4538,29 +4538,32 @@ openai = ["openai (>=0.27.8)"]
[[package]] [[package]]
name = "langsmith" name = "langsmith"
version = "0.1.81" version = "0.1.82"
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
optional = false optional = false
python-versions = "<4.0,>=3.8.1" python-versions = "<4.0,>=3.8.1"
files = [ files = [
{file = "langsmith-0.1.81-py3-none-any.whl", hash = "sha256:3251d823225eef23ee541980b9d9e506367eabbb7f985a086b5d09e8f78ba7e9"}, {file = "langsmith-0.1.82-py3-none-any.whl", hash = "sha256:9b3653e7d316036b0c60bf0bc3e280662d660f485a4ebd8e5c9d84f9831ae79c"},
{file = "langsmith-0.1.81.tar.gz", hash = "sha256:585ef3a2251380bd2843a664c9a28da4a7d28432e3ee8bcebf291ffb8e1f0af0"}, {file = "langsmith-0.1.82.tar.gz", hash = "sha256:c02e2bbc488c10c13b52c69d271eb40bd38da078d37b6ae7ae04a18bd48140be"},
] ]
[package.dependencies] [package.dependencies]
orjson = ">=3.9.14,<4.0.0" orjson = ">=3.9.14,<4.0.0"
pydantic = ">=1,<3" pydantic = [
{version = ">=1,<3", markers = "python_full_version < \"3.12.4\""},
{version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""},
]
requests = ">=2,<3" requests = ">=2,<3"
[[package]] [[package]]
name = "litellm" name = "litellm"
version = "1.40.25" version = "1.40.26"
description = "Library to easily interface with LLM API providers" description = "Library to easily interface with LLM API providers"
optional = false optional = false
python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8"
files = [ files = [
{file = "litellm-1.40.25-py3-none-any.whl", hash = "sha256:94bff834ca92338223bed474fe614ab30a706681a596e1e38ea60fe8a574a7a8"}, {file = "litellm-1.40.26-py3-none-any.whl", hash = "sha256:5daedec00a3a8e32f55b3099190ccd9d550177f6e516823002831e6620ae771c"},
{file = "litellm-1.40.25.tar.gz", hash = "sha256:437d515274b8cc901d527fbf14ce46599700225f4e1dae2d19b46b446e402b08"}, {file = "litellm-1.40.26.tar.gz", hash = "sha256:4dfd4ca3eb50a62600e60303c4975ba9fe7c52d07882d0d2b6bad2d474d88758"},
] ]
[package.dependencies] [package.dependencies]
@ -4604,13 +4607,13 @@ test = ["httpx (>=0.24.1)", "pytest (>=7.4.0)", "scipy (>=1.10)"]
[[package]] [[package]]
name = "locust" name = "locust"
version = "2.29.0" version = "2.29.1"
description = "Developer-friendly load testing framework" description = "Developer-friendly load testing framework"
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.9"
files = [ files = [
{file = "locust-2.29.0-py3-none-any.whl", hash = "sha256:aa9d94d3604ed9f2aab3248460d91e55d3de980a821dffdf8658b439b049d03f"}, {file = "locust-2.29.1-py3-none-any.whl", hash = "sha256:8b15daab44cdf50eef1860a32bb30969423e3795247115e5a37446da3240c6d6"},
{file = "locust-2.29.0.tar.gz", hash = "sha256:649c99ce49d00720a3084c0109547035ad9021222835386599a8b545d31ebe51"}, {file = "locust-2.29.1.tar.gz", hash = "sha256:2e0628a59e2689a50cb4735a9a43709e30f2da7ed276c15d877c5325507f44b1"},
] ]
[package.dependencies] [package.dependencies]
@ -4629,6 +4632,7 @@ requests = [
{version = ">=2.26.0", markers = "python_version <= \"3.11\""}, {version = ">=2.26.0", markers = "python_version <= \"3.11\""},
] ]
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.11\""}
Werkzeug = ">=2.0.0" Werkzeug = ">=2.0.0"
[[package]] [[package]]
@ -5335,38 +5339,38 @@ dill = ">=0.3.8"
[[package]] [[package]]
name = "mypy" name = "mypy"
version = "1.10.0" version = "1.10.1"
description = "Optional static typing for Python" description = "Optional static typing for Python"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"},
{file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"},
{file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"},
{file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"},
{file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"},
{file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"},
{file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"},
{file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"},
{file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"},
{file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"},
{file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"},
{file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"},
{file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"},
{file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"},
{file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"},
{file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"},
{file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"},
{file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"},
{file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"},
{file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"},
{file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"},
{file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"},
{file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"},
{file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"},
{file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"},
{file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"},
{file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"},
] ]
[package.dependencies] [package.dependencies]
@ -8107,13 +8111,13 @@ files = [
[[package]] [[package]]
name = "s3transfer" name = "s3transfer"
version = "0.10.1" version = "0.10.2"
description = "An Amazon S3 Transfer Manager" description = "An Amazon S3 Transfer Manager"
optional = false optional = false
python-versions = ">= 3.8" python-versions = ">=3.8"
files = [ files = [
{file = "s3transfer-0.10.1-py3-none-any.whl", hash = "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"}, {file = "s3transfer-0.10.2-py3-none-any.whl", hash = "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"},
{file = "s3transfer-0.10.1.tar.gz", hash = "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19"}, {file = "s3transfer-0.10.2.tar.gz", hash = "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6"},
] ]
[package.dependencies] [package.dependencies]
@ -8291,45 +8295,45 @@ tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc (
[[package]] [[package]]
name = "scipy" name = "scipy"
version = "1.13.1" version = "1.14.0"
description = "Fundamental algorithms for scientific computing in Python" description = "Fundamental algorithms for scientific computing in Python"
optional = true optional = true
python-versions = ">=3.9" python-versions = ">=3.10"
files = [ files = [
{file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, {file = "scipy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484"},
{file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, {file = "scipy-1.14.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6"},
{file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7"},
{file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1"},
{file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0"},
{file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0"},
{file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, {file = "scipy-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d"},
{file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, {file = "scipy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359"},
{file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, {file = "scipy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e"},
{file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, {file = "scipy-1.14.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"},
{file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf"},
{file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86"},
{file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8"},
{file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74"},
{file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, {file = "scipy-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb"},
{file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, {file = "scipy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc"},
{file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, {file = "scipy-1.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9"},
{file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, {file = "scipy-1.14.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4"},
{file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0"},
{file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f"},
{file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209"},
{file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14"},
{file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, {file = "scipy-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159"},
{file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, {file = "scipy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20"},
{file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, {file = "scipy-1.14.0.tar.gz", hash = "sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b"},
] ]
[package.dependencies] [package.dependencies]
numpy = ">=1.22.4,<2.3" numpy = ">=1.23.5,<2.3"
[package.extras] [package.extras]
dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "types-psutil", "typing_extensions"] dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"]
doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.12.0)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"]
test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"]
[[package]] [[package]]
name = "sentence-transformers" name = "sentence-transformers"
@ -8409,13 +8413,13 @@ tornado = ["tornado (>=5)"]
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "70.1.0" version = "70.1.1"
description = "Easily download, build, install, upgrade, and uninstall Python packages" description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "setuptools-70.1.0-py3-none-any.whl", hash = "sha256:d9b8b771455a97c8a9f3ab3448ebe0b29b5e105f1228bba41028be116985a267"}, {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"},
{file = "setuptools-70.1.0.tar.gz", hash = "sha256:01a1e793faa5bd89abc851fa15d0a0db26f160890c7102cd8dce643e886b47f5"}, {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"},
] ]
[package.extras] [package.extras]
@ -9405,13 +9409,13 @@ urllib3 = ">=2"
[[package]] [[package]]
name = "types-setuptools" name = "types-setuptools"
version = "70.0.0.20240524" version = "70.1.0.20240625"
description = "Typing stubs for setuptools" description = "Typing stubs for setuptools"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "types-setuptools-70.0.0.20240524.tar.gz", hash = "sha256:e31fee7b9d15ef53980526579ac6089b3ae51a005a281acf97178e90ac71aff6"}, {file = "types-setuptools-70.1.0.20240625.tar.gz", hash = "sha256:eb7175c9a304de4de9f4dfd0f299c754ac94cd9e30a262fbb5ff3047a0a6c517"},
{file = "types_setuptools-70.0.0.20240524-py3-none-any.whl", hash = "sha256:8f5379b9948682d72a9ab531fbe52932e84c4f38deda570255f9bae3edd766bc"}, {file = "types_setuptools-70.1.0.20240625-py3-none-any.whl", hash = "sha256:181986729bdae9fa7efc7d37f1578361739e35dd6ec456d37de8e8f3bd2be1ef"},
] ]
[[package]] [[package]]

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "langflow" name = "langflow"
version = "1.0.3" version = "1.0.5"
description = "A Python package with a built-in web application" description = "A Python package with a built-in web application"
authors = ["Langflow <contact@langflow.org>"] authors = ["Langflow <contact@langflow.org>"]
maintainers = [ maintainers = [

View file

@ -4,12 +4,12 @@ import sys
import time import time
import warnings import warnings
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Any, Callable, Optional
import click import click
import httpx import httpx
import typer import typer
from dotenv import load_dotenv from dotenv import dotenv_values, load_dotenv
from multiprocess import Process, cpu_count # type: ignore from multiprocess import Process, cpu_count # type: ignore
from packaging import version as pkg_version from packaging import version as pkg_version
from rich import box from rich import box
@ -130,6 +130,29 @@ def run(
if env_file: if env_file:
load_dotenv(env_file, override=True) load_dotenv(env_file, override=True)
env_vars = dotenv_values(env_file)
# Define a mapping of environment variables to their corresponding variables and types
env_var_mapping: dict[str, tuple[str, type | Callable[[Any], bool]]] = {
"LANGFLOW_HOST": ("host", str),
"LANGFLOW_PORT": ("port", int),
"LANGFLOW_WORKERS": ("workers", int),
"LANGFLOW_WORKER_TIMEOUT": ("timeout", int),
"LANGFLOW_COMPONENTS_PATH": ("components_path", Path),
"LANGFLOW_LOG_LEVEL": ("log_level", str),
"LANGFLOW_LOG_FILE": ("log_file", Path),
"LANGFLOW_LANGCHAIN_CACHE": ("cache", str),
"LANGFLOW_FRONTEND_PATH": ("path", str),
"LANGFLOW_OPEN_BROWSER": ("open_browser", lambda x: x.lower() == "true"),
"LANGFLOW_REMOVE_API_KEYS": ("remove_api_keys", lambda x: x.lower() == "true"),
"LANGFLOW_BACKEND_ONLY": ("backend_only", lambda x: x.lower() == "true"),
"LANGFLOW_STORE": ("store", lambda x: x.lower() == "true"),
}
# Update variables based on environment variables
for env_var, (var_name, var_type) in env_var_mapping.items():
if env_var in env_vars:
locals()[var_name] = var_type(env_vars[env_var])
update_settings( update_settings(
dev=dev, dev=dev,

View file

@ -121,9 +121,9 @@ async def retrieve_vertices_order(
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_playground, telemetry_service.log_package_playground,
PlaygroundPayload( PlaygroundPayload(
seconds=int(time.perf_counter() - start_time), playgroundSeconds=int(time.perf_counter() - start_time),
componentCount=components_count, playgroundComponentCount=components_count,
success=True, playgroundSuccess=True,
), ),
) )
return VerticesOrderResponse(ids=first_layer, run_id=graph._run_id, vertices_to_run=vertices_to_run) return VerticesOrderResponse(ids=first_layer, run_id=graph._run_id, vertices_to_run=vertices_to_run)
@ -131,10 +131,10 @@ async def retrieve_vertices_order(
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_playground, telemetry_service.log_package_playground,
PlaygroundPayload( PlaygroundPayload(
seconds=int(time.perf_counter() - start_time), playgroundSeconds=int(time.perf_counter() - start_time),
componentCount=components_count, playgroundComponentCount=components_count,
success=False, playgroundSuccess=False,
errorMessage=str(exc), playgroundErrorMessage=str(exc),
), ),
) )
if "stream or streaming set to True" in str(exc): if "stream or streaming set to True" in str(exc):
@ -280,10 +280,10 @@ async def build_vertex(
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_component, telemetry_service.log_package_component,
ComponentPayload( ComponentPayload(
name=vertex_id, componentName=vertex_id,
seconds=int(time.perf_counter() - start_time), componentSeconds=int(time.perf_counter() - start_time),
success=valid, componentSuccess=valid,
errorMessage=params, componentErrorMessage=params,
), ),
) )
return build_response return build_response
@ -291,10 +291,10 @@ async def build_vertex(
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_component, telemetry_service.log_package_component,
ComponentPayload( ComponentPayload(
name=vertex_id, componentName=vertex_id,
seconds=int(time.perf_counter() - start_time), componentSeconds=int(time.perf_counter() - start_time),
success=False, componentSuccess=False,
errorMessage=str(exc), componentErrorMessage=str(exc),
), ),
) )
logger.error(f"Error building Component:\n\n{exc}") logger.error(f"Error building Component:\n\n{exc}")

View file

@ -116,11 +116,29 @@ async def simple_run_flow(
return RunResponse(outputs=task_result, session_id=session_id) return RunResponse(outputs=task_result, session_id=session_id)
except sa.exc.StatementError as exc: except sa.exc.StatementError as exc:
# StatementError('(builtins.ValueError) badly formed hexadecimal UUID string') raise ValueError(str(exc)) from exc
if "badly formed hexadecimal UUID string" in str(exc):
logger.error(f"Flow ID {flow_id_str} is not a valid UUID")
# This means the Flow ID is not a valid UUID which means it can't find the flow async def simple_run_flow_task(
raise ValueError(str(exc)) from exc flow: Flow,
input_request: SimplifiedAPIRequest,
stream: bool = False,
api_key_user: Optional[User] = None,
):
"""
Run a flow task as a BackgroundTask, therefore it should not throw exceptions.
"""
try:
result = await simple_run_flow(
flow=flow,
input_request=input_request,
stream=stream,
api_key_user=api_key_user,
)
return result
except Exception as exc:
logger.exception(f"Error running flow {flow.id} task: {exc}")
@router.post("/run/{flow_id_or_name}", response_model=RunResponse, response_model_exclude_none=True) @router.post("/run/{flow_id_or_name}", response_model=RunResponse, response_model_exclude_none=True)
@ -191,7 +209,7 @@ async def simplified_run_flow(
end_time = time.perf_counter() end_time = time.perf_counter()
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_run, telemetry_service.log_package_run,
RunPayload(IsWebhook=False, seconds=int(end_time - start_time), success=True, errorMessage=""), RunPayload(runIsWebhook=False, runSeconds=int(end_time - start_time), runSuccess=True, runErrorMessage=""),
) )
return result return result
@ -199,7 +217,9 @@ async def simplified_run_flow(
end_time = time.perf_counter() end_time = time.perf_counter()
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_run, telemetry_service.log_package_run,
RunPayload(IsWebhook=False, seconds=int(end_time - start_time), success=False, errorMessage=str(exc)), RunPayload(
runIsWebhook=False, runSeconds=int(end_time - start_time), runSuccess=False, runErrorMessage=str(exc)
),
) )
if "badly formed hexadecimal UUID string" in str(exc): if "badly formed hexadecimal UUID string" in str(exc):
# This means the Flow ID is not a valid UUID which means it can't find the flow # This means the Flow ID is not a valid UUID which means it can't find the flow
@ -213,7 +233,9 @@ async def simplified_run_flow(
logger.exception(exc) logger.exception(exc)
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_run, telemetry_service.log_package_run,
RunPayload(IsWebhook=False, seconds=int(end_time - start_time), success=False, errorMessage=str(exc)), RunPayload(
runIsWebhook=False, runSeconds=int(end_time - start_time), runSuccess=False, runErrorMessage=str(exc)
),
) )
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)) from exc raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)) from exc
@ -266,20 +288,25 @@ async def webhook_run_flow(
) )
logger.debug("Starting background task") logger.debug("Starting background task")
background_tasks.add_task( # type: ignore background_tasks.add_task( # type: ignore
simple_run_flow, simple_run_flow_task,
flow=flow, flow=flow,
input_request=input_request, input_request=input_request,
) )
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_run, telemetry_service.log_package_run,
RunPayload(IsWebhook=True, seconds=int(time.perf_counter() - start_time), success=True, errorMessage=""), RunPayload(
runIsWebhook=True, runSeconds=int(time.perf_counter() - start_time), runSuccess=True, runErrorMessage=""
),
) )
return {"message": "Task started in the background", "status": "in progress"} return {"message": "Task started in the background", "status": "in progress"}
except Exception as exc: except Exception as exc:
background_tasks.add_task( background_tasks.add_task(
telemetry_service.log_package_run, telemetry_service.log_package_run,
RunPayload( RunPayload(
IsWebhook=True, seconds=int(time.perf_counter() - start_time), success=False, errorMessage=str(exc) runIsWebhook=True,
runSeconds=int(time.perf_counter() - start_time),
runSuccess=False,
runErrorMessage=str(exc),
), ),
) )
if "Flow ID is required" in str(exc) or "Request body is empty" in str(exc): if "Flow ID is required" in str(exc) or "Request body is empty" in str(exc):

View file

@ -209,6 +209,23 @@ def update_flow(
webhook_component = get_webhook_component_in_flow(db_flow.data) webhook_component = get_webhook_component_in_flow(db_flow.data)
db_flow.webhook = webhook_component is not None db_flow.webhook = webhook_component is not None
db_flow.updated_at = datetime.now(timezone.utc) 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
flow_from_db = session.exec(select(Flow).where(Flow.id == flow_id, Flow.user_id == current_user.id)).first()
if flow_from_db:
flows = session.exec(
select(Flow).where(Flow.name.like(f"{flow.name} (%")).where(Flow.user_id == current_user.id) # type: ignore
).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: if db_flow.folder_id is None:
default_folder = session.exec(select(Folder).where(Folder.name == DEFAULT_FOLDER_NAME)).first() default_folder = session.exec(select(Folder).where(Folder.name == DEFAULT_FOLDER_NAME)).first()
if default_folder: if default_folder:

View file

@ -3,44 +3,40 @@ from pydantic.v1 import SecretStr
from langflow.base.constants import STREAM_INFO_TEXT from langflow.base.constants import STREAM_INFO_TEXT
from langflow.base.models.model import LCModelComponent from langflow.base.models.model import LCModelComponent
from langflow.field_typing import LanguageModel from langflow.field_typing import LanguageModel
from langflow.io import BoolInput, DropdownInput, FloatInput, IntInput, MessageInput, Output, SecretStrInput, StrInput from langflow.inputs import (
BoolInput,
DropdownInput,
FloatInput,
IntInput,
MessageInput,
SecretStrInput,
StrInput,
)
class GoogleGenerativeAIComponent(LCModelComponent): class GoogleGenerativeAIComponent(LCModelComponent):
display_name: str = "Google Generative AI" display_name = "Google Generative AI"
description: str = "Generate text using Google Generative AI." description = "Generate text using Google Generative AI."
icon = "GoogleGenerativeAI" icon = "GoogleGenerativeAI"
inputs = [ inputs = [
SecretStrInput( MessageInput(name="input_value", display_name="Input"),
name="google_api_key", IntInput(
display_name="Google API Key", name="max_output_tokens",
info="The Google API Key to use for the Google Generative AI.", display_name="Max Output Tokens",
info="The maximum number of tokens to generate.",
), ),
DropdownInput( DropdownInput(
name="model", name="model",
display_name="Model", display_name="Model",
info="The name of the model to use.", info="The name of the model to use.",
options=["gemini-1.5-pro", "gemini-1.5-flash"], options=["gemini-1.5-pro", "gemini-1.5-flash", "gemini-1.0-pro", "gemini-1.0-pro-vision"],
value="gemini-1.5-pro", value="gemini-1.5-pro",
), ),
IntInput( SecretStrInput(
name="max_output_tokens", name="google_api_key",
display_name="Max Output Tokens", display_name="Google API Key",
info="The maximum number of tokens to generate.", info="The Google API Key to use for the Google Generative AI.",
advanced=True,
),
FloatInput(
name="temperature",
display_name="Temperature",
info="Run inference with this temperature. Must by in the closed interval [0.0, 1.0].",
value=0.1,
),
IntInput(
name="top_k",
display_name="Top K",
info="Decode using top-k sampling: consider the set of top_k most probable tokens. Must be positive.",
advanced=True,
), ),
FloatInput( FloatInput(
name="top_p", name="top_p",
@ -48,29 +44,26 @@ class GoogleGenerativeAIComponent(LCModelComponent):
info="The maximum cumulative probability of tokens to consider when sampling.", info="The maximum cumulative probability of tokens to consider when sampling.",
advanced=True, advanced=True,
), ),
FloatInput(name="temperature", display_name="Temperature", value=0.1),
BoolInput(name="stream", display_name="Stream", info=STREAM_INFO_TEXT, advanced=True),
IntInput( IntInput(
name="n", name="n",
display_name="N", display_name="N",
info="Number of chat completions to generate for each prompt. Note that the API may not return the full n completions if duplicates are generated.", info="Number of chat completions to generate for each prompt. Note that the API may not return the full n completions if duplicates are generated.",
advanced=True, advanced=True,
), ),
MessageInput(
name="input_value",
display_name="Input",
info="The input to the model.",
input_types=["Text", "Data", "Prompt"],
),
BoolInput(name="stream", display_name="Stream", info=STREAM_INFO_TEXT, advanced=True),
StrInput( StrInput(
name="system_message", name="system_message",
display_name="System Message", display_name="System Message",
info="System message to pass to the model.", info="System message to pass to the model.",
advanced=True, advanced=True,
), ),
] IntInput(
outputs = [ name="top_k",
Output(display_name="Text", name="text_output", method="text_response"), display_name="Top K",
Output(display_name="Language Model", name="model_output", method="build_model"), info="Decode using top-k sampling: consider the set of top_k most probable tokens. Must be positive.",
advanced=True,
),
] ]
def build_model(self) -> LanguageModel: def build_model(self) -> LanguageModel:

View file

@ -164,15 +164,15 @@ async def get_current_user_for_websocket(
def get_current_active_user(current_user: Annotated[User, Depends(get_current_user)]): def get_current_active_user(current_user: Annotated[User, Depends(get_current_user)]):
if not current_user.is_active: if not current_user.is_active:
raise HTTPException(status_code=400, detail="Inactive user") raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive user")
return current_user return current_user
def get_current_active_superuser(current_user: Annotated[User, Depends(get_current_user)]) -> User: def get_current_active_superuser(current_user: Annotated[User, Depends(get_current_user)]) -> User:
if not current_user.is_active: if not current_user.is_active:
raise HTTPException(status_code=401, detail="Inactive user") raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive user")
if not current_user.is_superuser: if not current_user.is_superuser:
raise HTTPException(status_code=400, detail="The user doesn't have enough privileges") raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="The user doesn't have enough privileges")
return current_user return current_user
@ -324,8 +324,8 @@ def authenticate_user(username: str, password: str, db: Session = Depends(get_se
if not user.is_active: if not user.is_active:
if not user.last_login_at: if not user.last_login_at:
raise HTTPException(status_code=400, detail="Waiting for approval") raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Waiting for approval")
raise HTTPException(status_code=400, detail="Inactive user") raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive user")
return user if verify_password(password, user.password) else None return user if verify_password(password, user.password) else None

View file

@ -2,10 +2,10 @@ from pydantic import BaseModel
class RunPayload(BaseModel): class RunPayload(BaseModel):
IsWebhook: bool = False runIsWebhook: bool = False
seconds: int runSeconds: int
success: bool runSuccess: bool
errorMessage: str = "" runErrorMessage: str = ""
class ShutdownPayload(BaseModel): class ShutdownPayload(BaseModel):
@ -23,14 +23,14 @@ class VersionPayload(BaseModel):
class PlaygroundPayload(BaseModel): class PlaygroundPayload(BaseModel):
seconds: int playgroundSeconds: int
componentCount: int | None = None playgroundComponentCount: int | None = None
success: bool playgroundSuccess: bool
errorMessage: str = "" playgroundErrorMessage: str = ""
class ComponentPayload(BaseModel): class ComponentPayload(BaseModel):
name: str componentName: str
seconds: int componentSeconds: int
success: bool componentSuccess: bool
errorMessage: str componentErrorMessage: str

View file

@ -1295,18 +1295,21 @@ types-requests = ">=2.31.0.2,<3.0.0.0"
[[package]] [[package]]
name = "langsmith" name = "langsmith"
version = "0.1.81" version = "0.1.82"
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
optional = false optional = false
python-versions = "<4.0,>=3.8.1" python-versions = "<4.0,>=3.8.1"
files = [ files = [
{file = "langsmith-0.1.81-py3-none-any.whl", hash = "sha256:3251d823225eef23ee541980b9d9e506367eabbb7f985a086b5d09e8f78ba7e9"}, {file = "langsmith-0.1.82-py3-none-any.whl", hash = "sha256:9b3653e7d316036b0c60bf0bc3e280662d660f485a4ebd8e5c9d84f9831ae79c"},
{file = "langsmith-0.1.81.tar.gz", hash = "sha256:585ef3a2251380bd2843a664c9a28da4a7d28432e3ee8bcebf291ffb8e1f0af0"}, {file = "langsmith-0.1.82.tar.gz", hash = "sha256:c02e2bbc488c10c13b52c69d271eb40bd38da078d37b6ae7ae04a18bd48140be"},
] ]
[package.dependencies] [package.dependencies]
orjson = ">=3.9.14,<4.0.0" orjson = ">=3.9.14,<4.0.0"
pydantic = ">=1,<3" pydantic = [
{version = ">=1,<3", markers = "python_full_version < \"3.12.4\""},
{version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""},
]
requests = ">=2,<3" requests = ">=2,<3"
[[package]] [[package]]

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "langflow-base" name = "langflow-base"
version = "0.0.79" version = "0.0.81"
description = "A Python package with a built-in web application" description = "A Python package with a built-in web application"
authors = ["Langflow <contact@langflow.org>"] authors = ["Langflow <contact@langflow.org>"]
maintainers = [ maintainers = [

View file

@ -102,7 +102,7 @@
"postcss": "^8.4.38", "postcss": "^8.4.38",
"prettier": "^3.3.2", "prettier": "^3.3.2",
"prettier-plugin-organize-imports": "^3.2.4", "prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.6.4", "prettier-plugin-tailwindcss": "^0.6.5",
"simple-git-hooks": "^2.11.1", "simple-git-hooks": "^2.11.1",
"tailwindcss": "^3.4.4", "tailwindcss": "^3.4.4",
"tailwindcss-dotted-background": "^1.1.0", "tailwindcss-dotted-background": "^1.1.0",

View file

@ -113,18 +113,18 @@
"@testing-library/react": "^16.0.0", "@testing-library/react": "^16.0.0",
"@testing-library/user-event": "^14.5.2", "@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"@types/lodash": "4.17.5",
"@types/node": "^20.14.2", "@types/node": "^20.14.2",
"@types/react": "^18.3.3", "@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"@types/uuid": "^9.0.8", "@types/uuid": "^9.0.8",
"@types/lodash": "4.17.5",
"@vitejs/plugin-react-swc": "^3.7.0", "@vitejs/plugin-react-swc": "^3.7.0",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"eslint": "^9.5.0", "eslint": "^9.5.0",
"postcss": "^8.4.38", "postcss": "^8.4.38",
"prettier": "^3.3.2", "prettier": "^3.3.2",
"prettier-plugin-organize-imports": "^3.2.4", "prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.6.4", "prettier-plugin-tailwindcss": "^0.6.5",
"simple-git-hooks": "^2.11.1", "simple-git-hooks": "^2.11.1",
"tailwindcss": "^3.4.4", "tailwindcss": "^3.4.4",
"tailwindcss-dotted-background": "^1.1.0", "tailwindcss-dotted-background": "^1.1.0",

View file

@ -153,7 +153,7 @@ export default function TableNodeCellRender({
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}
value={ value={
templateValue?.length === 0 || !templateValue Object.keys(templateValue)?.length === 0 || !templateValue
? [{ "": "" }] ? [{ "": "" }]
: convertObjToArray(templateValue, templateData.type) : convertObjToArray(templateValue, templateData.type)
} }

View file

@ -2,6 +2,7 @@ import { useEffect } from "react";
import { EDIT_TEXT_MODAL_TITLE } from "../../constants/constants"; import { EDIT_TEXT_MODAL_TITLE } from "../../constants/constants";
import { TypeModal } from "../../constants/enums"; import { TypeModal } from "../../constants/enums";
import GenericModal from "../../modals/genericModal"; import GenericModal from "../../modals/genericModal";
import { Case } from "../../shared/components/caseComponent";
import { TextAreaComponentType } from "../../types/components"; import { TextAreaComponentType } from "../../types/components";
import IconComponent from "../genericIconComponent"; import IconComponent from "../genericIconComponent";
import { Button } from "../ui/button"; import { Button } from "../ui/button";
@ -24,29 +25,31 @@ export default function TextAreaComponent({
return ( return (
<div className={"flex w-full items-center " + (disabled ? "" : "")}> <div className={"flex w-full items-center " + (disabled ? "" : "")}>
<div className="flex w-full items-center gap-3" data-testid={"div-" + id}> <div className="flex w-full items-center gap-3" data-testid={"div-" + id}>
<Input <Case condition={!editNode}>
id={id} <Input
data-testid={id} id={id}
value={value} data-testid={id}
disabled={disabled}
className={editNode ? "input-edit-node w-full" : "w-full"}
placeholder={"Type something..."}
onChange={(event) => {
onChange(event.target.value);
}}
/>
<div className="flex items-center">
<GenericModal
type={TypeModal.TEXT}
buttonText="Finish Editing"
modalTitle={EDIT_TEXT_MODAL_TITLE}
value={value} value={value}
setValue={(value: string) => {
onChange(value);
}}
disabled={disabled} disabled={disabled}
> className={editNode ? "input-edit-node w-full" : "w-full"}
{!editNode && ( placeholder={"Type something..."}
onChange={(event) => {
onChange(event.target.value);
}}
/>
</Case>
<GenericModal
type={TypeModal.TEXT}
buttonText="Finish Editing"
modalTitle={EDIT_TEXT_MODAL_TITLE}
value={value}
setValue={(value: string) => {
onChange(value);
}}
disabled={disabled}
>
{!editNode ? (
<div className="flex items-center">
<Button unstyled> <Button unstyled>
<IconComponent <IconComponent
strokeWidth={1.5} strokeWidth={1.5}
@ -58,9 +61,26 @@ export default function TextAreaComponent({
} }
/> />
</Button> </Button>
)} </div>
</GenericModal> ) : (
</div> <Button unstyled className="w-full">
<div className="flex w-full items-center gap-3">
<span
id={id}
data-testid={id}
className={
editNode
? "input-edit-node input-dialog"
: (disabled ? "input-disable text-ring " : "") +
" primary-input text-muted-foreground"
}
>
{value !== "" ? value : "Type something..."}
</span>
</div>
</Button>
)}
</GenericModal>
</div> </div>
</div> </div>
); );

View file

@ -65,12 +65,6 @@ const EditNodeModal = forwardRef(
} }
}, [gridApi, open]); }, [gridApi, open]);
// useEffect(() => {
// return () => {
// setOpenWDoubleClick(false);
// };
// }, []);
return ( return (
<BaseModal key={data.id} open={open} setOpen={setOpen}> <BaseModal key={data.id} open={open} setOpen={setOpen}>
<BaseModal.Trigger> <BaseModal.Trigger>

View file

@ -270,12 +270,12 @@ test("Blog Writer", async ({ page }) => {
"https://www.natgeokids.com/uk/discover/animals/sea-life/turtle-facts/", "https://www.natgeokids.com/uk/discover/animals/sea-life/turtle-facts/",
); );
await page await page
.getByTestId("input-list-input_urls-0") .getByTestId("input-list-input_urls-1")
.nth(1) .nth(0)
.fill("https://www.originaldiving.com/blog/top-ten-turtle-facts"); .fill("https://www.originaldiving.com/blog/top-ten-turtle-facts");
await page await page
.getByTestId("textarea-input_value") .getByTestId("popover-anchor-input-input_value")
.nth(0) .nth(0)
.fill( .fill(
"Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.", "Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.",
@ -284,7 +284,7 @@ test("Blog Writer", async ({ page }) => {
await page.getByTestId("button_run_chat output").click(); await page.getByTestId("button_run_chat output").click();
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await page.getByText("built successfully").last().click({ await page.getByText("built successfully").last().click({
timeout: 15000, timeout: 30000,
}); });
await page.getByText("Playground", { exact: true }).click(); await page.getByText("Playground", { exact: true }).click();
@ -403,17 +403,14 @@ test("Vector Store RAG", async ({ page }) => {
await page.getByText("test_file.txt").isVisible(); await page.getByText("test_file.txt").isVisible();
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
await page.getByTestId("button_run_astra db vector store").first().click(); await page.getByTestId("button_run_astra db").first().click();
await page await page.getByText("built successfully").last().click({
.getByText("Astra DB Vector Store built successfully") timeout: 30000,
.last() });
.click({
timeout: 15000,
});
await page.getByTestId("button_run_chat output").click(); await page.getByTestId("button_run_chat output").click();
await page.getByText("built successfully").last().click({ await page.getByText("built successfully").last().click({
timeout: 15000, timeout: 30000,
}); });
await page.getByText("Playground", { exact: true }).click(); await page.getByText("Playground", { exact: true }).click();
@ -427,15 +424,6 @@ test("Vector Store RAG", async ({ page }) => {
.last() .last()
.isVisible(); .isVisible();
await page.getByText("Extracted Chunks", { exact: true }).last().click();
const inputChunksValues = await page.getByPlaceholder("Empty").inputValue();
expect(inputChunksValues).toBe(
"this is a test file---this is a test file---this is a test file---this is a test file",
);
await page.getByTestId("icon-ExternalLink").last().click();
await page.getByPlaceholder("Send a message...").last().isHidden();
await page.getByText("Memories", { exact: true }).last().click(); await page.getByText("Memories", { exact: true }).last().click();
await page.getByText("Default Session").last().click(); await page.getByText("Default Session").last().click();

View file

@ -23,7 +23,7 @@ test("chat_io_teste", async ({ page }) => {
} }
const jsonContent = readFileSync( const jsonContent = readFileSync(
"src/frontend/tests/end-to-end/assets/ChatTest.json", "tests/end-to-end/assets/ChatTest.json",
"utf-8", "utf-8",
); );

View file

@ -48,14 +48,21 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
await page.getByPlaceholder("Send a message...").fill("Hello, how are you?"); await page.getByPlaceholder("Send a message...").fill("Hello, how are you?");
await page.getByTestId("icon-LucideSend").click(); await page.getByTestId("icon-LucideSend").click();
let valueUser = await page.getByTestId("sender_name_user").textContent(); let valueUser = await page.getByTestId("sender_name_user").textContent();
await page.waitForSelector('[data-testid="sender_name_ai"]', {
timeout: 100000,
});
let valueAI = await page.getByTestId("sender_name_ai").textContent(); let valueAI = await page.getByTestId("sender_name_ai").textContent();
expect(valueUser).toBe("User"); expect(valueUser).toBe("User");
expect(valueAI).toBe("AI"); expect(valueAI).toBe("AI");
await page.keyboard.press("Escape");
await page await page
.getByTestId("textarea-input_value") .getByTestId("textarea-input_value")
.nth(1) .nth(0)
.fill( .fill(
"testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!", "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!",
); );
@ -73,11 +80,11 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Save Changes", { exact: true }).click();
await page await page
.getByTestId("textarea-sender_name") .getByTestId("popover-anchor-input-sender_name")
.nth(1) .nth(1)
.fill("TestSenderNameUser"); .fill("TestSenderNameUser");
await page await page
.getByTestId("textarea-sender_name") .getByTestId("popover-anchor-input-sender_name")
.nth(0) .nth(0)
.fill("TestSenderNameAI"); .fill("TestSenderNameAI");
@ -150,6 +157,10 @@ test("user must be able to see output inspection", async ({ page }) => {
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await page.waitForSelector('[data-testid="icon-ScanEye"]', {
timeout: 30000,
});
await page.getByTestId("icon-ScanEye").nth(4).click(); await page.getByTestId("icon-ScanEye").nth(4).click();
await page.getByText("Sender", { exact: true }).isVisible(); await page.getByText("Sender", { exact: true }).isVisible();
@ -206,32 +217,46 @@ test("user must be able to send an image on chat", async ({ page }) => {
await page.getByText("Playground", { exact: true }).click(); await page.getByText("Playground", { exact: true }).click();
const jsonContent = readFileSync( // Read the image file as a binary string
"src/frontend/tests/end-to-end/assets/chain.png", const filePath = "tests/end-to-end/assets/chain.png";
"utf-8", const fileContent = readFileSync(filePath, "base64");
// Create the DataTransfer and File objects within the browser context
const dataTransfer = await page.evaluateHandle(
({ fileContent }) => {
const dt = new DataTransfer();
const byteCharacters = atob(fileContent);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const file = new File([byteArray], "chain.png", { type: "image/png" });
dt.items.add(file);
return dt;
},
{ fileContent },
); );
// Create the DataTransfer and File // Locate the target element
const dataTransfer = await page.evaluateHandle((data) => {
const dt = new DataTransfer();
// Convert the buffer to a hex array
const file = new File([data], "chain.png", {
type: "application/json",
});
dt.items.add(file);
return dt;
}, jsonContent);
const element = await page.getByPlaceholder("Send a message..."); const element = await page.getByPlaceholder("Send a message...");
// Dispatch the drop event on the target element
await element.dispatchEvent("drop", { dataTransfer }); await element.dispatchEvent("drop", { dataTransfer });
await page.waitForTimeout(4000);
await page.getByText("chain.png").isVisible(); await page.getByText("chain.png").isVisible();
await page.getByTestId("icon-LucideSend").click(); await page.getByTestId("icon-LucideSend").click();
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
await page.getByText("chain.png").isVisible(); await page.getByText("chain.png").isVisible();
await page.getByText("Close", { exact: true }).click(); await page.getByText("Close", { exact: true }).click();
await page.waitForSelector('[data-testid="icon-ScanEye"]', {
timeout: 30000,
});
await page.getByTestId("icon-ScanEye").nth(4).click(); await page.getByTestId("icon-ScanEye").nth(4).click();
await page.getByText("Restart").isHidden(); await page.getByText("Restart").isHidden();
}); });

View file

@ -31,7 +31,7 @@ test("CodeAreaModalComponent", async ({ page }) => {
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await page await page
.getByTestId("experimentalPython Function") .getByTestId("prototypesPython Function")
.dragTo(page.locator('//*[@id="react-flow-id"]')); .dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.mouse.up(); await page.mouse.up();
await page.mouse.down(); await page.mouse.down();
@ -65,19 +65,9 @@ class PythonFunctionComponent(CustomComponent):
await page.locator("textarea").fill(wCode); await page.locator("textarea").fill(wCode);
await page.locator('//*[@id="checkAndSaveBtn"]').click(); await page.locator('//*[@id="checkAndSaveBtn"]').click();
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
// expect(
// await page.getByText("invalid syntax (<unknown>, line 1)").isVisible()
// ).toBeTruthy();
await page.locator("textarea").press("Control+a"); await page.locator("textarea").press("Control+a");
await page.locator("textarea").fill(wCode); await page.locator("textarea").fill(wCode);
await page.locator("textarea").fill(customComponentCode); await page.locator("textarea").fill(customComponentCode);
await page.locator('//*[@id="checkAndSaveBtn"]').click(); await page.locator('//*[@id="checkAndSaveBtn"]').click();
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
// await page.getByTestId("code-button-modal").click();
// const inputCodeValue = await page
// .locator('//*[@id="codeValue"]')
// .inputValue();
// expect(inputCodeValue).toContain("def python_function(text: str) -> str");
}); });

View file

@ -17,7 +17,14 @@ test("should delete a flow", async ({ page }) => {
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
await page.getByText("My Collection").nth(0).click(); await page.getByText("My Collection").nth(0).click();
await page.getByText("Website Content QA").first().isVisible(); await page.getByText("Website Content QA").first().isVisible();
await page.getByLabel("checkbox-component").last().waitFor({
state: "visible",
timeout: 30000, // Timeout of 30 seconds
});
await page.getByLabel("checkbox-component").first().click(); await page.getByLabel("checkbox-component").first().click();
await page.getByTestId("icon-Trash2").click(); await page.getByTestId("icon-Trash2").click();
await page await page
.getByText("Are you sure you want to delete the selected component?") .getByText("Are you sure you want to delete the selected component?")
@ -36,6 +43,12 @@ test("should delete a component", async ({ page }) => {
await page.getByText("My Collection").nth(0).click(); await page.getByText("My Collection").nth(0).click();
await page.getByText("Components").first().click(); await page.getByText("Components").first().click();
await page.getByText("Basic RAG").first().isVisible(); await page.getByText("Basic RAG").first().isVisible();
await page.getByLabel("checkbox-component").last().waitFor({
state: "visible",
timeout: 30000, // Timeout of 30 seconds
});
await page.getByLabel("checkbox-component").first().click(); await page.getByLabel("checkbox-component").first().click();
await page.getByTestId("icon-Trash2").click(); await page.getByTestId("icon-Trash2").click();
await page await page

View file

@ -26,7 +26,7 @@ test.describe("drag and drop test", () => {
await page.locator("span").filter({ hasText: "My Collection" }).isVisible(); await page.locator("span").filter({ hasText: "My Collection" }).isVisible();
// Read your file into a buffer. // Read your file into a buffer.
const jsonContent = readFileSync( const jsonContent = readFileSync(
"src/frontend/tests/end-to-end/assets/collection.json", "tests/end-to-end/assets/collection.json",
"utf-8", "utf-8",
); );

View file

@ -44,24 +44,40 @@ test("LLMChain - Tooltip", async ({ page }) => {
) )
.hover() .hover()
.then(async () => { .then(async () => {
await expect(page.getByTestId("tooltip-Chains").first()).toBeVisible();
await expect( await expect(
page.getByTestId("tooltip-Model Specs").first(), page.getByTestId("available-output-chains").first(),
).toBeVisible(); ).toBeVisible();
await expect( await expect(
page.getByTestId("tooltip-Vector Search").first(), page.getByTestId("available-output-textsplitters").first(),
).toBeVisible(); ).toBeVisible();
await expect( await expect(
page.getByTestId("tooltip-Text Splitters").first(), page.getByTestId("available-output-retrievers").first(),
).toBeVisible(); ).toBeVisible();
await expect( await expect(
page.getByTestId("tooltip-Retrievers").first(), page.getByTestId("available-output-prototypes").first(),
).toBeVisible(); ).toBeVisible();
await expect(page.getByTestId("tooltip-Tools").first()).toBeVisible(); await expect(
await expect(page.getByTestId("tooltip-Memories").first()).toBeVisible(); page.getByTestId("available-output-tools").first(),
await expect(page.getByTestId("tooltip-Agents").first()).toBeVisible(); ).toBeVisible();
await expect(page.getByTestId("tooltip-Helpers").first()).toBeVisible(); await expect(
await expect(page.getByTestId("tooltip-Utilities").first()).toBeVisible(); page.getByTestId("available-output-memories").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-toolkits").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-chains").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-agents").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-helpers").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-langchain_utilities").first(),
).toBeVisible();
await page.getByTestId("icon-X").click(); await page.getByTestId("icon-X").click();
await page.waitForTimeout(500); await page.waitForTimeout(500);
}); });
@ -77,12 +93,10 @@ test("LLMChain - Tooltip", async ({ page }) => {
.hover() .hover()
.then(async () => { .then(async () => {
await expect( await expect(
page.getByTestId("tooltip-Model Specs").first(), page.getByTestId("available-input-models").first(),
).toBeVisible(); ).toBeVisible();
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
await expect(page.getByTestId("tooltip-Models").first()).toBeVisible();
await page.getByTestId("icon-Search").click(); await page.getByTestId("icon-Search").click();
await page.waitForTimeout(500); await page.waitForTimeout(500);
@ -100,12 +114,18 @@ test("LLMChain - Tooltip", async ({ page }) => {
.then(async () => { .then(async () => {
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
await expect(page.getByTestId("tooltip-Chains").first()).toBeVisible();
await expect( await expect(
page.getByTestId("tooltip-Experimental").first(), page.getByTestId("available-input-chains").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-prototypes").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-agents").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-helpers").first(),
).toBeVisible(); ).toBeVisible();
await expect(page.getByTestId("tooltip-Agents").first()).toBeVisible();
await expect(page.getByTestId("tooltip-Helpers").first()).toBeVisible();
await page.waitForTimeout(500); await page.waitForTimeout(500);
}); });
@ -176,26 +196,30 @@ test("LLMChain - Filter", async ({ page }) => {
) )
.click(); .click();
await expect(page.getByTestId("disclosure-model specs")).toBeVisible(); await expect(page.getByTestId("disclosure-models")).toBeVisible();
await expect(page.getByTestId("model_specsAnthropic").first()).toBeVisible();
await expect(page.getByTestId("model_specsAmazon Bedrock")).toBeVisible();
await expect(page.getByTestId("model_specsAzureChatOpenAI")).toBeVisible();
await expect(page.getByTestId("model_specsChatLiteLLM")).toBeVisible();
await expect(page.getByTestId("model_specsChatOllama")).toBeVisible();
await expect(page.getByTestId("model_specsChatOpenAI")).toBeVisible();
await expect(page.getByTestId("model_specsChatVertexAI")).toBeVisible();
await expect( await expect(
page.getByTestId("model_specsGoogle Generative AI"), page.getByTestId("modelsGoogle Generative AI").first(),
).toBeVisible();
await expect(page.getByTestId("chainsLLMChain").first()).toBeVisible();
await expect(
page.getByTestId("langchain_utilitiesSearchApi").first(),
).toBeVisible(); ).toBeVisible();
await expect( await expect(
page.getByTestId("model_specsHugging Face Inference API"), page.getByTestId("memoriesAstra DB Message Reader").first(),
).toBeVisible(); ).toBeVisible();
await expect(page.getByTestId("model_specsOllama")).toBeVisible();
await expect( await expect(
page.getByTestId("model_specsQianfanChatEndpoint"), page.getByTestId("prototypesFlow as Tool").first(),
).toBeVisible(); ).toBeVisible();
await expect(page.getByTestId("model_specsQianfanLLMEndpoint")).toBeVisible(); await expect(
await expect(page.getByTestId("model_specsVertexAI")).toBeVisible(); page.getByTestId("retrieversAmazon Kendra Retriever").first(),
).toBeVisible();
await expect(
page.getByTestId("textsplittersCharacterTextSplitter").first(),
).toBeVisible();
await expect(
page.getByTestId("toolkitsVectorStoreInfo").first(),
).toBeVisible();
await expect(page.getByTestId("toolsSearchApi").first()).toBeVisible();
await page.getByPlaceholder("Search").click(); await page.getByPlaceholder("Search").click();
@ -219,7 +243,6 @@ test("LLMChain - Filter", async ({ page }) => {
.click(); .click();
await expect(page.getByTestId("disclosure-models")).toBeVisible(); await expect(page.getByTestId("disclosure-models")).toBeVisible();
await expect(page.getByTestId("disclosure-model specs")).toBeVisible();
await page await page
.locator( .locator(
@ -227,10 +250,8 @@ test("LLMChain - Filter", async ({ page }) => {
) )
.click(); .click();
await expect(page.getByTestId("disclosure-saved")).toBeVisible();
await expect(page.getByTestId("disclosure-helpers")).toBeVisible(); await expect(page.getByTestId("disclosure-helpers")).toBeVisible();
await expect(page.getByTestId("disclosure-agents")).toBeVisible(); await expect(page.getByTestId("disclosure-agents")).toBeVisible();
await expect(page.getByTestId("disclosure-chains")).toBeVisible(); await expect(page.getByTestId("disclosure-chains")).toBeVisible();
await expect(page.getByTestId("disclosure-experimental")).toBeVisible(); await expect(page.getByTestId("disclosure-prototypes")).toBeVisible();
}); });

View file

@ -57,7 +57,7 @@ test("add folder by drag and drop", async ({ page }) => {
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
const jsonContent = readFileSync( const jsonContent = readFileSync(
"src/frontend/tests/end-to-end/assets/collection.json", "tests/end-to-end/assets/collection.json",
"utf-8", "utf-8",
); );

View file

@ -85,6 +85,11 @@ test("erase button should clear the chat messages", async ({ page }) => {
await page.getByPlaceholder("Send a message...").fill("Hello, how are you?"); await page.getByPlaceholder("Send a message...").fill("Hello, how are you?");
await page.getByTestId("icon-LucideSend").click(); await page.getByTestId("icon-LucideSend").click();
let valueUser = await page.getByTestId("sender_name_user").textContent(); let valueUser = await page.getByTestId("sender_name_user").textContent();
await page.waitForSelector('[data-testid="sender_name_ai"]', {
timeout: 30000,
});
let valueAI = await page.getByTestId("sender_name_ai").textContent(); let valueAI = await page.getByTestId("sender_name_ai").textContent();
expect(valueUser).toBe("User"); expect(valueUser).toBe("User");

View file

@ -24,11 +24,11 @@ test("InputListComponent", async ({ page }) => {
await page.waitForTimeout(3000); await page.waitForTimeout(3000);
await page.getByTestId("extended-disclosure").click(); await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click(); await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("astradb"); await page.getByPlaceholder("Search").fill("url");
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await page await page
.getByTestId("vectorsearchAstra DB Search") .getByTestId("dataURL")
.dragTo(page.locator('//*[@id="react-flow-id"]')); .dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.mouse.up(); await page.mouse.up();
await page.mouse.down(); await page.mouse.down();
@ -36,95 +36,71 @@ test("InputListComponent", async ({ page }) => {
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTestId("input-list-input_urls-0").fill("test test test test");
await page.getByTestId("input-list-plus-btn_urls-0").click();
await page.getByTestId("input-list-plus-btn_urls-0").click();
await page
.getByTestId("input-list-input_urls-1")
.fill("test1 test1 test1 test1");
await page
.getByTestId("input-list-input_urls-2")
.fill("test2 test2 test2 test2");
await page.getByTestId("div-generic-node").click(); await page.getByTestId("div-generic-node").click();
await page.getByTestId("more-options-modal").click(); await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click(); await page.getByTestId("edit-button-modal").click();
expect(
await page.getByTestId("showmetadata_indexing_exclude").isChecked(),
).toBeFalsy();
await page.getByTestId("showmetadata_indexing_exclude").click();
expect(
await page.getByTestId("showmetadata_indexing_exclude").isChecked(),
).toBeTruthy();
expect(
await page.getByTestId("showmetadata_indexing_include").isChecked(),
).toBeFalsy();
await page.getByTestId("showmetadata_indexing_include").click();
expect(
await page.getByTestId("showmetadata_indexing_include").isChecked(),
).toBeTruthy();
await page
.getByTestId("input-list-input-edit_metadata_indexing_include-0")
.fill("test test test test");
await page
.getByTestId("input-list-plus-btn-edit_metadata_indexing_include-0")
.click();
await page
.getByTestId("input-list-input-edit_metadata_indexing_include-1")
.fill("test1 test1 test1 test1");
await page.getByText("Save Changes", { exact: true }).click();
await page
.getByTestId("input-list-input_metadata_indexing_include-0")
.fill("test test test test");
const value0 = await page const value0 = await page
.getByTestId("input-list-input_metadata_indexing_include-0") .getByTestId("input-list-input-edit_urls-0")
.inputValue(); .inputValue();
const value1 = await page const value1 = await page
.getByTestId("input-list-input_metadata_indexing_include-1") .getByTestId("input-list-input-edit_urls-1")
.inputValue();
const value2 = await page
.getByTestId("input-list-input-edit_urls-2")
.inputValue(); .inputValue();
if ( if (
value0 !== "test test test test" || value0 !== "test test test test" ||
value1 !== "test1 test1 test1 test1" value1 !== "test1 test1 test1 test1" ||
value2 !== "test2 test2 test2 test2"
) { ) {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page await page.getByTestId("input-list-minus-btn-edit_urls-1").click();
.getByTestId("input-list-minus-btn_metadata_indexing_include-1")
.click();
const plusButtonLocator = page.getByTestId( const plusButtonLocator = page.getByTestId(
"input-list-plus-btn_metadata_indexing_include-1", "input-list-minus-btn-edit_urls-1",
); );
const elementCount = await plusButtonLocator?.count(); const elementCount = await plusButtonLocator?.count();
if (elementCount > 0) { if (elementCount > 1) {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page await page.getByText("Save Changes", { exact: true }).click();
.getByTestId("input-list-plus-btn_metadata_indexing_include-0")
.click();
await page
.getByTestId("input-list-plus-btn_metadata_indexing_include-0")
.click();
await page
.getByTestId("input-list-plus-btn_metadata_indexing_include-0")
.click();
await page
.getByTestId("input-list-plus-btn_metadata_indexing_include-0")
.click();
await page.getByTestId("input-list-minus-btn_urls-2").isHidden();
await page.getByTestId("input-list-plus-btn_urls-0").click();
await page.getByTestId("input-list-plus-btn_urls-0").click();
await page.getByTestId("input-list-input_urls-0").fill("test test test test");
await page await page
.getByTestId("input-list-input_metadata_indexing_include-0") .getByTestId("input-list-input_urls-1")
.fill("test test test test");
await page
.getByTestId("input-list-input_metadata_indexing_include-1")
.fill("test1 test1 test1 test1"); .fill("test1 test1 test1 test1");
await page await page
.getByTestId("input-list-input_metadata_indexing_include-2") .getByTestId("input-list-input_urls-2")
.fill("test2 test2 test2 test2"); .fill("test2 test2 test2 test2");
await page await page
.getByTestId("input-list-input_metadata_indexing_include-3") .getByTestId("input-list-input_urls-3")
.fill("test3 test3 test3 test3"); .fill("test3 test3 test3 test3");
await page.getByTestId("div-generic-node").click(); await page.getByTestId("div-generic-node").click();
@ -132,16 +108,16 @@ test("InputListComponent", async ({ page }) => {
await page.getByTestId("edit-button-modal").click(); await page.getByTestId("edit-button-modal").click();
const value0Edit = await page const value0Edit = await page
.getByTestId("input-list-input-edit_metadata_indexing_include-0") .getByTestId("input-list-input-edit_urls-0")
.inputValue(); .inputValue();
const value1Edit = await page const value1Edit = await page
.getByTestId("input-list-input-edit_metadata_indexing_include-1") .getByTestId("input-list-input-edit_urls-1")
.inputValue(); .inputValue();
const value2Edit = await page const value2Edit = await page
.getByTestId("input-list-input-edit_metadata_indexing_include-2") .getByTestId("input-list-input-edit_urls-2")
.inputValue(); .inputValue();
const value3Edit = await page const value3Edit = await page
.getByTestId("input-list-input-edit_metadata_indexing_include-3") .getByTestId("input-list-input-edit_urls-3")
.inputValue(); .inputValue();
if ( if (
@ -153,23 +129,17 @@ test("InputListComponent", async ({ page }) => {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page await page.getByTestId("input-list-minus-btn-edit_urls-1").click();
.getByTestId("input-list-minus-btn-edit_metadata_indexing_include-1") await page.getByTestId("input-list-minus-btn-edit_urls-1").click();
.click(); await page.getByTestId("input-list-minus-btn-edit_urls-1").click();
await page
.getByTestId("input-list-minus-btn-edit_metadata_indexing_include-1")
.click();
await page
.getByTestId("input-list-minus-btn-edit_metadata_indexing_include-1")
.click();
const plusButtonLocatorEdit0 = await page.getByTestId( const plusButtonLocatorEdit0 = await page.getByTestId(
"input-list-plus-btn-edit_metadata_indexing_include-0", "input-list-plus-btn-edit_urls-0",
); );
const elementCountEdit0 = await plusButtonLocatorEdit0?.count(); const elementCountEdit0 = await plusButtonLocatorEdit0?.count();
const plusButtonLocatorEdit2 = await page.getByTestId( const plusButtonLocatorEdit2 = await page.getByTestId(
"input-list-plus-btn-edit_metadata_indexing_include-2", "input-list-plus-btn-edit_urls-1",
); );
const elementCountEdit2 = await plusButtonLocatorEdit2?.count(); const elementCountEdit2 = await plusButtonLocatorEdit2?.count();
@ -178,13 +148,13 @@ test("InputListComponent", async ({ page }) => {
} }
const minusButtonLocatorEdit1 = await page.getByTestId( const minusButtonLocatorEdit1 = await page.getByTestId(
"input-list-minus-btn-edit_metadata_indexing_include-1", "input-list-minus-btn-edit_urls-1",
); );
const elementCountMinusEdit1 = await minusButtonLocatorEdit1?.count(); const elementCountMinusEdit1 = await minusButtonLocatorEdit1?.count();
const minusButtonLocatorEdit2 = await page.getByTestId( const minusButtonLocatorEdit2 = await page.getByTestId(
"input-list-minus-btn-edit_metadata_indexing_include-2", "input-list-minus-btn-edit_urls-2",
); );
const elementCountMinusEdit2 = await minusButtonLocatorEdit2?.count(); const elementCountMinusEdit2 = await minusButtonLocatorEdit2?.count();

View file

@ -30,7 +30,7 @@ test("IntComponent", async ({ page }) => {
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await page await page
.getByTestId("model_specsChatOpenAI") .getByTestId("modelsOpenAI")
.first() .first()
.dragTo(page.locator('//*[@id="react-flow-id"]')); .dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.mouse.up(); await page.mouse.up();
@ -65,7 +65,7 @@ test("IntComponent", async ({ page }) => {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page.getByTestId("title-ChatOpenAI").click(); await page.getByTestId("title-OpenAI").click();
await page.getByTitle("fit view").click(); await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();

View file

@ -30,7 +30,7 @@ test("KeypairListComponent", async ({ page }) => {
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await page await page
.getByTestId("model_specsAmazon Bedrock") .getByTestId("modelsAmazon Bedrock")
.dragTo(page.locator('//*[@id="react-flow-id"]')); .dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.mouse.up(); await page.mouse.up();
await page.mouse.down(); await page.mouse.down();
@ -38,6 +38,14 @@ test("KeypairListComponent", async ({ page }) => {
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click();
await page.getByTestId("showmodel_kwargs").click();
expect(await page.getByTestId("showmodel_kwargs").isChecked()).toBeTruthy();
await page.getByText("Save Changes", { exact: true }).click();
await page.locator('//*[@id="keypair0"]').click(); await page.locator('//*[@id="keypair0"]').click();
await page.locator('//*[@id="keypair0"]').fill("testtesttesttest"); await page.locator('//*[@id="keypair0"]').fill("testtesttesttest");
await page.locator('//*[@id="keypair100"]').click(); await page.locator('//*[@id="keypair100"]').click();

View file

@ -72,6 +72,8 @@ test("PromptTemplateComponent", async ({ page }) => {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page.getByTestId("div-generic-node").click();
await page.getByTestId("more-options-modal").click(); await page.getByTestId("more-options-modal").click();
await page.getByTestId("save-button-modal").click(); await page.getByTestId("save-button-modal").click();
@ -102,13 +104,16 @@ test("PromptTemplateComponent", async ({ page }) => {
await page.getByTestId("more-options-modal").click(); await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click(); await page.getByTestId("edit-button-modal").click();
value = await page.locator('//*[@id="textarea-edit-prompt"]').inputValue(); value =
(await page.locator('//*[@id="textarea-edit-prompt"]').textContent()) ?? "";
if (value != "prompt_value_!@#!@#") { if (value != "prompt_value_!@#!@#") {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
value = await page.locator('//*[@id="textarea-edit-prompt1"]').inputValue(); value =
(await page.locator('//*[@id="textarea-edit-prompt1"]').textContent()) ??
"";
if (value != "prompt_name_test_123123!@#!@#") { if (value != "prompt_name_test_123123!@#!@#") {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
@ -122,13 +127,20 @@ test("PromptTemplateComponent", async ({ page }) => {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page.locator('//*[@id="textarea-edit-prompt1"]').click();
await page await page
.locator('//*[@id="textarea-edit-prompt1"]') .getByTestId("text-area-modal")
.fill("prompt_edit_test_12312312321!@#$"); .fill("prompt_edit_test_12312312321!@#$");
await page.getByText("Finish Editing", { exact: true }).click();
await page.locator('//*[@id="textarea-edit-prompt"]').click();
await page await page
.locator('//*[@id="textarea-edit-prompt"]') .getByTestId("text-area-modal")
.fill("prompt_edit_test_44444444444!@#$"); .fill("prompt_edit_test_44444444444!@#$");
await page.getByText("Finish Editing", { exact: true }).click();
await page.locator('//*[@id="showtemplate"]').click(); await page.locator('//*[@id="showtemplate"]').click();
expect(await page.locator('//*[@id="showtemplate"]').isChecked()).toBeFalsy(); expect(await page.locator('//*[@id="showtemplate"]').isChecked()).toBeFalsy();
@ -174,13 +186,16 @@ test("PromptTemplateComponent", async ({ page }) => {
await page.locator('//*[@id="showprompt1"]').click(); await page.locator('//*[@id="showprompt1"]').click();
expect(await page.locator('//*[@id="showprompt1"]').isChecked()).toBeTruthy(); expect(await page.locator('//*[@id="showprompt1"]').isChecked()).toBeTruthy();
value = await page.locator('//*[@id="textarea-edit-prompt"]').inputValue(); value =
(await page.locator('//*[@id="textarea-edit-prompt"]').textContent()) ?? "";
if (value != "prompt_edit_test_44444444444!@#$") { if (value != "prompt_edit_test_44444444444!@#$") {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
value = await page.locator('//*[@id="textarea-edit-prompt1"]').inputValue(); value =
(await page.locator('//*[@id="textarea-edit-prompt1"]').textContent()) ??
"";
if (value != "prompt_edit_test_12312312321!@#$") { if (value != "prompt_edit_test_12312312321!@#$") {
expect(false).toBeTruthy(); expect(false).toBeTruthy();

View file

@ -26,7 +26,7 @@ test.describe("save component tests", () => {
// Read your file into a buffer. // Read your file into a buffer.
const jsonContent = readFileSync( const jsonContent = readFileSync(
"src/frontend/tests/end-to-end/assets/flow_group_test.json", "tests/end-to-end/assets/flow_group_test.json",
"utf-8", "utf-8",
); );

View file

@ -259,6 +259,10 @@ test("should share component with share button", async ({ page }) => {
await page.getByText("Save").last().click(); await page.getByText("Save").last().click();
await page.getByText("Close").last().click(); await page.getByText("Close").last().click();
await page.waitForSelector('[data-testid="icon-Share3"]', {
timeout: 100000,
});
await page.getByTestId("icon-Share3").first().click(); await page.getByTestId("icon-Share3").first().click();
await page.getByText("Name:").isVisible(); await page.getByText("Name:").isVisible();
await page.getByText("Description:").isVisible(); await page.getByText("Description:").isVisible();

View file

@ -21,8 +21,17 @@ test("TextAreaModalComponent", async ({ page }) => {
} }
await page.getByTestId("blank-flow").click(); await page.getByTestId("blank-flow").click();
await page.waitForTimeout(3000);
await page.getByTestId("extended-disclosure").click(); await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 30000,
});
const focusElementsOnBoard = async ({ page }) => {
const focusElements = await page.getByTestId("extended-disclosure");
await focusElements.click();
};
await focusElementsOnBoard({ page });
await page.getByPlaceholder("Search").click(); await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("prompt"); await page.getByPlaceholder("Search").fill("prompt");

View file

@ -29,8 +29,17 @@ test("TextInputOutputComponent", async ({ page }) => {
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await page.getByTestId("blank-flow").click(); await page.getByTestId("blank-flow").click();
await page.waitForTimeout(3000); await page.waitForSelector('[data-testid="extended-disclosure"]', {
await page.getByTestId("extended-disclosure").click(); timeout: 30000,
});
const focusElementsOnBoard = async ({ page }) => {
const focusElements = await page.getByTestId("extended-disclosure");
focusElements.click();
};
await focusElementsOnBoard({ page });
await page.getByPlaceholder("Search").click(); await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("text input"); await page.getByPlaceholder("Search").fill("text input");
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
@ -56,7 +65,15 @@ test("TextInputOutputComponent", async ({ page }) => {
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
// Click and hold on the first element await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[1]/div/div[2]/div[5]/button/div[1]',
)
.waitFor({
state: "visible",
timeout: 30000,
});
await page await page
.locator( .locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[1]/div/div[2]/div[5]/button/div[1]', '//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[1]/div/div[2]/div[5]/button/div[1]',
@ -64,6 +81,15 @@ test("TextInputOutputComponent", async ({ page }) => {
.hover(); .hover();
await page.mouse.down(); await page.mouse.down();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[2]/div/div[2]/div[3]/div/button/div[1]',
)
.waitFor({
state: "visible",
timeout: 30000,
});
// Move to the second element // Move to the second element
await page await page
.locator( .locator(
@ -88,6 +114,15 @@ test("TextInputOutputComponent", async ({ page }) => {
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[2]/div/div[2]/div[15]/button/div[1]',
)
.waitFor({
state: "visible",
timeout: 30000,
});
// Click and hold on the first element // Click and hold on the first element
await page await page
.locator( .locator(
@ -96,6 +131,15 @@ test("TextInputOutputComponent", async ({ page }) => {
.hover(); .hover();
await page.mouse.down(); await page.mouse.down();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[3]/div/div[2]/div[3]/div/button/div[1]',
)
.waitFor({
state: "visible",
timeout: 30000,
});
// Move to the second element // Move to the second element
await page await page
.locator( .locator(

View file

@ -21,8 +21,16 @@ test("ToggleComponent", async ({ page }) => {
} }
await page.getByTestId("blank-flow").click(); await page.getByTestId("blank-flow").click();
await page.waitForTimeout(3000);
await page.getByTestId("extended-disclosure").click(); await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 30000,
});
const focusElementsOnBoard = async ({ page }) => {
const focusElements = await page.getByTestId("extended-disclosure");
focusElements.click();
};
await focusElementsOnBoard({ page });
await page.getByPlaceholder("Search").click(); await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("directory"); await page.getByPlaceholder("Search").fill("directory");

View file

@ -108,7 +108,13 @@ test("check if tweaks are updating when someothing on the flow changes", async (
.getByTestId("popover-anchor-input-persist_directory") .getByTestId("popover-anchor-input-persist_directory")
.fill("persist_directory_123123123!@#$&*(&%$@"); .fill("persist_directory_123123123!@#$&*(&%$@");
await page.getByText("API", { exact: true }).first().click(); const focusElementsOnBoard = async ({ page }) => {
await page.waitForSelector("text=API", { timeout: 30000 });
const focusElements = await page.getByText("API", { exact: true }).first();
await focusElements.click();
};
await focusElementsOnBoard({ page });
await page.getByText("Tweaks").nth(1).click(); await page.getByText("Tweaks").nth(1).click();

View file

@ -24,10 +24,23 @@ test("user should be able to see multiple edges and interact with them", async (
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
await page.getByText("Vector Store RAG", { exact: true }).last().click(); await page.getByText("Vector Store RAG", { exact: true }).last().click();
await page.waitForTimeout(3000); await page.waitForTimeout(5000);
await page.getByText("Retriever", { exact: true }).first().isVisible(); await page.getByText("Retriever", { exact: true }).first().isVisible();
await page.getByText("Search Results", { exact: true }).first().isVisible(); await page.getByText("Search Results", { exact: true }).first().isVisible();
await page.getByTestId("icon-Eye").nth(24).click();
const focusElementsOnBoard = async ({ page }) => {
await page.waitForSelector('[title="fit view"]', { timeout: 30000 });
const focusElements = await page.getByTitle("fit view");
await focusElements.click();
};
await focusElementsOnBoard({ page });
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTestId("output-inspection-retriever").first().click();
await page.getByText("Retriever", { exact: true }).first().isHidden(); await page.getByText("Retriever", { exact: true }).first().isHidden();
await page.getByTestId("icon-ChevronDown").last().isVisible(); await page.getByTestId("icon-ChevronDown").last().isVisible();
await page.getByTestId("icon-ChevronDown").last().click(); await page.getByTestId("icon-ChevronDown").last().click();

View file

@ -62,10 +62,19 @@ test("should interact with global variables", async ({ page }) => {
await page.getByText(randomName).isVisible(); await page.getByText(randomName).isVisible();
await page const focusElementsOnBoard = async ({ page }) => {
.getByLabel("Press Space to toggle all rows selection (unchecked)") await page.waitForSelector(
.nth(0) '[aria-label="Press Space to toggle all rows selection (unchecked)"]',
.click(); { timeout: 30000 },
);
const focusElements = await page
.getByLabel("Press Space to toggle all rows selection (unchecked)")
.first();
await focusElements.click();
};
await focusElementsOnBoard({ page });
await page.getByTestId("icon-Trash2").click(); await page.getByTestId("icon-Trash2").click();
await page.getByText("No data available").isVisible(); await page.getByText("No data available").isVisible();
}); });

View file

@ -75,15 +75,15 @@ def test_user_waiting_for_approval(
def test_deactivated_user_cannot_login(client, deactivated_user): def test_deactivated_user_cannot_login(client, deactivated_user):
login_data = {"username": deactivated_user.username, "password": "testpassword"} login_data = {"username": deactivated_user.username, "password": "testpassword"}
response = client.post("/api/v1/login", data=login_data) response = client.post("/api/v1/login", data=login_data)
assert response.status_code == 400, response.json() assert response.status_code == 401, response.json()
assert response.json()["detail"] == "Inactive user" assert response.json()["detail"] == "Inactive user", response.text
def test_deactivated_user_cannot_access(client, deactivated_user, logged_in_headers): def test_deactivated_user_cannot_access(client, deactivated_user, logged_in_headers):
# Assuming the headers for deactivated_user # Assuming the headers for deactivated_user
response = client.get("/api/v1/users", headers=logged_in_headers) response = client.get("/api/v1/users", headers=logged_in_headers)
assert response.status_code == 400, response.json() assert response.status_code == 403, response.json()
assert response.json()["detail"] == "The user doesn't have enough privileges" assert response.json()["detail"] == "The user doesn't have enough privileges", response.text
def test_data_consistency_after_update(client, active_user, logged_in_headers, super_user_headers): def test_data_consistency_after_update(client, active_user, logged_in_headers, super_user_headers):
@ -124,7 +124,7 @@ def test_inactive_user(client):
login_data = {"username": "inactiveuser", "password": "testpassword"} login_data = {"username": "inactiveuser", "password": "testpassword"}
response = client.post("/api/v1/login", data=login_data) response = client.post("/api/v1/login", data=login_data)
assert response.status_code == 400 assert response.status_code == 401
assert response.json()["detail"] == "Inactive user" assert response.json()["detail"] == "Inactive user"
@ -154,7 +154,7 @@ def test_read_all_users(client, super_user_headers):
def test_normal_user_cant_read_all_users(client, logged_in_headers): def test_normal_user_cant_read_all_users(client, logged_in_headers):
response = client.get("/api/v1/users", headers=logged_in_headers) response = client.get("/api/v1/users", headers=logged_in_headers)
assert response.status_code == 400, response.json() assert response.status_code == 403, response.json()
assert response.json() == {"detail": "The user doesn't have enough privileges"} assert response.json() == {"detail": "The user doesn't have enough privileges"}
@ -228,5 +228,5 @@ def test_delete_user_wrong_id(client, test_user, super_user_headers):
def test_normal_user_cant_delete_user(client, test_user, logged_in_headers): def test_normal_user_cant_delete_user(client, test_user, logged_in_headers):
user_id = test_user["id"] user_id = test_user["id"]
response = client.delete(f"/api/v1/users/{user_id}", headers=logged_in_headers) response = client.delete(f"/api/v1/users/{user_id}", headers=logged_in_headers)
assert response.status_code == 400 assert response.status_code == 403
assert response.json() == {"detail": "The user doesn't have enough privileges"} assert response.json() == {"detail": "The user doesn't have enough privileges"}