diff --git a/.github/workflows/docs_test.yml b/.github/workflows/docs_test.yml new file mode 100644 index 000000000..cc25b56f6 --- /dev/null +++ b/.github/workflows/docs_test.yml @@ -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 diff --git a/.github/workflows/lint-py.yml b/.github/workflows/lint-py.yml index 9dab54eb8..8a4abe0f9 100644 --- a/.github/workflows/lint-py.yml +++ b/.github/workflows/lint-py.yml @@ -2,19 +2,20 @@ name: Lint Python on: pull_request: + types: [opened, synchronize, reopened] paths: - "poetry.lock" - "pyproject.toml" - "src/backend/**" - "tests/**" merge_group: - branches: [dev] - + types: [checks_requested] env: POETRY_VERSION: "1.8.2" jobs: lint: + name: Run Mypy runs-on: ubuntu-latest strategy: matrix: @@ -34,6 +35,8 @@ jobs: run: | poetry env use ${{ matrix.python-version }} poetry install + - name: Run Mypy + run: | make lint env: GITHUB_TOKEN: ${{ secrets.github_token }} diff --git a/.github/workflows/python_test.yml b/.github/workflows/python_test.yml index c3c320aad..9e065c58f 100644 --- a/.github/workflows/python_test.yml +++ b/.github/workflows/python_test.yml @@ -1,26 +1,21 @@ name: Python tests on: - push: - branches: [main] - paths: - - "poetry.lock" - - "pyproject.toml" - - "src/backend/**" pull_request: - branches: [dev] + types: [opened, synchronize, reopened] + branches: [dev, main] paths: - "poetry.lock" - "pyproject.toml" - "src/backend/**" merge_group: - branches: [dev] - + types: [checks_requested] env: POETRY_VERSION: "1.8.2" jobs: build: + name: Run Unit Tests runs-on: ubuntu-latest strategy: matrix: @@ -50,7 +45,7 @@ jobs: poetry run python -m langflow run --host 127.0.0.1 --port 7860 --backend-only & SERVER_PID=$! # 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 kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) sleep 10 # give the server some time to terminate diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b6453075e..ec9828c0a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,11 +14,7 @@ on: required: false type: boolean default: true - branch: - description: "Branch to release from" - required: true - type: string - default: "main" + env: POETRY_VERSION: "1.8.2" @@ -62,7 +58,7 @@ jobs: python -m langflow run --host 127.0.0.1 --port 7860 & SERVER_PID=$! # 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 kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) 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 & SERVER_PID=$! # 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 kill $SERVER_PID || (echo "Failed to terminate the server" && exit 1) sleep 10 # give the server some time to terminate @@ -180,4 +176,4 @@ jobs: generateReleaseNotes: true prerelease: ${{ inputs.pre_release }} tag: v${{ needs.release-main.outputs.version }} - commit: ${{ inputs.branch }} \ No newline at end of file + commit: ${{ github.ref }} \ No newline at end of file diff --git a/.github/workflows/typescript_test.yml b/.github/workflows/typescript_test.yml index be081bec6..bd06b5dab 100644 --- a/.github/workflows/typescript_test.yml +++ b/.github/workflows/typescript_test.yml @@ -1,9 +1,13 @@ name: Run Frontend Tests on: - pull_request: - paths: - - "src/frontend/**" + workflow_dispatch: + inputs: + branch: + description: "Branch to run tests on" + required: true + type: string + env: POETRY_VERSION: "1.8.2" @@ -15,6 +19,7 @@ env: jobs: setup-and-test: + name: Run Frontend Tests on branch ${{ inputs.branch }} runs-on: ubuntu-latest strategy: fail-fast: false @@ -24,6 +29,8 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} - name: Setup Node.js uses: actions/setup-node@v4 @@ -88,7 +95,7 @@ jobs: - name: Run Playwright Tests run: | 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 if: always() diff --git a/.vscode/launch.json b/.vscode/launch.json index a2a38dcba..eaaf23f33 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -34,14 +34,12 @@ "args": [ "run", "--path", - "${workspaceFolder}/src/backend/base/langflow/frontend" + "${workspaceFolder}/src/backend/base/langflow/frontend", + "--env-file", + "${workspaceFolder}/.env" ], "jinja": true, - "justMyCode": false, - "env": { - "LANGFLOW_LOG_LEVEL": "debug" - }, - "envFile": "${workspaceFolder}/.env" + "justMyCode": false }, { "name": "Python: Remote Attach", diff --git a/poetry.lock b/poetry.lock index a4f0db362..c8653b9e4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -368,13 +368,13 @@ files = [ [[package]] name = "bce-python-sdk" -version = "0.9.14" +version = "0.9.17" description = "BCE SDK for python" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,<4,>=2.7" files = [ - {file = "bce_python_sdk-0.9.14-py3-none-any.whl", hash = "sha256:5704aa454151ee608b01ddda7531457433f9b4bb8afbd00706dd368f3b4339a1"}, - {file = "bce_python_sdk-0.9.14.tar.gz", hash = "sha256:7cbd182ec1e21034f10d3cdb812f3171d31908f1a783d6cf643039272942d8e8"}, + {file = "bce_python_sdk-0.9.17-py3-none-any.whl", hash = "sha256:6c5995d60edad3f6771b83ccd79197fc00d88081e3175ca8eecad8a29551ad75"}, + {file = "bce_python_sdk-0.9.17.tar.gz", hash = "sha256:aaece4c590b859ad6bc2d6a04b4a01308ac781ef1d539116b299ec50d62e1ca1"}, ] [package.dependencies] @@ -461,17 +461,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.131" +version = "1.34.132" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.131-py3-none-any.whl", hash = "sha256:05e388cb937e82be70bfd7eb0c84cf8011ff35cf582a593873ac21675268683b"}, - {file = "boto3-1.34.131.tar.gz", hash = "sha256:dab8f72a6c4e62b4fd70da09e08a6b2a65ea2115b27dd63737142005776ef216"}, + {file = "boto3-1.34.132-py3-none-any.whl", hash = "sha256:b5d1681a0d8bf255787c8b37f911d706672d5722c9ace5342cd283a3cdb04820"}, + {file = "boto3-1.34.132.tar.gz", hash = "sha256:3b2964060620f1bbe9574b5f8d3fb2a4e087faacfc6023c24154b184f1b16443"}, ] [package.dependencies] -botocore = ">=1.34.131,<1.35.0" +botocore = ">=1.34.132,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -480,13 +480,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.131" +version = "1.34.132" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.131-py3-none-any.whl", hash = "sha256:13b011d7b206ce00727dcee26548fa3b550db9046d5a0e90ac25a6e6c8fde6ef"}, - {file = "botocore-1.34.131.tar.gz", hash = "sha256:502ddafe1d627fcf1e4c007c86454e5dd011dba7c58bd8e8a5368a79f3e387dc"}, + {file = "botocore-1.34.132-py3-none-any.whl", hash = "sha256:06ef8b4bd3b3cb5a9b9a4273a543b257be3304030978ba51516b576a65156c39"}, + {file = "botocore-1.34.132.tar.gz", hash = "sha256:372a6cfce29e5de9bcf8c95af901d0bc3e27d8aa2295fadee295424f95f43f16"}, ] [package.dependencies] @@ -2576,13 +2576,13 @@ test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", [[package]] name = "google-ai-generativelanguage" -version = "0.6.4" +version = "0.6.5" description = "Google Ai Generativelanguage API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-ai-generativelanguage-0.6.4.tar.gz", hash = "sha256:1750848c12af96cb24ae1c3dd05e4bfe24867dc4577009ed03e1042d8421e874"}, - {file = "google_ai_generativelanguage-0.6.4-py3-none-any.whl", hash = "sha256:730e471aa549797118fb1c88421ba1957741433ada575cf5dd08d3aebf903ab1"}, + {file = "google-ai-generativelanguage-0.6.5.tar.gz", hash = "sha256:c4089c277fa4e26722f76ab03ee3039f28be8bf1c9be282948b9583a154c6d79"}, + {file = "google_ai_generativelanguage-0.6.5-py3-none-any.whl", hash = "sha256:236875bb4a6d6ebdba2f12bd9d5e776100fd913402157a47b5e9fb80a13f25a7"}, ] [package.dependencies] @@ -2896,16 +2896,16 @@ testing = ["pytest"] [[package]] name = "google-generativeai" -version = "0.5.4" +version = "0.7.0" description = "Google Generative AI High level API client library and tools." optional = false python-versions = ">=3.9" 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] -google-ai-generativelanguage = "0.6.4" +google-ai-generativelanguage = "0.6.5" google-api-core = "*" google-api-python-client = "*" google-auth = ">=2.15.0" @@ -3812,72 +3812,72 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jiter" -version = "0.4.2" +version = "0.5.0" description = "Fast iterable JSON parser." optional = false python-versions = ">=3.8" files = [ - {file = "jiter-0.4.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c2b003ff58d14f5e182b875acd5177b2367245c19a03be9a2230535d296f7550"}, - {file = "jiter-0.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b48c77c25f094707731cd5bad6b776046846b60a27ee20efc8fadfb10a89415f"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f50ad6b172bde4d45f4d4ea10c49282a337b8bb735afc99763dfa55ea84a743"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:95f6001e86f525fbbc9706db2078dc22be078b0950de55b92d37041930f5f940"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16646ef23b62b007de80460d303ebb2d81e355dac9389c787cec87cdd7ffef2f"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b4e847c13b0bf1255c711a92330e7a8cb8b5cdd1e37d7db309627bcdd3367ff"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c536589be60e4c5f2b20fadc4db7e9f55d4c9df3551f29ddf1c4a18dcc9dd54"}, - {file = "jiter-0.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3b2763996167830889a854b4ded30bb90897f9b76be78069c50c3ec4540950e"}, - {file = "jiter-0.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:675e8ab98c99495091af6b6e9bf2b6353bcf81f25ab6ce27d36127e315b4505d"}, - {file = "jiter-0.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e48e43d9d999aaf55f53406b8846ff8cbe3e47ee4b9dc37e5a10a65ce760809f"}, - {file = "jiter-0.4.2-cp310-none-win32.whl", hash = "sha256:881b6e67c50bc36acb3570eda693763c8cd77d590940e06fa6d325d0da52ec1b"}, - {file = "jiter-0.4.2-cp310-none-win_amd64.whl", hash = "sha256:bb8f7b43259efc6add0d721ade2953e064b24e2026d26d979bc09ec080844cef"}, - {file = "jiter-0.4.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:24ad336ac47f274fa83f6fbedcabff9d3387c80f67c66b992688e6a8ba2c47e9"}, - {file = "jiter-0.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fc392a220095730afe365ce1516f2f88bb085a2fd29ea191be9c6e3c71713d9a"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1fdc408de36c81460896de0176f2f7b9f3574dcd35693a0b2c00f4ca34c98e4"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c10ad76722ee6a8c820b0db06a793c08b7d679e5201b9563015bd1e06c959a09"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbb46d1e9c82bba87f0cbda38413e49448a7df35b1e55917124bff9f38974a23"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:194e28ef4b5f3b61408cb2ee6b6dcbcdb0c9063d01b92b01345b7605692849f5"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f0a447533eccd62748a727e058efa10a8d7cf1de8ffe1a4d705ecb41dad9090"}, - {file = "jiter-0.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5f7704d7260bbb88cca3453951af739589132b26e896a3144fa2dae2263716d7"}, - {file = "jiter-0.4.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:01427458bc9550f2eda09d425755330e7d0eb09adce099577433bebf05d28d59"}, - {file = "jiter-0.4.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:159b8416879c0053b17c352f70b67b749ef5b2924c6154318ecf71918aab0905"}, - {file = "jiter-0.4.2-cp311-none-win32.whl", hash = "sha256:f2445234acfb79048ce1a0d5d0e181abb9afd9e4a29d8d9988fe26cc5773a81a"}, - {file = "jiter-0.4.2-cp311-none-win_amd64.whl", hash = "sha256:e15a65f233b6b0e5ac10ddf3b97ceb18aa9ffba096259961641d78b4ee321bd5"}, - {file = "jiter-0.4.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d61d59521aea9745447ce50f74d39a16ef74ec9d6477d9350d77e75a3d774ad2"}, - {file = "jiter-0.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eef607dc0acc251923427808dbd017f1998ae3c1a0430a261527aa5cbb3a942"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af6bf39954646e374fc47429c656372ac731a6a26b644158a5a84bcdbed33a47"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f509d23606e476852ee46a2b65b5c4ad3905f17424d9cc19c1dffa1c94ba3c6"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59672774daa44ee140aada0c781c82bee4d9ac5e522966186cfb6b3c217d8a51"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24a0458efac5afeca254cf557b8a654e17013075a69905c78f88d557f129d871"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8860766d1c293e75c1bb4e25b74fa987e3adf199cac3f5f9e6e49c2bebf092f"}, - {file = "jiter-0.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a109f3281b72bbf4921fe43db1005c004a38559ca0b6c4985add81777dfe0a44"}, - {file = "jiter-0.4.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:faa7e667454b77ad2f0ef87db39f4944de759617aadf210ea2b73f26bb24755f"}, - {file = "jiter-0.4.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3512f8b00cafb6780b427cb6282800d2bf8277161d9c917830661bd4ed1d3528"}, - {file = "jiter-0.4.2-cp312-none-win32.whl", hash = "sha256:853b35d508ee5b66d06630473c1c0b7bb5e29bf4785c9d2202437116c94f7e21"}, - {file = "jiter-0.4.2-cp312-none-win_amd64.whl", hash = "sha256:4a3a8197784278eb8b24cb02c45e1cad67c2ce5b5b758adfb19b87f74bbdff9c"}, - {file = "jiter-0.4.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:ca2a4d750aed3154b89f2efb148609fc985fad8db739460797aaf9b478acedda"}, - {file = "jiter-0.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0e6c304b3cc6896256727e1fb8991c7179a345eca8224e201795e9cacf4683b0"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cc34ac708ae1750d077e490321761ec4b9a055b994cbdd1d6fbd37099e4aa7b"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c93383875ab8d2e4f760aaff335b4a12ff32d4f9cf49c4498d657734f611466"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce197ee044add576afca0955b42142dd0312639adb6ebadbdbe4277f2855614f"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a427716813ff65480ca5b5117cfa099f49b49cd38051f8609bd0d5493013ca0"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:479990218353356234669e70fac53e5eb6f739a10db25316171aede2c97d9364"}, - {file = "jiter-0.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d35a91ec5ac74cf33234c431505299fa91c0a197c2dbafd47400aca7c69489d4"}, - {file = "jiter-0.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b27189847193708c94ad10ca0d891309342ae882725d2187cf5d2db02bde8d1b"}, - {file = "jiter-0.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:76c255308cd1093fb411a03756b7bb220e48d4a98c30cbc79ed448bf3978e27d"}, - {file = "jiter-0.4.2-cp38-none-win32.whl", hash = "sha256:bb77438060bad49cc251941e6701b31138365c8a0ddaf10cdded2fcc6dd30701"}, - {file = "jiter-0.4.2-cp38-none-win_amd64.whl", hash = "sha256:ce858af19f7ce0d4b51c9f6c0c9d08f1e9dcef1986c5875efd0674a7054292ca"}, - {file = "jiter-0.4.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:6128838a2f357b3921b2a3242d5dc002ae4255ecc8f9f05c20d56d7d2d79c5ad"}, - {file = "jiter-0.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f2420cebb9ba856cb57dcab1d2d8def949b464b0db09c22a4e4dbd52fff7b200"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5d13d8128e853b320e00bb18bd4bb8b136cc0936091dc87633648fc688eb705"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eba5d6e54f149c508ba88677f97d3dc7dd75e9980d234bbac8027ac6db0763a3"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0fad5d64af0bc0545237419bf4150d8de56f0bd217434bdd1a59730327252bef"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d179e7bca89cf5719bd761dd37a341ff0f98199ecaa9c14af09792e47e977cc"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36353caee9f103d8ee7bda077f6400505b0f370e27eabcab33a33d21de12a2a6"}, - {file = "jiter-0.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dd146c25bce576ca5db64fc7eccb8862af00f1f0e30108796953f12a53660e4c"}, - {file = "jiter-0.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:14b7c08cadbcd703041c66dc30e24e17de2f340281cac0e69374223ecf153aa4"}, - {file = "jiter-0.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a90f1a8b3d29aea198f8ea2b01148276ced8056e5103f32525266b3d880e65c9"}, - {file = "jiter-0.4.2-cp39-none-win32.whl", hash = "sha256:25b174997c780337b61ae57b1723455eecae9a17a9659044fd3c3b369190063f"}, - {file = "jiter-0.4.2-cp39-none-win_amd64.whl", hash = "sha256:bef62cea18521c5b99368147040c7e560c55098a35c93456f110678a2d34189a"}, - {file = "jiter-0.4.2.tar.gz", hash = "sha256:29b9d44f23f0c05f46d482f4ebf03213ee290d77999525d0975a17f875bf1eea"}, + {file = "jiter-0.5.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b599f4e89b3def9a94091e6ee52e1d7ad7bc33e238ebb9c4c63f211d74822c3f"}, + {file = "jiter-0.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a063f71c4b06225543dddadbe09d203dc0c95ba352d8b85f1221173480a71d5"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc0d5b8b3dd12e91dd184b87273f864b363dfabc90ef29a1092d269f18c7e28"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c22541f0b672f4d741382a97c65609332a783501551445ab2df137ada01e019e"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63314832e302cc10d8dfbda0333a384bf4bcfce80d65fe99b0f3c0da8945a91a"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a25fbd8a5a58061e433d6fae6d5298777c0814a8bcefa1e5ecfff20c594bd749"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:503b2c27d87dfff5ab717a8200fbbcf4714516c9d85558048b1fc14d2de7d8dc"}, + {file = "jiter-0.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d1f3d27cce923713933a844872d213d244e09b53ec99b7a7fdf73d543529d6d"}, + {file = "jiter-0.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c95980207b3998f2c3b3098f357994d3fd7661121f30669ca7cb945f09510a87"}, + {file = "jiter-0.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:afa66939d834b0ce063f57d9895e8036ffc41c4bd90e4a99631e5f261d9b518e"}, + {file = "jiter-0.5.0-cp310-none-win32.whl", hash = "sha256:f16ca8f10e62f25fd81d5310e852df6649af17824146ca74647a018424ddeccf"}, + {file = "jiter-0.5.0-cp310-none-win_amd64.whl", hash = "sha256:b2950e4798e82dd9176935ef6a55cf6a448b5c71515a556da3f6b811a7844f1e"}, + {file = "jiter-0.5.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4c8e1ed0ef31ad29cae5ea16b9e41529eb50a7fba70600008e9f8de6376d553"}, + {file = "jiter-0.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c6f16e21276074a12d8421692515b3fd6d2ea9c94fd0734c39a12960a20e85f3"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5280e68e7740c8c128d3ae5ab63335ce6d1fb6603d3b809637b11713487af9e6"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:583c57fc30cc1fec360e66323aadd7fc3edeec01289bfafc35d3b9dcb29495e4"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26351cc14507bdf466b5f99aba3df3143a59da75799bf64a53a3ad3155ecded9"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829df14d656b3fb87e50ae8b48253a8851c707da9f30d45aacab2aa2ba2d614"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42a4bdcf7307b86cb863b2fb9bb55029b422d8f86276a50487982d99eed7c6e"}, + {file = "jiter-0.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04d461ad0aebf696f8da13c99bc1b3e06f66ecf6cfd56254cc402f6385231c06"}, + {file = "jiter-0.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6375923c5f19888c9226582a124b77b622f8fd0018b843c45eeb19d9701c403"}, + {file = "jiter-0.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2cec323a853c24fd0472517113768c92ae0be8f8c384ef4441d3632da8baa646"}, + {file = "jiter-0.5.0-cp311-none-win32.whl", hash = "sha256:aa1db0967130b5cab63dfe4d6ff547c88b2a394c3410db64744d491df7f069bb"}, + {file = "jiter-0.5.0-cp311-none-win_amd64.whl", hash = "sha256:aa9d2b85b2ed7dc7697597dcfaac66e63c1b3028652f751c81c65a9f220899ae"}, + {file = "jiter-0.5.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9f664e7351604f91dcdd557603c57fc0d551bc65cc0a732fdacbf73ad335049a"}, + {file = "jiter-0.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:044f2f1148b5248ad2c8c3afb43430dccf676c5a5834d2f5089a4e6c5bbd64df"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:702e3520384c88b6e270c55c772d4bd6d7b150608dcc94dea87ceba1b6391248"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:528d742dcde73fad9d63e8242c036ab4a84389a56e04efd854062b660f559544"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cf80e5fe6ab582c82f0c3331df27a7e1565e2dcf06265afd5173d809cdbf9ba"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:44dfc9ddfb9b51a5626568ef4e55ada462b7328996294fe4d36de02fce42721f"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c451f7922992751a936b96c5f5b9bb9312243d9b754c34b33d0cb72c84669f4e"}, + {file = "jiter-0.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:308fce789a2f093dca1ff91ac391f11a9f99c35369117ad5a5c6c4903e1b3e3a"}, + {file = "jiter-0.5.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7f5ad4a7c6b0d90776fdefa294f662e8a86871e601309643de30bf94bb93a64e"}, + {file = "jiter-0.5.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ea189db75f8eca08807d02ae27929e890c7d47599ce3d0a6a5d41f2419ecf338"}, + {file = "jiter-0.5.0-cp312-none-win32.whl", hash = "sha256:e3bbe3910c724b877846186c25fe3c802e105a2c1fc2b57d6688b9f8772026e4"}, + {file = "jiter-0.5.0-cp312-none-win_amd64.whl", hash = "sha256:a586832f70c3f1481732919215f36d41c59ca080fa27a65cf23d9490e75b2ef5"}, + {file = "jiter-0.5.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f04bc2fc50dc77be9d10f73fcc4e39346402ffe21726ff41028f36e179b587e6"}, + {file = "jiter-0.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6f433a4169ad22fcb550b11179bb2b4fd405de9b982601914ef448390b2954f3"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad4a6398c85d3a20067e6c69890ca01f68659da94d74c800298581724e426c7e"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6baa88334e7af3f4d7a5c66c3a63808e5efbc3698a1c57626541ddd22f8e4fbf"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ece0a115c05efca597c6d938f88c9357c843f8c245dbbb53361a1c01afd7148"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:335942557162ad372cc367ffaf93217117401bf930483b4b3ebdb1223dbddfa7"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:649b0ee97a6e6da174bffcb3c8c051a5935d7d4f2f52ea1583b5b3e7822fbf14"}, + {file = "jiter-0.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f4be354c5de82157886ca7f5925dbda369b77344b4b4adf2723079715f823989"}, + {file = "jiter-0.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5206144578831a6de278a38896864ded4ed96af66e1e63ec5dd7f4a1fce38a3a"}, + {file = "jiter-0.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8120c60f8121ac3d6f072b97ef0e71770cc72b3c23084c72c4189428b1b1d3b6"}, + {file = "jiter-0.5.0-cp38-none-win32.whl", hash = "sha256:6f1223f88b6d76b519cb033a4d3687ca157c272ec5d6015c322fc5b3074d8a5e"}, + {file = "jiter-0.5.0-cp38-none-win_amd64.whl", hash = "sha256:c59614b225d9f434ea8fc0d0bec51ef5fa8c83679afedc0433905994fb36d631"}, + {file = "jiter-0.5.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:0af3838cfb7e6afee3f00dc66fa24695199e20ba87df26e942820345b0afc566"}, + {file = "jiter-0.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:550b11d669600dbc342364fd4adbe987f14d0bbedaf06feb1b983383dcc4b961"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:489875bf1a0ffb3cb38a727b01e6673f0f2e395b2aad3c9387f94187cb214bbf"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b250ca2594f5599ca82ba7e68785a669b352156260c5362ea1b4e04a0f3e2389"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ea18e01f785c6667ca15407cd6dabbe029d77474d53595a189bdc813347218e"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:462a52be85b53cd9bffd94e2d788a09984274fe6cebb893d6287e1c296d50653"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92cc68b48d50fa472c79c93965e19bd48f40f207cb557a8346daa020d6ba973b"}, + {file = "jiter-0.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c834133e59a8521bc87ebcad773608c6fa6ab5c7a022df24a45030826cf10bc"}, + {file = "jiter-0.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab3a71ff31cf2d45cb216dc37af522d335211f3a972d2fe14ea99073de6cb104"}, + {file = "jiter-0.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cccd3af9c48ac500c95e1bcbc498020c87e1781ff0345dd371462d67b76643eb"}, + {file = "jiter-0.5.0-cp39-none-win32.whl", hash = "sha256:368084d8d5c4fc40ff7c3cc513c4f73e02c85f6009217922d0823a48ee7adf61"}, + {file = "jiter-0.5.0-cp39-none-win_amd64.whl", hash = "sha256:ce03f7b4129eb72f1687fa11300fbf677b02990618428934662406d2a76742a1"}, + {file = "jiter-0.5.0.tar.gz", hash = "sha256:1d916ba875bcab5c5f7d927df998c4cb694d27dceddf3392e58beaf10563368a"}, ] [[package]] @@ -4292,40 +4292,40 @@ langchain-core = ">=0.2.7,<0.3.0" [[package]] name = "langchain-google-genai" -version = "1.0.6" +version = "1.0.7" description = "An integration package connecting Google's genai package and LangChain" optional = false python-versions = "<4.0,>=3.9" files = [ - {file = "langchain_google_genai-1.0.6-py3-none-any.whl", hash = "sha256:65188b3c2867efda78e09c29371499ab0d25c6a111b175365fdae2b5be1502e6"}, - {file = "langchain_google_genai-1.0.6.tar.gz", hash = "sha256:7c964117fa385c490b323ee50ab46907229823d3678b80bfacc8fa0a237fb0b9"}, + {file = "langchain_google_genai-1.0.7-py3-none-any.whl", hash = "sha256:8fc03a0b5f635d369d1eec25076921ea7a472a1cb96dbea8e8ff2c2cdce58650"}, + {file = "langchain_google_genai-1.0.7.tar.gz", hash = "sha256:6522da59720ad551867e278d63c053e0fb65fa4fa1d65382aacedca5293930fa"}, ] [package.dependencies] -google-generativeai = ">=0.5.2,<0.6.0" -langchain-core = ">=0.2.2,<0.3" +google-generativeai = ">=0.7.0,<0.8.0" +langchain-core = ">=0.2.9,<0.3" [package.extras] images = ["pillow (>=10.1.0,<11.0.0)"] [[package]] name = "langchain-google-vertexai" -version = "1.0.5" +version = "1.0.6" description = "An integration package connecting Google VertexAI and LangChain" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_google_vertexai-1.0.5-py3-none-any.whl", hash = "sha256:38f4a39bf35927d744d0883907c4d4a59eef059e9b36f28bb5c737c2aae6963b"}, - {file = "langchain_google_vertexai-1.0.5.tar.gz", hash = "sha256:50005dc12ff9d66bbbab9e1ab660574b1584eee3e7b5a647dc8a009a94f0c500"}, + {file = "langchain_google_vertexai-1.0.6-py3-none-any.whl", hash = "sha256:240a9be3ae749335ec9a495502ca8f2bff60a432b8400a21cbd93b415e4d166d"}, + {file = "langchain_google_vertexai-1.0.6.tar.gz", hash = "sha256:000c4cfd0dee73317e1752dfeec76a08c5bf24f7a134d79b9905a720ac886b11"}, ] [package.dependencies] -google-cloud-aiplatform = ">=1.47.0,<2.0.0" -google-cloud-storage = ">=2.14.0,<3.0.0" -langchain-core = ">=0.2.2,<0.3" +google-cloud-aiplatform = ">=1.56.0,<2.0.0" +google-cloud-storage = ">=2.17.0,<3.0.0" +langchain-core = ">=0.2.9,<0.3" [package.extras] -anthropic = ["anthropic[vertexai] (>=0.23.0,<1)"] +anthropic = ["anthropic[vertexai] (>=0.29.0,<1)"] [[package]] name = "langchain-groq" @@ -4456,7 +4456,7 @@ six = "*" [[package]] name = "langflow-base" -version = "0.0.78" +version = "0.0.80" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.13" @@ -4538,29 +4538,32 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.81" +version = "0.1.82" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.81-py3-none-any.whl", hash = "sha256:3251d823225eef23ee541980b9d9e506367eabbb7f985a086b5d09e8f78ba7e9"}, - {file = "langsmith-0.1.81.tar.gz", hash = "sha256:585ef3a2251380bd2843a664c9a28da4a7d28432e3ee8bcebf291ffb8e1f0af0"}, + {file = "langsmith-0.1.82-py3-none-any.whl", hash = "sha256:9b3653e7d316036b0c60bf0bc3e280662d660f485a4ebd8e5c9d84f9831ae79c"}, + {file = "langsmith-0.1.82.tar.gz", hash = "sha256:c02e2bbc488c10c13b52c69d271eb40bd38da078d37b6ae7ae04a18bd48140be"}, ] [package.dependencies] 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" [[package]] name = "litellm" -version = "1.40.25" +version = "1.40.26" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.40.25-py3-none-any.whl", hash = "sha256:94bff834ca92338223bed474fe614ab30a706681a596e1e38ea60fe8a574a7a8"}, - {file = "litellm-1.40.25.tar.gz", hash = "sha256:437d515274b8cc901d527fbf14ce46599700225f4e1dae2d19b46b446e402b08"}, + {file = "litellm-1.40.26-py3-none-any.whl", hash = "sha256:5daedec00a3a8e32f55b3099190ccd9d550177f6e516823002831e6620ae771c"}, + {file = "litellm-1.40.26.tar.gz", hash = "sha256:4dfd4ca3eb50a62600e60303c4975ba9fe7c52d07882d0d2b6bad2d474d88758"}, ] [package.dependencies] @@ -4604,13 +4607,13 @@ test = ["httpx (>=0.24.1)", "pytest (>=7.4.0)", "scipy (>=1.10)"] [[package]] name = "locust" -version = "2.29.0" +version = "2.29.1" description = "Developer-friendly load testing framework" optional = false python-versions = ">=3.9" files = [ - {file = "locust-2.29.0-py3-none-any.whl", hash = "sha256:aa9d94d3604ed9f2aab3248460d91e55d3de980a821dffdf8658b439b049d03f"}, - {file = "locust-2.29.0.tar.gz", hash = "sha256:649c99ce49d00720a3084c0109547035ad9021222835386599a8b545d31ebe51"}, + {file = "locust-2.29.1-py3-none-any.whl", hash = "sha256:8b15daab44cdf50eef1860a32bb30969423e3795247115e5a37446da3240c6d6"}, + {file = "locust-2.29.1.tar.gz", hash = "sha256:2e0628a59e2689a50cb4735a9a43709e30f2da7ed276c15d877c5325507f44b1"}, ] [package.dependencies] @@ -4629,6 +4632,7 @@ requests = [ {version = ">=2.26.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" [[package]] @@ -5335,38 +5339,38 @@ dill = ">=0.3.8" [[package]] name = "mypy" -version = "1.10.0" +version = "1.10.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, - {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, - {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, - {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, - {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, - {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, - {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, - {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, - {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, - {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, - {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, - {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, - {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, - {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, - {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, - {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, - {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, - {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, - {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, - {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, - {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, - {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, - {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, + {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, + {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, + {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, + {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, + {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, + {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, + {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, + {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, + {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, + {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, + {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, + {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, + {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, + {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, + {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, + {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, + {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, + {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, + {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, + {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, + {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, + {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, ] [package.dependencies] @@ -8107,13 +8111,13 @@ files = [ [[package]] name = "s3transfer" -version = "0.10.1" +version = "0.10.2" description = "An Amazon S3 Transfer Manager" optional = false -python-versions = ">= 3.8" +python-versions = ">=3.8" files = [ - {file = "s3transfer-0.10.1-py3-none-any.whl", hash = "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"}, - {file = "s3transfer-0.10.1.tar.gz", hash = "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19"}, + {file = "s3transfer-0.10.2-py3-none-any.whl", hash = "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"}, + {file = "s3transfer-0.10.2.tar.gz", hash = "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6"}, ] [package.dependencies] @@ -8291,45 +8295,45 @@ tests = ["black (>=24.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.9)", "numpydoc ( [[package]] name = "scipy" -version = "1.13.1" +version = "1.14.0" description = "Fundamental algorithms for scientific computing in Python" optional = true -python-versions = ">=3.9" +python-versions = ">=3.10" files = [ - {file = "scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca"}, - {file = "scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989"}, - {file = "scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"}, - {file = "scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94"}, - {file = "scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9"}, - {file = "scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299"}, - {file = "scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa"}, - {file = "scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59"}, - {file = "scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1"}, - {file = "scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627"}, - {file = "scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884"}, - {file = "scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16"}, - {file = "scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5"}, - {file = "scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004"}, - {file = "scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d"}, - {file = "scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c"}, - {file = "scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2"}, - {file = "scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7"}, + {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0"}, + {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0"}, + {file = "scipy-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d"}, + {file = "scipy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf"}, + {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8"}, + {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74"}, + {file = "scipy-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb"}, + {file = "scipy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0"}, + {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209"}, + {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14"}, + {file = "scipy-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159"}, + {file = "scipy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20"}, + {file = "scipy-1.14.0.tar.gz", hash = "sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b"}, ] [package.dependencies] -numpy = ">=1.22.4,<2.3" +numpy = ">=1.23.5,<2.3" [package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy", "pycodestyle", "pydevtool", "rich-click", "ruff", "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)"] -test = ["array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +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.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 = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "sentence-transformers" @@ -8409,13 +8413,13 @@ tornado = ["tornado (>=5)"] [[package]] name = "setuptools" -version = "70.1.0" +version = "70.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-70.1.0-py3-none-any.whl", hash = "sha256:d9b8b771455a97c8a9f3ab3448ebe0b29b5e105f1228bba41028be116985a267"}, - {file = "setuptools-70.1.0.tar.gz", hash = "sha256:01a1e793faa5bd89abc851fa15d0a0db26f160890c7102cd8dce643e886b47f5"}, + {file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, + {file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, ] [package.extras] @@ -9405,13 +9409,13 @@ urllib3 = ">=2" [[package]] name = "types-setuptools" -version = "70.0.0.20240524" +version = "70.1.0.20240625" description = "Typing stubs for setuptools" optional = false python-versions = ">=3.8" files = [ - {file = "types-setuptools-70.0.0.20240524.tar.gz", hash = "sha256:e31fee7b9d15ef53980526579ac6089b3ae51a005a281acf97178e90ac71aff6"}, - {file = "types_setuptools-70.0.0.20240524-py3-none-any.whl", hash = "sha256:8f5379b9948682d72a9ab531fbe52932e84c4f38deda570255f9bae3edd766bc"}, + {file = "types-setuptools-70.1.0.20240625.tar.gz", hash = "sha256:eb7175c9a304de4de9f4dfd0f299c754ac94cd9e30a262fbb5ff3047a0a6c517"}, + {file = "types_setuptools-70.1.0.20240625-py3-none-any.whl", hash = "sha256:181986729bdae9fa7efc7d37f1578361739e35dd6ec456d37de8e8f3bd2be1ef"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 0ea058281..159c81fbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.3" +version = "1.0.5" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/langflow/__main__.py b/src/backend/base/langflow/__main__.py index 730d31ea7..256b614c2 100644 --- a/src/backend/base/langflow/__main__.py +++ b/src/backend/base/langflow/__main__.py @@ -4,12 +4,12 @@ import sys import time import warnings from pathlib import Path -from typing import Optional +from typing import Any, Callable, Optional import click import httpx import typer -from dotenv import load_dotenv +from dotenv import dotenv_values, load_dotenv from multiprocess import Process, cpu_count # type: ignore from packaging import version as pkg_version from rich import box @@ -130,6 +130,29 @@ def run( if env_file: 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( dev=dev, diff --git a/src/backend/base/langflow/api/v1/chat.py b/src/backend/base/langflow/api/v1/chat.py index dc44d498b..e19342568 100644 --- a/src/backend/base/langflow/api/v1/chat.py +++ b/src/backend/base/langflow/api/v1/chat.py @@ -121,9 +121,9 @@ async def retrieve_vertices_order( background_tasks.add_task( telemetry_service.log_package_playground, PlaygroundPayload( - seconds=int(time.perf_counter() - start_time), - componentCount=components_count, - success=True, + playgroundSeconds=int(time.perf_counter() - start_time), + playgroundComponentCount=components_count, + playgroundSuccess=True, ), ) 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( telemetry_service.log_package_playground, PlaygroundPayload( - seconds=int(time.perf_counter() - start_time), - componentCount=components_count, - success=False, - errorMessage=str(exc), + playgroundSeconds=int(time.perf_counter() - start_time), + playgroundComponentCount=components_count, + playgroundSuccess=False, + playgroundErrorMessage=str(exc), ), ) if "stream or streaming set to True" in str(exc): @@ -280,10 +280,10 @@ async def build_vertex( background_tasks.add_task( telemetry_service.log_package_component, ComponentPayload( - name=vertex_id, - seconds=int(time.perf_counter() - start_time), - success=valid, - errorMessage=params, + componentName=vertex_id, + componentSeconds=int(time.perf_counter() - start_time), + componentSuccess=valid, + componentErrorMessage=params, ), ) return build_response @@ -291,10 +291,10 @@ async def build_vertex( background_tasks.add_task( telemetry_service.log_package_component, ComponentPayload( - name=vertex_id, - seconds=int(time.perf_counter() - start_time), - success=False, - errorMessage=str(exc), + componentName=vertex_id, + componentSeconds=int(time.perf_counter() - start_time), + componentSuccess=False, + componentErrorMessage=str(exc), ), ) logger.error(f"Error building Component:\n\n{exc}") diff --git a/src/backend/base/langflow/api/v1/endpoints.py b/src/backend/base/langflow/api/v1/endpoints.py index e5c648d1f..92358111a 100644 --- a/src/backend/base/langflow/api/v1/endpoints.py +++ b/src/backend/base/langflow/api/v1/endpoints.py @@ -116,11 +116,29 @@ async def simple_run_flow( return RunResponse(outputs=task_result, session_id=session_id) except sa.exc.StatementError as exc: - # StatementError('(builtins.ValueError) badly formed hexadecimal UUID string') - 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 - raise ValueError(str(exc)) from exc + raise ValueError(str(exc)) from exc + + +async def simple_run_flow_task( + 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) @@ -191,7 +209,7 @@ async def simplified_run_flow( end_time = time.perf_counter() background_tasks.add_task( 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 @@ -199,7 +217,9 @@ async def simplified_run_flow( end_time = time.perf_counter() background_tasks.add_task( 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): # 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) background_tasks.add_task( 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 @@ -266,20 +288,25 @@ async def webhook_run_flow( ) logger.debug("Starting background task") background_tasks.add_task( # type: ignore - simple_run_flow, + simple_run_flow_task, flow=flow, input_request=input_request, ) background_tasks.add_task( 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"} except Exception as exc: background_tasks.add_task( telemetry_service.log_package_run, 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): diff --git a/src/backend/base/langflow/api/v1/flows.py b/src/backend/base/langflow/api/v1/flows.py index 800e2c088..d735a314b 100644 --- a/src/backend/base/langflow/api/v1/flows.py +++ b/src/backend/base/langflow/api/v1/flows.py @@ -209,6 +209,23 @@ def update_flow( webhook_component = get_webhook_component_in_flow(db_flow.data) db_flow.webhook = webhook_component is not None 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: default_folder = session.exec(select(Folder).where(Folder.name == DEFAULT_FOLDER_NAME)).first() if default_folder: diff --git a/src/backend/base/langflow/components/models/GoogleGenerativeAIModel.py b/src/backend/base/langflow/components/models/GoogleGenerativeAIModel.py index 377e307a9..d4e75e54b 100644 --- a/src/backend/base/langflow/components/models/GoogleGenerativeAIModel.py +++ b/src/backend/base/langflow/components/models/GoogleGenerativeAIModel.py @@ -3,44 +3,40 @@ from pydantic.v1 import SecretStr from langflow.base.constants import STREAM_INFO_TEXT from langflow.base.models.model import LCModelComponent 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): - display_name: str = "Google Generative AI" - description: str = "Generate text using Google Generative AI." + display_name = "Google Generative AI" + description = "Generate text using Google Generative AI." icon = "GoogleGenerativeAI" inputs = [ - SecretStrInput( - name="google_api_key", - display_name="Google API Key", - info="The Google API Key to use for the Google Generative AI.", + MessageInput(name="input_value", display_name="Input"), + IntInput( + name="max_output_tokens", + display_name="Max Output Tokens", + info="The maximum number of tokens to generate.", ), DropdownInput( name="model", display_name="Model", 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", ), - IntInput( - name="max_output_tokens", - display_name="Max Output Tokens", - info="The maximum number of tokens to generate.", - 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, + SecretStrInput( + name="google_api_key", + display_name="Google API Key", + info="The Google API Key to use for the Google Generative AI.", ), FloatInput( name="top_p", @@ -48,29 +44,26 @@ class GoogleGenerativeAIComponent(LCModelComponent): info="The maximum cumulative probability of tokens to consider when sampling.", advanced=True, ), + FloatInput(name="temperature", display_name="Temperature", value=0.1), + BoolInput(name="stream", display_name="Stream", info=STREAM_INFO_TEXT, advanced=True), IntInput( 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.", 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( name="system_message", display_name="System Message", info="System message to pass to the model.", advanced=True, ), - ] - outputs = [ - Output(display_name="Text", name="text_output", method="text_response"), - Output(display_name="Language Model", name="model_output", method="build_model"), + 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, + ), ] def build_model(self) -> LanguageModel: diff --git a/src/backend/base/langflow/services/auth/utils.py b/src/backend/base/langflow/services/auth/utils.py index b0a35e474..4c2fdbfb4 100644 --- a/src/backend/base/langflow/services/auth/utils.py +++ b/src/backend/base/langflow/services/auth/utils.py @@ -164,15 +164,15 @@ async def get_current_user_for_websocket( def get_current_active_user(current_user: Annotated[User, Depends(get_current_user)]): 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 def get_current_active_superuser(current_user: Annotated[User, Depends(get_current_user)]) -> User: 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: - 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 @@ -324,8 +324,8 @@ def authenticate_user(username: str, password: str, db: Session = Depends(get_se if not user.is_active: if not user.last_login_at: - raise HTTPException(status_code=400, detail="Waiting for approval") - raise HTTPException(status_code=400, detail="Inactive user") + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Waiting for approval") + raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Inactive user") return user if verify_password(password, user.password) else None diff --git a/src/backend/base/langflow/services/telemetry/schema.py b/src/backend/base/langflow/services/telemetry/schema.py index bba7a23e4..9d62e128a 100644 --- a/src/backend/base/langflow/services/telemetry/schema.py +++ b/src/backend/base/langflow/services/telemetry/schema.py @@ -2,10 +2,10 @@ from pydantic import BaseModel class RunPayload(BaseModel): - IsWebhook: bool = False - seconds: int - success: bool - errorMessage: str = "" + runIsWebhook: bool = False + runSeconds: int + runSuccess: bool + runErrorMessage: str = "" class ShutdownPayload(BaseModel): @@ -23,14 +23,14 @@ class VersionPayload(BaseModel): class PlaygroundPayload(BaseModel): - seconds: int - componentCount: int | None = None - success: bool - errorMessage: str = "" + playgroundSeconds: int + playgroundComponentCount: int | None = None + playgroundSuccess: bool + playgroundErrorMessage: str = "" class ComponentPayload(BaseModel): - name: str - seconds: int - success: bool - errorMessage: str + componentName: str + componentSeconds: int + componentSuccess: bool + componentErrorMessage: str diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 256a5eef9..fd3571889 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -1295,18 +1295,21 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langsmith" -version = "0.1.81" +version = "0.1.82" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.81-py3-none-any.whl", hash = "sha256:3251d823225eef23ee541980b9d9e506367eabbb7f985a086b5d09e8f78ba7e9"}, - {file = "langsmith-0.1.81.tar.gz", hash = "sha256:585ef3a2251380bd2843a664c9a28da4a7d28432e3ee8bcebf291ffb8e1f0af0"}, + {file = "langsmith-0.1.82-py3-none-any.whl", hash = "sha256:9b3653e7d316036b0c60bf0bc3e280662d660f485a4ebd8e5c9d84f9831ae79c"}, + {file = "langsmith-0.1.82.tar.gz", hash = "sha256:c02e2bbc488c10c13b52c69d271eb40bd38da078d37b6ae7ae04a18bd48140be"}, ] [package.dependencies] 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" [[package]] diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index c1eab2bb9..3a07f47a5 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow-base" -version = "0.0.79" +version = "0.0.81" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index d6b9d3b74..811237487 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -102,7 +102,7 @@ "postcss": "^8.4.38", "prettier": "^3.3.2", "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", "tailwindcss": "^3.4.4", "tailwindcss-dotted-background": "^1.1.0", diff --git a/src/frontend/package.json b/src/frontend/package.json index a4b10db6c..219b5c7d4 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -113,18 +113,18 @@ "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", + "@types/lodash": "4.17.5", "@types/node": "^20.14.2", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/uuid": "^9.0.8", - "@types/lodash": "4.17.5", "@vitejs/plugin-react-swc": "^3.7.0", "autoprefixer": "^10.4.19", "eslint": "^9.5.0", "postcss": "^8.4.38", "prettier": "^3.3.2", "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", "tailwindcss": "^3.4.4", "tailwindcss-dotted-background": "^1.1.0", diff --git a/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx b/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx index b55788134..d0c3d4e53 100644 --- a/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx +++ b/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx @@ -153,7 +153,7 @@ export default function TableNodeCellRender({ disabled={disabled} editNode={true} value={ - templateValue?.length === 0 || !templateValue + Object.keys(templateValue)?.length === 0 || !templateValue ? [{ "": "" }] : convertObjToArray(templateValue, templateData.type) } diff --git a/src/frontend/src/components/textAreaComponent/index.tsx b/src/frontend/src/components/textAreaComponent/index.tsx index ce42437d7..18a7f5b40 100644 --- a/src/frontend/src/components/textAreaComponent/index.tsx +++ b/src/frontend/src/components/textAreaComponent/index.tsx @@ -2,6 +2,7 @@ import { useEffect } from "react"; import { EDIT_TEXT_MODAL_TITLE } from "../../constants/constants"; import { TypeModal } from "../../constants/enums"; import GenericModal from "../../modals/genericModal"; +import { Case } from "../../shared/components/caseComponent"; import { TextAreaComponentType } from "../../types/components"; import IconComponent from "../genericIconComponent"; import { Button } from "../ui/button"; @@ -24,29 +25,31 @@ export default function TextAreaComponent({ return (
- { - onChange(event.target.value); - }} - /> -
- + { - onChange(value); - }} disabled={disabled} - > - {!editNode && ( + className={editNode ? "input-edit-node w-full" : "w-full"} + placeholder={"Type something..."} + onChange={(event) => { + onChange(event.target.value); + }} + /> + + { + onChange(value); + }} + disabled={disabled} + > + {!editNode ? ( +
- )} - -
+
+ ) : ( + + )} +
); diff --git a/src/frontend/src/modals/editNodeModal/index.tsx b/src/frontend/src/modals/editNodeModal/index.tsx index cb6f82f59..f4a368fa6 100644 --- a/src/frontend/src/modals/editNodeModal/index.tsx +++ b/src/frontend/src/modals/editNodeModal/index.tsx @@ -65,12 +65,6 @@ const EditNodeModal = forwardRef( } }, [gridApi, open]); - // useEffect(() => { - // return () => { - // setOpenWDoubleClick(false); - // }; - // }, []); - return ( diff --git a/src/frontend/tests/end-to-end/basicExamples.spec.ts b/src/frontend/tests/end-to-end/basicExamples.spec.ts index e103fff30..c5f80c362 100644 --- a/src/frontend/tests/end-to-end/basicExamples.spec.ts +++ b/src/frontend/tests/end-to-end/basicExamples.spec.ts @@ -270,12 +270,12 @@ test("Blog Writer", async ({ page }) => { "https://www.natgeokids.com/uk/discover/animals/sea-life/turtle-facts/", ); await page - .getByTestId("input-list-input_urls-0") - .nth(1) + .getByTestId("input-list-input_urls-1") + .nth(0) .fill("https://www.originaldiving.com/blog/top-ten-turtle-facts"); await page - .getByTestId("textarea-input_value") + .getByTestId("popover-anchor-input-input_value") .nth(0) .fill( "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.waitForTimeout(5000); await page.getByText("built successfully").last().click({ - timeout: 15000, + timeout: 30000, }); 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.waitForTimeout(2000); - await page.getByTestId("button_run_astra db vector store").first().click(); - await page - .getByText("Astra DB Vector Store built successfully") - .last() - .click({ - timeout: 15000, - }); + await page.getByTestId("button_run_astra db").first().click(); + await page.getByText("built successfully").last().click({ + timeout: 30000, + }); await page.getByTestId("button_run_chat output").click(); await page.getByText("built successfully").last().click({ - timeout: 15000, + timeout: 30000, }); await page.getByText("Playground", { exact: true }).click(); @@ -427,15 +424,6 @@ test("Vector Store RAG", async ({ page }) => { .last() .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("Default Session").last().click(); diff --git a/src/frontend/tests/end-to-end/chatInputOutput.spec.ts b/src/frontend/tests/end-to-end/chatInputOutput.spec.ts index e71178040..e1adf3d88 100644 --- a/src/frontend/tests/end-to-end/chatInputOutput.spec.ts +++ b/src/frontend/tests/end-to-end/chatInputOutput.spec.ts @@ -23,7 +23,7 @@ test("chat_io_teste", async ({ page }) => { } const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/ChatTest.json", + "tests/end-to-end/assets/ChatTest.json", "utf-8", ); diff --git a/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts b/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts index 4de3c49e5..524312bb3 100644 --- a/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts +++ b/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts @@ -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.getByTestId("icon-LucideSend").click(); 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(); expect(valueUser).toBe("User"); expect(valueAI).toBe("AI"); + await page.keyboard.press("Escape"); + await page .getByTestId("textarea-input_value") - .nth(1) + .nth(0) .fill( "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 - .getByTestId("textarea-sender_name") + .getByTestId("popover-anchor-input-sender_name") .nth(1) .fill("TestSenderNameUser"); await page - .getByTestId("textarea-sender_name") + .getByTestId("popover-anchor-input-sender_name") .nth(0) .fill("TestSenderNameAI"); @@ -150,6 +157,10 @@ test("user must be able to see output inspection", async ({ page }) => { await page.waitForTimeout(5000); + await page.waitForSelector('[data-testid="icon-ScanEye"]', { + timeout: 30000, + }); + await page.getByTestId("icon-ScanEye").nth(4).click(); 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(); - const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/chain.png", - "utf-8", + // Read the image file as a binary string + const filePath = "tests/end-to-end/assets/chain.png"; + 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 - 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); - + // Locate the target element const element = await page.getByPlaceholder("Send a message..."); + // Dispatch the drop event on the target element await element.dispatchEvent("drop", { dataTransfer }); + await page.waitForTimeout(4000); + await page.getByText("chain.png").isVisible(); await page.getByTestId("icon-LucideSend").click(); await page.waitForTimeout(2000); await page.getByText("chain.png").isVisible(); 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.getByText("Restart").isHidden(); }); diff --git a/src/frontend/tests/end-to-end/codeAreaModalComponent.spec.ts b/src/frontend/tests/end-to-end/codeAreaModalComponent.spec.ts index 6d9ac2d02..044065d18 100644 --- a/src/frontend/tests/end-to-end/codeAreaModalComponent.spec.ts +++ b/src/frontend/tests/end-to-end/codeAreaModalComponent.spec.ts @@ -31,7 +31,7 @@ test("CodeAreaModalComponent", async ({ page }) => { await page.waitForTimeout(1000); await page - .getByTestId("experimentalPython Function") + .getByTestId("prototypesPython Function") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); await page.mouse.down(); @@ -65,19 +65,9 @@ class PythonFunctionComponent(CustomComponent): await page.locator("textarea").fill(wCode); await page.locator('//*[@id="checkAndSaveBtn"]').click(); await page.waitForTimeout(1000); - // expect( - // await page.getByText("invalid syntax (, line 1)").isVisible() - // ).toBeTruthy(); await page.locator("textarea").press("Control+a"); await page.locator("textarea").fill(wCode); await page.locator("textarea").fill(customComponentCode); await page.locator('//*[@id="checkAndSaveBtn"]').click(); 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"); }); diff --git a/src/frontend/tests/end-to-end/deleteComponentFlows.spec.ts b/src/frontend/tests/end-to-end/deleteComponentFlows.spec.ts index 7992dcb6e..9099727b6 100644 --- a/src/frontend/tests/end-to-end/deleteComponentFlows.spec.ts +++ b/src/frontend/tests/end-to-end/deleteComponentFlows.spec.ts @@ -17,7 +17,14 @@ test("should delete a flow", async ({ page }) => { await page.waitForTimeout(5000); await page.getByText("My Collection").nth(0).click(); 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.getByTestId("icon-Trash2").click(); await page .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("Components").first().click(); 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.getByTestId("icon-Trash2").click(); await page diff --git a/src/frontend/tests/end-to-end/dragAndDrop.spec.ts b/src/frontend/tests/end-to-end/dragAndDrop.spec.ts index 03d11aaf7..ee1789d2d 100644 --- a/src/frontend/tests/end-to-end/dragAndDrop.spec.ts +++ b/src/frontend/tests/end-to-end/dragAndDrop.spec.ts @@ -26,7 +26,7 @@ test.describe("drag and drop test", () => { await page.locator("span").filter({ hasText: "My Collection" }).isVisible(); // Read your file into a buffer. const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/collection.json", + "tests/end-to-end/assets/collection.json", "utf-8", ); diff --git a/src/frontend/tests/end-to-end/filterEdge.spec.ts b/src/frontend/tests/end-to-end/filterEdge.spec.ts index a85f2c3e5..77bef251d 100644 --- a/src/frontend/tests/end-to-end/filterEdge.spec.ts +++ b/src/frontend/tests/end-to-end/filterEdge.spec.ts @@ -44,24 +44,40 @@ test("LLMChain - Tooltip", async ({ page }) => { ) .hover() .then(async () => { - await expect(page.getByTestId("tooltip-Chains").first()).toBeVisible(); await expect( - page.getByTestId("tooltip-Model Specs").first(), + page.getByTestId("available-output-chains").first(), ).toBeVisible(); await expect( - page.getByTestId("tooltip-Vector Search").first(), + page.getByTestId("available-output-textsplitters").first(), ).toBeVisible(); await expect( - page.getByTestId("tooltip-Text Splitters").first(), + page.getByTestId("available-output-retrievers").first(), ).toBeVisible(); await expect( - page.getByTestId("tooltip-Retrievers").first(), + page.getByTestId("available-output-prototypes").first(), ).toBeVisible(); - await expect(page.getByTestId("tooltip-Tools").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Memories").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Agents").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Helpers").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Utilities").first()).toBeVisible(); + await expect( + page.getByTestId("available-output-tools").first(), + ).toBeVisible(); + await expect( + 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.waitForTimeout(500); }); @@ -77,12 +93,10 @@ test("LLMChain - Tooltip", async ({ page }) => { .hover() .then(async () => { await expect( - page.getByTestId("tooltip-Model Specs").first(), + page.getByTestId("available-input-models").first(), ).toBeVisible(); await page.waitForTimeout(2000); - await expect(page.getByTestId("tooltip-Models").first()).toBeVisible(); - await page.getByTestId("icon-Search").click(); await page.waitForTimeout(500); @@ -100,12 +114,18 @@ test("LLMChain - Tooltip", async ({ page }) => { .then(async () => { await page.waitForTimeout(2000); - await expect(page.getByTestId("tooltip-Chains").first()).toBeVisible(); 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(); - await expect(page.getByTestId("tooltip-Agents").first()).toBeVisible(); - await expect(page.getByTestId("tooltip-Helpers").first()).toBeVisible(); await page.waitForTimeout(500); }); @@ -176,26 +196,30 @@ test("LLMChain - Filter", async ({ page }) => { ) .click(); - await expect(page.getByTestId("disclosure-model specs")).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(page.getByTestId("disclosure-models")).toBeVisible(); 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(); await expect( - page.getByTestId("model_specsHugging Face Inference API"), + page.getByTestId("memoriesAstra DB Message Reader").first(), ).toBeVisible(); - await expect(page.getByTestId("model_specsOllama")).toBeVisible(); await expect( - page.getByTestId("model_specsQianfanChatEndpoint"), + page.getByTestId("prototypesFlow as Tool").first(), ).toBeVisible(); - await expect(page.getByTestId("model_specsQianfanLLMEndpoint")).toBeVisible(); - await expect(page.getByTestId("model_specsVertexAI")).toBeVisible(); + await expect( + 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(); @@ -219,7 +243,6 @@ test("LLMChain - Filter", async ({ page }) => { .click(); await expect(page.getByTestId("disclosure-models")).toBeVisible(); - await expect(page.getByTestId("disclosure-model specs")).toBeVisible(); await page .locator( @@ -227,10 +250,8 @@ test("LLMChain - Filter", async ({ page }) => { ) .click(); - await expect(page.getByTestId("disclosure-saved")).toBeVisible(); - await expect(page.getByTestId("disclosure-helpers")).toBeVisible(); await expect(page.getByTestId("disclosure-agents")).toBeVisible(); await expect(page.getByTestId("disclosure-chains")).toBeVisible(); - await expect(page.getByTestId("disclosure-experimental")).toBeVisible(); + await expect(page.getByTestId("disclosure-prototypes")).toBeVisible(); }); diff --git a/src/frontend/tests/end-to-end/folders.spec.ts b/src/frontend/tests/end-to-end/folders.spec.ts index 99ed07669..d049b39f9 100644 --- a/src/frontend/tests/end-to-end/folders.spec.ts +++ b/src/frontend/tests/end-to-end/folders.spec.ts @@ -57,7 +57,7 @@ test("add folder by drag and drop", async ({ page }) => { await page.waitForTimeout(2000); const jsonContent = readFileSync( - "src/frontend/tests/end-to-end/assets/collection.json", + "tests/end-to-end/assets/collection.json", "utf-8", ); diff --git a/src/frontend/tests/end-to-end/generalBugs.spec.ts b/src/frontend/tests/end-to-end/generalBugs.spec.ts index 11ec86af4..a0e435fd5 100644 --- a/src/frontend/tests/end-to-end/generalBugs.spec.ts +++ b/src/frontend/tests/end-to-end/generalBugs.spec.ts @@ -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.getByTestId("icon-LucideSend").click(); 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(); expect(valueUser).toBe("User"); diff --git a/src/frontend/tests/end-to-end/inputListComponent.spec.ts b/src/frontend/tests/end-to-end/inputListComponent.spec.ts index e28ba67b2..fa91b685f 100644 --- a/src/frontend/tests/end-to-end/inputListComponent.spec.ts +++ b/src/frontend/tests/end-to-end/inputListComponent.spec.ts @@ -24,11 +24,11 @@ test("InputListComponent", async ({ page }) => { await page.waitForTimeout(3000); await page.getByTestId("extended-disclosure").click(); await page.getByPlaceholder("Search").click(); - await page.getByPlaceholder("Search").fill("astradb"); + await page.getByPlaceholder("Search").fill("url"); await page.waitForTimeout(1000); await page - .getByTestId("vectorsearchAstra DB Search") + .getByTestId("dataURL") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); 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.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("more-options-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 - .getByTestId("input-list-input_metadata_indexing_include-0") + .getByTestId("input-list-input-edit_urls-0") .inputValue(); 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(); if ( value0 !== "test test test test" || - value1 !== "test1 test1 test1 test1" + value1 !== "test1 test1 test1 test1" || + value2 !== "test2 test2 test2 test2" ) { expect(false).toBeTruthy(); } - await page - .getByTestId("input-list-minus-btn_metadata_indexing_include-1") - .click(); + await page.getByTestId("input-list-minus-btn-edit_urls-1").click(); const plusButtonLocator = page.getByTestId( - "input-list-plus-btn_metadata_indexing_include-1", + "input-list-minus-btn-edit_urls-1", ); const elementCount = await plusButtonLocator?.count(); - if (elementCount > 0) { + if (elementCount > 1) { expect(false).toBeTruthy(); } - 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-plus-btn_metadata_indexing_include-0") - .click(); + await page.getByText("Save Changes", { exact: true }).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 - .getByTestId("input-list-input_metadata_indexing_include-0") - .fill("test test test test"); - await page - .getByTestId("input-list-input_metadata_indexing_include-1") + .getByTestId("input-list-input_urls-1") .fill("test1 test1 test1 test1"); await page - .getByTestId("input-list-input_metadata_indexing_include-2") + .getByTestId("input-list-input_urls-2") .fill("test2 test2 test2 test2"); await page - .getByTestId("input-list-input_metadata_indexing_include-3") + .getByTestId("input-list-input_urls-3") .fill("test3 test3 test3 test3"); await page.getByTestId("div-generic-node").click(); @@ -132,16 +108,16 @@ test("InputListComponent", async ({ page }) => { await page.getByTestId("edit-button-modal").click(); const value0Edit = await page - .getByTestId("input-list-input-edit_metadata_indexing_include-0") + .getByTestId("input-list-input-edit_urls-0") .inputValue(); const value1Edit = await page - .getByTestId("input-list-input-edit_metadata_indexing_include-1") + .getByTestId("input-list-input-edit_urls-1") .inputValue(); const value2Edit = await page - .getByTestId("input-list-input-edit_metadata_indexing_include-2") + .getByTestId("input-list-input-edit_urls-2") .inputValue(); const value3Edit = await page - .getByTestId("input-list-input-edit_metadata_indexing_include-3") + .getByTestId("input-list-input-edit_urls-3") .inputValue(); if ( @@ -153,23 +129,17 @@ test("InputListComponent", async ({ page }) => { expect(false).toBeTruthy(); } - 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(); - await page - .getByTestId("input-list-minus-btn-edit_metadata_indexing_include-1") - .click(); + await page.getByTestId("input-list-minus-btn-edit_urls-1").click(); + await page.getByTestId("input-list-minus-btn-edit_urls-1").click(); + await page.getByTestId("input-list-minus-btn-edit_urls-1").click(); 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 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(); @@ -178,13 +148,13 @@ test("InputListComponent", async ({ page }) => { } 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 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(); diff --git a/src/frontend/tests/end-to-end/intComponent.spec.ts b/src/frontend/tests/end-to-end/intComponent.spec.ts index aa54ac5b4..30522d397 100644 --- a/src/frontend/tests/end-to-end/intComponent.spec.ts +++ b/src/frontend/tests/end-to-end/intComponent.spec.ts @@ -30,7 +30,7 @@ test("IntComponent", async ({ page }) => { await page.waitForTimeout(1000); await page - .getByTestId("model_specsChatOpenAI") + .getByTestId("modelsOpenAI") .first() .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); @@ -65,7 +65,7 @@ test("IntComponent", async ({ page }) => { expect(false).toBeTruthy(); } - await page.getByTestId("title-ChatOpenAI").click(); + await page.getByTestId("title-OpenAI").click(); await page.getByTitle("fit view").click(); await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click(); diff --git a/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts b/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts index 31a4521ae..685f5b4fd 100644 --- a/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts +++ b/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts @@ -30,7 +30,7 @@ test("KeypairListComponent", async ({ page }) => { await page.waitForTimeout(1000); await page - .getByTestId("model_specsAmazon Bedrock") + .getByTestId("modelsAmazon Bedrock") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); 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.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"]').fill("testtesttesttest"); await page.locator('//*[@id="keypair100"]').click(); diff --git a/src/frontend/tests/end-to-end/promptModalComponent.spec.ts b/src/frontend/tests/end-to-end/promptModalComponent.spec.ts index b91cb6ed5..74bc44480 100644 --- a/src/frontend/tests/end-to-end/promptModalComponent.spec.ts +++ b/src/frontend/tests/end-to-end/promptModalComponent.spec.ts @@ -72,6 +72,8 @@ test("PromptTemplateComponent", async ({ page }) => { expect(false).toBeTruthy(); } + await page.getByTestId("div-generic-node").click(); + await page.getByTestId("more-options-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("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_!@#!@#") { 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!@#!@#") { expect(false).toBeTruthy(); @@ -122,13 +127,20 @@ test("PromptTemplateComponent", async ({ page }) => { expect(false).toBeTruthy(); } + await page.locator('//*[@id="textarea-edit-prompt1"]').click(); await page - .locator('//*[@id="textarea-edit-prompt1"]') + .getByTestId("text-area-modal") .fill("prompt_edit_test_12312312321!@#$"); + + await page.getByText("Finish Editing", { exact: true }).click(); + + await page.locator('//*[@id="textarea-edit-prompt"]').click(); await page - .locator('//*[@id="textarea-edit-prompt"]') + .getByTestId("text-area-modal") .fill("prompt_edit_test_44444444444!@#$"); + await page.getByText("Finish Editing", { exact: true }).click(); + await page.locator('//*[@id="showtemplate"]').click(); expect(await page.locator('//*[@id="showtemplate"]').isChecked()).toBeFalsy(); @@ -174,13 +186,16 @@ test("PromptTemplateComponent", async ({ page }) => { await page.locator('//*[@id="showprompt1"]').click(); 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!@#$") { 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!@#$") { expect(false).toBeTruthy(); diff --git a/src/frontend/tests/end-to-end/saveComponents.spec.ts b/src/frontend/tests/end-to-end/saveComponents.spec.ts index fa9dbbc00..17be7622b 100644 --- a/src/frontend/tests/end-to-end/saveComponents.spec.ts +++ b/src/frontend/tests/end-to-end/saveComponents.spec.ts @@ -26,7 +26,7 @@ test.describe("save component tests", () => { // Read your file into a buffer. 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", ); diff --git a/src/frontend/tests/end-to-end/store.spec.ts b/src/frontend/tests/end-to-end/store.spec.ts index bcd5ec15b..9ca0b040d 100644 --- a/src/frontend/tests/end-to-end/store.spec.ts +++ b/src/frontend/tests/end-to-end/store.spec.ts @@ -259,6 +259,10 @@ test("should share component with share button", async ({ page }) => { await page.getByText("Save").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.getByText("Name:").isVisible(); await page.getByText("Description:").isVisible(); diff --git a/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts b/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts index 590d43933..54cb1f1ad 100644 --- a/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts +++ b/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts @@ -21,8 +21,17 @@ test("TextAreaModalComponent", async ({ page }) => { } 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").fill("prompt"); diff --git a/src/frontend/tests/end-to-end/textInputOutput.spec.ts b/src/frontend/tests/end-to-end/textInputOutput.spec.ts index 586e1361e..40b054c59 100644 --- a/src/frontend/tests/end-to-end/textInputOutput.spec.ts +++ b/src/frontend/tests/end-to-end/textInputOutput.spec.ts @@ -29,8 +29,17 @@ test("TextInputOutputComponent", async ({ page }) => { await page.waitForTimeout(1000); 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").fill("text input"); await page.waitForTimeout(1000); @@ -56,7 +65,15 @@ test("TextInputOutputComponent", async ({ page }) => { 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 .locator( '//*[@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(); 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 await page .locator( @@ -88,6 +114,15 @@ test("TextInputOutputComponent", async ({ page }) => { 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 await page .locator( @@ -96,6 +131,15 @@ test("TextInputOutputComponent", async ({ page }) => { .hover(); 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 await page .locator( diff --git a/src/frontend/tests/end-to-end/toggleComponent.spec.ts b/src/frontend/tests/end-to-end/toggleComponent.spec.ts index 58d909af4..5c8eef429 100644 --- a/src/frontend/tests/end-to-end/toggleComponent.spec.ts +++ b/src/frontend/tests/end-to-end/toggleComponent.spec.ts @@ -21,8 +21,16 @@ test("ToggleComponent", async ({ page }) => { } 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").fill("directory"); diff --git a/src/frontend/tests/end-to-end/tweaks_test.spec.ts b/src/frontend/tests/end-to-end/tweaks_test.spec.ts index 871e8a2ba..bc4ab7c56 100644 --- a/src/frontend/tests/end-to-end/tweaks_test.spec.ts +++ b/src/frontend/tests/end-to-end/tweaks_test.spec.ts @@ -108,7 +108,13 @@ test("check if tweaks are updating when someothing on the flow changes", async ( .getByTestId("popover-anchor-input-persist_directory") .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(); diff --git a/src/frontend/tests/end-to-end/twoEdges.spec.ts b/src/frontend/tests/end-to-end/twoEdges.spec.ts index abae18ba3..b40ef8a4a 100644 --- a/src/frontend/tests/end-to-end/twoEdges.spec.ts +++ b/src/frontend/tests/end-to-end/twoEdges.spec.ts @@ -24,10 +24,23 @@ test("user should be able to see multiple edges and interact with them", async ( await page.waitForTimeout(1000); 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("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.getByTestId("icon-ChevronDown").last().isVisible(); await page.getByTestId("icon-ChevronDown").last().click(); diff --git a/src/frontend/tests/end-to-end/userSettings.spec.ts b/src/frontend/tests/end-to-end/userSettings.spec.ts index df760cbca..1876031fc 100644 --- a/src/frontend/tests/end-to-end/userSettings.spec.ts +++ b/src/frontend/tests/end-to-end/userSettings.spec.ts @@ -62,10 +62,19 @@ test("should interact with global variables", async ({ page }) => { await page.getByText(randomName).isVisible(); - await page - .getByLabel("Press Space to toggle all rows selection (unchecked)") - .nth(0) - .click(); + const focusElementsOnBoard = async ({ page }) => { + await page.waitForSelector( + '[aria-label="Press Space to toggle all rows selection (unchecked)"]', + { 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.getByText("No data available").isVisible(); }); diff --git a/tests/test_user.py b/tests/test_user.py index cd1cf9165..86d4b1865 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -75,15 +75,15 @@ def test_user_waiting_for_approval( def test_deactivated_user_cannot_login(client, deactivated_user): login_data = {"username": deactivated_user.username, "password": "testpassword"} response = client.post("/api/v1/login", data=login_data) - assert response.status_code == 400, response.json() - assert response.json()["detail"] == "Inactive user" + assert response.status_code == 401, response.json() + assert response.json()["detail"] == "Inactive user", response.text def test_deactivated_user_cannot_access(client, deactivated_user, logged_in_headers): # Assuming the headers for deactivated_user response = client.get("/api/v1/users", headers=logged_in_headers) - assert response.status_code == 400, response.json() - assert response.json()["detail"] == "The user doesn't have enough privileges" + assert response.status_code == 403, response.json() + 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): @@ -124,7 +124,7 @@ def test_inactive_user(client): login_data = {"username": "inactiveuser", "password": "testpassword"} 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" @@ -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): 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"} @@ -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): user_id = test_user["id"] 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"}