diff --git a/docs/description.md b/docs/description.md
index 2b982477f..69ed35c46 100644
--- a/docs/description.md
+++ b/docs/description.md
@@ -248,6 +248,34 @@ llama_new_context_with_model: total VRAM used: 4857.93 MB (model: 4095.05 MB, co
AVX = 1 | AVX2 = 1 | AVX512 = 0 | AVX512_VBMI = 0 | AVX512_VNNI = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 1 | SSSE3 = 0 | VSX = 0 |
```
+#### Vectorstores
+PrivateGPT supports [Chroma](https://www.trychroma.com/), [Qdrant](https://qdrant.tech/) as vectorstore providers. Chroma being the default.
+
+To enable Qdrant, set the `vectorstore.database` property in the `settings.yaml` file to `qdrant` and install the `qdrant` extra.
+
+```bash
+poetry install --extras qdrant
+```
+
+By default Qdrant tries to connect to an instance at `http://localhost:3000`.
+
+Qdrant settings can be configured by setting values to the `qdrant` propery in the `settings.yaml` file.
+
+The available configuration options are:
+| Field | Description |
+|--------------|-------------|
+| location | If `:memory:` - use in-memory Qdrant instance.
If `str` - use it as a `url` parameter.|
+| url | Either host or str of 'Optional[scheme], host, Optional[port], Optional[prefix]'.
Eg. `http://localhost:6333` |
+| port | Port of the REST API interface. Default: `6333` |
+| grpc_port | Port of the gRPC interface. Default: `6334` |
+| prefer_grpc | If `true` - use gRPC interface whenever possible in custom methods. |
+| https | If `true` - use HTTPS(SSL) protocol.|
+| api_key | API key for authentication in Qdrant Cloud.|
+| prefix | If set, add `prefix` to the REST URL path.
Example: `service/v1` will result in `http://localhost:6333/service/v1/{qdrant-endpoint}` for REST API.|
+| timeout | Timeout for REST and gRPC API requests.
Default: 5.0 seconds for REST and unlimited for gRPC |
+| host | Host name of Qdrant service. If url and host are not set, defaults to 'localhost'.|
+| path | Persistence path for QdrantLocal. Eg. `local_data/private_gpt/qdrant`|
+
#### Known issues and Troubleshooting
Execution of LLMs locally still has a lot of sharp edges, specially when running on non Linux platforms.
diff --git a/poetry.lock b/poetry.lock
index 91af264d3..2a2a6769a 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
[[package]]
name = "aiofiles"
@@ -1339,6 +1339,74 @@ files = [
[package.extras]
protobuf = ["grpcio-tools (>=1.59.2)"]
+[[package]]
+name = "grpcio-tools"
+version = "1.59.2"
+description = "Protobuf code generator for gRPC"
+optional = true
+python-versions = ">=3.7"
+files = [
+ {file = "grpcio-tools-1.59.2.tar.gz", hash = "sha256:75905266cf90f1866b322575c2edcd4b36532c33fc512bb1b380dc58d84b1030"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-linux_armv7l.whl", hash = "sha256:9b2885c0e2c9a97bde33497a919032afbd8b5c6dc2f8d4dd4198e77226e0de05"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2f410375830a9bb7140a07da4d75bf380e0958377bed50d77d1dae302de4314e"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:e21fc172522d2dda815223a359b2aca9bc317a1b5e5dea5a58cd5079333af133"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:072a7ce979ea4f7579c3c99fcbde3d1882c3d1942a3b51d159f67af83b714cd8"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b38f8edb2909702c2478b52f6213982c21e4f66f739ac953b91f97863ba2c06a"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:12fdee2de80d83eadb1294e0f8a0cb6cefcd2e4988ed680038ab09cd04361ee4"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a3cb707da722a0b6c4021fc2cc1c005a8d4037d8ad0252f93df318b9b8a6b4f3"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-win32.whl", hash = "sha256:ec2fbb02ebb9f2ae1b1c69cccf913dee8c41f5acad94014d3ce11b53720376e3"},
+ {file = "grpcio_tools-1.59.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0dc271a200dbab6547b2c73fcbdb7efe94c31cb633aa20d073f7cf4493493e1"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-linux_armv7l.whl", hash = "sha256:d634b65cc8ee769edccf1647d8a16861a27e0d8cbd787c711168d2c5e9bddbd1"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:b0b712acec00a9cbc2204c271d638062a2cb8ce74f25d158b023ff6e93182659"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:dd5c78f8e7c6e721b9009c92481a0e3b30a9926ef721120723a03b8a34a34fb9"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:724f4f0eecc17fa66216eebfff145631070f04ed7fb4ddf7a7d1c4f954ecc2a1"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77ec33ddee691e60511e2a7c793aad4cf172ae20e08d95c786cbba395f6203a7"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fa1b9dee7811fad081816e884d063c4dd4946dba61aa54243b4c76c311090c48"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ba8dba19e7b2b6f7369004533866f222ba483b9e14d2d152ecf9339c0df1283a"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-win32.whl", hash = "sha256:df35d145bc2f6e5f57b74cb69f66526675a5f2dcf7d54617ce0deff0c82cca0a"},
+ {file = "grpcio_tools-1.59.2-cp311-cp311-win_amd64.whl", hash = "sha256:99ddc0f5304071a355c261ae49ea5d29b9e9b6dcf422dfc55ada70a243e27e8f"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-linux_armv7l.whl", hash = "sha256:670f5889853215999eb3511a623dd7dff01b1ce1a64610d13366e0fd337f8c79"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:1e949e66d4555ce319fd7acef90df625138078d8729c4dc6f6a9f05925034433"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:09d809ca88999b2578119683f9f0f6a9b42de95ea21550852114a1540b6a642c"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db0925545180223fabd6da9b34513efac83aa16673ef8b1cb0cc678e8cf0923c"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2ccb59dfbf2ebd668a5a7c4b7bb2b859859641d2b199114b557cd045aac6102"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:12cc7698fad48866f68fdef831685cb31ef5814ac605d248c4e5fc964a6fb3f6"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:55c401599d5093c4cfa83b8f0ee9757b4d6d3029b10bd67be2cffeada7a44961"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-win32.whl", hash = "sha256:896f5cdf58f658025a4f7e4ea96c81183b4b6a4b1b4d92ae66d112ac91f062f1"},
+ {file = "grpcio_tools-1.59.2-cp312-cp312-win_amd64.whl", hash = "sha256:b53db1523015a3acda75722357df6c94afae37f6023800c608e09a5c05393804"},
+ {file = "grpcio_tools-1.59.2-cp37-cp37m-linux_armv7l.whl", hash = "sha256:d08b398509ea4d544bcecddd9a21f59dc556396916c3915904cac206af2db72b"},
+ {file = "grpcio_tools-1.59.2-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:09749e832e06493841000275248b031f7154665900d1e1b0e42fc17a64bf904d"},
+ {file = "grpcio_tools-1.59.2-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:e972746000aa192521715f776fab617a3437bed29e90fe0e0fd0d0d6f498d7d4"},
+ {file = "grpcio_tools-1.59.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cbeeb3d8ec4cb25c92e17bfbdcef3c3669e85c5ee787a6e581cb942bc0ae2b88"},
+ {file = "grpcio_tools-1.59.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed8e6632d8d839456332d97b96db10bd2dbf3078e728d063394ac2d54597ad80"},
+ {file = "grpcio_tools-1.59.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:531f87c8e884c6a2e58f040039dfbfe997a4e33baa58f7c7d9993db37b1f5ad0"},
+ {file = "grpcio_tools-1.59.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:feca316e17cfead823af6eae0fc20c0d5299a94d71cfb7531a0e92d050a5fb2f"},
+ {file = "grpcio_tools-1.59.2-cp37-cp37m-win_amd64.whl", hash = "sha256:41b5dd6a06c2563ac3b3adda6d875b15e63eb7b1629e85fc9af608c3a76c4c82"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-linux_armv7l.whl", hash = "sha256:7ec536cdae870a74080c665cfb1dca8d0784a931aa3c26376ef971a3a51b59d4"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:9c106ebbed0db446f59f0efe5c3fce33a0a21bf75b392966585e4b5934891b92"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:32141ef309543a446337e934f0b7a2565a6fca890ff4e543630a09ef72c8d00b"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f2ce5ecd63c492949b03af73b1dd6d502c567cc2f9c2057137e518b0c702a01"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a9ce2a209871ed1c5ae2229e6f4f5a3ea96d83b7871df5d9773d72a72545683"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7f0e26af7c07bfa906c91ca9f5932514928a7f032f5f20aecad6b5541037de7e"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:48782727c5cff8b8c96e028a8a58614ff6a37eadc0db85866516210c7aafe9ae"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-win32.whl", hash = "sha256:4a1810bc5de51cc162a19ed3c11da8ddc64d8cfcba049ef337c20fcb397f048b"},
+ {file = "grpcio_tools-1.59.2-cp38-cp38-win_amd64.whl", hash = "sha256:3cf9949a2aadcece3c1e0dd59249aea53dbfc8cc94f7d707797acd67cf6cf931"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-linux_armv7l.whl", hash = "sha256:f52e0ce8f2dcf1f160c847304016c446075a83ab925d98933d4681bfa8af2962"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:eb597d6bf9f5bfa54d00546e828f0d4e2c69250d1bc17c27903c0c7b66372135"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:17ef468836d7cf0b2419f4d5c7ac84ec2d598a1ae410773585313edacf7c393e"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dee5f7e7a56177234e61a483c70ca2ae34e73128372c801bb7039993870889f1"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f50ff312b88918c5a6461e45c5e03869749a066b1c24a7327e8e13e117efe4fc"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a85da4200295ee17e3c1ae068189a43844420ed7e9d531a042440f52de486dfb"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f518f22a3082de00f0d7a216e96366a87e6973111085ba1603c3bfa7dba2e728"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-win32.whl", hash = "sha256:6e735a26e8ea8bb89dc69343d1d00ea607449c6d81e21f339ee118562f3d1931"},
+ {file = "grpcio_tools-1.59.2-cp39-cp39-win_amd64.whl", hash = "sha256:3491cb69c909d586c23d7e6d0ac87844ca22f496f505ce429c0d3301234f2cf3"},
+]
+
+[package.dependencies]
+grpcio = ">=1.59.2"
+protobuf = ">=4.21.6,<5.0dev"
+setuptools = "*"
+
[[package]]
name = "h11"
version = "0.14.0"
@@ -1350,6 +1418,32 @@ files = [
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
]
+[[package]]
+name = "h2"
+version = "4.1.0"
+description = "HTTP/2 State-Machine based protocol implementation"
+optional = true
+python-versions = ">=3.6.1"
+files = [
+ {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"},
+ {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"},
+]
+
+[package.dependencies]
+hpack = ">=4.0,<5"
+hyperframe = ">=6.0,<7"
+
+[[package]]
+name = "hpack"
+version = "4.0.0"
+description = "Pure-Python HPACK header compression"
+optional = true
+python-versions = ">=3.6.1"
+files = [
+ {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"},
+ {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"},
+]
+
[[package]]
name = "httpcore"
version = "1.0.2"
@@ -1433,6 +1527,7 @@ files = [
[package.dependencies]
anyio = "*"
certifi = "*"
+h2 = {version = ">=3,<5", optional = true, markers = "extra == \"http2\""}
httpcore = "*"
idna = "*"
sniffio = "*"
@@ -1490,6 +1585,17 @@ files = [
[package.dependencies]
pyreadline3 = {version = "*", markers = "sys_platform == \"win32\" and python_version >= \"3.8\""}
+[[package]]
+name = "hyperframe"
+version = "6.0.1"
+description = "HTTP/2 framing layer for Python"
+optional = true
+python-versions = ">=3.6.1"
+files = [
+ {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"},
+ {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"},
+]
+
[[package]]
name = "identify"
version = "2.5.31"
@@ -2941,6 +3047,25 @@ files = [
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
+[[package]]
+name = "portalocker"
+version = "2.8.2"
+description = "Wraps the portalocker recipe for easy usage"
+optional = true
+python-versions = ">=3.8"
+files = [
+ {file = "portalocker-2.8.2-py3-none-any.whl", hash = "sha256:cfb86acc09b9aa7c3b43594e19be1345b9d16af3feb08bf92f23d4dce513a28e"},
+ {file = "portalocker-2.8.2.tar.gz", hash = "sha256:2b035aa7828e46c58e9b31390ee1f169b98e1066ab10b9a6a861fe7e25ee4f33"},
+]
+
+[package.dependencies]
+pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""}
+
+[package.extras]
+docs = ["sphinx (>=1.7.1)"]
+redis = ["redis"]
+tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)", "types-redis"]
+
[[package]]
name = "posthog"
version = "3.0.2"
@@ -3416,6 +3541,29 @@ files = [
{file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"},
]
+[[package]]
+name = "pywin32"
+version = "306"
+description = "Python for Window Extensions"
+optional = true
+python-versions = "*"
+files = [
+ {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"},
+ {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"},
+ {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"},
+ {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"},
+ {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"},
+ {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"},
+ {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"},
+ {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"},
+ {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"},
+ {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"},
+ {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"},
+ {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"},
+ {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"},
+ {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"},
+]
+
[[package]]
name = "pyyaml"
version = "6.0.1"
@@ -3475,6 +3623,29 @@ files = [
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
]
+[[package]]
+name = "qdrant-client"
+version = "1.6.4"
+description = "Client library for the Qdrant vector search engine"
+optional = true
+python-versions = ">=3.8,<3.13"
+files = [
+ {file = "qdrant_client-1.6.4-py3-none-any.whl", hash = "sha256:db4696978d6a62d78ff60f70b912383f1e467bda3053f732b01ddb5f93281b10"},
+ {file = "qdrant_client-1.6.4.tar.gz", hash = "sha256:bbd65f383b6a55a9ccf4e301250fa925179340dd90cfde9b93ce4230fd68867b"},
+]
+
+[package.dependencies]
+grpcio = ">=1.41.0"
+grpcio-tools = ">=1.41.0"
+httpx = {version = ">=0.14.0", extras = ["http2"]}
+numpy = {version = ">=1.21", markers = "python_version >= \"3.8\" and python_version < \"3.12\""}
+portalocker = ">=2.7.0,<3.0.0"
+pydantic = ">=1.10.8"
+urllib3 = ">=1.26.14,<2.0.0"
+
+[package.extras]
+fastembed = ["fastembed (==0.1.1)"]
+
[[package]]
name = "referencing"
version = "0.30.2"
@@ -5320,7 +5491,10 @@ files = [
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
+[extras]
+qdrant = ["qdrant-client"]
+
[metadata]
lock-version = "2.0"
python-versions = ">=3.11,<3.12"
-content-hash = "3ea28113b04a06b1dfcbe6f43cdce086b596c714a53c10eb6501ab0c5d464412"
+content-hash = "a72d664bdd24534d353deb2ad98cdebb5caa1647315405260c9c9f6e64d52f5a"
diff --git a/private_gpt/components/vector_store/vector_store_component.py b/private_gpt/components/vector_store/vector_store_component.py
index d68358abc..397d6daa7 100644
--- a/private_gpt/components/vector_store/vector_store_component.py
+++ b/private_gpt/components/vector_store/vector_store_component.py
@@ -1,7 +1,8 @@
+import logging
import typing
import chromadb
-from chromadb.config import Settings
+from chromadb.config import Settings as ChromaSettings
from injector import inject, singleton
from llama_index import VectorStoreIndex
from llama_index.indices.vector_store import VectorIndexRetriever
@@ -10,6 +11,9 @@
from private_gpt.components.vector_store.batched_chroma import BatchedChromaVectorStore
from private_gpt.open_ai.extensions.context_filter import ContextFilter
from private_gpt.paths import local_data_path
+from private_gpt.settings.settings import Settings
+
+logger = logging.getLogger(__name__)
@typing.no_type_check
@@ -36,22 +40,58 @@ class VectorStoreComponent:
vector_store: VectorStore
@inject
- def __init__(self) -> None:
- chroma_settings = Settings(anonymized_telemetry=False)
- chroma_client = chromadb.PersistentClient(
- path=str((local_data_path / "chroma_db").absolute()),
- settings=chroma_settings,
- )
- chroma_collection = chroma_client.get_or_create_collection(
- "make_this_parameterizable_per_api_call"
- ) # TODO
+ def __init__(self, settings: Settings) -> None:
+ match settings.vectorstore.database:
+ case "chroma":
+ chroma_settings = ChromaSettings(anonymized_telemetry=False)
+ chroma_client = chromadb.PersistentClient(
+ path=str((local_data_path / "chroma_db").absolute()),
+ settings=chroma_settings,
+ )
+ chroma_collection = chroma_client.get_or_create_collection(
+ "make_this_parameterizable_per_api_call"
+ ) # TODO
- self.vector_store = typing.cast(
- VectorStore,
- BatchedChromaVectorStore(
- chroma_client=chroma_client, chroma_collection=chroma_collection
- ),
- )
+ self.vector_store = typing.cast(
+ VectorStore,
+ BatchedChromaVectorStore(
+ chroma_client=chroma_client, chroma_collection=chroma_collection
+ ),
+ )
+
+ case "qdrant":
+ try:
+ from llama_index.vector_stores.qdrant import QdrantVectorStore
+ from qdrant_client import QdrantClient # type: ignore
+ except ImportError as e:
+ raise ImportError(
+ "'qdrant_client' is not installed."
+ "To use PrivateGPT with Qdrant, install the 'qdrant' extra."
+ "`poetry install --extras qdrant`"
+ ) from e
+ if settings.qdrant is None:
+ logger.info(
+ "Qdrant config not found. Using default settings."
+ "Trying to connect to Qdrant at localhost:6333."
+ )
+ client = QdrantClient()
+ else:
+ client = QdrantClient(
+ **settings.qdrant.model_dump(exclude_none=True)
+ )
+ self.vector_store = typing.cast(
+ VectorStore,
+ QdrantVectorStore(
+ client=client,
+ collection_name="make_this_parameterizable_per_api_call",
+ ), # TODO
+ )
+ case _:
+ # Should be unreachable
+ # The settings validator should have caught this
+ raise ValueError(
+ f"Vectorstore database {settings.vectorstore.database} not supported"
+ )
@staticmethod
def get_retriever(
diff --git a/private_gpt/settings/settings.py b/private_gpt/settings/settings.py
index 88c174187..785f7b40f 100644
--- a/private_gpt/settings/settings.py
+++ b/private_gpt/settings/settings.py
@@ -84,6 +84,10 @@ class LLMSettings(BaseModel):
mode: Literal["local", "openai", "sagemaker", "mock"]
+class VectorstoreSettings(BaseModel):
+ database: Literal["chroma", "qdrant"]
+
+
class LocalSettings(BaseModel):
llm_hf_repo_id: str
llm_hf_model_file: str
@@ -104,6 +108,53 @@ class UISettings(BaseModel):
path: str
+class QdrantSettings(BaseModel):
+ location: str | None = Field(
+ None,
+ description=(
+ "If `:memory:` - use in-memory Qdrant instance.\n"
+ "If `str` - use it as a `url` parameter.\n"
+ ),
+ )
+ url: str | None = Field(
+ None,
+ description=(
+ "Either host or str of 'Optional[scheme], host, Optional[port], Optional[prefix]'."
+ ),
+ )
+ port: int | None = Field(6333, description="Port of the REST API interface.")
+ grpc_port: int | None = Field(6334, description="Port of the gRPC interface.")
+ prefer_grpc: bool | None = Field(
+ False,
+ description="If `true` - use gRPC interface whenever possible in custom methods.",
+ )
+ https: bool | None = Field(
+ None,
+ description="If `true` - use HTTPS(SSL) protocol.",
+ )
+ api_key: str | None = Field(
+ None,
+ description="API key for authentication in Qdrant Cloud.",
+ )
+ prefix: str | None = Field(
+ None,
+ description=(
+ "Prefix to add to the REST URL path."
+ "Example: `service/v1` will result in "
+ "'http://localhost:6333/service/v1/{qdrant-endpoint}' for REST API."
+ ),
+ )
+ timeout: float | None = Field(
+ None,
+ description="Timeout for REST and gRPC API requests.",
+ )
+ host: str | None = Field(
+ None,
+ description="Host name of Qdrant service. If url and host are None, set to 'localhost'.",
+ )
+ path: str | None = Field(None, description="Persistence path for QdrantLocal.")
+
+
class Settings(BaseModel):
server: ServerSettings
data: DataSettings
@@ -112,6 +163,8 @@ class Settings(BaseModel):
local: LocalSettings
sagemaker: SagemakerSettings
openai: OpenAISettings
+ vectorstore: VectorstoreSettings
+ qdrant: QdrantSettings | None = None
"""
diff --git a/pyproject.toml b/pyproject.toml
index 114bde1f0..568a36b4e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -15,6 +15,7 @@ pypdf = "^3.16.2"
llama-index = "0.8.67"
chromadb = "^0.4.13"
watchdog = "^3.0.0"
+qdrant-client = {version = "^1.6.4", optional = true}
[tool.poetry.group.dev.dependencies]
black = "^22"
@@ -42,6 +43,9 @@ sentence-transformers = "^2.2.2"
torch = ">=2.0.0, !=2.0.1, !=2.1.0"
transformers = "^4.34.0"
+[tool.poetry.extras]
+qdrant = ["qdrant-client"]
+
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
diff --git a/settings.yaml b/settings.yaml
index 807ad53b6..f686fdb54 100644
--- a/settings.yaml
+++ b/settings.yaml
@@ -23,6 +23,9 @@ ui:
llm:
mode: local
+vectorstore:
+ database: chroma
+
local:
llm_hf_repo_id: TheBloke/Mistral-7B-Instruct-v0.1-GGUF
llm_hf_model_file: mistral-7b-instruct-v0.1.Q4_K_M.gguf