diff --git a/poetry.lock b/poetry.lock index 5e53d5282..58498c4d1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. [[package]] name = "aiofiles" @@ -148,6 +148,27 @@ files = [ {file = "aiostream-0.4.5.tar.gz", hash = "sha256:3ecbf87085230fbcd9605c32ca20c4fb41af02c71d076eab246ea22e35947d88"}, ] +[[package]] +name = "anthropic" +version = "0.2.10" +description = "Library for accessing the anthropic API" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anthropic-0.2.10-py3-none-any.whl", hash = "sha256:a007496207fd186b0bcb9592b00ca130069d2a427f3d6f602a61dbbd1ac6316e"}, + {file = "anthropic-0.2.10.tar.gz", hash = "sha256:e4da061a86d8ffb86072c0b0feaf219a3a4f7dfddd4224df9ba769e469498c19"}, +] + +[package.dependencies] +aiohttp = "*" +httpx = "*" +requests = "*" +tokenizers = "*" + +[package.extras] +dev = ["black (>=22.3.0)", "pytest"] + [[package]] name = "anyio" version = "3.7.0" @@ -719,14 +740,14 @@ superset = ["apache-superset (>=1.4.1)"] [[package]] name = "cohere" -version = "4.6.0" +version = "4.7.0" description = "" category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "cohere-4.6.0-py3-none-any.whl", hash = "sha256:fc60fa73a2d96bdb9f70da4a290d3ede320b74ac01a24c229011049d7cb3511f"}, - {file = "cohere-4.6.0.tar.gz", hash = "sha256:43218a0a40f6fc023e068732994fb631ce5d160a0bc9f9a3a22524b5932f34ea"}, + {file = "cohere-4.7.0-py3-none-any.whl", hash = "sha256:ed15621bd271b941110a572cbf6187a4db78cc8d7d9d35a881bffcaeeea21d7c"}, + {file = "cohere-4.7.0.tar.gz", hash = "sha256:46c674545ad36133a555c6db7f25bdc299e05ec4f77dee707b661a57eb06aea6"}, ] [package.dependencies] @@ -862,31 +883,31 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "40.0.2" +version = "41.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, - {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"}, - {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"}, - {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"}, - {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"}, - {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"}, - {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"}, + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:f73bff05db2a3e5974a6fd248af2566134d8981fd7ab012e5dd4ddb1d9a70699"}, + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:1a5472d40c8f8e91ff7a3d8ac6dfa363d8e3138b961529c996f3e2df0c7a411a"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fa01527046ca5facdf973eef2535a27fec4cb651e4daec4d043ef63f6ecd4ca"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b46e37db3cc267b4dea1f56da7346c9727e1209aa98487179ee8ebed09d21e43"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d198820aba55660b4d74f7b5fd1f17db3aa5eb3e6893b0a41b75e84e4f9e0e4b"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:948224d76c4b6457349d47c0c98657557f429b4e93057cf5a2f71d603e2fc3a3"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:059e348f9a3c1950937e1b5d7ba1f8e968508ab181e75fc32b879452f08356db"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b4ceb5324b998ce2003bc17d519080b4ec8d5b7b70794cbd2836101406a9be31"}, + {file = "cryptography-41.0.1-cp37-abi3-win32.whl", hash = "sha256:8f4ab7021127a9b4323537300a2acfb450124b2def3756f64dc3a3d2160ee4b5"}, + {file = "cryptography-41.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:1fee5aacc7367487b4e22484d3c7e547992ed726d14864ee33c0176ae43b0d7c"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9a6c7a3c87d595608a39980ebaa04d5a37f94024c9f24eb7d10262b92f739ddb"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5d092fdfedaec4cbbffbf98cddc915ba145313a6fdaab83c6e67f4e6c218e6f3"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a8e6c2de6fbbcc5e14fd27fb24414507cb3333198ea9ab1258d916f00bc3039"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb33ccf15e89f7ed89b235cff9d49e2e62c6c981a6061c9c8bb47ed7951190bc"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f0ff6e18d13a3de56f609dd1fd11470918f770c6bd5d00d632076c727d35485"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7bfc55a5eae8b86a287747053140ba221afc65eb06207bedf6e019b8934b477c"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eb8163f5e549a22888c18b0d53d6bb62a20510060a22fd5a995ec8a05268df8a"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8dde71c4169ec5ccc1087bb7521d54251c016f126f922ab2dfe6649170a3b8c5"}, + {file = "cryptography-41.0.1.tar.gz", hash = "sha256:d34579085401d3f49762d2f7d6634d6b6c2ae1242202e860f4d26b046e3a1006"}, ] [package.dependencies] @@ -895,23 +916,23 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "check-manifest", "mypy", "ruff"] -sdist = ["setuptools-rust (>=0.11.4)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -tox = ["tox"] [[package]] name = "ctransformers" -version = "0.2.2" +version = "0.2.5" description = "Python bindings for the Transformer models implemented in C/C++ using GGML library." category = "main" optional = false python-versions = "*" files = [ - {file = "ctransformers-0.2.2-py3-none-any.whl", hash = "sha256:bf682dd0293dd87911c9a9a1169a4873ff55baebc16d465c6029c77f11b18cf6"}, - {file = "ctransformers-0.2.2.tar.gz", hash = "sha256:1fc36b3fde36d9fd3cb69e48993315bb1f5f54ae552720eb909dc4b3a131c743"}, + {file = "ctransformers-0.2.5-py3-none-any.whl", hash = "sha256:5e0ee7d2be2cb1d627a702acdbf1f4f3c9c97d706e9d7f59a13079c1836a1432"}, + {file = "ctransformers-0.2.5.tar.gz", hash = "sha256:b813f19d5c2249b75422ae3188b1c834aeb8a095800df32328559a740acdb404"}, ] [package.dependencies] @@ -1044,14 +1065,14 @@ weaviate = ["weaviate-client (>=3.9.0,<3.10.0)"] [[package]] name = "docker" -version = "6.1.2" +version = "6.1.3" description = "A Python library for the Docker Engine API." category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "docker-6.1.2-py3-none-any.whl", hash = "sha256:134cd828f84543cbf8e594ff81ca90c38288df3c0a559794c12f2e4b634ea19e"}, - {file = "docker-6.1.2.tar.gz", hash = "sha256:dcc088adc2ec4e7cfc594e275d8bd2c9738c56c808de97476939ef67db5af8c2"}, + {file = "docker-6.1.3-py3-none-any.whl", hash = "sha256:aecd2277b8bf8e506e484f6ab7aec39abe0038e29fa4a6d3ba86c3fe01844ed9"}, + {file = "docker-6.1.3.tar.gz", hash = "sha256:aa6d17830045ba5ef0168d5eaa34d37beeb113948c413affe1d5991fc11f9a20"}, ] [package.dependencies] @@ -1096,9 +1117,7 @@ files = [ {file = "duckdb-0.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b2707096d6df4321044fcde2c9f04da632d11a8be60957fd09d49a42fae71a29"}, {file = "duckdb-0.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b27df1b70ae74d2c88efb5ffca8490954fdc678099509a9c4404ca30acc53426"}, {file = "duckdb-0.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75a97c800271b52dd0f37696d074c50576dcb4b2750b6115932a98696a268070"}, - {file = "duckdb-0.8.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:804cac261a5e016506a6d67838a65d19b06a237f7949f1704f0e800eb708286a"}, {file = "duckdb-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6b9abca7fa6713e1d031c18485343b4de99742c7e1b85c10718aa2f31a4e2c6"}, - {file = "duckdb-0.8.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:51aa6d606d49072abcfeb3be209eb559ac94c1b5e70f58ac3adbb94aca9cd69f"}, {file = "duckdb-0.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7c8dc769aaf2be0a1c57995ca657e5b92c1c56fc8437edb720ca6cab571adf14"}, {file = "duckdb-0.8.0-cp311-cp311-win32.whl", hash = "sha256:c4207d18b42387c4a035846d8878eb967070198be8ac26fd77797ce320d1a400"}, {file = "duckdb-0.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:0c392257547c20794c3072fcbca99a49ef0a49974005d755e93893e2b4875267"}, @@ -1194,6 +1213,41 @@ files = [ [package.extras] tests = ["asttokens", "littleutils", "pytest", "rich"] +[[package]] +name = "faiss-cpu" +version = "1.7.4" +description = "A library for efficient similarity search and clustering of dense vectors." +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "faiss-cpu-1.7.4.tar.gz", hash = "sha256:265dc31b0c079bf4433303bf6010f73922490adff9188b915e2d3f5e9c82dd0a"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50d4ebe7f1869483751c558558504f818980292a9b55be36f9a1ee1009d9a686"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7b1db7fae7bd8312aeedd0c41536bcd19a6e297229e1dce526bde3a73ab8c0b5"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17b7fa7194a228a84929d9e6619d0e7dbf00cc0f717e3462253766f5e3d07de8"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dca531952a2e3eac56f479ff22951af4715ee44788a3fe991d208d766d3f95f3"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-win_amd64.whl", hash = "sha256:7173081d605e74766f950f2e3d6568a6f00c53f32fd9318063e96728c6c62821"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0bbd6f55d7940cc0692f79e32a58c66106c3c950cee2341b05722de9da23ea3"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e13c14280376100f143767d0efe47dcb32618f69e62bbd3ea5cd38c2e1755926"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c521cb8462f3b00c0c7dfb11caff492bb67816528b947be28a3b76373952c41d"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afdd9fe1141117fed85961fd36ee627c83fc3b9fd47bafb52d3c849cc2f088b7"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-win_amd64.whl", hash = "sha256:2ff7f57889ea31d945e3b87275be3cad5d55b6261a4e3f51c7aba304d76b81fb"}, + {file = "faiss_cpu-1.7.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eeaf92f27d76249fb53c1adafe617b0f217ab65837acf7b4ec818511caf6e3d8"}, + {file = "faiss_cpu-1.7.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:102b1bd763e9b0c281ac312590af3eaf1c8b663ccbc1145821fe6a9f92b8eaaf"}, + {file = "faiss_cpu-1.7.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5512da6707c967310c46ff712b00418b7ae28e93cb609726136e826e9f2f14fa"}, + {file = "faiss_cpu-1.7.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0c2e5b9d8c28c99f990e87379d5bbcc6c914da91ebb4250166864fd12db5755b"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:43f67f325393145d360171cd98786fcea6120ce50397319afd3bb78be409fb8a"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6a4e4af194b8fce74c4b770cad67ad1dd1b4673677fc169723e4c50ba5bd97a8"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31bfb7b9cffc36897ae02a983e04c09fe3b8c053110a287134751a115334a1df"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52d7de96abef2340c0d373c1f5cbc78026a3cebb0f8f3a5920920a00210ead1f"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-win_amd64.whl", hash = "sha256:699feef85b23c2c729d794e26ca69bebc0bee920d676028c06fd0e0becc15c7e"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:559a0133f5ed44422acb09ee1ac0acffd90c6666d1bc0d671c18f6e93ad603e2"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1d71539fe3dc0f1bed41ef954ca701678776f231046bf0ca22ccea5cf5bef6"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12d45e0157024eb3249842163162983a1ac8b458f1a8b17bbf86f01be4585a99"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f0eab359e066d32c874f51a7d4bf6440edeec068b7fe47e6d803c73605a8b4c"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-win_amd64.whl", hash = "sha256:98459ceeeb735b9df1a5b94572106ffe0a6ce740eb7e4626715dd218657bb4dc"}, +] + [[package]] name = "fake-useragent" version = "1.1.3" @@ -1211,14 +1265,14 @@ importlib-resources = {version = ">=5.0", markers = "python_version < \"3.10\""} [[package]] name = "fastapi" -version = "0.95.2" +version = "0.96.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "fastapi-0.95.2-py3-none-any.whl", hash = "sha256:d374dbc4ef2ad9b803899bd3360d34c534adc574546e25314ab72c0c4411749f"}, - {file = "fastapi-0.95.2.tar.gz", hash = "sha256:4d9d3e8c71c73f11874bcf5e33626258d143252e329a01002f767306c64fb982"}, + {file = "fastapi-0.96.0-py3-none-any.whl", hash = "sha256:b8e11fe81e81eab4e1504209917338e0b80f783878a42c2b99467e5e1019a1e9"}, + {file = "fastapi-0.96.0.tar.gz", hash = "sha256:71232d47c2787446991c81c41c249f8a16238d52d779c0e6b43927d3773dbe3c"}, ] [package.dependencies] @@ -1387,14 +1441,14 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.19.0" +version = "2.19.1" description = "Google Authentication Library" category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "google-auth-2.19.0.tar.gz", hash = "sha256:f39d528077ac540793dd3c22a8706178f157642a67d874db25c640b7fead277e"}, - {file = "google_auth-2.19.0-py2.py3-none-any.whl", hash = "sha256:be617bfaf77774008e9d177573f782e109188c8a64ae6e744285df5cea3e7df6"}, + {file = "google-auth-2.19.1.tar.gz", hash = "sha256:a9cfa88b3e16196845e64a3658eb953992129d13ac7337b064c6546f77c17183"}, + {file = "google_auth-2.19.1-py2.py3-none-any.whl", hash = "sha256:ea165e014c7cbd496558796b627c271aa8c18b4cba79dc1cc962b24c5efdfb85"}, ] [package.dependencies] @@ -2037,14 +2091,14 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.13.2" +version = "8.14.0" description = "IPython: Productive Interactive Computing" category = "dev" optional = false python-versions = ">=3.9" files = [ - {file = "ipython-8.13.2-py3-none-any.whl", hash = "sha256:ffca270240fbd21b06b2974e14a86494d6d29290184e788275f55e0b55914926"}, - {file = "ipython-8.13.2.tar.gz", hash = "sha256:7dff3fad32b97f6488e02f87b970f309d082f758d7b7fc252e3b19ee0e432dbb"}, + {file = "ipython-8.14.0-py3-none-any.whl", hash = "sha256:248aca623f5c99a6635bc3857677b7320b9b8039f99f070ee0d20a5ca5a8e6bf"}, + {file = "ipython-8.14.0.tar.gz", hash = "sha256:1d197b907b6ba441b692c48cf2a3a2de280dc0ac91a3405b39349a50272ca0a1"}, ] [package.dependencies] @@ -2376,13 +2430,13 @@ text-helpers = ["chardet (>=5.1.0,<6.0.0)"] [[package]] name = "langchain-serve" -version = "0.0.40" +version = "0.0.41" description = "Langchain Serve - serve your langchain apps on Jina AI Cloud." category = "main" optional = true python-versions = "*" files = [ - {file = "langchain-serve-0.0.40.tar.gz", hash = "sha256:c60b173fcf0b682fbb70d34e8f485ce168e2229f55cb5c4ffbc26a5206af1c06"}, + {file = "langchain-serve-0.0.41.tar.gz", hash = "sha256:fcf0d3ac9e48b5b24825ae2e1d8a383795c5744b18ef61cb74a99020a9e5d46a"}, ] [package.dependencies] @@ -4679,14 +4733,14 @@ idna2008 = ["idna"] [[package]] name = "rich" -version = "13.3.5" +version = "13.4.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.5-py3-none-any.whl", hash = "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704"}, - {file = "rich-13.3.5.tar.gz", hash = "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c"}, + {file = "rich-13.4.1-py3-none-any.whl", hash = "sha256:d204aadb50b936bf6b1a695385429d192bc1fdaf3e8b907e8e26f4c4e4b5bf75"}, + {file = "rich-13.4.1.tar.gz", hash = "sha256:76f6b65ea7e5c5d924ba80e322231d7cb5b5981aa60bfc1e694f1bc097fe6fe1"}, ] [package.dependencies] @@ -5100,14 +5154,14 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] [[package]] name = "textual" -version = "0.26.0" +version = "0.27.0" description = "Modern Text User Interface framework" category = "main" optional = true python-versions = ">=3.7,<4.0" files = [ - {file = "textual-0.26.0-py3-none-any.whl", hash = "sha256:1efd04e9f61b3e95fd1c65436d3262f99e3f86cdeb524d13045bb551eb615c02"}, - {file = "textual-0.26.0.tar.gz", hash = "sha256:78094c83017d2836b726513abdf434cc034a0e68cc45e63b3b056c9b8b7fa673"}, + {file = "textual-0.27.0-py3-none-any.whl", hash = "sha256:dc45eaf7da330686c56d6f76f59d05fd216ce6aad90fa44ee269881efc622151"}, + {file = "textual-0.27.0.tar.gz", hash = "sha256:8bdcb09dc35a706ef939b1276ccfdec10eaaee6147b41cb7587cf33298a8dd33"}, ] [package.dependencies] @@ -6180,4 +6234,4 @@ deploy = ["langchain-serve"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "2bf357ad30f79c68751b34c991b4a73767ceb628657f4133228d4eb487d8a6fb" +content-hash = "4cac7dea0c1222711ba7eed82d5716d5e361d454edb6e0299b387fbb115d2c3d" diff --git a/pyproject.toml b/pyproject.toml index 78104f327..cde7ddca5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "0.0.79" +version = "0.0.80" description = "A Python package with a built-in web application" authors = ["Logspace "] maintainers = [ @@ -22,7 +22,7 @@ langflow = "langflow.__main__:main" [tool.poetry.dependencies] python = ">=3.9,<3.12" -fastapi = "^0.95.0" +fastapi = "^0.96.0" uvicorn = "^0.20.0" beautifulsoup4 = "^4.11.2" google-search-results = "^2.4.1" @@ -57,6 +57,8 @@ jina = "3.15.2" sentence-transformers = "^2.2.2" ctransformers = "^0.2.2" cohere = "^4.6.0" +faiss-cpu = "^1.7.4" +anthropic = "^0.2.9" [tool.poetry.group.dev.dependencies] diff --git a/src/backend/langflow/api/validate.py b/src/backend/langflow/api/validate.py index 53a7ee350..e90e554f0 100644 --- a/src/backend/langflow/api/validate.py +++ b/src/backend/langflow/api/validate.py @@ -9,7 +9,7 @@ from langflow.api.base import ( PromptValidationResponse, validate_prompt, ) -from langflow.graph.node.types import VectorStoreNode +from langflow.graph.vertex.types import VectorStoreVertex from langflow.interface.run import build_graph from langflow.utils.logger import logger from langflow.utils.validate import validate_code @@ -49,7 +49,7 @@ def post_validate_node(node_id: str, data: dict): node = graph.get_node(node_id) if node is None: raise ValueError(f"Node {node_id} not found") - if not isinstance(node, VectorStoreNode): + if not isinstance(node, VectorStoreVertex): node.build() return json.dumps({"valid": True, "params": str(node._built_object_repr())}) except Exception as e: diff --git a/src/backend/langflow/config.yaml b/src/backend/langflow/config.yaml index 4060d1f3e..963c29549 100644 --- a/src/backend/langflow/config.yaml +++ b/src/backend/langflow/config.yaml @@ -55,6 +55,8 @@ llms: - LlamaCpp - CTransformers - Cohere + - Anthropic + - ChatAnthropic memories: - ConversationBufferMemory - ConversationSummaryMemory @@ -79,7 +81,7 @@ tools: - Calculator - Serper Search - Tool - - PythonFunction + - PythonFunctionTool - JsonSpec - News API - TMDB API @@ -118,6 +120,7 @@ vectorstores: - Chroma - Qdrant - Weaviate + - FAISS wrappers: - RequestsWrapper # - ChatPromptTemplate diff --git a/src/backend/langflow/custom/customs.py b/src/backend/langflow/custom/customs.py index ee266b0ee..f7a82e4a3 100644 --- a/src/backend/langflow/custom/customs.py +++ b/src/backend/langflow/custom/customs.py @@ -4,7 +4,7 @@ from langflow.template import frontend_node CUSTOM_NODES = { "prompts": {"ZeroShotPrompt": frontend_node.prompts.ZeroShotPromptNode()}, "tools": { - "PythonFunction": frontend_node.tools.PythonFunctionNode(), + "PythonFunctionTool": frontend_node.tools.PythonFunctionToolNode(), "Tool": frontend_node.tools.ToolNode(), }, "agents": { diff --git a/src/backend/langflow/graph/__init__.py b/src/backend/langflow/graph/__init__.py index 44859da02..a68e844ee 100644 --- a/src/backend/langflow/graph/__init__.py +++ b/src/backend/langflow/graph/__init__.py @@ -1,35 +1,35 @@ from langflow.graph.edge.base import Edge from langflow.graph.graph.base import Graph -from langflow.graph.node.base import Node -from langflow.graph.node.types import ( - AgentNode, - ChainNode, - DocumentLoaderNode, - EmbeddingNode, - LLMNode, - MemoryNode, - PromptNode, - TextSplitterNode, - ToolNode, - ToolkitNode, - VectorStoreNode, - WrapperNode, +from langflow.graph.vertex.base import Vertex +from langflow.graph.vertex.types import ( + AgentVertex, + ChainVertex, + DocumentLoaderVertex, + EmbeddingVertex, + LLMVertex, + MemoryVertex, + PromptVertex, + TextSplitterVertex, + ToolVertex, + ToolkitVertex, + VectorStoreVertex, + WrapperVertex, ) __all__ = [ "Graph", - "Node", + "Vertex", "Edge", - "AgentNode", - "ChainNode", - "DocumentLoaderNode", - "EmbeddingNode", - "LLMNode", - "MemoryNode", - "PromptNode", - "TextSplitterNode", - "ToolNode", - "ToolkitNode", - "VectorStoreNode", - "WrapperNode", + "AgentVertex", + "ChainVertex", + "DocumentLoaderVertex", + "EmbeddingVertex", + "LLMVertex", + "MemoryVertex", + "PromptVertex", + "TextSplitterVertex", + "ToolVertex", + "ToolkitVertex", + "VectorStoreVertex", + "WrapperVertex", ] diff --git a/src/backend/langflow/graph/edge/base.py b/src/backend/langflow/graph/edge/base.py index 2bf5a1ba4..08f084a5c 100644 --- a/src/backend/langflow/graph/edge/base.py +++ b/src/backend/langflow/graph/edge/base.py @@ -2,13 +2,13 @@ from langflow.utils.logger import logger from typing import TYPE_CHECKING if TYPE_CHECKING: - from langflow.graph.node.base import Node + from langflow.graph.vertex.base import Vertex class Edge: - def __init__(self, source: "Node", target: "Node"): - self.source: "Node" = source - self.target: "Node" = target + def __init__(self, source: "Vertex", target: "Vertex"): + self.source: "Vertex" = source + self.target: "Vertex" = target self.validate_edge() def validate_edge(self) -> None: @@ -41,7 +41,7 @@ class Edge: logger.debug(self.target_reqs) if no_matched_type: raise ValueError( - f"Edge between {self.source.node_type} and {self.target.node_type} " + f"Edge between {self.source.vertex_type} and {self.target.vertex_type} " f"has no matched type" ) diff --git a/src/backend/langflow/graph/graph/base.py b/src/backend/langflow/graph/graph/base.py index 3ba67837f..020f539ec 100644 --- a/src/backend/langflow/graph/graph/base.py +++ b/src/backend/langflow/graph/graph/base.py @@ -1,12 +1,12 @@ from typing import Dict, List, Type, Union from langflow.graph.edge.base import Edge -from langflow.graph.graph.constants import NODE_TYPE_MAP -from langflow.graph.node.base import Node -from langflow.graph.node.types import ( - FileToolNode, - LLMNode, - ToolkitNode, +from langflow.graph.graph.constants import VERTEX_TYPE_MAP +from langflow.graph.vertex.base import Vertex +from langflow.graph.vertex.types import ( + FileToolVertex, + LLMVertex, + ToolkitVertex, ) from langflow.interface.tools.constants import FILE_TOOLS from langflow.utils import payload @@ -26,7 +26,7 @@ class Graph: def _build_graph(self) -> None: """Builds the graph from the nodes and edges.""" - self.nodes = self._build_nodes() + self.nodes = self._build_vertices() self.edges = self._build_edges() for edge in self.edges: edge.source.add_edge(edge) @@ -43,12 +43,12 @@ class Graph: llm_node = None for node in self.nodes: node._build_params() - if isinstance(node, LLMNode): + if isinstance(node, LLMVertex): llm_node = node if llm_node: for node in self.nodes: - if isinstance(node, ToolkitNode): + if isinstance(node, ToolkitVertex): node.params["llm"] = llm_node def _remove_invalid_nodes(self) -> None: @@ -60,23 +60,23 @@ class Graph: or (len(self.nodes) == 1 and len(self.edges) == 0) ] - def _validate_node(self, node: Node) -> bool: + def _validate_node(self, node: Vertex) -> bool: """Validates a node.""" # All nodes that do not have edges are invalid return len(node.edges) > 0 - def get_node(self, node_id: str) -> Union[None, Node]: + def get_node(self, node_id: str) -> Union[None, Vertex]: """Returns a node by id.""" return next((node for node in self.nodes if node.id == node_id), None) - def get_nodes_with_target(self, node: Node) -> List[Node]: + def get_nodes_with_target(self, node: Vertex) -> List[Vertex]: """Returns the nodes connected to a node.""" - connected_nodes: List[Node] = [ + connected_nodes: List[Vertex] = [ edge.source for edge in self.edges if edge.target == node ] return connected_nodes - def build(self) -> List[Node]: + def build(self) -> List[Vertex]: """Builds the graph.""" # Get root node root_node = payload.get_root_node(self) @@ -84,9 +84,9 @@ class Graph: raise ValueError("No root node found") return root_node.build() - def get_node_neighbors(self, node: Node) -> Dict[Node, int]: + def get_node_neighbors(self, node: Vertex) -> Dict[Vertex, int]: """Returns the neighbors of a node.""" - neighbors: Dict[Node, int] = {} + neighbors: Dict[Vertex, int] = {} for edge in self.edges: if edge.source == node: neighbor = edge.target @@ -117,28 +117,30 @@ class Graph: edges.append(Edge(source, target)) return edges - def _get_node_class(self, node_type: str, node_lc_type: str) -> Type[Node]: + def _get_vertex_class(self, node_type: str, node_lc_type: str) -> Type[Vertex]: """Returns the node class based on the node type.""" if node_type in FILE_TOOLS: - return FileToolNode - if node_type in NODE_TYPE_MAP: - return NODE_TYPE_MAP[node_type] - return NODE_TYPE_MAP[node_lc_type] if node_lc_type in NODE_TYPE_MAP else Node + return FileToolVertex + if node_type in VERTEX_TYPE_MAP: + return VERTEX_TYPE_MAP[node_type] + return ( + VERTEX_TYPE_MAP[node_lc_type] if node_lc_type in VERTEX_TYPE_MAP else Vertex + ) - def _build_nodes(self) -> List[Node]: - """Builds the nodes of the graph.""" - nodes: List[Node] = [] + def _build_vertices(self) -> List[Vertex]: + """Builds the vertices of the graph.""" + nodes: List[Vertex] = [] for node in self._nodes: node_data = node["data"] node_type: str = node_data["type"] # type: ignore node_lc_type: str = node_data["node"]["template"]["_type"] # type: ignore - NodeClass = self._get_node_class(node_type, node_lc_type) - nodes.append(NodeClass(node)) + VertexClass = self._get_vertex_class(node_type, node_lc_type) + nodes.append(VertexClass(node)) return nodes - def get_children_by_node_type(self, node: Node, node_type: str) -> List[Node]: + def get_children_by_node_type(self, node: Vertex, node_type: str) -> List[Vertex]: """Returns the children of a node based on the node type.""" children = [] node_types = [node.data["type"]] diff --git a/src/backend/langflow/graph/graph/constants.py b/src/backend/langflow/graph/graph/constants.py index f5bc9b8e3..ff1317d39 100644 --- a/src/backend/langflow/graph/graph/constants.py +++ b/src/backend/langflow/graph/graph/constants.py @@ -1,17 +1,17 @@ -from langflow.graph.node.base import Node -from langflow.graph.node.types import ( - AgentNode, - ChainNode, - DocumentLoaderNode, - EmbeddingNode, - LLMNode, - MemoryNode, - PromptNode, - TextSplitterNode, - ToolNode, - ToolkitNode, - VectorStoreNode, - WrapperNode, +from langflow.graph.vertex.base import Vertex +from langflow.graph.vertex.types import ( + AgentVertex, + ChainVertex, + DocumentLoaderVertex, + EmbeddingVertex, + LLMVertex, + MemoryVertex, + PromptVertex, + TextSplitterVertex, + ToolVertex, + ToolkitVertex, + VectorStoreVertex, + WrapperVertex, ) from langflow.interface.agents.base import agent_creator from langflow.interface.chains.base import chain_creator @@ -33,17 +33,17 @@ from typing import Dict, Type DIRECT_TYPES = ["str", "bool", "code", "int", "float", "Any", "prompt"] -NODE_TYPE_MAP: Dict[str, Type[Node]] = { - **{t: PromptNode for t in prompt_creator.to_list()}, - **{t: AgentNode for t in agent_creator.to_list()}, - **{t: ChainNode for t in chain_creator.to_list()}, - **{t: ToolNode for t in tool_creator.to_list()}, - **{t: ToolkitNode for t in toolkits_creator.to_list()}, - **{t: WrapperNode for t in wrapper_creator.to_list()}, - **{t: LLMNode for t in llm_creator.to_list()}, - **{t: MemoryNode for t in memory_creator.to_list()}, - **{t: EmbeddingNode for t in embedding_creator.to_list()}, - **{t: VectorStoreNode for t in vectorstore_creator.to_list()}, - **{t: DocumentLoaderNode for t in documentloader_creator.to_list()}, - **{t: TextSplitterNode for t in textsplitter_creator.to_list()}, +VERTEX_TYPE_MAP: Dict[str, Type[Vertex]] = { + **{t: PromptVertex for t in prompt_creator.to_list()}, + **{t: AgentVertex for t in agent_creator.to_list()}, + **{t: ChainVertex for t in chain_creator.to_list()}, + **{t: ToolVertex for t in tool_creator.to_list()}, + **{t: ToolkitVertex for t in toolkits_creator.to_list()}, + **{t: WrapperVertex for t in wrapper_creator.to_list()}, + **{t: LLMVertex for t in llm_creator.to_list()}, + **{t: MemoryVertex for t in memory_creator.to_list()}, + **{t: EmbeddingVertex for t in embedding_creator.to_list()}, + **{t: VectorStoreVertex for t in vectorstore_creator.to_list()}, + **{t: DocumentLoaderVertex for t in documentloader_creator.to_list()}, + **{t: TextSplitterVertex for t in textsplitter_creator.to_list()}, } diff --git a/src/backend/langflow/graph/node/__init__.py b/src/backend/langflow/graph/vertex/__init__.py similarity index 100% rename from src/backend/langflow/graph/node/__init__.py rename to src/backend/langflow/graph/vertex/__init__.py diff --git a/src/backend/langflow/graph/node/base.py b/src/backend/langflow/graph/vertex/base.py similarity index 92% rename from src/backend/langflow/graph/node/base.py rename to src/backend/langflow/graph/vertex/base.py index 5076deb9c..4593e0a40 100644 --- a/src/backend/langflow/graph/node/base.py +++ b/src/backend/langflow/graph/vertex/base.py @@ -1,5 +1,5 @@ from langflow.cache import base as cache_utils -from langflow.graph.node.constants import DIRECT_TYPES +from langflow.graph.vertex.constants import DIRECT_TYPES from langflow.interface import loading from langflow.interface.listing import ALL_TYPES_DICT from langflow.utils.logger import logger @@ -17,7 +17,7 @@ if TYPE_CHECKING: from langflow.graph.edge.base import Edge -class Node: +class Vertex: def __init__(self, data: Dict, base_type: Optional[str] = None) -> None: self.id: str = data["id"] self._data = data @@ -48,12 +48,12 @@ class Node: ] template_dict = self.data["node"]["template"] - self.node_type = ( + self.vertex_type = ( self.data["type"] if "Tool" not in self.output else template_dict["_type"] ) if self.base_type is None: for base_type, value in ALL_TYPES_DICT.items(): - if self.node_type in value: + if self.vertex_type in value: self.base_type = base_type break @@ -113,7 +113,7 @@ class Node: if value["required"] and not edges: # If a required parameter is not found, raise an error raise ValueError( - f"Required input {key} for module {self.node_type} not found" + f"Required input {key} for module {self.vertex_type} not found" ) elif value["list"]: # If this is a list parameter, append all sources to a list @@ -128,7 +128,7 @@ class Node: # so we need to check if value has value new_value = value.get("value") if new_value is None: - warnings.warn(f"Value for {key} in {self.node_type} is None. ") + warnings.warn(f"Value for {key} in {self.vertex_type} is None. ") if value.get("type") == "int": with contextlib.suppress(TypeError, ValueError): new_value = int(new_value) # type: ignore @@ -148,12 +148,12 @@ class Node: # and continue # Another aspect is that the node_type is the class that we need to import # and instantiate with these built params - logger.debug(f"Building {self.node_type}") + logger.debug(f"Building {self.vertex_type}") # Build each node in the params dict for key, value in self.params.copy().items(): # Check if Node or list of Nodes and not self # to avoid recursion - if isinstance(value, Node): + if isinstance(value, Vertex): if value == self: del self.params[key] continue @@ -177,7 +177,7 @@ class Node: self.params[key] = result elif isinstance(value, list) and all( - isinstance(node, Node) for node in value + isinstance(node, Vertex) for node in value ): self.params[key] = [] for node in value: @@ -193,17 +193,17 @@ class Node: try: self._built_object = loading.instantiate_class( - node_type=self.node_type, + node_type=self.vertex_type, base_type=self.base_type, params=self.params, ) except Exception as exc: raise ValueError( - f"Error building node {self.node_type}: {str(exc)}" + f"Error building node {self.vertex_type}: {str(exc)}" ) from exc if self._built_object is None: - raise ValueError(f"Node type {self.node_type} not found") + raise ValueError(f"Node type {self.vertex_type} not found") self._built = True @@ -220,7 +220,7 @@ class Node: return f"Node(id={self.id}, data={self.data})" def __eq__(self, __o: object) -> bool: - return self.id == __o.id if isinstance(__o, Node) else False + return self.id == __o.id if isinstance(__o, Vertex) else False def __hash__(self) -> int: return id(self) diff --git a/src/backend/langflow/graph/node/constants.py b/src/backend/langflow/graph/vertex/constants.py similarity index 100% rename from src/backend/langflow/graph/node/constants.py rename to src/backend/langflow/graph/vertex/constants.py diff --git a/src/backend/langflow/graph/node/types.py b/src/backend/langflow/graph/vertex/types.py similarity index 77% rename from src/backend/langflow/graph/node/types.py rename to src/backend/langflow/graph/vertex/types.py index 9b25fd6ee..7d61f2393 100644 --- a/src/backend/langflow/graph/node/types.py +++ b/src/backend/langflow/graph/vertex/types.py @@ -1,22 +1,22 @@ from typing import Any, Dict, List, Optional, Union -from langflow.graph.node.base import Node +from langflow.graph.vertex.base import Vertex from langflow.graph.utils import extract_input_variables_from_prompt -class AgentNode(Node): +class AgentVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="agents") - self.tools: List[ToolNode] = [] - self.chains: List[ChainNode] = [] + self.tools: List[ToolVertex] = [] + self.chains: List[ChainVertex] = [] def _set_tools_and_chains(self) -> None: for edge in self.edges: source_node = edge.source - if isinstance(source_node, ToolNode): + if isinstance(source_node, ToolVertex): self.tools.append(source_node) - elif isinstance(source_node, ChainNode): + elif isinstance(source_node, ChainVertex): self.chains.append(source_node) def build(self, force: bool = False) -> Any: @@ -33,24 +33,28 @@ class AgentNode(Node): self._build() #! Cannot deepcopy VectorStore, VectorStoreRouter, or SQL agents - if self.node_type in ["VectorStoreAgent", "VectorStoreRouterAgent", "SQLAgent"]: + if self.vertex_type in [ + "VectorStoreAgent", + "VectorStoreRouterAgent", + "SQLAgent", + ]: return self._built_object return self._built_object -class ToolNode(Node): +class ToolVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="tools") -class PromptNode(Node): +class PromptVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="prompts") def build( self, force: bool = False, - tools: Optional[Union[List[Node], List[ToolNode]]] = None, + tools: Optional[Union[List[Vertex], List[ToolVertex]]] = None, ) -> Any: if not self._built or force: if ( @@ -59,7 +63,7 @@ class PromptNode(Node): ): self.params["input_variables"] = [] # Check if it is a ZeroShotPrompt and needs a tool - if "ShotPrompt" in self.node_type: + if "ShotPrompt" in self.vertex_type: tools = ( [tool_node.build() for tool_node in tools] if tools is not None @@ -83,31 +87,31 @@ class PromptNode(Node): return self._built_object -class ChainNode(Node): +class ChainVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="chains") def build( self, force: bool = False, - tools: Optional[Union[List[Node], List[ToolNode]]] = None, + tools: Optional[Union[List[Vertex], List[ToolVertex]]] = None, ) -> Any: if not self._built or force: # Check if the chain requires a PromptNode for key, value in self.params.items(): - if isinstance(value, PromptNode): + if isinstance(value, PromptVertex): # Build the PromptNode, passing the tools if available self.params[key] = value.build(tools=tools, force=force) self._build() #! Cannot deepcopy SQLDatabaseChain - if self.node_type in ["SQLDatabaseChain"]: + if self.vertex_type in ["SQLDatabaseChain"]: return self._built_object return self._built_object -class LLMNode(Node): +class LLMVertex(Vertex): built_node_type = None class_built_object = None @@ -117,28 +121,28 @@ class LLMNode(Node): def build(self, force: bool = False) -> Any: # LLM is different because some models might take up too much memory # or time to load. So we only load them when we need them.ß - if self.node_type == self.built_node_type: + if self.vertex_type == self.built_node_type: return self.class_built_object if not self._built or force: self._build() - self.built_node_type = self.node_type + self.built_node_type = self.vertex_type self.class_built_object = self._built_object # Avoid deepcopying the LLM # that are loaded from a file return self._built_object -class ToolkitNode(Node): +class ToolkitVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="toolkits") -class FileToolNode(ToolNode): +class FileToolVertex(ToolVertex): def __init__(self, data: Dict): super().__init__(data) -class WrapperNode(Node): +class WrapperVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="wrappers") @@ -150,7 +154,7 @@ class WrapperNode(Node): return self._built_object -class DocumentLoaderNode(Node): +class DocumentLoaderVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="documentloaders") @@ -158,17 +162,17 @@ class DocumentLoaderNode(Node): # This built_object is a list of documents. Maybe we should # show how many documents are in the list? if self._built_object: - return f"""{self.node_type}({len(self._built_object)} documents) + return f"""{self.vertex_type}({len(self._built_object)} documents) Documents: {self._built_object[:3]}...""" - return f"{self.node_type}()" + return f"{self.vertex_type}()" -class EmbeddingNode(Node): +class EmbeddingVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="embeddings") -class VectorStoreNode(Node): +class VectorStoreVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="vectorstores") @@ -176,12 +180,12 @@ class VectorStoreNode(Node): return "Vector stores can take time to build. It will build on the first query." -class MemoryNode(Node): +class MemoryVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="memory") -class TextSplitterNode(Node): +class TextSplitterVertex(Vertex): def __init__(self, data: Dict): super().__init__(data, base_type="textsplitters") @@ -189,5 +193,6 @@ class TextSplitterNode(Node): # This built_object is a list of documents. Maybe we should # show how many documents are in the list? if self._built_object: - return f"""{self.node_type}({len(self._built_object)} documents)\nDocuments: {self._built_object[:3]}...""" - return f"{self.node_type}()" + return f"""{self.vertex_type}({len(self._built_object)} documents) + \nDocuments: {self._built_object[:3]}...""" + return f"{self.vertex_type}()" diff --git a/src/backend/langflow/interface/custom_lists.py b/src/backend/langflow/interface/custom_lists.py index 0fea838b6..a944363ae 100644 --- a/src/backend/langflow/interface/custom_lists.py +++ b/src/backend/langflow/interface/custom_lists.py @@ -11,12 +11,14 @@ from langchain import ( text_splitter, ) from langchain.agents import agent_toolkits +from langchain.chat_models import ChatAnthropic from langchain.chat_models import ChatOpenAI from langflow.interface.importing.utils import import_class ## LLMs llm_type_to_cls_dict = llms.type_to_cls_dict +llm_type_to_cls_dict["anthropic-chat"] = ChatAnthropic # type: ignore llm_type_to_cls_dict["openai-chat"] = ChatOpenAI # type: ignore ## Chains diff --git a/src/backend/langflow/interface/importing/utils.py b/src/backend/langflow/interface/importing/utils.py index d08e52999..f65376d48 100644 --- a/src/backend/langflow/interface/importing/utils.py +++ b/src/backend/langflow/interface/importing/utils.py @@ -9,6 +9,7 @@ from langchain.base_language import BaseLanguageModel from langchain.chains.base import Chain from langchain.chat_models.base import BaseChatModel from langchain.tools import BaseTool +from langflow.utils import validate def import_module(module_path: str) -> Any: @@ -147,3 +148,10 @@ def import_utility(utility: str) -> Any: if utility == "SQLDatabase": return import_class(f"langchain.sql_database.{utility}") return import_class(f"langchain.utilities.{utility}") + + +def get_function(code): + """Get the function""" + function_name = validate.extract_function_name(code) + + return validate.create_function(code, function_name) diff --git a/src/backend/langflow/interface/loading.py b/src/backend/langflow/interface/loading.py index a3799be16..62d5561b3 100644 --- a/src/backend/langflow/interface/loading.py +++ b/src/backend/langflow/interface/loading.py @@ -21,12 +21,12 @@ from langchain.llms.loading import load_llm_from_config from pydantic import ValidationError from langflow.interface.agents.custom import CUSTOM_AGENTS -from langflow.interface.importing.utils import import_by_type +from langflow.interface.importing.utils import get_function, import_by_type from langflow.interface.run import fix_memory_inputs from langflow.interface.toolkits.base import toolkits_creator from langflow.interface.types import get_type_list from langflow.interface.utils import load_file_into_dict -from langflow.utils import util, validate +from langflow.utils import util def instantiate_class(node_type: str, base_type: str, params: Dict) -> Any: @@ -100,11 +100,9 @@ def instantiate_tool(node_type, class_object, params): if node_type == "JsonSpec": params["dict_"] = load_file_into_dict(params.pop("path")) return class_object(**params) - elif node_type == "PythonFunction": - function_string = params["code"] - if isinstance(function_string, str): - return validate.eval_function(function_string) - raise ValueError("Function should be a string") + elif node_type == "PythonFunctionTool": + params["func"] = get_function(params.get("code")) + return class_object(**params) elif node_type.lower() == "tool": return class_object(**params) return class_object(**params) diff --git a/src/backend/langflow/interface/tools/base.py b/src/backend/langflow/interface/tools/base.py index a8e7045c0..d6b114e4c 100644 --- a/src/backend/langflow/interface/tools/base.py +++ b/src/backend/langflow/interface/tools/base.py @@ -71,7 +71,8 @@ class ToolCreator(LangChainTypeCreator): for tool, tool_fcn in ALL_TOOLS_NAMES.items(): tool_params = get_tool_params(tool_fcn) - tool_name = tool_params.get("name", tool) + + tool_name = tool_params.get("name") or tool if tool_name in settings.tools or settings.dev: if tool_name == "JsonSpec": diff --git a/src/backend/langflow/interface/tools/constants.py b/src/backend/langflow/interface/tools/constants.py index f939d55ad..31c75ec08 100644 --- a/src/backend/langflow/interface/tools/constants.py +++ b/src/backend/langflow/interface/tools/constants.py @@ -9,10 +9,10 @@ from langchain.agents.load_tools import ( from langchain.tools.json.tool import JsonSpec from langflow.interface.importing.utils import import_class -from langflow.interface.tools.custom import PythonFunction +from langflow.interface.tools.custom import PythonFunctionTool FILE_TOOLS = {"JsonSpec": JsonSpec} -CUSTOM_TOOLS = {"Tool": Tool, "PythonFunction": PythonFunction} +CUSTOM_TOOLS = {"Tool": Tool, "PythonFunctionTool": PythonFunctionTool} OTHER_TOOLS = {tool: import_class(f"langchain.tools.{tool}") for tool in tools.__all__} diff --git a/src/backend/langflow/interface/tools/custom.py b/src/backend/langflow/interface/tools/custom.py index 4c641f388..b2d43565d 100644 --- a/src/backend/langflow/interface/tools/custom.py +++ b/src/backend/langflow/interface/tools/custom.py @@ -1,13 +1,14 @@ -from typing import Callable, Optional +from typing import Optional +from langflow.interface.importing.utils import get_function from pydantic import BaseModel, validator from langflow.utils import validate +from langchain.agents.tools import Tool class Function(BaseModel): code: str - function: Optional[Callable] = None imports: Optional[str] = None # Eval code and store the function @@ -24,14 +25,17 @@ class Function(BaseModel): return v - def get_function(self): - """Get the function""" - function_name = validate.extract_function_name(self.code) - return validate.create_function(self.code, function_name) - - -class PythonFunction(Function): +class PythonFunctionTool(Function, Tool): """Python function""" + name: str = "Custom Tool" + description: str code: str + + def ___init__(self, name: str, description: str, code: str): + self.name = name + self.description = description + self.code = code + self.func = get_function(self.code) + super().__init__(name=name, description=description, func=self.func) diff --git a/src/backend/langflow/template/frontend_node/base.py b/src/backend/langflow/template/frontend_node/base.py index a64195813..a97c7b8b0 100644 --- a/src/backend/langflow/template/frontend_node/base.py +++ b/src/backend/langflow/template/frontend_node/base.py @@ -125,6 +125,9 @@ class FrontendNode(BaseModel): elif name == "ChatOpenAI" and key == "model_name": field.options = constants.CHAT_OPENAI_MODELS field.is_list = True + elif (name == "Anthropic" or name == "ChatAnthropic") and key == "model_name": + field.options = constants.ANTHROPIC_MODELS + field.is_list = True if "api_key" in key and "OpenAI" in str(name): field.display_name = "OpenAI API Key" field.required = False diff --git a/src/backend/langflow/template/frontend_node/tools.py b/src/backend/langflow/template/frontend_node/tools.py index 2819be4d9..4e97fec8c 100644 --- a/src/backend/langflow/template/frontend_node/tools.py +++ b/src/backend/langflow/template/frontend_node/tools.py @@ -59,11 +59,33 @@ class ToolNode(FrontendNode): return super().to_dict() -class PythonFunctionNode(FrontendNode): - name: str = "PythonFunction" +class PythonFunctionToolNode(FrontendNode): + name: str = "PythonFunctionTool" template: Template = Template( - type_name="python_function", + type_name="PythonFunctionTool", fields=[ + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=False, + value="", + name="name", + advanced=False, + ), + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=False, + value="", + name="description", + advanced=False, + ), TemplateField( field_type="code", required=True, @@ -73,11 +95,11 @@ class PythonFunctionNode(FrontendNode): value=DEFAULT_PYTHON_FUNCTION, name="code", advanced=False, - ) + ), ], ) description: str = "Python function to be executed." - base_classes: list[str] = ["function"] + base_classes: list[str] = ["Tool"] def to_dict(self): return super().to_dict() diff --git a/src/backend/langflow/utils/constants.py b/src/backend/langflow/utils/constants.py index 2d101ab98..1b6bbdcc3 100644 --- a/src/backend/langflow/utils/constants.py +++ b/src/backend/langflow/utils/constants.py @@ -7,6 +7,20 @@ OPENAI_MODELS = [ ] CHAT_OPENAI_MODELS = ["gpt-3.5-turbo", "gpt-4", "gpt-4-32k"] +ANTHROPIC_MODELS = [ + "claude-v1", # largest model, ideal for a wide range of more complex tasks. + "claude-v1-100k", # An enhanced version of claude-v1 with a 100,000 token (roughly 75,000 word) context window. + "claude-instant-v1", # A smaller model with far lower latency, sampling at roughly 40 words/sec! + "claude-instant-v1-100k", # Like claude-instant-v1 with a 100,000 token context window but retains its performance. + # Specific sub-versions of the above models: + "claude-v1.3", # Vs claude-v1.2: better instruction-following, code, and non-English dialogue and writing. + "claude-v1.3-100k", # An enhanced version of claude-v1.3 with a 100,000 token (roughly 75,000 word) context window. + "claude-v1.2", # Vs claude-v1.1: small adv in general helpfulness, instruction following, coding, and other tasks. + "claude-v1.0", # An earlier version of claude-v1. + "claude-instant-v1.1", # Latest version of claude-instant-v1. Better than claude-instant-v1.0 at most tasks. + "claude-instant-v1.1-100k", # Version of claude-instant-v1.1 with a 100K token context window. + "claude-instant-v1.0", # An earlier version of claude-instant-v1. +] DEFAULT_PYTHON_FUNCTION = """ def python_function(text: str) -> str: diff --git a/src/backend/langflow/utils/util.py b/src/backend/langflow/utils/util.py index 293d31154..f4e4927d8 100644 --- a/src/backend/langflow/utils/util.py +++ b/src/backend/langflow/utils/util.py @@ -302,7 +302,9 @@ def format_dict(d, name: Optional[str] = None): elif name == "ChatOpenAI" and key == "model_name": value["options"] = constants.CHAT_OPENAI_MODELS value["list"] = True - + elif (name == "Anthropic" or name == "ChatAnthropic") and key == "model_name": + value["options"] = constants.ANTHROPIC_MODELS + value["list"] = True return d diff --git a/src/frontend/src/icons/Anthropic/anthropic.svg b/src/frontend/src/icons/Anthropic/anthropic.svg new file mode 100644 index 000000000..67ae02ea5 --- /dev/null +++ b/src/frontend/src/icons/Anthropic/anthropic.svg @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/src/frontend/src/icons/Anthropic/anthropic_box.svg b/src/frontend/src/icons/Anthropic/anthropic_box.svg new file mode 100644 index 000000000..fa9923ed7 --- /dev/null +++ b/src/frontend/src/icons/Anthropic/anthropic_box.svg @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/frontend/src/icons/Anthropic/index.tsx b/src/frontend/src/icons/Anthropic/index.tsx new file mode 100644 index 000000000..4cdf8f910 --- /dev/null +++ b/src/frontend/src/icons/Anthropic/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import { ReactComponent as AnthropicSVG } from "./anthropic_box.svg"; + +export const AnthropicIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{}> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/pages/FlowPage/components/DisclosureComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/DisclosureComponent/index.tsx index 31bf78156..6878ad3c4 100644 --- a/src/frontend/src/pages/FlowPage/components/DisclosureComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/DisclosureComponent/index.tsx @@ -5,6 +5,7 @@ import { DisclosureComponentType } from "../../../../types/components"; export default function DisclosureComponent({ button: { title, Icon, buttons = [] }, children, + openDisc, }: DisclosureComponentType) { return ( @@ -27,14 +28,14 @@ export default function DisclosureComponent({
- + {children} diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index e8dbfbb6b..deeed6c70 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -15,6 +15,7 @@ import { MagnifyingGlassIcon } from "@heroicons/react/24/outline"; export default function ExtraSidebar() { const { data } = useContext(typesContext); const [dataFilter, setFilterData] = useState(data); + const [search, setSearch] = useState(""); function onDragStart( event: React.DragEvent, @@ -58,6 +59,7 @@ export default function ExtraSidebar() { className="dark:text-white focus:outline-none block w-full rounded-md py-1.5 ps-3 pr-9 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 sm:text-sm sm:leading-6 dark:ring-0 dark:bg-[#2d3747] dark:focus:outline-none" onChange={(e) => { handleSearchInput(e.target.value); + setSearch(e.target.value); }} />
@@ -71,6 +73,7 @@ export default function ExtraSidebar() { .map((d: keyof APIObjectType, i) => Object.keys(dataFilter[d]).length > 0 ? ( >; diff --git a/src/frontend/src/utils.ts b/src/frontend/src/utils.ts index 998873238..0e0459c69 100644 --- a/src/frontend/src/utils.ts +++ b/src/frontend/src/utils.ts @@ -21,6 +21,7 @@ import { FlowType, NodeType } from "./types/flow"; import { APITemplateType, TemplateVariableType } from "./types/api"; import _ from "lodash"; import { ChromaIcon } from "./icons/ChromaIcon"; +import { AnthropicIcon } from "./icons/Anthropic"; import { AirbyteIcon } from "./icons/Airbyte"; import { AzIcon } from "./icons/AzLogo"; import { BingIcon } from "./icons/Bing"; @@ -155,6 +156,8 @@ export const nodeIcons: { AirbyteJSONLoader: AirbyteIcon, // SerpAPIWrapper: SerperIcon, // AZLyricsLoader: AzIcon, + Anthropic: AnthropicIcon, + ChatAnthropic: AnthropicIcon, BingSearchAPIWrapper: BingIcon, BingSearchRun: BingIcon, Cohere: CohereIcon, diff --git a/tests/data/complex_example.json b/tests/data/complex_example.json index 8d46a97d6..89a3b9324 100644 --- a/tests/data/complex_example.json +++ b/tests/data/complex_example.json @@ -197,7 +197,7 @@ "y": 136.29836646158452 }, "data": { - "type": "PythonFunction", + "type": "PythonFunctionTool", "node": { "template": { "code": { @@ -210,6 +210,26 @@ "type": "str", "list": false }, + "description": { + "required": true, + "placeholder": "", + "show": true, + "multiline": true, + "value": "My description", + "name": "description", + "type": "str", + "list": false + }, + "name": { + "required": true, + "placeholder": "", + "show": true, + "multiline": true, + "value": "My Tool", + "name": "name", + "type": "str", + "list": false + }, "_type": "python_function" }, "description": "Python function to be executed.", diff --git a/tests/test_custom_types.py b/tests/test_custom_types.py index 399450e2e..7503426ab 100644 --- a/tests/test_custom_types.py +++ b/tests/test_custom_types.py @@ -1,16 +1,23 @@ # Test this: +from langflow.interface.importing.utils import get_function import pytest -from langflow.interface.tools.custom import PythonFunction +from langflow.interface.tools.custom import PythonFunctionTool from langflow.utils import constants def test_python_function(): """Test Python function""" - func = PythonFunction(code=constants.DEFAULT_PYTHON_FUNCTION) - assert func.get_function()("text") == "text" + code = constants.DEFAULT_PYTHON_FUNCTION + func = get_function(code) + func = PythonFunctionTool(name="Test", description="Testing", code=code, func=func) + assert func("text") == "text" # the tool decorator should raise an error if # the function is not str -> str # This raises ValidationError with pytest.raises(SyntaxError): - func = PythonFunction(code=pytest.CODE_WITH_SYNTAX_ERROR) + code = pytest.CODE_WITH_SYNTAX_ERROR + func = get_function(code) + func = PythonFunctionTool( + name="Test", description="Testing", code=code, func=func + ) diff --git a/tests/test_graph.py b/tests/test_graph.py index cdbe0ba93..4d53d61f1 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -1,20 +1,20 @@ from typing import Type, Union from langflow.graph.edge.base import Edge -from langflow.graph.node.base import Node +from langflow.graph.vertex.base import Vertex import pytest from langchain.chains.base import Chain from langchain.llms.fake import FakeListLLM from langflow.graph import Graph -from langflow.graph.node.types import ( - AgentNode, - ChainNode, - FileToolNode, - LLMNode, - PromptNode, - ToolkitNode, - ToolNode, - WrapperNode, +from langflow.graph.vertex.types import ( + AgentVertex, + ChainVertex, + FileToolVertex, + LLMVertex, + PromptVertex, + ToolkitVertex, + ToolVertex, + WrapperVertex, ) from langflow.interface.run import get_result_and_thought from langflow.utils.payload import get_root_node @@ -25,7 +25,7 @@ from langflow.utils.payload import get_root_node # BASIC_EXAMPLE_PATH, COMPLEX_EXAMPLE_PATH, OPENAPI_EXAMPLE_PATH -def get_node_by_type(graph, node_type: Type[Node]) -> Union[Node, None]: +def get_node_by_type(graph, node_type: Type[Vertex]) -> Union[Vertex, None]: """Get a node by type""" return next((node for node in graph.nodes if isinstance(node, node_type)), None) @@ -35,7 +35,7 @@ def test_graph_structure(basic_graph): assert len(basic_graph.nodes) > 0 assert len(basic_graph.edges) > 0 for node in basic_graph.nodes: - assert isinstance(node, Node) + assert isinstance(node, Vertex) for edge in basic_graph.edges: assert isinstance(edge, Edge) assert edge.source in basic_graph.nodes @@ -158,14 +158,16 @@ def test_get_node_neighbors_complex(complex_graph): tool_neighbors = complex_graph.get_nodes_with_target(tool) assert tool_neighbors is not None # Check if there is a PythonFunction in the tool's neighbors - assert any("PythonFunction" in neighbor.data["type"] for neighbor in tool_neighbors) + assert any( + "PythonFunctionTool" in neighbor.data["type"] for neighbor in tool_neighbors + ) def test_get_node(basic_graph): """Test getting a single node""" node_id = basic_graph.nodes[0].id node = basic_graph.get_node(node_id) - assert isinstance(node, Node) + assert isinstance(node, Vertex) assert node.id == node_id @@ -174,7 +176,7 @@ def test_build_nodes(basic_graph): assert len(basic_graph.nodes) == len(basic_graph._nodes) for node in basic_graph.nodes: - assert isinstance(node, Node) + assert isinstance(node, Vertex) def test_build_edges(basic_graph): @@ -182,8 +184,8 @@ def test_build_edges(basic_graph): assert len(basic_graph.edges) == len(basic_graph._edges) for edge in basic_graph.edges: assert isinstance(edge, Edge) - assert isinstance(edge.source, Node) - assert isinstance(edge.target, Node) + assert isinstance(edge.source, Vertex) + assert isinstance(edge.target, Vertex) def test_get_root_node(basic_graph, complex_graph): @@ -191,13 +193,13 @@ def test_get_root_node(basic_graph, complex_graph): assert isinstance(basic_graph, Graph) root = get_root_node(basic_graph) assert root is not None - assert isinstance(root, Node) + assert isinstance(root, Vertex) assert root.data["type"] == "TimeTravelGuideChain" # For complex example, the root node is a ZeroShotAgent too assert isinstance(complex_graph, Graph) root = get_root_node(complex_graph) assert root is not None - assert isinstance(root, Node) + assert isinstance(root, Vertex) assert root.data["type"] == "ZeroShotAgent" @@ -257,14 +259,14 @@ def assert_agent_was_built(graph): def test_agent_node_build(complex_graph): - agent_node = get_node_by_type(complex_graph, AgentNode) + agent_node = get_node_by_type(complex_graph, AgentVertex) assert agent_node is not None built_object = agent_node.build() assert built_object is not None def test_tool_node_build(complex_graph): - tool_node = get_node_by_type(complex_graph, ToolNode) + tool_node = get_node_by_type(complex_graph, ToolVertex) assert tool_node is not None built_object = tool_node.build() assert built_object is not None @@ -272,7 +274,7 @@ def test_tool_node_build(complex_graph): def test_chain_node_build(complex_graph): - chain_node = get_node_by_type(complex_graph, ChainNode) + chain_node = get_node_by_type(complex_graph, ChainVertex) assert chain_node is not None built_object = chain_node.build() assert built_object is not None @@ -280,7 +282,7 @@ def test_chain_node_build(complex_graph): def test_prompt_node_build(complex_graph): - prompt_node = get_node_by_type(complex_graph, PromptNode) + prompt_node = get_node_by_type(complex_graph, PromptVertex) assert prompt_node is not None built_object = prompt_node.build() assert built_object is not None @@ -288,7 +290,7 @@ def test_prompt_node_build(complex_graph): def test_llm_node_build(basic_graph): - llm_node = get_node_by_type(basic_graph, LLMNode) + llm_node = get_node_by_type(basic_graph, LLMVertex) assert llm_node is not None built_object = llm_node.build() assert built_object is not None @@ -296,7 +298,7 @@ def test_llm_node_build(basic_graph): def test_toolkit_node_build(openapi_graph): - toolkit_node = get_node_by_type(openapi_graph, ToolkitNode) + toolkit_node = get_node_by_type(openapi_graph, ToolkitVertex) assert toolkit_node is not None built_object = toolkit_node.build() assert built_object is not None @@ -304,7 +306,7 @@ def test_toolkit_node_build(openapi_graph): def test_file_tool_node_build(openapi_graph): - file_tool_node = get_node_by_type(openapi_graph, FileToolNode) + file_tool_node = get_node_by_type(openapi_graph, FileToolVertex) assert file_tool_node is not None built_object = file_tool_node.build() assert built_object is not None @@ -312,7 +314,7 @@ def test_file_tool_node_build(openapi_graph): def test_wrapper_node_build(openapi_graph): - wrapper_node = get_node_by_type(openapi_graph, WrapperNode) + wrapper_node = get_node_by_type(openapi_graph, WrapperVertex) assert wrapper_node is not None built_object = wrapper_node.build() assert built_object is not None @@ -327,7 +329,7 @@ def test_get_result_and_thought(basic_graph): message = "Hello" # Find the node that is an LLMNode and change the # _built_object to a FakeListLLM - llm_node = get_node_by_type(basic_graph, LLMNode) + llm_node = get_node_by_type(basic_graph, LLMVertex) assert llm_node is not None llm_node._built_object = FakeListLLM(responses=responses) llm_node._built = True