diff --git a/Makefile b/Makefile index fcb592426..fdb09a13e 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,10 @@ all: help init: @echo 'Installing pre-commit hooks' git config core.hooksPath .githooks + @echo 'Installing backend dependencies' + make install_backend + @echo 'Installing frontend dependencies' + make install_frontend coverage: poetry run pytest --cov \ @@ -17,7 +21,7 @@ tests: format: poetry run black . - poetry run ruff --select I --fix . + poetry run ruff . --fix cd src/frontend && npm run format lint: diff --git a/poetry.lock b/poetry.lock index 91d7e2389..1104b786a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -5,7 +5,7 @@ name = "aiofiles" version = "23.1.0" description = "File support for asyncio." category = "main" -optional = true +optional = false python-versions = ">=3.7,<4.0" files = [ {file = "aiofiles-23.1.0-py3-none-any.whl", hash = "sha256:9312414ae06472eb6f1d163f555e466a23aed1c8f60c30cccf7121dba2e53eb2"}, @@ -141,7 +141,7 @@ name = "aiostream" version = "0.4.5" description = "Generator-based operators for asynchronous iteration" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "aiostream-0.4.5-py3-none-any.whl", hash = "sha256:25b7c2d9c83570d78c0ef5a20e949b7d0b8ea3b0b0a4f22c49d3f721105a6057"}, @@ -212,14 +212,14 @@ server = ["Deprecated (>=1.2.0,<1.3.0)", "PyYAML (>=5.4.1,<6.1.0)", "aiofiles (> [[package]] name = "asgiref" -version = "3.7.1" +version = "3.7.2" description = "ASGI specs, helper code, and adapters" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ - {file = "asgiref-3.7.1-py3-none-any.whl", hash = "sha256:33958cb2e4b3cd8b1b06ef295bd8605cde65b11df51d3beab39e2e149a610ab3"}, - {file = "asgiref-3.7.1.tar.gz", hash = "sha256:8de379fcc383bcfe4507e229fc31209ea23d4831c850f74063b2c11639474dd2"}, + {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, + {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, ] [package.dependencies] @@ -387,14 +387,14 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "cachetools" -version = "5.3.0" +version = "5.3.1" description = "Extensible memoizing collections and decorators" category = "main" optional = false -python-versions = "~=3.7" +python-versions = ">=3.7" files = [ - {file = "cachetools-5.3.0-py3-none-any.whl", hash = "sha256:429e1a1e845c008ea6c85aa35d4b98b65d6a9763eeef3e37e92728a12d1de9d4"}, - {file = "cachetools-5.3.0.tar.gz", hash = "sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14"}, + {file = "cachetools-5.3.1-py3-none-any.whl", hash = "sha256:95ef631eeaea14ba2e36f06437f36463aac3a096799e876ee55e5cdccb102590"}, + {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, ] [[package]] @@ -938,21 +938,21 @@ files = [ [[package]] name = "deprecated" -version = "1.2.13" +version = "1.2.14" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, - {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] [[package]] name = "dill" @@ -974,7 +974,7 @@ name = "docarray" version = "0.21.0" description = "The data structure for unstructured data" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "docarray-0.21.0.tar.gz", hash = "sha256:3c9f605123800c1b0cdf8c458be3fb19c05e9a81f723e51200ef531b02e689ee"}, @@ -1003,7 +1003,7 @@ name = "docker" version = "6.1.2" description = "A Python library for the Docker Engine API." category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "docker-6.1.2-py3-none-any.whl", hash = "sha256:134cd828f84543cbf8e594ff81ca90c38288df3c0a559794c12f2e4b634ea19e"}, @@ -1092,7 +1092,7 @@ name = "ecdsa" version = "0.18.0" description = "ECDSA cryptographic signature library (pure python)" category = "main" -optional = true +optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ {file = "ecdsa-0.18.0-py2.py3-none-any.whl", hash = "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"}, @@ -1165,25 +1165,25 @@ importlib-resources = {version = ">=5.0", markers = "python_version < \"3.10\""} [[package]] name = "fastapi" -version = "0.92.0" +version = "0.95.2" 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.92.0-py3-none-any.whl", hash = "sha256:ae7b97c778e2f2ec3fb3cb4fb14162129411d99907fb71920f6d69a524340ebf"}, - {file = "fastapi-0.92.0.tar.gz", hash = "sha256:023a0f5bd2c8b2609014d3bba1e14a1d7df96c6abea0a73070621c9862b9a4de"}, + {file = "fastapi-0.95.2-py3-none-any.whl", hash = "sha256:d374dbc4ef2ad9b803899bd3360d34c534adc574546e25314ab72c0c4411749f"}, + {file = "fastapi-0.95.2.tar.gz", hash = "sha256:4d9d3e8c71c73f11874bcf5e33626258d143252e329a01002f767306c64fb982"}, ] [package.dependencies] pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" -starlette = ">=0.25.0,<0.26.0" +starlette = ">=0.27.0,<0.28.0" [package.extras] all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] dev = ["pre-commit (>=2.17.0,<3.0.0)", "ruff (==0.0.138)", "uvicorn[standard] (>=0.12.0,<0.21.0)"] -doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer[all] (>=0.6.1,<0.8.0)"] -test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==22.10.0)", "coverage[toml] (>=6.5.0,<8.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "pyyaml (>=5.3.1,<7.0.0)", "ruff (==0.0.138)", "sqlalchemy (>=1.3.18,<1.4.43)", "types-orjson (==3.6.2)", "types-ujson (==5.6.0.0)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"] +doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer-cli (>=0.0.13,<0.0.14)", "typer[all] (>=0.6.1,<0.8.0)"] +test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6.5.0,<8.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.7)", "pyyaml (>=5.3.1,<7.0.0)", "ruff (==0.0.138)", "sqlalchemy (>=1.3.18,<1.4.43)", "types-orjson (==3.6.2)", "types-ujson (==5.7.0.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"] [[package]] name = "filelock" @@ -1555,7 +1555,7 @@ name = "grpcio-health-checking" version = "1.47.5" description = "Standard Health Checking Service for gRPC" category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "grpcio-health-checking-1.47.5.tar.gz", hash = "sha256:74f36ef2ff704c46965bd74cdea51afc0bbcde641134c9d09ecb5063391db516"}, @@ -1571,7 +1571,7 @@ name = "grpcio-reflection" version = "1.47.5" description = "Standard Protobuf Reflection Service for gRPC" category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "grpcio-reflection-1.47.5.tar.gz", hash = "sha256:ac391ec327861f16bc870638101fee80799eccf39c5b09e9ddd776d6854b9873"}, @@ -2034,7 +2034,7 @@ name = "jcloud" version = "0.2.10" description = "Simplify deploying and managing Jina projects on Jina Cloud" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "jcloud-0.2.10.tar.gz", hash = "sha256:40f9e0f8cbef4a711d58941939e206923eb1fdd65941f7b4ded4f448cc5a927f"}, @@ -2077,7 +2077,7 @@ name = "jina" version = "3.15.2" description = "Build multimodal AI services via cloud native technologies · Neural Search · Generative AI · MLOps" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "jina-3.15.2.tar.gz", hash = "sha256:41c3fbe14736edf34e69b0245410554347b209aa01f4cf8e2c65d6e3972ba0b0"}, @@ -2195,7 +2195,7 @@ name = "jina-hubble-sdk" version = "0.38.0" description = "SDK for Hubble API at Jina AI." category = "main" -optional = true +optional = false python-versions = ">=3.7.0" files = [ {file = "jina-hubble-sdk-0.38.0.tar.gz", hash = "sha256:1667917ed16d75eddd1e0d3b8e9d78ffd611de59500abeca48b05040c7571c4c"}, @@ -2216,6 +2216,24 @@ rich = "*" [package.extras] full = ["aiohttp", "black (==22.3.0)", "docker", "filelock", "flake8 (==4.0.1)", "importlib-metadata", "isort (==5.10.1)", "mock (==4.0.3)", "pathspec", "pytest (==7.0.0)", "pytest-asyncio (==0.19.0)", "pytest-cov (==3.0.0)", "pytest-mock (==3.7.0)", "python-jose", "pyyaml", "requests", "rich"] +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "joblib" version = "1.2.0" @@ -2275,14 +2293,14 @@ test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] [[package]] name = "langchain" -version = "0.0.176" +version = "0.0.183" description = "Building applications with LLMs through composability" category = "main" optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "langchain-0.0.176-py3-none-any.whl", hash = "sha256:b2a1958ed07d884869b4bdaa28d63a005787e7f4938d2bbe984b3662827db861"}, - {file = "langchain-0.0.176.tar.gz", hash = "sha256:25f2875d48efab9b32affbe886b85580b1a9df0fb5ae54798eb28aeafba60bec"}, + {file = "langchain-0.0.183-py3-none-any.whl", hash = "sha256:d98e56bf5189599f6500d59908f85b5a6cdf65545e34b41165c7c98beb1ccd0e"}, + {file = "langchain-0.0.183.tar.gz", hash = "sha256:ec9712ae9d11b14f02e703f123d9493f82d49fd80e86df4ff4014df2af06aeca"}, ] [package.dependencies] @@ -2299,14 +2317,13 @@ SQLAlchemy = ">=1.4,<3" tenacity = ">=8.1.0,<9.0.0" [package.extras] -all = ["O365 (>=2.0.26,<3.0.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.2.6,<0.3.0)", "arxiv (>=1.4,<2.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "beautifulsoup4 (>=4,<5)", "clickhouse-connect (>=0.5.14,<0.6.0)", "cohere (>=3,<4)", "deeplake (>=3.3.0,<4.0.0)", "docarray (>=0.31.0,<0.32.0)", "duckduckgo-search (>=2.8.6,<3.0.0)", "elasticsearch (>=8,<9)", "faiss-cpu (>=1,<2)", "google-api-python-client (==2.70.0)", "google-search-results (>=2,<3)", "gptcache (>=0.1.7)", "hnswlib (>=0.7.0,<0.8.0)", "html2text (>=2020.1.16,<2021.0.0)", "huggingface_hub (>=0,<1)", "jina (>=3.14,<4.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "lancedb (>=0.1,<0.2)", "lark (>=1.1.5,<2.0.0)", "lxml (>=4.9.2,<5.0.0)", "manifest-ml (>=0.0.1,<0.0.2)", "networkx (>=2.6.3,<3.0.0)", "nlpcloud (>=1,<2)", "nltk (>=3,<4)", "nomic (>=1.0.43,<2.0.0)", "openai (>=0,<1)", "opensearch-py (>=2.0.0,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pexpect (>=4.8.0,<5.0.0)", "pgvector (>=0.1.6,<0.2.0)", "pinecone-client (>=2,<3)", "pinecone-text (>=0.4.2,<0.5.0)", "protobuf (==3.19.6)", "psycopg2-binary (>=2.9.5,<3.0.0)", "pyowm (>=3.3.0,<4.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pytesseract (>=0.3.10,<0.4.0)", "pyvespa (>=0.33.0,<0.34.0)", "qdrant-client (>=1.1.2,<2.0.0)", "redis (>=4,<5)", "sentence-transformers (>=2,<3)", "spacy (>=3,<4)", "steamship (>=2.16.9,<3.0.0)", "tensorflow-text (>=2.11.0,<3.0.0)", "tiktoken (>=0.3.2,<0.4.0)", "torch (>=1,<3)", "transformers (>=4,<5)", "weaviate-client (>=3,<4)", "wikipedia (>=1,<2)", "wolframalpha (==5.0.0)"] -azure = ["azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "openai (>=0,<1)"] +all = ["O365 (>=2.0.26,<3.0.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.2.6,<0.3.0)", "arxiv (>=1.4,<2.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "beautifulsoup4 (>=4,<5)", "clickhouse-connect (>=0.5.14,<0.6.0)", "cohere (>=3,<4)", "deeplake (>=3.3.0,<4.0.0)", "docarray[hnswlib] (>=0.32.0,<0.33.0)", "duckduckgo-search (>=2.8.6,<3.0.0)", "elasticsearch (>=8,<9)", "faiss-cpu (>=1,<2)", "google-api-python-client (==2.70.0)", "google-search-results (>=2,<3)", "gptcache (>=0.1.7)", "html2text (>=2020.1.16,<2021.0.0)", "huggingface_hub (>=0,<1)", "jina (>=3.14,<4.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "lancedb (>=0.1,<0.2)", "langkit (>=0.0.1.dev3,<0.1.0)", "lark (>=1.1.5,<2.0.0)", "lxml (>=4.9.2,<5.0.0)", "manifest-ml (>=0.0.1,<0.0.2)", "momento (>=1.5.0,<2.0.0)", "neo4j (>=5.8.1,<6.0.0)", "networkx (>=2.6.3,<3.0.0)", "nlpcloud (>=1,<2)", "nltk (>=3,<4)", "nomic (>=1.0.43,<2.0.0)", "openai (>=0,<1)", "openlm (>=0.0.5,<0.0.6)", "opensearch-py (>=2.0.0,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pexpect (>=4.8.0,<5.0.0)", "pgvector (>=0.1.6,<0.2.0)", "pinecone-client (>=2,<3)", "pinecone-text (>=0.4.2,<0.5.0)", "psycopg2-binary (>=2.9.5,<3.0.0)", "pyowm (>=3.3.0,<4.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pytesseract (>=0.3.10,<0.4.0)", "pyvespa (>=0.33.0,<0.34.0)", "qdrant-client (>=1.1.2,<2.0.0)", "redis (>=4,<5)", "requests-toolbelt (>=1.0.0,<2.0.0)", "sentence-transformers (>=2,<3)", "spacy (>=3,<4)", "steamship (>=2.16.9,<3.0.0)", "tensorflow-text (>=2.11.0,<3.0.0)", "tiktoken (>=0.3.2,<0.4.0)", "torch (>=1,<3)", "transformers (>=4,<5)", "weaviate-client (>=3,<4)", "wikipedia (>=1,<2)", "wolframalpha (==5.0.0)"] +azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "openai (>=0,<1)"] cohere = ["cohere (>=3,<4)"] +docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"] embeddings = ["sentence-transformers (>=2,<3)"] -extended-testing = ["atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "chardet (>=5.1.0,<6.0.0)", "gql (>=3.4.1,<4.0.0)", "html2text (>=2020.1.16,<2021.0.0)", "jq (>=1.4.1,<2.0.0)", "lxml (>=4.9.2,<5.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "psychicapi (>=0.2,<0.3)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "telethon (>=1.28.5,<2.0.0)", "tqdm (>=4.48.0)", "zep-python (>=0.25,<0.26)"] -hnswlib = ["docarray (>=0.31.0,<0.32.0)", "hnswlib (>=0.7.0,<0.8.0)", "protobuf (==3.19.6)"] -in-memory-store = ["docarray (>=0.31.0,<0.32.0)"] -llms = ["anthropic (>=0.2.6,<0.3.0)", "cohere (>=3,<4)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (>=0,<1)", "torch (>=1,<3)", "transformers (>=4,<5)"] +extended-testing = ["atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "chardet (>=5.1.0,<6.0.0)", "gql (>=3.4.1,<4.0.0)", "html2text (>=2020.1.16,<2021.0.0)", "jq (>=1.4.1,<2.0.0)", "lxml (>=4.9.2,<5.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "psychicapi (>=0.2,<0.3)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "telethon (>=1.28.5,<2.0.0)", "tqdm (>=4.48.0)", "zep-python (>=0.30,<0.31)"] +llms = ["anthropic (>=0.2.6,<0.3.0)", "cohere (>=3,<4)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (>=0,<1)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"] openai = ["openai (>=0,<1)", "tiktoken (>=0.3.2,<0.4.0)"] qdrant = ["qdrant-client (>=1.1.2,<2.0.0)"] text-helpers = ["chardet (>=5.1.0,<6.0.0)"] @@ -2359,13 +2376,13 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "llama-cpp-python" -version = "0.1.50" +version = "0.1.55" description = "A Python wrapper for llama.cpp" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "llama_cpp_python-0.1.50.tar.gz", hash = "sha256:e305ae1b9f135f94afd8dd227701e6a1cd36db9c28f736b830ec364127c00bb9"}, + {file = "llama_cpp_python-0.1.55.tar.gz", hash = "sha256:1bc749f314a979c601b2dae22eb1f2d63fe791bc1237cce24d36b4f856be8ca2"}, ] [package.dependencies] @@ -2559,6 +2576,66 @@ profiling = ["gprof2dot"] rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] +[[package]] +name = "markupsafe" +version = "2.1.2" +description = "Safely add untrusted strings to HTML/XML markup." +category = "main" +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, + {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, + {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, + {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, + {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, + {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, + {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, +] + [[package]] name = "marshmallow" version = "3.19.0" @@ -3082,7 +3159,7 @@ name = "opentelemetry-api" version = "1.18.0" description = "OpenTelemetry Python API" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_api-1.18.0-py3-none-any.whl", hash = "sha256:d05bcc94ec239fd76fd90d784c5e3ad081a8a1ac2ffc8a2c83a49ace052d1492"}, @@ -3099,7 +3176,7 @@ name = "opentelemetry-exporter-otlp" version = "1.18.0" description = "OpenTelemetry Collector Exporters" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_exporter_otlp-1.18.0-py3-none-any.whl", hash = "sha256:2b8d18aa3f8fa360df2fe6c274132cf38939a02f8aa621d6ed060a920aa9e4c6"}, @@ -3115,7 +3192,7 @@ name = "opentelemetry-exporter-otlp-proto-common" version = "1.18.0" description = "OpenTelemetry Protobuf encoding" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_exporter_otlp_proto_common-1.18.0-py3-none-any.whl", hash = "sha256:276073ccc8c6e6570fe05ca8ca0de77d662bc89bc614ec8bfbc855112f7e25e3"}, @@ -3130,7 +3207,7 @@ name = "opentelemetry-exporter-otlp-proto-grpc" version = "1.18.0" description = "OpenTelemetry Collector Protobuf over gRPC Exporter" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_exporter_otlp_proto_grpc-1.18.0-py3-none-any.whl", hash = "sha256:c773bc9df2c9d6464f0d5936963399b2fc440f0616c1277f29512d540ad7e0a2"}, @@ -3155,7 +3232,7 @@ name = "opentelemetry-exporter-otlp-proto-http" version = "1.18.0" description = "OpenTelemetry Collector Protobuf over HTTP Exporter" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_exporter_otlp_proto_http-1.18.0-py3-none-any.whl", hash = "sha256:c22110705473f1c61bd4d74ded3b8bd3fac66ffbe7d9ba376267d8539919ed90"}, @@ -3180,7 +3257,7 @@ name = "opentelemetry-exporter-prometheus" version = "1.12.0rc1" description = "Prometheus Metric Exporter for OpenTelemetry" category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "opentelemetry-exporter-prometheus-1.12.0rc1.tar.gz", hash = "sha256:f10c6c243d69d5b63f755885b36a4ce8ef2cdf3e737c4e6bf00f32e87668f0a9"}, @@ -3197,7 +3274,7 @@ name = "opentelemetry-instrumentation" version = "0.39b0" description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation-0.39b0-py3-none-any.whl", hash = "sha256:fcfd74413159fe797e343104f7e85a3f8146713634debcac10a057ac7f1eb011"}, @@ -3214,7 +3291,7 @@ name = "opentelemetry-instrumentation-aiohttp-client" version = "0.39b0" description = "OpenTelemetry aiohttp client instrumentation" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation_aiohttp_client-0.39b0-py3-none-any.whl", hash = "sha256:315adf314f35532677b7ae2abd9a663ec86df7183594605592f0e89e599d86ca"}, @@ -3237,7 +3314,7 @@ name = "opentelemetry-instrumentation-asgi" version = "0.39b0" description = "ASGI instrumentation for OpenTelemetry" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation_asgi-0.39b0-py3-none-any.whl", hash = "sha256:cb9cbf56e32be12b0e5e70c21cf27999f10920afc73110457f4e4b0ec4078c5f"}, @@ -3260,7 +3337,7 @@ name = "opentelemetry-instrumentation-fastapi" version = "0.39b0" description = "OpenTelemetry FastAPI Instrumentation" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation_fastapi-0.39b0-py3-none-any.whl", hash = "sha256:33223b46393ef63229d35c4e0903e900674d3dfc65ada49fbfd51db8742295cb"}, @@ -3283,7 +3360,7 @@ name = "opentelemetry-instrumentation-grpc" version = "0.39b0" description = "OpenTelemetry gRPC instrumentation" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_instrumentation_grpc-0.39b0-py3-none-any.whl", hash = "sha256:1ab7a1e4a43efd8e827d1666065253fdc4dca76ca7bcf43417fe7523999e3145"}, @@ -3306,7 +3383,7 @@ name = "opentelemetry-proto" version = "1.18.0" description = "OpenTelemetry Python Proto" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_proto-1.18.0-py3-none-any.whl", hash = "sha256:34d1c49283f0246a58761d9322d5a79702a09afda0bb181bb6378ed26862e446"}, @@ -3321,7 +3398,7 @@ name = "opentelemetry-sdk" version = "1.18.0" description = "OpenTelemetry Python SDK" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_sdk-1.18.0-py3-none-any.whl", hash = "sha256:a097cc1e0db6ff33b4d250a9350dc17975d24a22aa667fca2866e60c51306723"}, @@ -3339,7 +3416,7 @@ name = "opentelemetry-semantic-conventions" version = "0.39b0" description = "OpenTelemetry Semantic Conventions" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_semantic_conventions-0.39b0-py3-none-any.whl", hash = "sha256:0dd7a9dc0dfde2335f643705bba8f7c44182c797bc208b7601f0b8e8211cfd5c"}, @@ -3351,7 +3428,7 @@ name = "opentelemetry-util-http" version = "0.39b0" description = "Web util for OpenTelemetry" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "opentelemetry_util_http-0.39b0-py3-none-any.whl", hash = "sha256:587c3f8931b8a1e910a04fd736e8ff1386fe25c09dc92dc85104679112221483"}, @@ -3662,7 +3739,7 @@ name = "prometheus-client" version = "0.17.0" description = "Python client for the Prometheus monitoring system." category = "main" -optional = true +optional = false python-versions = ">=3.6" files = [ {file = "prometheus_client-0.17.0-py3-none-any.whl", hash = "sha256:a77b708cf083f4d1a3fb3ce5c95b4afa32b9c521ae363354a4a910204ea095ce"}, @@ -4156,7 +4233,7 @@ name = "python-jose" version = "3.3.0" description = "JOSE implementation in Python" category = "main" -optional = true +optional = false python-versions = "*" files = [ {file = "python-jose-3.3.0.tar.gz", hash = "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a"}, @@ -4190,7 +4267,7 @@ name = "python-multipart" version = "0.0.6" description = "A streaming multipart parser for Python" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18"}, @@ -4613,6 +4690,166 @@ files = [ {file = "ruff-0.0.254.tar.gz", hash = "sha256:0eb66c9520151d3bd950ea43b3a088618a8e4e10a5014a72687881e6f3606312"}, ] +[[package]] +name = "scikit-learn" +version = "1.2.2" +description = "A set of python modules for machine learning and data mining" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "scikit-learn-1.2.2.tar.gz", hash = "sha256:8429aea30ec24e7a8c7ed8a3fa6213adf3814a6efbea09e16e0a0c71e1a1a3d7"}, + {file = "scikit_learn-1.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99cc01184e347de485bf253d19fcb3b1a3fb0ee4cea5ee3c43ec0cc429b6d29f"}, + {file = "scikit_learn-1.2.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e6e574db9914afcb4e11ade84fab084536a895ca60aadea3041e85b8ac963edb"}, + {file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fe83b676f407f00afa388dd1fdd49e5c6612e551ed84f3b1b182858f09e987d"}, + {file = "scikit_learn-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2642baa0ad1e8f8188917423dd73994bf25429f8893ddbe115be3ca3183584"}, + {file = "scikit_learn-1.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ad66c3848c0a1ec13464b2a95d0a484fd5b02ce74268eaa7e0c697b904f31d6c"}, + {file = "scikit_learn-1.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfeaf8be72117eb61a164ea6fc8afb6dfe08c6f90365bde2dc16456e4bc8e45f"}, + {file = "scikit_learn-1.2.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:fe0aa1a7029ed3e1dcbf4a5bc675aa3b1bc468d9012ecf6c6f081251ca47f590"}, + {file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:065e9673e24e0dc5113e2dd2b4ca30c9d8aa2fa90f4c0597241c93b63130d233"}, + {file = "scikit_learn-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf036ea7ef66115e0d49655f16febfa547886deba20149555a41d28f56fd6d3c"}, + {file = "scikit_learn-1.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:8b0670d4224a3c2d596fd572fb4fa673b2a0ccfb07152688ebd2ea0b8c61025c"}, + {file = "scikit_learn-1.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9c710ff9f9936ba8a3b74a455ccf0dcf59b230caa1e9ba0223773c490cab1e51"}, + {file = "scikit_learn-1.2.2-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:2dd3ffd3950e3d6c0c0ef9033a9b9b32d910c61bd06cb8206303fb4514b88a49"}, + {file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44b47a305190c28dd8dd73fc9445f802b6ea716669cfc22ab1eb97b335d238b1"}, + {file = "scikit_learn-1.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:953236889928d104c2ef14027539f5f2609a47ebf716b8cbe4437e85dce42744"}, + {file = "scikit_learn-1.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:7f69313884e8eb311460cc2f28676d5e400bd929841a2c8eb8742ae78ebf7c20"}, + {file = "scikit_learn-1.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8156db41e1c39c69aa2d8599ab7577af53e9e5e7a57b0504e116cc73c39138dd"}, + {file = "scikit_learn-1.2.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fe175ee1dab589d2e1033657c5b6bec92a8a3b69103e3dd361b58014729975c3"}, + {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d5312d9674bed14f73773d2acf15a3272639b981e60b72c9b190a0cffed5bad"}, + {file = "scikit_learn-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea061bf0283bf9a9f36ea3c5d3231ba2176221bbd430abd2603b1c3b2ed85c89"}, + {file = "scikit_learn-1.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6477eed40dbce190f9f9e9d0d37e020815825b300121307942ec2110302b66a3"}, +] + +[package.dependencies] +joblib = ">=1.1.1" +numpy = ">=1.17.3" +scipy = ">=1.3.2" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "pandas (>=1.0.5)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=3.1.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.1.3)", "pandas (>=1.0.5)", "plotly (>=5.10.0)", "pooch (>=1.6.0)", "scikit-image (>=0.16.2)", "seaborn (>=0.9.0)"] +tests = ["black (>=22.3.0)", "flake8 (>=3.8.2)", "matplotlib (>=3.1.3)", "mypy (>=0.961)", "numpydoc (>=1.2.0)", "pandas (>=1.0.5)", "pooch (>=1.6.0)", "pyamg (>=4.0.0)", "pytest (>=5.3.1)", "pytest-cov (>=2.9.0)", "scikit-image (>=0.16.2)"] + +[[package]] +name = "scipy" +version = "1.10.1" +description = "Fundamental algorithms for scientific computing in Python" +category = "main" +optional = false +python-versions = "<3.12,>=3.8" +files = [ + {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, + {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, + {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"}, + {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2"}, + {file = "scipy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1"}, + {file = "scipy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd"}, + {file = "scipy-1.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5"}, + {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35"}, + {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d"}, + {file = "scipy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f"}, + {file = "scipy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35"}, + {file = "scipy-1.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88"}, + {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1"}, + {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f"}, + {file = "scipy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415"}, + {file = "scipy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9"}, + {file = "scipy-1.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6"}, + {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353"}, + {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601"}, + {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, + {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, +] + +[package.dependencies] +numpy = ">=1.19.5,<1.27.0" + +[package.extras] +dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "sentence-transformers" +version = "2.2.2" +description = "Multilingual text embeddings" +category = "main" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "sentence-transformers-2.2.2.tar.gz", hash = "sha256:dbc60163b27de21076c9a30d24b5b7b6fa05141d68cf2553fa9a77bf79a29136"}, +] + +[package.dependencies] +huggingface-hub = ">=0.4.0" +nltk = "*" +numpy = "*" +scikit-learn = "*" +scipy = "*" +sentencepiece = "*" +torch = ">=1.6.0" +torchvision = "*" +tqdm = "*" +transformers = ">=4.6.0,<5.0.0" + +[[package]] +name = "sentencepiece" +version = "0.1.99" +description = "SentencePiece python wrapper" +category = "main" +optional = false +python-versions = "*" +files = [ + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0eb528e70571b7c02723e5804322469b82fe7ea418c96051d0286c0fa028db73"}, + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:77d7fafb2c4e4659cbdf303929503f37a26eabc4ff31d3a79bf1c5a1b338caa7"}, + {file = "sentencepiece-0.1.99-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be9cf5b9e404c245aeb3d3723c737ba7a8f5d4ba262ef233a431fa6c45f732a0"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baed1a26464998f9710d20e52607c29ffd4293e7c71c6a1f83f51ad0911ec12c"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9832f08bb372d4c8b567612f8eab9e36e268dff645f1c28f9f8e851be705f6d1"}, + {file = "sentencepiece-0.1.99-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:019e7535108e309dae2b253a75834fc3128240aa87c00eb80732078cdc182588"}, + {file = "sentencepiece-0.1.99-cp310-cp310-win32.whl", hash = "sha256:fa16a830416bb823fa2a52cbdd474d1f7f3bba527fd2304fb4b140dad31bb9bc"}, + {file = "sentencepiece-0.1.99-cp310-cp310-win_amd64.whl", hash = "sha256:14b0eccb7b641d4591c3e12ae44cab537d68352e4d3b6424944f0c447d2348d5"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6d3c56f24183a1e8bd61043ff2c58dfecdc68a5dd8955dc13bab83afd5f76b81"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed6ea1819fd612c989999e44a51bf556d0ef6abfb553080b9be3d347e18bcfb7"}, + {file = "sentencepiece-0.1.99-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2a0260cd1fb7bd8b4d4f39dc2444a8d5fd4e0a0c4d5c899810ef1abf99b2d45"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a1abff4d1ff81c77cac3cc6fefa34fa4b8b371e5ee51cb7e8d1ebc996d05983"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:004e6a621d4bc88978eecb6ea7959264239a17b70f2cbc348033d8195c9808ec"}, + {file = "sentencepiece-0.1.99-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db361e03342c41680afae5807590bc88aa0e17cfd1a42696a160e4005fcda03b"}, + {file = "sentencepiece-0.1.99-cp311-cp311-win32.whl", hash = "sha256:2d95e19168875b70df62916eb55428a0cbcb834ac51d5a7e664eda74def9e1e0"}, + {file = "sentencepiece-0.1.99-cp311-cp311-win_amd64.whl", hash = "sha256:f90d73a6f81248a909f55d8e6ef56fec32d559e1e9af045f0b0322637cb8e5c7"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:62e24c81e74bd87a6e0d63c51beb6527e4c0add67e1a17bac18bcd2076afcfeb"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57efcc2d51caff20d9573567d9fd3f854d9efe613ed58a439c78c9f93101384a"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a904c46197993bd1e95b93a6e373dca2f170379d64441041e2e628ad4afb16f"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d89adf59854741c0d465f0e1525b388c0d174f611cc04af54153c5c4f36088c4"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-win32.whl", hash = "sha256:47c378146928690d1bc106fdf0da768cebd03b65dd8405aa3dd88f9c81e35dba"}, + {file = "sentencepiece-0.1.99-cp36-cp36m-win_amd64.whl", hash = "sha256:9ba142e7a90dd6d823c44f9870abdad45e6c63958eb60fe44cca6828d3b69da2"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b7b1a9ae4d7c6f1f867e63370cca25cc17b6f4886729595b885ee07a58d3cec3"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0f644c9d4d35c096a538507b2163e6191512460035bf51358794a78515b74f7"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8843d23a0f686d85e569bd6dcd0dd0e0cbc03731e63497ca6d5bacd18df8b85"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33e6f690a1caebb4867a2e367afa1918ad35be257ecdb3455d2bbd787936f155"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-win32.whl", hash = "sha256:8a321866c2f85da7beac74a824b4ad6ddc2a4c9bccd9382529506d48f744a12c"}, + {file = "sentencepiece-0.1.99-cp37-cp37m-win_amd64.whl", hash = "sha256:c42f753bcfb7661c122a15b20be7f684b61fc8592c89c870adf52382ea72262d"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85b476406da69c70586f0bb682fcca4c9b40e5059814f2db92303ea4585c650c"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cfbcfe13c69d3f87b7fcd5da168df7290a6d006329be71f90ba4f56bc77f8561"}, + {file = "sentencepiece-0.1.99-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:445b0ec381af1cd4eef95243e7180c63d9c384443c16c4c47a28196bd1cda937"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6890ea0f2b4703f62d0bf27932e35808b1f679bdb05c7eeb3812b935ba02001"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb71af492b0eefbf9f2501bec97bcd043b6812ab000d119eaf4bd33f9e283d03"}, + {file = "sentencepiece-0.1.99-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27b866b5bd3ddd54166bbcbf5c8d7dd2e0b397fac8537991c7f544220b1f67bc"}, + {file = "sentencepiece-0.1.99-cp38-cp38-win32.whl", hash = "sha256:b133e8a499eac49c581c3c76e9bdd08c338cc1939e441fee6f92c0ccb5f1f8be"}, + {file = "sentencepiece-0.1.99-cp38-cp38-win_amd64.whl", hash = "sha256:0eaf3591dd0690a87f44f4df129cf8d05d8a4029b5b6709b489b8e27f9a9bcff"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38efeda9bbfb55052d482a009c6a37e52f42ebffcea9d3a98a61de7aee356a28"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6c030b081dc1e1bcc9fadc314b19b740715d3d566ad73a482da20d7d46fd444c"}, + {file = "sentencepiece-0.1.99-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84dbe53e02e4f8a2e45d2ac3e430d5c83182142658e25edd76539b7648928727"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b0f55d0a0ee1719b4b04221fe0c9f0c3461dc3dabd77a035fa2f4788eb3ef9a"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e800f206cd235dc27dc749299e05853a4e4332e8d3dfd81bf13d0e5b9007d9"}, + {file = "sentencepiece-0.1.99-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ae1c40cda8f9d5b0423cfa98542735c0235e7597d79caf318855cdf971b2280"}, + {file = "sentencepiece-0.1.99-cp39-cp39-win32.whl", hash = "sha256:c84ce33af12ca222d14a1cdd37bd76a69401e32bc68fe61c67ef6b59402f4ab8"}, + {file = "sentencepiece-0.1.99-cp39-cp39-win_amd64.whl", hash = "sha256:350e5c74d739973f1c9643edb80f7cc904dc948578bcb1d43c6f2b173e5d18dd"}, + {file = "sentencepiece-0.1.99.tar.gz", hash = "sha256:189c48f5cb2949288f97ccdb97f0473098d9c3dcf5a3d99d4eabe719ec27297f"}, +] + [[package]] name = "setuptools" version = "67.8.0" @@ -4766,14 +5003,14 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] [[package]] name = "starlette" -version = "0.25.0" +version = "0.27.0" description = "The little ASGI library that shines." category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "starlette-0.25.0-py3-none-any.whl", hash = "sha256:774f1df1983fd594b9b6fb3ded39c2aa1979d10ac45caac0f4255cbe2acb8628"}, - {file = "starlette-0.25.0.tar.gz", hash = "sha256:854c71e73736c429c2bdb07801f2c76c9cba497e7c3cf4988fde5e95fe4cdb3c"}, + {file = "starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"}, + {file = "starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75"}, ] [package.dependencies] @@ -4834,6 +5071,18 @@ typing-extensions = ">=4.4.0,<5.0.0" [package.extras] dev = ["aiohttp (>=3.8.1)", "click (>=8.1.2)", "msgpack (>=1.0.3)"] +[[package]] +name = "threadpoolctl" +version = "3.1.0" +description = "threadpoolctl" +category = "main" +optional = false +python-versions = ">=3.6" +files = [ + {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, + {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, +] + [[package]] name = "tiktoken" version = "0.3.3" @@ -4959,6 +5208,85 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "torch" +version = "2.0.1" +description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" +category = "main" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "torch-2.0.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:8ced00b3ba471856b993822508f77c98f48a458623596a4c43136158781e306a"}, + {file = "torch-2.0.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:359bfaad94d1cda02ab775dc1cc386d585712329bb47b8741607ef6ef4950747"}, + {file = "torch-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:7c84e44d9002182edd859f3400deaa7410f5ec948a519cc7ef512c2f9b34d2c4"}, + {file = "torch-2.0.1-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:567f84d657edc5582d716900543e6e62353dbe275e61cdc36eda4929e46df9e7"}, + {file = "torch-2.0.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:787b5a78aa7917465e9b96399b883920c88a08f4eb63b5a5d2d1a16e27d2f89b"}, + {file = "torch-2.0.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:e617b1d0abaf6ced02dbb9486803abfef0d581609b09641b34fa315c9c40766d"}, + {file = "torch-2.0.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b6019b1de4978e96daa21d6a3ebb41e88a0b474898fe251fd96189587408873e"}, + {file = "torch-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:dbd68cbd1cd9da32fe5d294dd3411509b3d841baecb780b38b3b7b06c7754434"}, + {file = "torch-2.0.1-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:ef654427d91600129864644e35deea761fb1fe131710180b952a6f2e2207075e"}, + {file = "torch-2.0.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:25aa43ca80dcdf32f13da04c503ec7afdf8e77e3a0183dd85cd3e53b2842e527"}, + {file = "torch-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5ef3ea3d25441d3957348f7e99c7824d33798258a2bf5f0f0277cbcadad2e20d"}, + {file = "torch-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0882243755ff28895e8e6dc6bc26ebcf5aa0911ed81b2a12f241fc4b09075b13"}, + {file = "torch-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:f66aa6b9580a22b04d0af54fcd042f52406a8479e2b6a550e3d9f95963e168c8"}, + {file = "torch-2.0.1-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:1adb60d369f2650cac8e9a95b1d5758e25d526a34808f7448d0bd599e4ae9072"}, + {file = "torch-2.0.1-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:1bcffc16b89e296826b33b98db5166f990e3b72654a2b90673e817b16c50e32b"}, + {file = "torch-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:e10e1597f2175365285db1b24019eb6f04d53dcd626c735fc502f1e8b6be9875"}, + {file = "torch-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:423e0ae257b756bb45a4b49072046772d1ad0c592265c5080070e0767da4e490"}, + {file = "torch-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:8742bdc62946c93f75ff92da00e3803216c6cce9b132fbca69664ca38cfb3e18"}, + {file = "torch-2.0.1-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:c62df99352bd6ee5a5a8d1832452110435d178b5164de450831a3a8cc14dc680"}, + {file = "torch-2.0.1-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:671a2565e3f63b8fe8e42ae3e36ad249fe5e567435ea27b94edaa672a7d0c416"}, +] + +[package.dependencies] +filelock = "*" +jinja2 = "*" +networkx = "*" +sympy = "*" +typing-extensions = "*" + +[package.extras] +opt-einsum = ["opt-einsum (>=3.3)"] + +[[package]] +name = "torchvision" +version = "0.15.2" +description = "image and video datasets and models for torch deep learning" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "torchvision-0.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7754088774e810c5672b142a45dcf20b1bd986a5a7da90f8660c43dc43fb850c"}, + {file = "torchvision-0.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37eb138e13f6212537a3009ac218695483a635c404b6cc1d8e0d0d978026a86d"}, + {file = "torchvision-0.15.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:54143f7cc0797d199b98a53b7d21c3f97615762d4dd17ad45a41c7e80d880e73"}, + {file = "torchvision-0.15.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:1eefebf5fbd01a95fe8f003d623d941601c94b5cec547b420da89cb369d9cf96"}, + {file = "torchvision-0.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:96fae30c5ca8423f4b9790df0f0d929748e32718d88709b7b567d2f630c042e3"}, + {file = "torchvision-0.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5f35f6bd5bcc4568e6522e4137fa60fcc72f4fa3e615321c26cd87e855acd398"}, + {file = "torchvision-0.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:757505a0ab2be7096cb9d2bf4723202c971cceddb72c7952a7e877f773de0f8a"}, + {file = "torchvision-0.15.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:012ad25cfd9019ff9b0714a168727e3845029be1af82296ff1e1482931fa4b80"}, + {file = "torchvision-0.15.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b02a7ffeaa61448737f39a4210b8ee60234bda0515a0c0d8562f884454105b0f"}, + {file = "torchvision-0.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:10be76ceded48329d0a0355ac33da131ee3993ff6c125e4a02ab34b5baa2472c"}, + {file = "torchvision-0.15.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f12415b686dba884fb086f53ac803f692be5a5cdd8a758f50812b30fffea2e4"}, + {file = "torchvision-0.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:31211c01f8b8ec33b8a638327b5463212e79a03e43c895f88049f97af1bd12fd"}, + {file = "torchvision-0.15.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c55f9889e436f14b4f84a9c00ebad0d31f5b4626f10cf8018e6c676f92a6d199"}, + {file = "torchvision-0.15.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:9a192f2aa979438f23c20e883980b23d13268ab9f819498774a6d2eb021802c2"}, + {file = "torchvision-0.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:c07071bc8d02aa8fcdfe139ab6a1ef57d3b64c9e30e84d12d45c9f4d89fb6536"}, + {file = "torchvision-0.15.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4790260fcf478a41c7ecc60a6d5200a88159fdd8d756e9f29f0f8c59c4a67a68"}, + {file = "torchvision-0.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:987ab62225b4151a11e53fd06150c5258ced24ac9d7c547e0e4ab6fbca92a5ce"}, + {file = "torchvision-0.15.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:63df26673e66cba3f17e07c327a8cafa3cce98265dbc3da329f1951d45966838"}, + {file = "torchvision-0.15.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b85f98d4cc2f72452f6792ab4463a3541bc5678a8cdd3da0e139ba2fe8b56d42"}, + {file = "torchvision-0.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:07c462524cc1bba5190c16a9d47eac1fca024d60595a310f23c00b4ffff18b30"}, +] + +[package.dependencies] +numpy = "*" +pillow = ">=5.3.0,<8.3.0 || >=8.4.0" +requests = "*" +torch = "2.0.1" + +[package.extras] +scipy = ["scipy"] + [[package]] name = "tornado" version = "6.3.2" @@ -5017,6 +5345,74 @@ files = [ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] +[[package]] +name = "transformers" +version = "4.29.0" +description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" +category = "main" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "transformers-4.29.0-py3-none-any.whl", hash = "sha256:51f89cbdd515dffac38c002277511d004e1a12a284ab852a4d5641430a409d1f"}, + {file = "transformers-4.29.0.tar.gz", hash = "sha256:b5dff9ce3708dc6639d892435fa69c51dee5c89870f888fa59ef0fc3baa3d8c7"}, +] + +[package.dependencies] +filelock = "*" +huggingface-hub = ">=0.11.0,<1.0" +numpy = ">=1.17" +packaging = ">=20.0" +pyyaml = ">=5.1" +regex = "!=2019.12.17" +requests = "*" +tokenizers = ">=0.11.1,<0.11.3 || >0.11.3,<0.14" +tqdm = ">=4.27" + +[package.extras] +accelerate = ["accelerate (>=0.19.0)"] +all = ["Pillow", "accelerate (>=0.19.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.6.9)", "jax (>=0.2.8,!=0.3.2,<=0.3.6)", "jaxlib (>=0.1.65,<=0.3.6)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "numba (<0.57.0)", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf (<=3.20.2)", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"] +audio = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)"] +codecarbon = ["codecarbon (==1.2.0)"] +deepspeed = ["accelerate (>=0.19.0)", "deepspeed (>=0.8.3)"] +deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.19.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.8.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "optuna", "parameterized", "protobuf (<=3.20.2)", "psutil", "pytest", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "sentencepiece (>=0.1.91,!=0.1.92)", "timeout-decorator"] +dev = ["GitPython (<3.1.19)", "Pillow", "accelerate (>=0.19.0)", "av (==9.2.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "decord (==0.6.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.6.9)", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.2.8,!=0.3.2,<=0.3.6)", "jaxlib (>=0.1.65,<=0.3.6)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "numba (<0.57.0)", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf (<=3.20.2)", "psutil", "pyctcdecode (>=0.4.0)", "pytest", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +dev-tensorflow = ["GitPython (<3.1.19)", "Pillow", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "nltk", "numba (<0.57.0)", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf (<=3.20.2)", "psutil", "pyctcdecode (>=0.4.0)", "pytest", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "urllib3 (<2.0.0)"] +dev-torch = ["GitPython (<3.1.19)", "Pillow", "accelerate (>=0.19.0)", "beautifulsoup4", "black (>=23.1,<24.0)", "codecarbon (==1.2.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "hf-doc-builder", "hf-doc-builder (>=0.3.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "librosa", "nltk", "numba (<0.57.0)", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf (<=3.20.2)", "psutil", "pyctcdecode (>=0.4.0)", "pytest", "pytest-timeout", "pytest-xdist", "ray[tune]", "rhoknp (>=1.1.0)", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (>=0.0.241,<=0.0.259)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "timeout-decorator", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] +docs = ["Pillow", "accelerate (>=0.19.0)", "av (==9.2.0)", "codecarbon (==1.2.0)", "decord (==0.6.0)", "flax (>=0.4.1,<=0.6.9)", "hf-doc-builder", "jax (>=0.2.8,!=0.3.2,<=0.3.6)", "jaxlib (>=0.1.65,<=0.3.6)", "kenlm", "keras-nlp (>=0.3.1)", "librosa", "numba (<0.57.0)", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf (<=3.20.2)", "pyctcdecode (>=0.4.0)", "ray[tune]", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx", "timm", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "torchaudio", "torchvision"] +docs-specific = ["hf-doc-builder"] +fairscale = ["fairscale (>0.3)"] +flax = ["flax (>=0.4.1,<=0.6.9)", "jax (>=0.2.8,!=0.3.2,<=0.3.6)", "jaxlib (>=0.1.65,<=0.3.6)", "optax (>=0.0.8,<=0.1.4)"] +flax-speech = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)"] +ftfy = ["ftfy"] +integrations = ["optuna", "ray[tune]", "sigopt"] +ja = ["fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "rhoknp (>=1.1.0)", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)"] +modelcreation = ["cookiecutter (==1.7.3)"] +natten = ["natten (>=0.14.6)"] +onnx = ["onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "tf2onnx"] +onnxruntime = ["onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)"] +optuna = ["optuna"] +quality = ["GitPython (<3.1.19)", "black (>=23.1,<24.0)", "datasets (!=2.5.0)", "hf-doc-builder (>=0.3.0)", "isort (>=5.5.4)", "ruff (>=0.0.241,<=0.0.259)", "urllib3 (<2.0.0)"] +ray = ["ray[tune]"] +retrieval = ["datasets (!=2.5.0)", "faiss-cpu"] +sagemaker = ["sagemaker (>=2.31.0)"] +sentencepiece = ["protobuf (<=3.20.2)", "sentencepiece (>=0.1.91,!=0.1.92)"] +serving = ["fastapi", "pydantic", "starlette", "uvicorn"] +sigopt = ["sigopt"] +sklearn = ["scikit-learn"] +speech = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] +testing = ["GitPython (<3.1.19)", "beautifulsoup4", "black (>=23.1,<24.0)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "hf-doc-builder (>=0.3.0)", "nltk", "parameterized", "protobuf (<=3.20.2)", "psutil", "pytest", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "safetensors (>=0.2.1)", "timeout-decorator"] +tf = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx"] +tf-cpu = ["keras-nlp (>=0.3.1)", "onnxconverter-common", "tensorflow-cpu (>=2.4,<2.13)", "tensorflow-text (<2.13)", "tf2onnx"] +tf-speech = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)"] +timm = ["timm"] +tokenizers = ["tokenizers (>=0.11.1,!=0.11.3,<0.14)"] +torch = ["accelerate (>=0.19.0)", "torch (>=1.9,!=1.12.0)"] +torch-speech = ["kenlm", "librosa", "numba (<0.57.0)", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] +torch-vision = ["Pillow", "torchvision"] +torchhub = ["filelock", "huggingface-hub (>=0.11.0,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf (<=3.20.2)", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.11.1,!=0.11.3,<0.14)", "torch (>=1.9,!=1.12.0)", "tqdm (>=4.27)"] +video = ["av (==9.2.0)", "decord (==0.6.0)"] +vision = ["Pillow"] + [[package]] name = "typer" version = "0.7.0" @@ -5374,7 +5770,7 @@ name = "websocket-client" version = "1.5.2" description = "WebSocket client for Python with low level API options" category = "main" -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "websocket-client-1.5.2.tar.gz", hash = "sha256:c7d67c13b928645f259d9b847ab5b57fd2d127213ca41ebd880de1f553b7c23b"}, @@ -5557,14 +5953,14 @@ files = [ [[package]] name = "xlsxwriter" -version = "3.1.1" +version = "3.1.2" description = "A Python module for creating Excel XLSX files." category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "XlsxWriter-3.1.1-py3-none-any.whl", hash = "sha256:b50e3bd905d7dafa6ea45210e2cc5600b4ccd104a0d3a4d4d7cf813b78426440"}, - {file = "XlsxWriter-3.1.1.tar.gz", hash = "sha256:03459ee76f664470c4c63a8977cab624fb259d0fc1faac64dc9cc6f3cc08f945"}, + {file = "XlsxWriter-3.1.2-py3-none-any.whl", hash = "sha256:331508ff39d610ecdaf979e458840bc1eab6e6a02cfd5d08f044f0f73636236f"}, + {file = "XlsxWriter-3.1.2.tar.gz", hash = "sha256:78751099a770273f1c98b8d6643351f68f98ae8e6acf9d09d37dc6798f8cd3de"}, ] [[package]] @@ -5736,4 +6132,4 @@ deploy = ["langchain-serve"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "ba932035d31d7784a0df6690b2078f1f4a0f37f63b87e7f211c738807b46b313" +content-hash = "e27db1a183064e9181241ce688ee70a4fee4b5df7d3ebf4b6c13eae8fffe4dcc" diff --git a/pyproject.toml b/pyproject.toml index 4223403bc..b2863de69 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,22 +22,22 @@ langflow = "langflow.__main__:main" [tool.poetry.dependencies] python = ">=3.9,<3.12" -fastapi = "^0.92.0" +fastapi = "^0.95.0" uvicorn = "^0.20.0" beautifulsoup4 = "^4.11.2" google-search-results = "^2.4.1" google-api-python-client = "^2.79.0" typer = "^0.7.0" gunicorn = "^20.1.0" -langchain = "^0.0.176" -openai = "^0.27.2" +langchain = "^0.0.183" +openai = "^0.27.7" types-pyyaml = "^6.0.12.8" dill = "^0.3.6" pandas = "^1.5.3" chromadb = "^0.3.21" huggingface-hub = "^0.13.3" rich = "^13.3.3" -llama-cpp-python = "0.1.50" +llama-cpp-python = "^0.1.50" networkx = "^3.1" unstructured = "^0.5.11" pypdf = "^3.7.1" @@ -53,6 +53,9 @@ langchain-serve = { version = "^0.0.33", optional = true } qdrant-client = "^1.2.0" websockets = "^11.0.3" weaviate-client = "^3.19.2" +jina = "3.15.2" +sentence-transformers = "^2.2.2" + [tool.poetry.group.dev.dependencies] black = "^23.1.0" diff --git a/src/backend/langflow/api/chat_manager.py b/src/backend/langflow/api/chat_manager.py index 663243d17..8b1c7a621 100644 --- a/src/backend/langflow/api/chat_manager.py +++ b/src/backend/langflow/api/chat_manager.py @@ -29,10 +29,10 @@ class ChatHistory(Subject): if not isinstance(message, FileResponse): self.notify() - def get_history(self, client_id: str, filter=True) -> List[ChatMessage]: + def get_history(self, client_id: str, filter_messages=True) -> List[ChatMessage]: """Get the chat history for a client.""" if history := self.history.get(client_id, []): - if filter: + if filter_messages: return [msg for msg in history if msg.type not in ["start", "stream"]] return history else: @@ -54,7 +54,9 @@ class ChatManager: """Send the last chat message to the client.""" client_id = self.cache_manager.current_client_id if client_id in self.active_connections: - chat_response = self.chat_history.get_history(client_id, filter=False)[-1] + chat_response = self.chat_history.get_history( + client_id, filter_messages=False + )[-1] if chat_response.is_bot: # Process FileResponse if isinstance(chat_response, FileResponse): @@ -128,7 +130,7 @@ class ChatManager: raise e # Send a response back to the frontend, if needed intermediate_steps = intermediate_steps or "" - history = self.chat_history.get_history(client_id, filter=False) + history = self.chat_history.get_history(client_id, filter_messages=False) file_responses = [] if history: # Iterate backwards through the history diff --git a/src/backend/langflow/cache/base.py b/src/backend/langflow/cache/base.py index 1f2039b27..0f1ff5d92 100644 --- a/src/backend/langflow/cache/base.py +++ b/src/backend/langflow/cache/base.py @@ -120,7 +120,7 @@ def save_binary_file(content: str, file_name: str, accepted_types: list[str]) -> # Get the destination folder cache_path = Path(tempfile.gettempdir()) / PREFIX - if content is None: + if not content: raise ValueError("Please, reload the file in the loader.") data = content.split(",")[1] decoded_bytes = base64.b64decode(data) diff --git a/src/backend/langflow/config.yaml b/src/backend/langflow/config.yaml index 149e7bf80..23cf2b6f2 100644 --- a/src/backend/langflow/config.yaml +++ b/src/backend/langflow/config.yaml @@ -42,8 +42,11 @@ documentloaders: - IMSDbLoader - GitbookLoader - ReadTheDocsLoader + - NotionDirectoryLoader embeddings: - OpenAIEmbeddings + - HuggingFaceEmbeddings + llms: - OpenAI # - AzureOpenAI @@ -60,6 +63,9 @@ prompts: - ZeroShotPrompt textsplitters: - CharacterTextSplitter + - RecursiveCharacterTextSplitter + - LatexTextSplitter + - PythonCodeTextSplitter toolkits: - OpenAPIToolkit - JsonToolkit diff --git a/src/backend/langflow/custom/customs.py b/src/backend/langflow/custom/customs.py index 2b2ccc43f..ee266b0ee 100644 --- a/src/backend/langflow/custom/customs.py +++ b/src/backend/langflow/custom/customs.py @@ -1,24 +1,27 @@ -from langflow.template import nodes +from langflow.template import frontend_node # These should always be instantiated CUSTOM_NODES = { - "prompts": {"ZeroShotPrompt": nodes.ZeroShotPromptNode()}, - "tools": {"PythonFunction": nodes.PythonFunctionNode(), "Tool": nodes.ToolNode()}, + "prompts": {"ZeroShotPrompt": frontend_node.prompts.ZeroShotPromptNode()}, + "tools": { + "PythonFunction": frontend_node.tools.PythonFunctionNode(), + "Tool": frontend_node.tools.ToolNode(), + }, "agents": { - "JsonAgent": nodes.JsonAgentNode(), - "CSVAgent": nodes.CSVAgentNode(), - "initialize_agent": nodes.InitializeAgentNode(), - "VectorStoreAgent": nodes.VectorStoreAgentNode(), - "VectorStoreRouterAgent": nodes.VectorStoreRouterAgentNode(), - "SQLAgent": nodes.SQLAgentNode(), + "JsonAgent": frontend_node.agents.JsonAgentNode(), + "CSVAgent": frontend_node.agents.CSVAgentNode(), + "initialize_agent": frontend_node.agents.InitializeAgentNode(), + "VectorStoreAgent": frontend_node.agents.VectorStoreAgentNode(), + "VectorStoreRouterAgent": frontend_node.agents.VectorStoreRouterAgentNode(), + "SQLAgent": frontend_node.agents.SQLAgentNode(), }, "utilities": { - "SQLDatabase": nodes.SQLDatabaseNode(), + "SQLDatabase": frontend_node.agents.SQLDatabaseNode(), }, "chains": { - "SeriesCharacterChain": nodes.SeriesCharacterChainNode(), - "TimeTravelGuideChain": nodes.TimeTravelGuideChainNode(), - "MidJourneyPromptChain": nodes.MidJourneyPromptChainNode(), + "SeriesCharacterChain": frontend_node.chains.SeriesCharacterChainNode(), + "TimeTravelGuideChain": frontend_node.chains.TimeTravelGuideChainNode(), + "MidJourneyPromptChain": frontend_node.chains.MidJourneyPromptChainNode(), }, } diff --git a/src/backend/langflow/interface/agents/custom.py b/src/backend/langflow/interface/agents/custom.py index 0cbf7baca..4654ef7cb 100644 --- a/src/backend/langflow/interface/agents/custom.py +++ b/src/backend/langflow/interface/agents/custom.py @@ -28,7 +28,6 @@ from langchain.agents.agent_toolkits.vectorstore.prompt import ( ROUTER_PREFIX as VECTORSTORE_ROUTER_PREFIX, ) from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS -from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS as SQL_FORMAT_INSTRUCTIONS from langchain.base_language import BaseLanguageModel from langchain.memory.chat_memory import BaseChatMemory from langchain.sql_database import SQLDatabase @@ -220,7 +219,7 @@ class SQLAgent(CustomAgentExecutor): QuerySQLDataBaseTool(db=db), # type: ignore InfoSQLDatabaseTool(db=db), # type: ignore ListSQLDatabaseTool(db=db), # type: ignore - QueryCheckerTool(db=db, llm_chain=llmchain), # type: ignore + QueryCheckerTool(db=db, llm_chain=llmchain, llm=llm), # type: ignore ] prefix = SQL_PREFIX.format(dialect=toolkit.dialect, top_k=10) @@ -228,7 +227,7 @@ class SQLAgent(CustomAgentExecutor): tools=tools, # type: ignore prefix=prefix, suffix=SQL_SUFFIX, - format_instructions=SQL_FORMAT_INSTRUCTIONS, + format_instructions=FORMAT_INSTRUCTIONS, ) llm_chain = LLMChain( llm=llm, diff --git a/src/backend/langflow/interface/base.py b/src/backend/langflow/interface/base.py index d51d81788..48d6dccc4 100644 --- a/src/backend/langflow/interface/base.py +++ b/src/backend/langflow/interface/base.py @@ -3,7 +3,9 @@ from typing import Any, Dict, List, Optional, Type, Union from pydantic import BaseModel -from langflow.template.base import FrontendNode, Template, TemplateField +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template from langflow.utils.logger import logger # Assuming necessary imports for Field, Template, and FrontendNode classes diff --git a/src/backend/langflow/interface/chains/base.py b/src/backend/langflow/interface/chains/base.py index 7b8da370b..ad66f07b2 100644 --- a/src/backend/langflow/interface/chains/base.py +++ b/src/backend/langflow/interface/chains/base.py @@ -4,7 +4,7 @@ from langflow.custom.customs import get_custom_nodes from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import chain_type_to_cls_dict from langflow.settings import settings -from langflow.template.nodes import ChainFrontendNode +from langflow.template.frontend_node.chains import ChainFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/custom_lists.py b/src/backend/langflow/interface/custom_lists.py index ee8869bfb..0fea838b6 100644 --- a/src/backend/langflow/interface/custom_lists.py +++ b/src/backend/langflow/interface/custom_lists.py @@ -9,11 +9,9 @@ from langchain import ( memory, requests, text_splitter, - utilities, ) from langchain.agents import agent_toolkits from langchain.chat_models import ChatOpenAI -from langchain.sql_database import SQLDatabase from langflow.interface.importing.utils import import_class @@ -72,9 +70,3 @@ documentloaders_type_to_cls_dict: dict[str, Any] = { textsplitter_type_to_cls_dict: dict[str, Any] = dict( inspect.getmembers(text_splitter, inspect.isclass) ) - -## Utilities -utility_type_to_cls_dict: dict[str, Any] = dict( - inspect.getmembers(utilities, inspect.isclass) -) -utility_type_to_cls_dict["SQLDatabase"] = SQLDatabase diff --git a/src/backend/langflow/interface/document_loaders/base.py b/src/backend/langflow/interface/document_loaders/base.py index aab017c0f..a13d5cd5b 100644 --- a/src/backend/langflow/interface/document_loaders/base.py +++ b/src/backend/langflow/interface/document_loaders/base.py @@ -118,7 +118,7 @@ class DocumentLoaderCreator(LangChainTypeCreator): "value": "", "display_name": "Web Page", } - elif name in {"ReadTheDocsLoader"}: + elif name in {"ReadTheDocsLoader", "NotionDirectoryLoader"}: signature["template"]["path"] = { "type": "str", "required": True, diff --git a/src/backend/langflow/interface/embeddings/base.py b/src/backend/langflow/interface/embeddings/base.py index 933d8ad39..1dfa05a99 100644 --- a/src/backend/langflow/interface/embeddings/base.py +++ b/src/backend/langflow/interface/embeddings/base.py @@ -3,8 +3,8 @@ from typing import Dict, List, Optional, Type from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import embedding_type_to_cls_dict from langflow.settings import settings -from langflow.template.base import FrontendNode -from langflow.template.nodes import EmbeddingFrontendNode +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.frontend_node.embeddings import EmbeddingFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/importing/utils.py b/src/backend/langflow/interface/importing/utils.py index 8c65bf60e..d08e52999 100644 --- a/src/backend/langflow/interface/importing/utils.py +++ b/src/backend/langflow/interface/importing/utils.py @@ -71,9 +71,9 @@ def import_class(class_path: str) -> Any: def import_prompt(prompt: str) -> Type[PromptTemplate]: + """Import prompt from prompt name""" from langflow.interface.prompts.custom import CUSTOM_PROMPTS - """Import prompt from prompt name""" if prompt == "ZeroShotPrompt": return import_class("langchain.prompts.PromptTemplate") elif prompt in CUSTOM_PROMPTS: diff --git a/src/backend/langflow/interface/llms/base.py b/src/backend/langflow/interface/llms/base.py index 04a36eb2d..66e153880 100644 --- a/src/backend/langflow/interface/llms/base.py +++ b/src/backend/langflow/interface/llms/base.py @@ -3,7 +3,7 @@ from typing import Dict, List, Optional, Type from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import llm_type_to_cls_dict from langflow.settings import settings -from langflow.template.nodes import LLMFrontendNode +from langflow.template.frontend_node.llms import LLMFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/loading.py b/src/backend/langflow/interface/loading.py index bd2946a3e..cd6898a7f 100644 --- a/src/backend/langflow/interface/loading.py +++ b/src/backend/langflow/interface/loading.py @@ -152,10 +152,10 @@ def instantiate_utility(node_type, class_object, params): def load_flow_from_json(path: str, build=True): + """Load flow from json file""" # This is done to avoid circular imports from langflow.graph import Graph - """Load flow from json file""" with open(path, "r", encoding="utf-8") as f: flow_graph = json.load(f) data_graph = flow_graph["data"] diff --git a/src/backend/langflow/interface/memories/base.py b/src/backend/langflow/interface/memories/base.py index f26b09351..f0d8f88f5 100644 --- a/src/backend/langflow/interface/memories/base.py +++ b/src/backend/langflow/interface/memories/base.py @@ -3,8 +3,8 @@ from typing import Dict, List, Optional, Type from langflow.interface.base import LangChainTypeCreator from langflow.interface.custom_lists import memory_type_to_cls_dict from langflow.settings import settings -from langflow.template.base import FrontendNode -from langflow.template.nodes import MemoryFrontendNode +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.frontend_node.memories import MemoryFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/prompts/base.py b/src/backend/langflow/interface/prompts/base.py index 5f83a5412..39bd94c5b 100644 --- a/src/backend/langflow/interface/prompts/base.py +++ b/src/backend/langflow/interface/prompts/base.py @@ -6,7 +6,7 @@ from langflow.custom.customs import get_custom_nodes from langflow.interface.base import LangChainTypeCreator from langflow.interface.importing.utils import import_class from langflow.settings import settings -from langflow.template.nodes import PromptFrontendNode +from langflow.template.frontend_node.prompts import PromptFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/tools/base.py b/src/backend/langflow/interface/tools/base.py index 888accb29..a8e7045c0 100644 --- a/src/backend/langflow/interface/tools/base.py +++ b/src/backend/langflow/interface/tools/base.py @@ -16,7 +16,8 @@ from langflow.interface.tools.constants import ( ) from langflow.interface.tools.util import get_tool_params from langflow.settings import settings -from langflow.template.base import Template, TemplateField +from langflow.template.field.base import TemplateField +from langflow.template.template.base import Template from langflow.utils import util from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/utilities/base.py b/src/backend/langflow/interface/utilities/base.py index e60e344ad..6c12b0186 100644 --- a/src/backend/langflow/interface/utilities/base.py +++ b/src/backend/langflow/interface/utilities/base.py @@ -1,9 +1,12 @@ -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Type + +from langchain import SQLDatabase, utilities from langflow.custom.customs import get_custom_nodes from langflow.interface.base import LangChainTypeCreator -from langflow.interface.custom_lists import utility_type_to_cls_dict +from langflow.interface.importing.utils import import_class from langflow.settings import settings +from langflow.template.frontend_node.utilities import UtilitiesFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_class @@ -11,16 +14,39 @@ from langflow.utils.util import build_template_from_class class UtilityCreator(LangChainTypeCreator): type_name: str = "utilities" + @property + def frontend_node_class(self) -> Type[UtilitiesFrontendNode]: + return UtilitiesFrontendNode + @property def type_to_loader_dict(self) -> Dict: - return utility_type_to_cls_dict + """ + Returns a dictionary mapping utility names to their corresponding loader classes. + If the dictionary has not been created yet, it is created by importing all utility classes + from the langchain.chains module and filtering them according to the settings.utilities list. + """ + if self.type_dict is None: + self.type_dict = { + utility_name: import_class(f"langchain.utilities.{utility_name}") + for utility_name in utilities.__all__ + } + self.type_dict["SQLDatabase"] = SQLDatabase + # Filter according to settings.utilities + self.type_dict = { + name: utility + for name, utility in self.type_dict.items() + if name in settings.utilities or settings.dev + } + + return self.type_dict def get_signature(self, name: str) -> Optional[Dict]: """Get the signature of a utility.""" try: - if name in get_custom_nodes(self.type_name).keys(): - return get_custom_nodes(self.type_name)[name] - return build_template_from_class(name, utility_type_to_cls_dict) + custom_nodes = get_custom_nodes(self.type_name) + if name in custom_nodes.keys(): + return custom_nodes[name] + return build_template_from_class(name, self.type_to_loader_dict) except ValueError as exc: raise ValueError(f"Utility {name} not found") from exc @@ -29,11 +55,7 @@ class UtilityCreator(LangChainTypeCreator): return None def to_list(self) -> List[str]: - return [ - utility.__name__ - for utility in self.type_to_loader_dict.values() - if utility.__name__ in settings.utilities or settings.dev - ] + return list(self.type_to_loader_dict.keys()) utility_creator = UtilityCreator() diff --git a/src/backend/langflow/interface/utils.py b/src/backend/langflow/interface/utils.py index 7368fda3e..2b7c5acd1 100644 --- a/src/backend/langflow/interface/utils.py +++ b/src/backend/langflow/interface/utils.py @@ -44,7 +44,7 @@ def try_setting_streaming_options(langchain_object, websocket): langchain_object.llm_chain, "llm" ): llm = langchain_object.llm_chain.llm - if isinstance(llm, BaseLanguageModel): - llm.streaming = bool(hasattr(llm, "streaming")) + if isinstance(llm, BaseLanguageModel) and hasattr(llm, "streaming"): + llm.streaming = True return langchain_object diff --git a/src/backend/langflow/interface/vector_store/base.py b/src/backend/langflow/interface/vector_store/base.py index d30563d7b..7ec1e0f5b 100644 --- a/src/backend/langflow/interface/vector_store/base.py +++ b/src/backend/langflow/interface/vector_store/base.py @@ -5,7 +5,7 @@ from langchain import vectorstores from langflow.interface.base import LangChainTypeCreator from langflow.interface.importing.utils import import_class from langflow.settings import settings -from langflow.template.nodes import VectorStoreFrontendNode +from langflow.template.frontend_node.vectorstores import VectorStoreFrontendNode from langflow.utils.logger import logger from langflow.utils.util import build_template_from_method diff --git a/src/backend/langflow/template/base.py b/src/backend/langflow/template/base.py index 76b544974..8b1378917 100644 --- a/src/backend/langflow/template/base.py +++ b/src/backend/langflow/template/base.py @@ -1,255 +1 @@ -import re -from abc import ABC -from typing import Any, Callable, List, Optional, Union -from pydantic import BaseModel - -from langflow.template.constants import FORCE_SHOW_FIELDS -from langflow.utils import constants - - -class TemplateFieldCreator(BaseModel, ABC): - field_type: str = "str" - required: bool = False - placeholder: str = "" - is_list: bool = False - show: bool = True - multiline: bool = False - value: Any = None - suffixes: list[str] = [] - fileTypes: list[str] = [] - file_types: list[str] = [] - content: Union[str, None] = None - password: bool = False - options: list[str] = [] - name: str = "" - display_name: Optional[str] = None - advanced: bool = False - - def to_dict(self): - result = self.dict() - # Remove key if it is None - for key in list(result.keys()): - if result[key] is None or result[key] == []: - del result[key] - result["type"] = result.pop("field_type") - result["list"] = result.pop("is_list") - - if result.get("file_types"): - result["fileTypes"] = result.pop("file_types") - - if self.field_type == "file": - result["content"] = self.content - return result - - -class TemplateField(TemplateFieldCreator): - pass - - -class Template(BaseModel): - type_name: str - fields: list[TemplateField] - - def process_fields( - self, - name: Optional[str] = None, - format_field_func: Union[Callable, None] = None, - ): - if format_field_func: - for field in self.fields: - format_field_func(field, name) - - def to_dict(self, format_field_func=None): - self.process_fields(self.type_name, format_field_func) - result = {field.name: field.to_dict() for field in self.fields} - result["_type"] = self.type_name # type: ignore - return result - - -class FrontendNode(BaseModel): - template: Template - description: str - base_classes: List[str] - name: str = "" - - def to_dict(self) -> dict: - return { - self.name: { - "template": self.template.to_dict(self.format_field), - "description": self.description, - "base_classes": self.base_classes, - } - } - - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - """Formats a given field based on its attributes and value.""" - SPECIAL_FIELD_HANDLERS = { - "allowed_tools": lambda field: "Tool", - "max_value_length": lambda field: "int", - } - - key = field.name - value = field.to_dict() - _type = value["type"] - - _type = FrontendNode.remove_optional(_type) - _type, is_list = FrontendNode.check_for_list_type(_type) - field.is_list = is_list or field.is_list - _type = FrontendNode.replace_mapping_with_dict(_type) - _type = FrontendNode.handle_union_type(_type) - - field.field_type = FrontendNode.handle_special_field( - field, key, _type, SPECIAL_FIELD_HANDLERS - ) - field.field_type = FrontendNode.handle_dict_type(field, _type) - field.show = FrontendNode.should_show_field(key, field.required) - field.password = FrontendNode.should_be_password(key, field.show) - field.multiline = FrontendNode.should_be_multiline(key) - - FrontendNode.replace_default_value(field, value) - FrontendNode.handle_specific_field_values(field, key, name) - FrontendNode.handle_kwargs_field(field) - FrontendNode.handle_api_key_field(field, key) - - @staticmethod - def remove_optional(_type: str) -> str: - """Removes 'Optional' wrapper from the type if present.""" - return re.sub(r"Optional\[(.*)\]", r"\1", _type) - - @staticmethod - def check_for_list_type(_type: str) -> tuple: - """Checks for list type and returns the modified type and a boolean indicating if it's a list.""" - is_list = "List" in _type or "Sequence" in _type - if is_list: - _type = re.sub(r"(List|Sequence)\[(.*)\]", r"\2", _type) - return _type, is_list - - @staticmethod - def replace_mapping_with_dict(_type: str) -> str: - """Replaces 'Mapping' with 'dict'.""" - return _type.replace("Mapping", "dict") - - @staticmethod - def handle_union_type(_type: str) -> str: - """Simplifies the 'Union' type to the first type in the Union.""" - if "Union" in _type: - _type = _type.replace("Union[", "")[:-1] - _type = _type.split(",")[0] - _type = _type.replace("]", "").replace("[", "") - return _type - - @staticmethod - def handle_special_field( - field, key: str, _type: str, SPECIAL_FIELD_HANDLERS - ) -> str: - """Handles special field by using the respective handler if present.""" - handler = SPECIAL_FIELD_HANDLERS.get(key) - return handler(field) if handler else _type - - @staticmethod - def handle_dict_type(field: TemplateField, _type: str) -> str: - """Handles 'dict' type by replacing it with 'code' or 'file' based on the field name.""" - if "dict" in _type.lower(): - if field.name == "dict_": - field.field_type = "file" - field.suffixes = [".json", ".yaml", ".yml"] - field.file_types = ["json", "yaml", "yml"] - else: - field.field_type = "code" - return _type - - @staticmethod - def replace_default_value(field: TemplateField, value: dict) -> None: - """Replaces default value with actual value if 'default' is present in value.""" - if "default" in value: - field.value = value["default"] - - @staticmethod - def handle_specific_field_values( - field: TemplateField, key: str, name: Optional[str] = None - ) -> None: - """Handles specific field values for certain fields.""" - if key == "headers": - field.value = """{'Authorization': - 'Bearer '}""" - if name == "OpenAI" and key == "model_name": - field.options = constants.OPENAI_MODELS - field.is_list = True - elif name == "ChatOpenAI" and key == "model_name": - field.options = constants.CHAT_OPENAI_MODELS - field.is_list = True - if "api_key" in key and "OpenAI" in str(name): - field.display_name = "OpenAI API Key" - field.required = False - if field.value is None: - field.value = "" - - @staticmethod - def handle_kwargs_field(field: TemplateField) -> None: - """Handles kwargs field by setting certain attributes.""" - if "kwargs" in field.name.lower(): - field.advanced = True - field.required = False - field.show = False - - @staticmethod - def handle_api_key_field(field: TemplateField, key: str) -> None: - """Handles api key field by setting certain attributes.""" - if "api" in key.lower() and "key" in key.lower(): - field.required = False - field.advanced = False - - @staticmethod - def should_show_field(key: str, required: bool) -> bool: - """Determines whether the field should be shown.""" - return ( - (required and key not in ["input_variables"]) - or key in FORCE_SHOW_FIELDS - or "api" in key - or ("key" in key and "input" not in key and "output" not in key) - ) - - @staticmethod - def should_be_password(key: str, show: bool) -> bool: - """Determines whether the field should be a password field.""" - return ( - any(text in key.lower() for text in {"password", "token", "api", "key"}) - and show - ) - - @staticmethod - def should_be_multiline(key: str) -> bool: - """Determines whether the field should be multiline.""" - return key in { - "suffix", - "prefix", - "template", - "examples", - "code", - "headers", - "description", - } - - @staticmethod - def replace_dict_with_code_or_file( - field: TemplateField, _type: str, key: str - ) -> str: - """Replaces 'dict' type with 'code' or 'file'.""" - if "dict" in _type.lower(): - if key == "dict_": - field.field_type = "file" - field.suffixes = [".json", ".yaml", ".yml"] - field.file_types = ["json", "yaml", "yml"] - else: - field.field_type = "code" - return field.field_type - - @staticmethod - def set_field_default_value(field: TemplateField, value: dict, key: str) -> None: - """Sets the field value with the default value if present.""" - if "default" in value: - field.value = value["default"] - if key == "headers": - field.value = """{'Authorization': 'Bearer '}""" diff --git a/src/backend/langflow/template/field/__init__.py b/src/backend/langflow/template/field/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/langflow/template/field/base.py b/src/backend/langflow/template/field/base.py new file mode 100644 index 000000000..a1de2c1b6 --- /dev/null +++ b/src/backend/langflow/template/field/base.py @@ -0,0 +1,43 @@ +from abc import ABC +from typing import Any, Optional, Union + +from pydantic import BaseModel + + +class TemplateFieldCreator(BaseModel, ABC): + field_type: str = "str" + required: bool = False + placeholder: str = "" + is_list: bool = False + show: bool = True + multiline: bool = False + value: Any = None + suffixes: list[str] = [] + fileTypes: list[str] = [] + file_types: list[str] = [] + content: Union[str, None] = None + password: bool = False + options: list[str] = [] + name: str = "" + display_name: Optional[str] = None + advanced: bool = False + + def to_dict(self): + result = self.dict() + # Remove key if it is None + for key in list(result.keys()): + if result[key] is None or result[key] == []: + del result[key] + result["type"] = result.pop("field_type") + result["list"] = result.pop("is_list") + + if result.get("file_types"): + result["fileTypes"] = result.pop("file_types") + + if self.field_type == "file": + result["content"] = self.content + return result + + +class TemplateField(TemplateFieldCreator): + pass diff --git a/src/backend/langflow/template/frontend_node/__init__.py b/src/backend/langflow/template/frontend_node/__init__.py new file mode 100644 index 000000000..1aa946d41 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/__init__.py @@ -0,0 +1,21 @@ +from langflow.template.frontend_node import ( + agents, + chains, + embeddings, + llms, + memories, + prompts, + tools, + vectorstores, +) + +__all__ = [ + "agents", + "chains", + "embeddings", + "memories", + "tools", + "llms", + "prompts", + "vectorstores", +] diff --git a/src/backend/langflow/template/frontend_node/agents.py b/src/backend/langflow/template/frontend_node/agents.py new file mode 100644 index 000000000..e4fe40187 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/agents.py @@ -0,0 +1,233 @@ +from typing import Optional + +from langchain.agents import types + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template + +NON_CHAT_AGENTS = { + agent_type: agent_class + for agent_type, agent_class in types.AGENT_TO_CLASS.items() + if "chat" not in agent_type.value +} + + +class SQLAgentNode(FrontendNode): + name: str = "SQLAgent" + template: Template = Template( + type_name="sql_agent", + fields=[ + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=False, + value="", + name="database_uri", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct a sql agent from an LLM and tools.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() + + +class VectorStoreRouterAgentNode(FrontendNode): + name: str = "VectorStoreRouterAgent" + template: Template = Template( + type_name="vectorstorerouter_agent", + fields=[ + TemplateField( + field_type="VectorStoreRouterToolkit", + required=True, + show=True, + name="vectorstoreroutertoolkit", + display_name="Vector Store Router Toolkit", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct an agent from a Vector Store Router.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() + + +class VectorStoreAgentNode(FrontendNode): + name: str = "VectorStoreAgent" + template: Template = Template( + type_name="vectorstore_agent", + fields=[ + TemplateField( + field_type="VectorStoreInfo", + required=True, + show=True, + name="vectorstoreinfo", + display_name="Vector Store Info", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct an agent from a Vector Store.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() + + +class SQLDatabaseNode(FrontendNode): + name: str = "SQLDatabase" + template: Template = Template( + type_name="sql_database", + fields=[ + TemplateField( + field_type="str", + required=True, + is_list=False, + show=True, + multiline=False, + value="", + name="uri", + ), + ], + ) + description: str = """SQLAlchemy wrapper around a database.""" + base_classes: list[str] = ["SQLDatabase"] + + def to_dict(self): + return super().to_dict() + + +class CSVAgentNode(FrontendNode): + name: str = "CSVAgent" + template: Template = Template( + type_name="csv_agent", + fields=[ + TemplateField( + field_type="file", + required=True, + show=True, + name="path", + value="", + suffixes=[".csv"], + fileTypes=["csv"], + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct a json agent from a CSV and tools.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() + + +class InitializeAgentNode(FrontendNode): + name: str = "initialize_agent" + template: Template = Template( + type_name="initailize_agent", + fields=[ + TemplateField( + field_type="str", + required=True, + is_list=True, + show=True, + multiline=False, + options=list(NON_CHAT_AGENTS.keys()), + value=list(NON_CHAT_AGENTS.keys())[0], + name="agent", + advanced=False, + ), + TemplateField( + field_type="BaseChatMemory", + required=False, + show=True, + name="memory", + advanced=False, + ), + TemplateField( + field_type="Tool", + required=False, + show=True, + name="tools", + is_list=True, + advanced=False, + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + advanced=False, + ), + ], + ) + description: str = """Construct a json agent from an LLM and tools.""" + base_classes: list[str] = ["AgentExecutor", "function"] + + def to_dict(self): + return super().to_dict() + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + # do nothing and don't return anything + pass + + +class JsonAgentNode(FrontendNode): + name: str = "JsonAgent" + template: Template = Template( + type_name="json_agent", + fields=[ + TemplateField( + field_type="BaseToolkit", + required=True, + show=True, + name="toolkit", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + show=True, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = """Construct a json agent from an LLM and tools.""" + base_classes: list[str] = ["AgentExecutor"] + + def to_dict(self): + return super().to_dict() diff --git a/src/backend/langflow/template/frontend_node/base.py b/src/backend/langflow/template/frontend_node/base.py new file mode 100644 index 000000000..2714cd4ae --- /dev/null +++ b/src/backend/langflow/template/frontend_node/base.py @@ -0,0 +1,200 @@ +import re +from typing import List, Optional + +from pydantic import BaseModel + +from langflow.template.constants import FORCE_SHOW_FIELDS +from langflow.template.field.base import TemplateField +from langflow.template.template.base import Template +from langflow.utils import constants + + +class FrontendNode(BaseModel): + template: Template + description: str + base_classes: List[str] + name: str = "" + + def to_dict(self) -> dict: + return { + self.name: { + "template": self.template.to_dict(self.format_field), + "description": self.description, + "base_classes": self.base_classes, + } + } + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + """Formats a given field based on its attributes and value.""" + SPECIAL_FIELD_HANDLERS = { + "allowed_tools": lambda field: "Tool", + "max_value_length": lambda field: "int", + } + + key = field.name + value = field.to_dict() + _type = value["type"] + + _type = FrontendNode.remove_optional(_type) + _type, is_list = FrontendNode.check_for_list_type(_type) + field.is_list = is_list or field.is_list + _type = FrontendNode.replace_mapping_with_dict(_type) + _type = FrontendNode.handle_union_type(_type) + + field.field_type = FrontendNode.handle_special_field( + field, key, _type, SPECIAL_FIELD_HANDLERS + ) + field.field_type = FrontendNode.handle_dict_type(field, _type) + field.show = FrontendNode.should_show_field(key, field.required) + field.password = FrontendNode.should_be_password(key, field.show) + field.multiline = FrontendNode.should_be_multiline(key) + + FrontendNode.replace_default_value(field, value) + FrontendNode.handle_specific_field_values(field, key, name) + FrontendNode.handle_kwargs_field(field) + FrontendNode.handle_api_key_field(field, key) + + @staticmethod + def remove_optional(_type: str) -> str: + """Removes 'Optional' wrapper from the type if present.""" + return re.sub(r"Optional\[(.*)\]", r"\1", _type) + + @staticmethod + def check_for_list_type(_type: str) -> tuple: + """Checks for list type and returns the modified type and a boolean indicating if it's a list.""" + is_list = "List" in _type or "Sequence" in _type + if is_list: + _type = re.sub(r"(List|Sequence)\[(.*)\]", r"\2", _type) + return _type, is_list + + @staticmethod + def replace_mapping_with_dict(_type: str) -> str: + """Replaces 'Mapping' with 'dict'.""" + return _type.replace("Mapping", "dict") + + @staticmethod + def handle_union_type(_type: str) -> str: + """Simplifies the 'Union' type to the first type in the Union.""" + if "Union" in _type: + _type = _type.replace("Union[", "")[:-1] + _type = _type.split(",")[0] + _type = _type.replace("]", "").replace("[", "") + return _type + + @staticmethod + def handle_special_field( + field, key: str, _type: str, SPECIAL_FIELD_HANDLERS + ) -> str: + """Handles special field by using the respective handler if present.""" + handler = SPECIAL_FIELD_HANDLERS.get(key) + return handler(field) if handler else _type + + @staticmethod + def handle_dict_type(field: TemplateField, _type: str) -> str: + """Handles 'dict' type by replacing it with 'code' or 'file' based on the field name.""" + if "dict" in _type.lower(): + if field.name == "dict_": + field.field_type = "file" + field.suffixes = [".json", ".yaml", ".yml"] + field.file_types = ["json", "yaml", "yml"] + else: + field.field_type = "code" + return _type + + @staticmethod + def replace_default_value(field: TemplateField, value: dict) -> None: + """Replaces default value with actual value if 'default' is present in value.""" + if "default" in value: + field.value = value["default"] + + @staticmethod + def handle_specific_field_values( + field: TemplateField, key: str, name: Optional[str] = None + ) -> None: + """Handles specific field values for certain fields.""" + if key == "headers": + field.value = """{'Authorization': + 'Bearer '}""" + if name == "OpenAI" and key == "model_name": + field.options = constants.OPENAI_MODELS + field.is_list = True + elif name == "ChatOpenAI" and key == "model_name": + field.options = constants.CHAT_OPENAI_MODELS + field.is_list = True + if "api_key" in key and "OpenAI" in str(name): + field.display_name = "OpenAI API Key" + field.required = False + if field.value is None: + field.value = "" + + @staticmethod + def handle_kwargs_field(field: TemplateField) -> None: + """Handles kwargs field by setting certain attributes.""" + if "kwargs" in field.name.lower(): + field.advanced = True + field.required = False + field.show = False + + @staticmethod + def handle_api_key_field(field: TemplateField, key: str) -> None: + """Handles api key field by setting certain attributes.""" + if "api" in key.lower() and "key" in key.lower(): + field.required = False + field.advanced = False + + field.display_name = key.replace("_", " ").title() + field.display_name = field.display_name.replace("Api", "API") + + @staticmethod + def should_show_field(key: str, required: bool) -> bool: + """Determines whether the field should be shown.""" + return ( + (required and key not in ["input_variables"]) + or key in FORCE_SHOW_FIELDS + or "api" in key + or ("key" in key and "input" not in key and "output" not in key) + ) + + @staticmethod + def should_be_password(key: str, show: bool) -> bool: + """Determines whether the field should be a password field.""" + return ( + any(text in key.lower() for text in {"password", "token", "api", "key"}) + and show + ) + + @staticmethod + def should_be_multiline(key: str) -> bool: + """Determines whether the field should be multiline.""" + return key in { + "suffix", + "prefix", + "template", + "examples", + "code", + "headers", + "description", + } + + @staticmethod + def replace_dict_with_code_or_file( + field: TemplateField, _type: str, key: str + ) -> str: + """Replaces 'dict' type with 'code' or 'file'.""" + if "dict" in _type.lower(): + if key == "dict_": + field.field_type = "file" + field.suffixes = [".json", ".yaml", ".yml"] + field.file_types = ["json", "yaml", "yml"] + else: + field.field_type = "code" + return field.field_type + + @staticmethod + def set_field_default_value(field: TemplateField, value: dict, key: str) -> None: + """Sets the field value with the default value if present.""" + if "default" in value: + field.value = value["default"] + if key == "headers": + field.value = """{'Authorization': 'Bearer '}""" diff --git a/src/backend/langflow/template/frontend_node/chains.py b/src/backend/langflow/template/frontend_node/chains.py new file mode 100644 index 000000000..cfcda2ef4 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/chains.py @@ -0,0 +1,157 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template + + +class ChainFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + + field.advanced = False + if "key" in field.name: + field.password = False + field.show = False + if field.name in ["input_key", "output_key"]: + field.required = True + field.show = True + field.advanced = True + + # Separated for possible future changes + if field.name == "prompt" and field.value is None: + field.required = True + field.show = True + field.advanced = False + if field.name == "memory": + field.required = False + field.show = True + field.advanced = False + if field.name == "verbose": + field.required = False + field.show = True + field.advanced = True + if field.name == "llm": + field.required = True + field.show = True + field.advanced = False + + +class SeriesCharacterChainNode(FrontendNode): + name: str = "SeriesCharacterChain" + template: Template = Template( + type_name="SeriesCharacterChain", + fields=[ + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="character", + ), + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="series", + ), + TemplateField( + field_type="BaseLanguageModel", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="llm", + display_name="LLM", + ), + ], + ) + description: str = "SeriesCharacterChain is a chain you can use to have a conversation with a character from a series." # noqa + base_classes: list[str] = [ + "LLMChain", + "BaseCustomChain", + "Chain", + "ConversationChain", + "SeriesCharacterChain", + "function", + ] + + +class TimeTravelGuideChainNode(FrontendNode): + name: str = "TimeTravelGuideChain" + template: Template = Template( + type_name="TimeTravelGuideChain", + fields=[ + TemplateField( + field_type="BaseLanguageModel", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="llm", + display_name="LLM", + ), + TemplateField( + field_type="BaseChatMemory", + required=False, + show=True, + name="memory", + advanced=False, + ), + ], + ) + description: str = "Time travel guide chain to be used in the flow." + base_classes: list[str] = [ + "LLMChain", + "BaseCustomChain", + "TimeTravelGuideChain", + "Chain", + "ConversationChain", + ] + + +class MidJourneyPromptChainNode(FrontendNode): + name: str = "MidJourneyPromptChain" + template: Template = Template( + type_name="MidJourneyPromptChain", + fields=[ + TemplateField( + field_type="BaseLanguageModel", + required=True, + placeholder="", + is_list=False, + show=True, + advanced=False, + multiline=False, + name="llm", + display_name="LLM", + ), + TemplateField( + field_type="BaseChatMemory", + required=False, + show=True, + name="memory", + advanced=False, + ), + ], + ) + description: str = "MidJourneyPromptChain is a chain you can use to generate new MidJourney prompts." + base_classes: list[str] = [ + "LLMChain", + "BaseCustomChain", + "Chain", + "ConversationChain", + "MidJourneyPromptChain", + ] diff --git a/src/backend/langflow/template/frontend_node/embeddings.py b/src/backend/langflow/template/frontend_node/embeddings.py new file mode 100644 index 000000000..d466b11a4 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/embeddings.py @@ -0,0 +1,51 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class EmbeddingFrontendNode(FrontendNode): + @staticmethod + def format_jina_fields(field: TemplateField): + if "jina" in field.name: + field.show = True + field.advanced = False + + if "auth" in field.name or "token" in field.name: + field.password = True + field.show = True + field.advanced = False + + if field.name == "jina_api_url": + field.show = True + field.advanced = True + field.display_name = "Jina API URL" + field.password = False + + @staticmethod + def format_openai_fields(field: TemplateField): + if "openai" in field.name: + field.show = True + field.advanced = True + split_name = field.name.split("_") + title_name = " ".join([s.capitalize() for s in split_name]) + field.display_name = title_name.replace("Openai", "OpenAI").replace( + "Api", "API" + ) + + if "api_key" in field.name: + field.password = True + field.show = True + field.advanced = False + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + field.advanced = not field.required + field.show = True + if field.name == "headers": + field.show = False + + # Format Jina fields + EmbeddingFrontendNode.format_jina_fields(field) + EmbeddingFrontendNode.format_openai_fields(field) diff --git a/src/backend/langflow/template/frontend_node/llms.py b/src/backend/langflow/template/frontend_node/llms.py new file mode 100644 index 000000000..4dc32dff1 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/llms.py @@ -0,0 +1,50 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class LLMFrontendNode(FrontendNode): + @staticmethod + def format_openai_field(field: TemplateField): + if "openai" in field.name.lower(): + field.display_name = ( + field.name.title().replace("Openai", "OpenAI").replace("_", " ") + ).replace("Api", "API") + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + display_names_dict = { + "huggingfacehub_api_token": "HuggingFace Hub API Token", + } + FrontendNode.format_field(field, name) + SHOW_FIELDS = ["repo_id"] + if field.name in SHOW_FIELDS: + field.show = True + + if "api" in field.name and ("key" in field.name or "token" in field.name): + field.password = True + field.show = True + # Required should be False to support + # loading the API key from environment variables + field.required = False + field.advanced = False + + if field.name == "task": + field.required = True + field.show = True + field.is_list = True + field.options = ["text-generation", "text2text-generation"] + field.advanced = True + + if display_name := display_names_dict.get(field.name): + field.display_name = display_name + if field.name == "model_kwargs": + field.field_type = "code" + field.advanced = True + field.show = True + elif field.name in ["model_name", "temperature"]: + field.advanced = False + field.show = True + + LLMFrontendNode.format_openai_field(field) diff --git a/src/backend/langflow/template/frontend_node/memories.py b/src/backend/langflow/template/frontend_node/memories.py new file mode 100644 index 000000000..91d892627 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/memories.py @@ -0,0 +1,20 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class MemoryFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + + if not isinstance(field.value, str): + field.value = None + if field.name == "k": + field.required = True + field.show = True + field.field_type = "int" + field.value = 10 + field.display_name = "Memory Size" + field.password = False diff --git a/src/backend/langflow/template/frontend_node/prompts.py b/src/backend/langflow/template/frontend_node/prompts.py new file mode 100644 index 000000000..830623a7e --- /dev/null +++ b/src/backend/langflow/template/frontend_node/prompts.py @@ -0,0 +1,111 @@ +from typing import Optional + +from langchain.agents.mrkl import prompt + +from langflow.template.constants import DEFAULT_PROMPT, HUMAN_PROMPT, SYSTEM_PROMPT +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template + + +class PromptFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + # if field.field_type == "StringPromptTemplate" + # change it to str + PROMPT_FIELDS = [ + "template", + "suffix", + "prefix", + "examples", + "format_instructions", + ] + if field.field_type == "StringPromptTemplate" and "Message" in str(name): + field.field_type = "prompt" + field.multiline = True + field.value = HUMAN_PROMPT if "Human" in field.name else SYSTEM_PROMPT + if field.name == "template" and field.value == "": + field.value = DEFAULT_PROMPT + + if field.name in PROMPT_FIELDS: + field.field_type = "prompt" + field.advanced = False + + if ( + "Union" in field.field_type + and "BaseMessagePromptTemplate" in field.field_type + ): + field.field_type = "BaseMessagePromptTemplate" + + # All prompt fields should be password=False + field.password = False + + +class PromptTemplateNode(FrontendNode): + name: str = "PromptTemplate" + template: Template + description: str + base_classes: list[str] = ["BasePromptTemplate"] + + def to_dict(self): + return super().to_dict() + + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + if field.name == "examples": + field.advanced = False + + +class BasePromptFrontendNode(FrontendNode): + name: str + template: Template + description: str + base_classes: list[str] + + def to_dict(self): + return super().to_dict() + + +class ZeroShotPromptNode(BasePromptFrontendNode): + name: str = "ZeroShotPrompt" + template: Template = Template( + type_name="zero_shot", + fields=[ + TemplateField( + field_type="str", + required=False, + placeholder="", + is_list=False, + show=True, + multiline=True, + value=prompt.PREFIX, + name="prefix", + ), + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=True, + value=prompt.SUFFIX, + name="suffix", + ), + TemplateField( + field_type="str", + required=False, + placeholder="", + is_list=False, + show=True, + multiline=True, + value=prompt.FORMAT_INSTRUCTIONS, + name="format_instructions", + ), + ], + ) + description: str = "Prompt template for Zero Shot Agent." + base_classes: list[str] = ["BasePromptTemplate"] + + def to_dict(self): + return super().to_dict() diff --git a/src/backend/langflow/template/frontend_node/tools.py b/src/backend/langflow/template/frontend_node/tools.py new file mode 100644 index 000000000..2819be4d9 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/tools.py @@ -0,0 +1,83 @@ +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode +from langflow.template.template.base import Template +from langflow.utils.constants import DEFAULT_PYTHON_FUNCTION + + +class ToolNode(FrontendNode): + name: str = "Tool" + template: Template = Template( + type_name="Tool", + fields=[ + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=True, + value="", + name="name", + advanced=False, + ), + TemplateField( + field_type="str", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=True, + value="", + name="description", + advanced=False, + ), + TemplateField( + name="func", + field_type="function", + required=True, + is_list=False, + show=True, + multiline=True, + advanced=False, + ), + TemplateField( + field_type="bool", + required=True, + placeholder="", + is_list=False, + show=True, + multiline=False, + value=False, + name="return_direct", + ), + ], + ) + description: str = "Tool to be used in the flow." + base_classes: list[str] = ["Tool"] + + def to_dict(self): + return super().to_dict() + + +class PythonFunctionNode(FrontendNode): + name: str = "PythonFunction" + template: Template = Template( + type_name="python_function", + fields=[ + TemplateField( + field_type="code", + required=True, + placeholder="", + is_list=False, + show=True, + value=DEFAULT_PYTHON_FUNCTION, + name="code", + advanced=False, + ) + ], + ) + description: str = "Python function to be executed." + base_classes: list[str] = ["function"] + + def to_dict(self): + return super().to_dict() diff --git a/src/backend/langflow/template/frontend_node/utilities.py b/src/backend/langflow/template/frontend_node/utilities.py new file mode 100644 index 000000000..77d01a23e --- /dev/null +++ b/src/backend/langflow/template/frontend_node/utilities.py @@ -0,0 +1,21 @@ +import json +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class UtilitiesFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + # field.field_type could be "Literal['news', 'search', 'places', 'images'] + # we need to convert it to a list + if "Literal" in field.field_type: + field.options = eval(field.field_type.replace("Literal", "")) + field.is_list = True + field.field_type = "str" + + if isinstance(field.value, dict): + field.field_type = "code" + field.value = json.dumps(field.value, indent=4) diff --git a/src/backend/langflow/template/frontend_node/vectorstores.py b/src/backend/langflow/template/frontend_node/vectorstores.py new file mode 100644 index 000000000..76f623852 --- /dev/null +++ b/src/backend/langflow/template/frontend_node/vectorstores.py @@ -0,0 +1,64 @@ +from typing import Optional + +from langflow.template.field.base import TemplateField +from langflow.template.frontend_node.base import FrontendNode + + +class VectorStoreFrontendNode(FrontendNode): + @staticmethod + def format_field(field: TemplateField, name: Optional[str] = None) -> None: + FrontendNode.format_field(field, name) + # Define common field attributes + basic_fields = ["work_dir", "collection_name", "api_key", "location"] + advanced_fields = [ + "n_dim", + "key", + "prefix", + "distance_func", + "content_payload_key", + "metadata_payload_key", + "timeout", + "host", + "path", + "url", + "port", + "https", + "prefer_grpc", + "grpc_port", + ] + + # Check and set field attributes + if field.name == "texts": + field.name = "documents" + field.field_type = "TextSplitter" + field.display_name = "Text Splitter" + field.required = True + field.show = True + field.advanced = False + + elif "embedding" in field.name: + # for backwards compatibility + field.name = "embedding" + field.required = True + field.show = True + field.advanced = False + field.display_name = "Embedding" + field.field_type = "Embeddings" + + elif field.name in basic_fields: + field.show = True + field.advanced = False + if field.name == "api_key": + field.display_name = "API Key" + field.password = True + elif field.name == "location": + field.value = ":memory:" + field.placeholder = ":memory:" + + elif field.name in advanced_fields: + field.show = True + field.advanced = True + if "key" in field.name: + field.password = False + # TODO: Weaviate requires weaviate_url to be passed as it is not part of + # the class or from_texts method. We need the add_extra_fields to fix this diff --git a/src/backend/langflow/template/nodes.py b/src/backend/langflow/template/nodes.py index d19cae612..8b1378917 100644 --- a/src/backend/langflow/template/nodes.py +++ b/src/backend/langflow/template/nodes.py @@ -1,691 +1 @@ -from typing import Optional -from langchain.agents import loading -from langchain.agents.mrkl import prompt - -from langflow.template.base import FrontendNode, Template, TemplateField -from langflow.template.constants import DEFAULT_PROMPT, HUMAN_PROMPT, SYSTEM_PROMPT -from langflow.utils.constants import DEFAULT_PYTHON_FUNCTION - -NON_CHAT_AGENTS = { - agent_type: agent_class - for agent_type, agent_class in loading.AGENT_TO_CLASS.items() - if "chat" not in agent_type.value -} - - -class BasePromptFrontendNode(FrontendNode): - name: str - template: Template - description: str - base_classes: list[str] - - def to_dict(self): - return super().to_dict() - - -class ZeroShotPromptNode(BasePromptFrontendNode): - name: str = "ZeroShotPrompt" - template: Template = Template( - type_name="zero_shot", - fields=[ - TemplateField( - field_type="str", - required=False, - placeholder="", - is_list=False, - show=True, - multiline=True, - value=prompt.PREFIX, - name="prefix", - ), - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=True, - value=prompt.SUFFIX, - name="suffix", - ), - TemplateField( - field_type="str", - required=False, - placeholder="", - is_list=False, - show=True, - multiline=True, - value=prompt.FORMAT_INSTRUCTIONS, - name="format_instructions", - ), - ], - ) - description: str = "Prompt template for Zero Shot Agent." - base_classes: list[str] = ["BasePromptTemplate"] - - def to_dict(self): - return super().to_dict() - - -class PromptTemplateNode(FrontendNode): - name: str = "PromptTemplate" - template: Template - description: str - base_classes: list[str] = ["BasePromptTemplate"] - - def to_dict(self): - return super().to_dict() - - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - if field.name == "examples": - field.advanced = False - - -class PythonFunctionNode(FrontendNode): - name: str = "PythonFunction" - template: Template = Template( - type_name="python_function", - fields=[ - TemplateField( - field_type="code", - required=True, - placeholder="", - is_list=False, - show=True, - value=DEFAULT_PYTHON_FUNCTION, - name="code", - advanced=False, - ) - ], - ) - description: str = "Python function to be executed." - base_classes: list[str] = ["function"] - - def to_dict(self): - return super().to_dict() - - -class MidJourneyPromptChainNode(FrontendNode): - name: str = "MidJourneyPromptChain" - template: Template = Template( - type_name="MidJourneyPromptChain", - fields=[ - TemplateField( - field_type="BaseLanguageModel", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="llm", - display_name="LLM", - ), - TemplateField( - field_type="BaseChatMemory", - required=False, - show=True, - name="memory", - advanced=False, - ), - ], - ) - description: str = "MidJourneyPromptChain is a chain you can use to generate new MidJourney prompts." - base_classes: list[str] = [ - "LLMChain", - "BaseCustomChain", - "Chain", - "ConversationChain", - "MidJourneyPromptChain", - ] - - -class TimeTravelGuideChainNode(FrontendNode): - name: str = "TimeTravelGuideChain" - template: Template = Template( - type_name="TimeTravelGuideChain", - fields=[ - TemplateField( - field_type="BaseLanguageModel", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="llm", - display_name="LLM", - ), - TemplateField( - field_type="BaseChatMemory", - required=False, - show=True, - name="memory", - advanced=False, - ), - ], - ) - description: str = "Time travel guide chain to be used in the flow." - base_classes: list[str] = [ - "LLMChain", - "BaseCustomChain", - "TimeTravelGuideChain", - "Chain", - "ConversationChain", - ] - - -class SeriesCharacterChainNode(FrontendNode): - name: str = "SeriesCharacterChain" - template: Template = Template( - type_name="SeriesCharacterChain", - fields=[ - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="character", - ), - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="series", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - placeholder="", - is_list=False, - show=True, - advanced=False, - multiline=False, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = "SeriesCharacterChain is a chain you can use to have a conversation with a character from a series." # noqa - base_classes: list[str] = [ - "LLMChain", - "BaseCustomChain", - "Chain", - "ConversationChain", - "SeriesCharacterChain", - "function", - ] - - -class ToolNode(FrontendNode): - name: str = "Tool" - template: Template = Template( - type_name="Tool", - fields=[ - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=True, - value="", - name="name", - advanced=False, - ), - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=True, - value="", - name="description", - advanced=False, - ), - TemplateField( - name="func", - field_type="function", - required=True, - is_list=False, - show=True, - multiline=True, - advanced=False, - ), - TemplateField( - field_type="bool", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=False, - value=False, - name="return_direct", - ), - ], - ) - description: str = "Tool to be used in the flow." - base_classes: list[str] = ["Tool"] - - def to_dict(self): - return super().to_dict() - - -class JsonAgentNode(FrontendNode): - name: str = "JsonAgent" - template: Template = Template( - type_name="json_agent", - fields=[ - TemplateField( - field_type="BaseToolkit", - required=True, - show=True, - name="toolkit", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct a json agent from an LLM and tools.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class InitializeAgentNode(FrontendNode): - name: str = "initialize_agent" - template: Template = Template( - type_name="initailize_agent", - fields=[ - TemplateField( - field_type="str", - required=True, - is_list=True, - show=True, - multiline=False, - options=list(NON_CHAT_AGENTS.keys()), - value=list(NON_CHAT_AGENTS.keys())[0], - name="agent", - advanced=False, - ), - TemplateField( - field_type="BaseChatMemory", - required=False, - show=True, - name="memory", - advanced=False, - ), - TemplateField( - field_type="Tool", - required=False, - show=True, - name="tools", - is_list=True, - advanced=False, - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - advanced=False, - ), - ], - ) - description: str = """Construct a json agent from an LLM and tools.""" - base_classes: list[str] = ["AgentExecutor", "function"] - - def to_dict(self): - return super().to_dict() - - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - # do nothing and don't return anything - pass - - -class CSVAgentNode(FrontendNode): - name: str = "CSVAgent" - template: Template = Template( - type_name="csv_agent", - fields=[ - TemplateField( - field_type="file", - required=True, - show=True, - name="path", - value="", - suffixes=[".csv"], - fileTypes=["csv"], - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct a json agent from a CSV and tools.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class SQLDatabaseNode(FrontendNode): - name: str = "SQLDatabase" - template: Template = Template( - type_name="sql_database", - fields=[ - TemplateField( - field_type="str", - required=True, - is_list=False, - show=True, - multiline=False, - value="", - name="uri", - ), - ], - ) - description: str = """SQLAlchemy wrapper around a database.""" - base_classes: list[str] = ["SQLDatabase"] - - def to_dict(self): - return super().to_dict() - - -class VectorStoreAgentNode(FrontendNode): - name: str = "VectorStoreAgent" - template: Template = Template( - type_name="vectorstore_agent", - fields=[ - TemplateField( - field_type="VectorStoreInfo", - required=True, - show=True, - name="vectorstoreinfo", - display_name="Vector Store Info", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct an agent from a Vector Store.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class VectorStoreRouterAgentNode(FrontendNode): - name: str = "VectorStoreRouterAgent" - template: Template = Template( - type_name="vectorstorerouter_agent", - fields=[ - TemplateField( - field_type="VectorStoreRouterToolkit", - required=True, - show=True, - name="vectorstoreroutertoolkit", - display_name="Vector Store Router Toolkit", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct an agent from a Vector Store Router.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class SQLAgentNode(FrontendNode): - name: str = "SQLAgent" - template: Template = Template( - type_name="sql_agent", - fields=[ - TemplateField( - field_type="str", - required=True, - placeholder="", - is_list=False, - show=True, - multiline=False, - value="", - name="database_uri", - ), - TemplateField( - field_type="BaseLanguageModel", - required=True, - show=True, - name="llm", - display_name="LLM", - ), - ], - ) - description: str = """Construct an agent from a Vector Store Router.""" - base_classes: list[str] = ["AgentExecutor"] - - def to_dict(self): - return super().to_dict() - - -class PromptFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - # if field.field_type == "StringPromptTemplate" - # change it to str - PROMPT_FIELDS = [ - "template", - "suffix", - "prefix", - "examples", - "format_instructions", - ] - if field.field_type == "StringPromptTemplate" and "Message" in str(name): - field.field_type = "prompt" - field.multiline = True - field.value = HUMAN_PROMPT if "Human" in field.name else SYSTEM_PROMPT - if field.name == "template" and field.value == "": - field.value = DEFAULT_PROMPT - - if field.name in PROMPT_FIELDS: - field.field_type = "prompt" - field.advanced = False - - if ( - "Union" in field.field_type - and "BaseMessagePromptTemplate" in field.field_type - ): - field.field_type = "BaseMessagePromptTemplate" - - # All prompt fields should be password=False - field.password = False - - -class MemoryFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - - if not isinstance(field.value, str): - field.value = None - if field.name == "k": - field.required = True - field.show = True - field.field_type = "int" - field.value = 10 - field.display_name = "Memory Size" - field.password = False - - -class ChainFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - - field.advanced = False - if "key" in field.name: - field.password = False - field.show = False - if field.name in ["input_key", "output_key"]: - field.required = True - field.show = True - field.advanced = True - - # Separated for possible future changes - if field.name == "prompt" and field.value is None: - # if no prompt is provided, use the default prompt - field.required = False - field.show = True - field.advanced = False - if field.name == "memory": - field.required = False - field.show = True - field.advanced = False - if field.name == "verbose": - field.required = False - field.show = True - field.advanced = True - if field.name == "llm": - field.required = True - field.show = True - field.advanced = False - - -class LLMFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - display_names_dict = { - "huggingfacehub_api_token": "HuggingFace Hub API Token", - } - FrontendNode.format_field(field, name) - SHOW_FIELDS = ["repo_id"] - if field.name in SHOW_FIELDS: - field.show = True - - if "api" in field.name and ("key" in field.name or "token" in field.name): - field.password = True - field.show = True - # Required should be False to support - # loading the API key from environment variables - field.required = False - field.advanced = False - - if field.name == "task": - field.required = True - field.show = True - field.is_list = True - field.options = ["text-generation", "text2text-generation"] - field.advanced = True - - if display_name := display_names_dict.get(field.name): - field.display_name = display_name - if field.name == "model_kwargs": - field.field_type = "code" - field.advanced = True - field.show = True - elif field.name in ["model_name", "temperature"]: - field.advanced = False - field.show = True - - -class EmbeddingFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - if field.name == "headers": - field.show = False - - -class VectorStoreFrontendNode(FrontendNode): - @staticmethod - def format_field(field: TemplateField, name: Optional[str] = None) -> None: - FrontendNode.format_field(field, name) - # Define common field attributes - basic_fields = ["work_dir", "collection_name", "api_key", "location"] - advanced_fields = [ - "n_dim", - "key", - "prefix", - "distance_func", - "content_payload_key", - "metadata_payload_key", - "timeout", - "host", - "path", - "url", - "port", - "https", - "prefer_grpc", - "grpc_port", - ] - - # Check and set field attributes - if field.name == "texts": - field.name = "documents" - field.field_type = "TextSplitter" - field.display_name = "Text Splitter" - field.required = True - field.show = True - field.advanced = False - - elif "embedding" in field.name: - # for backwards compatibility - field.name = "embedding" - field.required = True - field.show = True - field.advanced = False - field.display_name = "Embedding" - field.field_type = "Embeddings" - - elif field.name in basic_fields: - field.show = True - field.advanced = False - if field.name == "api_key": - field.display_name = "API Key" - field.password = True - elif field.name == "location": - field.value = ":memory:" - field.placeholder = ":memory:" - - elif field.name in advanced_fields: - field.show = True - field.advanced = True - if "key" in field.name: - field.password = False - - # TODO: Weaviate requires weaviate_url to be passed as it is not part of - # the class or from_texts method. We need the add_extra_fields to fix this diff --git a/src/backend/langflow/template/template/__init__.py b/src/backend/langflow/template/template/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/langflow/template/template/base.py b/src/backend/langflow/template/template/base.py new file mode 100644 index 000000000..9279f5efb --- /dev/null +++ b/src/backend/langflow/template/template/base.py @@ -0,0 +1,25 @@ +from typing import Callable, Optional, Union + +from pydantic import BaseModel + +from langflow.template.field.base import TemplateField + + +class Template(BaseModel): + type_name: str + fields: list[TemplateField] + + def process_fields( + self, + name: Optional[str] = None, + format_field_func: Union[Callable, None] = None, + ): + if format_field_func: + for field in self.fields: + format_field_func(field, name) + + def to_dict(self, format_field_func=None): + self.process_fields(self.type_name, format_field_func) + result = {field.name: field.to_dict() for field in self.fields} + result["_type"] = self.type_name # type: ignore + return result diff --git a/src/backend/langflow/utils/util.py b/src/backend/langflow/utils/util.py index 9f2e53bc5..af49856d7 100644 --- a/src/backend/langflow/utils/util.py +++ b/src/backend/langflow/utils/util.py @@ -10,49 +10,6 @@ from langflow.template.constants import FORCE_SHOW_FIELDS from langflow.utils import constants -def build_template_from_parameters( - name: str, type_to_loader_dict: Dict, add_function: bool = False -): - # Retrieve the function that matches the provided name - func = None - for _, v in type_to_loader_dict.items(): - if v.__name__ == name: - func = v - break - - if func is None: - raise ValueError(f"{name} not found") - - # Process parameters - parameters = func.__annotations__ - variables = {} - for param_name, param_type in parameters.items(): - if param_name in ["return", "kwargs"]: - continue - - variables[param_name] = { - "type": param_type.__name__, - "default": parameters[param_name].__repr_args__()[0][1], - # Op - "placeholder": "", - } - - # Get the base classes of the return type - return_type = parameters.get("return") - base_classes = get_base_classes(return_type) if return_type else [] - if add_function: - base_classes.append("function") - - # Get the function's docstring - docs = inspect.getdoc(func) or "" - - return { - "template": format_dict(variables, name), - "description": docs["Description"], # type: ignore - "base_classes": base_classes, - } - - def build_template_from_function( name: str, type_to_loader_dict: Dict, add_function: bool = False ): diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 9d5ad3128..2df5e0c43 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -1,13 +1,17 @@ import { BugAntIcon, - CheckCircleIcon, Cog6ToothIcon, - EllipsisHorizontalCircleIcon, - ExclamationCircleIcon, InformationCircleIcon, TrashIcon, } from "@heroicons/react/24/outline"; -import { classNames, nodeColors, nodeIcons, toNormalCase } from "../../utils"; + +import { + CheckCircleIcon, + EllipsisHorizontalCircleIcon, + ExclamationCircleIcon, +} from "@heroicons/react/24/solid"; + +import { classNames, nodeColors, nodeIcons, toNormalCase, toTitleCase } from "../../utils"; import ParameterComponent from "./components/parameterComponent"; import { typesContext } from "../../contexts/typesContext"; import { useContext, useState, useEffect, useRef, Fragment } from "react"; @@ -102,7 +106,9 @@ export default function GenericNode({ color: nodeColors[types[data.type]] ?? nodeColors.unknown, }} /> -
{data.type}
+ +
{data.type}
+
{ + setOpen(true); + }} > - +
+
+
+
+
+
+ + {myModalTitle} + +
+
+
+
+
+